实验f4b 8位12指令微程序CPU设计
- rom.mif
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←4H
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
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,
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;
-
CPU电路图
-
一些操作的仿真波形
1, load, add, store, halt (22+10)
RAM中的内容:
0 : 022A; Load 2A
1 : 032B; ADD 2B
2 : 012C; Store 2C
3 : 0C00; Halt
2a : 0016;
2b : 000A;
RAM 中 2b 寻址的内容为 0020H
操作波形:
程序1波形图及逐条指令、逐个阶段、逐个操作、逐个部件逐个数据变化的对应关系分析,数据运算过程分析。
(详细分析可任选一条指令为例,必须结合测试波形、电路图、代码、指令系统设计具体说明,标注控制信号,地址,数据等信息的每一次流动、变化。)
开始时PC值为0,PC将指令地址通过地址总线传递给MAR。
在开始时由于CAR的值为0,然后会将CAR中的值0传入通过下图红线到rom中找出对应的微指令。
然后通过下图红线数据线将微指令传入到control中.
control获取指令,传递信号给MAR.
MAR从通过下图红线从ram(0)中取出指令022A.
再通过下数据总线传输到MBR中,其中02为操作码,2A为地址码
此时该CPU会将读信号R置为1,并且将CAR的值+1变为1,然后会将CAR中的值1像上述过程一样传入到rom中找出对应的微指令,并通过数据线将微指令传入到control中,所以该CPU会读取MBR 中存的操作码字段通过下图红线地址总线读出并存入到OP(IR)中并且将CAR的值+1变为1
此时CAR的值为2,然后会将CAR中的值2传入到rom中找出对应的微指令,并通过数据线将微指令传入到 control中,所以该CPU会执行CAR←CAR+OP操作,使得CAR的值变为04;然后会将CAR中的值4传入到rom中 找出对应的微指令,并通过数据线将微指令传入到control中,此时CAR的值为04,所以该CPU会执行 CAR←19,使得CAR的值变为19;此时CAR的值为19,然后会将CAR中的值19传入到rom中找出对应的微指令, 并通过数据线将微指令传入到control中,至此正式进入LOAD操作,先将MBR中地址码通过下图红线地址 总线传入到MAR中
然后ACC中的值和BR中的值相加并存回ACC使得ACC值为16,最后会将CAR的值+1;此时整个LOAD操作执行 完毕,CAR的值为1c,然后会将CAR中的值1c传入到rom中找出对应的微指令,并通过数据线将微指令传入 到control中,该CPU会将CAR中的值置零。通过以上操作就完成了 0 : 022A; Load 2A这条指令。此时PC值为1,PC中的值会通过地址总线传到MAR,然后从ram(1)中取出指令032B并通过数据总 线传输到MBR中,其中03为操作码,2B为地址码。并且在开始时由于CAR的值为0,然后会将CAR中的值0传 入到rom中找出对应的微指令,并通过数据线将微指令传入到control中,此时该CPU会将读信号R置为1, 并且将CAR的值+1变为1;此时CAR的值为1,然后会将CAR中的值1传入到rom中找出对应的微指令,并通过 数据线将微指令传入到control中,所以该CPU会读取MBR中存的操作码字段通过地址总线读出并存入到OP 中并且将CAR的值+1变为1;此时CAR的值为2,然后会将CAR中的值2传入到rom中找出对应的微指令,并通 过数据线将微指令传入到control中,所以该CPU会执行CAR←CAR+OP操作,使得CAR的值变为05;此时CAR 的值为05,然后会将CAR中的值5传入到rom中找出对应的微指令,并通过数据线将微指令传入到control 中,所以该CPU会执行CAR←1E,使得CAR的值变为1E;此时CAR的值为1E,然后会将CAR中的值1e传入到rom 中找出对应的微指令,并通过数据线将微指令传入到control中,至此正式进入ADD操作,先将MBR中地址 码通过地址总线传入到MAR中,然后将CAR的值+1;此时CAR的值为1f,然后会将CAR中的值1f传入到rom中 找出对应的微指令,并通过数据线将微指令传入到control中,此时CPU会执行PC+1的操作,并且将读信 号R置为1,最后将CAR的值+1;此时CAR的值为20,然后会将CAR中的值20传入到rom中找出对应的微指令, 并通过数据线将微指令传入到control中,该CPU会将MBR中的操作码对应的操作数000A通过数据总线传入 到BR中,然后ACC中的值和BR中的值相加并存回ACC使得ACC值为0020,最后会将CAR的值+1;此时整个ADD 操作执行完毕,CAR的值为21,然后会将CAR中的值21传入到rom中找出对应的微指令,并通过数据线将微 指令传入到control中,该CPU会将CAR中的值置零。
2, load, SUB, store, halt (22-10)
The contents in RAM:
0 : 022A; Load 2A
1 : 042B; SUB 2B
2 : 012C; Store 2C
3 : 0C00; Halt
2a : 0016;
2b : 000A;
The content in RAM addressed of 2c is 000C(H).
The waveform of the operate:
指令操作过程基本和上面加法指令一致,不同点在于042B的操作码OP为04加上CAR上的02为06,此时CAR 的值为06,然后会将CAR中的值6传入到rom中找出对应的微指令,并通过数据线将微指令传入到control 中,所以该CPU会执行CAR←23,使得CAR的值变为23;此时CAR的值为23,然后会将CAR中的值23传入到rom 中找出对应的微指令,并通过数据线将微指令传入到control中,至此正式进入SUB操作,先将MBR中地址 码通过地址总线传入到MAR中,然后将CAR的值+1;此时CAR的值为24,然后会将CAR中的值24传入到rom中 找出对应的微指令,并通过数据线将微指令传入到control中,此时CPU会执行PC+1的操作,并且将读信号 R置为1,最后将CAR的值+1;此时CAR的值为25,该CPU会将MBR中的操作码对应的操作数000A通过数据总 线传入到BR中,然后ACC中的值和BR中的值相减并存回ACC使得ACC值为000C,最后会将CAR的值+1;此时 整个SUB操作执行完毕,CAR的值为26,然后会将CAR中的值26传入到rom中找出对应的微指令,并通过数 据线将微指令传入到control中,该CPU会将CAR中的值置零。
3, Sum from 1 to 100
The contents in RAM are shown in table2.
The content in RAM addressed of A4 is 13BA(H).
The waveform of the operate:
The clock cycle of CAR is 400 ns.
From the waveform, it takes 2.314ms to execute the operate. So the number of the executing cycles is 2.134/0.0004=5335.
程序4波形图及逐条指令、逐个阶段、逐个操作、逐个部件逐个数据变化的对应关系分析,数据运算过程分析。(必做)
以第一个循环的ADD A3指令为例,此时PC值为05,PC的值通过地址总线传到MAR,然后从ram中取出指令03A3并通过数据总线传输到MBR中。开始时由于CAR的值为0,然后会将CAR中的值0传入到rom中找出对应的微指令,并通过数据线将微指令传入到control中,此时该CPU会将读信号R置为1,并且将CAR的值+1变为1;此时CAR的值为1,然后会将CAR中的值1传入到rom 中找出对应的微指令,并通过数据线将微指令传入到control中,所以该CPU会读取MBR中存的操作码字段 通过地址总线读出并存入到OP中并且将CAR的值+1变为1;此时CAR的值为2,然后会将CAR中的值2传入到 rom中找出对应的微指令,将微指令传入到control,所以CPU会执行CAR←CAR+OP操作,使得CAR的值变为05;此时CAR的值为05,然后会将CAR中的值5传入到rom中找出对应的微指令,并通过数 据线将微指令传入到control中,所以该CPU会执行CAR←1E,使得CAR的值变为1E;此时CAR的值为1E,然 后会将CAR中的值1e传入到rom中找出对应的微指令,并通过数据线将微指令传入到control中,至此正式 进入ADD操作,先将MBR中地址码通过地址总线传入到MAR中,然后将CAR的值+1;此时CAR的值为1f,然后会将CAR中的值1f传入到rom中找出对应的微指令,并通过数据线将微指令传入到control中,此时CPU会 执行PC+1的操作,并且将读信号R置为1,最后将CAR的值+1;此时CAR的值为20,然后会将CAR中的值20传 入到rom中找出对应的微指令,并通过数据线将微指令传入到control中,该CPU会将MBR中的操作码对应 的操作数0064通过数据总线传入到BR中,然后ACC中的值和BR中的值相加并存回ACC使得ACC值为0064,最 后会将CAR的值+1;此时整个ADD操作执行完毕,CAR的值为21,然后会将CAR中的值21传入到rom中找出对 应的微指令,并通过数据线将微指令传入到control中,该CPU会将CAR中的值置零。
-
(I)The GDF of CPU:
-
(II) 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
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
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*BR; end if; --MPY
end if;
end if;
if ACC>0 then PCjmp<='1';
else PCjmp<='0';
end if;
end process;
end behave;