Verilog - elegant solution for variable width definition - Page 1
Forum section: electronics / general

author: daqq
author_rank: Super Contributor
timestamp: January 23, 2020, 11:12:18 am
content: Hi guys,I've got some modules that can be used for varying sample widths. Say you have a 12bit ADC, you instantiate a module with the parameter SampleMSB = 11. The output of the module is a 32bit control register that hooks up to a standard bus the rest of the system shares. The upper 16 bits are used for something else.Code:assign Reg_Out[31:16] = SomethingElse;assign Reg_Out[15:(SampleMSB+1)] = 0;assign Reg_Out[SampleMSB:0] = SampleOut;Now, this works well, but when I want to use it for 16 bit samples, the code fails, as (SampleMSB+1) is 16 and 15:16 is nonsense.The obvious way is to keep it unconnected and the compiler will default it to zero, but will issue a warning when the module is used for say, 12 bits.What would be the elegant way of filling out the rest of the register? I suppose I could use some awfulgeneratecommand, but I was hoping for something a tad more elegant.Thanks,David

author: asmi
author_rank: Super Contributor
timestamp: January 23, 2020, 12:19:18 pm
content: I would try something like assign Reg_Out[15:0] = { {(15-SampleMSB){1'b0}}, SampleOut}; just make sure there is a right amount of curly braces (don't have compiler handy to verify syntax). Or even combine the whole 32 bits into a single operator: assign Reg_Out = { SomethingElse, {(15-SampleMSB){1'b0}}, SampleOut}; - this assumes "SomethingElse" is exactly 16 bits.

author: SiliconWizard
author_rank: Super Contributor
timestamp: January 23, 2020, 03:03:23 pm
content: Quote from: daqq on January 23, 2020, 11:12:18 amNote that I don't know much of Verilog - I routinely use VHDL - but wouldn't something like the following work (the equivalent would in VHDL as subsequent assignments just override the earlier ones)?Code:assign Reg_Out[31:16] = SomethingElse;assign Reg_Out[15:0] = 0;assign Reg_Out[SampleMSB:0] = SampleOut;

author: BrianHG
author_rank: Super Contributor
timestamp: January 23, 2020, 03:57:59 pm
content: Quote from: daqq on January 23, 2020, 11:12:18 amPlease verify that this still give you a warning:Code:assign Reg_Out[31:16] = SomethingElse;assign Reg_Out[15:0] = SampleOut[SampleMSB:0];or this guy (this one is the ''elegant'' one as the " 16'h0' " force defines the unused bits as 0 and the " + " allows the compiler to sum any number of bits from SampleOut, all the way up to 16 bit automatically.):Code:assign Reg_Out[31:16] = SomethingElse;assign Reg_Out[15:0] = 16'h0 + SampleOut[SampleMSB:0];

author: daqq
author_rank: Super Contributor
timestamp: January 23, 2020, 10:33:41 pm
content: Thanks everyone, great ideas all around!QuoteWill try at work!

author: daqq
author_rank: Super Contributor
timestamp: January 24, 2020, 08:04:52 am
content: So, update:My original code:Code:assign Reg_Out[SampleMSB:0] = MemoryReadData;Generates this kind of warning:Code:[Synth 8-3331] design XXX has unconnected port Reg_OutOther solutions:Code:assign Reg_Control_o[15:0] = MemoryReadData[SampleMSB:0];Generates no warning.Code:assign Reg_Control_o[15:0] = MemoryReadData;Generates no warning. Will use that.Code:assign Reg_Control_o[15:0] = 16'h0 + MemoryReadData[SampleMSB:0];Generates no warning.Thanks everyone! I was overthinking itedit: And now to exorcise other warnings that the compiler generates for the input side. The standard control register length is 32 bits as well, but I use only, say, 5 bits of it. As such I get a whole warnings like:Code:[Synth 8-3331] design XXX has unconnected port RegControl_iIn the thousandsAny reasonable way to fix it on the input side?