you are here: home > free stuff
This page holds some pieces of code which could be useful to designers working in VHDL, particularly applied to FPGAs.
LED Flasher with Varying Intensity
This code generates a flashing LED signal with an intensity which rises smoothly from 0% (off) to 100% (fully on). In this example, each intensity cycle contains 32 intensity levels and the code ticks through the levels at the rate of 150Hz, giving an overall flash rate of approximately 5Hz.
First we generate a 150Hz Tick signal from the master clock:
-- divide the main clock down to approx 150Hz
constant CLOCK_RATE: integer := 25*1000*1000;
constant TICK_RATE : integer := 150;
constant FREQ_DIV : integer := CLOCK_RATE/TICK_RATE;
signal Counter: integer range 0 to FREQ_DIV;
signal Tick : boolean;
process (clk)
begin
if rising_edge(clk) then
if Counter=0 then
Counter <= FREQ_DIV;
else
Counter <= Counter-1;
end if;
Tick <= Counter=0;
end if;
end process;
Then generate a saw-tooth incrementing Delta register which wraps round to 0.
-- set B=5 forces 32 intensity levels
constant B: integer := 5;
signal Delta : unsigned(B-1 downto 0);
process (clk)
begin
if rising_edge(clk) then
if Tick then
Delta <= Delta+1;
end if;
end if;
end process;
Now we can generate LedOn - the LED PWM signal.
-- Accum is the phase accumulator for the PWM
signal Accum : unsigned(B downto 0);
signal LedOn : boolean;
process (clk)
variable Acc, Delt: unsigned(Accum'range);
begin
if rising_edge(clk) then
if Tick then
Accum <= (others=>'0');
else
Acc := '0' & Accum(B-1 downto 0); -- clear overflow to zero
Delt:= '0' & Delta;
-- bit-extend with zero
Accum <= Acc + Delt;
end if;
LedOn <= (Accum(B) = '1');
-- overflow drives LED
end if;
end process;
Locking Logic to a Single Xilinx Virtex LUT
How do you constrain HDL logic so that it is mapped to a single LUT in a Xilinx Virtex or Virtex-E part? This package lets you define your VHDL logic like this:
signal a,b,c,d,x : std_logic;
LU: VLut4 generic map ( ExprStr => "((I0*I1)@(I2*~I3))" )
port map (I0=>a, I1=>b, I2=>c, I3=>d, O=>x );
This evaluates the following expression:
x <= (a and b) xor ( c and (not d));
Cautions:
- This is a VHDL solution. A Verilog solution is more complex.
- We developed this package with Synplicity. It may work with other synthesizers, or it may not.
Here is the VHDL package and components to download : VirtexLut.vhd
VHDL Version of itoa()
A VHDL equivalent to the itoa() function in C is sometimes needed in testbench code and in attribute string generation. This is a simple recursive implementation of itoa(). The local variable n (see below) is not technically necessary.
type TStr10 is array (0 to 9) of string(1 to 1);
constant Str10: TStr10 :=
("0","1","2","3","4","5","6","7","8","9");
function itoa( x : integer ) return string is
variable n: integer := x; -- needed by some compilers
begin
if n < 0 then return "-" & itoa(-n);
elsif n < 10 then return Str10(n);
else return itoa(n/10) & Str10(n rem 10);
end if;
end function itoa;
The function has been tested for integers up into the thousands. It probably will not give the correct answer with integers which use 32 bits or more of precision.