10-06-2015 01:32 PM
I have memory module that stores a range of log_2 values and is designed to be used as a look-up table. The memory is created by instantiating 16 pairs of RAMB36 using the snip of code in the attached Xilinx_forum_post_snip.txt file. The memory module that contains this snip has been tested and works in both simulation and in a fully implemented hardware design; the module has been unmodified and used for a several years in both capacities.
The memory module uses defparam to redefine the 128 INIT parameters associated with each generated RAMB36 instantiations (RAMB36_lower_inst and RAMB36_lower_inst). As you can see in the snip, each generated memory module, bitpos[0:15] (lower and upper), has its own distinct value for all of its 128 INIT parameters. Note: there is some logic in the memory module (not shown) that selects the correct log_2 value for each input but it is just some bit assignments and has nothing to do with the problem I'm having.
The memory module, "gen_log2", is instantiated by a wrapper module, "wrapper", that also instantiates four additional modules. The additional modules use gen_log2 to "look up" log_2 values.
*** The problem ***
I have to design a top-level module, "top", that instantiates multiple wrapper modules (10-20 or more). To simplify the code and reduce duplication, I wrote a generate for loop to generate several wrapper modules. So basically top instantiates wrapper, and wrapper instantiates gen_log2. The generate block in top looks something like this:
generate genvar k; for(k=0; k < NUM_WM_MODS; k = k + 1) begin: wm_gen /**************************** * Generated wrapper modules ****************************/ wrapper inst_wrapper ( .clk(clk), .rst(rst), // other ports omitted ); end // close to the begin: wm_gen of the for loop endgenerate
The hierarchical code with top, wrapper, and gen_log2 synthesize with no warnings that mention a problem with (or removal of) the defparam statements. However, when I try to simulate the code using ISim, I get the message "defparam under generate scope cannot change parameter value outside of hierarchy" from the HDLCompiler. I only get this error when I attempt to simulate top. I do not get this error when I simulate wrapper. The IEEE Verilog 2001 standard states:
"Using the defparam statement, parameter values can be changed in any module instance throughout the design using the hierarchical name of the parameter. However, a defparam statement in a hierarchy under a generate scope or array of instances shall not change a parameter value outside that hierarchy."
To my knowledge that defparam statements in gen_log2 are in the same hierarchy as the generate block of gen_log2. Relative to top, gen_log2 is hierarchically under top but I don't see a point where defparam is attempting to change a parameter outside of the current instantiated gen_log2 module. Is it possible that the HDLCompiler thinks that the defparam statement is modifying the INIT parameter of a gen_log2 module instanted by a different generated wrapper module?
I've searched multiple places and I haven't seen an example similar to my problem. In addition, I've seen several documents/forums that state using defparam is not advised but I have not found an alternative solution for designs where the parameters of each generated module must be assigned its own unique value.
Therefore, writing in this forum in hope that the Xilinx community can help me resolve this issue.
Given what I have described above, if there is a way to fix the error specified by the HDLCompiler would you please tell me how? Otherwise, if using defparam to assign the parameters of each generated module a unique value (as done in gen_log2) the only way it could be done, is there some way to get ISim to allow me to simulate the design?
Please see the attached Xilinx_forum_post_snip.txt file for the gen_log2 code snip.
10-07-2015 12:41 AM
from you description, it seems like you have following scenario
parameter p1 = 10;
for(i = 0; i <= 0; i = i + 1)
begin : b2
begin // this begin will create a new un-named generate block.
defparam b2.I1.p1 = 20;
When you have defparam under begin-end, it will generate an un-named generate block and using defparam in a generated block to change the parameter outside the hierarchy is illegal.
If I comment out the begin-end block around defparam then it's working fine so make sure that in your design, you don't have any such scenario i.e defparam present in named or un-named generate block.
10-07-2015 07:56 AM
Unfortunately I don't have the defparam encapsulated in its own generate begin-end block but I wish/hope it is that easy to fix. The generte code and defparam statements (provided in Xilinx_forum_post_snip.txt attached to the original post) are encapsulated in the same scope, which is the gen_log2 module itself.
The architecture of the gen_log2 module is essentially this:
module gen_log2 ( // ports omitted ); // reg and wire declarations
always@* begin // logic that assigns bit ranges from the RAMB36 out ports to wire/reg nets // using a case statement end always@(posedge clk) begin // assignments to registers (e.g., rNum <= cNum) r == notation for register end // several assign statements to output ports of gen_log2 // the code in the attached Xilinx_forum_post_snip.txt file goes here endmodule
Your solution is suggesting that, by removing the begin and end keywords that encapsilate the defparam statements, it will remove the error. However, in gen_log2, the defparam statements are not encapsilated by begin-end. They are in the same scope as the generate block.
The error occurs when, in a top-level module called "top", I attempt to use a generate block to generate several copies of a module (called "wrapper") that instantiates gen_log2. If I build (synthesize and implement) or simulate wrapper, I get no error. If I build top, I get no error. If I simulate top, I get an error.
10-07-2015 10:59 AM
I think I found a solution. There are three modules, top, wrapper, and gen_log2. Modules top and gen_log2 use generate blocks. The module gen_log2 uses defparam to modify the INIT parameters of the RAMB36s that it instantiates using generate. Here is the heirarchy
top : instantiates several wrapper modules (inst_wrapper) using generate with loop label wm_gen
wrapper : instantiates one gen_log2 (inst_gen_log2)
gen_log2 : instaniates 16 pairs of RAMB36 using generate with loop label bitpos (see attached file in previous posts)
I moved the defparam statements from gen_log2 to inside of the generate block in top. I then modified the statements to reflect the heirarchical path to the RAMB36 INIT parameters. Using the snip of code for top (posted earlier) and the snip of gen_log2 I have something like this:
module top( //ports ); // reg and wire declarations generate genvar k; for(k=0; k < NUM_WM_MODS; k = k + 1) begin: wm_gen /**************************** * Generated wrapper modules ****************************/ wrapper inst_wrapper ( .clk(clk), .rst(rst), // other ports omitted ); defparam wm_gen[k].inst_wrapper.inst_gen_log2.bitpos.RAMB36_lower_inst.INIT_00 = 256'hCD9B3264CD9B3264CD9B3266CD993266CC9933664CD9B3266CC9933664CD9932; // other lines omitted defparam wm_gen[k].inst_wrapper.inst_gen_log2.bitpos.RAMB36_upper_inst.INIT_7F = 256'hFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF; end // close to the begin: wm_gen of the for loop endgenerate
// other logic
This makes it through synthsis and the HDLCompiler. After looking at ISim, the RAMB36 INIT parameters appear to be set correctly but I haven't fully testing the execution yet.
10-07-2015 12:14 PM
From your description, it seems like you have something like this
parameter p1 = 10;
for(i = 0; i <= 0; i = i + 1)
begin : b2
defparam b2.I1.p1 = 20; // move this defparam to inside generate block but outside for-generate.
for(j = 0; j <=10 ; j = j + 1)
begin : b3
For this ISim showing ERROR, which is wrong so as a work-around, you can simply move the defparam inside the generate block and it will work.