用Verilog HDL写一个单周期MIPS Processor但是有问题。不知道是哪里写的不对?

标签里没有Verilog很尴尬。。。用Verilog写一个Single Cycle Processor,主模块是processor。小模块有:
datapath, controller, ALUController, data memory, instruction memory,
register file,ALU, FlipFlop, ImmGen。一共九个小模块。这些模块我都写出来了,但是找不到错误在哪里,希望有人帮下忙。其实是很基础的东西,但是工作量会比较大所以悬赏也会比较多。可以确定没有问题的模块有Datapath,Controller,ALUController。顺便说下我用的是Vivado

大体的设计图如下:
图片说明

还有:图片说明

processor的testbench如下

`timescale 1ns / 1ps

module  tb_processor ();

/**  Clock & reset  **/
reg  clk , rst ;
wire  [31:0]  tb_Result;

processor  processor_inst(
    .clk          (clk),
    .reset       (rst),
    .Result   (tb_Result)
);

always  begin
#10;
clk = ~clk;
end

initial  begin
clk = 0;
@( posedge  clk );
    rst = 1;
@( posedge  clk );
    rst = 0;
end

integer  point  =0;

always @(*)
begin

    #20;
    if (tb_Result  == 32'h00000000) // and
    begin
        point = point + 1;
    end

    #20;
    if (tb_Result  == 32'h00000001) // addi
    begin
        point = point + 1;
    end

    #20;
    if (tb_Result  == 32'h00000002) // addi
    begin
        point = point + 1;
    end

    #20;
    if (tb_Result  == 32'h00000004) // addi
    begin
        point = point + 1;
    end;

    #20;
    if (tb_Result  == 32'h00000005) // addi
    begin
        point = point + 1;
    end;

    #20;
    if (tb_Result  == 32'h00000007) // addi
    begin
        point = point + 1;
    end

    #20;
    if (tb_Result  == 32'h00000008) //addi
    begin
        point = point + 1;
    end

    # 20;
    if (tb_Result  == 32'h0000000b)// addi
    begin
        point = point + 1;
    end

    # 20;
    if (tb_Result  == 32'h00000003) // add
    begin
        point = point + 1;
    end

    # 20;
    if (tb_Result  == 32'hfffffffe) // sub
    begin
        point = point + 1;
    end;

    # 20;
    if (tb_Result  == 32'h00000000) // and
    begin
        point = point + 1;
    end;

    # 20;
    if (tb_Result  == 32'h00000005) // or
    begin
        point = point + 1;
    end;

    # 20;
    if (tb_Result  == 32'h00000001)// SLT
    begin
        point = point + 1;
    end;

    #20;
    if (tb_Result  == 32'hfffffff4) // NOR
    begin
        point = point + 1;
    end

    #20;
    if (tb_Result  == 32'h000004D2) // andi
    begin
        point = point + 1;
    end

    #20;
    if (tb_Result  == 32'hfffff8d7) // ori
    begin
        point = point + 1;
    end

    #20;
    if (tb_Result  == 32'h00000001) // SLT
    begin
        point = point + 1;
    end;

    # 20;
    if (tb_Result  == 32'hfffffb2c) // nor
    begin
        point = point + 1;
    end;

    # 20;
    if (tb_Result  == 32'h00000030) // sw
    begin
        point = point + 1;
    end;

    # 20;
    if (tb_Result  == 32'h00000030) // l
    begin
        point = point + 1;
    end;

    # 20;
    if (tb_Result  == 32'h00000030) // lw
    begin
        point = point + 1;
    end;

    $display ("%s%d","The  number  of  correct  test  cases  is:" , point);

end

initial  begin
#430;
$finish ;

end

endmodule

正确的结果应该是这样↓
图片说明
我自己的结果是这样↓
图片说明

下面发我所有模块的代码
processor:

`timescale 1ns / 1ps

module processor
(
    input clk, reset,

    output [31:0] Result
);

wire reg_write1;
wire mem2reg1;
wire alu_src1;
wire mem_write1;
wire mem_read1;
wire [3:0]alu_cc1;
wire [6:0]opcode1;
wire [6:0]funct71;
wire [2:0]funct31;
wire [31:0] alu_result1;

wire [1:0]ALUOp1;

data_path un(
    .clk(clk),
    .reset(reset),
    .alu_result(alu_result1),
    .reg_write(reg_write1),
    .mem2reg(mem2reg1),
    .alu_src(alu_src1),
    .mem_write(mem_write1),
    .mem_read(mem_read1),
    .alu_cc(alu_cc1),
    .opcode(opcode1),
    .funct7(funct71),
    .funct3(funct31)
);

Controller uni(
    .Opcode(opcode1),
    .ALUSrc(alu_src1),
    .MemtoReg(mem2reg1),
    .RegWrite(reg_write1),
    .MemRead(mem_read1),
    .MemWrite(mem_write1),
    .ALUOp(ALUOp1)
);

ALUController u(
    .ALUOp(ALUOp1),
    .Funct7(funct71),
    .Funct3(funct31),
    .Operation(alu_cc1)
);

assign Result = alu_result1;

endmodule

Datapath:

`timescale 1ns / 1ps

module data_path  #(
    parameter PC_W = 8,
    parameter INS_W = 32,
    parameter RF_ADDRESS = 5,
    parameter DATA_W = 32,
    parameter  DM_ADDRESS = 9,
    parameter  ALU_CC_W = 4
)(
    input                      clk ,
    input                      reset ,
    input                      reg_write ,
    input                      mem2reg ,
    input                      alu_src ,
    input                      mem_write,
    input                      mem_read,
    input   [ALU_CC_W -1:0]   alu_cc ,
    output            [6:0]   opcode ,
    output            [6:0]   funct7,
    output            [2:0]   funct3 ,
    output    [DATA_W -1:0]   alu_result );

wire [PC_W -1:0]    pc , pc_next;
wire [INS_W -1:0]   instruction;
wire [DATA_W -1:0]  l_alu_result;
wire [DATA_W -1:0]  reg1 , reg2;
wire [DATA_W -1:0]  l_read_data;
wire [DATA_W -1:0]  l_reg_wr_data;
wire [DATA_W -1:0]  srcb ;
wire [DATA_W -1:0]  extimm;

    assign  pc_next = pc + 4;
    FlipFlop   pcreg(clk , reset , pc_next , pc);

    Instr_mem  instruction_mem (pc , instruction );

    assign  opcode = instruction [6:0];
    assign  funct7 = instruction [31:25];
    assign  funct3 = instruction [14:12];

    RegFile  rf(
        .clk            ( clk                     ),
        .reset          ( reset                  ),
        .rg_wrt_en     ( reg_write             ),
        .rg_wrt_addr   ( instruction [11:7]    ),
        .rg_rd_addr1   ( instruction [19:15]   ),
        .rg_rd_addr2   ( instruction [24:20]   ),
        .rg_wrt_data   ( l_reg_wr_data         ),
        .rg_rd_data1   ( reg1                   ),
        .rg_rd_data2   ( reg2                    ));

        assign  l_reg_wr_data = mem2reg ? l_read_data : l_alu_result;

        ImmGen  ext_imm (instruction , extimm );

        assign  srcb = alu_src ? extimm : reg2;
        alu_32  alu_module( .A_in(reg1), .B_in(srcb), .ALU_Sel(alu_cc),
        .ALU_Out(l_alu_result), .Carry_Out(), .Zero(), .Overflow ());

        assign  alu_result = l_alu_result;

        DataMem  data_mem(.addr(l_alu_result[DM_ADDRESS -1:2]) , .read_data(l_read_data),
        .write_data(reg2), .MemWrite(mem_write), .MemRead(mem_read) );

endmodule

FlipFlop:

`timescale 1ns / 1ps

module FlipFlop(
    clk , reset,
    d ,
    q
    );

input [7:0]d;
input clk;
input reset;
output reg [7:0]q;

always @(posedge clk) begin
    if (reset) 
    q <= 0;
    else
    q <= d;
    end

endmodule****

instruction memory:

**`timescale 1ns / 1ps**

// Module definition
module Instr_mem(
    input [7:0] addr ,
    output wire [31:0] instruction
);

reg [31:0] Instruction_memory [0:63];

initial
begin
Instruction_memory[0] = 32'h00007033;
Instruction_memory[1] = 32'h00100093;
Instruction_memory[2] = 32'h00200113;
Instruction_memory[3] = 32'h00308193;
Instruction_memory[4] = 32'h00408213;
Instruction_memory[5] = 32'h00510293;
Instruction_memory[6] = 32'h00610313;
Instruction_memory[7] = 32'h00718393;
Instruction_memory[8] = 32'h00208433;
Instruction_memory[9] = 32'h404404b3;
Instruction_memory[10] = 32'h00317533;
Instruction_memory[11] = 32'h0041e5b3;
Instruction_memory[12] = 32'h0041a633;
Instruction_memory[13] = 32'h007346b3;
Instruction_memory[14] = 32'h4d34f713;
Instruction_memory[15] = 32'h8d35e793;
Instruction_memory[16] = 32'h4d26a813;
Instruction_memory[17] = 32'h4d244893;
Instruction_memory[18] = 32'h02b02823;
Instruction_memory[19] = 32'h03002603;
end

assign instruction = Instruction_memory[addr];

endmodule

RegFile:

`timescale 1ns / 1ps

// Module definition
module RegFile(
    clk , reset , rg_wrt_en ,
    rg_wrt_addr ,
    rg_rd_addr1 ,
    rg_rd_addr2 ,
    rg_wrt_data ,
    rg_rd_data1 ,
    rg_rd_data2
);

input clk;
input reset;
input rg_wrt_en;
input [4:0] rg_rd_addr1;
input [4:0] rg_rd_addr2;
output [31:0] rg_rd_data1;
output [31:0] rg_rd_data2;
input [4:0] rg_wrt_addr;
input [31:0] rg_wrt_data;
reg [31:0] register_file [0:31];
assign rg_rd_data1 = register_file[rg_rd_addr1];
assign rg_rd_data2 = register_file[rg_rd_addr2];
integer i;
always @(posedge clk or reset) begin
    if (reset) begin
        for (i = 0; i < 32; i = i + 1)
        register_file[i] <= 0;
        end else begin
        if (rg_wrt_en)
        register_file[rg_wrt_addr] <= rg_wrt_data;
        end
        end

endmodule

ImmGen:

`timescale 1ns / 1ps
module ImmGen(
    InstCode ,
    ImmOut
    );
input [31:0] InstCode;
output reg [31:0] ImmOut;
always @(InstCode)
begin
case (InstCode[6:0])

7'b0000011 /*I-type load*/     :
    ImmOut = {InstCode[31]? {20{1'b1}}:20'b0 , InstCode[31:20]};
7'b0010011  /*I-type  addi*/     :
    ImmOut = {InstCode[31]? {20{1'b1}}:20'b0 , InstCode[31:20]};
7'b0100011  /*S-type   store*/           :
    ImmOut = {InstCode[31]? {20{1'b1}}:20'b0 , InstCode[31:25], InstCode[11:7]};
7'b0010111  /*U-type  AUIPC*/    :
    ImmOut = {InstCode[31:12], 12'b0};
default
    ImmOut = {32'b0};
endcase
end
endmodule

ALU:

`timescale 1ns / 1ps
module alu_32(
    input   [31:0] A_in ,B_in ,
    input   [3:0]   ALU_Sel ,
    output [31:0] ALU_Out , 
    output  reg     Carry_Out ,
    output          Zero ,
    output  reg     Overflow = 1'b0
    );
reg   [31:0] ALU_Result;
reg [32:0] temp;
reg [32:0] twos_com; 
assign  ALU_Out    = ALU_Result;  
assign  Zero       = (ALU_Result  == 0); 

always @(*)
    begin
        Overflow = 1'b0;
        Carry_Out = 1'b0;
        case(ALU_Sel)
            4'b0000:
                ALU_Result = A_in & B_in;
            4'b0001:
                ALU_Result = A_in | B_in;
            4'b0010:
                begin
                    ALU_Result = $signed(A_in) + $signed(B_in);
                    temp = {1'b0, A_in} + {1'b0, B_in};
                    Carry_Out = temp[32];
                    if ((A_in[31] & B_in[31] & ~ALU_Out[31]) |
                    (~A_in[31] & ~B_in[31] & ALU_Out[31]))
                        Overflow = 1'b1;
                    else
                        Overflow = 1'b0;
                end
            4'b0110:
                begin
                    ALU_Result = $signed(A_in) - $signed(B_in) ;
                    twos_com = ~(B_in) + 1'b1;
                    if ((A_in[31] & twos_com[31] & ~ALU_Out[31]) |
                    (~A_in[31] & ~twos_com[31] & ALU_Out[31]))
                        Overflow = 1'b1;

                    else
                        Overflow = 1'b0;
                end
            4'b0111:
                ALU_Result = ($signed(A_in) < $signed(B_in ))?32 'd1:32'd0;
            4'b1100:
                ALU_Result = ~(A_in | B_in);
            4'b1111:
                ALU_Result = (A_in==B_in )?32'd1:32'd0 ;
            default: ALU_Result = A_in + B_in ;
        endcase
    end
endmodule

data memory:

`timescale 1ns / 1ps

module DataMem(MemRead, MemWrite, addr, write_data, read_data);

input wire MemRead;
input wire MemWrite;
input wire [8:0] addr;
input [31:0] write_data;
output reg [31:0] read_data;
reg [31:0] memory [0:127];
integer i;
initial
    begin
    read_data = 0;
    for (i = 0; i < 128; i = i + 1) begin
        memory[i] = i; end
    end
always @(*)
    begin
    if (MemWrite)
        memory[addr] = write_data;
    if (MemRead)
        read_data = memory[addr];
    end
endmodule

Controller:

`timescale 1ns / 1ps


module Controller(
    Opcode,
    ALUSrc, MemtoReg, RegWrite, MemRead, MemWrite,
    ALUOp
    );

input [6:0] Opcode;
output reg ALUSrc;
output reg MemtoReg;
output reg RegWrite;
output reg MemRead;
output reg MemWrite;
output reg [1:0] ALUOp;


always @(*)
begin
    case(Opcode)
    7'b0110011: begin
    MemtoReg = 1'b0;
    MemWrite = 1'b0;
    MemRead = 1'b0;
    ALUSrc = 1'b0;
    RegWrite = 1'b1;
    ALUOp = 2'b10;
    end

    7'b0010011: begin
    MemtoReg = 1'b0;
    MemWrite = 1'b0;
    MemRead = 1'b0;
    ALUSrc = 1'b1;
    RegWrite = 1'b1;
    ALUOp = 2'b00;
    end

    7'b0000011: begin
    MemtoReg = 1'b1;
    MemWrite = 1'b0;
    MemRead = 1'b1;
    ALUSrc = 1'b1;
    RegWrite = 1'b1;
    ALUOp = 2'b01;
    end

    7'b0100011: begin
    MemtoReg = 1'b0;
    MemWrite = 1'b1;
    MemRead = 1'b0;
    ALUSrc = 1'b1;
    RegWrite = 1'b0;
    ALUOp = 2'b01;
    end

    default: begin
    MemtoReg = 1'b0;
    MemWrite = 1'b0;
    MemRead = 1'b0;
    ALUSrc = 1'b0;
    RegWrite = 1'b1;
    ALUOp = 2'b00;
    end
    endcase
    end

endmodule

ALUController:

`timescale 1ns / 1ps

module ALUController(
    ALUOp, Funct7, Funct3, Operation
    );

input [1:0] ALUOp;
input [6:0] Funct7;
input [2:0] Funct3;
output reg [3:0] Operation;
wire [11:0] ALU_In;
assign ALU_In = {Funct7, Funct3, ALUOp};
always @(ALU_In)
    casex (ALU_In)
    12'b000000011110: Operation = 4'b0000;
    12'b000000011010: Operation = 4'b0001;
    12'b000000010010: Operation = 4'b1100;
    12'b000000001010: Operation = 4'b0111;
    12'b000000000010: Operation = 4'b0010;
    12'b010000000010: Operation = 4'b0110;
    12'bxxxxxxx11100: Operation = 4'b0000;
    12'bxxxxxxx11000: Operation = 4'b0001;
    12'bxxxxxxx10000: Operation = 4'b1100;
    12'bxxxxxxx01000: Operation = 4'b0111;
    12'bxxxxxxx00000: Operation = 4'b0010;
    12'bxxxxxxx01001: Operation = 4'b0010;
    12'bxxxxxxx01001: Operation = 4'b0010;
    default: Operation = 4'b0000;
    endcase

endmodule

https://blog.csdn.net/saber_jk/article/details/80928188