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.