简体   繁体   中英

generate inside generate verilog + error near generate(veri - 1137)

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM