从零开始写处理器(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触发器在上升沿时数据变化导致没有读到,有解决方案会更新。

浙公网安备 33010602011771号