5

what is the equivalent of #define, #ifdef and #ifndef in VHDL?

I want to use generics as #define, and change the design according to them. as a simple example: define a string generic and use it to determine if the clock is single or differential.

generic (
  something : boolean := FALSE;
  CLK_MODE : string := "SINGLE_ENDED"
);

Now, How to change the logic according to the generics? one can of course write 2 possible logic descriptions with a simple if statement but then both will be synthesized (although only one is really used).

Also, Is it possible to change the ports according to the generic? for the CLK example, 2 in ports are needed for differential clock but only one is needed for single ended clock. how to enable or disable the second port according to the generic?

mewais
  • 1,265
  • 3
  • 25
  • 42

2 Answers2

8

One way to synthesize different hardware circuits depending on a condition is using a generic with an if-generate statement. In the example below, when the generic ARITHMETIC_OPERATION_IS_ADD is true, an adder is generated. When it is false, a subtractor is generated.

library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;

entity conditional_hardware is
    generic (
        ARITHMETIC_OPERATION_IS_ADD: boolean := true
    );
    port (
        a, b: in unsigned(7 downto 0);
        y: out unsigned(7 downto 0)
    );
end;

architecture example of conditional_hardware is
begin

    adder: if ARITHMETIC_OPERATION_IS_ADD generate
        y <= a + b;
    end generate;

    subtractor: if not ARITHMETIC_OPERATION_IS_ADD generate
        y <= a - b;
    end generate;

end;

Note: if you really want it, there are VHDL preprocessors that work much as their C++ counterparts. For instance, take a look at http://vhdlpp.sourceforge.net/README.

For a very good and comprehensive introduction to the fundamentals of reusable VHDL, I highly recommend VLSI Technology's whitepaper Coding Tips and Techniques for Synthesizeable, Reusable VHDL.

It's been a while since I last used LVDS, so the following may be out of date. For outputs, you can assign complementary values to two output pins:

diff_out_p <= my_signal;
diff_out_n <= not my_signal;

Then, on your project settings file, assign them to a differential pair, and set the output standard to LVDS or whatever you use.

For inputs, my tool manual recommends instantiating a primitive. This primitive has two inputs and one output. You should connect the inputs to a differential pair, and use the output in your VHDL code (<data_out> in the example below).

library altera; 
use altera.altera_primitives_components.all; 

lvds_input_buffer : ALT_INBUF_DIFF
generic map (
    IO_STANDARD => "LVDS",
    LOCATION => "IOBANK_1A",
    ENABLE_BUS_HOLD => "off",
    WEAK_PULL_UP_RESISTOR => "off"
)  port map ( 
    i => <data_in_pos>,
    ibar => <data_in_neg>,
    o => <data_out>
);
Franz Forstmayr
  • 1,219
  • 1
  • 15
  • 31
rick
  • 1,626
  • 11
  • 18
  • what about the ports? can they be changed according to the generics? – mewais Oct 24 '13 at 16:17
  • 1
    Depending on what you want to accomplish, you can create a top-level entity which has all the pins as ports. Then you would use if-generates to connect only the ones you actually use. – rick Oct 24 '13 at 16:23
3

Clocks

I would avoid using anything other than a single-ended clock signal in your internal HDL.

Right at the top level, instantiate your differential pair buffer (an IBUFDS in Xilinx-land) to convert to your internal clock signal and use then that signal throughout.

Ports

There's no way of changing the number of port pins based on a generic. What you can do is assign a default to an optional input, which means you don't have to connect it up when you instantiate the entity. You can use generics to decide whether to use the signal or not.

generic (
  something : boolean := FALSE

);
port (
   some_normal_port : std_logic;
   some_optional_port : std_logic := 'U';
....

and then

if something generate
   some logic using the optional port
else
   some logic not using the optional port
end generate;
Martin Thompson
  • 16,395
  • 1
  • 38
  • 56
  • Hi Martin, thanks for a great answer. I want to use this ```if-generate``` inside a process, however I found out that I cannot use it. What I want to do is enable/disable a code snippet inside a process according to value of a boolean generic. Can I achieve it in VHDL? Thanks – efe373 Nov 23 '22 at 10:15
  • just use `if some_bool then do_stuff end if;` if the generic is set to false the synthesizer will optimize all that logic away :) – Martin Thompson Nov 23 '22 at 15:00