基于Verilog的单周期和多周期CPU设计,数据通路采用分散互联,控制器采用硬布线方式实现
原理方面如各条指令的流程和控制信号的内容可参考相关教材,在此不进行介绍,仅介绍核心组件的实现方法
模拟采用的是modelsim,指令集参考的是MIPS32的标准指令集,实现的十条指令格式皆取自其中
10条指令内容:
单周期
总体结构
- 数据通路
分散互联,CU采用组合逻辑+硬布线实现
组件实现
ALU
根据ALUctl
信号对输入的A和B进行计算,若结果为零则Zero
输出高电平
module ALU (ALUctl,A,B,ALUout,Zero);
input [2:0] ALUctl;
input [31:0] A,B;
output reg [31:0] ALUout;
output Zero;
assign Zero=(ALUout==0);
always @(ALUctl,A,B)
begin
case(ALUctl)
3'b000:ALUout<=A+B; //add
3'b001:ALUout<=A-B; //sub
3'b010:ALUout<=A+B; //addu
3'b011:ALUout<=A&B; //and
3'b100:ALUout<=A|B; //or
3'b101:ALUout<=~(A|B); //nor
default:ALUout<=0;
endcase
end
endmodule
ALU_CU
根据ALUOp
信号输出ALUctl
00
->addu01
->sub10
->由FuncCode
决定,根据MIPS32指令输出对应信号
module ALU_CU(ALUop,FuncCode,Out);
input [1:0] ALUop;
input [5:0] FuncCode;
output reg [2:0] Out;
/*
add 000
sub 001
addu 010
and 011
or 100
nor 101
*/
always @*
case(ALUop)
2'b00:Out=3'b010; //addu
2'b01:Out=3'b001; //sub
2'b10:
begin
case(FuncCode)
6'b100000:Out=3'b000; //add
6'b100010:Out=3'b001; //sub
6'b100001:Out=3'b010; //addu
6'b100100:Out=3'b011; //and
6'b100101:Out=3'b100; //or
6'b100111:Out=3'b101; //nor
default:Out=3'b111;
endcase
end
default:Out=3'b111;
endcase
endmodule
RF
具体输入输出如下,其中RegWr
为写使能,当其有效时,在clock
上升沿将数据写入寄存器
为保证测试,第一个寄存器为基址寄存器,并初始化了基址为0
module reg_file(Read1,Read2,WriteReg,WriteData,RegWr,Data1,Data2,clock);
input [4:0] Read1,Read2,WriteReg; //reg number
input [31:0] WriteData; //data to write
input RegWr; //write control
input clock; //clock for write
output [31:0] Data1,Data2; //data to read
reg [31:0] RF [31:0]; //32 reg(32bit)
//测试用,保存基址
initial
begin
RF[0]=0;
end
assign Data1=RF[Read1];
assign Data2=RF[Read2];
always
begin
@(posedge clock) if(RegWr) RF[WriteReg]<=WriteData;
end
endmodule
指令存储器
使用寄存器堆模拟,为了测试根据MIPS32指令集初始化了一些指令,并且为了保证PC+4的地址正确,对输入地址进行了转换以对应寄存器序号,具体测试代码见测试部分
module mem_ins(addr,ins);
input [31:0] addr;
output [31:0] ins;
reg [31:0] mem [1023:0];
//测试用
initial
begin
mem[0]=32'b100011_00000_00100_00000000_00000011; //lw
mem[1]=32'b100011_00000_00001_00000000_00000001; //lw
mem[2]=32'b100011_00000_00010_00000000_00000010; //lw
mem[3]=32'b100011_00000_00011_00000000_00000100; //lw
mem[4]=32'b000100_00010_00011_00000000_00000010; //beq
mem[5]=32'b000000_00010_00001_00010_00000_100000; //add
mem[6]=32'b000010_00_0001_0000_0000_0000_0000_0100; //j
mem[7]=32'b101011_00000_00010_00000000_00000011; //sw
mem[8]=32'b000010_00_0001_0000_0000_0000_0000_0000; //j
end
assign ins=mem[((addr-32'h00400000)>>2)]; //转换输入地址为寄存器序号
endmodule
数据存储器
使用寄存器模拟,由于未实现立即数指令,为保证测试,初始化了一些数据,内容为对应的寄存器编号
由于只实现了按字读写,因此输入的地址无需翻译,直接对应了寄存器编号
clock
信号用于保证写入正确,存储器只在clock
信号的下降沿写,若不加clock
信号会出现写入不稳定的输入的问题
module mem_data(ena_W,ena_R,addr,data_W,data_R,clock);
input ena_W,ena_R,clock;
input [31:0] addr;
input [31:0] data_W;
output reg [31:0] data_R;
reg [31:0] mem [1023:0];
//测试用
integer i;
initial
begin
for(i=0;i<1024;i=i+1)
mem[i]=i;
end
//只在下降沿写,保证写入内容的稳定
always@(negedge clock)
begin
if(ena_W)
begin
if((addr)<1024)
begin
mem[(addr)]<=data_W;
end
end
end
always@(addr,ena_R,data_R)
begin
if(ena_R)
begin
if((addr)<1024) data_R<=mem[(addr)];
end
end
endmodule
MCU
组合逻辑实现,输出输入指令编号对应操作所需要的信号(5种类型)
module MCU(
input [5:0] In,
output reg RegDst,reg Jump,reg RegWr,reg Branch,reg MemtoReg,reg [1:0] ALUOp,reg MemWr,reg MemRd,reg ALUSrc);
always@ (In)
begin
case(In)
6'b000000:{MemRd,MemWr,ALUOp,ALUSrc,RegDst,RegWr,Branch,Jump,MemtoReg}={10'b0010011000}; //R
6'b100011:{MemRd,MemWr,ALUOp,ALUSrc,RegDst,RegWr,Branch,Jump,MemtoReg}={10'b1000101001}; //lw
6'b101011:{MemRd,MemWr,ALUOp,ALUSrc,RegDst,RegWr,Branch,Jump,MemtoReg}={10'b010010000x}; //sw
6'b000100:{MemRd,MemWr,ALUOp,ALUSrc,RegDst,RegWr,Branch,Jump,MemtoReg}={10'b000100010x}; //beq
6'b000010:{MemRd,MemWr,ALUOp,ALUSrc,RegDst,RegWr,Branch,Jump,MemtoReg}={10'b0011xx0x1x}; //j
default: {MemRd,MemWr,ALUOp,ALUSrc,RegDst,RegWr,Branch,Jump,MemtoReg}={10'b0000000000};
endcase
end
endmodule
PC
rst
信号用于重置PC为第一条指令对应的地址;clock
上升沿写入,由于是单周期,无需写使能
module reg_PC(clock,rst,In,Out);
input clock;
input rst;
//input ena; 单周期无需写使能
input [31:0] In;
output [31:0] Out;
reg [31:0] PC;
always @(posedge rst) PC<=32'h00400000;
always @(posedge clock)
begin
if(1/*ena*/) PC<=In; //enable input (单周期无需写使能)
end
assign Out=PC;
endmodule
其他组件
其他模块实现较为简单
加法器
module ADD (A,B,Out);
input [31:0] A,B;
output reg [31:0] Out;
always @(A,B)
begin
if(A===B) Out<=A+4; //PC+4
else Out<=A+B;
end
endmodule
与门
module ANDgate(in1,in2,Out);
input in1,in2;
output Out;
assign Out=in1&in2;
endmodule
MUX
module MUX_2_32(in0,in1,Sel,Out);
input [31:0] in0,in1;
input Sel;
output reg[31:0] Out;
always@(in0,in1,Sel)
case (Sel)
0: Out<=in0;
default: Out<=in1;
endcase
endmodule
module MUX_2_5(in0,in1,Sel,Out);
input [4:0] in0,in1;
input Sel;
output reg[4:0] Out;
always@(in0,in1,Sel)
case (Sel)
0: Out<=in0;
default: Out<=in1;
endcase
endmodule
SHL2
module SHL2_32(In,Out);
input [31:0] In;
output [31:0] Out;
assign Out={In[29:0],2'b00};
endmodule
module SHL2_26(In,Out);
input [25:0] In;
output [27:0] Out;
assign Out={In[25:0],2'b00};
endmodule
SigExt16_32
module SigExt16_32(In,Out);
input [15:0] In;
output [31:0] Out;
assign Out={{16{In[15]}},In[15:0]};
endmodule
CPU
根据数据通路进行连线,时钟信号和rst
信号由外部输入
`include "MUX_2_32.v"
`include "ALU_CU.v"
`include "SHL2.v"
`include "ALU.v"
`include "reg_file.v"
`include "SigExt16_32.v"
`include "mem_ins.v"
`include "reg_PC.v"
`include "ANDgate.v"
`include "MCU.v"
`include "ADD_32.v"
module CPU(clock,rst);
input clock,rst;
wire [31:0] PC_out, PC_in, Inst, Add1_out, ALU_A, ALU_B, ALU_out, ADD2_B, ADD2_out, SigExt_out, data_W, data_R, WriteData_RF;
wire [31:0] MUX_2_32_1_out;
wire MemRd,MemWr,ALUSrc,RegDst,RegWr,Branch,Jump,MemtoReg,Zero,ANDgate_out;
wire [1:0] ALUOp;
wire [2:0] ALUctl;
wire [4:0] W_Reg;
wire [27:0] SHL2_out28;
reg_PC reg_PC(.clock(clock),.rst(rst),.In(PC_in),.Out(PC_out));
ADD ADD1(.A(PC_out),.B(PC_out),.Out(Add1_out));
MCU MCU(.MemRd(MemRd),.MemWr(MemWr),.ALUOp(ALUOp),.ALUSrc(ALUSrc),.RegDst(RegDst),.RegWr(RegWr),.Branch(Branch),.Jump(Jump),.MemtoReg(MemtoReg),
.In(Inst[31:26]));
SHL2_26 SHL2_26(.In(Inst[25:0]),.Out(SHL2_out28));
ALU_CU ALU_CU(.ALUop(ALUOp),.FuncCode(Inst[5:0]),.Out(ALUctl));
ALU ALU(.ALUctl(ALUctl),.A(ALU_A),.B(ALU_B),.ALUout(ALU_out),.Zero(Zero));
ADD ADD2(.A(Add1_out),.B(ADD2_B),.Out(ADD2_out));
SigExt16_32 SigExt16_32(.In(Inst[15:0]),.Out(SigExt_out));
SHL2_32 SHL2_32(.In(SigExt_out),.Out(ADD2_B));
mem_ins mem_ins(.addr(PC_out),.ins(Inst));
mem_data mem_data(.ena_W(MemWr),.ena_R(MemRd),.addr(ALU_out),.data_W(data_W),.data_R(data_R),.clock(clock));
reg_file reg_file(.Read1(Inst[25:21]),.Read2(Inst[20:16]),.WriteReg(W_Reg),
.WriteData(WriteData_RF),.RegWr(RegWr),.Data1(ALU_A),.Data2(data_W),.clock(clock));
ANDgate ANDgate(.in1(Branch),.in2(Zero),.Out(ANDgate_out));
MUX_2_5 MUX_2_5(.in0(Inst[20:16]),.in1(Inst[15:11]),.Sel(RegDst),.Out(W_Reg));
MUX_2_32 MUX_2_32_1(.in0(Add1_out),.in1(ADD2_out),.Sel(ANDgate_out),.Out(MUX_2_32_1_out));
MUX_2_32 MUX_2_32_2(.in0(MUX_2_32_1_out),.in1({Add1_out[31:28],SHL2_out28[27:0]}),.Sel(Jump),.Out(PC_in));
MUX_2_32 MUX_2_32_3(.in0(data_W),.in1(SigExt_out),.Sel(ALUSrc),.Out(ALU_B));
MUX_2_32 MUX_2_32_4(.in0(ALU_out),.in1(data_R),.Sel(MemtoReg),.Out(WriteData_RF));
endmodule
测试
测试模块
时钟信号和rst
信号由测试模块给出
`include "CPU.v"
module CPU_TEST();
reg rst;
reg clock;
initial
begin
rst=0;
clock=0;
#1 rst=1;
#5 rst=0;
end
always #50 clock=~clock;
CPU CPU(.clock(clock),.rst(rst));
endmodule
测试代码
根据MIPS32指令集,设计了如下测试代码
编号 | PC | 内容 | 指令 |
---|---|---|---|
0 | 0x00400000 | R4<=mem[3] | lw_R0_R4_3 |
1 | 0x00400004 | R1<=mem[1] | lw_R0_R1_1 |
2 | 0x00400008 | R2<=mem[2] | lw_R0_R2_2 |
3 | 0x0040000c | R3<=mem[4] | lw_R0_R3_4 |
4 | 0x00400010 | beq R3==R2 ->7 | beq_R2_R3_2 |
5 | 0x00400014 | R2=R2+R1 | 0_R2_R1_R2_0_add |
6 | 0x00400018 | jmp->4 | j_0x100004 |
7 | 0x0040001c | mem[3]<=R2 | sw_R0_R2_3 |
8 | 0x00400020 | jmp->0 | j_0x100000 |
首先寄存器R4,R1,R2,R3分别写入数据3,1,2,4,然后累加(每次加1(R1))R2直到R2(初值2)=R3(4),然后将R2的值写入内存mem[3]中,再跳转到程序开头,此时R4的写入的应该是R2的值(4)
测试结果
可以看到R2的值不断累加,直到等于R3,最后R4写入了R2的值,结果符合程序逻辑
多周期
总体结构
- 数据通路
CU采用组合逻辑+有限状态机实现
- CU
- 有限状态机
主要组件
ALU和ALU_CU等组件与单周期相同
寄存器
不同于单周期,多周期数据通路多了很多寄存器用于存储中间数据,这些寄存器有不同特点:
-
与单周期相同,只需
clock
信号控制写入(MDR、ALUOut、A、B)module reg_32(clock,In,Out); input clock; input [31:0] In; output [31:0] Out; reg [31:0] reg32; always @(posedge clock) begin reg32<=In; end assign Out=reg32; endmodule
-
需要写使能和
clock
信号同时对写入进行控制(PC、IR)module reg_IR(clock,ena_W,In,Out); input clock; input ena_W; input [31:0] In; output [31:0] Out; reg [31:0] IR; always @(posedge clock) begin if(ena_W) IR<=In; //enable input end assign Out=IR; endmodule
-
需要
clock
信号进行写入控制和rst
信号进行重置(PC、SR)module reg_SR(clock,rst,In,Out); input clock; input rst; input [3:0] In; output [3:0] Out; reg [3:0] SR; always @(posedge rst) SR<=0; always @(posedge clock) begin SR<=In; end assign Out=SR; endmodule
module reg_PC(clock,rst,ena_W,In,Out); input clock; input rst; input ena_W; input [31:0] In; output [31:0] Out; reg [31:0] PC; always @(posedge rst) PC<=32'h00400000; always @(posedge clock) begin if(ena_W) PC<=In; //enable input end assign Out=PC; endmodule
CU
用有限状态机实现,根据前一个状态和输入判断下一步状态并输出对应信号
module CU(
input [3:0] S, [5:0] OP,
output reg PCWr,reg PCWrCond,reg IorD,reg MemRd,reg MemWr,reg IRWr,reg MemtoReg,
output reg [1:0] PCSrc,reg [1:0] ALUOp,reg [1:0] ALUSrcB,reg ALUSrcA,reg RegWr,reg RegDst,
output reg [3:0] NS
);
always@(S)
begin
case(S)
0:NS<=1;
1:
begin
case(OP)
6'b100011:NS<=2;
6'b101011:NS<=2;
6'b000000:NS<=6;
6'b000100:NS<=8;
6'b000010:NS<=9;
default:NS<=4'b1xx1;
endcase
end
2:
begin
case(OP)
6'b100011:NS<=3;
6'b101011:NS<=5;
default:NS<=0;
endcase
end
3:NS<=4;
4:NS<=0;
5:NS<=0;
6:NS<=7;
7:NS<=0;
8:NS<=0;
9:NS<=0;
default:NS<=0;
endcase
end
always@(S)
case(S)
0:{PCWr,PCWrCond,IorD,MemRd,MemWr,IRWr,MemtoReg, PCSrc , ALUOp , ALUSrcB ,ALUSrcA,RegWr,RegDst}={16'b1001010_00_00_01_000};
1:{PCWr,PCWrCond,IorD,MemRd,MemWr,IRWr,MemtoReg, PCSrc , ALUOp , ALUSrcB ,ALUSrcA,RegWr,RegDst}={16'b0000000_00_00_11_000};
2:{PCWr,PCWrCond,IorD,MemRd,MemWr,IRWr,MemtoReg, PCSrc , ALUOp , ALUSrcB ,ALUSrcA,RegWr,RegDst}={16'b0000000_00_00_10_100};
3:{PCWr,PCWrCond,IorD,MemRd,MemWr,IRWr,MemtoReg, PCSrc , ALUOp , ALUSrcB ,ALUSrcA,RegWr,RegDst}={16'b0011000_00_00_00_000};
4:{PCWr,PCWrCond,IorD,MemRd,MemWr,IRWr,MemtoReg, PCSrc , ALUOp , ALUSrcB ,ALUSrcA,RegWr,RegDst}={16'b0000001_00_00_00_010};
5:{PCWr,PCWrCond,IorD,MemRd,MemWr,IRWr,MemtoReg, PCSrc , ALUOp , ALUSrcB ,ALUSrcA,RegWr,RegDst}={16'b0010100_00_00_00_000};
6:{PCWr,PCWrCond,IorD,MemRd,MemWr,IRWr,MemtoReg, PCSrc , ALUOp , ALUSrcB ,ALUSrcA,RegWr,RegDst}={16'b0000000_00_10_00_100};
7:{PCWr,PCWrCond,IorD,MemRd,MemWr,IRWr,MemtoReg, PCSrc , ALUOp , ALUSrcB ,ALUSrcA,RegWr,RegDst}={16'b0000000_00_00_00_011};
8:{PCWr,PCWrCond,IorD,MemRd,MemWr,IRWr,MemtoReg, PCSrc , ALUOp , ALUSrcB ,ALUSrcA,RegWr,RegDst}={16'b0100000_01_01_00_100};
9:{PCWr,PCWrCond,IorD,MemRd,MemWr,IRWr,MemtoReg, PCSrc , ALUOp , ALUSrcB ,ALUSrcA,RegWr,RegDst}={16'b1000000_10_00_00_000};
default:{PCWr,PCWrCond,IorD,MemRd,MemWr,IRWr,MemtoReg, PCSrc , ALUOp , ALUSrcB ,ALUSrcA,RegWr,RegDst}={16'b0000000_00_00_00_000};
endcase
endmodule
内存
合并了数据存储器和指令存储器,同样用寄存器堆模拟,并初始化相应数据,指令同单周期
需要注意的是读指令和读数据的地址转换方式不同
module mem(ena_W,ena_R,addr,data_W,data_R,clock);
input ena_W,ena_R,clock;
input [31:0] addr;
input [31:0] data_W;
output reg [31:0] data_R;
reg [31:0] mem [1023:0];
//测试用
integer i;
initial
begin
for(i=0;i<512;i=i+1)
mem[i]=i;
end
//测试用
initial
begin
mem[512+0]=32'b100011_00000_00100_00000000_00000011; //lw
mem[512+1]=32'b100011_00000_00001_00000000_00000001; //lw
mem[512+2]=32'b100011_00000_00010_00000000_00000010; //lw
mem[512+3]=32'b100011_00000_00011_00000000_00000100; //lw
mem[512+4]=32'b000100_00010_00011_00000000_00000010; //beq
mem[512+5]=32'b000000_00010_00001_00010_00000_100000; //add
mem[512+6]=32'b000010_00_0001_0000_0000_0000_0000_0100; //j
mem[512+7]=32'b101011_00000_00010_00000000_00000011; //sw
mem[512+8]=32'b000010_00_0001_0000_0000_0000_0000_0000; //j
end
always@(negedge clock)
begin
if(ena_W)
begin
if((addr)<512)
begin
mem[(addr)]<=data_W;
end
end
end
always@(addr,ena_R,data_R)
begin
if(ena_R)
begin
if((addr)<512) data_R<=mem[(addr)]; //读数据
else data_R<=mem[((addr-32'h00400000)>>2)+512]; //读指令
end
end
endmodule
其他组件
其他大部分组件与单周期相同
MUX_4
module MUX_3_32(in0,in1,in2,Sel,Out);
input [31:0] in0,in1,in2;
input [1:0] Sel;
output reg[31:0] Out;
always@(in0,in1,in2,Sel)
case (Sel)
0: Out<=in0;
1: Out<=in1;
2: Out<=in2;
default: Out<=in0;
endcase
endmodule
module MUX_4_32_1x(in0,in2,in3,Sel,Out);
input [31:0] in0,in2,in3;
input [1:0] Sel;
output reg[31:0] Out;
always@(in0,in2,in3,Sel)
case (Sel)
0: Out<=in0;
1: Out<=4;
2: Out<=in2;
default: Out<=in3;
endcase
endmodule
或门
module ORgate(in1,in2,Out);
input in1,in2;
output Out;
assign Out=in1|in2;
endmodule
CPU
根据数据通路进行连线,时钟信号和rst
信号由外部输入
`include "MUX_2_32.v"
`include "ALU_CU.v"
`include "MUX_4_32.v"
`include "SHL2.v"
`include "ALU.v"
`include "reg_file.v"
`include "SigExt16_32.v"
`include "reg_PC.v"
`include "reg_32.v"
`include "ANDgate.v"
`include "ORgate.v"
`include "mem.v"
`include "CU.v"
module CPU(clock,rst);
input clock,rst;
wire [31:0] Inst,PC_in,PC_out,mem_addr,mem_data_R,A_in,B_in,A_out,B_out,ALU_A,ALU_B,ALU_out,ALUOut_out,MDR_out;
wire [31:0] SigExt_out,SHL2_32_out,WriteData_RF;
wire [27:0] SHL2_26_out;
wire PCWr,PCWrCond,IorD,MemRd,MemWr,IRWr,MemtoReg,ALUSrcA,RegWr,RegDst,ena_W_PC,Zero,ANDgate_out;
wire [1:0] PCSrc,ALUOp,ALUSrcB;
wire [3:0] SR_out,SR_in;
wire [2:0] ALUctl;
wire [4:0] WriteReg;
CU CU(.S(SR_out),.OP(Inst[31:26]),
.PCWr(PCWr),.PCWrCond(PCWrCond),.IorD(IorD),.MemRd(MemRd),.MemWr(MemWr),.IRWr(IRWr),.MemtoReg(MemtoReg),
.PCSrc(PCSrc),.ALUOp(ALUOp),.ALUSrcB(ALUSrcB),.ALUSrcA(ALUSrcA),.RegWr(RegWr),.RegDst(RegDst),
.NS(SR_in));
reg_SR SR(.clock(clock),.rst(rst),.In(SR_in),.Out(SR_out));
reg_PC PC(.clock(clock),.rst(rst),.ena_W(ena_W_PC),.In(PC_in),.Out(PC_out));
mem mem(.ena_W(MemWr),.ena_R(MemRd),.addr(mem_addr),.data_W(B_out),.data_R(mem_data_R),.clock(clock));
reg_IR IR(.clock(clock),.ena_W(IRWr),.In(mem_data_R),.Out(Inst));
reg_32 A(.clock(clock),.In(A_in),.Out(A_out));
reg_32 B(.clock(clock),.In(B_in),.Out(B_out));
ALU ALU(.ALUctl(ALUctl),.A(ALU_A),.B(ALU_B),.ALUout(ALU_out),.Zero(Zero));
ALU_CU ALU_CU(.ALUop(ALUOp),.FuncCode(Inst[5:0]),.Out(ALUctl));
reg_32 ALUOut(.clock(clock),.In(ALU_out),.Out(ALUOut_out));
reg_32 MDR(.clock(clock),.In(mem_data_R),.Out(MDR_out));
SigExt16_32 SigExt16_32(.In(Inst[15:0]),.Out(SigExt_out));
SHL2_32 SHL2_32(.In(SigExt_out),.Out(SHL2_32_out));
SHL2_26 SHL2_26(.In(Inst[25:0]),.Out(SHL2_26_out));
reg_file RF(.Read1(Inst[25:21]),.Read2(Inst[20:16]),.WriteReg(WriteReg),.WriteData(WriteData_RF),.RegWr(RegWr),.Data1(A_in),.Data2(B_in),.clock(clock));
ANDgate ANDgate(.in1(PCWrCond),.in2(Zero),.Out(ANDgate_out));
ORgate ORgate(.in1(PCWr),.in2(ANDgate_out),.Out(ena_W_PC));
MUX_2_32 MUX_2_32_1(.in0(PC_out),.in1(ALUOut_out),.Sel(IorD),.Out(mem_addr));
MUX_2_32 MUX_2_32_2(.in0(ALUOut_out),.in1(MDR_out),.Sel(MemtoReg),.Out(WriteData_RF));
MUX_2_32 MUX_2_32_3(.in0(PC_out),.in1(A_out),.Sel(ALUSrcA),.Out(ALU_A));
MUX_2_5 MUX_2_5(.in0(Inst[20:16]),.in1(Inst[15:11]),.Sel(RegDst),.Out(WriteReg));
MUX_4_32_1x MUX_4_32_1x(.in0(B_out),.in2(SigExt_out),.in3(SHL2_32_out),.Sel(ALUSrcB),.Out(ALU_B));
MUX_3_32 MUX_3_32(.in0(ALU_out),.in1(ALUOut_out),.in2({PC_out[31:28],SHL2_26_out[27:0]}),.Sel(PCSrc),.Out(PC_in));
endmodule
测试
测试模块和测试代码同单周期
测试结果
可以看到状态正常转换,并且R2累加
最后R4写入了R2的值,结果符合程序逻辑