I'm attempting to write a general-purpose Verilog latch module with width and delay parameters (delay for synchronization/CDC purposes). At first I wanted to generate a number of delay registers based on the delay parameter, but I decided instead to simply have one shift register, sized according to the delay, as I believe it's cleaner. The code is as follows:
module latch # (
parameter WIDTH = 32,
parameter DELAY = 0
)
(
input clk,
input resetn,
input [WIDTH-1:0] din,
output reg [WIDTH-1:0] dout
);
reg [(WIDTH*(DELAY))-1:0] dly;
always @ (posedge clk)
begin
if (!resetn)
begin
dly <= 0;
dout <= 0;
end
else
begin
if (DELAY == 0)
begin
dout <= din;
end
else
begin
dly <= {dly[(WIDTH*(DELAY-1))-1:0], din};
dout <= dly[(WIDTH*(DELAY))-1 -: WIDTH];
end
end
end
endmodule
xvlog
has no problem with this, even when instantiated with DELAY = 0
. However, Vivado synthesis returns:
ERROR: [Synth 8-524] part-select [-1:0] out of range of prefix 'dly'
when this module is instantiated with DELAY = 0
. How would you get around this? I thought I might be able to get away with defining a max macro and setting the top index of the register to max(0, (WIDTH*(DELAY-1))-1)
, but of course that gets rejected as a variable width register. Is it possible to conditionally declare registers based on parameters?
You can try a generate
if
statement to conditionally declare the registers:
module latch # (
parameter WIDTH = 32,
parameter DELAY = 0
)
(
input clk,
input resetn,
input [WIDTH-1:0] din,
output reg [WIDTH-1:0] dout
);
if (DELAY == 0)
begin
always @ (posedge clk)
begin
if (!resetn)
begin
dout <= 0;
end
else
begin
dout <= din;
end
end
end
else if (DELAY == 1)
begin
reg [WIDTH-1:0] dly;
always @ (posedge clk)
begin
if (!resetn)
begin
dly <= 0;
dout <= 0;
end
else
begin
dly <= din;
dout <= dly;
end
end
end
else
begin
reg [(WIDTH*(DELAY))-1:0] dly;
always @ (posedge clk)
begin
if (!resetn)
begin
dly <= 0;
dout <= 0;
end
else
begin
dly <= {dly[(WIDTH*(DELAY-1))-1:0], din};
dout <= dly[(WIDTH*DELAY)-1 -: WIDTH];
end
end
end
endmodule
The generate
keyword is optional. Refer to IEEE Std 1800-2017, section 27. Generate constructs