电子科技大学《计算机组成结构》项目一:MIPS指令集单周期CPU仿真。

《计算机组成结构》是一门讲述计算机内部结构原理的课程,老师在期末会留下项目作业,是通过modelsim或是vivado仿真,modelsim好像并没有开源,正经人可能都会选择去下载破解版的,如果能看到这里那大概率是已经下载好了的,这里就不再BB了。

首先这个项目是比较简单的,这一点我们需要明确(后面做流水线是真的难!)。我们需要实现R型,I型,以及J型约莫十二条左右的指令。通过对数据通路的学习,我们可以构造出整个CPU的基本原理图。

                                                                        

上图为单周期CPU设计完成时的数据通路和必要的控制线路图。在单周期的实现中我们主要先是设计了几个大的模块。包括INSTEMEM(用于存储指令)、REGFILE(寄存器)、CONUNIT(控制)、DATAMEM(存储数据)等,然后,在最终的CPU模块中将所有的模块相连接起来。

注意:如果你尝试看懂这份代码,那么请记住,在verilog编程上面的思路和C语言并不一样,C语言的编译是一条一条的按顺序编译,但是verilog更像是一根根网线去把他连接起来,只要连通了就没什么问题,并不在意先后顺序,学了锁存器的时候请仔细理解那一章时间与信号的变化关系。

这里附上代码:

PC寄存器代码模块:

module PC(Clk,Clrn,PC,Addr);  
input Clk,Clrn;    
input[31:0] PC;
output [31:0] Addr;
wire [31:0] Qn;
D_FFEC32 dffec32(PC,Clk,1,Clrn,Addr,Qn);
Endmodule

PC+4代码实现:

module PCadd4(PC,PCout);
input [31:0] PC;
output [31:0] PCout;
CLA_32 cla32(PC,4,0, PCout, Cout);
Endmodule

指令寄存器代码:

这里为了便于后续验证,我已经设置了几条指令。

module INSTMEM(Addr,Inst);
    input[31:0]Addr;
    output[31:0]Inst;
    wire[31:0]Rom[31:0];
    assign Rom[5'h00]=32'h20010008;//addi $1,$0,8 $1=8
    assign Rom[5'h01]=32'h3402000C;//ori $2,$0,12 $2=12
    assign Rom[5'h02]=32'h00221820;//add $3,$1,$2 $3=20
    assign Rom[5'h03]=32'h00412022;//sub $4,$2,$1 $4=4
    assign Rom[5'h04]=32'h00222824;//and $5,$1,$2 $5=8
    assign Rom[5'h05]=32'h00223025;//or $6,$1,$2 $6=12
    assign Rom[5'h06]=32'h14220002;//bne $1,$2,2
    assign Rom[5'h07]=32'hXXXXXXXX;
    assign Rom[5'h08]=32'hXXXXXXXX;
    assign Rom[5'h09]=32'h10220002;// beq $1,$2,2
    assign Rom[5'h0A]=32'h0800000D;// J 0D 
    assign Rom[5'h0B]=32'hXXXXXXXX;
    assign Rom[5'h0C]=32'hXXXXXXXX;
    assign Rom[5'h0D]=32'hAC02000A;// sw $2 10($0) memory[$0+10]=10
    assign Rom[5'h0E]=32'h8C04000A;//lw $4 10($0) $4=12
    assign Rom[5'h0F]=32'h30470009;//andi $7,$2,9
    assign Rom[5'h10]=32'hXXXXXXXX;
    assign Rom[5'h11]=32'hXXXXXXXX;
    assign Rom[5'h12]=32'hXXXXXXXX;
    assign Rom[5'h13]=32'hXXXXXXXX;
    assign Rom[5'h14]=32'hXXXXXXXX;
    assign Rom[5'h15]=32'hXXXXXXXX;
    assign Rom[5'h16]=32'hXXXXXXXX;
    assign Rom[5'h17]=32'hXXXXXXXX;
    assign Rom[5'h18]=32'hXXXXXXXX;
    assign Rom[5'h19]=32'hXXXXXXXX;
    assign Rom[5'h1A]=32'hXXXXXXXX;
    assign Rom[5'h1B]=32'hXXXXXXXX;
    assign Rom[5'h1C]=32'hXXXXXXXX;
    assign Rom[5'h1D]=32'hXXXXXXXX;
    assign Rom[5'h1E]=32'hXXXXXXXX;
    assign Rom[5'h1F]=32'hXXXXXXXX;
    assign Inst=Rom[Addr[6:2]];
endmodule

DATAMEM的代码实现:

module DATAMEM(Addr,Din,Clk,We,Dout);
input [31:0] Addr,Din;
input Clk,We;
output [31:0] Dout;
reg [31:0] Ram [31:0];
integer i;
initial begin
for (i=0;i<=31;i=i+1)
Ram[i]=i;
end
always @(posedge Clk) begin
if(We) Ram[Addr[6:2]]<=Din;
end
assign Dout =Ram[Addr[6:2]];
endmodule

移位器的实现:

module SHIFTER_32(X,Sa,Arith,Right,Sh);
input [31:0]X;
input [4:0]Sa;
input Arith,Right;
output [31:0]Sh;
wire [31:0]T4,T3,T2,T1,T0,S4,S3,S2,S1;
wire a=X[31]&Arith;
wire [15:0]e={16{a}};
parameter z=16'b0000000000000000;
wire [31:0]L1u,L1d,L2u,L2d,L3u,L3d,L4u,L4d,L5u,L5d;
assign L1u={X[15:0],z[15:0]};
assign L1d={e,X[31:16]};
MUX2X32 M1l(L1u,L1d,Right,T4);
MUX2X32 M1r(X,T4,Sa[4],S4);
assign L2u={S4[23:0],z[7:0]};
assign L2d={e[7:0],S4[31:8]};
MUX2X32 M2l(L2u,L2d,Right,T3);
MUX2X32 M2r(S4,T3,Sa[3],S3);
assign L3u={S3[27:0],z[3:0]};
assign L3d={e[3:0],S3[31:4]};
MUX2X32 M3l(L3u,L3d,Right,T2);
MUX2X32 M3r(S3,T2,Sa[2],S2);
assign L4u={S2[29:0],z[1:0]};
assign L4d={e[1:0],S2[31:2]};
MUX2X32 M4l(L4u,L4d,Right,T1);
MUX2X32 M4r(S2,T1,Sa[1],S1);
assign L5u={S1[30:0],z[0]};
assign L5d={e[0],S1[31:1]};
MUX2X32 M5l(L5u,L5d,Right,T0);
MUX2X32 M5r(S1,T0,Sa[0],Sh);
endmodule

J指令得到的地址计算:

module SHIFTER_addr(X,PCadd4,Sh);
input [25:0] X;
input [31:0] PCadd4;
output [31:0] Sh;
parameter z=2'b00;
assign Sh={PCadd4[31:28],X[25:0],z};
endmodule

MUX的实现:

module MUX2X32(A0,A1,S,Y);
input [31:0] A0,A1;
input S;
output [31:0] Y;
assign Y=(S==1'b0)?A0:A1;
endmodule

module MUX4X32(A0,A1,A2,A3,S,Y);
input [31:0] A0,A1,A2,A3;
input [1:0]S;
output [31:0] Y;
assign Y=(S==2'b00)?A0:
(S==2'b01)?A1:
(S==2'b10)?A2:A3;
endmodule

module MUX2X5(A0,A1,S,Y);
input [4:0] A0,A1;
input S;
output [4:0] Y;
assign Y=(S==1'b0)?A0:A1;
endmodule

module MUX32X32(A0,A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11,A12,A13,A14,A15,A16,A17,A18,A19,A20,A21,A22,A23,A24,A25,A26,A27,A28,A29,A30,A31,S,Y);
input [31:0]A0,A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11,A12,A13,A14,A15,A16,A17,A18,A19,A20,A21,A22,A23,A24,A25,A26,A27,A28,A29,A30,A31;
input [4:0]S;
output [31:0]Y;
assign     Y= S==(5'b00000)?A0:
              S==(5'b00001)?A1:
              S==(5'b00010)?A2:
              S==(5'b00011)?A3:
              S==(5'b00100)?A4:
              S==(5'b00101)?A5:
              S==(5'b00110)?A6:
              S==(5'b00111)?A7:
              S==(5'b01000)?A8:
              S==(5'b01001)?A9:
              S==(5'b01010)?A10:
              S==(5'b01011)?A11:
              S==(5'b01100)?A12:
              S==(5'b01101)?A13:
              S==(5'b01110)?A14:
              S==(5'b01111)?A15:
              S==(5'b10000)?A16:
              S==(5'b10001)?A17:
              S==(5'b10010)?A18:
              S==(5'b10011)?A19:
              S==(5'b10100)?A20:
              S==(5'b10101)?A21:
              S==(5'b10110)?A22:
              S==(5'b10111)?A23:
              S==(5'b11000)?A24:
              S==(5'b11001)?A25:
              S==(5'b11010)?A26:
              S==(5'b11011)?A27:
              S==(5'b11100)?A28:
              S==(5'b11101)?A29:
              S==(5'b11110)?A30:
                            A31;
endmodule

扩展器的实现:

module EXT16T32(X,Se,Y);
input [15:0] X;
input Se;
output [31:0] Y;
wire [31:0] E0,E1;
wire [15:0] e={16{X[15]}};
parameter z=16'b0;
assign E0={z,X};
assign E1={e,X};
MUX2X32 i(E0,E1,Se,Y);
endmodule



CONUNIT模块的实现:

module CONUNIT(Op,Func,Z,Regrt,Se,Wreg,Aluqb,Aluc,Wmem,Pcsrc,Reg2reg);
input[5:0]Op,Func;
input Z;
output Regrt,Se,Wreg,Aluqb,Wmem,Reg2reg;
output[1:0]Pcsrc,Aluc;
wire R_type=~|Op;
wire I_add=R_type&Func[5]&~Func[4]&~Func[3]&~Func[2]&~Func[1]&~Func[0];
wire I_sub=R_type&Func[5]&~Func[4]&~Func[3]&~Func[2]&Func[1]&~Func[0];
wire I_and=R_type&Func[5]&~Func[4]&~Func[3]&Func[2]&~Func[1]&~Func[0];
wire I_or=R_type&Func[5]&~Func[4]&~Func[3]&Func[2]&~Func[1]&Func[0];
wire I_addi=~Op[5]&~Op[4]&Op[3]&~Op[2]&~Op[1]&~Op[0];
wire I_andi=~Op[5]&~Op[4]&Op[3]&Op[2]&~Op[1]&~Op[0];
wire I_ori=~Op[5]&~Op[4]&Op[3]&Op[2]&~Op[1]&Op[0];
wire I_lw=Op[5]&~Op[4]&~Op[3]&~Op[2]&Op[1]&Op[0];
wire I_sw=Op[5]&~Op[4]&Op[3]&~Op[2]&Op[1]&Op[0];
wire I_beq=~Op[5]&~Op[4]&~Op[3]&Op[2]&~Op[1]&~Op[0];
wire I_bne=~Op[5]&~Op[4]&~Op[3]&Op[2]&~Op[1]&Op[0];
wire I_J=~Op[5]&~Op[4]&~Op[3]&~Op[2]&Op[1]&~Op[0];
assign Regrt=I_addi|I_andi|I_ori|I_lw|I_sw|I_beq|I_bne|I_J;
assign Se=I_addi|I_lw|I_sw|I_beq|I_bne;
assign Wreg=I_add|I_sub|I_and|I_or|I_addi|I_andi|I_ori|I_lw;
assign Aluqb=I_add|I_sub|I_and|I_or|I_beq|I_bne|I_J;
assign Aluc[1]=I_and|I_or|I_andi|I_ori;
assign Aluc[0]=I_sub|I_or|I_ori|I_beq|I_bne;
assign Wmem=I_sw;
assign Pcsrc[1]=I_beq&Z|I_bne&~Z|I_J;
assign Pcsrc[0]=I_J;
assign Reg2reg=I_add|I_sub|I_and|I_or|I_addi|I_andi|I_ori|I_sw|I_beq|I_bne|I_J;
endmodule    

REGFILE的实现:

module D_Latch(D,En,Q,Qn);
input D,En;
output Q,Qn;
wire Sn,Rn,Dn;
not i0(Dn,D);
nand i1(Sn,D,En);
nand i2(Rn,En,Dn);
nand i3(Q,Sn,Qn);
nand i4(Qn,Q,Rn);
endmodule

module D_FF(D,Clk,Q,Qn);
input D,Clk;
output Q,Qn;
wire Clkn,Q0,Qn0;
not i0(Clkn,Clk);
D_Latch d0(D,Clkn,Q0,Qn0);
D_Latch d1(Q0,Clk,Q,Qn);
endmodule

module D_FFEC(D,Clk,En,Clrn,Q,Qn);
input D,Clk,En,Clrn;
output Q,Qn;
wire Y0,Y_C;
MUX2X1 m0(Q,D,En,Y0);
and i0(Y_C,Y0,Clrn);
D_FF d0(Y_C,Clk,Q,Qn);
endmodule

module D_FFEC32(D,Clk,En,Clrn,Q,Qn);
input[31:0]D;
input Clk,En,Clrn;
output[31:0]Q,Qn;
D_FFEC d0(D[0],Clk,En,Clrn,Q[0],Qn[0]);
D_FFEC d1(D[1],Clk,En,Clrn,Q[1],Qn[1]);
D_FFEC d2(D[2],Clk,En,Clrn,Q[2],Qn[2]);
D_FFEC d3(D[3],Clk,En,Clrn,Q[3],Qn[3]);
D_FFEC d4(D[4],Clk,En,Clrn,Q[4],Qn[4]);
D_FFEC d5(D[5],Clk,En,Clrn,Q[5],Qn[5]);
D_FFEC d6(D[6],Clk,En,Clrn,Q[6],Qn[6]);
D_FFEC d7(D[7],Clk,En,Clrn,Q[7],Qn[7]);
D_FFEC d8(D[8],Clk,En,Clrn,Q[8],Qn[8]);
D_FFEC d9(D[9],Clk,En,Clrn,Q[9],Qn[9]);
D_FFEC d10(D[10],Clk,En,Clrn,Q[10],Qn[10]);
D_FFEC d11(D[11],Clk,En,Clrn,Q[11],Qn[11]);
D_FFEC d12(D[12],Clk,En,Clrn,Q[12],Qn[12]);
D_FFEC d13(D[13],Clk,En,Clrn,Q[13],Qn[13]);
D_FFEC d14(D[14],Clk,En,Clrn,Q[14],Qn[14]);
D_FFEC d15(D[15],Clk,En,Clrn,Q[15],Qn[15]);
D_FFEC d16(D[16],Clk,En,Clrn,Q[16],Qn[16]);
D_FFEC d17(D[17],Clk,En,Clrn,Q[17],Qn[17]);
D_FFEC d18(D[18],Clk,En,Clrn,Q[18],Qn[18]);
D_FFEC d19(D[19],Clk,En,Clrn,Q[19],Qn[19]);
D_FFEC d20(D[20],Clk,En,Clrn,Q[20],Qn[20]);
D_FFEC d21(D[21],Clk,En,Clrn,Q[21],Qn[21]);
D_FFEC d22(D[22],Clk,En,Clrn,Q[22],Qn[22]);
D_FFEC d23(D[23],Clk,En,Clrn,Q[23],Qn[23]);
D_FFEC d24(D[24],Clk,En,Clrn,Q[24],Qn[24]);
D_FFEC d25(D[25],Clk,En,Clrn,Q[25],Qn[25]);
D_FFEC d26(D[26],Clk,En,Clrn,Q[26],Qn[26]);
D_FFEC d27(D[27],Clk,En,Clrn,Q[27],Qn[27]);
D_FFEC d28(D[28],Clk,En,Clrn,Q[28],Qn[28]);
D_FFEC d29(D[29],Clk,En,Clrn,Q[29],Qn[29]);
D_FFEC d30(D[30],Clk,En,Clrn,Q[30],Qn[30]);
D_FFEC d31(D[31],Clk,En,Clrn,Q[31],Qn[31]);
endmodule

module REG32(D,En,Clk,Clrn,Q31,Q30,Q29,Q28,Q27,Q26,Q25,Q24,Q23,Q22,Q21,Q20,Q19,Q18,Q17,Q16,Q15,Q14,Q13,Q12,Q11,Q10,Q9,Q8,Q7,Q6,Q5,Q4,Q3,Q2,Q1,Q0);
input[31:0]D,En;
input Clk,Clrn;
output[31:0]Q31,Q30,Q29,Q28,Q27,Q26,Q25,Q24,Q23,Q22,Q21,Q20,Q19,Q18,Q17,Q16,Q15,Q14,Q13,Q12,Q11,Q10,Q9,Q8,Q7,Q6,Q5,Q4,Q3,Q2,Q1,Q0;
wire [31:0]Qn31,Qn30,Qn29,Qn28,Qn27,Qn26,Qn25,Qn24,Qn23,Qn22,Qn21,Qn20,Qn19,Qn18,Qn17,Qn16,Qn15,Qn14,Qn13,Qn12,Qn11,Qn10,Qn9,Qn8,Qn7,Qn6,Qn5,Qn4,Qn3,Qn2,Qn1,Qn0;
D_FFEC32 q31(D,Clk,En[31],Clrn,Q31,Qn31);
D_FFEC32 q30(D,Clk,En[30],Clrn,Q30,Qn30);
D_FFEC32 q29(D,Clk,En[29],Clrn,Q29,Qn29);
D_FFEC32 q28(D,Clk,En[28],Clrn,Q28,Qn28);
D_FFEC32 q27(D,Clk,En[27],Clrn,Q27,Qn27);
D_FFEC32 q26(D,Clk,En[26],Clrn,Q26,Qn26);
D_FFEC32 q25(D,Clk,En[25],Clrn,Q25,Qn25);
D_FFEC32 q24(D,Clk,En[24],Clrn,Q24,Qn24);
D_FFEC32 q23(D,Clk,En[23],Clrn,Q23,Qn23);
D_FFEC32 q22(D,Clk,En[22],Clrn,Q22,Qn22);
D_FFEC32 q21(D,Clk,En[21],Clrn,Q21,Qn21);
D_FFEC32 q20(D,Clk,En[20],Clrn,Q20,Qn20);
D_FFEC32 q19(D,Clk,En[19],Clrn,Q19,Qn19);
D_FFEC32 q18(D,Clk,En[18],Clrn,Q18,Qn18);
D_FFEC32 q17(D,Clk,En[17],Clrn,Q17,Qn17);
D_FFEC32 q16(D,Clk,En[16],Clrn,Q16,Qn16);
D_FFEC32 q15(D,Clk,En[15],Clrn,Q15,Qn15);
D_FFEC32 q14(D,Clk,En[14],Clrn,Q14,Qn14);
D_FFEC32 q13(D,Clk,En[13],Clrn,Q13,Qn13);
D_FFEC32 q12(D,Clk,En[12],Clrn,Q12,Qn12);
D_FFEC32 q11(D,Clk,En[11],Clrn,Q11,Qn11);
D_FFEC32 q10(D,Clk,En[10],Clrn,Q10,Qn10);
D_FFEC32 q9(D,Clk,En[9],Clrn,Q9,Qn9);
D_FFEC32 q8(D,Clk,En[8],Clrn,Q8,Qn8);
D_FFEC32 q7(D,Clk,En[7],Clrn,Q7,Qn7);
D_FFEC32 q6(D,Clk,En[6],Clrn,Q6,Qn6);
D_FFEC32 q5(D,Clk,En[5],Clrn,Q5,Qn5);
D_FFEC32 q4(D,Clk,En[4],Clrn,Q4,Qn4);
D_FFEC32 q3(D,Clk,En[3],Clrn,Q3,Qn3);
D_FFEC32 q2(D,Clk,En[2],Clrn,Q2,Qn2);
D_FFEC32 q1(D,Clk,En[1],Clrn,Q1,Qn1);
assign Q0=32'h00000000;
assign Qn0=32'h00000000;
endmodule

module DEC5T32E(I,En,Y);
input En;
input [4:0] I;
output  [31:0] Y;
assign Y=(En==0?0:1<<I);
endmodule
最终实现代码:
module REGFILE(Ra,Rb,D,Wr,We,Clk,Clrn,Qa,Qb);
input [4:0]Ra,Rb,Wr;
input [31:0]D;
input We,Clk,Clrn;
output [31:0]Qa,Qb;
wire [31:0]Y;
wire [31:0]Q31,Q30,Q29,Q28,Q27,Q26,Q25,Q24,Q23,Q22,Q21,Q20,Q19,Q18,Q17,Q16,Q15,Q14,Q13,Q12,Q11,Q10,Q9,Q8,Q7,Q6,Q5,Q4,Q3,Q2,Q1,Q0;
DEC5T32E dec(Wr,We,Y);
REG32 reg32(D,Y,Clk,Clrn,Q31,Q30,Q29,Q28,Q27,Q26,Q25,Q24,Q23,Q22,Q21,Q20,Q19,Q18,Q17,Q16,Q15,Q14,Q13,Q12,Q11,Q10,Q9,Q8,Q7,Q6,Q5,Q4,Q3,Q2,Q1,Q0);
MUX32X32 select1(Q0,Q1,Q2,Q3,Q4,Q5,Q6,Q7,Q8,Q9,Q10,Q11,Q12,Q13,Q14,Q15,Q16,Q17,Q18,Q19,Q20,Q21,Q22,Q23,Q24,Q25,Q26,Q27,Q28,Q29,Q30,Q31,Ra,Qa);
MUX32X32 select2(Q0,Q1,Q2,Q3,Q4,Q5,Q6,Q7,Q8,Q9,Q10,Q11,Q12,Q13,Q14,Q15,Q16,Q17,Q18,Q19,Q20,Q21,Q22,Q23,Q24,Q25,Q26,Q27,Q28,Q29,Q30,Q31,Rb,Qb);
endmodule

ALU的实现:

module CLA_4(X,Y,Cin,S,Cout);
input [3:0] X,Y;
input Cin;
output [3:0] S;
output Cout;
wire Cout0,Cout1,Cout2;
assign Cout0=X[0]*Y[0]+(X[0]+Y[0])*Cin;
assign Cout1=X[1]*Y[1]+(X[1]+Y[1])*X[0]*Y[0]+(X[0]+Y[0])*(X[1]+Y[1])*Cin;
assign Cout2=X[2]*Y[2]+X[1]*Y[1]*(X[2]+Y[2])+(X[2]+Y[2])*(X[1]+Y[1])*X[0]*Y[0]+(X[0]+Y[0])*(X[1]+Y[1])*(X[2]+Y[2])*Cin;
assign Cout=X[3]*Y[3]+X[2]*Y[2]*(X[3]+Y[3])+(X[3]+Y[3])*(X[2]+Y[2])*X[1]*Y[1]+(X[3]+Y[3])*(X[2]+Y[2])*(X[1]+Y[1])*X[0]*Y[0]+(X[0]+Y[0])*(X[1]+Y[1])*(X[2]+Y[2])*(X[3]+Y[3])*Cin;
assign S[0]=X[0]+Y[0]+Cin;
assign S[1]=X[1]+Y[1]+Cout0;
assign S[2]=X[2]+Y[2]+Cout1;
assign S[3]=X[3]+Y[3]+Cout2;
endmodule

module CLA_32(X,Y,Cin,S,Cout);
input[31:0]X,Y;
input Cin;
output[31:0]S;
output Cout;
wire Cout0,Cout1,Cout2,Cout3,Cout4,Cout5,Cout6;
CLA_4 add0(X[3:0],Y[3:0],Cin,S[3:0],Cout0);
CLA_4 add1(X[7:4],Y[7:4],Cout0,S[7:4],Cout1);
CLA_4 add2(X[11:8],Y[11:8],Cout1,S[11:8],Cout2);
CLA_4 add3(X[15:12],Y[15:12],Cout2,S[15:12],Cout3);
CLA_4 add4(X[19:16],Y[19:16],Cout3,S[19:16],Cout4);
CLA_4 add5(X[23:20],Y[23:20],Cout4,S[23:20],Cout5);
CLA_4 add6(X[27:24],Y[27:24],Cout5,S[27:24],Cout6);
CLA_4 add7(X[31:28],Y[31:28],Cout6,S[31:28],Cout);
endmodule

module ADDSUB_32(X,Y,Sub,S);
input [31:0]X,Y;
wire Cout;
input Sub;
output [31:0]S;
CLA_32 adder0(X,Y^{32{Sub}},Sub,S,Cout);
endmodule

module ALU(X,Y,Aluc,R,Z);
input [31:0]X,Y;
input [1:0]Aluc;
output [31:0]R;
output Z;
wire[31:0]d_as,d_and,d_or,d_and_or;
ADDSUB_32 as(X,Y,Aluc[0],d_as);
assign d_and=X&Y;
assign d_or=X|Y;
MUX2X32 select1(d_and,d_or,Aluc[0],d_and_or);
MUX2X32 seleted(d_as,d_and_or,Aluc[1],R);
assign Z=~|R;
endmodule

CPU封装代码:

module CPU(Clk,Clrn,Addr,Inst,Qa,Qb,ALU_R,NPC,D);
input Clk;
input Clrn;
output [31:0] Addr,Inst,Qa,Qb,ALU_R,NPC,D;
wire [31:0] R,PC,PCout,EXTout,SHIFTout1,SHIFTout2,Y,D,CLAout,Dout;
wire [4:0] Wr;
wire Regrt,We,Z,Se,Wreg,Aluqb,Wmem,Reg2reg,Cout;
wire [1:0] Pcsrc,Aluc;
PC pc(Clk,Clrn,PC,Addr);
PCadd4 pcadd4(Addr,PCout);
INSTMEM instmem(Addr,Inst);
CONUNIT conunit(Inst[31:26],Inst[5:0],Z,Regrt,Se,Wreg,Aluqb,Aluc,Wmem,Pcsrc,Reg2reg);
MUX2X5 mux1(Inst[15:11],Inst[20:16],Regrt,Wr);
EXT16T32 ext1(Inst[15:0],Se,EXTout);
SHIFTER_addr shifter1(Inst[25:0],PC,SHIFTout1);
SHIFTER_32 shifter2(EXTout,2,0,0,SHIFTout2); 
REGFILE regfile(Inst[25:21],Inst[20:16],D,Wr,Wreg,Clk,Clrn,Qa,Qb);
MUX2X32 mux2(EXTout,Qb,Aluqb,Y);
ALU alu(Qa,Y,Aluc,R,Z);
DATAMEM datamem(R,Qb,Clk,Wmem,Dout);
MUX2X32 mux4(Dout,R,Reg2reg,D);
CLA_32 cla_32(PCout,SHIFTout2,0,CLAout,Cout);
MUX4X32 mux3(PCout,0,CLAout,SHIFTout1,Pcsrc,PC);
assign NPC=PC;
assign ALU_R=R;
endmodule

最后贴上测试代码:

`timescale 100us/1us
module CPU_tb;
reg clk,clrn;
wire [31:0] addr,inst,qa,qb,alur,npc,d;
CPU CPU(.Clk(clk),.Clrn(clrn),.Addr(addr),.Inst(inst),.Qa(qa),.Qb(qb),.ALU_R(alur),.NPC(npc),.D(d));
initial begin        
clk=0;
clrn=0;
#100
clrn<=1;end
always #100 clk=~clk;
endmodule

最后贴上仿真结果总图:

  • 8
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
基于单/多周期MIPS指令系统的CPU设计与仿真计算机工程领域中非常重要的一项研究工作。在此方面的研究主要围绕着如何设计和实现MIPS指令集体系结构的处理器,其目的是加速数据的处理和增强计算机的性能。 在CPU设计中,单/多周期指的是CPU执行指令时需要的CPU时钟周期数。单周期指令系统的CPU设计最为简单,每个指令都需要一个时钟周期,但多周期指令系统则需要更多的时钟周期。多周期指令系统需要比单周期指令系统更高的时钟频率,因为它需要进行更多的时钟周期,但其优点在于具有更高的性能,在短时间内能够执行更多的指令。因此,在设计CPU时,需根据具体应用场景选择单周期或多周期指令系统。 在进行CPU设计时,需要考虑多个方面的因素,例如指令识别、数据通路、流水线设计、存储器设计等。其中,指令识别是CPU设计中重要的一个环节,需要实现对MIPS指令集的解码。数据通路设计需要将各个部件连接在一起,如ALU、寄存器等。流水线设计可以提高CPU的运行效率,允许多个指令同时被处理,提高了CPU的吞吐量。存储器设计可以用于存储指令和数据。 CPU设计完成后,需要进行仿真来验证其功能和正确性。在仿真过程中,需要考虑各种异常情况,例如数据的歧义、存储器访问冲突等。通过仿真验证CPU的正确性可以保证其可以正常使用。 总之,基于单/多周期MIPS指令系统的CPU设计与仿真是现代计算机工程领域中非常重要的一项研究工作。在此方面的研究不断推动着计算机技术的不断发展,进一步加强了计算机的处理能力和性能。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值