Writing verilog code from quite a few days and one question I have is 'Can we write generate block inside generate block'? I am writing an RTL something like this:
Where 'n' is a parameter.
reg [DATA_WIDTH:0] flops [n-1:0];
generate
if (n > 0) begin
always @(posedge clk) begin
if (en) begin
flops[0] <= mem[addr];
end
end
generate
genvar i;
for (i = 1; i <= n ; i = i + 1) begin
always @(posedge clk) begin
flops[i] <= flops[i-1];
end
end
endgenerate
always @(flops[n - 1])
douta = flops[n - 1];
else
always @(posedge clk) begin
if (en) begin
primary_output = mem[addr];
end
end
end
endgenerate
While compiling the above code, I am getting :
ERROR: syntax error near generate (VERI-1137)
Not sure why. Purpose of this RTL is to create an pipeline of 'n' flops at the output side of the design.
Lets say n is 2, then circuit should become :
flop1-> flop2-> primary output of design
flop1 and flop2 are newly created flops.
You are a long long way from where you should be.
Verilog is not a programming language; it is a hardware description language . You model hardware as a network of concurrent processes. Each process models a small bit of hardware such as a counter, a state machine, a shift-register, some combinational logic... In Verilog, each process is coded as an always
block. So, one always
statement never ever can appear inside another; that makes no sense.
Secondly, generate
is quite a specialised statement. You use it when you want either a large number or a variable number of concurrent processes. That is not a common thing to need, so generate
is not common, but is useful when required. You don't need a generate statement to implement a parameterisable shift-register. And, because an always
block is a concurrent statement it sits inside a generate
statement, not the other way round.
I don't know what your design intent is exactly, to I suspect this code does not do exactly what you want. However, it does implement a parameterisable shift-register of length n
and width DATA_WIDTH+1
(did you really mean that?), enabled by the en
input:
module N_FLOPS #(n = 2, DATA_WIDTH = 8) (input [DATA_WIDTH:0] dina, input clk, en, output [DATA_WIDTH:0] douta);
reg [DATA_WIDTH:0] flops [n-1:0];
always @(posedge clk)
if (en)
begin : SR
integer i;
flops[0] <= dina;
for (i = 1; i <= n ; i = i + 1)
flops[i] <= flops[i-1];
end
assign douta = flops[n-1];
endmodule
http://www.edaplayground.com/x/3kuY
You can see - no generate
statements required. This code conforms to this template, which suffices for any sequential logic without an asynchronous reset:
always @(posedge CLOCK) // or negedge
begin
// do things that occur on the rising (or falling) edge of CLOCK
// stuff here gets synthesised to combinational logic on the D input
// of the resulting flip-flops
end
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.