Verilog:在for循环中分配一个命名的生成循环线

时间:2018-06-14 02:54:26

标签: verilog fpga

我收到一个我不明白的语法错误。在某种意义上,Verilog似乎对索引是一个变量很挑剔,但我不确定这里到底发生了什么,或者如何在没有硬编码的情况下绕过它。

这是我的主要模块:

module mojo_top(
    // 50MHz clock input
    input clk,
    // Input from reset button (active low)
    input rst_n,
    // cclk input from AVR, high when AVR is ready
    input cclk,
    // Outputs to the 8 onboard LEDs
    output[7:0]led,
    // AVR SPI connections
    output spi_miso,
    input spi_ss,
    input spi_mosi,
    input spi_sck,
    // AVR ADC channel select
    output [3:0] spi_channel,
    // Serial connections
    input avr_tx, // AVR Tx => FPGA Rx
    output avr_rx, // AVR Rx => FPGA Tx
    input avr_rx_busy // AVR Rx buffer full

    );

// these signals should be high-z when not used
assign spi_miso = 1'bz;
assign avr_rx = 1'bz;
assign spi_channel = 4'bzzzz;

wire rst = ~rst_n; // make reset active high

genvar i;
generate
  for (i=0; i<4; i=i+1) begin: clocks
    wire clk_slow;
    slow_clock #(.FREQ(2**i)) clk1 (
      .clk(clk),
      .rst(rst),
      .clk_out(clk_slow)
    );
    assign led[i] = clk_slow;
  end
endgenerate

always @(*) begin
  for (k=0; k<4; k=k+1) begin
    assign led[4+k] = clocks[k].clk_slow; // Why can't I do this?
  end
end

endmodule

我生成4个时钟(1Hz,2Hz,4Hz和8Hz)。在最后的始终块中,我有这一行:led[4+k] = clocks[k].clk_slow;试图将这4个时钟分配给a不同的领导(led[7:4])。 该错误在.之后抱怨clocks[k]。我想知道我是否不允许在右侧有变量索引,但是当我只放置led[4+k] = clocks[k]时,没有语法错误(尽管在构建它时显然会出现不同的错误)。

为什么我可以led[4+k] = clocks[k]而不是led[4+k] = clocks[k].clk_slow?我应该用不同的语法来做这件事吗?我在这里使用for循环是不可能做到的?

修改 如果有人想知道,这里是我遇到的具体错误。再一次,看起来它只是在抱怨我做了任何事情,一旦我索引了我想要的特定生成块。

Line 46, Column 24 : extraneous input '.' expecting {';', '[', '<=', '*', '+', '-', '?', '&', '|', '^', '~^', '^~', '/', '%', '==', '!=', '===', '!==', '&&', '||', '**', '<', '>', '>=', '>>', '<<', '>>>', '<<<'}

我还应该提到led[4+k] = clocks[0].clk_slow没问题。它允许我led[4+k] = clocks[0].clk_slow,而不是led[4+k] = clocks[k].clk_slow

2 个答案:

答案 0 :(得分:1)

  

我还应该提到led [4 + k] =时钟[0] .clk_slow是可以的。它让我做了[4 + k] =时钟[0] .clk_slow,但没有led [4 + k] =时钟[k] .clk_slow

使用的时钟名必须与常量变量一起使用,并且不能在for循环内变化。所以clock [0]工作得非常好。

生成块展开,取代&#39; k&#39;用字面数字。它类似于宏文本扩展。你生成的块被扩展为

    begin : clocks[0]
        wire clock_slow;
        assign led[0] = clocks[0].clock_slow;
    end
    begin : clocks[1]
        wire clock_slow;
        assign led[1] = clocks[1].clock_slow;
    end
    begin : clocks[2]
        wire clock_slow;
        assign led[2] = clocks[2].clock_slow;
    end
    ...

请注意,wire clock_slow不会成为电线阵列。相反,它变成一组名为clocks [0] .clock_slow,clocks [1] .clock_slow,...的命名连线,你只能通过指定一个常量索引来访问它。这是因为范围数组不像常规数组。每个实例可以包含不同的类型。例如:

begin : clocks[0]
        wire clock_slow;
        assign led[0] = clocks[0].clock_slow;
    end
    begin : clocks[1]
        wire clock_slow;
        assign led[1] = clocks[1].clock_slow;
    end
    begin : clocks[2]
        wire clock_slow;
        assign led[2] = clocks[2].clock_slow;
    end
    ...

a [0] .clock_slow是2位线,[1] .clock_slow是3位线。所以引用[i] .clock_slow不会编译。但是您可以使用另一个生成块genvar来索引到另一个生成的块实例。

例如:

genvar i;
for (i = 0; i < MAX_LIMIT; i++) begin: a
    wire [i+1:0] clock_slow;
end

此外,led被声明为不具有值的电线。但是你已经使用了led in always block来存储价值。如果你在任何其他模拟器中运行,那也会出错。

谢谢,这是一个很好的问题。

答案 1 :(得分:0)

您已将led[i]分配给clk_slow,为什么还要将led[i]分配给led[4+i]?或者甚至在生成块之外led[7:4]led[3:0](和沟渠clk_slow,执行.clk_out(led[i]))?另外,您无法在wire中输入always@(*),请使用assign