How do I initiate multiple instances of 1 module in verilog? - Page 1
Forum section: electronics / general

author: BrianHG
author_rank: Super Contributor
timestamp: December 25, 2019, 10:50:56 am
content: I have a module called MAGGIE. It is fed by are receives bus controls. I want to initiate 15 of them without copying and pasting 15 of the same modules. I would like to do something along the lines of a 'for' loop, however, for loops are not outside the 'always' portion of you verilog code.Example of what I would like to do:Code:for (i=1 ; i<NUM_LAYERS ; i=i+1) beginmaggie maggie_(.clk ( clk ),.pc_ena_in ( pc_ena[3:0] ), // Synchronous sub-pixel clock divider.hw_regs ( GPU_HW_Control_regs ), // MAGGIE controls.HV_trig ( HV_triggers_in ), // H&V sync and top left window coordinates going into MAGGIE.cmd_in ( GPU_ram_cmd_out[i-1] ), // comand coming in from previous MAGGIE channel.ram_din ( GPU_ram_data_out[i-1] ), // GPU ram read data comand coming in from previous MAGGIE channel.read_addr ( GPU_ram_addr_in ), // current MAGGIE directed pixel/pixel or tile/tile read address going out.cmd_out ( GPU_ram_cmd_in ), // current MAGGIE directed real time pixel/pixel command going out.bp_2_rast_cmd ( maggie_to_bp2r ) ); // once per frame BART controls going outdefparam maggie_.H_RESET_TRIG = 6 , // H&V trigger which defines when the MAGGIE resets and increments it's internal registersmaggie_.H_POS_TRIG = 8+2*i, // H&V trigger which defines the beginning top left coordinate of the MAGGIE's open windowmaggie_.HW_REG_BASE = 64+16*i, // Base address for the 16 bytes which controls the MAGGIE and paired BART modules.maggie_.RAM_READ_CYCLES= 3 ; // Defines the GPU_ram module's read pixel clock cycles.endNow obviously this cant function, but, are there verilog compiler directives or shortcut which would allow me to initiate 30 of these MAGGIE modules without having to copy and paste 30 of these into the beginning of my code and editing all the integervalues incrementing 1 for each instance?

author: BrianHG
author_rank: Super Contributor
timestamp: December 25, 2019, 11:06:17 am
content: Found it, it was the 'generate' command:Code:genvar x;generatefor (x=1 ; x<NUM_LAYERS ; x=x+1) begin : maggie_instmaggie maggie_inst (.clk ( clk ),.pc_ena_in ( pc_ena[3:0] ), // Synchronous sub-pixel clock divider.hw_regs ( GPU_HW_Control_regs ), // MAGGIE controls.HV_trig ( HV_triggers_in ), // H&V sync and top left window coordinates going into MAGGIE.cmd_in ( GPU_ram_cmd_out[x-1] ), // comand coming in from previous MAGGIE channel.ram_din ( GPU_ram_data_out[x-1] ), // GPU ram read data comand coming in from previous MAGGIE channel.read_addr ( GPU_ram_addr_in ), // current MAGGIE directed pixel/pixel or tile/tile read address going out.cmd_out ( GPU_ram_cmd_in ), // current MAGGIE directed real time pixel/pixel command going out.bp_2_rast_cmd ( maggie_to_bp2r ) ); // once per frame BART controls going outdefparam maggie_inst.H_RESET_TRIG= 6 , // H&V trigger which defines when the MAGGIE resets and increments it's internal registersmaggie_inst.H_POS_TRIG= 8+2*x, // H&V trigger which defines the beginning top left coordinate of the MAGGIE's open windowmaggie_inst.HW_REG_BASE= 64+16*x, // Base address for the 16 bytes which controls the MAGGIE and paired BART modules.maggie_inst.RAM_READ_CYCLES= 3 ; // Defines the GPU_ram module's read pixel clock cycles.endendgenerateSorry to waste anyone's time, but at least this may help others...

author: asmi
author_rank: Super Contributor
timestamp: December 25, 2019, 08:45:01 pm
content: This is how real engineers are supposed to work. Ran into a problem, and solved it himself shortly thereafterI would add that there is also "generate if/else" statement which is useful for conditional inclusion of submodules or pieces of code based on parameters.Also instead of using defparam you can specify parameters directly via #() construct:Code:module_type #(.PARAM1("STR"),.PARAM2(42)) inst_name (...);This makes code more readable in my opinion as all parameters are defined right at instantiation.

author: rstofer
author_rank: Super Contributor
timestamp: December 25, 2019, 10:27:47 pm
content: Is the following line correct? The code will only generate NUM_LAYERS - 1 instances. If NUM_LAYERS is 5, the loop executes for 1..4for (x=1 ; x<NUM_LAYERS ; x=x+1) begin : maggie_inst

author: BrianHG
author_rank: Super Contributor
timestamp: December 26, 2019, 12:41:02 am
content: Yes, this is correct as I'm actually beginning with module #0 which is counted, but, because of the following 2 lines:--------------------.cmd_in ( GPU_ram_cmd_out[x-1] ), // comand coming in from previous MAGGIE channel.ram_din ( GPU_ram_data_out[x-1] ), // GPU ram read data comand coming in from previous MAGGIE channel--------------------The first MAGGIE module I have manually defined just prior in the code, but not shown, takes in place of the 'x-1' the value of 'NUM_LAYERS - 1', wrapping around from the top MAGGIE module. This creates a circular chain. Yes, there may have been a way to mathematically insert module #0 into the for loop and make that 'x-1' = to 'NUM_LAYERS - 1' for module #0 alone.