综合性比较强的大实验,先是在实验室完成前面三个小实验,最后再三个结合完成最后的16位CPU的设计,需要软硬件结合一起。











部分代码如下:
process(RST, CLK)
begin
if RST = '0' then state <= 0; a<="0000000000000000"; b<="0000000000000000"; opCode<="0000"; output <= (others=>'0'); stateCnt <= not "0000000";
elsif CLK'event and CLK = '1' then
case state is
when 0 => state <= 1; a <= INPUT; stateCnt <= not "1000000";OUTPUT<=a;
when 1 => state <= 2; b <= INPUT; stateCnt <= not "1111001";OUTPUT<=b;
when 2 => state <= 3; opCode <= input(3 downto 0); stateCnt <= not "0100100"; OUTPUT <= input;
when 3 => state <= 4; OUTPUT<= y; stateCnt <= not "0110000";
when 4 => state <= 0; output<= outout; stateCnt <= not "0011001";
end case;
end if;
end process;
process(RST, opCode)
begin
cflag <= '0';
oflag <= '0';
zflag <= '0';
sflag <= '0';
case opCode is
-- 加法
when "0000" => y<= a + b;
if(y = "0000000000000000") then
zflag <= '1';
end if;
if(a(15) = '1' and b(15) = '1') then
cflag <= '1';
if(y(15) = '0') then
oflag <= '1';
end if;
end if;
if(a(15) = '0' and b(15) = '0' and y(15) = '1') then
oflag <= '1';
end if;
if(y(15) = '1') then
sflag <= '1';
end if;
temp <= "1111111111111111" - a;
if(b > temp) then
cflag <= '1';
end if;
-- 减法
when "0001" => y<= a + (not b) + 1;
if(y(15) = '1') then
sflag <= '1';
end if;
if(y = "0000000000000000") then
zflag <= '1';
end if;
temp <= (not b) + 1;
if(a(15) = '1' and temp(15) = '1') then
cflag <= '1';
if(y(15) = '0') then
oflag <= '1';
end if;
end if;
if(a(15) = '0' and temp(15) = '0' and y(15) = '1') then
oflag <= '1';
end if;
if(a < b) then
cflag <= '1';
end if;
-- 加减,逻辑与,或,亦或,非,逻辑、循环、算数
when "0010" => y<= a and b;
if(y(15) = '1') then
sflag <= '1';
end if;
if(y = "0000000000000000") then
zflag <= '1';
end if;
when "0011" => y<= a or b;
if(y(15) = '1') then
sflag <= '1';
end if;
if(y = "0000000000000000") then
zflag <= '1';
end if;
when "0100" => y<= a xor b;
if(y(15) = '1') then
sflag <= '1';
end if;
if(y = "0000000000000000") then
zflag <= '1';
end if;
when "0101" => y<= not a;
if(y(15) = '1') then
sflag <= '1';
end if;
if(y = "0000000000000000") then
zflag <= '1';
end if;
-- 逻辑
when "0110" => y<= to_stdlogicvector(to_bitvector(a) sll conv_integer(b));
when "0111" => y<= to_stdlogicvector(to_bitvector(a) srl conv_integer(b));
-- 算数
when "1000" => y<= to_stdlogicvector(to_bitvector(a) sll conv_integer(b));
when "1001" => y<= to_stdlogicvector(to_bitvector(a) sra conv_integer(b));
-- 循环
when "1010" => y<= to_stdlogicvector(to_bitvector(a) rol conv_integer(b));
when "1011" => y<= to_stdlogicvector(to_bitvector(a) ror conv_integer(b));
-- when "0010" => y<= a + b + Cin;
-- when "0011" => y<= a - b - Cin;
3.实验拓展(实现ADC和SBB指令,已经验收通过)
-- ADC(带进位加)
初始进位,A异或B异或C(三个里面有奇数个1则为1),向高一位的进位,AB或AC或BC(至少有两个1则有进位)
when "1100" => y<= a + b+cflag;
if(y = "0000000000000000") then
zflag <= '1';
end if;
if(a(15) = '1' and b(15) = '1') then
cflag <= '1';
if(y(15) = '0') then
oflag <= '1';
end if;
end if;
if(a(15) = '0' and b(15) = '0' and y(15) = '1') then
oflag <= '1';
end if;
if(y(15) = '1') then
sflag <= '1';
end if;
temp <= "1111111111111111" - a;
if(b > temp) then
cflag <= '1';
end if;
-- SBB带借位减(A-B-C)
初始借位,A异或B异或C(三个里面有奇数个1则为1),向高一位的借位,(BC均为1或BC有一个为1同时A为0就要借位即借位为1)
when "1101" => y<= a + (not b) -cflag;
if(y(15) = '1') then
sflag <= '1';
end if;
if(y = "0000000000000000") then
zflag <= '1';
end if;
temp <= (not b) + 1;
if(a(15) = '1' and temp(15) = '1') then
cflag <= '1';
if(y(15) = '0') then
oflag <= '1';
end if;
end if;
if(a(15) = '0' and temp(15) = '0' and y(15) = '1') then
oflag <= '1';
end if;
if(a < b) then
cflag <= '1';
end if;
when others=> y<="0000000000000000";
end case;
outout(15) <= oflag;
outout(14) <= cflag;
outout(13) <= zflag;
outout(12) <= sflag;
end process;

三、综合实验总结
1.实验难点
(1) 在输出标志位时,如何通过操作数和操作结果判断标志位:
(2)在判断进位标志位cFlags时,需要仔细考虑指令对标志位的影响和影响的原理,尤其是ADC指令和SBB指令,需要记录每一位的进位并利用循环结构得到最终结果和进位标志位(类似全加器原理)。
(3)在判断溢出标志位oFlags时,要灵活掌握操作数和运算结果之间符号位的变化与OF标志位的关系,以便正确设置标志位。
(4)在进行移位运算时,要将需要被移位的操作数(即A)的数据类型转换为位矢量类型后才可以移位,将移位操作数转换成整数。
2.心得体会
略
四、思考题
(1)ALU进行算术逻辑运算所使用的电路是组合逻辑电路还是时序逻辑电路?
答:组合逻辑电路,没有记忆功能,此时刻输入只取决于此时刻输出。
(2)如果给定了A和B的初值,且每次运算完后结果都写入到B中,再进行下次运算。这样一个带暂存功能的ALU要增加一些什么电路来实现?
答: 增加暂存器TMP和累加器AC。




六.部分代码展示
begin
process(RST,ctrl_r)
begin
if RST='0' then
ctrl_state<=N;
elsif rising_edge(ctrl_r)then
case ctrl_state is
when N=>
ctrl_state<=W;
when W=>
ctrl_state<=R;
when R=>
ctrl_state<=W;
end case;
end if;
end process;
process(RST,CLK,ctrl_state)
begin
if RST='0' then
tmp_data<=x"0000";
tmp_read_addr<=x"0000";
tmp_addr<=x"0000";
to_light<=x"0000";
RAM1_EN<='1';
RAM1_OE<='0';
RAM1_We<='0';
address_state<=waiting;
write_state<=waiting;
read_state<=waiting;
elsif rising_edge(CLK) then
case ctrl_state is
when N=>
ADDR<=Input_data;
SEG <= not"1000000";
tmp_addr<=Input_data;
tmp_read_addr<=Input_data;
when W=>
case write_state is
when waiting =>
address_state<=waiting ;
write_state<=start;
read_state<=waiting;
SEG <= not"1000000";
when start=>
--tmp_data<=Input_data;
ADDR<=tmp_addr;
DATA<=Input_data;
RAM1_EN<='0';
RAM1_OE<='1';
RAM1_We<='0';
SEG<=not"1111001";
write_state<=over;
when over=>
write_state<=waiting;
tmp_addr<=tmp_addr+1;
SEG <= not "0100100";
end case;
when r=>
case read_state is
when waiting=>
address_state<=waiting;
read_state<=start;
write_state<=waiting;
SEG <= not"1000000";
when start=>
RAM1_EN<='0';
RAM1_OE<='1';
RAM1_We<='1';
ADDR<=tmp_read_addr;
DATA<=(others=>'Z');
read_state<=read;
SEG<=not"1111001";
when read=>
RAM1_OE<='0';
RAM1_We<='1';
to_light<=DATA;
SEG <=not "0100100";
read_state<=over;
when over=>
SEG <= not"0110000";
read_state<=waiting;
tmp_read_addr<=tmp_read_addr+1;
end case;
end case;
end if;
dbc<='1';
end process;
light<=to_light;
end Behavioral;
三、综合实验总结
1.实验难点
略
2.心得体会
略
四、思考题
静态存储器的读、写时序各有什么特点?
答:如图所示,特点如下:





3.部分代码展示
architecture Behavioral of unit is
signal bzero : std_logic;(布尔)------------------------
type shower_state is (PC,ALU,Mem,Reg);--------枚举类型,有四种状态---计数,加法器,内存,寄存器
signal shower : shower_state;--------------------
type controler_state is
(instruction_fetch,decode,execute,mem_control,write_reg);
signal state : controler_state;
signal PCWrite : std_logic;-------------------是否改写PC
signal PCWriteCond : std_logic;--------------------转移指令的条件
signal PCSource : std_logic;------------------------新的PC来源选择
signal ALUOp : std_logic_vector(1 downto 0);-----ALU运算功能选择
signal ALUSrcA : std_logic;---------------------------ALU源操作数A的选择
signal ALUSrcB : std_logic_vector(1 downto 0);
signal MemRead : std_logic;--------------------------是否读寄存器
signal MemWrite : std_logic;--------------------------是否写寄存器
signal IRWrite : std_logic;-----------------------------写IR
signal MemtoReg : std_logic_vector(1 downto 0);---写入寄存器堆的数据来源选择
signal RegWrite : std_logic_vector(2 downto 0);------写寄存器控制
signal RegDst : std_logic_vector(1 downto 0);--------选择目的寄存器
signal IorD : std_logic;-----------------存储器地址来源
signal tmpb_zero : std_logic;
signal tmp_light : std_logic_vector(15 downto 0);
begin
light <= tmp_light;----灯
process(clk,rst,showCtrl)---------按钮
begin
if rst='0' then
shower<=PC;
elsif rising_edge(showCtrl) then-----按
case shower is -----跳转四个状态
when PC=>
shower<=ALU;
when ALU=>
shower<=Mem;
when Mem=>
shower<=Reg;
when Reg=>
shower<=PC;
end case;
end if;
end process;
process(clk0,rst,state)
begin
if rst='0' then
tmp_light<=x"0000";
elsif rising_edge(clk0) then
case shower is
when PC=>
tmp_light(15 downto 0)<=x"0000";
tmp_light(15)<=PCWrite;
tmp_light(11)<=PCSource;
tmp_light(7)<=PCWriteCond;
when ALU=>
tmp_light(15 downto 0)<=x"0000";
tmp_light(15 downto 14)<=ALUOp;
tmp_light(11)<=ALUSrcA;
tmp_light(7 downto 6)<=ALUSrcB;
when Mem=>
tmp_light(15 downto 0)<=x"0000";
tmp_light(15)<=MemRead;
tmp_light(11)<=MemWrite;
tmp_light(7)<=IRWrite;
tmp_light(3 downto 2)<=MemtoReg;
when Reg=>
tmp_light(15 downto 0)<=x"0000";
tmp_light(15 downto 13)<=RegWrite;
tmp_light(11 downto 10)<=RegDst;
tmp_light(7)<=IorD;
end case;
end if;
end process;
process(rst,bzero_Ctrl)
begin
if rst = '0' then
bzero<='0';
elsif rising_edge (bzero_Ctrl) then
if bzero <= '0' then
bzero <= '1';
tmpb_zero<='0';
elsif bzero = '1' then
tmpb_zero<='1';
bzero<='0';
end if;
end if;
end process;
process (bzero)
begin
if bzero = '1' then
PCWriteCond<='1';
elsif bzero = '0' then
PCWriteCond<='0';
end if;
end process;
process (rst,clk)
begin
if(rst = '0') then
state<=instruction_fetch;
IorD<='0';
IRWrite<='0';
MemRead<='0';
MemWrite<='0';
MemtoReg<="00";
ALUOp<="00";
ALUSrcA<='0';
ALUSrcB<="00";
PCWrite<='0';
PCSource<='0';
RegDst<="00";
RegWrite<="000";
elsif rising_edge (clk) then
case state is
when instruction_fetch=>--------------取指
MemRead<='1';
ALUSrcA<='0';
IorD<='0';
ALUSrcB<="01";
ALUOp<="00";
PCWrite<='1';
PCSource<='0';
IRWrite<='1';
RegWrite<="000";
state<=decode;
when decode=>----------------译码
IRWrite<='0';
MemRead<='0';
PCWrite<='0';
ALUSrcA<='0';
ALUSrcB<="10";
ALUOp<="00";
state<=execute;
when execute=>---------------执行
case instructions(15 downto 11) is
when "00100" =>
ALUSrcA<='1';
ALUOp<="10";
PCSource<='1';
state<=instruction_fetch;
when "10011"=>
ALUSrcA<='1';
ALUSrcB<="10";
ALUOp<="00";
state<=mem_control;
when "11011"=>
ALUSrcA<='1';
ALUSrcB<="10";
ALUOp<="00";
state<=mem_control;
when "11100" =>
case instructions (1 downto 0) is
when "01" => -----addu
ALUSrcA<='1';
ALUSrcB<="00";
ALUOp<="00";
when "11" => -----subu
ALUSrcA<='1';
ALUSrcB<="00";
ALUOp<="01";
when others =>
null;
end case;
state <=write_reg;
when "11101" =>
case instructions(4 downto 0) is
when "01101" =>
ALUSrcA<='1';
ALUSrcB<="00";
ALUOp<="10";
state<=write_reg;
when "00000" =>
case instructions(7 downto 5) is
when "000"=>
ALUSrcA<='1';
ALUOp<="10";
PCWrite<= '1';
PCSource <= '0';
state<= instruction_fetch;
when others=>
null;
end case;
when others =>
null;
end case;
when others=>
null;
end case;
when mem_control =>---------------访存
PCWrite<= '0';
RegWrite<="000";
case instructions(15 downto 11) is
when "10011" =>
MemRead <= '1';
IorD <= '1';
state <= write_reg;
when "11011" =>
MemWrite <= '1';
IorD <= '1';
state <= write_reg;
when others =>
null;
end case;
when write_reg=>----------------写入
Memwrite <= '0';
MemRead <= '0';
case instructions (15 downto 11) is
when "10011" =>
RegDst <= "10";
RegWrite <= "001";
MemtoReg <= "01";
when "11011" =>
MemWrite <= '0';
IorD <= '0';
when "11100" =>
case instructions (1 downto 0) is
when "01" =>
RegDst<= "01";
RegWrite<= "001";
MemtoReg <= "00";
when "11" =>
RegDst <="01";
RegWrite<= "001";
MemtoReg <= "00";
when others =>
null;
end case;
when "11101" =>
case instructions (4 downto 0) is
when "01101"=>
RegDst <="00";
RegWrite<= "001";
MemtoReg <= "00";
when others =>
null;
end case;
when others=>
null;
end case;
state <= instruction_fetch;
end case;
end if;
end process;
end Behavioral;
三.执行阶段实现的七条指令
七条指令分别为:ADDU SUBU BNEZ JR OR LW SW。
前面演示了取值,译码,到执行的时候,需要参考实验书上的131页到133页的七条指令格式的设计,这时候对应的代码会有指令的指示跳转到各自的指令执行的地方,LED灯会有各自的位置亮起。至于指令的数据通路和解释,将在下一个实验CPU中给出。
下面给出实验时候执行阶段手写的指令:

四.实验截图
红色部分是演示时候LED灯亮的位置
黄色部分是执行阶段输入的指令代表的数字
蓝色部分三个按钮有重置,跳转状态(ALU,Mem,Reg,PC),跳转周期(取值,译码,执行,访存,写回)的功能,即CLK,RST和右边第一个红色小按钮。

四、综合实验总结
1.实验难点
略
2.心得体会
略
实验四 16位CPU设计实验
一、目的与要求
实现一个基于MIPS指令集的CPU,数据总线16位,地址总线16位,具有8个16位的通用寄存器。指令包括访存指令(如LW,SW),传送指令(如LI,MOVE),算术运算指令(如ADDU,SUBU),逻辑运算指令(NOT,OR),移位运算指令(如SLL),具体指令见实验指导书P23-P32。
具体要求:
(1)完成7条指令,必须包括访存指令LW和SW,其余每类指令最多2条。
(2)按照取指、译码、执行、访存和写回五个工作周期,分析每条指令的指令流程。
(3)根据指令流程,设计每条指令的CPU数据通路,定义涉及的所有微操作控制信号。然后逐一合并数据通路,说明增加或减少处理器功能部件的理由。给出控制器的完整设计过程。
(4)编写VHDL程序实现CPU,并通过实验板验证。
二、实验正文
1.实验内容
(1)实现一个基于MIPS指令集的多周期CPU
(2)设计完成7条指令,必须包括访存指令LW和SW,其余每类指令最多2条
(3)按照取指、译码、执行、访存和写回五个工作周期,分析每条指令的指令流程
(4)根据指令流程,设计每条指令的CPU数据通路,定义涉及的所有微操作控制信号。然后逐一合并数据通路,说明增加或减少处理器功能部件的理由。给出控制器的完整设计过程。
(5)编写VHDL程序实现CPU,并通过实验板验证。
(6)给出完整的设计报告,包括基本部件设计,如寄存器组、特殊寄存器、多路选择器等;每一条指令的数据通路图,以及CPU总数据通路图;控制器的设计等。





(2)SUBU

数据通路分析过程:
①取指令阶段:需要从程序寄存器PC中取出当前指令地址送给指令存储器InstructionMemory的地址输入端,然后从指令存储器数据输出端口得到指令内容以便下一周期译码,同时要将PC当前内容加2送给PC寄存器,使其指向下一条指令。
②译码阶段:需要从指令中得到Rs寄存器和Rt寄存器的编号,送给寄存器组RegisterFiles的Ra和Rb输入端,从输出端A、B取出其中内容即源操作数,送给运算器输入端以便于下一步进行减法运算,同时需要从指令中取出Rd寄存器编号送给寄存器组Rw输入端作为目的地址,以便之后将运算器运算结果送给寄存器组的输入端W,写入寄存器Rd。
③计算阶段:A、B通过运算部件ALU进行减法运算。
④写回寄存器阶段:将ALU输出端得到的运算结果送给寄存器组的输入端W,写入寄存器Rd。
控制信号:
RegWrite:由于加法功能需要读出寄存器Ra和Rb的内容还需要向Rw寄存器写入内容,所以需要增加一个控制信号控制寄存器组的读/写。
ALUop:由于ALU的功能有多种,故增加一个控制信号控制ALU功能选择。
(3)LW
①取指令阶段:需要从程序寄存器PC中取出当前指令地址送给指令存储器InstructionMemory的地址输入端,然后从指令存储器数据输出端口得到指令内容以便下一周期译码,同时将PC加2送给PC,指向下一条指令。
②译码阶段:需要从指令中的第11位到第9位取出Rs寄存器编号送给寄存器组Ra输入端,从输出端A取出Rs寄存器内容送给运算器A输入端,第5位到第0位取出6位立即数经过扩展送给运算器B输入端,同时还要将指令第8位到第6位送给Rw输入端作为目的寄存器编号。
③计算阶段:A、B输入的内容送给运算器进行加法运算。
④读存储器:ALU输出内容送给数据存储器地址输入端addr。
⑤写回寄存器:数据存储器数据输出端D送给寄存器组数据写入端W,根据Rw中存放的Rt寄存器编号,将数据写入Rt寄存器。
控制信号:
ALUop:控制选择ALU功能为加法。
ALUsrcB:控制选择运算器B输入端的内容来源,本指令中来源于指令低6位扩展到16位后的立即数。
RegWrite:控制寄存器组的读出和写入。
RegDsrc:控制选择寄存器组Rw输入端的来源,本指令中应选择指令8到6位作为寄存器编号。
Jump、PCsource:控制下一条指令的转移。
RWmem:控制数据存储器的读出和写入。
Wsrc:控制选择写入寄存器的数据来源,本指令来源于数据存储器输出数据。

(4)SW
数据通路分析过程:
①取指令阶段:需要从程序寄存器PC中取出当前指令地址送给指令存储器InstructionMemory的地址输入端,然后从指令存储器数据输出端口得到指令内容以便下一周期译码,同时将PC加2送给PC,指向下一条指令。
②译码阶段:需要从指令中的第11位到第9位取出Rs寄存器编号送给寄存器组Ra输入端,从输出端A取出Rs寄存器内容送给运算器A输入端,第5位到第0位取出6位立即数经过扩展送给运算器B输入端,同时还要将指令第8位到第6位送给Rb输入端作为输入数据寄存器编号。
③计算阶段:运算器对A、B输入的内容进行加法运算,运算后结果为目的地址需要送给数据存储器地址端addr。
④读寄存器:寄存器组B输出端内容输入数据,将其送给数据存储器数据输入端W。
⑤写回存储器:将数据存储器输入端W的数据写入目的地址addr。
控制信号:
ALUop:控制选择ALU功能为加法。
ALUsrcB:控制选择运算器B输入端的内容来源,本指令中来源于指令低6位扩展到16位后的立即数。
RegWrite:控制寄存器组的读出和写入。
Jump、PCsource:控制下一条指令的转移。
RWmem:控制数据存储器的读出和写入。
Wsrc:控制选择写入寄存器的数据来源,本指令来源于数据存储器输出数据。

(5)ADDIU
数据通路分析过程:
①取指令阶段:需要从程序寄存器PC中取出当前指令地址送给指令存储器InstructionMemory的地址输入端,然后从指令存储器数据输出端口得到指令内容以便下一周期译码,同时将PC加2送给PC,指向下一条指令。
②译码阶段:需要从指令中的第11位到第9位取出Rs寄存器编号送给寄存器组Ra输入端,从输出端A取出Rs寄存器内容送给运算器A输入端,第11位到第9位取出Rs寄存器编号还要送给Rw输入端作为运算后的目的寄存器编号,取出指令的8到0位送给运算器B输入端,。
③计算阶段:A、B输入的内容送给运算器进行加法运算。
④写回阶段:ALU输出内容送给寄存器组W输入端写回Rw所存的编号的寄存器。
控制信号:
ALUop:控制选择ALU功能为加法。
ALUsrcB:控制选择运算器B输入端的内容来源,本指令中来源于指令低9位扩展到16位后的立即数。
RegWrite:控制寄存器组的读出和写入。
RegDsrc:控制选择寄存器组Rw输入端的来源,本指令中应选择指令11到9位作为寄存器编号。
Jump、PCsource:控制下一条指令的转移。


(6)B

数据通路分析过程:
①取指令阶段:需要从程序寄存器PC中取出当前指令地址送给指令存储器InstructionMemory的地址输入端,然后从指令存储器数据输出端口得到指令内容以便下一周期译码。
②译码阶段:需要从指令中的低12位扩展成16位与当前PC内容相加送回PC。
控制信号:
Jump:由于PC的值和当前执行指令有关,故增加一个控制信号Jump通过一个多路选择器控制PC的选择。
(7)JR

数据通路分析过程:
①取指令阶段:需要从程序寄存器PC中取出当前指令地址送给指令存储器InstructionMemory的地址输入端,然后从指令存储器数据输出端口得到指令内容以便下一周期译码。
②译码阶段:需要从指令中的第11位到第9位取出Rs寄存器编号送给寄存器组Ra输入端,从输出端A取出Rs寄存器内容以便下一步根据指令功能通过运算器运算。
③计算阶段:寄存器取出的内容送给ALU输入端A,通过ALUop控制信号选择直接输出源操作数A的功能。
④写回阶段:ALU输出内容送给PC。
控制信号:
RegWrite:由于需要将读出Rs寄存器内容,所以需要一个寄存器读信号,将内容从寄存器组输出端口A输出。
ALUop:此指令运算器需要新的功能,故用ALUop信号控制运算器功能选择,这条指令中应该选择输出Y=A。
PCsource:PC的内容又增加了新的选择,故需要一个OPsource信号通过多路选择器控制PC的输入选择。
(5)根据CPU总数据通路图设计控制器:列出控制信号表格以及每条指令在每个指令周期控制信号的值,完成控制器完整设计:





(7)部分代码展示
process(RST,showCtrl) -----状态转换
begin
if RST = '0' then
State_show <= PC;
stateCnt_L <= "0111001";
elsif showCtrl'event and showCtrl = '1' then
case State_show is
when PC =>
stateCnt_L <= "0000110";
State_show <= ALU;
when ALU =>
stateCnt_L <= "1011011";
State_show <= M;
when M =>
stateCnt_L <= "1001111";
State_show <= REG;
when REG =>
stateCnt_L <= "1100110";
State_show <= PC;
end case;
end if;
end process;
......
when decode =>
stateCnt_R <= "1011011";
AluSrcA <= '0';
ALUSrcB <= "10";
ALUOp <= "00";
MemRead <= '0';
IRWrite <= '0';
PcWrite <= '0';
CU_state <= execute;
case instruction(15 downto 11) is
when "11100" =>
rx <= instruction(10 downto 8);
ry <= instruction(7 downto 5);
rz <= instruction(4 downto 2);
when "00100" => --BEQZ
rx <= instruction(10 downto 8);
IMD <= instruction(7 downto 0);
when "11101" =>
case instruction(4 downto 0) is
when "00000" => --JR
rx <= instruction(10 downto 8);
when "01110" => --XOR
rx <= instruction(10 downto 8);
ry <= instruction(7 downto 5);
when others =>
null;
end case;
when "10011" => --LW
rx <= instruction(10 downto 8);
ry <= instruction(7 downto 5);
im <= instruction(4 downto 0);
when "11011" => --SW
rx <= instruction(10 downto 8);
ry <= instruction(7 downto 5);
im <= instruction(4 downto 0);
when others =>
null;
end case;
when execute =>
stateCnt_R <= "1001111";
control_state <= 0;
case instruction(15 downto 11) is
when "11100" =>
if instruction(1 downto 0) = "01" then --ADDU
ALUSrcA <= '1';
ALUSrcB <= "00";
ALUOp <= "00";
elsif instruction(1 downto 0) = "11" then --SUBU
ALUSrcA <= '1';
ALUSrcB <= "00";
ALUOp <= "01";
end if;
CU_state <= write_reg;
when "00100" => --BEQZ
ALUSrcA <= '1';
ALUOp <= "10";
PCSource <= '1';
CU_state <= instruction_fetch;
when "11101" =>
case instruction(4 downto 0) is
when "00000" => --JR
ALUSrcA <= '1';
ALUOp <= "10";
PcWrite <= '1';
PCSource <= '0';
CU_state <= instruction_fetch;
when "01110" => --XOR
ALUSrcA <= '1';
ALUSrcB <= "00";
ALUOp <= "10";
CU_state <= write_reg;
when others =>
null;
end case;
when "10011" => --LW
ALUSrcA <= '1';
ALUSrcB <= "10";
ALUOp <= "00";
CU_state <= write_reg;
when "11011" => --SW
ALUSrcA <= '1';
ALUSrcB <= "10";
ALUOp <= "00";
CU_state <= write_reg;
when others =>
null;
end case;
when mem_control =>
stateCnt_R <= "1100110";
case instruction(15 downto 11) is
when "10011" => --LW
RegWrite <= "000";
MemRead <= '1';
IorD <= '1';
PcWrite <= '0';
case control_state is
when 2 =>
RAM1_EN <= '0';
RAM1_OE <= '1';
RAM1_WE <= '1';
DATA(4 downto 0) <= DATA(4 downto 0) + im;
tmp_read_addr <= DATA;
CU_state <= mem_control;
control_state <= 3;
when 3 =>
ADDR <= tmp_read_addr;
DATA <= (others=>'Z');
RAM1_OE<='0';
RAM1_WE<='1';
CU_state <= write_reg;
control_state <= 4;
when others =>
null;
end case;
when "11011" => --SW
RegWrite <= "000";
MemWrite <= '1';
IorD <= '1';
PcWrite <= '0';
case control_state is
when 4 =>
RAM1_EN <= '0';
RAM1_OE <= '1';
RAM1_WE <= '1';
DATA(4 downto 0) <= DATA(4 downto 0) + im;
tmp_addr <= DATA;
CU_state <= mem_control;
control_state <= 5;
when 5 =>
ADDR <= tmp_addr;
DATA <= tmp_data;
RAM1_WE<='0';
RAM1_OE<='1';
CU_state <= write_reg;
control_state <= 0;
when others =>
null;
end case;
when others =>
null;
end case;
when write_reg =>
stateCnt_R <= "1101101";
case instruction(15 downto 11) is
when "11100" =>
case instruction(1 downto 0) is
when "01" => --ADDU
RegDst <= "01";
RegWrite <= "001";
MemtoReg <= "00";
MemRead <= '0';
MemWrite <= '0';
case control_state is
when 0 =>
RAM1_EN <= '0';
RAM1_OE <= '1';
RAM1_WE <= '1';
tmp_addr1 <= "0000000000000000";
tmp_read_addr1 <="0000000000000000";
tmp_read_addr1(2 downto 0) <= rx;
CU_state <= write_reg;
control_state <= 1;
when 1 =>
ADDR <= tmp_read_addr1;
DATA <= (others=>'Z');
RAM1_OE<='0';
RAM1_WE<='1';
CU_state <= write_reg;
control_state <= 2;
when 2 =>
RAM1_EN <= '0';
RAM1_OE <= '1';
RAM1_WE <= '1';
tmp_data1 <= DATA;
tmp_read_addr1<="0000000000000000";
tmp_read_addr1(2 downto 0) <= ry;
CU_state <= write_reg;
control_state <= 3;
when 3 =>
ADDR <= tmp_read_addr1;
DATA <= (others=>'Z');
RAM1_OE<='0';
RAM1_WE<='1';
CU_state <= write_reg;
control_state <= 4;
when 4 =>
RAM1_EN <= '0';
RAM1_OE <= '1';
RAM1_WE <= '1';
tmp_data1 <= DATA + tmp_data1;
tmp_addr1(2 downto 0) <= rz;
CU_state <= write_reg;
control_state <= 5;
when 5 =>
ADDR <= tmp_addr1;
DATA <= tmp_data1;
RAM1_WE<='0';
RAM1_OE<='1';
CU_state<=instruction_fetch;
control_state <= 0;
when others =>
null;
end case;
when "11" => --SUBU
RegDst <= "01";
RegWrite <= "001";
MemtoReg <= "00";
MemRead <= '0';
MemWrite <= '0';
case control_state is
when 0 =>
RAM1_EN <= '0';
RAM1_OE <= '1';
RAM1_WE <= '1';
tmp_addr<="0000000000000000";
tmp_read_addr<="0000000000000000";
tmp_read_addr(2 downto 0) <= rx;
CU_state <= write_reg;
control_state <= 1;
when 1 =>
ADDR <= tmp_read_addr;
DATA <= (others=>'Z');
RAM1_OE<='0';
RAM1_WE<='1';
CU_state <= write_reg;
control_state <= 2;
when 2 =>
RAM1_EN <= '0';
RAM1_OE <= '1';
RAM1_WE <= '1';
tmp_data <= DATA;
tmp_read_addr<="0000000000000000";
tmp_read_addr(2 downto 0) <= ry;
CU_state <= write_reg;
control_state <= 3;
when 3 =>
ADDR <= tmp_read_addr;
DATA <= (others=>'Z');
RAM1_OE<='0';
RAM1_WE<='1';
CU_state <= write_reg;
control_state <= 4;
when 4 =>
RAM1_EN <= '0';
RAM1_OE <= '1';
RAM1_WE <= '1';
tmp_data <= tmp_data - DATA;
tmp_addr(2 downto 0) <= rz;
CU_state <= write_reg;
control_state <= 5;
when 5 =>
ADDR <= tmp_addr;
DATA <= tmp_data;
RAM1_WE<='0';
RAM1_OE<='1';
CU_state <=instruction_fetch;
control_state <= 0;
when others =>
null;
end case;
when others =>
null;
end case;
when "11101" => --XOR
RegDst <= "00";
RegWrite <= "001";
MemtoReg <= "00";
MemRead <= '0';
MemWrite <= '0';
case control_state is
when 0 =>
RAM1_EN <= '0';
RAM1_OE <= '1';
RAM1_WE <= '1';
tmp_addr <= "0000000000000000";
tmp_read_addr <="0000000000000000";
tmp_read_addr(2 downto 0) <= rx;
CU_state <= write_reg;
control_state <= 1;
when 1 =>
ADDR <= tmp_read_addr;
DATA <= (others=>'Z');
RAM1_OE<='0';
RAM1_WE<='1';
CU_state <= write_reg;
control_state <= 2;
when 2 =>
RAM1_EN <= '0';
RAM1_OE <= '1';
RAM1_WE <= '1';
tmp_data <= DATA;
tmp_read_addr <="0000000000000000";
tmp_read_addr(2 downto 0) <= ry;
CU_state <= write_reg;
control_state <= 3;
when 3 =>
ADDR <= tmp_read_addr;
DATA <= (others=>'Z');
RAM1_OE<='0';
RAM1_WE<='1';
CU_state <= write_reg;
control_state <= 4;
when 4 =>
RAM1_EN <= '0';
RAM1_OE <= '1';
RAM1_WE <= '1';
tmp_data <= tmp_data xor DATA;
tmp_addr(2 downto 0) <= rx;
CU_state <= write_reg;
control_state <= 5;
when 5 =>
ADDR <= tmp_addr;
DATA <= tmp_data;
RAM1_WE<='0';
RAM1_OE<='1';
CU_state <= instruction_fetch;
control_state <= 0;
when others =>
null;
end case;
when "10011" => --LW
RegDst <= "10";
RegWrite <= "001";
MemtoReg <= "01";
MemRead <= '0';
MemWrite <= '0';
case control_state is
when 0 =>
RAM1_EN <= '0';
RAM1_OE <= '1';
RAM1_WE <= '1';
tmp_addr <= "0000000000000000";
tmp_read_addr <="0000000000000000";
tmp_read_addr(2 downto 0) <= rx;
CU_state <= write_reg;
control_state <= 1;
when 1 =>
ADDR <= tmp_read_addr;
DATA <= (others=>'Z');
RAM1_OE<='0';
RAM1_WE<='1';
CU_state <= mem_control;
control_state <= 2;
when 4 =>
RAM1_EN <= '0';
RAM1_OE <= '1';
RAM1_WE <= '1';
tmp_data <= DATA;
tmp_addr(2 downto 0) <= ry;
CU_state <= write_reg;
control_state <= 5;
when 5 =>
ADDR <= tmp_addr;
DATA <= tmp_data;
RAM1_WE<='0';
RAM1_OE<='1';
CU_state <= instruction_fetch;
control_state <= 0;
when others =>
null;
end case;
when "11011" => --SW
MemRead <= '0';
MemWrite <= '0';
IorD <= '0';
case control_state is
when 0 =>
RAM1_EN <= '0';
RAM1_OE <= '1';
RAM1_WE <= '1';
tmp_addr <= "0000000000000000";
tmp_read_addr <="0000000000000000";
tmp_read_addr(2 downto 0) <= ry;
CU_state <= write_reg;
control_state <= 1;
when 1 =>
ADDR <= tmp_read_addr;
DATA <= (others=>'Z');
RAM1_OE<='0';
RAM1_WE<='1';
CU_state <= write_reg;
control_state <= 2;
when 2 =>
RAM1_EN <= '0';
RAM1_OE <= '1';
RAM1_WE <= '1';
tmp_data <= DATA;
tmp_read_addr <="0000000000000000";
tmp_read_addr(2 downto 0) <= rx;
CU_state <= write_reg;
control_state <= 3;
when 3 =>
ADDR <= tmp_read_addr;
DATA <= (others=>'Z');
RAM1_OE<='0';
RAM1_WE<='1';
CU_state <= mem_control;
control_state <= 4;
when others =>
null;
end case;
when others =>
null;
end case;
end case;
end if;
end process;
三、综合实验总结
1.实验难点
略
2.心得体会
略
四.思考题
设计完成后,给出每条指令输入后在数据通路中的执行过程。
如上面实验步骤给出来的数据通路图,七条指令的都已经给出执行过程。
XXX申请验优!
我有一个模型:classItem项目有一个属性“商店”基于存储的值,我希望Item对象对特定方法具有不同的行为。Rails中是否有针对此的通用设计模式?如果方法中没有大的if-else语句,这是如何干净利落地完成的? 最佳答案 通常通过Single-TableInheritance. 关于ruby-on-rails-Rails-子类化模型的设计模式是什么?,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.co
我将应用程序升级到Rails4,一切正常。我可以登录并转到我的编辑页面。也更新了观点。使用标准View时,用户会更新。但是当我添加例如字段:name时,它不会在表单中更新。使用devise3.1.1和gem'protected_attributes'我需要在设备或数据库上运行某种更新命令吗?我也搜索过这个地方,找到了许多不同的解决方案,但没有一个会更新我的用户字段。我没有添加任何自定义字段。 最佳答案 如果您想允许额外的参数,您可以在ApplicationController中使用beforefilter,因为Rails4将参数
请帮助我理解范围运算符...和..之间的区别,作为Ruby中使用的“触发器”。这是PragmaticProgrammersguidetoRuby中的一个示例:a=(11..20).collect{|i|(i%4==0)..(i%3==0)?i:nil}返回:[nil,12,nil,nil,nil,16,17,18,nil,20]还有:a=(11..20).collect{|i|(i%4==0)...(i%3==0)?i:nil}返回:[nil,12,13,14,15,16,17,18,nil,20] 最佳答案 触发器(又名f/f)是
目录前言滤波电路科普主要分类实际情况单位的概念常用评价参数函数型滤波器简单分析滤波电路构成低通滤波器RC低通滤波器RL低通滤波器高通滤波器RC高通滤波器RL高通滤波器部分摘自《LC滤波器设计与制作》,侵权删。前言最近需要学习放大电路和滤波电路,但是由于只在之前做音乐频谱分析仪的时候简单了解过一点点运放,所以也是相当从零开始学习了。滤波电路科普主要分类滤波器:主要是从不同频率的成分中提取出特定频率的信号。有源滤波器:由RC元件与运算放大器组成的滤波器。可滤除某一次或多次谐波,最普通易于采用的无源滤波器结构是将电感与电容串联,可对主要次谐波(3、5、7)构成低阻抗旁路。无源滤波器:无源滤波器,又称
在VMware16.2.4安装Ubuntu一、安装VMware1.打开VMwareWorkstationPro官网,点击即可进入。2.进入后向下滑动找到Workstation16ProforWindows,点击立即下载。3.下载完成,文件大小615MB,如下图:4.鼠标右击,以管理员身份运行。5.点击下一步6.勾选条款,点击下一步7.先勾选,再点击下一步8.去掉勾选,点击下一步9.点击下一步10.点击安装11.点击许可证12.在百度上搜索VM16许可证,复制填入,然后点击输入即可,亲测有效。13.点击完成14.重启系统,点击是15.双击VMwareWorkstationPro图标,进入虚拟机主
项目介绍随着我国经济迅速发展,人们对手机的需求越来越大,各种手机软件也都在被广泛应用,但是对于手机进行数据信息管理,对于手机的各种软件也是备受用户的喜爱小学生兴趣延时班预约小程序的设计与开发被用户普遍使用,为方便用户能够可以随时进行小学生兴趣延时班预约小程序的设计与开发的数据信息管理,特开发了小程序的设计与开发的管理系统。小学生兴趣延时班预约小程序的设计与开发的开发利用现有的成熟技术参考,以源代码为模板,分析功能调整与小学生兴趣延时班预约小程序的设计与开发的实际需求相结合,讨论了小学生兴趣延时班预约小程序的设计与开发的使用。开发环境开发说明:前端使用微信微信小程序开发工具:后端使用ssm:VU
我明白了:x,(y,z)=1,*[2,3]x#=>1y#=>2z#=>nil我想知道为什么z的值为nil。 最佳答案 x,(y,z)=1,*[2,3]右侧的splat*是内联扩展的,所以它等同于:x,(y,z)=1,2,3左边带括号的列表被视为嵌套赋值,所以它等价于:x=1y,z=23被丢弃,而z被分配给nil。 关于ruby-带括号和splat运算符的并行赋值,我们在StackOverflow上找到一个类似的问题: https://stackoverflow
我在我的项目中有一个用户和一个管理员角色。我使用Devise创建了身份验证。在我的管理员角色中,我没有任何确认。在我的用户模型中,我有以下内容:devise:database_authenticatable,:confirmable,:recoverable,:rememberable,:trackable,:validatable,:timeoutable,:registerable#Setupaccessible(orprotected)attributesforyourmodelattr_accessible:email,:username,:prename,:surname,:
问题是:除了在“OperatorExpressions”?例如:1%!2 最佳答案 是的,可以创建自定义运算符,但有一些注意事项。Ruby本身并不直接支持它,但是superatorsgem做了一个巧妙的把戏,将运算符链接在一起。这允许您创建自己的运算符,但有一些限制:$geminstallsuperators19然后:require'superators19'classArraysuperator"%~"do|operand|"#{self}percent-tilde#{operand}"endendputs[1]%~[2]#Out
我正在尝试创建密码规则来设计可恢复的密码更改。我通过passwords_controller.rb做了一个父类(superclass),但我需要在应用规则之前检查用户角色,但我所拥有的只是reset_password_token。 最佳答案 假设您的模型是用户:User.with_reset_password_token(your_token_here)Source 关于ruby-on-rails-设计通过reset_password_token获取用户,我们在StackOverflow