I am almost finished implementing a 5-stage-pipeline Mips Cpu on FPGA board(Spartan 3E starter kit). But one Module has a critical problem.
That problem is when mMdule take Data from input signal, Module take old values. That Module is register which is the most important part of CPU.
here is Screenshot(Isim): screenshot http://cfile8.uf.tistory.com/original/2441AB3351B74AD217FE01
Gray arrow is what I design(What I want).
But Module work as red arrow.
Module define
(When reg_write is true) and (Clk is true-not show in screenshot)
register[write_reg]=write_data;
I have my own FPGA board(Spartan 3E starter kit)
I implement only this module on board. I made signal(Clk, signal. write_reg, write_data)
with onboard sw0~4. (even though clk)
and then it working!
no problem.
but when use this Module in Whole CPU design.
Module Occur old values problem.
Here is the whole source
module reg1(Reset, Clk, read_reg1, read_reg2, write_reg, write_data, reg_write, read_data1, read_data2
);
input Reset;
input Clk;
input reg_write;
input [4:0] read_reg1, read_reg2, write_reg;
input [31:0] write_data;
output [31:0] read_data1;
output [31:0] read_data2;
reg [31:0] register [11:0];
reg [31:0] read_data1_reg;
reg [31:0] read_data2_reg;
wire [31:0] read_data1=read_data1_reg;
wire [31:0] read_data2=read_data2_reg;
always @(reg_write or Reset or read_reg1 or read_reg2)
begin
if(reg_write == 1'b0 )
begin
case(read_reg1)
5'b00000: read_data1_reg=register[0];
5'b00001: read_data1_reg=register[1];
5'b00010: read_data1_reg=register[2];
5'b00011: read_data1_reg=register[3];
5'b00100: read_data1_reg=register[4];
5'b00101: read_data1_reg=register[5];
5'b00110: read_data1_reg=register[6];
5'b00111: read_data1_reg=register[7];
5'b01000: read_data1_reg=register[8];
5'b01001: read_data1_reg=register[9];
5'b01010: read_data1_reg=register[10];
5'b01011: read_data1_reg=register[11];
default: read_data1_reg=32'h00000000;
endcase
case(read_reg2)
5'b00000: read_data2_reg=register[0];
5'b00001: read_data2_reg=register[1];
5'b00010: read_data2_reg=register[2];
5'b00011: read_data2_reg=register[3];
5'b00100: read_data2_reg=register[4];
5'b00101: read_data2_reg=register[5];
5'b00110: read_data2_reg=register[6];
5'b00111: read_data2_reg=register[7];
5'b01000: read_data2_reg=register[8];
5'b01001: read_data2_reg=register[9];
5'b01010: read_data2_reg=register[10];
5'b01011: read_data2_reg=register[11];
default: read_data2_reg=32'h00000000;
endcase
end
else
begin
if(Clk==1'b1)
case(write_reg)
5'b00000: register[0] = write_data;
5'b00001: register[1] = write_data;
5'b00010: register[2] = write_data;
5'b00011: register[3] = write_data;
5'b00100: register[4] = write_data;
5'b00101: register[5] = write_data;
5'b00110: register[6] = write_data;
5'b00111: register[7] = write_data;
5'b01000: register[8] = write_data;
5'b01001: register[9] = write_data;
5'b01010: register[10] = write_data;
5'b01011: register[11] = write_data;
default: register[0] = register[0];
endcase
else
begin
//read_data1_reg = register[read_reg1];
//read_data2_reg = register[read_reg2];
case(read_reg1)
5'b00000: read_data1_reg=register[0];
5'b00001: read_data1_reg=register[1];
5'b00010: read_data1_reg=register[2];
5'b00011: read_data1_reg=register[3];
5'b00100: read_data1_reg=register[4];
5'b00101: read_data1_reg=register[5];
5'b00110: read_data1_reg=register[6];
5'b00111: read_data1_reg=register[7];
5'b01000: read_data1_reg=register[8];
5'b01001: read_data1_reg=register[9];
5'b01010: read_data1_reg=register[10];
5'b01011: read_data1_reg=register[11];
default: read_data1_reg=32'h00000000;
endcase
case(read_reg2)
5'b00000: read_data2_reg=register[0];
5'b00001: read_data2_reg=register[1];
5'b00010: read_data2_reg=register[2];
5'b00011: read_data2_reg=register[3];
5'b00100: read_data2_reg=register[4];
5'b00101: read_data2_reg=register[5];
5'b00110: read_data2_reg=register[6];
5'b00111: read_data2_reg=register[7];
5'b01000: read_data2_reg=register[8];
5'b01001: read_data2_reg=register[9];
5'b01010: read_data2_reg=register[10];
5'b01011: read_data2_reg=register[11];
default: read_data2_reg=32'h00000000;
endcase
end
end
if(Reset)
begin
register[0] = 32'h00000000;
register[1] = 32'h00000000;
register[2] = 32'h00000000;
register[3] = 32'h00000000;
register[4] = 32'h00000000;
register[5] = 32'h00000000;
register[6] = 32'h00000000;
register[7] = 32'h00000000;
register[8] = 32'h00000000;
register[9] = 32'h00000000;
register[10] = 32'h00000000;
register[11] = 32'b00000000000000000000000110010000;
case(read_reg1)
5'b00000: read_data1_reg=register[0];
5'b00001: read_data1_reg=register[1];
5'b00010: read_data1_reg=register[2];
5'b00011: read_data1_reg=register[3];
5'b00100: read_data1_reg=register[4];
5'b00101: read_data1_reg=register[5];
5'b00110: read_data1_reg=register[6];
5'b00111: read_data1_reg=register[7];
5'b01000: read_data1_reg=register[8];
5'b01001: read_data1_reg=register[9];
5'b01010: read_data1_reg=register[10];
5'b01011: read_data1_reg=register[11];
default: read_data1_reg=32'h00000000;
endcase
case(read_reg2)
5'b00000: read_data2_reg=register[0];
5'b00001: read_data2_reg=register[1];
5'b00010: read_data2_reg=register[2];
5'b00011: read_data2_reg=register[3];
5'b00100: read_data2_reg=register[4];
5'b00101: read_data2_reg=register[5];
5'b00110: read_data2_reg=register[6];
5'b00111: read_data2_reg=register[7];
5'b01000: read_data2_reg=register[8];
5'b01001: read_data2_reg=register[9];
5'b01010: read_data2_reg=register[10];
5'b01011: read_data2_reg=register[11];
default: read_data2_reg=32'h00000000;
endcase
//
end
else
begin
register[0] = register[0];
register[1] = register[1];
register[2] = register[2];
register[3] = register[3];
register[4] = register[4];
register[5] = register[5];
register[6] = register[6];
register[7] = register[7];
register[8] = register[8];
register[9] = register[9];
register[10] = register[10];
register[11] = register[11];
case(read_reg1)
5'b00000: read_data1_reg=register[0];
5'b00001: read_data1_reg=register[1];
5'b00010: read_data1_reg=register[2];
5'b00011: read_data1_reg=register[3];
5'b00100: read_data1_reg=register[4];
5'b00101: read_data1_reg=register[5];
5'b00110: read_data1_reg=register[6];
5'b00111: read_data1_reg=register[7];
5'b01000: read_data1_reg=register[8];
5'b01001: read_data1_reg=register[9];
5'b01010: read_data1_reg=register[10];
5'b01011: read_data1_reg=register[11];
default: read_data1_reg=32'h00000000;
endcase
case(read_reg2)
5'b00000: read_data2_reg=register[0];
5'b00001: read_data2_reg=register[1];
5'b00010: read_data2_reg=register[2];
5'b00011: read_data2_reg=register[3];
5'b00100: read_data2_reg=register[4];
5'b00101: read_data2_reg=register[5];
5'b00110: read_data2_reg=register[6];
5'b00111: read_data2_reg=register[7];
5'b01000: read_data2_reg=register[8];
5'b01001: read_data2_reg=register[9];
5'b01010: read_data2_reg=register[10];
5'b01011: read_data2_reg=register[11];
default: read_data2_reg=32'h00000000;
endcase
end
end
endmodule
First problem, clk is not in your sensitivity list of the always block, but you use it in one of the if statements.
More concerning is the coding of this whole block. You are inferring latches when you want registers. The first thing to correct is that you are using blocking assignments "=" when you want non-blocking assignments "<=". The second thing that you should look into changing is pulling out the registers assignment and do that in a different always block. it will look something like this:
always@(posedge clk, posedge reset)
begin
if(reset)
reset data
else if( write_en0
set regs to writedata
else
reg <= reg
end
always@(posedge clk, posedge reset)
begin
read_data1 data
end
always@(posedge clk, posedge reset)
begin
read_data2 data
end
this paper explains it well: http://www-inst.eecs.berkeley.edu/~cs152/fa04/handouts/CummingsHDLCON1999_BehavioralDelays_Rev1_1.pdf