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



我收到一个我不明白的语法错误。从某种意义上说,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 个时钟分别分配给不同的 LED (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

我还应该提到led[4+k] = clocks[0].clk_slow是可以的。它允许我做 led[4+k] = 时钟[0].clk_slow,但不能做 led[4+k] = 时钟[k].clk_slow

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

生成块被展开,将"k"替换为文字数字。它类似于宏文本扩展。您生成的块扩展到

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
...

请注意,导线clock_slow不会变成导线数组。相反,它变成了一组命名的电线,称为时钟[0].clock_slow,时钟[1].clock_slow,...您只能通过指定具有常量索引的 来访问。这是因为范围数组不像常规数组。每个实例可以保存不同的类型。例如:

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

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

例如:

genvar k;
generate
for( k = 0; k < 4; k=k+1) begin
assign led [ 4 + k ] = clocks[k].clock_slow;
end
endgenerate

此外,LED 被声明为不保存值的电线。但是您已经使用了 led in 始终阻止存储值。如果您在任何其他模拟器中运行,这也会产生错误。

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

你已经led[i]分配给clk_slow,为什么你不能led[i]也分配给led[4+i]?甚至led[7:4]在生成块之外led[3:0](并放弃clk_slow.clk_out(led[i])吗(?另外,您无法连接wire键入always@(*),请使用assign

最新更新