从零开始写处理器(3)——处理器测试

经过前两篇文章的介绍,我们已经完成了对所有模块的设计,这里给出top文件

`timescale 1ns / 1ps
module MIPSCpu(
input clk, rst_n,
input [31:0] ext_data,ext_data_addr,
input ext_data_en,
input [31:0] ext_instr,ext_instr_addr,
input ext_instr_en,
output [31:0] result,
input start);

wire regwrite,memtoregE,regwriteM,regwriteW,pcsrcD,memtoregM,regwriteE,memtoreg,memwrite;
wire [1:0] branch,forwardAE,forwardBE;
wire [3:0] alucontrol;
wire alusrc,regdst,jump,mult_sel,forwardAD,forwardBD,flushD,stallF,stallD,flushE;
wire[4:0] rsE,rtE,rtD,rsD,writeregM,writeregW,writeregE;
wire [5:0]op,funct;
    
datapath datapath(clk,rst_n,regwrite,memtoreg,memwrite,branch,alucontrol,
                    alusrc,regdst,jump,mult_sel,forwardAE,forwardBE,forwardAD,forwardBD,
                    flushD,stallF,stallD,flushE,rsE,rtE,rtD,rsD,writeregM,writeregW,
                    regwriteM,regwriteW, memtoregE,writeregE,pcsrcD,memtoregM,regwriteE,
                    op,funct,result,ext_data,ext_data_addr,ext_data_en,ext_instr,
                    ext_instr_addr,ext_instr_en,start);
                    
hazard_handle hazard_handle(rsE,rtE,rtD,rsD,writeregM,writeregW,regwriteM,regwriteW,
                            memtoregE,writeregE,pcsrcD,memtoregM,regwriteE,jump,
                            forwardAE,forwardBE,forwardAD,forwardBD,flushD,
                            stallF,stallD,flushE);
                            
control_unit control_unit(funct,op,rst_n,regwrite,memtoreg,memwrite,branch,alucontrol,
                        alusrc,regdst,jump,mult_sel);

endmodule

测试文件给出如下,需要用到两个文件,分别用于导入数据内存与指令内存,将这两个文件通过ext_端口导入到cpu中相应的寄存器后,对流水线寄存器进行复位,再将start置1,cpu会自动进行运算

`timescale 1ns / 1ps
module cpu_tb();

parameter SIZE_MEM = 10;
parameter SIZE_IM = 6;

reg clk;
reg rst_n;
reg [31:0] ext_data,ext_data_addr;
reg ext_data_en;
reg [31:0] ext_instr,ext_instr_addr;
reg ext_instr_en;
reg start;
wire [31:0] result;

reg [31:0]inst_mem_tb[SIZE_IM-1:0];
reg [31:0]data_mem_tb[SIZE_MEM-1:0];

integer i;

MIPSCpu cpu(clk,rst_n,ext_data,ext_data_addr,ext_data_en,ext_instr,ext_instr_addr,ext_instr_en,result,start);

always
begin
    #50 clk = !clk;
end

initial 
begin
    $readmemh("C:/Users/chenx/mips_5stages/mips_5stages.srcs/sources_1/new/im_file.txt",inst_mem_tb);
    $readmemh("C:/Users/chenx/mips_5stages/mips_5stages.srcs/sources_1/new/mem_file.txt",data_mem_tb);
end

initial 
begin
    rst_n = 1;
    clk = 1;
    ext_data = 0;
    ext_data_addr = 0;
    ext_data_en = 0;
    ext_instr = 0;
    ext_instr_addr = 0;
    ext_instr_en = 0;
    start = 0;
    @(negedge clk);
    for (i=0;i<SIZE_IM;i=i+1) begin//loading instruction memory
        ext_instr_en = 1;
        ext_instr_addr = 4*i;
        ext_instr = inst_mem_tb[i];
        @(negedge clk);
    end
    ext_instr = 0;
    ext_instr_addr = 0;
    ext_instr_en = 0;
    @(negedge clk);
        for (i=0;i<SIZE_MEM;i=i+1) begin//loading data memory
        ext_data_en = 1;
        ext_data_addr = 4*i;
        ext_data = data_mem_tb[i];
        @(negedge clk);
    end
    ext_data = 0;
    ext_data_addr = 0;
    ext_data_en = 0;
    @(negedge clk);
    #20
    rst_n = 0;
    #20
    rst_n = 1;
    start = 1;
end
endmodule

im_file中全为8位16进制数,使用指令见第一篇文章。我首先测试了lw指令,连续取数十次,结果符合。

在进行后续测试时感觉代码有些bug,主要问题是Execute寄存器不能正常工作,输出的数据不总是相对Decode阶段向后偏移一个时钟,目前还没有解决,出问题的部分如下所示

 alusrc与memtoreg这两个参数的传递出了问题,还有其它几个感觉参数传递的也有些奇怪。目前感觉是D触发器在上升沿时数据变化导致没有读到,有解决方案会更新。

 

posted @ 2020-02-08 21:42  霍比特人长不高  阅读(390)  评论(0)    收藏  举报