P
pallav
Guest
Hi,
I have a quick question about asynchronous/synchronous behavior. I
have a register file for my MIPS 32 processor. Originally, I was
modeling it using version 1 seen below. I realized the register read
access was asynchronous. Then I changed it to version 2 where the read
access is now synchronous. I'm only at simulation right now. But both
cases worked OK on my test cases. The output of the register files go
into pipeline registers for the execution stage. I think version 2 is
preferable as its fully synchrnous
My question is, are there any guidelines designers use for to
determine when to use asynchronous logic vs synchronous in logic
blocks?
Do managers enforce using flops at the input/output boundaries to
prevent timing problems that may creep up later on?
Also when running the simulations, I start with all registers as X
rather than initialized to 0. Is that a sufficient condition for
testing or should one also have them initialized to random (garbage)
values?
Thanks.
------------------------------------------------------------
module regfileV1 (/*AUTOARG*/);
input clk; // clock
input [4:0] r1, r2, w1; // source registers 1/2, destination
register 1
input [31:0] wdata; // ALU result to writeback
input wen; // enable register write
output [31:0] rd1, rd2; // data read from source registers 1/2
// A three-port register file supporting 2 reads and 1 write.
reg [31:0] regs[31:0]; // register file
// r0 is always constant 0.
assign rd1 = (r1 != 0) ? regs[r1] : 32'b0;
assign rd2 = (r2 != 0) ? regs[r2] : 32'b0;
// write on the negative edge of clk.
always @(negedge clk)
if (wen)
regs[w1] <= wdata;
endmodule // regfile
module regfileV2(/*AUTOARG*/);
input clk; // clock
input [4:0] r1, r2, w1; // source registers 1/2, destination
register 1
input [31:0] wdata; // ALU result to writeback
input wen; // enable register write
output reg [31:0] rd1, rd2; // data read from source registers
1/2
// A three-port register file supporting 2 reads and 1 write.
reg [31:0] regs[31:0]; // register file
// r0 is always constant 0.
always @(posedge clk)
begin
rd1 <= (r1 != 0) ? regs[r1] : 32'b0;
rd2 <= (r2 != 0) ? regs[r2] : 32'b0;
end
// write on the negative edge of clk.
always @(negedge clk)
if (wen)
regs[w1] <= wdata;
endmodule // regfile
I have a quick question about asynchronous/synchronous behavior. I
have a register file for my MIPS 32 processor. Originally, I was
modeling it using version 1 seen below. I realized the register read
access was asynchronous. Then I changed it to version 2 where the read
access is now synchronous. I'm only at simulation right now. But both
cases worked OK on my test cases. The output of the register files go
into pipeline registers for the execution stage. I think version 2 is
preferable as its fully synchrnous
My question is, are there any guidelines designers use for to
determine when to use asynchronous logic vs synchronous in logic
blocks?
Do managers enforce using flops at the input/output boundaries to
prevent timing problems that may creep up later on?
Also when running the simulations, I start with all registers as X
rather than initialized to 0. Is that a sufficient condition for
testing or should one also have them initialized to random (garbage)
values?
Thanks.
------------------------------------------------------------
module regfileV1 (/*AUTOARG*/);
input clk; // clock
input [4:0] r1, r2, w1; // source registers 1/2, destination
register 1
input [31:0] wdata; // ALU result to writeback
input wen; // enable register write
output [31:0] rd1, rd2; // data read from source registers 1/2
// A three-port register file supporting 2 reads and 1 write.
reg [31:0] regs[31:0]; // register file
// r0 is always constant 0.
assign rd1 = (r1 != 0) ? regs[r1] : 32'b0;
assign rd2 = (r2 != 0) ? regs[r2] : 32'b0;
// write on the negative edge of clk.
always @(negedge clk)
if (wen)
regs[w1] <= wdata;
endmodule // regfile
module regfileV2(/*AUTOARG*/);
input clk; // clock
input [4:0] r1, r2, w1; // source registers 1/2, destination
register 1
input [31:0] wdata; // ALU result to writeback
input wen; // enable register write
output reg [31:0] rd1, rd2; // data read from source registers
1/2
// A three-port register file supporting 2 reads and 1 write.
reg [31:0] regs[31:0]; // register file
// r0 is always constant 0.
always @(posedge clk)
begin
rd1 <= (r1 != 0) ? regs[r1] : 32'b0;
rd2 <= (r2 != 0) ? regs[r2] : 32'b0;
end
// write on the negative edge of clk.
always @(negedge clk)
if (wen)
regs[w1] <= wdata;
endmodule // regfile