Intel® FPGA University Program
University Program Material, Education Boards, and Laboratory Exercises
1198 Discussions

simulate simple traffic light example (VHDL, DE2)

Altera_Forum
Honored Contributor II
4,589 Views

Hi, 

 

i wrote a simple VHDL traffic light program using a clock divider to get a 1hz clock which i think is helpfull.  

 

clockdivider: 

library IEEE; use IEEE.STD_LOGIC_1164.ALL; use IEEE.STD_LOGIC_ARITH.ALL; use IEEE.STD_LOGIC_UNSIGNED.ALL; -- clockdivider ... divides x-hz clock into 1hz clock entity clockdiv is port ( -- Input ports clock50mhz : in STD_LOGIC; clockReset : in STD_LOGIC; -- Output ports clockOut : out STD_LOGIC ); end clockdiv; architecture controller of clockdiv is signal count : integer; signal clock1hz : STD_LOGIC; begin divide: process(clock50mhz,clockReset) begin if(clockReset = '1') then count <= 0; clock1hz <= '0'; elsif rising_edge(clock50mhz) then if (count >= 25000000) then clock1hz <=not clock1hz; count <= 0; else count<=count+1; end if; end if; end process; clockOut <= clock1hz; end controller; 

 

 

traffic light control: 

library IEEE; use IEEE.STD_LOGIC_1164.all; use IEEE.STD_LOGIC_unsigned.all; entity ampel_basic is port ( -- Input ports clock1hz : in STD_LOGIC; reset : in STD_LOGIC; -- Output ports tLightsRed1 : out STD_LOGIC; tLightsYellow1 : out STD_LOGIC; tLightsGreen1 : out STD_LOGIC; tLightsRed2 : out STD_LOGIC; tLightsYellow2 : out STD_LOGIC; tLightsGreen2 : out STD_LOGIC ); end ampel_basic; architecture controller of ampel_basic is signal count : integer; begin process(clock1hz, reset) begin if(reset = '1') then count <= 0; elsif rising_edge(clock1hz) then count <= count +1; if (count = 1) then -- light 1 green tLightsGreen1 <= '1'; tLightsYellow1 <= '0'; tLightsRed1 <= '0'; tLightsGreen2 <= '0'; tLightsYellow2 <= '0'; tLightsRed2 <= '1'; elsif (count = 30) then tLightsGreen1 <= '0'; tLightsYellow1 <= '1'; tLightsRed1 <= '0'; tLightsGreen2 <= '0'; tLightsYellow2 <= '0'; tLightsRed2 <= '1'; elsif (count = 31) then -- light 2 green tLightsGreen1 <= '0'; tLightsYellow1 <= '0'; tLightsRed1 <= '1'; tLightsGreen2 <= '1'; tLightsYellow2 <= '0'; tLightsRed2 <= '0'; elsif (count = 60) then tLightsGreen1 <= '0'; tLightsYellow1 <= '0'; tLightsRed1 <= '1'; tLightsGreen2 <= '0'; tLightsYellow2 <= '1'; tLightsRed2 <= '0'; count <= 0; -- reset counter end if; end if; end process; end controller;  

 

i connected both vhdl parts with a root shematic file and mapped the necessary ins and outs according to the DE2 user manual. 

 

First problem -> i'm not sure that my code is working as i expect. 

An the second one -> i want to create a waveform simulation to visualise the traffic light behavior  

 

any help would be great! 

thx alot
0 Kudos
6 Replies
Altera_Forum
Honored Contributor II
3,506 Views

To do both, you will need to create a testbench. A testbench is behavioural code that you do not compile in quartus - you use a simulation tool like modelsim. In it, you instantiate the unit under test (UUT) and drive the inputs and monitor the outputs. You can even read and write to text files if you want.

0 Kudos
Altera_Forum
Honored Contributor II
3,506 Views

is there a good tutorial for it, and do you see any major flaws in my code? 

thx for your quick answer
0 Kudos
Altera_Forum
Honored Contributor II
3,506 Views

The only main flaw is not with the code, but the design. Generating clocks in logic is usually fine for ASICs, but not so ok on FPGAs. With a 1MHz output, you'll probably be ok, but its not a good habit to get into. It is best to clock all logic on the same clock and generate different clock enables to get the different frequencies you need. This means that Timequest can easily check all the timings. With logic generated clocks you may have setup and hold time issues. 

 

Second is a little niggle - std_logic_signed/unsigned/arith are not standard VHDL libraries. The library that is standard is VHDL. Arithmatic was never meant to be done with std_logic_vectors. People keep using these because they were distributed by Synopsis in the early 90s. Numeric_std became part of VHDL in 1993, so engineers keep teaching old methods, along with many text books, and people never get themselves up to date (well, if up to date means using code that was standardised nearly 20 years ago!!!) 

 

Anyway, rant over. 

 

For tutorials, you'll probably find plenty if you google "VHDL testbench". But why not have a play around. 

 

heres an example of what you can do in testbenches - this one generates random numbers and checks for less than or greater than zero on each clock edge, and reports each one to the simulator console: 

 

library ieee; use ieee.std_logic_1164.all; use ieee.numeric_std.all; use ieee.math_real.all; entity play_TB is end entity; architecture rtl of play_TB is signal reset : std_logic; signal clk : std_logic := '0'; signal data : integer; signal ENDSIM : boolean; ----------------------------------------------- --RANDOM INTEGER GENERATORS ----------------------------------------------- procedure rand_int( variable seed1, seed2 : inout positive; result : out integer) is variable rand : real; begin uniform(seed1, seed2, rand); --from the math_real library result := integer(((rand - 0.5) *2.0) * real(integer'high)); --makes random range from integer'low to integer'high by making "rand" range -1 to +1 end procedure; -------------------------------------------------------------------------------------------------- --Writes a string to the Simulator Console. -------------------------------------------------------------------------------------------------- procedure echo (arg : in string := "") is begin std.textio.write(std.textio.output, arg); end procedure echo; begin reset <= '1', '0' after 100 ns; ENDSIM <= false, true after 1 ms; process begin while not ENDSIM loop clk <= not clk; wait for 10 ns; end loop; wait; end process; process variable s1, s2 : positive := 9134924; variable r : integer; variable n : positive; begin wait until reset = '0'; n := 1; while not ENDSIM loop rand_int(s1, s2, r); data <= r; wait until rising_edge(clk); echo("output " & integer'image(n) & ": " & integer'image(data) & " "); if data > 0 then echo("Greater than zero" & LF); else echo("Less than zero" & LF); end if; n := n + 1; end loop; wait; end process; end rtl;
0 Kudos
Altera_Forum
Honored Contributor II
3,506 Views

thx again, 

 

i don't know if a testbench is what i'm looking for. i need some kind of waveform , which shows the output signals + time dependency 

 

and i'm trying to get an 1hz clock ... will this be possible with my approach?
0 Kudos
Altera_Forum
Honored Contributor II
3,506 Views

The waveform will be generated in the simulator, but you still need to generate a clock and reset, and this is where the testbench comes in,

0 Kudos
Altera_Forum
Honored Contributor II
3,506 Views

 

--- Quote Start ---  

The waveform will be generated in the simulator, but you still need to generate a clock and reset, and this is where the testbench comes in, 

--- Quote End ---  

 

 

ah okay .. so i can't just simulate the board inputs and the 50 mhz clock, which is hardwired on the altera de2?  

 

again thx for the quick answer
0 Kudos
Reply