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>
);