Author Topic: Verilog - elegant solution for variable width definition  (Read 2262 times)

0 Members and 1 Guest are viewing this topic.

Offline daqqTopic starter

  • Super Contributor
  • ***
  • Posts: 2302
  • Country: sk
    • My site
Verilog - elegant solution for variable width definition
« on: January 23, 2020, 11:12:18 am »
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: [Select]
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 awful generate command, but I was hoping for something a tad more elegant.

Thanks,

David
Believe it or not, pointy haired people do exist!
+++Divide By Cucumber Error. Please Reinstall Universe And Reboot +++
 

Online asmi

  • Super Contributor
  • ***
  • Posts: 2732
  • Country: ca
Re: Verilog - elegant solution for variable width definition
« Reply #1 on: January 23, 2020, 12:19:18 pm »
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.
« Last Edit: January 23, 2020, 12:21:10 pm by asmi »
 
The following users thanked this post: daqq

Online SiliconWizard

  • Super Contributor
  • ***
  • Posts: 14465
  • Country: fr
Re: Verilog - elegant solution for variable width definition
« Reply #2 on: January 23, 2020, 03:03:23 pm »
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: [Select]
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 awful generate command, but I was hoping for something a tad more elegant.

Note 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: [Select]
assign Reg_Out[31:16] = SomethingElse;
assign Reg_Out[15:0] = 0;
assign Reg_Out[SampleMSB:0] = SampleOut;
 
The following users thanked this post: daqq

Offline BrianHG

  • Super Contributor
  • ***
  • Posts: 7733
  • Country: ca
Re: Verilog - elegant solution for variable width definition
« Reply #3 on: January 23, 2020, 03:57:59 pm »
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: [Select]
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 awful generate command, but I was hoping for something a tad more elegant.

Thanks,

David

Please verify that this still give you a warning:

Code: [Select]
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: [Select]
assign Reg_Out[31:16] = SomethingElse;
assign Reg_Out[15:0] = 16'h0 + SampleOut[SampleMSB:0];
« Last Edit: January 23, 2020, 05:02:07 pm by BrianHG »
 
The following users thanked this post: daqq

Offline daqqTopic starter

  • Super Contributor
  • ***
  • Posts: 2302
  • Country: sk
    • My site
Re: Verilog - elegant solution for variable width definition
« Reply #4 on: January 23, 2020, 10:33:41 pm »
Thanks everyone, great ideas all around!
Quote
Please verify that this still give you a warning:
Will try at work!
Believe it or not, pointy haired people do exist!
+++Divide By Cucumber Error. Please Reinstall Universe And Reboot +++
 

Offline daqqTopic starter

  • Super Contributor
  • ***
  • Posts: 2302
  • Country: sk
    • My site
Re: Verilog - elegant solution for variable width definition
« Reply #5 on: January 24, 2020, 08:04:52 am »
So, update:
My original code:
Code: [Select]
assign Reg_Out[SampleMSB:0] = MemoryReadData;Generates this kind of warning:
Code: [Select]
[Synth 8-3331] design XXX has unconnected port Reg_Out[15]
Other solutions:
Code: [Select]
assign Reg_Control_o[15:0] = MemoryReadData[SampleMSB:0];Generates no warning.
Code: [Select]
assign Reg_Control_o[15:0] = MemoryReadData;Generates no warning. Will use that.
Code: [Select]
assign Reg_Control_o[15:0] = 16'h0 + MemoryReadData[SampleMSB:0];Generates no warning.

Thanks everyone! I was overthinking it :)


edit: 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: [Select]
[Synth 8-3331] design XXX has unconnected port RegControl_i[12]In the thousands :( Any reasonable way to fix it on the input side?
« Last Edit: January 24, 2020, 08:39:57 am by daqq »
Believe it or not, pointy haired people do exist!
+++Divide By Cucumber Error. Please Reinstall Universe And Reboot +++
 


Share me

Digg  Facebook  SlashDot  Delicious  Technorati  Twitter  Google  Yahoo
Smf