目录
Calculate the sum of all integers from 1 to 100.
(1), programming with C language:
III. Internal Registers and Memory
V. Micro-programmed Control Unit
(I)Total control signals for instructions are listed as follows:
(II)The contents in rom.mif and the corresponding microprograms are listed as follows:
(III)The simulation waveforms of some operates
1, load, add, store, halt, 例如(22+10)
2,load, SUB, store, halt (22-10)
3,load, mpy, add, store, halt (13*10+22)
1, MBR (Memory Buffer Register)
3, MAR (Memory Address Register)
6, CAR (Control Address Register)
7, CONTRALR (Control Buffer Register)
8, ALU (Arithmetic Logic Unit)
Computer Organization and Architecture
Course Design
The Experiment Report
Of
CPU
I . Purpose
The purpose of this project is to design a simple CPU (Central Processing Unit). This CPU has basic instruction set, and we will utilize its instruction set to generate a very simple program to verify its performance. For simplicity, we will only consider the relationship among the CPU, registers, memory and instruction set. That is to say we only need consider the following items: Read/Write Registers, Read/Write Memory and Execute the instructions.
At least four parts constitute a simple CPU: the control unit, the internal registers, the ALU and instruction set, which are the main aspects of our project design and will be studied.
II . Instruction Set
Single-address instruction format is used in our simple CPU design. The instruction word contains two sections: the operation code (opcode), which defines the function of instructions (addition, subtraction, logic operations, etc.); the address part, in most instructions, the address part contains the memory location of the datum to be operated, we called it direct addressing. In some instructions, the address part is the operand, which is called immediate addressing.
For simplicity, the size of memory is 256× 16 in the computer. The instruction word has 16 bits. The opcode part has 8 bits and address part has 8 bits. The instruction word format can be expressed in Figure 1:
OPCODE [15..0] | ADDRESS [7..0] |
Figure 1 the instruction format
The opcode of the relevant instructions are listed in Table 1.
In Table 1, the notation [x] represents the contents of the location x in the memory. For example, the instruction word 00000011101110012 (03B916) means that the CPU adds word at location B916 in memory into the accumulator (ACC); the instruction word 00000101000001112 (050716) means if the sign bit of the ACC (ACC [15]) is 0, the CPU will use the address part of the instruction as the address of next instruction, if the sign bit is 1, the CPU will increase the program counter (PC) and use its content as the address of the next instruction.
Table 1 List of opcode of the relevant instructions
INSTRUCTION | OPCODE | COMMENTS |
STORE X | 01H | ACC→[X] |
LOAD X | 02H | [X]→ACC |
ADD X | 03H | ACC+[X]→ACC |
SUB X | 04H | ACC-[X]→ACC |
JMPGZ X | 05H | IF ACC>0 THEN X→PC ELSE PC+1→PC |
AND X | 06H | ACC and [X]→ACC |
OR X | 07H | ACC or [X]→ACC |
NOT X | 08H | Not [X]→ACC |
SHIFTR X | 09H | SHIFL ACC to RIGHT 1 bit, Logic Shift |
SHIFTL X | 0AH | SHIFT ACC to LEFT 1 bit, Logic Shift |
MPY X | 0BH | ACC×[X]→ACC |
HALT | 0CH | HALT A PROGRAM |
A program is designed to test these instructions:
Calculate the sum of all integers from 1 to 100.
(1), programming with C language:
sum=0;
temp=100;
loop :sum=sum+temp;
temp=temp-1;
if temp>=0 goto loop;
end
(2), Assume in the RAM_DQ:
sum is stored at location A4,
temp is stored at location A3,
the contents of location A0 is 0,
the contents of location A1 is 1,
the contents of location A2 is 10010=6416.
We can translate the above C language program with the instructions listed in Table 1 into the instruction program as shown in Table 2.
Table 2 Example of a program to sum from 1 to 100
Program with C | Program with instructions | Contents of RAM_DQ in HEX | |
Address | Contents | ||
sum=0; | LOAD A0 | 00 | 02A0 |
STORE A4 | 01 | 01A4 | |
temp=100 | LOAD A2 | 02 | 02A2 |
STORE A3 | 03 | 01A3 | |
loop:sum=sum+temp; | LOOP:LOAD A4 | 04 | 02A4 |
ADD A3 | 05 | 03A3 | |
STORE A4 | 06 | 01A4 | |
temp=temp-1; | LOAD A3 | 07 | 02A3 |
SUB A1 | 08 | 04A1 | |
STORE A3 | 09 | 01A3 | |
if temp>0 goto loop; | JMPGZ LOOP | 0A | 0504 |
end; | HALT | 0B | 0C00 |
0C | |||
… | … | ||
A0 | 0000 | ||
A1 | 0001 | ||
A2 | 0064 | ||
A3 | |||
A4 | |||
… | … |
III. Internal Registers and Memory
MAR (Memory Address Register)
MAR contains the memory location of the word to be read from the memory or written into the memory. Here, READ operation is denoted as the CPU reads from memory, and WRITE operation is denoted as the CPU writes to memory. In our design, MAR has 8 bits to access one of 256 addresses of the memory.
MBR (Memory Buffer Register)
MBR contains the value to be stored in memory or the last value read from memory. MBR is connected to the address lines of the system bus. In our design, MBR has 16 Bits.
PC (Program Counter)
PC keeps track of the instructions to be used in the program. In our design, PC has 8 bits.
IR (Instruction Register)
IR contains the opcode part of an instruction. In our design, IR has 8 bits.
BR (Buffer Register)
BR is used as an input of ALU, it holds other operand for ALU. In our design, BR has
16 bits.
LPM_RAM_DQ
LPM_RAM_DQ is a RAM with separate input and output ports. It works as a memory, and its size is 256×16. Although it’s not an internal register of CPU, we need it to simulate and test the performance of CPU.
LPM_ROM
LPM_ROM is a ROM with one address input port and one data output port, and its size of data is 32bits which contains control signals to execute micro-operations.
IV.ALU
ALU (Arithmetic Logic Unit) is a calculation unit which accomplishes basic arithmetic and logic operations. In our design, some operations must be supported which are listed as follows:
Table 3 ALU Operations
ALU control signal | Operations | Explanations |
3H | ADD | ACC←ACC+BR |
4H | SUB | ACC←ACC- BR |
6H | AND | ACC←ACC and BR |
7H | OR | ACC←ACC or BR |
8H | NOT | ACC←not ACC |
9H | SHIFTR | ACC←Shift ACC to Right 1 bit |
0AH | SHIFTL | ACC←Shift ACC to Left 1 bit |
V. Micro-programmed Control Unit
In the Microprogrammed control, the microprogram consists of some microinstruction and the microprogram is stored in control memory that generates all the control signals required to execute the instruction set correctly. The microinstruction contains some micro-operations which are executed at the same time.
Figure 2 shows the key elements of such an implementation.
The set of microinstructions is stored in the control memory. The control address register contains the address of the next microinstructions to be read. When a microinstruction is read from the control memory, it is transferred to a control buffer register. The register connects to the control lines emanating from the control unit. Thus, reading a microinstruction from the control memory is the same as executing that microinstruction. The third element shown in the figure is a sequencing unit that loads the control address register and issues a read command.
Figure 2 Control Unit Micro-architecture
(I)Total control signals for instructions are listed as follows:
Table 4 Control signals for the micro-operations
Bits in Control Memory | Micro-operation | Meaning |
C0~C7 | / | Branch Addresses |
C8 | PC←0 | Clear PC |
C9 | PC←PC+1 | Increment PC |
C10 | PC←MBR[7..0] | MBR[7..0] to PC |
C11 | ACC←0 | Clear ACC |
C12--C15 | ALU CONTROL | Control operations of ALU |
C16 | R | Read data from Memory to MBR |
C17 | W | Write data to Memory |
C18 | MAR←MBR[7..0] | MBR[7..0] to MAR as address |
C19 | MAR←PC | PC value to MAR |
C20 | MBR←ACC | ACC value to MBR |
C21 | IR←MBR[15..8] | MBR[15..8] to IR as opcode |
C22 | BR←MBR | Copy MBR to BR |
C23 | CAR←CAR+1 | Increment CAR |
C24 | CAR←C0~C7 | C7~C0 to CAR |
C25 | CAR←OPCODE+CAR | Add OP to CAR |
C26 | CAR←0 | Reset CAR |
C27--C31 | Not use | ----------- |
(II)The contents in rom.mif and the corresponding microprograms are listed as follows:
0 : 00810000; R←1, CAR←CAR+1
1 : 00A00000; OP←MBR[15..8],CAR←CAR+1
2 : 02000000; CAR←CAR+OP
3 : 01000014; CAR←14H
4 : 01000019; CAR←19H
5 : 0100001E; CAR←1EH
6 : 01000023; CAR←23H
7 : 01000041; CAR←41H
8 : 01000028; CAR←28H
9 : 0100002D; CAR←2DH
a : 01000032; CAR←32H
b : 01000037; CAR←37H
c : 0100003C; CAR←3CH
d : 01000046; CAR←46H
e : 0100004B; CAR←4BH
f : 00000000;
… ……
14 : 00840000; MAR←MBR[7..0], CAR←CAR+1 ------STORE
15 : 00920200; MBR←ACC, PC←PC+1,W←1,CAR←CAR+1
16 : 04080000; CAR←0, MAR←PC
17 : 00000000;
18 : 00000000;
19 : 00840000; MAR←MBR[7..0], CAR←CAR+1 ------LOAD
1a : 00810A00; PC←PC+1,R←1,ACC←0,CAR←CAR+1
1b : 00C03000; BR←MBR,ACC←ACC+BR, CAR←CAR+1
1c : 04080000; CAR←0
1d : 00000000;
1e : 00840000; MAR←MBR[7..0], CAR←CAR+1 ----------ADD
1f : 00810200; PC←PC+1,R←1,CAR←CAR+1
20 : 00C03000; BR←MBR,ACC←ACC+BR, CAR←CAR+1
21 : 04080000; CAR←0
22 : 00000000;
23 : 00840000; MAR←MBR[7..0], CAR←CAR+1 ----------SUB
24 : 00810200; PC←PC+1,R←1,CAR←CAR+1
25 : 00C04000; BR←MBR,ACC←ACC-BR, CAR←CAR+1
26 : 04080000; CAR←0
27 : 00000000;
28 : 00840000; MAR←MBR[7..0], CAR←CAR+1 ---------AND
29 : 00810200; PC←PC+1,R←1,CAR←CAR+1
2a : 00C06000; BR←MBR,ACC←ACC AND BR,CAR←CAR+1
2b : 04080000; CAR←0
2c : 00000000;
2d : 00840000; MAR←MBR[7..0], CAR←CAR+1 ---------OR
2e : 00810200; PC←PC+1,R←1,CAR←CAR+1
2f : 00C07000; BR←MBR,ACC←ACC OR BR, CAR←CAR+1
30 : 04080000; CAR←0
31 : 00000000;
32 : 00840000; MAR←MBR[7..0], CAR←CAR+1 ----------NOT
33 : 00808200; PC←PC+1, ACC←NOT ACC,CAR←CAR+1
34 : 04080000; CAR←0
35 : 00000000;
36 : 00000000;
37 : 00840000; MAR←MBR[7..0], CAR←CAR+1 ----------SHIFTR
38 : 08092000; PC←PC+1, ACC←SHIFT ACC to Right 1 bit,CAR←CAR+1
39 : 04080000; CAR←0
3a : 00000000;
3b : 00000000;
3c : 00840000; MAR←MBR[7..0], CAR←CAR+1 -----------SHIFTL
3d : 0080A200; PC←PC+1, ACC←SHIFT ACC to Left 1 bit,CAR←CAR+1
3e : 04080000; CAR←0
3f : 00000000;
40 : 00000000;
41 : 00840000; MAR←MBR[7..0], CAR←CAR+1 -----------JMPGEZ
42 : 00805000; CAR←CAR+1,(if ACC>0 then PCjmp<='1', PCout<=MBR_PC)
43 : 04080000; CAR←0
44 : 00000000;
45 : 00000000;
46 : 00840000; MAR←MBR[7..0], CAR←CAR+1 ------------MPY
47 : 00810200; PC←PC+1,R←1,CAR←CAR+1
48 : 00C0B000; BR←MBR,ACC←ACC*BR, CAR←CAR+1
49 : 04080000; CAR←0
4a : 00000000;
4b : 0100004B; CAR←4BH ------------------------------HALT
4c : 00000000;
(IIa) CPU电路图
rom.mif数据图
操作解释说明表:
(III)The simulation waveforms of some operates
1, load, add, store, halt, 例如(22+10)
The contents in RAM:
0 : 022A; Load 2A
1 : 032B; ADD 2B
2 : 012C; Store 2C
3 : 0C00; Halt
2a : 0016;
2b : 000A;
运算过程分析:ram(3)为0C00,终止程序,所以下面的存储单元2a,2b中存放的内容都是数据而不是指令。首先ram(0)<= 022A,将存放在存储单元2a的被加数 (0016)16 =(22)10 通过load操作放至ACC中,然后再让ACC加上加数(000A)16=(10)10。最后把结果(0020)16=(32)10存入RAM中地址为2C的单元,完成后终止程序。
ram.mif数据图
The content in RAM addressed of 2b is 0020(H).
The waveform of the operate:
(1)程序1波形图, 根据波形图,逐条指令数据运算过程分析、逐个阶段、逐个操作、逐个部件、逐个数据变化的对应关系分析。
【022A】
PCOUT为0,给ram地址为00的指令输出022A(如图中1);
MBR解析出操作码为IROUT=02(如图中2);
地址码为MAROUT=2A(如图中3);
RAM输出地址为2A的数据RAMOUT=0016(如图中4);
pcinc=1时,PCOUT=PCOUT+1=01(如图中5);
读信号R=1,MBR输出从RAM的地址2A中获取数据,BROUT=0016(如图中6);
ALUIN=0011,ALUOUT = ACCOUT + BROUT = 0000 + 0016 = 0016,完成运算后将结果放入ACC中保存(如图中7)。
【032B】
PCOUT=1(如图中1);
ram输出地址为0l的指令032B(如图中2;
MBR解析出操作码为IROUT=03(如图中3);
地址码为MAROUT=2B(如图中4);
RAM输出地址为2B的数据RAMOUT=000A(如图中5);
pcinc=1时,PCOUT=PCOUT+1=02(如图中6);
读信号R=1,MBR输出从RAM的地址2B中获取数据,BROUT=000A(如图中7);
ALUIN=0011,ALUOUT=ACCOUT+BROUT =0016+000A=0020,完成运算后将结果放入ACC中保存(如图中8)。
【012C】
PCOUT=2(如图中1);
ram输出地址为02的指令012C(如图中2);
MBR解析出操作码为IROUT=01(如图中3);
地址码为MAROUT=2C(如图中4);
W=1时,ACC的值写入地址为2C的单元,将完成的结果存入ram。ram输出刚刚存入2C的值RAMOUT=0020(如图中5)
【0C00】
PCOUT=3(如图中1);
ram输出地址为03的指令0C00(如图中2);
MBR解析出操作码为IROUT=0C(如图中3);
地址码为MAROUT=00;CAROUT=0E,CONTROLIN=ROMOUT=0100004B,故CAROUT=4B(如图中4),ROM取地址4B内容为0100004B,程序结束。
(2)任选一条指令作指令周期分析,根据波形图,结合微程序、微指令、微指令格式、代码、电路图、指令系统设计等作出具体说明,标注控制信号,地址,数据等信息的每一次流动、变化。
(必做)
对【022A】Load 2A进行详细分析:
取指阶段fetch
0 : 00810000; R←1, CAR←CAR+1
1 : 00A00000; OP←MBR[15..8],CAR←CAR+1
2 : 02000000; CAR←CAR+OP
4 : 01000019; CAR←19H
执行阶段load
19 : 00840000; MAR←MBR[7..0], CAR←CAR+1 ------LOAD
1a : 00810A00; PC←PC+1,R←1,ACC←0,CAR←CAR+1
1b : 00C03000; BR←MBR,ACC←ACC+BR, CAR←CAR+1
1c : 04080000; CAR←0
(a)取指阶段
0 : 00810000; R←1, CAR←CAR+1
clkMBR=↑,reset=0,ROM中位于地址CAROUT=00(H)的微指令rom(00)=00810000送到CONTROLR中解析控制指令,此时CONTROLR发出R=1,car_c=0001(B),CAR寻址方式选择自增寻址,carout=carout+1=01(H)
相关代码CAR.Vhd:
波形图:
电路图:
1 : 00A00000; OP←MBR[15..8],CAR←CAR+1
MAROUT=00(H),ram输出地址为00的指令022A(H),即RAM_MBR=RAMOUT=022A(H); ROM中位于地址CAROUT=01(H)的微指令rom(01)=00A00000(H)送到CONTROLR中解析控制指令,此时MBROP=1,carc=0001(H), MBR把ram_out=022A(H)的高位02送到MBROP中,再由IR送至op; car_c=0001(B),寻址方式选择自增寻址,carout=carout+1=02(H)
相关代码:
CONTROLR:
MBR_OPc<=control(21);
CARc<=control(26 downto 23);
MBR:
if reset='1' then
if R='1' then MBR_BR<=RAM_MBR; end if;
end if;
MBR:
if(clk'event and clk='0')then
if reset='1' then
if MBR_OPc='1' then MBR_OP<=RAM_MBR(15 downto 8); end if;
end if;
end if;
波形图:
电路图:
- : 02000000; CAR←CAR+OP
clkMBR↑, ROM中位于地址CAROUT=02(H)的微指令rom(02)=02000000(H)送到CONTROLR中解析控制指令,此时MBROP=1, car_c=0100(B),寻址方式选择基址寻址,carout=carout+op=04(H)
相关代码:
CAR.Vhd
波形图:
电路图:
4 : 01000019; CAR←19H
clkMBR↑, ROM中位于地址CAROUT=04(H)的微指令rom(04)=01000019(H)送到CONTROL中解析控制指令,此时car=19(H),car_c=0010(B), car_out = car = 19(H)
相关代码:CAR.vhd
波形图:
电路图:
19 : 00840000; MAR←MBR[7..0], CAR←CAR+1 ------LOAD
clkMBR=↑,ROM中位于地址CAROUT=19(H)的微指令rom(25)=00840000(H)送到CONTROLR中解析控制指令, carc=0001(H); MBR把ram_out=022A(H)的低位2A送到MAR中,然后有MBR_MARc=1,MARout输出2A(H); car_c=0001(B),寻址方式选择自增寻址,carout=carout+1=1a(H)
相关代码:
CAR代码:
if reset='1' then
if CARc="0001" then CARout<=CARout+1; end if;
end if;
MBR代码:
if(clk'event and clk='0')then
if reset='1' then
MBR_MAR<=RAM_MBR(7 downto 0);
end if;
end if;
波形图:
电路图:
1a : 00810A00; PC←PC+1,R←1,ACC←0,CAR←CAR+1
ROM中位于地址CAROUT=1a(H)的微指令rom(26)=00810A00(H)送到CONTROLR中解析控制指令,此时carc=0001(B),PCinc=1,R=1, ACCclear=1;ACC←0,PCout=PCout+1, car_c=0001(B),寻址方式选择自增寻址,carout=carout+1=1b(H)
相关代码:
CAR代码:
if reset='1' then
if CARc="0001" then CARout<=CARout+1; end if;
end if;
PC代码:
if(clk'event and clk='0')then
if reset='1' then
if PCinc='1' then PCout<=PCout+1; end if;
end if;
end if;
CONTROLR代码:
ACCclear<=control(11);
ALU代码:
if ACCclear='1' then ACC<=x"0000"; end if;
波形图:
电路图:
1b : 00C03000; BR←MBR, ACC←ACC+BR, CAR←CAR+1
ROM中位于地址CAROUT=1b(H)的微指令rom(27)=00C03000(H)送到CONTROLR中解析控制指令,此时carc=0001(B),aluCONTR=0011(B);BR=MBR;ACC=ACC+BR; car_c=0001(B),寻址方式选择自增寻址,carout=carout+1=1c(H)
相关代码:
CAR代码:
if reset='1' then
if CARc="0001" then CARout<=CARout+1; end if;
end if;
MBR代码:
if(clk'event and clk='0')then
if reset='1' then
if R='1' then MBR_BR<=RAM_MBR; end if;
end if;
end if;
ALU代码:
if(clk'event and clk='0')then
if reset='0' then ACC<=x"0000";
else
if aluCONTR="0011" then ACC<=BR+ACC; end if; --ADD
end if;
end if;
波形图:
电路图:
1c : 04080000; CAR←0
ROM中位于地址CAROUT=1c(H)的微指令rom(28)=04080000(H)送到CONTROLR中解析控制指令,此时carc=1000(B); car_c=1000(B),carout=00(H)
相关代码:
CAR代码:
if reset='1' then
if CARc="1000" then CARout<="00000000"; end if;
end if;
波形图:
电路图:
2,load, SUB, store, halt (22-10)
RAM内容:
0 : 022A; Load 2A
1 : 042B; SUB 2B
2 : 012C; Store 2C
3 : 0C00; Halt
2a : 0016;
2b : 000A;
实现计算22-10的结果过程:首先将数据(22)10=(0016)16通过LOAD操作放至ACC中,然后再让ACC减去(10)10=(000A)16。最后把结果(000C)16=(12)10存入RAM中地址为2C的单元,完成后终止程序。
【ram.mif】
【022A】
ram输出地址为00的指令022A(如图中1),MBR解析出操作码为IROUT=02(如图中2),地址码为MAROUT=2A(如图中3),RAM输出地址为2A的数据RAMOUT=0016(如图中4);pcinc=1时,PCOUT=PCOUT+1=01(如图中5); R=1,MBR输出从从RAM的地址2A中获取数据,BROUT=0016(如图中6);ALUIN=0011,ALUOUT = ACCOUT + BROUT = 0000 + 0016 = 0016(如图中7),完成将结果放入ACC。
【042B】
PCOUT=1(如图中1)、ram输出地址为0l的指令042B(如图中2),MBR解析出操作码为IPOUT=04(如图中3),地址码为MAROUT=2B(如图中4);RAM输出地址为2B的数据RAMOUT=000A(如图中5);pcinc=1时,PCOUT=PCOUT+1=02(如图中6); R=1,MBR输出从RAM的地址2B中获取数据,BROUT=000A(如图中7);ALUIN=0100,ALUOUT = ACCOUT - BROUT = 0016 - 000A = 000C(如图中8),完成将被加数放入ACC
【012C】
PCOUT=2(如图中1)、ram输出地址为02的指令012C(如图中2),MBR解析出操作码为IPOUT=01(如图中3),地址码为MAROUT=2C(如图中4);w=1时,ACC的值写入地址为2C的单元,将完成的结果存入ram。ram输出刚刚存入2C的值RAMOUT=000C(如图中5)
【0C00】
PCOUT=3(如图中1)、ram输出地址为03的指令0C00(如图中2),MBR解析出操作码为IPOUT=0C(如图中3),地址码为MAROUT=00;CAROUT=0E,CONTROLIN=ROMOUT=0100004B,故CAROUT=4B(如图中4),ROM取地址4B内的指令为00000000,自此CPU停机。
3,load, mpy, add, store, halt (13*10+22)
RAM内容:
0 : 022A; Load 2A
1 : 0B2B; MPY 2B
2 : 032C; ADD 2C
3 : 012D; Store 2D
4 : 0C00; Halt
2a : 000D;
2b : 000A;
2c : 0016;
为了验证我们的CPU,我们设计一个微程序,实现计算13*10+22的结果:首先将被加数(13)10=(000D)16通过LOAD操作放至ACC中,然后再让ACC乘上(10)10=(000A)16,然后再让ACC加上(22)10=(0016)16。最后把结果(0098)16=(152)10存入RAM中地址为2D的单元,完成后终止程序。
【ram.mif】
【022A】
ram输出地址为00的指令022A(如图中1),MBR解析出操作码为IPOUT=02(如图中2),地址码为MAROUT=2A(如图中3),RAM输出地址为2A的数据RAMOUT=0016(如图中4);pcinc=1时,PCOUT=PCOUT+1=01(如图中5); R=1,MBR输出从从RAM的地址2A中获取数据,BROUT=0016(如图中6);ALUIN=0011,ALUOUT = ACCOUT + BROUT = 0000 + 0016 = 0016(如图中7),完成将被加数放入ACC。
【0B2B】
PCOUT=1(如图中1)、ram输出地址为0l的指令0B2B(如图中2),MBR解析出操作码为IPOUT=0B(如图中3),地址码为MAROUT=2B(如图中4);RAM输出地址为2B的数据RAMOUT=000A(如图中5);pcinc=1时,PCOUT=PCOUT+1=02(如图中6); R=1,MBR输出从RAM的地址2B中获取数据,BROUT=000A(如图中7);ALUIN=1010,ALUOUT = ACCOUT * BROUT = 000D * 000A = 0082(如图中8),完成将被加数放入ACC。
【032C】
PCOUT=2(如图中1)、ram输出地址为02的指令032C(如图中2),MBR解析出操作码为IPOUT=03(如图中3),地址码为MAROUT=2C(如图中4);RAM输出地址为2C的数据RAMOUT=0016(如图中5);pcinc=1时,PCOUT=PCOUT+1=03(如图中6); R=1,MBR输出从RAM的地址2C中获取数据,BROUT=0016(如图中7);ALUIN=0011,ALUOUT = ACCOUT + BROUT = 0082 + 0016 = 0094(如图中8),完成将被加数放入ACC
【012D】
clkMBR=1时,PCOUT=3(如图中1)、ram输出地址为03的指令012D(如图中2),MBR解析出操作码为IPOUT=01(如图中3),地址码为MAROUT=2D(如图中4);w=1时,ACC的值写入地址为2D的单元,将完成的结果存入ram。ram输出刚刚存入2D的值RAMOUT=0094(如图中5)
【0C00】
clkMBR=1时,PCOUT=4(如图中1)、ram输出地址为03的指令0C00(如图中2),MBR解析出操作码为IPOUT=0C(如图中3),地址码为MAROUT=00;CAROUT=0E,CONTROLIN=ROMOUT=0100004B,故CAROUT=4B(如图中4),自此CPU停机。
4, Sum from 1 to 100
LOAD A0
PC从地址00开始,通过PC_out和MAR_in信号将地址发送到MAR。随后,R信号激活,从地址00读取指令02A0到MBR,并传输到IR。IR解析指令,识别出操作码02为LOAD操作,目标地址为A0。执行该指令后,PC自动递增到下一个地址。接着,MAR加载新地址A0,R信号再次激活,从地址A0读取数据0000到MBR。最后,MBR中的数据0000被传输到ACC。
STORE A4
PC当前指向地址01。控制信号PC_out和MAR_in被激活,将PC中的地址01传输到内存地址寄存器(MAR)。随后,R信号被激活,从地址01读取指令01A4到内存缓冲寄存器(MBR)。MBR的内容被传输到指令寄存器(IR),IR解析出操作码01,识别为STORE操作,目标地址为A4。同时,PC自动递增到下一个地址。接下来,将累加器(ACC)中的内容0000传输到MBR。然后,激活W信号(写信号),将MBR中的0000存储到内存地址A4。这一连串操作完成了STORE指令的执行,即将ACC中的数据写入到内存地址A4。
LOAD A2
PC指向02,控制信号激活后,地址02的指令02A2被读取到MBR,并传输至IR。IR解析出LOAD操作码,目标地址为A2。PC随后递增至下一条指令。接着,MAR加载地址A2,并读取该地址的数据0064到MBR。最终,MBR中的数据0064被传输到ACC。
STORE A3
PC当前指向地址03。PC_out和MAR_in信号激活,将PC内容03传输到MAR。R信号激活,读取地址03的指令01A3到MBR,随后传输到IR。IR识别出操作码01为STORE操作,地址为A3,并递增PC。接着,将累加器ACC中的0064传输到MBR,W信号激活,将MBR中的0064存储到地址A3。
进入LOOP:
LOAD A4
当PC指向04时,它首先通过PC_out和MAR_in控制信号将其内容传输到MAR。随后,R信号被激活,从地址04读取指令02A4到MBR,该指令随后被传输到IR。IR对指令进行解码,识别出操作码02对应的LOAD操作,其操作数为内存地址A4。指令执行后,PC自增到下一个地址。紧接着,MAR加载新的地址A4,并通过激活的R信号从该地址读取数据0000到MBR。最后,MBR中的数据0000被传输到ACC。
ADD A3
当PC指向05时,其内容被传输到MAR。R信号激活后,从地址05读取指令03A3到MBR,随后指令被传输到IR。IR解析出操作码03,识别为ADD操作,操作数地址为A3。同时,PC自增到下一个地址。接着,MAR加载新地址A3,并再次激活R信号,从地址A3读取数据0064到MBR。随后,执行ADD操作,将ACC中的当前值0000与MBR中的0064相加,得到结果0064,该结果更新到ACC中。
STORE A4
当PC指向06时,其内容被发送到MAR。R信号激活后,从地址06读取指令01A4到MBR,随后该指令被加载到IR。IR解析指令,识别出操作码01对应的STORE操作,目标地址为A4。同时,PC递增以指向下一条指令。接下来,将ACC中的当前值0064传输到MBR。激活W信号后,MBR中的内容(即0064)被存储到地址A4。
LOAD A3
当PC指向07时,控制信号PC_out和MAR_in被激活,将PC的内容(即07)传输到MAR。接着,R信号被激活,计算机从地址07读取指令02A3到MBR。MBR中的指令随后被传输到IR进行解码。IR识别出操作码02,对应的操作为LOAD,其操作数地址为A3。同时,PC自动递增到下一个地址。随后,MAR加载新的地址A3,R信号再次激活,从地址A3读取数据0064到MBR。最后,MBR中的数据0064被传输到ACC。
SUB A1
当PC指向08时,控制信号PC_out和MAR_in被激活,将PC的内容(即08)传输到MAR。R信号随后被激活,从地址08读取指令04A1到MBR,该指令随后被传输到IR进行解码。IR解析出操作码04,识别为SUB操作,其操作数地址为A1。同时,PC递增以指向下一条指令。接着,MAR加载地址A1,R信号再次激活,从地址A1读取数据0001到MBR。最后,执行SUB操作,将ACC中的当前值0064减去MBR中的0001,得到结果0063,并将此结果存储回ACC。
STORE A3
当PC指向09时,控制信号PC_out和MAR_in被激活,将PC的内容(即09)传输到MAR。随后,R信号被激活,从地址09读取指令01A3到MBR,指令随后被传输到IR进行解码。IR解析出操作码01,识别为STORE操作,其目标地址为A3。同时,PC递增到下一个地址。接着,将ACC中的当前值0063传输到MBR。最后,激活W信号,将MBR中的内容(即0063)存储到地址A3。
JMPGZ LOOP
当PC指向0A时,控制信号PC_out和MAR_in被激活,PC的内容(即0A)被传输到MAR。R信号随后被激活,从地址0A读取指令0504到MBR,该指令随后被传输到IR进行解析。
IR识别出操作码05,这是一个条件跳转指令JMPGZ,其跳转地址为04。接着,程序会检查ACC中的内容(当前为0063)。由于0063大于0,JMPGZ条件满足,PCjmp信号被激活,导致PC指向新的地址04,从而开始一个名为“LOOP”的循环。
在LOOP中,每次循环都会执行一系列步骤,包括从地址A3(即temp)读取一个值(初始为某个非零数),将该值加到ACC上,然后将更新后的ACC内容写回。这个过程会一直重复,每次循环ACC的内容都会增加新的A3内容(即temp减1的结果),而A3的内容则会递减,直到其变为0000。
当ACC累加到最终结果13BA时,A3(temp)的内容也恰好变为0000。此时,JMPGZ条件不再满足,因为A3的内容(即temp)已经变为0。因此,程序将不再执行跳转操作,而是继续执行下一条指令,从而跳出LOOP循环。这样,整个循环过程就完成了从temp中减去一系列数并将结果累加到ACC中的任务。
HALT
当PC指向0B时,控制信号PC_out和MAR_in激活,将PC的内容(即0B)传输到MAR。R信号随后被激活,从地址0B读取指令0C00到MBR,并立即将该指令传输到IR。IR解析出操作码0C,识别为HALT操作。执行此操作后,CPU将停止执行后续指令,并保持在当前状态,直到接收到特定的重启或中断信号。这标志着程序的正常结束或等待外部干预的状态。
通过上述一系列加载、存储、加法、减法和条件跳转指令,最终在RAM的A4地址中得到了1到100的整数和,即13BA(十六进制)。
VI. Appendix:
(I)The GDF of CPU:
The code of the CPU program:
1, MBR (Memory Buffer Register)
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
entity MBR is
port( clk, reset, MBR_OPc, ACC_MBRc,R,W:in std_logic;
ACC_MBR :in std_logic_vector(15 downto 0);
RAM_MBR :in std_logic_vector(15 downto 0);
MBR_RAM :out std_logic_vector(15 downto 0);
MBR_BR :out std_logic_vector(15 downto 0);
MBR_OP :out std_logic_vector(7 downto 0);
MBR_MAR :out std_logic_vector(7 downto 0);
MBR_PC :out std_logic_vector(7 downto 0));
end MBR;
architecture behave of MBR is
begin
process(clk)
variable temp:std_logic_vector(15 downto 0);
begin
if(clk'event and clk='0')then
if reset='1' then
if ACC_MBRc='1' then temp:=ACC_MBR; end if;
if R='1' then MBR_BR<=RAM_MBR; end if;
if W='1' then MBR_RAM<=temp; end if;
MBR_MAR<=RAM_MBR(7 downto 0);
MBR_PC<=RAM_MBR(7 downto 0);
if MBR_OPc='1' then MBR_OP<=RAM_MBR(15 downto 8); end if;
else MBR_BR<=x"0000";
MBR_MAR<="00000000";
MBR_OP<="00000000";
MBR_PC<="00000000";
end if;
end if;
end process;
end behave;
2, BR (Buffer Register)
library ieee;
use ieee.std_logic_1164.all;
entity BR is
port( MBR_BRc:in std_logic;
MBR_BR:in std_logic_vector(15 downto 0);
BRout:out std_logic_vector(15 downto 0));
end BR;
architecture behave of BR is
begin
process(MBR_BRc)
begin
if MBR_BRc='1' then BRout<=MBR_BR; end if;
end process;
end behave;
3, MAR (Memory Address Register)
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
entity MAR is
port( clk,PC_MARc,MBR_MARc:in std_logic;
PC,MBR_MAR:in std_logic_vector(7 downto 0);
MARout:out std_logic_vector(7 downto 0));
end MAR;
architecture behave of MAR is
begin
process(clk)
begin
if(clk'event and clk='1')then
if PC_MARc='1' then MARout<=PC; end if;
if MBR_MARc='1' then MARout<=MBR_MAR; end if;
end if;
end process;
end behave;
4, PC (Program Counter)
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
entity PC is
port( clk,PCjmp,PCc1,PCinc,PCc3,reset:in std_logic;
CONTRalu :in std_logic_vector(3 downto 0);
MBR_PC :in std_logic_vector(7 downto 0);
PCout :buffer std_logic_vector(7 downto 0));
end PC;
architecture behave of PC is
begin
process(clk)
begin
if(clk'event and clk='0')then
if reset='1' then
if CONTRalu="0101" then
if PCjmp='1' then PCout<=MBR_PC;
elsif PCjmp='0' then PCout<=PCout+1;
end if;
end if;
if PCc1='1' then PCout<="00000000"; end if;
if PCinc='1' then PCout<=PCout+1; end if;
if PCc3='1' then PCout<=MBR_PC; end if;
else PCout<="00000000";
end if;
end if;
end process;
end behave;
5, IR (Instruction Register)
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
entity IR is
port( opcode :in std_logic_vector(7 downto 0);
IRout :out std_logic_vector(7 downto 0));
end IR;
architecture behave of IR is
begin
IRout<=opcode;
end behave;
6, CAR (Control Address Register)
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
entity CAR is
port( clk,reset :in std_logic;
CARc :in std_logic_vector(3 downto 0);
CAR,OP :in std_logic_vector(7 downto 0);
CARout:buffer std_logic_vector(7 downto 0));
end CAR;
architecture behave of CAR is
begin
process(clk)
begin
if(clk'event and clk='1')then
if reset='1' then
if CARc="1000" then CARout<="00000000"; end if;
if CARc="0100" then CARout<=OP+CARout; end if;
if CARc="0010" then CARout<=CAR; end if;
if CARc="0001" then CARout<=CARout+1; end if;
else CARout<="00000000";
end if;
end if;
end process;
end behave;
7, CONTRALR (Control Buffer Register)
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
entity CONTROLR is
port(
control :in std_logic_vector(31 downto 0);
R,W, RW, PCc1,PCinc,PCc3:out std_logic;
ACCclear,MBR_MARc,PC_MARc:out std_logic;
ACC_MBRc,MBR_OPc,MBR_BRc:out std_logic;
CONTRout:out std_logic_vector(3 downto 0);
CARc :out std_logic_vector(3 downto 0);
CAR :out std_logic_vector(7 downto 0));
end CONTROLR;
architecture behave of CONTROLR is
begin
process(control)
begin
CAR<=control(7 downto 0);
PCc1<=control(8);
PCinc<=control(9);
PCc3<=control(10);
ACCclear<=control(11);
CONTRout<=control(15 downto 12);
R<=control(16);
W<=control(17);
MBR_MARc<=control(18);
PC_MARc<=control(19);
ACC_MBRc<=control(20);
MBR_OPc<=control(21);
MBR_BRc<=control(22);
CARc<=control(26 downto 23);
RW<=control(17);
end process;
end behave;
8, ALU (Arithmetic Logic Unit)
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
entity ALU is
port( clk,reset,ACCclear:in std_logic;
aluCONTR :in std_logic_vector(3 downto 0);
BR :in std_logic_vector(15 downto 0);
PCjmp :out std_logic;
ACC :buffer std_logic_vector(15 downto 0));
end ALU;
architecture behave of ALU is
begin
process(clk)
begin
if(clk'event and clk='0')then
if reset='0' then ACC<=x"0000";
else
if ACCclear='1' then ACC<=x"0000"; end if;
if aluCONTR="0011" then ACC<=BR+ACC; end if; --ADD
if aluCONTR="0100" then ACC<=ACC-BR; end if; --SUB
if aluCONTR="0110" then ACC<=ACC and BR; end if; --AND
if aluCONTR="0111" then ACC<=ACC or BR; end if; --OR
if aluCONTR="1000" then ACC<=not ACC; end if; --NOT
if aluCONTR="1001" then --SRR
ACC(14 downto 0)<=ACC(15 downto 1); ACC(15)<='0';
end if;
if aluCONTR="1010" then --SRL
ACC(15 downto 1)<=ACC(14 downto 0); ACC(0)<='0';
end if;
if aluCONTR="1011" then ACC<=ACC(7 downto 0)*BR(7 downto 0); end if; --MPY
end if;
end if;
if ACC>0 then PCjmp<='1';
else PCjmp<='0';
end if;
end process;
end behave;
9.LMP_ROM
LIBRARY ieee;
USE ieee.std_logic_1164.all;
LIBRARY altera_mf;
USE altera_mf.altera_mf_components.all; --使用宏功能库中的所有元件
ENTITY LMP_ROM IS
PORT (address : IN STD_LOGIC_VECTOR (7 DOWNTO 0);
inclock : IN STD_LOGIC ;
q : OUT STD_LOGIC_VECTOR (31 DOWNTO 0) );
END LMP_ROM;
ARCHITECTURE SYN OF LMP_ROM IS
SIGNAL sub_wire0 : STD_LOGIC_VECTOR (31 DOWNTO 0);
COMPONENT altsyncram --例化altsyncram元件,调用了LPM模块altsyncram
GENERIC ( --参数传递语句
intended_device_family : STRING; --类属参量数据类型定义
width_a : NATURAL;
widthad_a : NATURAL;
numwords_a : NATURAL;
operation_mode : STRING;
outdata_reg_a : STRING;
address_aclr_a : STRING;
outdata_aclr_a : STRING;
width_byteena_a : NATURAL;
init_file : STRING;
lpm_hint : STRING;
lpm_type : STRING );
PORT ( clock0 : IN STD_LOGIC ; --altsyncram元件接口声明
address_a: IN STD_LOGIC_VECTOR (7 DOWNTO 0);
q_a : OUT STD_LOGIC_VECTOR (31 DOWNTO 0) );
END COMPONENT;
BEGIN
q <= sub_wire0(31 DOWNTO 0);
altsyncram_component : altsyncram
GENERIC MAP ( intended_device_family => "Cyclone", --参数传递映射
width_a => 32, --数据线宽度8
widthad_a => 8, --地址线宽度6
numwords_a => 128, --数据数量64
operation_mode => "ROM", --LPM模式ROM
outdata_reg_a => "UNREGISTERED", --输出无锁存
address_aclr_a => "NONE", --无异步地址清0
outdata_aclr_a => "NONE", --无输出锁存异步清0
width_byteena_a => 1, -- byteena_a输入口宽度1
init_file => "./rom.mif", --ROM初始化数据文件,此处已修改过
lpm_hint => "ENABLE_RUNTIME_MOD=YES, INSTANCE_NAME=NONE",
lpm_type => "altsyncram" ) --LPM类型
PORT MAP (clock0 => inclock, address_a => address,q_a => sub_wire0 );
END SYN;
10.LMP_RAM
LIBRARY ieee;
USE ieee.std_logic_1164.all;
LIBRARY altera_mf;
USE altera_mf.altera_mf_components.all;
ENTITY LMP_RAM IS
PORT
(
address : IN STD_LOGIC_VECTOR (7 DOWNTO 0);
data : IN STD_LOGIC_VECTOR (15 DOWNTO 0);
inclock : IN STD_LOGIC := '1';
wren : IN STD_LOGIC ;
q : OUT STD_LOGIC_VECTOR (15 DOWNTO 0)
);
END LMP_RAM;
ARCHITECTURE SYN OF LMP_RAM IS
SIGNAL sub_wire0 : STD_LOGIC_VECTOR (15 DOWNTO 0);
BEGIN
q <= sub_wire0(15 DOWNTO 0);
altsyncram_component : altsyncram
GENERIC MAP (
clock_enable_input_a => "BYPASS",
clock_enable_output_a => "BYPASS",
init_file => "./sum100.mif",
intended_device_family => "Cyclone IV GX",
lpm_hint => "ENABLE_RUNTIME_MOD=NO",
lpm_type => "altsyncram",
numwords_a => 256,
operation_mode => "SINGLE_PORT",
outdata_aclr_a => "NONE",
outdata_reg_a => "UNREGISTERED",
power_up_uninitialized => "FALSE",
read_during_write_mode_port_a => "NEW_DATA_NO_NBE_READ",
widthad_a => 8,
width_a => 16,
width_byteena_a => 1
)
PORT MAP (
address_a => address,
clock0 => inclock,
data_a => data,
wren_a => wren,
q_a => sub_wire0
);
END SYN;