联系方式

  • QQ:99515681
  • 邮箱:99515681@qq.com
  • 工作时间:8:00-21:00
  • 微信:codinghelp

您当前位置:首页 >> C/C++编程C/C++编程

日期:2018-04-18 06:32

Implementation of a Single Cycle CPU simulator

1.Introduction


In this project, you are going to implement a single cycle CPU simulator called MiniCPU using C language. Your MiniCPU will demonstrate some functions of MIPS


processors as well as the principle of the datapath and the control signals. MiniCPU should read in a file containing MIPS machine codes (in the format specified


below) and simulate what the MIPS processor does cycle-by-cycle. A C file called component.c will be provided to you which implementing each component of the single-


cycle datapath, you are required to modify and fill in the body of the functions in this file.

在这个项目中,您将使用C语言实现一个名为MiniCPU的单周期CPU模拟器。 您的MiniCPU将演示MIPS处理器的一些功能以及数据通路和控制信号的原理。 MiniCPU应该读入包含MIPS机器代码的


文件(采用下面指定的格式),并模拟MIPS处理器循环的内容。 一个名为component.c的C文件将被提供给你,它实现了单周期数据通路的每个组件,你需要修改并填写这个文件中的函数体。


2.Specification of the simulator


2.1.Instructions to be simulated


The 14 instructions listed in Figure 1 in the appendix. Note that you are NOT required to treat situations leading to exception.


附录图1中列出了14条指令。 请注意,您不需要处理导致异常的情况。

2.2.Registers to be handled

MiniCPU should handle the 32 general purpose registers. At the start of the program, the registers are initialized to be the values specified in minicpu.c

MiniCPU应该处理32个通用寄存器。 在程序开始时,寄存器被初始化为minicpu.c中指定的值


2.3.Memory usage

内存使用情况

The size of memory of MiniCPU is 64kB (Address 0x0000 to 0xFFFF).

The system assumes that all program starts at memory location 0x4000.  

All instructions are word-aligned in the memory, i.e. the addresses of all instructions are multiple of 4.

The simulator (and the MIPS processor itself) treats the memory as one segment. (The division of memory into text, data and stack segments is only done by the


compiler/assembler.)

At the start of the program, all memory are initialized to zero, except those specified in the “-asc” file, as shown in the provided codes.

The memory is in the following format:

e.g. Store a 32-bit number 0xaabbccdd in memory address 0x0 – 0x3.

Mem[0]

Address0x00x10x20x3

Contentaabbccdd

MiniCPU的内存大小为64kB(地址0x0000至0xFFFF)。

系统假定所有程序从内存位置0x4000开始。

所有指令在内存中都是字对齐的,即所有指令的地址都是4的倍数。

模拟器(和MIPS处理器本身)将内存视为一个段。 (内存分为文本,数据和堆栈段只能由编译器/汇编程序完成。)

在程序开始时,除了在“-asc”文件中指定的内容之外,所有内存都被初始化为0,如提供的代码所示。

内存格式如下:

例如 将32位数字0xaabbccdd存储在内存地址0x0 - 0x3中。

2.4.Conditions that the MiniCPU should halt

MiniCPU应该停止的条件

If one of the following situations is encountered, the global flag Halt is set to 1, and hence the simulation halts.


An illegal instruction is encountered. Instructions beyond the list of instructions in Figure 1 are illegal.

Jumping to an address that is not word-aligned (being multiple of 4)

The address of lw or sw is not word-aligned

Accessing data or jump to address that is beyond the memory.

如果遇到以下情况之一,则全局标志Halt被设置为1,因此仿真暂停。


遇到非法指令。 图1中指令列表之外的指令是非法的。

跳转到不是字对齐的地址(是4的倍数)

lw或sw的地址不是字对齐的

“访问数据或跳转到超出内存的地址。


2.5.Format of the input machine code file

输入机器代码文件的格式

MiniCPU takes hexadecimal formatted machine codes, with filename xxx.asc, as input.  An example of .asc file is shown below. Code after “#” on any line is treated as


comments.

MiniCPU采用十六进制格式的机器代码,文件名xxx.asc作为输入。 下面显示了一个.asc文件的例子。 任何行上的“#”之后的代码都被视为注释。

20010000    #addi $1, $0, 0

200200c8    #addi $2, $0, 200

10220003    #beq $1, $2, 3

00000020    #delay slot

20210001    #addi $1, $1, 1

00000020    #no operation


The simulation ends when an illegal instruction, such as 0x00000000, is encountered.

在遇到非法指令(如0x00000000)时,仿真结束。

2.6.Note on branch addressing

关于分支寻址的说明

The branch offset in MIPS, and hence in MiniCPU, is relative to the next instruction, i.e. (PC+4). For example,

MIPS中的分支偏移,因此在MiniCPU中,相对于下一个指令,即(PC + 4)。 例如,

3.Resources


3.1.Files provided


Please download project.zip from ftp://ftp.must.edu.mo/, the following are files after unzip:


minicpu.c minicpu.hcomponent.cminicpuasm.pl   incommand

test01.asmtest01.asctest02.asmtest02.asc



These files contain the main program and the other supporting functions of the simulator. The code should be self-explanatory. You are required to fill in and modify


the functions in component.c. You are not allowed to modify minicpu.c and minicpu.h. All your works should be placed in component.c only. You are not allowed to add


new files. Otherwise, your program will not be marked.


3.1。 提供的文件


请从ftp://ftp.must.edu.mo/下载project.zip,解压缩后的文件如下:


minicpu.c minicpu.h component.c minicpuasm.pl命令

test01.asm test01.asc test02.asm test02.asc



这些文件包含模拟器的主程序和其他支持功能。 代码应该是不言自明的。 您需要填写和修改component.c中的函数。 你不能修改minicpu.c和minicpu.h。 所有的作品只能放在component.c


中。 您不允许添加新文件。 否则,您的程序将不会被标记。



3.2.MIPS assembler


A simple assembler minicpuasm.pl is provided for your convenience of testing your MinCPU. The command is:


$minicpuasm.pl filename.asm > filename.asc


where filename.asm is your assembly code file and filename.asc is the output machine code file in hexadecimal format.


3.2。 MIPS汇编器


提供了一个简单的汇编程序minicpuasm.pl,以方便您测试MinCPU。 该命令是:


$ minicpuasm.pl filename.asm> filename.asc


其中filename.asm是您的汇编代码文件和filename.asc是十六进制格式的输出机器代码文件。


4.Functions in component.c


Firstly, you are required to complete a function (ALU(…)) in component.c that simulates the operations of an ALU.

在component.c中的函数


首先,您需要在component.c中完成模拟ALU操作的函数(ALU(...))。

void ALU(unsigned A, unsigned B, char ALUControl, unsigned *ALUresult, char *Zero)

{

if(ALUControl==0x0)*ALUresult=A+B;         //add

}



ALU(…)

1.Implement the operations on input parameters A and B according to ALUControl.

2.Output the result to ALUresult.

3.Assign Zero to 1 if the result is zero; otherwise, assign 0.

4.The following table shows the operations of the ALU.

1.根据ALUControl对输入参数A和B进行操作。

2.将结果输出到ALUresult。

3.如果结果为零,则将零分配给1; 否则,分配0。

4.下表显示了ALU的操作。

ALUControlMeaning

000Z = A + B

001Z = A – B

010if A < B, Z = 1; otherwise, Z = 0

011if A < B, Z = 1; otherwise, Z = 0 (A and B are unsigned integers)

100Z = A AND B

101Z = A OR B

110Shift B left by 16 bits

111Z = NOR(A,B)


Secondly, you are required to fill in 9 functions in component.c. Each function simulates the operations of a section of the datapath. Figure 2 in the appendix shows


the datapath and the sections of the datapath you need to simulate.


In minicpu.c, the function Step() is the core function of the MiniCPU. This function invokes the 9 functions that you are required to implement to simulate the signals


and data passing between the components of the datapath. Read Step() thoroughly in order to understand the signals and data passing, and implement the 9 functions.


The following shows the specifications of the 9 functions:

其次,你需要填写component.c中的9个函数。 每个函数都模拟数据路径的一部分的操作。 附录中的图2显示了您需要模拟的数据路径和数据路径的各个部分。


在minicpu.c中,Step()函数是MiniCPU的核心功能。 该函数调用您需要实现的9个函数,以模拟数据路径组件之间传递的信号和数据。 仔细阅读Step()以了解信号和数据传递,并实现9


个功能。


以下显示了9个功能的规格:

instruction_fetch(…)

1.Fetch the instruction addressed by PC from Mem and write it to instruction.

2.Return 1 if an invalid instruction is encountered; otherwise, return 0.



int instruction_fetch(unsigned PC, unsigned *Mem, unsigned *instruction)

{ *instruction=Mem[PC>>2];

return 0;

}

instruction_partition(…)

1.Partition instruction into several parts (op, r1, r2, r3, funct, offset, jsec).

2.Read line 41 to 47 of minicpu.c for more information.


void instruction_partition(unsigned instruction, unsigned *op, unsigned *r1, unsigned *r2, unsigned *r3, unsigned *funct, unsigned *offset, unsigned *jsec)

{

*op = instruction >> 26;

}

instruction_decode(…)

1.Decode the instruction based on opcode (op).

2.Assign appropriate values to the variables (control signals) in the structure controls.

The meanings of the values of the control signals:

For MemRead, MemWrite or RegWrite, the value 1 means that enabled, 0 means that disabled, 2 means “don’t care”.

For RegDst, Jump, Branch, MemtoReg or ALUSrc, the value 0 or 1 indicates the selected path of the multiplexer; 2 means “don’t care”.

The following table shows the meaning of the values of ALUOp.

value (binary)Meaning

000ALU will do addition or “don’t care”

001ALU will do subtraction

010ALU will do “set less than” operation

011ALU will do “set less than unsigned” operation

100ALU will do “and” operation

101ALU will do “or” operation

110ALU will shift left extended_value by 16 bits

111The instruction is an R-type instruction

1.根据操作码(op)解码指令。

2.为结构控件中的变量(控制信号)分配适当的值。

控制信号值的含义:

对于MemRead,MemWrite或RegWrite,值1表示启用,0表示禁用,2表示“不关心”。

对于RegDst,Jump,Branch,MemtoReg或ALUSrc,值0或1表示多路复用器的选定路径; 2意味着“不在乎”。

下表显示了ALUOp的值的含义。

3.Return 1 if a halt condition occurs; otherwise, return 0.



int instruction_decode(unsigned op, struct_controls *controls)

{

if(op==0x0){//R-format

controls->RegWrite = 1;

controls->RegDst = 1;

controls->ALUOp = 7;

}


else return 1;//invalid instruction

return 0;

}




read_register(…)

1.Read the registers addressed by r1 and r2 from Reg, and write the read values to data1 and data2 respectively.


void read_register(unsigned r1, unsigned r2, unsigned *Reg, unsigned *data1, unsigned *data2)

{

*data1 = Reg[r1];

*data2 = Reg[r2];

}



sign_extend(…)

1.Assign the sign-extended value of offset to extended_value.



void sign_extend(unsigned offset, unsigned *extended_value)

{


}



ALU_operations(…)

1.Based on ALUOp and funct, perform ALU operations on data1, and data2 or extended_value.

2.Call the function ALU(…) to perform the actual ALU operation.

3.Output the result to ALUresult.

4.Return 1 if a halt condition occurs; otherwise, return 0.


int ALU_operations(unsigned data1, unsigned data2, unsigned extended_value, unsigned funct, char ALUOp, char ALUSrc, unsigned *ALUresult, char *Zero)

{

switch(ALUOp){

// R-type

case 7:

// funct = 0x20 = 32, add

if  (funct==0x20) ALU(data1, data2, 0x0, ALUresult, Zero);

else return 1;            //invalid funct

break;

default:

return 1;//invalid ALUop

}

return 0;

}



rw_memory(…)

1.Base on the value of MemWrite or MemRead to determine memory write operation or memory read operation.

2.Read the content of the memory location addressed by ALUresult to memdata.

3.Write the value of data2 to the memory location addressed by ALUresult.

4.Return 1 if a halt condition occurs; otherwise, return 0.


int rw_memory(unsigned ALUresult, unsigned data2, char MemWrite, char MemRead, unsigned *memdata, unsigned *Mem)

{

if (MemRead==1){

*memdata = Mem[ALUresult>>2];

}

return 0;

}



write_register(…)

1.Write the data (ALUresult or memdata) to a register (Reg) addressed by r2 or r3.


void write_register(unsigned r2, unsigned r3, unsigned memdata, unsigned ALUresult, char RegWrite, char RegDst, char MemtoReg, unsigned *Reg)

{

Reg[r2] = memdata;

}



PC_update(…)

1.Update the program counter (PC).


void PC_update(unsigned jsec, unsigned extended_value, char Branch, char Jump, char Zero, unsigned *PC)

{

*PC+=4;

}



The file minicpu.h is the header file which contains the definition of a structure storing the control signals and the prototypes of the above functions. The functions


may contain some parameters. Read minicpu.h for more information.

   minicpu.h文件是头文件,它包含了存储控制信号和上述函数原型的结构的定义。 这些函数可能包含一些参数。 阅读minicpu.h了解更多信息。


5. Notes


1.This project will be compiled and marked using Dev C++. You can download it from the web (http://www.bloodshed.net/dev/devcpp.html) and install it on your


computer. Remember you should download and install Dev C++ for C/C++.


2.Some instructions may try to write to the register $zero and we assume that they are valid. However, your simulator should always keep the value of $zero 0.


3.You should not do any “print” or ”printf()” operation in component.c; otherwise, the operation will disturb the marking process and your marks will be


deducted.


4.To run the compiled executable:


a.In Windows, open a command prompt.

b.Go to your working directory.

c.Type: your_executable input_asc_file < incommand


     Where incommand is the downloaded file. The output shows the values of all registers and memory locations, which allows you to check if your simulator can


produce the correct result or not.


5.To debug your program, check if the values of all registers and memory match the assembly program. The following is a sample output:


1.本项目将使用Dev C ++进行编译和标记。您可以从网站下载并将其安装到您的计算机上。请记住,您应该下载并安装Dev C ++ for C / C ++。


2.有些指令可能试图写入寄存器$零,我们假设它们是有效的。但是,您的模拟器应该始终保持$零的值0。


3.您不应在component.c中执行任何“print”或“printf()”操作。否则操作会干扰打标过程,扣分。


4.要运行编译的可执行文件:


一个。在Windows中,打开命令提示符。

湾转到您的工作目录。

C。键入:your_executable input_asc_file <命令


     其中命令是下载的文件。输出显示所有寄存器和存储器位置的值,这使您可以检查模拟器是否可以产生正确的结果。


5.要调试程序,检查所有寄存器和内存的值是否与汇编程序匹配。以下是一个示例输出:


版权所有:编程辅导网 2021 All Rights Reserved 联系方式:QQ:99515681 微信:codinghelp 电子信箱:99515681@qq.com
免责声明:本站部分内容从网络整理而来,只供参考!如有版权问题可联系本站删除。 站长地图

python代写
微信客服:codinghelp