0
votes

I am getting a syntax error that I do not understand. It seems Verilog is being picky about an index being a variable in some sense, but I'm not sure exactly what is going on here or how to get around it without hardcoding.

Here's my main module:

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

I'm generating 4 clocks (1Hz, 2Hz, 4Hz, and 8Hz).In the always block at the end, I have this line: led[4+k] = clocks[k].clk_slow; to try to assign these 4 clocks each to a different led (led[7:4]). The error is complaining about the . after clocks[k]. I wondered if I'm not allowed to have a variable index on the right hand side, but when I put just led[4+k] = clocks[k], there is no syntax error (though it obviously will get a different error when I build it).

Why can I have led[4+k] = clocks[k] but not led[4+k] = clocks[k].clk_slow? Am I supposed to do this with a different syntax? Is it impossible to do it with a for-loop as I have here?

EDIT: In case anyone is wondering, here's the specific error I'm getting. Again, it looks like it's just complaining that I did anything once I indexed the specific generate block I wanted.

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

I should also mention that led[4+k] = clocks[0].clk_slow is okay. It lets me do led[4+k] = clocks[0].clk_slow, but not led[4+k] = clocks[k].clk_slow.

2

2 Answers

1
votes

I should also mention that led[4+k] = clocks[0].clk_slow is okay. It lets me do led[4+k] = clocks[0].clk_slow, but not led[4+k] = clocks[k].clk_slow

clocks name used must be used with the constant variable and cannot be varying inside for loop. so clocks[0] works perfectly fine.

The generate block gets unrolled replacing 'k' with a literal digit. It similar to macro text expansion. You generate block gets expanded into

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

Note the wire clock_slow does not become an array of wires. Instead, it becomes a set of named wires called clocks[0].clock_slow, clocks[1].clock_slow, ... that you can only access by specifying a with a constant index. That is because of an array of scopes in not like a regular array. Each instance can hold different types. For example:

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

a[0].clock_slow is a 2-bit wire, a[1].clock_slow is a 3-bit wire. So referencing a[i].clock_slow does not compile. But you can use another generate block genvar to index into another generated block instance.

for example:

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

Also led is declared as a wire which doesn't hold a value. But you have used led in always block which stores the value. That will also give an error if you run in any other simulator.

Thanks, it was a good question.

0
votes

You've assigned led[i] to the clk_slow, why can't you also assign led[i] to led[4+i]? Or even led[7:4] to led[3:0] outside the generate block (and ditch clk_slow, do .clk_out(led[i]))? Also, you can't connect wire type in always@(*), use assign.