0

写了好几天的verilog代码,我有一个问题是'我们可以在生成块中编写生成块'吗?我正在写一个类似这样的 RTL:

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

在编译上面的代码时,我得到:

ERROR: syntax error near generate (VERI-1137)

不知道为什么。此 RTL 的目的是在设计的输出端创建一个包含“n”个触发器的管道。

假设 n 为 2,则电路应变为:

flop1-> flop2-> primary output of design

flop1 和 flop2 是新创建的触发器。

4

1 回答 1

5

你离你应该去的地方还有很长的路要走。

Verilog 不是一种编程语言。它是一种硬件描述语言。您将硬件建模为并发进程的网络。每个进程都对一小部分硬件进行建模,例如计数器、状态机、移位寄存器、一些组合逻辑……在 Verilog 中,每个进程都被编码为一个always块。因此,一个always语句永远不会出现在另一个语句中;这是没有意义的。

其次,generate是相当专业的说法。当您需要大量或可变数量的并发进程时,您可以使用它。这不是需要的常见事物,因此generate并不常见,但在需要时很有用。您不需要生成语句来实现可参数化的移位寄存器。而且,因为一个always块是一个并发语句,它位于一个generate语句中,而不是相反。

我不知道您的设计意图到底是什么,我怀疑这段代码并没有完全按照您的意愿行事。然而,它确实实现了一个长度n和宽度的可参数化移位寄存器DATA_WIDTH+1(你真的是那个意思吗?),由en输入启用:

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

你可以看到 - 不需要generate声明。此代码符合此模板,足以满足任何没有异步复位的顺序逻辑:

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
于 2016-08-02T08:55:19.080 回答