问题描述
我目前正在尝试在Verilog上实现32位单周期处理器。到目前为止,我的代码运行顺利(我能够成功实现r型指令,branch,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]}},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);
解决方法
暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!
如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。
小编邮箱:dio#foxmail.com (将#修改为@)