-1

I'm new to VHDL, Quartus II and ModelSim. Now I'm doing a lab where we are constructing a blinking LED. How should simulation be handled when the construction deals with relatively long time periods. The frequency of the blinking LED is 1 Hz and the clock on the dev board I'm using (Terasic DE2-115) is 50 MHz. In the code I'm counting the clock pulses and turn on the LED accordingly. However, when I want to verify my code with ModelSim, I get in to troubles dealing with times as long as seconds. So I solved it just by changing the period in the code to a couple of clock cycles to see that the waves behave as expected. For final compilation, I just change the count value that corresponds to 1 second.

But there should be a better way. I don't really want to touch the VHDL code after simulation. Should I use two rtl's, one for synthesis and one for simulation when dealing with time periods approaching 1 ms and higher?

The VHDL code

library ieee;
use ieee.std_logic_1164.all;
entity lab4 is
port(   CLOCK_50 : in std_logic; -- DE2-115 internal clock
KEY      : in std_logic_vector(0 downto 0);   -- Push-buttons, active 0
                                                -- KEY(0) as reset
LEDG     : out std_logic_vector(7 downto 0)); -- Green LEDs
end entity lab4;

architecture lab4_rtl of lab4 is
signal RESET_N : std_logic;
begin

-- Parallel VHDL
constant CLK_FRQ : integer := 50000000;

RESET_N <= KEY(0); -- Here we connect reset to a push-button

-- synch process with asynch reset, i.e. reset as soon as reset is active
p1 : process(CLOCK_50, RESET_N)
variable counter : integer := 0;
variable led_num : integer := 0;
begin

    -- reset part
    if RESET_N = '0' then --KEY is active 0
        counter := 0;      --reset counter 
        LEDG(0) <= '0';    --turn OFF leds

    -- synch part, updates depending on clock
    elsif rising_edge(CLOCK_50) then

        counter := counter + 1; 

        if counter < 50000000 then;
            LEDG(0) <= '1';
        elsif counter >= 50000000 AND counter < 100000000 then
            LEDG(0) <= '0';
        else
            counter := 0;
        end if;
    end if;

 end process p1;

end architecture lab4_rtl;
Alexander
  • 541
  • 5
  • 13

2 Answers2

1

You have declared a named constant, then ignored it...

constant CLK_FRQ : integer := 50000000;

First you can rewrite the counter in terms of CLK_FRQ and CLK_FRQ * 2 instead of magic numbers.

Then you can set different values for CLK_FRQ in sim and synth. There are various ways to do it but my preference is for a function.

function Clock_Frequency return natural is
begin
  -- synthesis translate_off
  return 50;
  -- synthesis translate_on
  return 50000000;
end Clock_Frequency;

It uses the "magic" pragmas translate_off (and _on) which may vary between synthesis tools but are accepted by most. These direct synthesis to ignore bits of the source : in this case, the first Return which is only seen by the simulator.

Now you can call this function to initialise the constant

constant CLK_FRQ : integer := Clock_Frequency;

Job done.

1

I would not change the clock frequency, because this doesn't change the count of events which have to be simulated by the simulator (this is also the time consuming factor). I think it's better to change the number of cycles which must pass until you change the LED output.

You can define a VHDL function which returns TRUE if you are in a simulation environment:

function SIMULATION return boolean is
    variable ret : boolean;
begin
    ret := false;
    --synthesis translate_off
    if Is_X('X') then ret := true; end if;
    --synthesis translate_on
    return  ret;
end function;

In addition to this, you can define a if-then-else function to simplify your code:

function ite(cond : BOOLEAN; value1 : INTEGER; value2 : INTEGER) return INTEGER is
begin
    if cond then
        return value1;
    else
        return value2;
    end if;
end function;

And now it's possible to select the counter's max value in one line like this:

constant COUNTER_MAX : INTEGER := ite(SIMULATION, 500, 50000);

Reviewing your code from above, there are some errors:

  • the LED is blinking at 0.5 Hz not 1 Hz (regarding your if
  • the duty-cycle is not 50.00000 %, because your counter is set to zero one cycle to late.
  • I think it's not intended that LED is synthesized as an addition Flip-Flop.
Paebbels
  • 15,573
  • 13
  • 70
  • 139