计算机组成原理实验报告

一、 实验内容

在本次实验中,将使用Verilog HDL实现31条MIPS指令的CPU的设计、前仿真、后仿真和下板调试运行。

二、 数据通路

(一)单独数据通路:

1 ADD

格式:ADD rd, rs, rt

操作:取指令,rd←rs+rt, PC←NPC(PC+4)

所需部件:PC, NPC, IMEM, Regfile, ALU

输入输出关系:

2 ADDU

格式:ADDU rd, rs, rt

操作:取指令,rd←rs+rt, PC←NPC(PC+4)

所需部件:PC, NPC, IMEM, Regfile, ALU

输入输出关系:

3 SUB

格式:SUB rd, rs, rt

操作:取指令,rd←rs-rt, PC←NPC(PC+4)

所需部件:PC, NPC, IMEM, Regfile, ALU

输入输出关系:

4 SUBU

格式:SUBU rd, rs, rt

操作:取指令,rd←rs-rt, PC←NPC(PC+4)

所需部件:PC, NPC, IMEM, Regfile, ALU

输入输出关系:

5 AND

格式:AND rd, rs, rt

操作:取指令,rd←rs & rt, PC←NPC(PC+4)

所需部件:PC, NPC, IMEM, Regfile, ALU

输入输出关系:

6 OR

格式:OR rd, rs, rt

操作:取指令,rd←rs | rt, PC←NPC(PC+4)

所需部件:PC, NPC, IMEM, Regfile, ALU

输入输出关系:

7 XOR

格式:XOR rd, rs, rt

操作:取指令,rd←rs ^ rt, PC←NPC(PC+4)

所需部件:PC, NPC, IMEM, Regfile, ALU

输入输出关系:

8 NOR

格式:NOR rd, rs, rt

操作:取指令,rd←~(rs | rt), PC←NPC(PC+4)

所需部件:PC, NPC, IMEM, Regfile, ALU

输入输出关系:

9 SLT

格式:SLT rd, rs, rt

操作:取指令,rd← rs < rt , PC←NPC(PC+4)

所需部件:PC, NPC, IMEM, Regfile, ALU

输入输出关系:

10 SLTU

格式:SLTU rd, rs, rt

操作:取指令,rd← rs < rt , PC←NPC(PC+4)

所需部件:PC, NPC, IMEM, Regfile, ALU

输入输出关系:

11 SLL

格式:SLL rd, rt, sa

操作:取指令, rd←rt << sa , PC←NPC(PC+4)

所需部件:PC, NPC, IMEM, Regfile, ALU, Ext5

输入输出关系:

12 SRL

格式:SRL rd, rt, sa

操作:取指令, rd←rt >> sa (logical) , PC←NPC(PC+4)

所需部件:PC, NPC, IMEM, Regfile, ALU, Ext5

输入输出关系:

13 SRA

格式:SRA rd, rt, sa

操作:取指令, rd←rt >> sa (arithmetic) , PC←NPC(PC+4)

所需部件:PC, NPC, IMEM, Regfile, ALU, Ext5

输入输出关系:

14 SLLV

格式:SLLV rd, rt, rs,

操作:取指令, rd←rt << rs  , PC←NPC(PC+4)

所需部件:PC, NPC, IMEM, Regfile, ALU

输入输出关系:

15 SRLV

格式:SRLV rd, rt,rs

操作:取指令, rd←rt >> rs (logical) , PC←NPC(PC+4)

所需部件:PC, NPC, IMEM, Regfile, ALU

输入输出关系:

16 SRAV

格式:SRAV rd, rt,rs

操作:取指令, rd←rt >> rs (arithmetic) , PC←NPC(PC+4)

所需部件:PC, NPC, IMEM, Regfile, ALU

输入输出关系:

17 JR

格式:JR rs

操作:取指令, PC←rs,  PC←NPC(PC+4)

所需部件:PC, NPC, IMEM, Regfile

输入输出关系:

18 ADDI

格式:ADDI rt, rs, imm16

操作:取指令、rt←rs+imm16(sign_extend) 、PC←NPC(PC+4)

所需部件::PC、NPC、IMEM、Rregfile、ALU、Ext16

输入输出关系:

19 ADDIU

格式:ADDIU rt, rs, imm16

操作:取指令、rt←rs+imm16(sign_extend) 、PC←NPC(PC+4)

所需部件:PC、NPC、IMEM、Rregfile、ALU、Ext16

输入输出关系:

20 ANDI

格式:ANDI rt, rs, imm16

操作:取指令、rt←rs&imm16(zero_extend) 、PC←NPC(PC+4)

所需部件:PC、NPC、IMEM、Rregfile、ALU、Ext16

输入输出关系:

21 ORI

格式:ORI rt, rs, imm16

操作:取指令、rt←rs|imm16(zero_extend) 、PC←NPC(PC+4)

所需部件:PC、NPC、IMEM、Rregfile、ALU、Ext16

输入输出关系:

22 XORI

格式:XORI rt, rs, imm16

操作:取指令、rt←rs^imm16(zero_extend) 、PC←NPC(PC+4)

所需部件:PC、NPC、IMEM、Rregfile、ALU、Ext16

输入输出关系:

23 LW

格式:LW rt, offset(base)

操作:取指令、rt←memory[rs + offset]、PC←NPC(PC+4)

所需部件:PC、NPC、IMEM、ALU、Ext16、DMEM

输入输出关系:

24 SW

格式:SW rt, offset(base)

操作:取指令、memory[base + offset]←rt、PC←NPC(PC+4)

所需部件:PC、NPC、IMEM、ALU、Ext16、DMEM

输入输出关系:

25 BEQ

格式:BEQ rs, rt, offset

操作: if (rs=rt)PC←NPC + Sign_ext(offset||02)

else PC← NPC(PC+4)

所需部件:PC、NPC、IMEM、Regfile、ALU、Ext18、ADD

输入输出关系:

26 BNE

格式:BNE rs, rt, offset

操作:if (rs≠rt)PC←NPC + Sign_ext(offset||02)

else PC← NPC(PC+4)

所需部件:PC、NPC、IMEM、Regfile、ALU、Ext18、ADD

输入输出关系:

27 SLTI

格式:SLTI rt, rs, imm16

操作:取指令、rt←rs < ext.imm16(sign_extend) 、PC←NPC(PC+4)

所需部件:PC、NPC、IMEM、Rregfile、ALU、Ext16

输入输出关系:

28 SLTIU

格式:SLTIU rt, rs, imm16

操作:取指令、rt←rs < ext.imm16(sign_extend) 、PC←NPC(PC+4)

所需部件:PC、NPC、IMEM、Rregfile、ALU、Ext16

输入输出关系:

29 LUI

格式:LUI rt, imm16

操作:取指令、rt←imm16||016 、PC←NPC(PC+4)

所需部件:PC、NPC、IMEM、Rregfile、ALU、Ext16

输入输出关系:

30 J

格式:J target

操作:取指令、PC ← PC31-28||instr_index||02 , PC←NPC(PC+4)

所需部件:PC、NPC、IMEM

输入输出关系:

31 JAL

格式:JAL target

操作:取指令、 R[31] ← PC + 8,PC ← PC31-28||instr_index||02 , PC←PC+4

所需部件::PC、NPC、IMEM

输入输出关系:

(二)整个数据通路

(三)部件表:

31条指令CPU所需部件及数据通路图

三、 模块建模

3.1 顶层模块sccomp_dataflow,调用cpu,imem和dram
module sccomp_dataflow(
    input clk_in,
    input reset,
    output [31:0] inst,
    output [31:0] pc
    );
    wire [31:0] imm;
    wire [31:0] Rt;
    wire [31:0] alu_r;
    wire cs;
    wire dm_w;
    wire dm_r;
    wire [31:0] ram_out;
    assign inst=imm;

    imem imem(((pc- 32'h00400000)/4),imm);
    //imem im(pc,inst)
    //IMEM imem(1,((pc- 32'h00400000)/4),imm);

    cpu sccpu(clk_in,reset,imm,ram_out, //input
                Rt,alu_r,pc,cs,dm_w,dm_r); //output

    DMEM dram(
    .clk(clk_in),
    .CS(cs),  //enable control signal
    .DM_W(dm_w), //write
    .DM_R(dm_r), //read
    .Addr((alu_r[9:0]-32'h10010000)/4),
    .Data_in(Rt),
    .Data_out(ram_out)
     );   
    
endmodule
3.2 cpu模块 发送控制信号
module cpu(
    input clk_in,
    input reset,
    input [31:0]imem,//
    input [31:0] ram_out,
    output [31:0] Rt,
    output [31:0] alu_r,
    output [31:0] pc,
    output cs, //dmem control signal 
    output dm_w, //dmem write
    output dm_r//dmem read
    );
    
    wire [31:0]npc;
    wire M3,M3_2,M4,M4_2, M2,M5,M1,M1_2,M6,M7; //mux2
    wire ALUC3,ALUC2,ALUC1,ALUC0;
    wire RF_W; //regfiles write
    wire RL_CLK; //regfiles clk

    wire [3:0]ALUC;//alu control
    wire [31:0] PC;
    wire [31:0] mux_out_1;
    wire [31:0] mux_out_1_2;
    wire [31:0] mux_out_2;
    wire [31:0] mux_out_3;
    wire [31:0] mux_out_3_2;
    
    wire [31:0] mux_in_4;
    wire [31:0] mux_out_4;
    wire [31:0] mux_out_4_2;
    wire [31:0] mux_out_5;
    
    wire [31:0] Rs; //Rs

    wire [31:0] ext18_sign;
    wire [4:0] rdc;
    wire [4:0] rsc;
    wire [4:0] rtc;
    wire [31:0] ext16;
    wire [31:0] ext16_sign;
    wire ext16_sin_judge;
    
    
    wire zero;
    wire carry;
    wire negative;
    wire overflow;
    
    assign pc = PC;
    //assign RDC_T = rdc;
    assign  mux_out_2_T=mux_out_2;

 wire _add, _addu, _sub, _subu, _and, _or, _xor, _nor;
   wire _slt, _sltu, _sll, _srl, _sra, _sllv, _srlv, _srav, _jr;
   wire  _addi, _addiu, _andi, _ori, _xori, _lw, _sw;
   wire _beq, _bne, _slti, _sltiu, _lui, _j, _jal;
   
   //1~17
   assign _add = (imem[31:26]==6'b000000&&imem[5:0]==6'b100000)?1'b1:1'b0;
   assign _addu = (imem[31:26]==6'b000000&&imem[5:0]==6'b100001)?1'b1:1'b0;
   assign _sub = (imem[31:26]==6'b000000&&imem[5:0]==6'b100010)?1'b1:1'b0;
   assign _subu = (imem[31:26]==6'b000000&&imem[5:0]==6'b100011)?1'b1:1'b0;
   assign _and = (imem[31:26]==6'b000000&&imem[5:0]==6'b100100)?1'b1:1'b0;
   assign _or = (imem[31:26]==6'b000000&&imem[5:0]==6'b100101)?1'b1:1'b0;
   assign _xor = (imem[31:26]==6'b000000&&imem[5:0]==6'b100110)?1'b1:1'b0;
   assign _nor = (imem[31:26]==6'b000000&&imem[5:0]==6'b100111)?1'b1:1'b0;
   
   assign _slt = (imem[31:26]==6'b000000&&imem[5:0]==6'b101010)?1'b1:1'b0;
   assign _sltu = (imem[31:26]==6'b000000&&imem[5:0]==6'b101011)?1'b1:1'b0;
   assign _sll = (imem[31:26]==6'b000000&&imem[5:0]==6'b000000)?1'b1:1'b0;
   assign _srl = (imem[31:26]==6'b000000&&imem[5:0]==6'b000010)?1'b1:1'b0;
   assign _sra = (imem[31:26]==6'b000000&&imem[5:0]==6'b000011)?1'b1:1'b0;
   assign _sllv = (imem[31:26]==6'b000000&&imem[5:0]==6'b000100)?1'b1:1'b0;
   assign _srlv = (imem[31:26]==6'b000000&&imem[5:0]==6'b000110)?1'b1:1'b0;
   assign _srav = (imem[31:26]==6'b000000&&imem[5:0]==6'b000111)?1'b1:1'b0;
   assign _jr = (imem[31:26]==6'b000000&&imem[5:0]==6'b001000)?1'b1:1'b0;
   
   //18~29
   assign _addi = (imem[31:26]==6'b001000)?1'b1:1'b0;
   assign _addiu = (imem[31:26]==6'b001001)?1'b1:1'b0;
   assign _andi = (imem[31:26]==6'b001100)?1'b1:1'b0;
   assign _ori = (imem[31:26]==6'b001101)?1'b1:1'b0;
   assign _xori = (imem[31:26]==6'b001110)?1'b1:1'b0;
   assign _lw = (imem[31:26]==6'b100011)?1'b1:1'b0;
   assign _sw = (imem[31:26]==6'b101011)?1'b1:1'b0;
   assign _beq = (imem[31:26]==6'b000100)?1'b1:1'b0;
   assign _bne = (imem[31:26]==6'b000101)?1'b1:1'b0;
   assign _slti = (imem[31:26]==6'b001010)?1'b1:1'b0;
   assign _sltiu = (imem[31:26]==6'b001011)?1'b1:1'b0;
   assign _lui = (imem[31:26]==6'b001111)?1'b1:1'b0;
   
   //30 31
   assign _j = (imem[31:26]==6'b000010)?1'b1:1'b0;
   assign _jal = (imem[31:26]==6'b000011)?1'b1:1'b0;
   
   wire exception;
   wire [4:0] cause;
   wire wdata;
   assign wdata = Rt;
   wire [31:0] rdata; 
   wire [31:0] status;
   wire [31:0] exc_addr;  //un
   
   //Control signal expression
   assign M3 = _sll || _srl || _sra ;
   assign M3_2 = _jal ;
   assign M4 = _addi || _addiu || _andi || _ori || _xori || _slti || _sltiu || _lui || _lw || _sw ;
   assign M4_2 = _jal ;
   assign M6 =_addi||_addiu||_andi||_ori||_xori|||_slti||_sltiu||_lui||_lw;//||_mfc0;
   assign M7 =_jal;
   assign ALUC[3] = _slt || _sltu ||_sllv || _srlv || _srav || _sll || _srl || _sra || _slti || _sltiu || _lui ;
   assign ALUC[2] = _and || _or ||_xor || _nor || _sllv || _srlv || _srav || _sll || _srl || _sra || _andi || _ori || _xori ;
   assign ALUC[1] = _add || _sub ||_xor || _nor || _slt || _sltu || _sllv || _sll || _addi || _xori || _slti || _sltiu ;
   assign ALUC[0] = _sub || _subu ||_or || _nor || _slt || _srlv || _srl || _ori || _slti || _beq || _bne ;//||_teq;//cp0 teq
   assign M2 = !_lw;
   assign rdc = M6?imem[20:16]:(M7?5'd31:imem[15:11]);
   assign RF_W= (!_sw)&&(!_beq)&&(!_bne)&&(!_j)&&(!_jr);
   assign RL_CLK= ((!_sw)&&(!_beq)&&(!_bne)&&(!_j)&&(!_jal)&&(!_jr))&&clk_in;
   assign M5 = (_beq&&zero) || (_bne&&(!zero)) ;
   assign M1 = (!_j)&&(!_jal) ;
   assign M1_2 = _jr ;
   assign cs = _lw || _sw;
   assign dm_r = _lw;
   assign dm_w = _sw;
   assign ext16_sin_judge = _addi || _addiu || _slti||_sltiu || _lw; //sign_ext
   
    assign ext18_sign = {{14{imem[15]}},{imem[15:0],2'h0}};
    assign npc = PC + 4;
    assign ext16_sign = {{16{imem[15]}},imem[15:0]};//
    assign ext16 = {16'h0,imem[15:0]};
    assign mux_in_4 = ext16_sin_judge?ext16_sign:ext16;
    assign rsc = imem[25:21];
    assign rtc = imem[20:16];
    
assign mux_out_1=M1?mux_out_5:{PC[31:28],imem[25:0],2'b00};  //mux1
  
assign mux_out_1_2=M1_2?Rs:mux_out_1; //mux1_2

assign mux_out_2=M2?alu_r:ram_out; //mux2  

assign mux_out_3=M3?{27'b0,imem[10:6]}:Rs;

assign mux_out_3_2=M3_2?PC:mux_out_3;

assign mux_out_4=M4?mux_in_4:Rt;

assign mux_out_4_2=M4_2?32'd4:mux_out_4;

assign mux_out_5=M5?ext18_sign+npc:npc;

pcreg PCreg(
.clk(clk_in),
.rst(reset),
.ena(1),
//.wena(1),
.data_in(mux_out_1_2),
.data_out(PC)
);

regfile cpu_ref(
.clk(clk_in),
.rst(reset),
.ena(1),
.we(RF_W),
.raddr1(rsc), //rsc
.raddr2(rtc),//rtc
.waddr(rdc),  //rdc 5bits
.wdata(mux_out_2), //rd
.rdata1(Rs), //rs
.rdata2(Rt) //rt
        );
        
ALU alu(
.a(mux_out_3_2),
.b(mux_out_4_2),
.aluc(ALUC),
.r(alu_r),
.zero(zero),
.carry(carry),
.negative(negative),
.overflow(overflow)
            );

endmodule
3.3 dmem模块
module DMEM(
    input clk,
    input CS,  //enable control signal
    input DM_W, //write
    input DM_R, //read
    input [9:0] Addr,
    input [31:0] Data_in,
    output  [31:0] Data_out
    );
    
reg [31:0] num [0:31];   
    assign Data_out=CS? (DM_R? num[Addr]: 32'h00000000):32'bzzzz_zzzz_zzzz_zzzz_zzzz_zzzz_zzzz_zzzz;
    always@(negedge clk or negedge CS)
    begin
    if(CS&&DM_W)num[Addr]<=Data_in;
    end
endmodule
3.4 ALU负责完成各类计算
module ALU(
        input [31:0] a,        //OP1
        input [31:0] b,        //OP2
        input [3:0] aluc,    //controller
        output [31:0] r,    //result
        output zero,
        output carry,
        output negative,
        output overflow);
        
    parameter Addu    =    4'b0000;    //r=a+b unsigned
    parameter Add    =    4'b0010;    //r=a+b signed
    parameter Subu    =    4'b0001;    //r=a-b unsigned
    parameter Sub    =    4'b0011;    //r=a-b signed
    parameter And    =    4'b0100;    //r=a&b
    parameter Or    =    4'b0101;    //r=a|b
    parameter Xor    =    4'b0110;    //r=a^b
    parameter Nor    =    4'b0111;    //r=~(a|b)
    parameter Lui1    =    4'b1000;    //r={b[15:0],16'b0}
    parameter Lui2    =    4'b1001;    //r={b[15:0],16'b0}
    parameter Slt    =    4'b1011;    //r=(a-b<0)?1:0 signed
    parameter Sltu    =    4'b1010;    //r=(a-b<0)?1:0 unsigned
    parameter Sra    =    4'b1100;    //r=b>>>a 
    parameter Sll    =    4'b1110;    //r=b<<a
    parameter Srl    =    4'b1101;    //r=b>>a
    
    parameter bits=31;
    parameter ENABLE=1,DISABLE=0;
    
    reg [32:0] result;
    wire signed [31:0] sa=a,sb=b;
    
    always@(*)begin
        case(aluc)
            Addu: begin
                result=a+b;
            end
            Subu: begin
                result=a-b;
            end
            Add: begin
                result=sa+sb;
            end
            Sub: begin
                result=sa-sb;
            end
            Sra: begin
                if(a==0) {result[31:0],result[32]}={b,1'b0};
                else {result[31:0],result[32]}=sb>>>(a-1);
            end
            Srl: begin
                if(a==0) {result[31:0],result[32]}={b,1'b0};
                else {result[31:0],result[32]}=b>>(a-1);
            end
            Sll: begin
                result=b<<a;
            end
            And: begin
                result=a&b;
            end
            Or: begin
                result=a|b;
            end
            Xor: begin
                result=a^b;
            end
            Nor: begin
                result=~(a|b);
            end
            Sltu: begin
                result=a<b?1:0;
            end
            Slt: begin
                result=sa<sb?1:0;
            end
            Lui1,Lui2: result = {b[15:0], 16'b0};
            default:
                result=a+b;
        endcase
    end
    
    assign r=result[31:0];
    assign carry = result[32]; 
    assign zero=(r==32'b0)?1:0;
    assign negative=result[31];
    assign overflow=result[32];
endmodule
3.5 regfiles模块
module regfile(
 input clk,    
 input rst,
 input ena,    
 input we, 
 input [4:0] raddr1,  
 input [4:0] raddr2, 
 input [4:0] waddr,   
 input  [31:0] wdata, 
 output wire [31:0] rdata1,
 output wire [31:0] rdata2
);

reg [31:0]array_reg[31:0];
assign rdata1 = ena?array_reg[raddr1]:32'bz;
assign rdata2 = ena?array_reg[raddr2]:32'bz;
    always @(negedge clk or posedge rst)
    //always @(posedge clk or posedge rst)
        begin
        if (rst) begin
        array_reg[0] <= 32'h0;
        array_reg[1] <= 32'h0;
        array_reg[2] <= 32'h0;
        array_reg[3] <= 32'h0;
        array_reg[4] <= 32'h0;
        array_reg[5] <= 32'h0;
        array_reg[6] <= 32'h0;
        array_reg[7] <= 32'h0;
        array_reg[8] <= 32'h0;
        array_reg[9] <= 32'h0;
        array_reg[10] <= 32'h0;
        array_reg[11] <= 32'h0;
        array_reg[12] <= 32'h0;
        array_reg[13] <= 32'h0;
        array_reg[14] <= 32'h0;
        array_reg[15] <= 32'h0;
        array_reg[16] <= 32'h0;
        array_reg[17] <= 32'h0;
        array_reg[18] <= 32'h0;
        array_reg[19] <= 32'h0;
        array_reg[20] <= 32'h0;
        array_reg[21] <= 32'h0;
        array_reg[22] <= 32'h0;
        array_reg[23] <= 32'h0;
        array_reg[24] <= 32'h0;
        array_reg[25] <= 32'h0;
        array_reg[26] <= 32'h0;
        array_reg[27] <= 32'h0;
        array_reg[28] <= 32'h0;
        array_reg[29] <= 32'h0;
        array_reg[30] <= 32'h0;
        array_reg[31] <= 32'h0;
        end
        else if ((ena&we)&& (waddr != 0))
            array_reg[waddr] <= wdata;
    end
endmodule
3.6 pc寄存器
module pcreg(clk,rst,ena,data_in,data_out);
    input clk;
    input rst;
    input ena;
    input [31:0]data_in;
    output reg[31:0]data_out;
   wire [31:0]data;
   always@(*) 
   begin
   if(ena==1)
   data_out=data;
   else
   data_out=data_out;
   end
    Asynchronous_D_FF DFF0(.CLK(clk),.D(data_in[0]),.RST_n(rst),.Q1(data[0]));
    Asynchronous_D_FF DFF1(.CLK(clk),.D(data_in[1]),.RST_n(rst),.Q1(data[1]));
    Asynchronous_D_FF DFF2(.CLK(clk),.D(data_in[2]),.RST_n(rst),.Q1(data[2]));
    Asynchronous_D_FF DFF3(.CLK(clk),.D(data_in[3]),.RST_n(rst),.Q1(data[3]));
    Asynchronous_D_FF DFF4(.CLK(clk),.D(data_in[4]),.RST_n(rst),.Q1(data[4]));
    Asynchronous_D_FF DFF5(.CLK(clk),.D(data_in[5]),.RST_n(rst),.Q1(data[5]));
    Asynchronous_D_FF DFF6(.CLK(clk),.D(data_in[6]),.RST_n(rst),.Q1(data[6]));
    Asynchronous_D_FF DFF7(.CLK(clk),.D(data_in[7]),.RST_n(rst),.Q1(data[7]));
    Asynchronous_D_FF DFF8(.CLK(clk),.D(data_in[8]),.RST_n(rst),.Q1(data[8]));
    Asynchronous_D_FF DFF9(.CLK(clk),.D(data_in[9]),.RST_n(rst),.Q1(data[9]));
    Asynchronous_D_FF DFF10(.CLK(clk),.D(data_in[10]),.RST_n(rst),.Q1(data[10]));
    Asynchronous_D_FF DFF11(.CLK(clk),.D(data_in[11]),.RST_n(rst),.Q1(data[11]));
    Asynchronous_D_FF DFF12(.CLK(clk),.D(data_in[12]),.RST_n(rst),.Q1(data[12]));
    Asynchronous_D_FF DFF13(.CLK(clk),.D(data_in[13]),.RST_n(rst),.Q1(data[13]));
    Asynchronous_D_FF DFF14(.CLK(clk),.D(data_in[14]),.RST_n(rst),.Q1(data[14]));
    Asynchronous_D_FF DFF15(.CLK(clk),.D(data_in[15]),.RST_n(rst),.Q1(data[15]));
    Asynchronous_D_FF DFF16(.CLK(clk),.D(data_in[16]),.RST_n(rst),.Q1(data[16]));
    Asynchronous_D_FF DFF17(.CLK(clk),.D(data_in[17]),.RST_n(rst),.Q1(data[17]));
    Asynchronous_D_FF DFF18(.CLK(clk),.D(data_in[18]),.RST_n(rst),.Q1(data[18]));
    Asynchronous_D_FF DFF19(.CLK(clk),.D(data_in[19]),.RST_n(rst),.Q1(data[19]));
    Asynchronous_D_FF DFF20(.CLK(clk),.D(data_in[20]),.RST_n(rst),.Q1(data[20]));
    Asynchronous_D_FF DFF21(.CLK(clk),.D(data_in[21]),.RST_n(rst),.Q1(data[21]));
    Asynchronous_D_FF1 DFF22(.CLK(clk),.D(data_in[22]),.RST_n(rst),.Q1(data[22]));//reset==1
    Asynchronous_D_FF DFF23(.CLK(clk),.D(data_in[23]),.RST_n(rst),.Q1(data[23]));
    Asynchronous_D_FF DFF24(.CLK(clk),.D(data_in[24]),.RST_n(rst),.Q1(data[24]));
    Asynchronous_D_FF DFF25(.CLK(clk),.D(data_in[25]),.RST_n(rst),.Q1(data[25]));
    Asynchronous_D_FF DFF26(.CLK(clk),.D(data_in[26]),.RST_n(rst),.Q1(data[26]));
    Asynchronous_D_FF DFF27(.CLK(clk),.D(data_in[27]),.RST_n(rst),.Q1(data[27]));
    Asynchronous_D_FF DFF28(.CLK(clk),.D(data_in[28]),.RST_n(rst),.Q1(data[28]));
    Asynchronous_D_FF DFF29(.CLK(clk),.D(data_in[29]),.RST_n(rst),.Q1(data[29]));
    Asynchronous_D_FF DFF30(.CLK(clk),.D(data_in[30]),.RST_n(rst),.Q1(data[30]));
    Asynchronous_D_FF DFF31(.CLK(clk),.D(data_in[31]),.RST_n(rst),.Q1(data[31]));
    
Endmodule

四、测试模块建模

cpu_tb
module CPU_tb();
	reg clk;
	reg rst;
	wire [31:0] inst;
	wire [31:0] pc;	

	//integer file_output;
	//integer counter = 0;
	

	sccomp_dataflow uut(.clk_in(clk),.reset(rst),.inst(inst),.pc(pc)//,.addr(addr)
	);
	

	    initial
	    begin
	     //  file_output = $fopen("E:/result.txt");
	       clk = 0;
	       rst = 1;
	       #5;
	       rst = 0;
	   
	end
	

	always
	 begin
	#10;
	 clk = ~clk;
	//if (clk == 1'b0)
	//begin
	//if (counter == 1500)
	//begin
	 //$fclose(file_output);
	//end 
	//#4
	 //   counter = counter + 1;
	  //  if (counter > 600)
	  // begin
	    //$fdisplay(file_output,"pc:%h",pc-32'h00400000);
	  //  $fdisplay(file_output,"pc:%h",pc);
	   // $fdisplay(file_output,"instr:%h",uut.inst);
	    //$fdisplay(file_output,"regfile0: %h",uut.sccpu.cpu_ref.array_reg[0]);
	    //$fdisplay(file_output,"regfile1: %h",uut.sccpu.cpu_ref.array_reg[1]);
	    //$fdisplay(file_output,"regfile2: %h",uut.sccpu.cpu_ref.array_reg[2]);
	    //$fdisplay(file_output,"regfile3: %h",uut.sccpu.cpu_ref.array_reg[3]);
	    //$fdisplay(file_output,"regfile4: %h",uut.sccpu.cpu_ref.array_reg[4]);
	    //$fdisplay(file_output,"regfile5: %h",uut.sccpu.cpu_ref.array_reg[5]);
	    //$fdisplay(file_output,"regfile6: %h",uut.sccpu.cpu_ref.array_reg[6]);
	    //$fdisplay(file_output,"regfile7: %h",uut.sccpu.cpu_ref.array_reg[7]);
	    //$fdisplay(file_output,"regfile8: %h",uut.sccpu.cpu_ref.array_reg[8]);
	    //$fdisplay(file_output,"regfile9: %h",uut.sccpu.cpu_ref.array_reg[9]);
	    //$fdisplay(file_output,"regfile10: %h",uut.sccpu.cpu_ref.array_reg[10]);
	    //$fdisplay(file_output,"regfile11: %h",uut.sccpu.cpu_ref.array_reg[11]);
	    //$fdisplay(file_output,"regfile12: %h",uut.sccpu.cpu_ref.array_reg[12]);
	    //$fdisplay(file_output,"regfile13: %h",uut.sccpu.cpu_ref.array_reg[13]);
	    //$fdisplay(file_output,"regfile14: %h",uut.sccpu.cpu_ref.array_reg[14]);
	    //$fdisplay(file_output,"regfile15: %h",uut.sccpu.cpu_ref.array_reg[15]);
	    //$fdisplay(file_output,"regfile16: %h",uut.sccpu.cpu_ref.array_reg[16]);
	    //$fdisplay(file_output,"regfile17: %h",uut.sccpu.cpu_ref.array_reg[17]);
	    //$fdisplay(file_output,"regfile18: %h",uut.sccpu.cpu_ref.array_reg[18]);
	    //$fdisplay(file_output,"regfile19: %h",uut.sccpu.cpu_ref.array_reg[19]);
	    //$fdisplay(file_output,"regfile20: %h",uut.sccpu.cpu_ref.array_reg[20]);
	    //$fdisplay(file_output,"regfile21: %h",uut.sccpu.cpu_ref.array_reg[21]);
	    //$fdisplay(file_output,"regfile22: %h",uut.sccpu.cpu_ref.array_reg[22]);
	    //$fdisplay(file_output,"regfile23: %h",uut.sccpu.cpu_ref.array_reg[23]);
	    //$fdisplay(file_output,"regfile24: %h",uut.sccpu.cpu_ref.array_reg[24]);
	    //$fdisplay(file_output,"regfile25: %h",uut.sccpu.cpu_ref.array_reg[25]);
	    //$fdisplay(file_output,"regfile26: %h",uut.sccpu.cpu_ref.array_reg[26]);
	    //$fdisplay(file_output,"regfile27: %h",uut.sccpu.cpu_ref.array_reg[27]);
	    //$fdisplay(file_output,"regfile28: %h",uut.sccpu.cpu_ref.array_reg[28]);
	    //$fdisplay(file_output,"regfile29: %h",uut.sccpu.cpu_ref.array_reg[29]);
	    //$fdisplay(file_output,"regfile30: %h",uut.sccpu.cpu_ref.array_reg[30]);
	    //$fdisplay(file_output,"regfile31: %h",uut.sccpu.cpu_ref.array_reg[31]);
	  // end
	//end
	end
	

	endmodule

在测试时,只需要修改cpu_tb以及IMEM的相应文件路径即可

module IMEM(
    input IM_R, //read
    input [9:0] Addr,
    output reg [31:0] data_out
    );
     reg [31:0] mem[1023:0];    
        initial begin
        $readmemh("E:/31test/intrs/_4_jr.txt",mem);
        end
       always @ (*)
       begin
         if(!IM_R) 
            begin
            data_out <= 32'hzzzz_zzzz;
            end
         else // read data
           data_out <= mem[Addr];
       end
   endmodule

使用$readmemh初始化IMEM,读取相应的指令,进行测试

五、实验结果

5.1前仿真测试

5.2后仿真测试

5.3 下板测试

Inst:

PC:

Logo

魔乐社区(Modelers.cn) 是一个中立、公益的人工智能社区,提供人工智能工具、模型、数据的托管、展示与应用协同服务,为人工智能开发及爱好者搭建开放的学习交流平台。社区通过理事会方式运作,由全产业链共同建设、共同运营、共同享有,推动国产AI生态繁荣发展。

更多推荐