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

6
  • 1
    At what event does the posedge occur? Provide that details. Commented Mar 8, 2016 at 18:03
  • 2
    Where/how is width defined? Commented Mar 8, 2016 at 18:07
  • posedge is a keyword. Do you mean posedge clock? Commented Mar 8, 2016 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 Commented Mar 8, 2016 at 18:50
  • The slice will be out of range once k has a value of 3 or higher. Commented Mar 8, 2016 at 19:11

2 Answers 2

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

Sign up to request clarification or add additional context in comments.

Comments

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

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.