cancel
Showing results for 
Search instead for 
Did you mean: 
Highlighted
Visitor
Visitor
854 Views
Registered: ‎02-18-2020

Generate block gets trimmed after synthesis

Jump to solution

Hello,

I am trying to find the index of the most significant 1 (take log2) on a data bus in run-time. I've written the below code to do this job for me but it gets trimmed after synthesis.

parameter DATA_WIDTH = 16;
input [DATA_WIDTH-1:0] max_value; output [$clog2(DATA_WIDTH)-1:0] max_index; genvar ii; for(ii = DATA_WIDTH-1; ii >= 0; ii = ii - 1) begin: GEN_FIND_MAX_INDEX wire [$clog2(DATA_WIDTH)-1:0] max_index_temp; if(ii == 0) assign max_index_temp = 0; else assign max_index_temp = max_value[ii] ? ii : GEN_FIND_MAX_INDEX[ii-1].max_index_temp; end assign max_index = GEN_FIND_MAX_INDEX[DATA_WIDTH-1].max_index_temp;

 The following code does the same job but I don't want to rewrite the case statement whenever the width of the input data changes.

parameter DATA_WIDTH = 16;
input [DATA_WIDTH-1:0] max_value;
output [$clog2(DATA_WIDTH)-1:0] max_index; always @* casez(max_value) 16'b1???????????????: max_index = 15; 16'b01??????????????: max_index = 14; 16'b001?????????????: max_index = 13; 16'b0001????????????: max_index = 12; 16'b00001???????????: max_index = 11; 16'b000001??????????: max_index = 10; 16'b0000001?????????: max_index = 9; 16'b00000001????????: max_index = 8; 16'b000000001???????: max_index = 7; 16'b0000000001??????: max_index = 6; 16'b00000000001?????: max_index = 5; 16'b000000000001????: max_index = 4; 16'b0000000000001???: max_index = 3; 16'b00000000000001??: max_index = 2; 16'b000000000000001?: max_index = 1; 16'b0000000000000001: max_index = 0; default: max_index = 0; endcase

 Can someone tell me what's the problem with the first code and suggest a fix?

Thanks.

0 Kudos
1 Solution

Accepted Solutions
Scholar
Scholar
603 Views
Registered: ‎09-16-2009

Re: Generate block gets trimmed after synthesis

Jump to solution

The first example (one generate iteration scope referencing another iteration's variable) is explicitly not allowed in Vivado according to UG901:

Under "Modules and Hierarchy"

Upwards name referencing           Not Supported

And the code in the OP's first example is an upwards naming reference.

The second one is gray - not really mentioned explicitly. I know some support of "Hierarchical names" was added recently in Vivado, although it's use is limited.

One normally works around these things by declaring variables (indexed - often multi-dimensional arrays) in the full module scope.  Then within the generate index, creating/referencing the (module scoped) variables according to the generate index, as neccesary.

Regards,

Mark

View solution in original post

17 Replies
Highlighted
Teacher
Teacher
824 Views
Registered: ‎07-09-2009

Re: Generate block gets trimmed after synthesis

Jump to solution
Look at what code your first code makes compared to the second .

<== If this was helpful, please feel free to give Kudos, and close if it answers your question ==>
0 Kudos
Highlighted
Visitor
Visitor
798 Views
Registered: ‎02-18-2020

Re: Generate block gets trimmed after synthesis

Jump to solution

Hi @drjohnsmith 

I've simulated both and confirmed that they both behave the same.

I would expect the generate statement to be converted to the following. Am I missing something?

assign max_index = max_value[15] ? 15 : max_value[14] ? 14 : max_value[13] ? 13 : max_value[12] ? 12 : max_value[11] ? 11 : max_value[10] ? 10 : max_value[9] ? 9 : max_value[8] ? 8 : max_value[7] ? 7 : max_value[6] ? 6 : max_value[5] ? 5: max_value[4] ? 4 : max_value[3] ? 3 : max_value[2] ? 2 : max_value[1] ? 1 : 0;

Thanks.

0 Kudos
Highlighted
Teacher
Teacher
789 Views
Registered: ‎07-09-2009

Re: Generate block gets trimmed after synthesis

Jump to solution
Ok, Im confused, any one else ?
<== If this was helpful, please feel free to give Kudos, and close if it answers your question ==>
0 Kudos
Highlighted
Xilinx Employee
Xilinx Employee
752 Views
Registered: ‎06-14-2018

Re: Generate block gets trimmed after synthesis

Jump to solution

Hi @avaarahoon ,

From design point of view, you could implement this in simple function or simple for loop to get index of leading 1.

Thanks,

Ajay 

0 Kudos
Highlighted
Visitor
Visitor
735 Views
Registered: ‎02-18-2020

Re: Generate block gets trimmed after synthesis

Jump to solution

Hi @apetley 

Thank you for the suggestion but I also want to know why my logic gets trimmed during synthesis.

0 Kudos
Highlighted
Teacher
Teacher
706 Views
Registered: ‎07-09-2009

Re: Generate block gets trimmed after synthesis

Jump to solution
Synthesis trims out parts that are not used or are absorbed into other parts ,
<== If this was helpful, please feel free to give Kudos, and close if it answers your question ==>
0 Kudos
Highlighted
Visitor
Visitor
704 Views
Registered: ‎02-18-2020

Re: Generate block gets trimmed after synthesis

Jump to solution

Hi @drjohnsmith 

max_index is used in another calculation. If I replace the generate loop with the case statement it appears in the synthesized design.

Thanks.

0 Kudos
Highlighted
Teacher
Teacher
684 Views
Registered: ‎07-09-2009

Re: Generate block gets trimmed after synthesis

Jump to solution
How are you checking it get synthesised away ?
<== If this was helpful, please feel free to give Kudos, and close if it answers your question ==>
0 Kudos
Highlighted
Visitor
Visitor
641 Views
Registered: ‎02-18-2020

Re: Generate block gets trimmed after synthesis

Jump to solution
 
This logic is a part of a simple I/Q sample compression algorithm where we apply a certain amount of shift to the samples coming from an RF front-end and send them over the network in UDP packets. We skipped post-synthesis simulation and directly tested the system on hardware in loopback mode with some sample data. We captured the network packets with Wireshark and saw that no shift was applied to the samples when we used the generate loop. Then we looked at the schematic and saw that max_index and the associated signals were removed from the datapath (they were not moved into the other blocks either). After we replaced it with the case statement we observed the expected 6-bit shift on the samples. In this case the schematic had all the required signals.
0 Kudos
Highlighted
Scholar
Scholar
622 Views
Registered: ‎09-16-2009

Re: Generate block gets trimmed after synthesis

Jump to solution

Dumb question, but isn't your code equivalent to:

assign max_index = $clog2( max_value ) - 1;
// of maybe you want - I wasn't clear on your requirements - depends on how you want the 2**N values returned
assign max_index = $clog2( max_value + 1) - 1;

And I think it's synthesizable by Vivado too.

But to your orignal question - what do you mean "it gets trimmed".  Does it produce an incorrect result? 

In any event - I think the problem is probably in your hierarchichal references - both within the generate loop (i.e. scope referencing another interation of the generate loop):

assign max_index_temp = max_value[ii] ? ii : GEN_FIND_MAX_INDEX[ii-1].max_index_temp;

And/or in the module scope reaching down into a specific scope:

assign max_index = GEN_FIND_MAX_INDEX[DATA_WIDTH-1].max_index_temp; 

Neither one of these scoping operations is what's normally considered synthesizable.  

Regards,

Mark

0 Kudos
Highlighted
Xilinx Employee
Xilinx Employee
612 Views
Registered: ‎06-14-2018

Re: Generate block gets trimmed after synthesis

Jump to solution

Hi @avaarahoon ,

This looks issue in Vivado. 

I have checked @markcurry 's reply about hierarchical referencing (here for generate loop) not supported by most syntheis tools. Will check if thats the case with Vivado too.

Alternate code is below.

//Code

module top(
max_value,
max_index
);

parameter DATA_WIDTH = 16;

input [DATA_WIDTH-1:0] max_value;
output [$clog2(DATA_WIDTH)-1:0] max_index;

genvar ii;

wire [$clog2(DATA_WIDTH)-1:0] max_index_temp [DATA_WIDTH-1:0];

for(ii = DATA_WIDTH-1; ii >= 0; ii = ii - 1) begin: GEN_FIND_MAX_INDEX

if(ii == 0)
assign max_index_temp[ii] = 0;
else

assign max_index_temp[ii] = max_value[ii] ? ii : max_index_temp[ii-1];
end


assign max_index = max_index_temp[DATA_WIDTH-1];

endmodule

Thanks,

Ajay

Scholar
Scholar
604 Views
Registered: ‎09-16-2009

Re: Generate block gets trimmed after synthesis

Jump to solution

The first example (one generate iteration scope referencing another iteration's variable) is explicitly not allowed in Vivado according to UG901:

Under "Modules and Hierarchy"

Upwards name referencing           Not Supported

And the code in the OP's first example is an upwards naming reference.

The second one is gray - not really mentioned explicitly. I know some support of "Hierarchical names" was added recently in Vivado, although it's use is limited.

One normally works around these things by declaring variables (indexed - often multi-dimensional arrays) in the full module scope.  Then within the generate index, creating/referencing the (module scoped) variables according to the generate index, as neccesary.

Regards,

Mark

View solution in original post

Highlighted
Visitor
Visitor
588 Views
Registered: ‎02-18-2020

Re: Generate block gets trimmed after synthesis

Jump to solution

Hi @markcurry 

I have used Verilog to write the code, not SystemVerilog and as far as I know, $clog2 function is not synthesizable. Thank you for making me realize hierarchichal references part which are not synthesizable.

0 Kudos
Highlighted
Scholar
Scholar
572 Views
Registered: ‎09-16-2009

Re: Generate block gets trimmed after synthesis

Jump to solution

@avaarahoon wrote:

I have used Verilog to write the code, not SystemVerilog and as far as I know, $clog2 function is not synthesizable. Thank you for making me realize hierarchichal references part which are not synthesizable.


Your original example includes using $clog2() - so it is certainly synthesizable under some circumstances (i.e. for a constant function).  I believe it's globally synthesizable even with a variable as an argument - as UG901 list no such restrictions.

i.e. the "division" operator lists restrictions to "a power of 2, or both operands are constant".  $clog2() is explicitly labeled in UG901 as supported - with no restrictions.  (other than turning on SystemVerilog support)

Regards,

Mark

Highlighted
Visitor
Visitor
562 Views
Registered: ‎02-18-2020

Re: Generate block gets trimmed after synthesis

Jump to solution

Hi @apetley 

Thank you for the alternate code.

0 Kudos
Highlighted
Visitor
Visitor
550 Views
Registered: ‎02-18-2020

Re: Generate block gets trimmed after synthesis

Jump to solution

@markcurry 

I have just tried it with a variable as an argument and the synthesis gave this error.

[Synth 8-280] expression must be constant: argument to $clog2

Regards

Highlighted
Scholar
Scholar
544 Views
Registered: ‎09-16-2009

Re: Generate block gets trimmed after synthesis

Jump to solution

Ok then - good catch - UG901 is wrong in this regard.  It should have a similar note in the documenation about the function being limited to constant.

Regards,

Mark

0 Kudos