1

First of all, I had a lot of difficulty phrasing the title of this question. So if you understand the problem I'm facing, and there is a better way to word it and the question has been answered before, I apologise, and please do point out to me how I can resolve this. Anyways, here's the relevant code snippet that I've truncated for clarity:

parameter RAM_DEPTH = 256;
reg ram [0:RAM_DEPTH-1]; //256 deep memory, 1-bit size per location

parameter NUM_INST = 64;
parameter N = 4;
genvar x;
generate for (x = 0; x < NUM_INST; x = x + 1) begin: xs
    //instantiate a module here
    //connect N bits to input port
    //which N bits depends module number x
    mod inst (
         .in(ram[x*N : x*N + N - 1]) //the error is here
    );
end endgenerate

The error is:

error: Array cannot be indexed by a range.

I understand that this is because ram is declared as reg ram [0:RAM_DEPTH-1] instead of reg [0:RAM_DEPTH-1] ram. But is there a way to automate concatenation of RAM bits based on the N parameter, i.e. instead of having to write .in({ram[x*N],ram[x*N+1],ram[x*N+2],ram[x*N+3]}), there's an automated range selection logic that concatenates the bits based on N. You can imagine that if, say, N = 256, I would have to write a very long concatenation operator, and also makes my module less parametric.

In this case, should I just be using reg [0:RAM_DEPTH-1] ram declaration, and re-write my module to support bit updates on a single register array instead?

Thanks.

sidmontu
  • 119
  • 1
  • 12
  • Have you tried the method described in http://stackoverflow.com/questions/18067571/indexing-vectors-and-arrays-with ? I seem to remember that it works well for things like this... – wilcroft Apr 18 '16 at 14:41
  • It should be possible in Verilog 2001.. What standard version are you using? – Eugene Sh. Apr 18 '16 at 14:44
  • @wilcroft The solution in your link is conceptually the same. If you look at the variable declaration, it is a single N-bit register, whereas I'm declaring N 1-bit registers (like a distributed memory block). I tried the `+:` operator anyway, and I'm still getting the same errors. – sidmontu Apr 18 '16 at 14:50
  • @EugeneSh. I'm using Icarus verilog, which according to documentation, support compilation with the Verilog 2001 standards using a -g2001 compilation flag. I just tried compiling with this flag, and still see the same errors. – sidmontu Apr 18 '16 at 14:52

1 Answers1

0

The easiest solution I found was to do as you suggested and turn reg ram [0:RAM_DEPTH-1] into reg [0:RAM_DEPTH-1] ram. An alternative would be the following:

parameter RAM_DEPTH = 256;
parameter NUM_INST = 64;
parameter N = 4;

reg [RAM_DEPTH-1:0] ram; //256 deep memory, 1-bit size per location
reg [N-1:0] ramwires [NUM_INST-1:0];

genvar x;
integer y, z;
generate for (x = 0; x < NUM_INST; x = x + 1) begin: xs
    mod inst (
        .in(ramwires[x])
    );
end endgenerate

always@(*)
    for (y = 0; y<NUM_INST; y = y + 1) begin
        for (z=0; z<N; z = z + 1) begin
            ramwires[y][z] = ram[y*N+z];
        end
    end

This converts the 1D array into a 2D array, which is easily passed into the module, while still being parameterizable.

wilcroft
  • 1,580
  • 2
  • 14
  • 20