# If you are seeing this message you are either a guru who has a custom browser setting, or your browser is out of date and cannot handle some of the more recent Web standards. In our opinion this site would look much better with the standard setup of a modern browser. However we intend it to be accessible to any browser or Internet device.

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.