Changing an attribute in a LOGIC declaration based on a parameter. - Page 1
Forum section: electronics / general

author: BrianHG
author_rank: Super Contributor
timestamp: August 21, 2021, 08:51:37 am
content: 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:(*preserve*) logic [PORT_VECTOR_SIZE-1:0] OUT_RD_VECTOR_int = 0 ;B:Code: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...

author: dtodorov
author_rank: Contributor
timestamp: August 21, 2021, 09:26:59 am
content: 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 logicCode:(*preserve*) logic [ BHG_EXTRA_SPEED * (PORT_VECTOR_SIZE-1) :0] OUT_RD_VECTOR_int = 0 ;

author: BrianHG
author_rank: Super Contributor
timestamp: August 21, 2021, 09:41:38 am
content: Quote from: dtodorov on August 21, 2021, 09:26:59 amWithout 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.

author: dtodorov
author_rank: Contributor
timestamp: August 21, 2021, 12:49:24 pm
content: Not sure if could help but just to push a bit the discussion:How about using a generate statement? I used this linkhttps://www.verilogpro.com/verilog-generate-configurable-rtl/tutorial to create an example testcase.Code:module test_genvar();parameter TEST_PARAM = 1;generateif (TEST_PARAM == 1) beginreg [15:0] test_param_set;endelse beginreg [3:0] test_param_not_set;endendgenerateendmoduleand the testbenchCode: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;endendmoduleand the result seem to be as expected:

author: BrianHG
author_rank: Super Contributor
timestamp: August 21, 2021, 04:32:20 pm
content: Generate was the first thing I tried a 2 days ago.Here was my code:Code:generateif (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 beginlogic [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.endendgenerateHere 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:generateif (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) beginOUT_RD_VECTOR_int <= vector_pipe_mem ; // 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 ;endend else beginlogic [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) beginOUT_RD_VECTOR_int <= vector_pipe_mem ; // 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 ;endendendgenerateAnd 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.

author: FenTiger
author_rank: Regular Contributor
timestamp: August 21, 2021, 05:19:52 pm
content: Quote from: BrianHG on August 21, 2021, 04:32:20 pmA 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

author: BrianHG
author_rank: Super Contributor
timestamp: August 21, 2021, 05:38:15 pm
content: 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.

author: FenTiger
author_rank: Regular Contributor
timestamp: August 21, 2021, 06:01:00 pm
content: Can you share the whole file?

author: BrianHG
author_rank: Super Contributor
timestamp: August 21, 2021, 07:07:40 pm
content: Quote from: FenTiger on August 21, 2021, 06:01:00 pmI attached the .sv.The generate is on line 224.

author: FenTiger
author_rank: Regular Contributor
timestamp: August 21, 2021, 07:18:00 pm
content: 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 andallits references into the inner scope, hence it works.