3

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

Ming Peng
  • 33
  • 1
  • 5
  • 1
    At what event does the posedge occur? Provide that details. – vim Mar 08 '16 at 18:03
  • 2
    Where/how is `width` defined? – dwikle Mar 08 '16 at 18:07
  • `posedge` is a keyword. Do you mean `posedge clock`? – Greg Mar 08 '16 at 18:24
  • I have edited the question, the width is wordlength and it is 32 bit in this case, and yes, it is a ´posedge clk´, I must have missed it. @Greg – Ming Peng Mar 08 '16 at 18:50
  • The slice will be out of range once `k` has a value of 3 or higher. – Greg Mar 08 '16 at 19:11
  • Yeah, I think this might be the problem, but in this case what should I do when k is bigger than the size, I mean how should I make it to stop increasing and get a result? Thanks for replying. @Greg – Ming Peng Mar 08 '16 at 20:08

2 Answers2

1

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
Greg
  • 16,013
  • 5
  • 43
  • 61
1

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

user3697625
  • 159
  • 3
  • 15