Ming Peng
Ming Peng

Reputation: 33

Verilog : Variable index is not supported in signal

I get an error saying 'Index is not supported in signal'. From what I can see the error is on the left hand side of the non-blocking assignment. Why does the code below give an error and is there a way to work around it?

...
parameter width = 32;
parameter size = 3;

input clk, reset;
input [width*size-1:0] A;
input [width*size-1:0] B;
output [width*size-1:0] result;

reg signed [width*size-1:0] partials;
reg signed [width-1:0] temp;
reg signed [width-1:0] currenta;
reg signed [width-1:0] currentb;
wire signed [width-1:0] temp1wire;
...
integer k = 0;
always @ (posedge clk)
begin
    currenta[width-1:0] <= A[width*k +: width];
    k = k+1
    currentb[width-1:0] <= B[width*k +: width];
    partials[width*k +: width] <= temp1wire;
end
Add Add1(clk, temp1wire, currenta, currentb);
...

This code is part of a sequential block that does vector addition and saves the result at partials[width*k +: width].

Upvotes: 3

Views: 3563

Answers (2)

user3697625
user3697625

Reputation: 187

I found this on the Xilinx forum:

"XST works fine with the indexed part-select operator "+:" if it is on the right-hand side (RHS) of the assignment. It also works fine when it is on the left-hand side (LHS) AND the starting index is a constant. Your case uses a variable as the starting index on the LHS and that what XST doesn't like although it's legal."

Upvotes: 1

Greg
Greg

Reputation: 19094

k needs to be clamped or wrapped around after reaching size-1. Wrapping around can be done with the mod operator (%); example:k = (k+1)%size. % may not synthesize optimally (check your synthesizer), so a if-statement is a functional alternative if(k==SIZE-1) k = 0; else k=k+1;


Suggestions:
It is generally recommenced to keep parameters as uppercase, this way you can easily identity parameters form signal names. Putting a blocking assignment inside a sequential block is legal, but most design rules recommend separating combinational logic from sequential assignments. I would prefer writing your code like the following:

// $clog is IEEE1364-2005 § 17.11, some synthesizers support it, others don't
reg [$clog2(SIZE):0] k=0, next_k;
always @* begin
  if (k==SIZE-1) begin
    next_k = 0; // wrap around
    // next_k = k; // clamp
  end
  else begin
    next_k = k+1;
  end
end
always @ (posedge clk)
begin
    currenta[WIDTH-1:0] <= A[WIDTH*k +: WIDTH];
    currentb[WIDTH-1:0] <= A[WIDTH*next_k +: WIDTH];
    partials[WIDTH*next_k +: WIDTH] <= temp1wire;
    k <= next_k;
end

Upvotes: 1

Related Questions