FPGARelated.com
Forums

Conditional Interpretation of VHDL

Started by David Wade June 22, 2015
I have a small project that produces a clone of the "BABY" computer at 
MOSI. I want to be able to produce two versions of the code, one which 
displays on a VGA screen and another which uses a Luminescent display.

To do this I need to be able to set different output signals depending 
on the way its built.

At present I am building two different projects and keeping them both up 
to date is a bit of a pain.

Dave Wade
David Wade <dave.g4ugm@gmail.com> wrote:
> I have a small project that produces a clone of the "BABY" computer at > MOSI. I want to be able to produce two versions of the code, one which > displays on a VGA screen and another which uses a Luminescent display.
> To do this I need to be able to set different output signals depending > on the way its built.
> At present I am building two different projects and keeping them both up > to date is a bit of a pain.
For verilog, there is `ifdef, similar to the C #ifdef. It seems that VHDL has if/generate, but I haven't tried it. Otherwise, most synthesis tools are good at removing unused logic. If you code such that the unneeded signals aren't used, the logic to generate them won't be, either. But it looks to me like if/generate should do what you want. -- glen
> Dave Wade
glen herrmannsfeldt wrote:
> David Wade <dave.g4ugm@gmail.com> wrote: >> I have a small project that produces a clone of the "BABY" computer at >> MOSI. I want to be able to produce two versions of the code, one which >> displays on a VGA screen and another which uses a Luminescent display. > >> To do this I need to be able to set different output signals depending >> on the way its built. > >> At present I am building two different projects and keeping them both up >> to date is a bit of a pain. > > For verilog, there is `ifdef, similar to the C #ifdef. > > It seems that VHDL has if/generate, but I haven't tried it. > > Otherwise, most synthesis tools are good at removing unused logic. > If you code such that the unneeded signals aren't used, the logic > to generate them won't be, either. > > But it looks to me like if/generate should do what you want. > > -- glen > >> Dave Wade
I'm not sure if if/generate will help if what you want is to define a different set of module ports. `ifdef is pre-processed, so you can slap it anywhere in the code to conditionally include or leave out items. -- Gabor
In article <mm9ub8$qlq$1@dont-email.me>,
GaborSzakacs  <gabor@alacron.com> wrote:
>glen herrmannsfeldt wrote: >> David Wade <dave.g4ugm@gmail.com> wrote: >>> I have a small project that produces a clone of the "BABY" computer at >>> MOSI. I want to be able to produce two versions of the code, one which >>> displays on a VGA screen and another which uses a Luminescent display. >> >>> To do this I need to be able to set different output signals depending >>> on the way its built. >> >>> At present I am building two different projects and keeping them both up >>> to date is a bit of a pain. >> >> For verilog, there is `ifdef, similar to the C #ifdef. >> >> It seems that VHDL has if/generate, but I haven't tried it. >> >> Otherwise, most synthesis tools are good at removing unused logic. >> If you code such that the unneeded signals aren't used, the logic >> to generate them won't be, either. >> >> But it looks to me like if/generate should do what you want. >> >> -- glen >> >>> Dave Wade > >I'm not sure if if/generate will help if what you want is to define a >different set of module ports. `ifdef is pre-processed, so you can slap >it anywhere in the code to conditionally include or leave out items. > >-- >Gabor
Speaking VERY generally here, but I think it's appropriate... The usual way to solve this sort of thing is to group the requisite shared logic in shared files. Then have two unique top levels which just feed the approprate signals down to the shared modules. Pretty straightforward really; shared code lives in shared files. Unique code lives in unique files. If you find yourself cut/pasting code too much, you need to rethink the code organization. Also, do rely on synthesis optimizations, as Glen indicated. These tools are VERY mature, and very good at their job. If your shared code includes some redundant (or unused) information in a certain solution, that's ok - leave it dangling unused. The optimizer will remove the unusued logic just fine. Similarly for inputs to shared modules - tied constants at inputs are optimized just as easily (through sequential stages too). Regards, Mark
Mark Curry <gtwrek@sonic.net> wrote:
> In article <mm9ub8$qlq$1@dont-email.me>,
(snip on optional logic for two choices)
>>I'm not sure if if/generate will help if what you want is to define a >>different set of module ports. `ifdef is pre-processed, so you can slap >>it anywhere in the code to conditionally include or leave out items.
Yes, it probably doesn't do that. I was thinking of the case where the ports have different signals for the two cases, or aren't used for one.
> Speaking VERY generally here, but I think it's appropriate...
> The usual way to solve this sort of thing is to group the requisite > shared logic in shared files. Then have two unique top levels > which just feed the approprate signals down to the shared > modules.
That sounds about right to me, though it depends on the actual goal. With big FPGAs, it is almost as easy to generate logic and use only the parts you need.
> Pretty straightforward really; shared code lives in shared files. > Unique code lives in unique files. If you find yourself > cut/pasting code too much, you need to rethink the code organization.
> Also, do rely on synthesis optimizations, as Glen indicated. > These tools are VERY mature, and very good at their job. > If your shared code includes some redundant (or unused) > information in a certain solution, that's ok - leave it dangling > unused. The optimizer will remove the unusued logic just fine.
I remember all those times where a tiny logic mistake causes the tools to remove everything. It takes some tracing back to see why it did that.
> Similarly for inputs to shared modules - tied constants at inputs > are optimized just as easily (through sequential stages too).
-- glen
On 6/22/2015 2:33 PM, David Wade wrote:
> I have a small project that produces a clone of the "BABY" computer at > MOSI. I want to be able to produce two versions of the code, one which > displays on a VGA screen and another which uses a Luminescent display. > > To do this I need to be able to set different output signals depending > on the way its built. > > At present I am building two different projects and keeping them both up > to date is a bit of a pain.
I'm not sure you will find much difference keeping two projects up to date and keeping one project with two projects nested within "if" statements. I've tried this before and found it to be a royal PITA. The size of each file grows and the conditionals make the code much harder to read. What I ended up with was to encapsulate the two varieties in two separate files (rather than letting the differences be spread across the project) and built two separate projects. They were still 90+% the same so a lot of testing could be reused. -- Rick
Thanks for all the suggestions. More posts in-line,,,,

On 22/06/2015 23:14, Mark Curry wrote:
> In article <mm9ub8$qlq$1@dont-email.me>, > GaborSzakacs <gabor@alacron.com> wrote: >> glen herrmannsfeldt wrote: >>> David Wade <dave.g4ugm@gmail.com> wrote: >>>> I have a small project that produces a clone of the "BABY" computer at >>>> MOSI. I want to be able to produce two versions of the code, one which >>>> displays on a VGA screen and another which uses a Luminescent display. >>> >>>> To do this I need to be able to set different output signals depending >>>> on the way its built. >>> >>>> At present I am building two different projects and keeping them both up >>>> to date is a bit of a pain. >>> >>> For verilog, there is `ifdef, similar to the C #ifdef. >>> >>> It seems that VHDL has if/generate, but I haven't tried it. >>> >>> Otherwise, most synthesis tools are good at removing unused logic. >>> If you code such that the unneeded signals aren't used, the logic >>> to generate them won't be, either. >>> >>> But it looks to me like if/generate should do what you want. >>> >>> -- glen >>> >>>> Dave Wade >> >> I'm not sure if if/generate will help if what you want is to define a >> different set of module ports. `ifdef is pre-processed, so you can slap >> it anywhere in the code to conditionally include or leave out items. >> >> -- >> Gabor > > Speaking VERY generally here, but I think it's appropriate... > > The usual way to solve this sort of thing is to group the requisite > shared logic in shared files. Then have two unique top levels > which just feed the approprate signals down to the shared > modules. > > Pretty straightforward really; shared code lives in shared files. Unique code > lives in unique files. If you find yourself cut/pasting code too much, you > need to rethink the code organization.
I think I need to do that any way, but I am finding it mildly challenging. I probably need to re-organize the code...
> > Also, do rely on synthesis optimizations, as Glen indicated. These tools are > VERY mature, and very good at their job. If your shared code includes some > redundant (or unused) information in a certain solution, that's ok - leave it > dangling unused. The optimizer will remove the unusued logic just fine. > Similarly for inputs to shared modules - tied constants at inputs are optimized > just as easily (through sequential stages too). >
OK I am sure I can do that but I.
> Regards, > > Mark >
Dave
Mark Curry <gtwrek@sonic.net> wrote:
> Also, do rely on synthesis optimizations, as Glen indicated. These tools are > VERY mature, and very good at their job. If your shared code includes some > redundant (or unused) information in a certain solution, that's ok - leave it > dangling unused. The optimizer will remove the unusued logic just fine.
Except when it doesn't. For instance, I have a toplevel model that defines some ports that are driven by transceivers. The pins are configured with appropriate I/O standards etc in the project configuration. Let's say I change my PCIe port from 4x to 1x, which is a simple dropdown on the PCIe core. If I have the ports on my toplevel module, but don't connect them to anything, I get an error. If I remove the ports from my toplevel module, but leave the transceiver settings alone, it compiles. The result is I have to do: module toplevel ( output PCIE_TX0_p, input PCIE_RX0_p, `ifdef PCIE_LANES_2X output PCIE_TX1_p, input PCIE_RX1_p, `ifdef PCIE_LANES_4X output PCIE_TX2_p, input PCIE_RX2_p, ... `endif `endif ) This is an unusual corner case, but there's an unusual case around every corner. Theo
Theo Markettos <theom+news@chiark.greenend.org.uk> wrote:

(snip)

>> The optimizer will remove the unusued logic just fine.
> Except when it doesn't.
> For instance, I have a toplevel model that defines some ports that are > driven by transceivers. The pins are configured with appropriate I/O > standards etc in the project configuration.
> Let's say I change my PCIe port from 4x to 1x, which is a simple dropdown on > the PCIe core. If I have the ports on my toplevel module, but don't connect > them to anything, I get an error. If I remove the ports from my toplevel > module, but leave the transceiver settings alone, it compiles.
This might depend on VHDL or veriog, but sometimes I assign Z to I/O ports, which will make the tools happy, and I can still use them as input ports. It might be that you can still also assign output values. Or you could use `ifdef or IF/GENERATE to assign them either the real value or a constant value. I usually assign constants instead of remove ports. (It makes it easier to add back later.) The one that keeps bothering me, is that you can't have lines in the UCF file for ports you aren't using. It would be really nice to include the whole UCF, and have it ignore the ports that your design didn't need (yet). -- glen
On 6/23/2015 4:08 PM, glen herrmannsfeldt wrote:
> Theo Markettos <theom+news@chiark.greenend.org.uk> wrote: > > (snip) > >>> The optimizer will remove the unusued logic just fine. > >> Except when it doesn't. > >> For instance, I have a toplevel model that defines some ports that are >> driven by transceivers. The pins are configured with appropriate I/O >> standards etc in the project configuration. > >> Let's say I change my PCIe port from 4x to 1x, which is a simple dropdown on >> the PCIe core. If I have the ports on my toplevel module, but don't connect >> them to anything, I get an error. If I remove the ports from my toplevel >> module, but leave the transceiver settings alone, it compiles. >
A standard way to do this without `ifdef is to make the ports vectors and use a parameter to define the port width. At least that's how the xilinx cores do it, and it works for either VHDL or Verilog. It's a bit clunky to refer to a lane as TXn[3] / TXp[3] (one bit slice of each of two "vectors" to make a differential pair) but it works.
> This might depend on VHDL or veriog, but sometimes I assign Z to I/O > ports, which will make the tools happy, and I can still use them as > input ports. It might be that you can still also assign output values. > > Or you could use `ifdef or IF/GENERATE to assign them either the > real value or a constant value. I usually assign constants instead > of remove ports. (It makes it easier to add back later.) > > > The one that keeps bothering me, is that you can't have lines in > the UCF file for ports you aren't using. >
You can certainly leave constraints for unused ports in Xilinx tools. There's a couple of command line options, -aul and -aut IIRC to allow unmatched LOC constraints and unmatched timing constraints. In some versions of ISE, you can place all constraints for a port, LOC, IO Standard, Slew, Pullup, etc. on one line using | between constraints and the -aul will ignore the full line. In other versions the -aul just ignores some of the constraints and errors out on others. Oh, well...
> It would be really nice to include the whole UCF, and have it ignore > the ports that your design didn't need (yet). > > -- glen >
-- Gabor