天天看點

Verilog 數字電路設計之帶hazard的五級流水線CPU

設計目标

Verilog 數字電路設計之帶hazard的五級流水線CPU

指令組成

一條指令由16bits組成,高5位是操作碼,代表不同的操作類型;低11位是操作數,分為3部分,10:8位作為标号,代表寄存器堆裡的某一個寄存器;3:0位與7:4位既可以像10:8位一樣作為寄存器标号,也可以作為具體的某一個數值(稱為立即數),具體根據指令來區分。

Verilog 數字電路設計之帶hazard的五級流水線CPU

資料通路

Verilog 數字電路設計之帶hazard的五級流水線CPU

簡易CPU指令集

Verilog 數字電路設計之帶hazard的五級流水線CPU
Verilog 數字電路設計之帶hazard的五級流水線CPU
Verilog 數字電路設計之帶hazard的五級流水線CPU

五級流水線

Verilog 數字電路設計之帶hazard的五級流水線CPU

框圖

Verilog 數字電路設計之帶hazard的五級流水線CPU

Hazard

  • Data Hazard
    • Arithmetic
      Verilog 數字電路設計之帶hazard的五級流水線CPU
      Solution: Data forwarding
      Verilog 數字電路設計之帶hazard的五級流水線CPU
    • LOAD
      Verilog 數字電路設計之帶hazard的五級流水線CPU
      Solution: Stall+Data forwarding
      Verilog 數字電路設計之帶hazard的五級流水線CPU
  • 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, value2,value3}
                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:] douta
    );
reg [15:0] i_mem[255:];
always @(*)
   begin
        douta <= i_mem[addra];
    end

initial begin

 //init test
       /*
        i_mem[]={`ADDI,`gr7,'d1,'d0};              // gr7 <= 16'h0010 for store address
        i_mem[]={`LDIH,`gr1,'b1011,'b0110};        // test for LDIH  gr1<="16'hb600"
        i_mem[]={`STORE,`gr1,'b0,`gr7,'h0};        // store to mem10 
        i_mem[]={`LOAD,`gr1,'b0,`gr0,'h0};         // gr1 <= fffd 
        i_mem[]={`LOAD,`gr2,'b0,`gr0,'h1};         // gr2 <= 4
        i_mem[]={`ADDC,`gr3,'b0,`gr1,'b0,`gr2};    // gr3 <= fffd + 4 + cf(=0) = 1, cf<=1
        i_mem[]={`STORE,`gr3,'b0,`gr7,'h1};        // store to mem11     
        i_mem[]={`ADDC,`gr3,'b0,`gr0,'b0,`gr2};    // gr3 <= 0 + 4 + cf(=1) = 5, cf<=0
        i_mem[]={`STORE,`gr3,'b0,`gr7,'h2};        // store to mem12
        i_mem[]={`LOAD,`gr1,'b0,`gr0,'h2};          // gr1 <= 5 
        i_mem[]={`SUBC,`gr3,'b0,`gr1,'b0,`gr2};    // gr3 <= 5 - 4 + cf(=0) =1, cf<=0    
        i_mem[]={`STORE,`gr3,'b0,`gr7,'h3};        // store to mem13        
        i_mem[]={`SUB,`gr3,'b0,`gr2,'b0,`gr1};     // gr3 <= 4 - 5 = -1, cf<=1    
        i_mem[]={`STORE,`gr3,'b0,`gr7,'h4};        // store to mem14        
        i_mem[]={`SUBC,`gr3,'b0,`gr2,'b0,`gr1};    // gr3 <= 5 - 4 - cf(=1) =2, cf<=0 
        i_mem[]={`STORE,`gr3,'b0,`gr7,'h5};        // store to mem15        
        i_mem[]={`LOAD,`gr1,'b0,`gr0,'h3};         // gr1 <= c369
        i_mem[]={`LOAD,`gr2,'b0,`gr0,'h4};         // gr2 <= 69c3       
        i_mem[]={`AND,`gr3,'b0,`gr1,'b0,`gr2};     // gr3 <= gr1 & gr2 = 4141
        i_mem[]={`STORE,`gr3,'b0,`gr7,'h6};        // store to mem16        
        i_mem[]={`OR,`gr3,'b0,`gr1,'b0,`gr2};      // gr3 <= gr1 | gr2 = ebeb
        i_mem[]={`STORE,`gr3,'b0,`gr7,'h7};        // store to mem17        
        i_mem[]={`XOR,`gr3,'b0,`gr1,'b0,`gr2};     // gr3 <= gr1 ^ gr2 = aaaa
        i_mem[]={`STORE,`gr3,'b0,`gr7,'h8};        // store to mem18
        i_mem[]={`SLL,`gr3,'b0,`gr1,'h0};          // gr3 <= gr1 < 0 
        i_mem[]={`STORE,`gr3,'b0,`gr7,'h9};        // store to mem19        
        i_mem[]={`SLL,`gr3,'b0,`gr1,'h1};          // gr3 <= gr1 < 1 
        i_mem[]={`STORE,`gr3,'b0,`gr7,'ha};        // store to mem1a        
        i_mem[]={`SLL,`gr3,'b0,`gr1,'h4};          // gr3 <= gr1 < 8 
        i_mem[]={`STORE,`gr3,'b0,`gr7,'hb};        // store to mem1b    
        i_mem[]={`SLL,`gr3,'b0,`gr1,'hf};          // gr3 <= gr1 < 15 
        i_mem[]={`STORE,`gr3,'b0,`gr7,'hc};        // store to mem1c
        i_mem[]={`SRL,`gr3,'b0,`gr1,'h0};          // gr3 <= gr1 > 0
        i_mem[]={`STORE,`gr3,'b0,`gr7,'hd};        // store to mem1d        
        i_mem[]={`SRL,`gr3,'b0,`gr1,'h1};          // gr3 <= gr1 > 1
        i_mem[]={`STORE,`gr3,'b0,`gr7,'he};        // store to mem1e        
        i_mem[]={`SRL,`gr3,'b0,`gr1,'h8};          // gr3 <= gr1 > 8
        i_mem[]={`STORE,`gr3,'b0,`gr7,'hf};        // store to mem1f        
        i_mem[]={`SRL,`gr3,'b0,`gr1,'hf};          // gr3 <= gr1 > 15
        i_mem[]={`ADDI,`gr7,'d1,'d0};              // gr7 <= 16'h20 for store address
        i_mem[]={`STORE,`gr3,'b0,`gr7,'h0};        // store to mem20
        i_mem[]={`SLA,`gr3,'b0,`gr1,'h0};          // gr3 <= gr1 < 0
        i_mem[]={`STORE,`gr3,'b0,`gr7,'h1};        // store to mem21
        i_mem[]={`SLA,`gr3,'b0,`gr1,'h1};          // gr3 <= gr1 < 1 
        i_mem[]={`STORE,`gr3,'b0,`gr7,'h2};        // store to mem22
        i_mem[]={`SLA,`gr3,'b0,`gr1,'h8};          // gr3 <= gr1 < 8 
        i_mem[]={`STORE,`gr3,'b0,`gr7,'h3};        // store to mem23
        i_mem[]={`SLA,`gr3,'b0,`gr1,'hf};          // gr3 <= gr1 < 15
        i_mem[]={`STORE,`gr3,'b0,`gr7,'h4};        // store to mem24
        i_mem[]={`SLA,`gr3,'b0,`gr2,'h0};          // gr3 <= gr1 < 0
        i_mem[]={`STORE,`gr3,'b0,`gr7,'h5};        // store to mem25
        i_mem[]={`SLA,`gr3,'b0,`gr2,'h1};          // gr3 <= gr1 < 1
        i_mem[]={`STORE,`gr3,'b0,`gr7,'h6};        // store to mem26
        i_mem[]={`SLA,`gr3,'b0,`gr2,'h8};          // gr3 <= gr1 < 8
        i_mem[]={`STORE,`gr3,'b0,`gr7,'h7};        // store to mem27
        i_mem[]={`SLA,`gr3,'b0,`gr2,'hf};          // gr3 <= gr1 < 15
        i_mem[]={`STORE,`gr3,'b0,`gr7,'h8};        // store to mem28
        i_mem[]={`SRA,`gr3,'b0,`gr1,'h0};          // gr3 <= gr1 > 0
        i_mem[]={`STORE,`gr3,'b0,`gr7,'h9};        // store to mem29
        i_mem[]={`SRA,`gr3,'b0,`gr1,'h1};          // gr3 <= gr1 > 1
        i_mem[]={`STORE,`gr3,'b0,`gr7,'ha};        // store to mem2a
        i_mem[]={`SRA,`gr3,'b0,`gr1,'h8};          // gr3 <= gr1 > 8
        i_mem[]={`STORE,`gr3,'b0,`gr7,'hb};        // store to mem2b
        i_mem[]={`SRA,`gr3,'b0,`gr1,'hf};          // gr3 <= gr1 > 15
        i_mem[]={`STORE,`gr3,'b0,`gr7,'hc};        // store to mem2c
        i_mem[]={`SRA,`gr3,'b0,`gr2,'h0};          // gr3 <= gr1 > 0
        i_mem[]={`STORE,`gr3,'b0,`gr7,'hd};        // store to mem2d
        i_mem[]={`SRA,`gr3,'b0,`gr2,'h1};          // gr3 <= gr1 > 1
        i_mem[]={`STORE,`gr3,'b0,`gr7,'he};        // store to mem2e
        i_mem[]={`SRA,`gr3,'b0,`gr2,'h8};          // gr3 <= gr1 > 8
        i_mem[]={`STORE,`gr3,'b0,`gr7,'hf};        // store to mem2f
        i_mem[]={`ADDI,`gr7,'d1,'d0};              // gr7 <= 16'h30 for store address
        i_mem[]={`SRA,`gr3,'b0,`gr2,'hf};          // gr3 <= gr1 > 15
        i_mem[]={`STORE,`gr3,'b0,`gr7,'h0};        // store to mem30        
        i_mem[]={`LOAD,`gr1,'b0,`gr0,'h5};         // gr1 <= 41
        i_mem[]={`LOAD,`gr2,'b0,`gr0,'h6};         // gr2 <= ffff
        i_mem[]={`LOAD,`gr3,'b0,`gr0,'h7};         // gr3 <= 1
        i_mem[]={`JUMP, 'd0,'h4f};                 // jump to 4f
        i_mem[]={`STORE,`gr7,'b0,`gr7,'h1};        // store to mem31
        i_mem[]={`JMPR, `gr1,'h10};                 // jump to 41+10 = 51
        i_mem[]={`STORE,`gr7,'b0,`gr7,'h2};        // store to mem32
        i_mem[]={`ADD, `gr4,'b0,`gr2,'b0,`gr3};    // gr4<= ffff + 1,cf<=1
        i_mem[]={`BNC,`gr1,'h28};                   // if(cf==0) jump to 69
        i_mem[]={`BC,`gr1,'h14};                    // if(cf==1) jump to 55
        i_mem[]={`STORE,`gr7,'b0,`gr7,'h3};        // store to mem33
        i_mem[]={`ADD, `gr4,'b0,`gr3,'b0,`gr3};    // gr4<= 1 + 1 , cf<=0
        i_mem[]={`BC,`gr1,'h28};                    // if(cf==1) jump to 69
        i_mem[]={`BNC,`gr1,'h18};                   // if(cf==0) jump to 59
        i_mem[]={`STORE,`gr7,'b0,`gr7,'h4};        // store to mem34
        i_mem[]={`CMP, 'd0,'b0,`gr3,'b0,`gr3};    // 1-1=0 , zf<=1,nf<=0
        i_mem[]={`BNZ,`gr1,'h28};                   // if(zf==0) jump to 69
        i_mem[]={`BZ,`gr1,'h1c};                    // if(zf==1) jump to 5d
        i_mem[]={`STORE,`gr7,'b0,`gr7,'h5};        // store to mem35
        i_mem[]={`CMP, 'd0,'b0,`gr4,'b0,`gr3};    // 2-1=1 , zf<=0,nf<=0 
        i_mem[]={`BZ,`gr1,'h28};                    // if(zf==1) jump to 69
        i_mem[]={`BNZ,`gr1,'h20};                   // if(zf==0) jump to 61
        i_mem[]={`STORE,`gr7,'b0,`gr7,'h6};        // store to mem36
        i_mem[]={`CMP, 'd0,'b0,`gr3,'b0,`gr4};    // 1-2=-1, nf<=1,zf<=0
        i_mem[]={`BNN,`gr1,'h28};                   // if(nf==0) jump to 69
        i_mem[]={`BN,`gr1,'h24};                    // if(nf==1) jump to 65 
        i_mem[]={`STORE,`gr7,'b0,`gr7,'h7};       // store to mem37
        i_mem[]={`CMP, 'd0,'b0,`gr4,'b0,`gr3};   // 2-1=1, nf<=0,zf<=0
        i_mem[]={`BN,`gr1,'h28};                   // if(nf==1) jump to 69
        i_mem[]={`BNN,`gr1,'h27};                  // if(nf==0) jump to 68
        i_mem[]={`STORE,`gr7,'b0,`gr7,'h8};       // store to mem38
        i_mem[]={`HALT, 'd0};                     // STOP*/


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

    i_mem[] <= {`LOAD, `gr1, 'b0, `gr0, 'b0001};  //gr1=0009
    i_mem[] <= {`LOAD, `gr2, 'b0, `gr0, 'b0010};  //gr2 = 0003  
    i_mem[] <= {`ADD, `gr3, 'b0, `gr0, 'b0, `gr1}; //gr3=0009  0006  0003
    i_mem[] <= {`SUB, `gr1, 'b0, `gr1, 'b0, `gr2}; //gr1=0006  0003  0
    i_mem[] <= {`BZ, `gr0, 'b0000_1001}; //no no jump to 09
    i_mem[] <= {`BNN, `gr0,  'b0000_0010}; //jump to 2  jump to 2
    i_mem[] <= {`ADD, `gr1, 'b0, `gr0, 'b0, `gr2};
    i_mem[] <= {`ADD, `gr2, 'b0, `gr0, 'b0, `gr3};
    i_mem[] <= {`JUMP, 'b000_0000_0010};
    i_mem[] <= {`STORE, `gr2, 'b0, `gr0, 'b0011}; //d[3]=0003
    i_mem[] <= {`LOAD, `gr1, 'b0, `gr0, 'b0001}; //gr1 = 0009
    i_mem[] <= {`LOAD, `gr2, 'b0, `gr0, 'b0010}; //gr2 = 0003
    i_mem[] <= {`ADDI, `gr4, 'h1}; // gr4=1
    i_mem[] <= {`SUB, `gr2, 'b0, `gr2, 'b0, `gr3}; //gr2 = 0
    i_mem[] <= {`BZ, `gr0, 'b0001_0000}; //jump to 16
    i_mem[] <= {`JUMP, 'b000_0000_1100}; //
    i_mem[] <= {`SUBI, `gr4, 'h1}; // gr4 = 0  -1
    i_mem[] <= {`BN, `gr0, 'b0001_0100}; //no  jump to 20
    i_mem[] <= {`ADD, `gr5, 'b0, `gr5, 'b0, `gr1};  //gr5 = 0009
    i_mem[] <= {`JUMP, 'b000_0001_0000}; //jump to 16
    i_mem[] <= {`STORE, `gr5, 'b0, `gr0, 'b0100}; //d[4]=0009
    i_mem[] <= {`LOAD, `gr1, 'b0, `gr0, 'b0011};//gr1=0003
    i_mem[] <= {`LOAD, `gr2, 'b0, `gr0, 'b0100};//gr2=0009
    i_mem[] <= {`HALT, 'b000_0000_0000};


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


    //冒泡排序
    /*
    i_mem[] <= {`LOAD, `gr3, 'b0, `gr0, 'b0000};  //gr3=000a;
    i_mem[] <= {`SUBI, `gr3, 'd0, 'd2};   //gr3=0008
    i_mem[] <= {`ADD, `gr1, 'b0, `gr0, 'b0, `gr0};  //gr1=0
    i_mem[] <= {`ADD, `gr2, 'b0, `gr3, 'b0, `gr0}; //gr2=0008
    i_mem[] <= {`LOAD, `gr4, 'b0, `gr2, 'd1}; //gr4=d[9]=1057
    i_mem[] <= {`LOAD, `gr5, 'b0, `gr2, 'd2}; //gr5=d[10]=2895
    i_mem[] <= {`CMP, 'd0, 'b0, `gr5, 'b0, `gr4}; //d[10] > d[9]
    i_mem[] <= {`BN, `gr0, 'b0000, 'b1010};  //no
    i_mem[] <= {`STORE, `gr4, 'b0, `gr2, 'd2}; //d[10]=gr4
    i_mem[] <= {`STORE, `gr5, 'b0, `gr2, 'd1}; //d[9]=gr5;
    i_mem[] <= {`SUBI, `gr2, 'd0, 'd1};  //gr2=0007
    i_mem[] <= {`CMP, 'd0, 'b0, `gr2, 'b0, `gr1}; //gr2>gr1
    i_mem[] <= {`BNN, `gr0, 'h0, 'b0100}; //
    i_mem[] <= {`ADDI, `gr1, 'd0, 'd1};
    i_mem[] <= {`CMP, 'd0, 'b0, `gr3, 'b0, `gr1};
    i_mem[] <= {`BNN, `gr0, 'h0, 'b0011};
    i_mem[] <= {`HALT, 'd0};
    */

    //sort
    /*
    i_mem[] <= {`ADDI, `gr1, 'b0000,  'b1001};
    i_mem[] <= {`ADDI, `gr2, 'b0000,  'b1001};
    i_mem[] <= {`JUMP, 'b000_0000_0101};//jump to start
    i_mem[] <= {`SUBI, `gr1, 'd0, 'd1};//new_round
    i_mem[] <= {`BZ, `gr7, 'b0001, 'b0010};//jump to end
    i_mem[] <= {`LOAD, `gr3, 'b0, `gr0, 'd0};//start
    i_mem[] <= {`LOAD, `gr4, 'b0, `gr0, 'd1};
    i_mem[] <= {`CMP, 'd0, 'b0, `gr3, 'b0, `gr4};
    i_mem[] <= {`BN, `gr7, 'h0, 'b1011};//jump to NO_op
    i_mem[] <= {`STORE, `gr3, 'b0, `gr0, 'd1};
    i_mem[] <= {`STORE, `gr4, 'b0, `gr0, 'd0};
    i_mem[] <= {`ADDI, `gr0, 'b0000, 'b0001};//NO_OP
    i_mem[] <= {`CMP, 'd0, 'b0, `gr0, 'b0, `gr2};
    i_mem[] <= {`BN, `gr7, 'b0001, 'b0001};//jump to continue 
    i_mem[] <= {`SUBI, `gr2, 'd0, 'd1};
    i_mem[] <= {`SUB, `gr0, 'b0,`gr0, 'b0,`gr0};
    i_mem[] <= {`JUMP, 'b000_0000_0011};//jump to new round
    i_mem[] <= {`JUMP, 'b000_0000_0101};//jump to start,continue
    i_mem[] <= {`HALT, 'd0};//end
    */

end

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

assign  douta = d_mem[addra];

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

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

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

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

  //64badde
  /*
  d_mem[0] <= 16'hfffe;
  d_mem[] <= 'hfffe;
  d_mem[2] <= 16'hfffe;
  d_mem[] <= 'h0000;
  d_mem[4] <= 16'hffff;
  d_mem[] <= 'hffff;
  d_mem[6] <= 16'hffff;
  d_mem[] <= 'h0000;
  */
  //冒泡排序
  /*
  d_mem[0] <= 16'h000a;
  d_mem[] <= 'h0004;
  d_mem[2] <= 16'h0005;
  d_mem[] <= 'h2369;
  d_mem[4] <= 16'h69c3;
  d_mem[] <= 'h0060;
  d_mem[6] <= 16'h0fff;
  d_mem[] <= 'h5555;
  d_mem[8] <= 16'h6152;
  d_mem[] <= 'h1057;
  d_mem[10] <= 16'h2895;
  d_mem[] <= 'h0000;
  */
    //sort
  /*
  d_mem[0] = 16'h000a;
  d_mem[] = 'h0009;
  d_mem[2] = 16'h0006;
  d_mem[] = 'h0005;
  d_mem[4] = 16'h0001;
  d_mem[] = 'h0004;
  d_mem[6] = 16'h0003;
  d_mem[] = 'h0011;
  d_mem[8] = 16'h0000;
  d_mem[] = 'h0000;
  d_mem[10] = 16'h0000;
  d_mem[] = '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 = ;
        enable = ;
        reset = ;
        start = ;

      $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[], uut.pcpu.gr[], uut.pcpu.gr[],
          uut.pcpu.gr[], uut.pcpu.gr[], uut.pcpu.gr[],
          uut.pcpu.gr[], uut.pcpu.cin, uut.pcpu.nf, uut.pcpu.zf);

        // Wait  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
    Verilog 數字電路設計之帶hazard的五級流水線CPU
  • 最大公約數和最小公倍數

    數字0x20和數字0x18的最大公約數是 0x0008,最小公倍數是0x0060。

    Verilog 數字電路設計之帶hazard的五級流水線CPU
  • 64位加法
    Verilog 數字電路設計之帶hazard的五級流水線CPU
  • 冒泡排序

    0x000a表示要對10個數字進行排序,下面為十個排好序的數字。

    Verilog 數字電路設計之帶hazard的五級流水線CPU
  • 排序
    Verilog 數字電路設計之帶hazard的五級流水線CPU