mips - 单周期 mips verilog 实现的程序计数器调试
问题描述
我目前正在尝试在 Verilog 上实现一个 32 位单周期处理器。到目前为止,我的代码运行顺利(我能够成功实现 r 型指令、分支、j 和 jal),但是当我尝试实现 jr 时我的代码开始失败。在调试时,我认为我的程序计数器实现可能是错误的。如果有人能指出我在哪里出错了,那将意味着很多。
这是我没有实现 jr 的程序计数器:
assign PCplus4 = inst_addr + 32'd4;
assign extendedimm = { {16{inst[15]}} , inst[15:0] };
assign extendedimmafter = extendedimm << 2;
assign PCbeforeBranch = PCplus4 + extendedimmafter;
always @ (posedge clk or negedge nrst)
begin
if(!nrst)
inst_next <= 0;
else if(Jump)
inst_next <= {PCplus4[31:28],inst[25:0],2'b00 };
else if(PCSrc)
inst_next <= PCbeforeBranch;
else
inst_next <= PCplus4;
end
assign inst_addr = inst_next;
这是我实现 jr 后的程序计数器:
assign PCSrc = Branch & (Zero ^ B);
assign PCplus4 = inst_addr + 32'd4;
assign extendedimm = { {16{inst[15]}} , inst[15:0] };
assign extendedimmafter = extendedimm << 2;
assign PCbeforeBranch = PCplus4 + extendedimmafter;
always @ (posedge clk or negedge nrst)
begin
if(!nrst)
inst_next <= 0;
else if(Jump)
inst_next <= {PCplus4[31:28],inst[25:0],2'b00 };
else if(PCSrc)
inst_next <= PCbeforeBranch;
else if(PCSrc3)
inst_next <= rd_dataA;
else
inst_next <= PCplus4;
end
assign inst_addr = inst_next;
编辑:正如有人在评论中指出的那样,rd_dataA 和 regfile 之间可能存在数据竞争,所以我发布了我的 regfile 实现以及我如何在下面的主代码中实例化它!
module rf(
input clk,
input nrst,
input [4:0] rd_addrA,
input [4:0] rd_addrB,
output [31:0] rd_dataA,
output [31:0] rd_dataB,
input wr_en,
input [4:0] wr_addr,
input [31:0] wr_data
);
reg [31:0] regf [31:0];
wire [31:0] reg1;
wire [31:0] reg2;
wire [31:0] reg3;
wire [31:0] reg4;
wire [31:0] reg5;
wire [31:0] reg6;
wire [31:0] reg7;
wire [31:0] reg8;
wire [31:0] reg9;
wire [31:0] reg10;
wire [31:0] reg11;
wire [31:0] reg12;
wire [31:0] reg13;
wire [31:0] reg14;
wire [31:0] reg15;
wire [31:0] reg16;
wire [31:0] reg17;
wire [31:0] reg18;
wire [31:0] reg19;
wire [31:0] reg20;
wire [31:0] reg21;
wire [31:0] reg22;
wire [31:0] reg23;
wire [31:0] reg24;
wire [31:0] reg25;
wire [31:0] reg26;
wire [31:0] reg27;
wire [31:0] reg28;
wire [31:0] reg29;
wire [31:0] reg30;
wire [31:0] reg31;
wire [31:0] reg32;
assign reg1 = regf[0];
assign reg2 = regf[1];
assign reg3 = regf[2];
assign reg4 = regf[3];
assign reg5 = regf[4];
assign reg6 = regf[5];
assign reg7 = regf[6];
assign reg8 = regf[7];
assign reg9 = regf[8];
assign reg10 = regf[9];
assign reg11 = regf[10];
assign reg12 = regf[11];
assign reg13 = regf[12];
assign reg14 = regf[13];
assign reg15 = regf[14];
assign reg16 = regf[15];
assign reg17 = regf[16];
assign reg18 = regf[17];
assign reg19 = regf[18];
assign reg20 = regf[19];
assign reg21 = regf[20];
assign reg22 = regf[21];
assign reg23 = regf[22];
assign reg24 = regf[23];
assign reg25 = regf[24];
assign reg26 = regf[25];
assign reg27 = regf[26];
assign reg28 = regf[27];
assign reg29 = regf[28];
assign reg30 = regf[29];
assign reg31 = regf[30];
assign reg32 = regf[31];
always @ (posedge clk, negedge nrst)
if (!nrst) begin
regf[0] <= 32'd0;
regf[1] <= 32'd0;
regf[2] <= 32'd0;
regf[3] <= 32'd0;
regf[4] <= 32'd0;
regf[5] <= 32'd0;
regf[6] <= 32'd0;
regf[7] <= 32'd0;
regf[8] <= 32'd0;
regf[9] <= 32'd0;
regf[10] <= 32'd0;
regf[11] <= 32'd0;
regf[12] <= 32'd0;
regf[13] <= 32'd0;
regf[14] <= 32'd0;
regf[15] <= 32'd0;
regf[16] <= 32'd0;
regf[17] <= 32'd0;
regf[18] <= 32'd0;
regf[19] <= 32'd0;
regf[20] <= 32'd0;
regf[21] <= 32'd0;
regf[22] <= 32'd0;
regf[23] <= 32'd0;
regf[24] <= 32'd0;
regf[25] <= 32'd0;
regf[26] <= 32'd0;
regf[27] <= 32'd0;
regf[28] <= 32'd0;
regf[29] <= 32'd0;
regf[30] <= 32'd0;
regf[31] <= 32'd0;
end
else
if (wr_en)
case (wr_addr)
5'd0: regf[wr_addr] <= 0;
default: regf[wr_addr] <= wr_data;
endcase
assign rd_dataA = regf[rd_addrA];
assign rd_dataB = regf[rd_addrB];
endmodule
以下是我在主代码中实例化 regfile 的方式:
always @ (*) begin
opcode <= inst[31:26];
rd_addrA <= inst[25:21];
rd_addrB <= inst[20:16];
shamt <= inst[10:6];
funct <= inst[5:0];
end
rf regf( clk, nrst, rd_addrA, rd_addrB, rd_dataA, rd_dataB, wr_en, wr_addr, WriteData);
解决方案
推荐阅读
- javascript - 如何在对象内部使用解构赋值
- bash - 在linux中使用file命令向文件添加扩展名
- ruby-on-rails - Rails 5:视图/控制器中未初始化的常量,但不是控制台
- r - 在 mlr 和 parallelMap 中可以并行化多个级别吗?例如 mlr.tuneParams 和 mlr.benchmark
- jboss - log4j2 似乎没有遵循我的日志滚动策略
- reactjs - 将 fetch 操作转换为 axios 操作
- c# - “必须声明标量变量@dni”
- c# - 如何修复清单中的不匹配引用和下载的程序集 LINQPad.exe 的标识
- javascript - 如何将相同的选项附加到多个选择下拉框?
- python - Flask Dash 将回调中生成的变量传递给另一个回调