Verilog 数字电路设计之带hazard的五级流水线CPU

设计目标

Verilog 数字电路设计之带hazard的五级流水线CPU_第1张图片

指令组成

一条指令由16bits组成,高5位是操作码,代表不同的操作类型;低11位是操作数,分为3部分,10:8位作为标号,代表寄存器堆里的某一个寄存器;3:0位与7:4位既可以像10:8位一样作为寄存器标号,也可以作为具体的某一个数值(称为立即数),具体根据指令来区分。
Verilog 数字电路设计之带hazard的五级流水线CPU_第2张图片

数据访问

Verilog 数字电路设计之带hazard的五级流水线CPU_第3张图片

简易CPU指令集

Verilog 数字电路设计之带hazard的五级流水线CPU_第4张图片
Verilog 数字电路设计之带hazard的五级流水线CPU_第5张图片
Verilog 数字电路设计之带hazard的五级流水线CPU_第6张图片

五级流水线

Verilog 数字电路设计之带hazard的五级流水线CPU_第7张图片

框图

Verilog 数字电路设计之带hazard的五级流水线CPU_第8张图片

Hazard

  • Data Hazard
    • Arithmetic
      Verilog 数字电路设计之带hazard的五级流水线CPU_第9张图片
      Solution: Data forwarding
      Verilog 数字电路设计之带hazard的五级流水线CPU_第10张图片
    • LOAD
      Verilog 数字电路设计之带hazard的五级流水线CPU_第11张图片
      Solution: Stall+Data forwarding
      Verilog 数字电路设计之带hazard的五级流水线CPU_第12张图片
  • Control Hazard
    During the time from branch instruction fetch to branch address generate (from IF to ID to EX to MEM, 3 stages), the 3 instructions followed by branch are in pipeline.
    Solution: Flush

Verilog代码

  • 顶层模块cpu.v
module cpu( input wire clk, enable, reset, start
); 

wire [15:0] d_datain; //data from memory 
wire [15:0] i_datain; //instruction
wire [7:0] d_addr;    //address for data memory
wire [15:0] d_dataout;//output data to data memory
wire d_we;            //write dm enable 
wire [7:0] i_addr;    //pc

PCPU pcpu(
    .clock(clk),
    .enable(enable),
    .reset(reset),
    .start(start),
    .d_datain(d_datain),
    .i_datain(i_datain),
    .d_addr(d_addr),
    .d_dataout(d_dataout),
    .d_we(d_we),
    .i_addr(i_addr)
);

I_mem i_mem(
    .addra(i_addr),
    .douta(i_datain)
);

D_mem d_mem(
    .wea(d_we),
    .addra(d_addr),
    .dina(d_dataout),
    .douta(d_datain)
);

endmodule
  • 头文件headfile.v
`ifndef HEADFILE_H_

`define idle 1'b0
`define exec 1'b1
`define NOP 5'b00000
`define HALT 5'b00001
`define LOAD 5'b00010
`define STORE 5'b00011
`define SLL 5'b00100
`define SLA 5'b00101
`define SRL 5'b00110
`define SRA 5'b00111
`define ADD 5'b01000
`define ADDI 5'b01001
`define SUB 5'b01010
`define SUBI 5'b01011
`define CMP 5'b01100
`define AND 5'b01101
`define OR 5'b01110
`define XOR 5'b01111
`define LDIH 5'b10000
`define ADDC 5'b10001
`define SUBC 5'b10010
`define JUMP 5'b11000
`define JMPR 5'b11001
`define BZ 5'b11010
`define BNZ 5'b11011
`define BN 5'b11100
`define BNN 5'b11101
`define BC 5'b11110
`define BNC 5'b11111
`define gr0 3'b000
`define gr1 3'b001
`define gr2 3'b010
`define gr3 3'b011
`define gr4 3'b100
`define gr5 3'b101
`define gr6 3'b110
`define gr7 3'b111 

`endif
  • 流水线cpu代码pcpu.v
`include "headfile.v"

module PCPU(input wire reset, enable, clock, start,
    input wire [15:0] d_datain,  //data from memory 
    i_datain,                    //instruction
    output wire [7:0] d_addr,    //address for data memory 
    output wire [7:0] i_addr,    //pc
    output wire [15:0] d_dataout,//output data to data memory 
    output wire d_we             //write enable 
    );
reg state,next_state;  //to control the CPU  
reg [7:0] pc;
reg [15:0] id_ir,ex_ir,mem_ir,wb_ir;
reg [15:0] reg_A, reg_B, reg_C, reg_C1, smdr, smdr1, ALUo; 
reg dw, zf, nf, cf, cin;
reg [15:0] gr[0:7];
assign d_dataout = smdr1;
assign d_we = dw;
assign d_addr = reg_C[7:0];
assign i_addr = pc;
//************* CPU control *************//
always @(posedge clock or negedge reset)
    begin
        if (!reset)
            state <= `idle;
        else
            state <= next_state;
    end
always @(*)
    begin
        case (state)
            `idle : 
                if ((enable == 1'b1) && (start == 1'b1)) // on
                    next_state <= `exec;
                else    
                    next_state <= `idle;
            `exec :
                if ((enable == 1'b0) || (wb_ir[15:11] == `HALT))//pause
                    next_state <= `idle;
                else
                    next_state <= `exec;
        endcase
    end

//************* IF *************// 取址
always @(posedge clock or negedge reset)
    begin
        if (!reset)
            begin
                id_ir <= 16'b0000_0000_0000_0000;
                pc <= 8'b0000_0000;
            end

        else if (state ==`exec)
            begin   
            if((ex_ir[15:11] == `BZ && zf == 1'b1) || (ex_ir[15:11] == `BN && nf == 1'b1)
                    ||(ex_ir[15:11] == `BNZ && zf == 1'b0) || (ex_ir[15:11] == `BNN && nf == 1'b0)
                     ||(ex_ir[15:11] == `BC && cin == 1'b1) || (ex_ir[15:11] == `BNC && cin == 1'b0)
                     || ex_ir[15:11] == `JMPR)
                    begin
                       pc <= ALUo[7:0];
                       id_ir <= 16'bx;//flush
                   end
                else if(id_ir[15:11] == `JUMP)
                   begin
                  pc <= id_ir[7:0]; //jump to {val2,val3}
                       id_ir <= 16'bx;
               end
                else if(id_ir[15:11] == `HALT) // STOP
                    begin 
                       pc <= pc; 
                       id_ir <= id_ir; 
                    end     
            //Load hazard  Stall    
                else if((id_ir[15:11] == `LOAD)&&(i_datain[15:11]!=`JUMP)&&(i_datain[15:11]!=`NOP)&&(i_datain[15:11]!=`HALT)
                  &&(i_datain[15:11]!=`LOAD)) 
                 begin
                      //r1
                   if((id_ir[10:8]==i_datain[2:0])&&((i_datain[15:11]==`ADD)||(i_datain[15:11]==`ADDC)
                       ||(i_datain[15:11]==`SUB)||(i_datain[15:11]==`SUBC)||(i_datain[15:11]==`CMP)||(i_datain[15:11]==`AND)
                        ||(i_datain[15:11]==`OR)||(i_datain[15:11]==`XOR)))
                       begin
                         pc <= pc;
                         id_ir <= 16'bx;
                       end
                      //r2
                    else if((id_ir[10:8]==i_datain[6:4])&&((i_datain[15:11]==`STORE)||(i_datain[15:11]==`ADD)
                      ||(i_datain[15:11]==`ADDC)||(i_datain[15:11]==`SUB)||(i_datain[15:11]==`SUBC)||(i_datain[15:11]==`AND)
                        ||(i_datain[15:11]==`OR)||(i_datain[15:11]==`XOR)||(i_datain[15:11]==`CMP)||(i_datain[15:11]==`SLL)
                        ||(i_datain[15:11]==`SRL)||(i_datain[15:11]==`SLA)||(i_datain[15:11]==`SRA)))
                       begin
                         pc <= pc;
                         id_ir <= 16'bx;
                       end
                      //r3
                   else if((id_ir[10:8]==i_datain[10:8])&&((i_datain[15:11]==`STORE)||(i_datain[15:11]==`LDIH)
                      ||(i_datain[15:11]==`SUBI)||(i_datain[15:11]==`JMPR)||(i_datain[15:11]==`BZ)||(i_datain[15:11]==`BNZ)
                       ||(i_datain[15:11]==`BN)||(i_datain[15:11]==`BNN)||(i_datain[15:11]==`BNC)||(i_datain[15:11]==`BNC)))
                       begin
                         pc <= pc;
                         id_ir <= 16'bx;
                       end
                      else
                         begin
                            pc <= pc + 1'b1;
                         id_ir <= i_datain;
                          end
                   end
                else
                   begin
                       pc <= pc + 1'b1;
                       id_ir <= i_datain;
                    end
            end
         else if(state==`idle)
                begin
                   id_ir <= id_ir;
                    pc <= pc;
                end         
    end
//************* ID *************//译码
always @(posedge clock or negedge reset)
    begin
        if (!reset)
            begin
                ex_ir <= 16'b0000_0000_0000_0000;
                reg_A <= 16'b0000_0000_0000_0000;
                reg_B <= 16'b0000_0000_0000_0000; 
                smdr <= 16'b0000_0000_0000_0000;
            end
        //flush
        else if(state == `exec && ((ex_ir[15:11]==`BZ && zf==1'b1) ||(ex_ir[15:11]==`BNZ && zf==1'b0) 
              ||(ex_ir[15:11]==`BN && nf==1'b1) || (ex_ir[15:11]==`BNN && nf==1'b0) ||(ex_ir[15:11]==`BC && cin==1'b1)
            ||(ex_ir[15:11]==`BNC && cin==1'b0) || ex_ir[15:11]==`JMPR))
              ex_ir <= 16'bx;

      else if (state == `exec)
            begin
                ex_ir <= id_ir;
               //regA
               //r1=r1+{val2,val3}
                if ((id_ir[15:11] == `BZ) || (id_ir[15:11] == `BNZ) || (id_ir[15:11] == `BN) || (id_ir[15:11] == `BNN) 
                  || (id_ir[15:11] == `BC) || (id_ir[15:11] == `BNC) || (id_ir[15:11] == `LDIH) || (id_ir[15:11] == `ADDI) 
                  || (id_ir[15:11] == `SUBI) || (id_ir[15:11] == `JMPR)) 
                  begin
                    //r1未写回
                   if(id_ir[10:8]==ex_ir[10:8]&&(ex_ir[15:11] == `ADD || ex_ir[15:11] == `LDIH || ex_ir[15:11] == `ADDI || ex_ir[15:11] == `SUB
                          || ex_ir[15:11] == `SUBI || ex_ir[15:11] == `ADDC || ex_ir[15:11] == `SUBC || ex_ir[15:11] == `AND 
                          || ex_ir[15:11] == `OR || ex_ir[15:11] == `XOR || ex_ir[15:11] == `SLL || ex_ir[15:11] == `SRL
                          || ex_ir[15:11] == `SLA || ex_ir[15:11] == `SRA ))
                       reg_A <= ALUo; 
                    else if(id_ir[10:8] == mem_ir[10:8]&&(mem_ir[15:11] == `ADD || mem_ir[15:11] == `LDIH || mem_ir[15:11] == `ADDI 
                            || mem_ir[15:11] == `SUB || mem_ir[15:11] == `SUBI || mem_ir[15:11] == `ADDC 
                             || mem_ir[15:11] == `SUBC || mem_ir[15:11] == `AND || mem_ir[15:11] == `OR || mem_ir[15:11] == `XOR 
                             || mem_ir[15:11] == `SLL || mem_ir[15:11] == `SRL || mem_ir[15:11] == `SLA || mem_ir[15:11] == `SRA 
                             || mem_ir[15:11] == `LOAD))
                             begin
                                 if(mem_ir[15:11]==`LOAD)  //load是否出结果
                               reg_A <= d_datain;
                            else
                              reg_A <= reg_C;  
                       end
               else if(wb_ir[10:8] == id_ir[10:8]&&(wb_ir[15:11] == `ADD || wb_ir[15:11] == `LDIH || wb_ir[15:11] == `ADDI 
                           || wb_ir[15:11] == `SUB || wb_ir[15:11] == `SUBI || wb_ir[15:11] == `ADDC || wb_ir[15:11] == `SUBC 
                             || wb_ir[15:11] == `AND || wb_ir[15:11] == `OR || wb_ir[15:11] == `XOR || wb_ir[15:11] == `SLL 
                             || wb_ir[15:11] == `SRL || wb_ir[15:11] == `SLA || wb_ir[15:11] == `SRA || wb_ir[15:11] == `LOAD ))
                       reg_A <= reg_C1;                 
                    else
                       reg_A <= gr[(id_ir[10:8])];//gr1
                  end
                //r1=r2#r3 or r1=r2#val 
                else if(id_ir[15:11] == `LOAD || id_ir[15:11] == `STORE || id_ir[15:11] == `ADD || id_ir[15:11] == `SUB 
                        || id_ir[15:11] == `ADDC || id_ir[15:11] == `SUBC || id_ir[15:11] == `CMP || id_ir[15:11] == `AND 
                          || id_ir[15:11] == `OR || id_ir[15:11] == `XOR || id_ir[15:11] == `SLL || id_ir[15:11] == `SRL 
                          || id_ir[15:11] == `SLA || id_ir[15:11] == `SRA) 
                    begin
                       //r2未写回
                       if( (ex_ir[15:11] == `ADD || ex_ir[15:11] == `LDIH || ex_ir[15:11] == `ADDI || ex_ir[15:11] == `SUB
                          || ex_ir[15:11] == `SUBI || ex_ir[15:11] == `ADDC || ex_ir[15:11] == `SUBC || ex_ir[15:11] == `AND 
                          || ex_ir[15:11] == `OR || ex_ir[15:11] == `XOR || ex_ir[15:11] == `SLL || ex_ir[15:11] == `SRL
                          || ex_ir[15:11] == `SLA || ex_ir[15:11] == `SRA )&& ex_ir[10:8] == id_ir[6:4])
                            reg_A <= ALUo;
                        else if( (mem_ir[15:11] == `ADD || mem_ir[15:11] == `LDIH || mem_ir[15:11] == `ADDI 
                              || mem_ir[15:11] == `SUB || mem_ir[15:11] == `SUBI || mem_ir[15:11] == `ADDC 
                               || mem_ir[15:11] == `SUBC || mem_ir[15:11] == `AND || mem_ir[15:11] == `OR || mem_ir[15:11] == `XOR 
                               || mem_ir[15:11] == `SLL || mem_ir[15:11] == `SRL || mem_ir[15:11] == `SLA || mem_ir[15:11] == `SRA 
                               || mem_ir[15:11] == `LOAD)&& mem_ir[10:8] == id_ir[6:4])
                                 if(mem_ir[15:11]==`LOAD)
                              reg_A <= d_datain;
                           else
                                    reg_A <= reg_C;
                        else if( (wb_ir[15:11] == `ADD || wb_ir[15:11] == `LDIH || wb_ir[15:11] == `ADDI || wb_ir[15:11] == `SUB
                            || wb_ir[15:11] == `SUBI || wb_ir[15:11] == `ADDC || wb_ir[15:11] == `SUBC || wb_ir[15:11] == `AND 
                            || wb_ir[15:11] == `OR || wb_ir[15:11] == `XOR || wb_ir[15:11] == `SLL || wb_ir[15:11] == `SRL
                            || wb_ir[15:11] == `SLA || wb_ir[15:11] == `SRA || wb_ir[15:11] == `LOAD )&& wb_ir[10:8] == id_ir[6:4])
                             reg_A <= reg_C1;
                        else
                            reg_A <= gr[id_ir[6:4]];//gr2
                     end    
                //flush  
               else if((mem_ir[15:11]==`BZ && zf==1'b1) ||(mem_ir[15:11]==`BNZ && zf==1'b0) 
                  ||(mem_ir[15:11]==`BN && nf==1'b1) || (mem_ir[15:11]==`BNN && nf==1'b0) ||(mem_ir[15:11]==`BC && cin==1'b1)
                ||(mem_ir[15:11]==`BNC && cin==1'b0) || mem_ir[15:11]==`JMPR)
                    reg_A <= 16'bx;  
                else if(id_ir[15:11] == `JUMP)
                    reg_A <= 16'bx;
                else
                    reg_A <= gr[id_ir[6:4]];//gr2
                //regB
                if (id_ir[15:11] == `LOAD || id_ir[15:11] == `STORE || id_ir[15:11] == `SLL || (id_ir[15:11] == `SRL) 
                  || (id_ir[15:11] == `SLA) || (id_ir[15:11] == `SRA))
                    reg_B <= {12'b0000_0000_0000, id_ir[3:0]};//val3
                else if ((id_ir[15:11] == `BZ) || (id_ir[15:11] == `BNZ) || (id_ir[15:11] == `BN) || (id_ir[15:11] == `BNN)
                      || (id_ir[15:11] == `BC) || (id_ir[15:11] == `BNC)
                      || (id_ir[15:11] == `ADDI) || (id_ir[15:11] == `SUBI) || (id_ir[15:11] == `JMPR))
                    reg_B <= {8'b0000_0000, id_ir[7:0]};//{00000000, value2value3}
                else if(id_ir[15:11] == `LDIH)
                   reg_B <= {id_ir[7:0], 8'b0000_0000};//{val2,val3,00000000)
                //r1=r2#r3
                else if(id_ir[15:11] == `ADD || id_ir[15:11] == `SUB || id_ir[15:11] == `ADDC || id_ir[15:11] == `SUBC 
                    || id_ir[15:11] == `CMP || id_ir[15:11] == `AND || id_ir[15:11] == `OR || id_ir[15:11] == `XOR)
                   begin
                       if( (ex_ir[15:11] == `ADD || ex_ir[15:11] == `LDIH || ex_ir[15:11] == `ADDI || ex_ir[15:11] == `SUB
                          || ex_ir[15:11] == `SUBI || ex_ir[15:11] == `ADDC || ex_ir[15:11] == `SUBC || ex_ir[15:11] == `AND 
                          || ex_ir[15:11] == `OR || ex_ir[15:11] == `XOR || ex_ir[15:11] == `SLL || ex_ir[15:11] == `SRL
                          || ex_ir[15:11] == `SLA || ex_ir[15:11] == `SRA )&& ex_ir[10:8] == id_ir[2:0])
                            reg_B <= ALUo;
                        else if( (mem_ir[15:11] == `ADD || mem_ir[15:11] == `LDIH || mem_ir[15:11] == `ADDI 
                           || mem_ir[15:11] == `LOAD || mem_ir[15:11] == `SUB || mem_ir[15:11] == `SUBI || mem_ir[15:11] == `ADDC 
                            || mem_ir[15:11] == `SUBC || mem_ir[15:11] == `AND || mem_ir[15:11] == `OR || mem_ir[15:11] == `XOR
                            || mem_ir[15:11] == `SLL || mem_ir[15:11] == `SRL || mem_ir[15:11] == `SLA || mem_ir[15:11] == `SRA )
                            && mem_ir[10:8] == id_ir[2:0])
                      begin
                           if(mem_ir[15:11]==`LOAD)
                               reg_B <= d_datain;
                           else
                               reg_B <= reg_C;
                      end
                        else if( (wb_ir[15:11] == `ADD || wb_ir[15:11] == `LDIH || wb_ir[15:11] == `ADDI || wb_ir[15:11] == `SUB
                           || wb_ir[15:11] == `SUBI || wb_ir[15:11] == `ADDC || wb_ir[15:11] == `SUBC || wb_ir[15:11] == `AND 
                           || wb_ir[15:11] == `OR || wb_ir[15:11] == `XOR || wb_ir[15:11] == `SLL || wb_ir[15:11] == `SRL
                           || wb_ir[15:11] == `SLA || wb_ir[15:11] == `SRA || wb_ir[15:11] == `LOAD)&& wb_ir[10:8] == id_ir[2:0])
                             reg_B <= reg_C1;
                        else
                            reg_B <= gr[id_ir[2:0]];//gr2
                     end
                //flush
                else if((mem_ir[15:11]==`BZ && zf==1'b1) ||(mem_ir[15:11]==`BNZ && zf==1'b0) 
                  ||(mem_ir[15:11]==`BN && nf==1'b1) || (mem_ir[15:11]==`BNN && nf==1'b0) ||(mem_ir[15:11]==`BC && cin==1'b1)
                ||(mem_ir[15:11]==`BNC && cin==1'b0) || mem_ir[15:11]==`JMPR)
                    reg_B <= 16'bx; 
                else if(id_ir[15:11] == `JUMP)
                   reg_B <= 16'bx;
                else
                    reg_B <= gr[id_ir[2:0]];//gr3
               //STORE  
               if (id_ir[15:11] == `STORE)
                   begin
                      //r1未写回
                      if(id_ir[10:8] == ex_ir[10:8] && (ex_ir[15:11] == `ADD || ex_ir[15:11] == `LDIH || ex_ir[15:11] == `ADDI 
                         || ex_ir[15:11] == `SUB || ex_ir[15:11] == `SUBI || ex_ir[15:11] == `ADDC || ex_ir[15:11] == `SUBC 
                         || ex_ir[15:11] == `AND || ex_ir[15:11] == `OR || ex_ir[15:11] == `XOR || ex_ir[15:11] == `SLL 
                         || ex_ir[15:11] == `SRL || ex_ir[15:11] == `SLA || ex_ir[15:11] == `SRA ))
                           smdr <= ALUo;
                      else if(id_ir[10:8] == mem_ir[10:8] && (mem_ir[15:11] == `ADD || mem_ir[15:11] == `LDIH 
                         || mem_ir[15:11] == `ADDI || mem_ir[15:11] == `SUB || mem_ir[15:11] == `SUBI || mem_ir[15:11] == `ADDC 
                          || mem_ir[15:11] == `SUBC || mem_ir[15:11] == `AND || mem_ir[15:11] == `OR || mem_ir[15:11] == `XOR
                          || mem_ir[15:11] == `SLL || mem_ir[15:11] == `SRL || mem_ir[15:11] == `SLA || mem_ir[15:11] == `SRA
                          || mem_ir[15:11] == `LOAD))
                           begin
                          if(mem_ir[15:11]==`LOAD)
                              smdr <= d_datain;
                          else
                              smdr <= reg_C;                  
                     end
                      else if(id_ir[10:8] == wb_ir[10:8] && (wb_ir[15:11] == `ADD || wb_ir[15:11] == `LDIH 
                         || wb_ir[15:11] == `LOAD || wb_ir[15:11] == `ADDI || wb_ir[15:11] == `SUB || wb_ir[15:11] == `SUBI 
                          || wb_ir[15:11] == `ADDC || wb_ir[15:11] == `SUBC || wb_ir[15:11] == `AND || wb_ir[15:11] == `OR 
                          || wb_ir[15:11] == `XOR || wb_ir[15:11] == `SLL || wb_ir[15:11] == `SRL || wb_ir[15:11] == `SLA 
                          || wb_ir[15:11] == `SRA ))
                           smdr <= reg_C1;
                      else
                          smdr <= gr[id_ir[10:8]];
                    end
                else
                    smdr <= gr[id_ir[10:8]];


            end
   end
//************* ALU *************//计算
reg signed [15:0] reg_A1;// for SRA 算术右移
always @(*)
begin
  reg_A1 <= reg_A;
end

always @(*)
    begin
      //加减
      if(ex_ir[15:11] == `ADD || ex_ir[15:11] == `LDIH || ex_ir[15:11] == `ADDI) 
         {cf, ALUo} <= reg_A + reg_B;
      else if(ex_ir[15:11] == `CMP || (ex_ir[15:11] == `SUB) || (ex_ir[15:11] == `SUBI))
         {cf, ALUo} <= reg_A - reg_B;
      else if(ex_ir[15:11] == `ADDC)
         {cf, ALUo} <= reg_A + reg_B + cin;
      else if(ex_ir[15:11] == `SUBC)
         {cf, ALUo} <= reg_A - reg_B - cin;
      //逻辑
     else if(ex_ir[15:11] == `AND)
        {cf, ALUo} <= reg_A & reg_B;      
      else if(ex_ir[15:11] == `OR)
         {cf, ALUo} <= reg_A | reg_B;
      else if(ex_ir[15:11] == `XOR)
         {cf, ALUo} <= reg_A ^ reg_B;
      //移位
      else if(ex_ir[15:11] == `SLL)
         {cf, ALUo} <= reg_A << reg_B;
      else if(ex_ir[15:11] == `SRL)
         {cf, ALUo} <= reg_A >> reg_B;
      else if(ex_ir[15:11] == `SLA)
         {cf, ALUo} <= reg_A <<< reg_B;
      else if(ex_ir[15:11] == `SRA)
         {cf, ALUo} <= reg_A1 >>> reg_B;
      //存取、跳转
      else if(ex_ir[15:11] == `LOAD || ex_ir[15:11] == `STORE 
             || ex_ir[15:11] == `BN || ex_ir[15:11] == `BNN || ex_ir[15:11] == `BZ || ex_ir[15:11] == `BNZ
                || ex_ir[15:11] == `BC || ex_ir[15:11] == `BNC || ex_ir[15:11] == `JMPR)
          {cf, ALUo} <= reg_A + reg_B;
      else 
         {cf, ALUo} <= 17'b0;
    end     
//************* EX *************//  执行
always @(posedge clock or negedge reset)
    begin
        if (!reset)
            begin
                mem_ir <= 16'b0000_0000_0000_0000;
                reg_C <= 16'b0000_0000_0000_0000;
                smdr1 <= 16'b0000_0000_0000_0000;
                zf <= 1'b0;
                nf <= 1'b0;
                cin <= 1'b0;
                dw <= 1'b0;
            end 
       else if (state == `exec)
            begin
                mem_ir <= ex_ir;
                reg_C <= ALUo;

                if ((ex_ir[15:11] == `ADD) || (ex_ir[15:11] == `CMP) || (ex_ir[15:11] == `LDIH) || (ex_ir[15:11] == `ADDI) 
                 || (ex_ir[15:11] == `ADDC) || (ex_ir[15:11] == `SUB) || (ex_ir[15:11] == `SUBI) || (ex_ir[15:11] == `SUBC))
                    begin
                        if (ALUo == 16'b0000_0000_0000_0000)
                            zf <= 1'b1;//if zero
                        else
                            zf <= 1'b0;
                        if (ALUo[15] == 1'b1)//if negative 
                            nf <= 1'b1;
                        else
                            nf <= 1'b0;
                    end
                else
                  begin
                     zf <= zf;
                      nf <= nf;
                  end
                //carry 
                if ((ex_ir[15:11] == `ADD) || (ex_ir[15:11] == `LDIH) || (ex_ir[15:11] == `ADDI) || (ex_ir[15:11] == `ADDC)
                 || (ex_ir[15:11] == `SUB) || (ex_ir[15:11] == `SUBI) || (ex_ir[15:11] == `SUBC))                   
                      cin <= cf;
                else
                      cin <= cin; 
                //STORE   
                if (ex_ir[15:11] == `STORE)
                    begin
                        dw <= 1'b1;//data wire enable
                        smdr1 <= smdr;
                    end
                else
                   begin
                       dw <= 1'b0;
                        smdr1 <= 16'b0;
                    end

            end
   end    
//************* MEM *************// 存储器访问
always @(posedge clock or negedge reset)
    begin
        if (!reset)
            begin
                wb_ir <= 16'b0000_0000_0000_0000;
                reg_C1 <= 16'b0000_0000_0000_0000;
            end 
        else if (state == `exec)
            begin
                wb_ir <= mem_ir;
                if (mem_ir[15:11] == `LOAD)
                        reg_C1 <= d_datain;
                else
                        reg_C1 <= reg_C;
            end
   end      
//************* WB *************//
always @(posedge clock or negedge reset)//写回
    begin
        if (!reset)
            begin
                gr[7] <= 16'b0000_0000_0000_0000;
                gr[6] <= 16'b0000_0000_0000_0000;
                gr[5] <= 16'b0000_0000_0000_0000;
                gr[4] <= 16'b0000_0000_0000_0000;
                gr[3] <= 16'b0000_0000_0000_0000;
                gr[2] <= 16'b0000_0000_0000_0000;
                gr[1] <= 16'b0000_0000_0000_0000;
                gr[0] <= 16'b0000_0000_0000_0000;
            end 
        else if (state == `exec)
            begin
                if ((wb_ir[15:11] == `LOAD) || (wb_ir[15:11] == `ADD) || (wb_ir[15:11] == `LDIH) || (wb_ir[15:11] == `ADDI)
                 || (wb_ir[15:11] == `ADDC) || (wb_ir[15:11] == `SUB) || (wb_ir[15:11] == `SUBI) || (wb_ir[15:11] == `SUBC)
                 ||(wb_ir[15:11] == `AND) ||(wb_ir[15:11] == `OR) ||(wb_ir[15:11] == `XOR) || (wb_ir[15:11] == `SLL)
                 ||(wb_ir[15:11] == `SRL) ||(wb_ir[15:11] == `SLA) || (wb_ir[15:11] == `SRA))
                    gr[wb_ir[10:8]] <= reg_C1;//write back to gr1
                else
                   gr[wb_ir[10:8]] <= gr[wb_ir[10:8]];
            end
   end      

endmodule

测试

  • Instruction Memory: I_mem.v
`include "headfile.v"
module I_mem(input wire [7:0] addra, output reg [15:0] douta
    );
reg [15:0] i_mem[255:0];
always @(*)
   begin
        douta <= i_mem[addra];
    end

initial begin

 //init test
       /*
        i_mem[0]={`ADDI,`gr7,4'd1,4'd0};              // gr7 <= 16'h0010 for store address
        i_mem[1]={`LDIH,`gr1,4'b1011,4'b0110};        // test for LDIH  gr1<="16'hb600"
        i_mem[2]={`STORE,`gr1,1'b0,`gr7,4'h0};        // store to mem10 
        i_mem[3]={`LOAD,`gr1,1'b0,`gr0,4'h0};         // gr1 <= fffd 
        i_mem[4]={`LOAD,`gr2,1'b0,`gr0,4'h1};         // gr2 <= 4
        i_mem[5]={`ADDC,`gr3,1'b0,`gr1,1'b0,`gr2};    // gr3 <= fffd + 4 + cf(=0) = 1, cf<=1
        i_mem[6]={`STORE,`gr3,1'b0,`gr7,4'h1};        // store to mem11     
        i_mem[7]={`ADDC,`gr3,1'b0,`gr0,1'b0,`gr2};    // gr3 <= 0 + 4 + cf(=1) = 5, cf<=0
        i_mem[8]={`STORE,`gr3,1'b0,`gr7,4'h2};        // store to mem12
        i_mem[9]={`LOAD,`gr1,1'b0,`gr0,4'h2};          // gr1 <= 5 
        i_mem[10]={`SUBC,`gr3,1'b0,`gr1,1'b0,`gr2};    // gr3 <= 5 - 4 + cf(=0) =1, cf<=0    
        i_mem[11]={`STORE,`gr3,1'b0,`gr7,4'h3};        // store to mem13        
        i_mem[12]={`SUB,`gr3,1'b0,`gr2,1'b0,`gr1};     // gr3 <= 4 - 5 = -1, cf<=1    
        i_mem[13]={`STORE,`gr3,1'b0,`gr7,4'h4};        // store to mem14        
        i_mem[14]={`SUBC,`gr3,1'b0,`gr2,1'b0,`gr1};    // gr3 <= 5 - 4 - cf(=1) =2, cf<=0 
        i_mem[15]={`STORE,`gr3,1'b0,`gr7,4'h5};        // store to mem15        
        i_mem[16]={`LOAD,`gr1,1'b0,`gr0,4'h3};         // gr1 <= c369
        i_mem[17]={`LOAD,`gr2,1'b0,`gr0,4'h4};         // gr2 <= 69c3       
        i_mem[18]={`AND,`gr3,1'b0,`gr1,1'b0,`gr2};     // gr3 <= gr1 & gr2 = 4141
        i_mem[19]={`STORE,`gr3,1'b0,`gr7,4'h6};        // store to mem16        
        i_mem[20]={`OR,`gr3,1'b0,`gr1,1'b0,`gr2};      // gr3 <= gr1 | gr2 = ebeb
        i_mem[21]={`STORE,`gr3,1'b0,`gr7,4'h7};        // store to mem17        
        i_mem[22]={`XOR,`gr3,1'b0,`gr1,1'b0,`gr2};     // gr3 <= gr1 ^ gr2 = aaaa
        i_mem[23]={`STORE,`gr3,1'b0,`gr7,4'h8};        // store to mem18
        i_mem[24]={`SLL,`gr3,1'b0,`gr1,4'h0};          // gr3 <= gr1 < 0 
        i_mem[25]={`STORE,`gr3,1'b0,`gr7,4'h9};        // store to mem19        
        i_mem[26]={`SLL,`gr3,1'b0,`gr1,4'h1};          // gr3 <= gr1 < 1 
        i_mem[27]={`STORE,`gr3,1'b0,`gr7,4'ha};        // store to mem1a        
        i_mem[28]={`SLL,`gr3,1'b0,`gr1,4'h4};          // gr3 <= gr1 < 8 
        i_mem[29]={`STORE,`gr3,1'b0,`gr7,4'hb};        // store to mem1b    
        i_mem[30]={`SLL,`gr3,1'b0,`gr1,4'hf};          // gr3 <= gr1 < 15 
        i_mem[31]={`STORE,`gr3,1'b0,`gr7,4'hc};        // store to mem1c
        i_mem[32]={`SRL,`gr3,1'b0,`gr1,4'h0};          // gr3 <= gr1 > 0
        i_mem[33]={`STORE,`gr3,1'b0,`gr7,4'hd};        // store to mem1d        
        i_mem[34]={`SRL,`gr3,1'b0,`gr1,4'h1};          // gr3 <= gr1 > 1
        i_mem[35]={`STORE,`gr3,1'b0,`gr7,4'he};        // store to mem1e        
        i_mem[36]={`SRL,`gr3,1'b0,`gr1,4'h8};          // gr3 <= gr1 > 8
        i_mem[37]={`STORE,`gr3,1'b0,`gr7,4'hf};        // store to mem1f        
        i_mem[38]={`SRL,`gr3,1'b0,`gr1,4'hf};          // gr3 <= gr1 > 15
        i_mem[39]={`ADDI,`gr7,4'd1,4'd0};              // gr7 <= 16'h20 for store address
        i_mem[40]={`STORE,`gr3,1'b0,`gr7,4'h0};        // store to mem20
        i_mem[41]={`SLA,`gr3,1'b0,`gr1,4'h0};          // gr3 <= gr1 < 0
        i_mem[42]={`STORE,`gr3,1'b0,`gr7,4'h1};        // store to mem21
        i_mem[43]={`SLA,`gr3,1'b0,`gr1,4'h1};          // gr3 <= gr1 < 1 
        i_mem[44]={`STORE,`gr3,1'b0,`gr7,4'h2};        // store to mem22
        i_mem[45]={`SLA,`gr3,1'b0,`gr1,4'h8};          // gr3 <= gr1 < 8 
        i_mem[46]={`STORE,`gr3,1'b0,`gr7,4'h3};        // store to mem23
        i_mem[47]={`SLA,`gr3,1'b0,`gr1,4'hf};          // gr3 <= gr1 < 15
        i_mem[48]={`STORE,`gr3,1'b0,`gr7,4'h4};        // store to mem24
        i_mem[49]={`SLA,`gr3,1'b0,`gr2,4'h0};          // gr3 <= gr1 < 0
        i_mem[50]={`STORE,`gr3,1'b0,`gr7,4'h5};        // store to mem25
        i_mem[51]={`SLA,`gr3,1'b0,`gr2,4'h1};          // gr3 <= gr1 < 1
        i_mem[52]={`STORE,`gr3,1'b0,`gr7,4'h6};        // store to mem26
        i_mem[53]={`SLA,`gr3,1'b0,`gr2,4'h8};          // gr3 <= gr1 < 8
        i_mem[54]={`STORE,`gr3,1'b0,`gr7,4'h7};        // store to mem27
        i_mem[55]={`SLA,`gr3,1'b0,`gr2,4'hf};          // gr3 <= gr1 < 15
        i_mem[56]={`STORE,`gr3,1'b0,`gr7,4'h8};        // store to mem28
        i_mem[57]={`SRA,`gr3,1'b0,`gr1,4'h0};          // gr3 <= gr1 > 0
        i_mem[58]={`STORE,`gr3,1'b0,`gr7,4'h9};        // store to mem29
        i_mem[59]={`SRA,`gr3,1'b0,`gr1,4'h1};          // gr3 <= gr1 > 1
        i_mem[60]={`STORE,`gr3,1'b0,`gr7,4'ha};        // store to mem2a
        i_mem[61]={`SRA,`gr3,1'b0,`gr1,4'h8};          // gr3 <= gr1 > 8
        i_mem[62]={`STORE,`gr3,1'b0,`gr7,4'hb};        // store to mem2b
        i_mem[63]={`SRA,`gr3,1'b0,`gr1,4'hf};          // gr3 <= gr1 > 15
        i_mem[64]={`STORE,`gr3,1'b0,`gr7,4'hc};        // store to mem2c
        i_mem[65]={`SRA,`gr3,1'b0,`gr2,4'h0};          // gr3 <= gr1 > 0
        i_mem[66]={`STORE,`gr3,1'b0,`gr7,4'hd};        // store to mem2d
        i_mem[67]={`SRA,`gr3,1'b0,`gr2,4'h1};          // gr3 <= gr1 > 1
        i_mem[68]={`STORE,`gr3,1'b0,`gr7,4'he};        // store to mem2e
        i_mem[69]={`SRA,`gr3,1'b0,`gr2,4'h8};          // gr3 <= gr1 > 8
        i_mem[70]={`STORE,`gr3,1'b0,`gr7,4'hf};        // store to mem2f
        i_mem[71]={`ADDI,`gr7,4'd1,4'd0};              // gr7 <= 16'h30 for store address
        i_mem[72]={`SRA,`gr3,1'b0,`gr2,4'hf};          // gr3 <= gr1 > 15
        i_mem[73]={`STORE,`gr3,1'b0,`gr7,4'h0};        // store to mem30        
        i_mem[74]={`LOAD,`gr1,1'b0,`gr0,4'h5};         // gr1 <= 41
        i_mem[75]={`LOAD,`gr2,1'b0,`gr0,4'h6};         // gr2 <= ffff
        i_mem[76]={`LOAD,`gr3,1'b0,`gr0,4'h7};         // gr3 <= 1
        i_mem[77]={`JUMP, 3'd0,8'h4f};                 // jump to 4f
        i_mem[78]={`STORE,`gr7,1'b0,`gr7,4'h1};        // store to mem31
        i_mem[79]={`JMPR, `gr1,8'h10};                 // jump to 41+10 = 51
        i_mem[80]={`STORE,`gr7,1'b0,`gr7,4'h2};        // store to mem32
        i_mem[81]={`ADD, `gr4,1'b0,`gr2,1'b0,`gr3};    // gr4<= ffff + 1,cf<=1
        i_mem[82]={`BNC,`gr1,8'h28};                   // if(cf==0) jump to 69
        i_mem[83]={`BC,`gr1,8'h14};                    // if(cf==1) jump to 55
        i_mem[84]={`STORE,`gr7,1'b0,`gr7,4'h3};        // store to mem33
        i_mem[85]={`ADD, `gr4,1'b0,`gr3,1'b0,`gr3};    // gr4<= 1 + 1 , cf<=0
        i_mem[86]={`BC,`gr1,8'h28};                    // if(cf==1) jump to 69
        i_mem[87]={`BNC,`gr1,8'h18};                   // if(cf==0) jump to 59
        i_mem[88]={`STORE,`gr7,1'b0,`gr7,4'h4};        // store to mem34
        i_mem[89]={`CMP, 3'd0,1'b0,`gr3,1'b0,`gr3};    // 1-1=0 , zf<=1,nf<=0
        i_mem[90]={`BNZ,`gr1,8'h28};                   // if(zf==0) jump to 69
        i_mem[91]={`BZ,`gr1,8'h1c};                    // if(zf==1) jump to 5d
        i_mem[92]={`STORE,`gr7,1'b0,`gr7,4'h5};        // store to mem35
        i_mem[93]={`CMP, 3'd0,1'b0,`gr4,1'b0,`gr3};    // 2-1=1 , zf<=0,nf<=0 
        i_mem[94]={`BZ,`gr1,8'h28};                    // if(zf==1) jump to 69
        i_mem[95]={`BNZ,`gr1,8'h20};                   // if(zf==0) jump to 61
        i_mem[96]={`STORE,`gr7,1'b0,`gr7,4'h6};        // store to mem36
        i_mem[97]={`CMP, 3'd0,1'b0,`gr3,1'b0,`gr4};    // 1-2=-1, nf<=1,zf<=0
        i_mem[98]={`BNN,`gr1,8'h28};                   // if(nf==0) jump to 69
        i_mem[99]={`BN,`gr1,8'h24};                    // if(nf==1) jump to 65 
        i_mem[100]={`STORE,`gr7,1'b0,`gr7,4'h7};       // store to mem37
        i_mem[101]={`CMP, 3'd0,1'b0,`gr4,1'b0,`gr3};   // 2-1=1, nf<=0,zf<=0
        i_mem[102]={`BN,`gr1,8'h28};                   // if(nf==1) jump to 69
        i_mem[103]={`BNN,`gr1,8'h27};                  // if(nf==0) jump to 68
        i_mem[104]={`STORE,`gr7,1'b0,`gr7,4'h8};       // store to mem38
        i_mem[105]={`HALT, 11'd0};                     // STOP*/


    //最大公因数 最小公倍数:gcm

    i_mem[0] <= {`LOAD, `gr1, 1'b0, `gr0, 4'b0001};  //gr1=0009
    i_mem[1] <= {`LOAD, `gr2, 1'b0, `gr0, 4'b0010};  //gr2 = 0003  
    i_mem[2] <= {`ADD, `gr3, 1'b0, `gr0, 1'b0, `gr1}; //gr3=0009  0006  0003
    i_mem[3] <= {`SUB, `gr1, 1'b0, `gr1, 1'b0, `gr2}; //gr1=0006  0003  0
    i_mem[4] <= {`BZ, `gr0, 8'b0000_1001}; //no no jump to 09
    i_mem[5] <= {`BNN, `gr0,  8'b0000_0010}; //jump to 2  jump to 2
    i_mem[6] <= {`ADD, `gr1, 1'b0, `gr0, 1'b0, `gr2};
    i_mem[7] <= {`ADD, `gr2, 1'b0, `gr0, 1'b0, `gr3};
    i_mem[8] <= {`JUMP, 11'b000_0000_0010};
    i_mem[9] <= {`STORE, `gr2, 1'b0, `gr0, 4'b0011}; //d[3]=0003
    i_mem[10] <= {`LOAD, `gr1, 1'b0, `gr0, 4'b0001}; //gr1 = 0009
    i_mem[11] <= {`LOAD, `gr2, 1'b0, `gr0, 4'b0010}; //gr2 = 0003
    i_mem[12] <= {`ADDI, `gr4, 8'h1}; // gr4=1
    i_mem[13] <= {`SUB, `gr2, 1'b0, `gr2, 1'b0, `gr3}; //gr2 = 0
    i_mem[14] <= {`BZ, `gr0, 8'b0001_0000}; //jump to 16
    i_mem[15] <= {`JUMP, 11'b000_0000_1100}; //
    i_mem[16] <= {`SUBI, `gr4, 8'h1}; // gr4 = 0  -1
    i_mem[17] <= {`BN, `gr0, 8'b0001_0100}; //no  jump to 20
    i_mem[18] <= {`ADD, `gr5, 1'b0, `gr5, 1'b0, `gr1};  //gr5 = 0009
    i_mem[19] <= {`JUMP, 11'b000_0001_0000}; //jump to 16
    i_mem[20] <= {`STORE, `gr5, 1'b0, `gr0, 4'b0100}; //d[4]=0009
    i_mem[21] <= {`LOAD, `gr1, 1'b0, `gr0, 4'b0011};//gr1=0003
    i_mem[22] <= {`LOAD, `gr2, 1'b0, `gr0, 4'b0100};//gr2=0009
    i_mem[23] <= {`HALT, 11'b000_0000_0000};


   //64位加法:64badder
    /*
    i_mem[0]=16'h4c04 ; //{`ADDI,`gr4,8'h04};  gr4=0004
   i_mem[1]=16'h1100 ; //{`LOAD, `gr1, 1'b0, `gr0, 4'b0000};  gr1 = fffe
    i_mem[2]=16'h1204 ; //{`LOAD, `gr2, 1'b0, `gr0, 4'b0100};  gr2 = ffff
    i_mem[3]=16'h4312 ; //{`ADD, `gr3, 1'b0, `gr1, 1'b0, `gr2};  gr3 = fffd
    i_mem[4]=16'hfd06 ; //{`BNC, `gr5, 8'b0000_0110};  no
    i_mem[5]=16'h4e01 ; //{`ADDI,`gr6,8'h01};  gr6=0001
    i_mem[6]=16'h4337 ; //{`ADD, `gr3, 1'b0, `gr3, 1'b0, `gr7};  gr3 = fffd
    i_mem[7]=16'hfd0b ; //{`BNC, `gr5, 8'b0000_1011};jump to 11
    i_mem[8]=16'h5e00 ;  //{`SUBI, `gr6, 8'h0}; 
    i_mem[9]=16'hdd0b ;   //{`BNZ, `gr5, 8'h0b};
    i_mem[10]=16'h4e01 ;  //{`ADDI,`gr6,8'h01};
    i_mem[11]=16'h5777 ;    //{`SUB, `gr7, 1'b0, `gr7, 1'b0, `gr7};  gr7 = 0
    i_mem[12]=16'h4776 ;  //{`ADD, `gr7, 1'b0, `gr7, 1'b0, `gr6};  gr7 = 0001
    i_mem[13]=16'h5666 ;    //{`SUB, `gr6, 1'b0, `gr6, 1'b0, `gr6};  gr6 = 0
    i_mem[14]=16'h1b08 ;  //{`STORE, `gr3, 1'b0, `gr0, 4'b1000};  d[8]=fffd
    i_mem[15]=16'h4801 ;     //{`ADDI,`gr0,8'h01};  gr0=0001    
   i_mem[16]=16'h6004 ;  //{`CMP, 3'b0,1'b0,`gr0,1'b0,`gr4}; 1<4
   i_mem[17]=16'he501 ; //{`BN, `gr5, 8'b0000_0001};  jump to 1
    i_mem[18]=16'h0800 ; //halt*/


    //冒泡排序
    /*
    i_mem[0] <= {`LOAD, `gr3, 1'b0, `gr0, 4'b0000};  //gr3=000a;
    i_mem[1] <= {`SUBI, `gr3, 4'd0, 4'd2};   //gr3=0008
    i_mem[2] <= {`ADD, `gr1, 1'b0, `gr0, 1'b0, `gr0};  //gr1=0
    i_mem[3] <= {`ADD, `gr2, 1'b0, `gr3, 1'b0, `gr0}; //gr2=0008
    i_mem[4] <= {`LOAD, `gr4, 1'b0, `gr2, 4'd1}; //gr4=d[9]=1057
    i_mem[5] <= {`LOAD, `gr5, 1'b0, `gr2, 4'd2}; //gr5=d[10]=2895
    i_mem[6] <= {`CMP, 3'd0, 1'b0, `gr5, 1'b0, `gr4}; //d[10] > d[9]
    i_mem[7] <= {`BN, `gr0, 4'b0000, 4'b1010};  //no
    i_mem[8] <= {`STORE, `gr4, 1'b0, `gr2, 4'd2}; //d[10]=gr4
    i_mem[9] <= {`STORE, `gr5, 1'b0, `gr2, 4'd1}; //d[9]=gr5;
    i_mem[10] <= {`SUBI, `gr2, 4'd0, 4'd1};  //gr2=0007
    i_mem[11] <= {`CMP, 3'd0, 1'b0, `gr2, 1'b0, `gr1}; //gr2>gr1
    i_mem[12] <= {`BNN, `gr0, 4'h0, 4'b0100}; //
    i_mem[13] <= {`ADDI, `gr1, 4'd0, 4'd1};
    i_mem[14] <= {`CMP, 3'd0, 1'b0, `gr3, 1'b0, `gr1};
    i_mem[15] <= {`BNN, `gr0, 4'h0, 4'b0011};
    i_mem[16] <= {`HALT, 11'd0};
    */

    //sort
    /*
    i_mem[0] <= {`ADDI, `gr1, 4'b0000,  4'b1001};
    i_mem[1] <= {`ADDI, `gr2, 4'b0000,  4'b1001};
    i_mem[2] <= {`JUMP, 11'b000_0000_0101};//jump to start
    i_mem[3] <= {`SUBI, `gr1, 4'd0, 4'd1};//new_round
    i_mem[4] <= {`BZ, `gr7, 4'b0001, 4'b0010};//jump to end
    i_mem[5] <= {`LOAD, `gr3, 1'b0, `gr0, 4'd0};//start
    i_mem[6] <= {`LOAD, `gr4, 1'b0, `gr0, 4'd1};
    i_mem[7] <= {`CMP, 3'd0, 1'b0, `gr3, 1'b0, `gr4};
    i_mem[8] <= {`BN, `gr7, 4'h0, 4'b1011};//jump to NO_op
    i_mem[9] <= {`STORE, `gr3, 1'b0, `gr0, 4'd1};
    i_mem[10] <= {`STORE, `gr4, 1'b0, `gr0, 4'd0};
    i_mem[11] <= {`ADDI, `gr0, 4'b0000, 4'b0001};//NO_OP
    i_mem[12] <= {`CMP, 3'd0, 1'b0, `gr0, 1'b0, `gr2};
    i_mem[13] <= {`BN, `gr7, 4'b0001, 4'b0001};//jump to continue 
    i_mem[14] <= {`SUBI, `gr2, 4'd0, 4'd1};
    i_mem[15] <= {`SUB, `gr0, 1'b0,`gr0, 1'b0,`gr0};
    i_mem[16] <= {`JUMP, 11'b000_0000_0011};//jump to new round
    i_mem[17] <= {`JUMP, 11'b000_0000_0101};//jump to start,continue
    i_mem[18] <= {`HALT, 11'd0};//end
    */

end

endmodule
  • Data Memory : D_mem.v
module D_mem(input wire wea, input wire [7:0] addra, input wire [15:0] dina, output wire [15:0] douta
    );
reg [15:0] d_mem[255:0];

assign  douta = d_mem[addra];

always @(*)
   begin
        if(wea == 1'b1)
             d_mem[addra] <= dina;
   end

initial begin
  //init_test
  /*
  d_mem[0] <= 16'hfffd;
  d_mem[1] <= 16'h0004;
  d_mem[2] <= 16'h0005;
  d_mem[3] <= 16'hc369;
  d_mem[4] <= 16'h69c3;
  d_mem[5] <= 16'h0041;
  d_mem[6] <= 16'hffff;
  d_mem[7] <= 16'h0001;
  d_mem[8] <= 16'h0000;
  d_mem[9] <= 16'h0000;
  d_mem[10] <= 16'h0000;*/

  //最大公因数 最小公倍数data

  d_mem[0] <= 16'h0000;
  d_mem[1] <= 16'h0020;  //32
  d_mem[2] <= 16'h0018;   //24      8 96

  //64badde
  /*
  d_mem[0] <= 16'hfffe;
  d_mem[1] <= 16'hfffe;
  d_mem[2] <= 16'hfffe;
  d_mem[3] <= 16'h0000;
  d_mem[4] <= 16'hffff;
  d_mem[5] <= 16'hffff;
  d_mem[6] <= 16'hffff;
  d_mem[7] <= 16'h0000;
  */
  //冒泡排序
  /*
  d_mem[0] <= 16'h000a;
  d_mem[1] <= 16'h0004;
  d_mem[2] <= 16'h0005;
  d_mem[3] <= 16'h2369;
  d_mem[4] <= 16'h69c3;
  d_mem[5] <= 16'h0060;
  d_mem[6] <= 16'h0fff;
  d_mem[7] <= 16'h5555;
  d_mem[8] <= 16'h6152;
  d_mem[9] <= 16'h1057;
  d_mem[10] <= 16'h2895;
  d_mem[11] <= 16'h0000;
  */
    //sort
  /*
  d_mem[0] = 16'h000a;
  d_mem[1] = 16'h0009;
  d_mem[2] = 16'h0006;
  d_mem[3] = 16'h0005;
  d_mem[4] = 16'h0001;
  d_mem[5] = 16'h0004;
  d_mem[6] = 16'h0003;
  d_mem[7] = 16'h0011;
  d_mem[8] = 16'h0000;
  d_mem[9] = 16'h0000;
  d_mem[10] = 16'h0000;
  d_mem[11] = 16'h0000;/
 */
end
endmodule
  • 仿真文件test.v
module test;

    // Inputs
    reg clk;
    reg enable;
    reg reset;
    reg start;

    // Instantiate the Unit Under Test (UUT)
    cpu uut (
        .clk(clk), 
        .enable(enable), 
        .reset(reset), 
        .start(start)
    );
   always #5 clk = ~clk;
    initial begin
        // Initialize Inputs
        clk = 0;
        enable = 0;
        reset = 0;
        start = 0;

      $monitor("%h:%b:%h:%h:%h:%h:%h:%h:%b:%h:%h:%h:%h:%h:%h:%h:%h:%b:%b:%b", 
         uut.pcpu.pc, uut.pcpu.id_ir, uut.pcpu.reg_A, uut.pcpu.reg_B, uut.pcpu.reg_C,
         uut.pcpu.d_addr, uut.pcpu.d_dataout, uut.pcpu.ALUo, uut.pcpu.d_we, uut.pcpu.reg_C1, uut.pcpu.gr[1], uut.pcpu.gr[2], uut.pcpu.gr[3],
          uut.pcpu.gr[4], uut.pcpu.gr[5], uut.pcpu.gr[6],
          uut.pcpu.gr[7], uut.pcpu.cin, uut.pcpu.nf, uut.pcpu.zf);

        // Wait 100 ns for global reset to finish
        #100;
      $display("pc:      id_ir:    regA:regB:regC:da:dout:ALUo:dwe:reC1: gr1:gr2:gr3: gr4: gr5: gr6: gr7: cf:nf:zf");        
        // Add stimulus here
        #10 reset <= 0;
      #10 reset <= 1;
      #10 enable <= 1;
      #10 start <=1;
        #10 start <= 0;
        #100;   

    end

endmodule

结果验证(Data Memory)

  • init_test
    Verilog 数字电路设计之带hazard的五级流水线CPU_第13张图片
    Verilog 数字电路设计之带hazard的五级流水线CPU_第14张图片

  • 最大公约数和最小公倍数
    数字0x20和数字0x18的最大公约数是 0x0008,最小公倍数是0x0060。
    Verilog 数字电路设计之带hazard的五级流水线CPU_第15张图片

  • 64位加法
    Verilog 数字电路设计之带hazard的五级流水线CPU_第16张图片

  • 冒泡排序
    0x000a表示要对10个数字进行排序,下面为十个排好序的数字。
    Verilog 数字电路设计之带hazard的五级流水线CPU_第17张图片

  • 排序
    Verilog 数字电路设计之带hazard的五级流水线CPU_第18张图片

你可能感兴趣的:(数字电路设计)