Author Topic: Changing an attribute in a LOGIC declaration based on a parameter.  (Read 1355 times)

0 Members and 1 Guest are viewing this topic.

Online BrianHGTopic starter

  • Super Contributor
  • ***
  • Posts: 8080
  • Country: ca
Ok, I'm looking for the correct way to do this.

I have a parameter bit called 'BHG_EXTRA_SPEED'.

I have this logic cell I wish to declare in these 2 ways:

A:
Code: [Select]
(*preserve*) logic [PORT_VECTOR_SIZE-1:0] OUT_RD_VECTOR_int = 0 ;B:
Code: [Select]
logic [PORT_VECTOR_SIZE-1:0] OUT_RD_VECTOR_int = 0 ;
The difference is the 'preserve' attribute.  I want the attribute when BHG_EXTRA_SPEED=1, and dont want it when BHG_EXTRA_SPEED=0.

What is the proper way to do this?
My current method is a dirty trick, but it still wastes a bunch of logic cells...
 

Offline dtodorov

  • Contributor
  • Posts: 46
  • Country: bg
Re: Changing an attribute in a LOGIC declaration based on a parameter.
« Reply #1 on: August 21, 2021, 09:26:59 am »
To me it seems using a `ifdef.. would do better.
Anyhow maybe you can mux the logic of this OUT_RD_VECTOR_int somehow based on the parameter BHG_EXTRA_SPEED, so that at least the non-preserved logic would get optimized if not used?

Another thing maybe would be to multiply the width of the preserved logic based on the BHG_EXTRA_SPEED, at least trying to reduce the amount of non-optimized logic
Code: [Select]
(*preserve*) logic [ BHG_EXTRA_SPEED * (PORT_VECTOR_SIZE-1) :0] OUT_RD_VECTOR_int = 0 ;
 

Online BrianHGTopic starter

  • Super Contributor
  • ***
  • Posts: 8080
  • Country: ca
Re: Changing an attribute in a LOGIC declaration based on a parameter.
« Reply #2 on: August 21, 2021, 09:41:38 am »
To me it seems using a `ifdef.. would do better.
Anyhow maybe you can mux the logic of this OUT_RD_VECTOR_int somehow based on the parameter BHG_EXTRA_SPEED, so that at least the non-preserved logic would get optimized if not used?

Another thing maybe would be to multiply the width of the preserved logic based on the BHG_EXTRA_SPEED, at least trying to reduce the amount of non-optimized logic
Code: [Select]
(*preserve*) logic [ BHG_EXTRA_SPEED * (PORT_VECTOR_SIZE-1) :0] OUT_RD_VECTOR_int = 0 ;

Without the 'preserve', quartus will auto infer a prior feeding array as M9K block ram.  With the preserve, the prior feeding array will be placed in logic cells.  This is what I actually want, a SystemVerilog level means of switching this feature on and off via parameter which may be set from previous .sv modules.  If the word 'preserve' show up anywhere in the chain, even for 1 bit, the ram will never be inferred.  So it needs to be there or not based on the BHG_EXTRA_SPEED.

How would I word it if I were to use  `ifdef ?
My parameter changes numerous features throughout a few of my .sv source files simultaneously.
« Last Edit: August 21, 2021, 09:44:18 am by BrianHG »
 

Offline dtodorov

  • Contributor
  • Posts: 46
  • Country: bg
Re: Changing an attribute in a LOGIC declaration based on a parameter.
« Reply #3 on: August 21, 2021, 12:49:24 pm »
Not sure if could help but just to push a bit the discussion:
How about using a generate statement? I used this link https://www.verilogpro.com/verilog-generate-configurable-rtl/ tutorial to create an example testcase.

Code: [Select]
module test_genvar();

parameter TEST_PARAM = 1;

generate
if (TEST_PARAM == 1) begin
reg [15:0] test_param_set;
end
else begin
reg [3:0] test_param_not_set;
end
endgenerate
endmodule

and the testbench
Code: [Select]
module tb_test_genvar();

test_genvar #(0) i_test_0();
test_genvar #(1) i_test_1();

initial begin

$shm_open("waves.shm", 0);
$shm_probe("ASCTMF");

#100;
$finish;

end
endmodule

and the result seem to be as expected:

 

Online BrianHGTopic starter

  • Super Contributor
  • ***
  • Posts: 8080
  • Country: ca
Re: Changing an attribute in a LOGIC declaration based on a parameter.
« Reply #4 on: August 21, 2021, 04:32:20 pm »
Generate was the first thing I tried a 2 days ago.
Here was my code:
Code: [Select]
generate
if (BHG_EXTRA_SPEED) begin
                     (*preserve*) logic [PORT_VECTOR_SIZE-1:0] OUT_RD_VECTOR_int = 0 ; // This prevents inferred block ram for the read vector FIFO offering greater FMAX.
                     end else begin
                                  logic [PORT_VECTOR_SIZE-1:0] OUT_RD_VECTOR_int = 0 ; // This allows inferred block ram for the read vector FIFO offering a much smaller LC/LUT count.
                     end
endgenerate

Here is the error later-on when I used the logic cell:
# -- Compiling module BrianHG_DDR3_CMD_SEQUENCER
# ** Error: BrianHG_DDR3_CMD_SEQUENCER.sv(251): (vlog-2730) Undefined variable: 'OUT_RD_VECTOR_int'.

However, weirdly, I just tried again with an odd addition, this:
Code: [Select]
generate
if (BHG_EXTRA_SPEED) begin
    (*preserve*) logic [PORT_VECTOR_SIZE-1:0]          OUT_RD_VECTOR_int  = 0                      ; // This prevents inferred block ram for the read vector FIFO offering greater FMAX.
                 always_ff @(posedge CLK) begin
                                                       OUT_RD_VECTOR_int <= vector_pipe_mem[vrpos] ; // Add a DFF latch stage so that when Quartus infers a ram block for the read vector FIFO, it sees a second DFF on the output to improve FMAX performance.
                 if (IN_READ_RDY_t != IN_READ_RDY_tdl) OUT_RD_VECTOR     <= OUT_RD_VECTOR_int      ;
                 end
    end else begin
                 logic [PORT_VECTOR_SIZE-1:0]          OUT_RD_VECTOR_int  = 0                      ; // This allows inferred block ram for the read vector FIFO offering a much smaller LC/LUT count.
                 always_ff @(posedge CLK) begin
                                                       OUT_RD_VECTOR_int <= vector_pipe_mem[vrpos] ; // Add a DFF latch stage so that when Quartus infers a ram block for the read vector FIFO, it sees a second DFF on the output to improve FMAX performance.
                 if (IN_READ_RDY_t != IN_READ_RDY_tdl) OUT_RD_VECTOR     <= OUT_RD_VECTOR_int      ;
                 end
    end
endgenerate

And this time it worked.  I do not know why, but for the rest of my code to make use of the 'OUT_RD_VECTOR_int', it must be defined, set and used, all 3, inside each generate IF for it to work.

Just placing the 'set', or just placing the 'read' outside the generate's ifs simplifies out the LC all together even in Modelsim simulations.
 

Offline FenTiger

  • Regular Contributor
  • *
  • Posts: 88
  • Country: gb
Re: Changing an attribute in a LOGIC declaration based on a parameter.
« Reply #5 on: August 21, 2021, 05:19:52 pm »
And this time it worked.  I do not know why, but for the rest of my code to make use of the 'OUT_RD_VECTOR_int', it must be defined, set and used, all 3, inside each generate IF for it to work.

A generate block defines a local scope. 'OUT_RD_VECTOR_int' is only visible within that scope. https://www.chipverify.com/verilog/verilog-hierarchical-reference-scope
 

Online BrianHGTopic starter

  • Super Contributor
  • ***
  • Posts: 8080
  • Country: ca
Re: Changing an attribute in a LOGIC declaration based on a parameter.
« Reply #6 on: August 21, 2021, 05:38:15 pm »
It seems to be visible outside that scope, as long as I at least 1 read and 1 write to it once withing that scope.
« Last Edit: August 21, 2021, 05:43:04 pm by BrianHG »
 

Offline FenTiger

  • Regular Contributor
  • *
  • Posts: 88
  • Country: gb
Re: Changing an attribute in a LOGIC declaration based on a parameter.
« Reply #7 on: August 21, 2021, 06:01:00 pm »
Can you share the whole file?
 

Online BrianHGTopic starter

  • Super Contributor
  • ***
  • Posts: 8080
  • Country: ca
Re: Changing an attribute in a LOGIC declaration based on a parameter.
« Reply #8 on: August 21, 2021, 07:07:40 pm »
Can you share the whole file?
I attached the .sv.


The generate is on line 224.
 

Offline FenTiger

  • Regular Contributor
  • *
  • Posts: 88
  • Country: gb
Re: Changing an attribute in a LOGIC declaration based on a parameter.
« Reply #9 on: August 21, 2021, 07:18:00 pm »
Perfect - thanks!

I still think my scope explanation is correct; I can't see any references at all to OUT_RD_VECTOR_int outside the generate block. If you still had another read outside the block I think this would still fail, but you've moved the signal and all its references into the inner scope, hence it works.
« Last Edit: August 21, 2021, 07:19:38 pm by FenTiger »
 
The following users thanked this post: BrianHG


Share me

Digg  Facebook  SlashDot  Delicious  Technorati  Twitter  Google  Yahoo
Smf