cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 
Highlighted
Explorer
Explorer
6,343 Views
Registered: ‎01-01-2016

verilog genvar block error...not able to access an array

Jump to solution
for (o=0;o<row2;o=o+1) 


if (finout[o]>524288 || finout[o]==524288 || finout[o]< -524288)

     assign finout[o]=finout[o]+1;
     assign finout[o]=finout[o]>>>1;

 end

The above is my code in verilog where finout changes every posedge of clock cycle. I have to access every element of finout and check if it lies in a specified range and if not i have to do certain steps. But i'm getting error in IF loop that i have used and not able to access the elements of finout "Line 104: finout is not a constant"

Can someone help me on this.

Thanks in advance, Sandy

0 Kudos
1 Solution

Accepted Solutions
Highlighted
Guide
Guide
10,112 Views
Registered: ‎01-23-2009

You have to understand what a generate block is doing...

 

A generate loop is part of the structural portion of Verilog - inside the generate block structure is being created; you are

  - instatiating a module

  - using primitive gates

  - declaring variables or nets

  - creating continous assignments

  - (a whole bunch of other things)

 

These all are creating structure. When synthesized, these things will (usually) create circuit structures - will connect up flip-flops and LUTs.

 

Now lets look at what you are trying to do. At a particular moment in time you are looking at the dynamic value in a reg and either creating or not creating structure. That clearly doesn't make sense - either the LUT is part of your design or its not - it can't be part of the design during some clocks, and not during others.

 

Lets even look at the continuous assignments themselves

 

assign a = a+1;

 

This clearly can't work, its saying that the value of a should always be a+1 - that's what a continuous assign does it continuously has a net take the value of an expression. If this were to be implemented (forget about the genvar), this would either be rejected by synthesis, or would form a combinatorial loop (which would oscillate).

 

So, what you are trying to do is not a job for a genvar or a continuous assgn.

 

What are you trying to do? On every clock, you are trying to go through every element of an array, and based on certain characteristics of the current contents of that cell, change the value to something else. This is not structure, this is procedure.

 

So

 

// row2 must be a constant
// To have each element able to store 524288 to -524288 requires 21 bits
// 20 bits can only go -524288 to 524287
reg signed [20:0] finout [row2-1:0];
reg signed [20:0] tmp; 

// All elements of finout must somehow be initialized; either using a reset or some other mechanism

integer o; // Loop variable

always @(posedge clk)
begin
  for (o=0; o<row2; o=o+1)
  begin
     if ((finout[o] >=524288) || (finout[0] < -524288))
     begin
        // need to use temporary variable to ensure sign extension
        tmp = finout[o] + 1'sb1;  // must use blocking assignment
        finout[0] <= tmp / 3'sb2; // Use division since arithmetic shift right does
                                              // not preserve sign bit
      end  // if
  end  // for
end  // always

 

Now this should synthesize (other than the question of how finout is initialized. But, be warned, this has the potential to be very big. This will generate

   - 21*row2 flip-flops

   - 2* row2 comparators (which will probably degenerate to one or two bit comparisons, since the RHS are constants)

   - row2 signed 21 bit adders

 

If row2 is large (and it MUST be a constant; i.e. a parameter or localparam), this has the potential to create an immense amount of logic...

 

Avrum

 

View solution in original post

Tags (1)
3 Replies
Highlighted
Guide
Guide
10,113 Views
Registered: ‎01-23-2009

You have to understand what a generate block is doing...

 

A generate loop is part of the structural portion of Verilog - inside the generate block structure is being created; you are

  - instatiating a module

  - using primitive gates

  - declaring variables or nets

  - creating continous assignments

  - (a whole bunch of other things)

 

These all are creating structure. When synthesized, these things will (usually) create circuit structures - will connect up flip-flops and LUTs.

 

Now lets look at what you are trying to do. At a particular moment in time you are looking at the dynamic value in a reg and either creating or not creating structure. That clearly doesn't make sense - either the LUT is part of your design or its not - it can't be part of the design during some clocks, and not during others.

 

Lets even look at the continuous assignments themselves

 

assign a = a+1;

 

This clearly can't work, its saying that the value of a should always be a+1 - that's what a continuous assign does it continuously has a net take the value of an expression. If this were to be implemented (forget about the genvar), this would either be rejected by synthesis, or would form a combinatorial loop (which would oscillate).

 

So, what you are trying to do is not a job for a genvar or a continuous assgn.

 

What are you trying to do? On every clock, you are trying to go through every element of an array, and based on certain characteristics of the current contents of that cell, change the value to something else. This is not structure, this is procedure.

 

So

 

// row2 must be a constant
// To have each element able to store 524288 to -524288 requires 21 bits
// 20 bits can only go -524288 to 524287
reg signed [20:0] finout [row2-1:0];
reg signed [20:0] tmp; 

// All elements of finout must somehow be initialized; either using a reset or some other mechanism

integer o; // Loop variable

always @(posedge clk)
begin
  for (o=0; o<row2; o=o+1)
  begin
     if ((finout[o] >=524288) || (finout[0] < -524288))
     begin
        // need to use temporary variable to ensure sign extension
        tmp = finout[o] + 1'sb1;  // must use blocking assignment
        finout[0] <= tmp / 3'sb2; // Use division since arithmetic shift right does
                                              // not preserve sign bit
      end  // if
  end  // for
end  // always

 

Now this should synthesize (other than the question of how finout is initialized. But, be warned, this has the potential to be very big. This will generate

   - 21*row2 flip-flops

   - 2* row2 comparators (which will probably degenerate to one or two bit comparisons, since the RHS are constants)

   - row2 signed 21 bit adders

 

If row2 is large (and it MUST be a constant; i.e. a parameter or localparam), this has the potential to create an immense amount of logic...

 

Avrum

 

View solution in original post

Tags (1)
Highlighted
Xilinx Employee
Xilinx Employee
6,306 Views
Registered: ‎08-01-2008
This error occurs when an invalid size is specified for an integer constant literal.

Take the following piece of code as an example:

module top (a,b,out);
input a, b;
output out;
assign out = a ? b : 0'b0;
endmodule

In the above piece of sample code, the size constant in the expression is specified as 0, which causes the 13.3 XST to error out with the following HDLCompiler error:

"ERROR:HDLCompiler:1818 - "top.v" Line 4: Invalid size of integer constant literal
INFO - You can change the severity of this error message to warning using switch -change_error_to_warning "HDLCompiler:1818""
Thanks and Regards
Balkrishan
--------------------------------------------------------------------------------------------
Please mark the post as an answer "Accept as solution" in case it helped resolve your query.
Give kudos in case a post in case it guided to the solution.
Highlighted
Explorer
Explorer
5,705 Views
Registered: ‎01-01-2016

@avrumw

 

Amazing answer. You explained it very clearly. Thanks a lot.

 

Thanks,

Sandy

0 Kudos