- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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
Link Copied
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
is there a good tutorial for it, and do you see any major flaws in my code?
thx for your quick answer- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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;
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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?- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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,
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
--- 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
- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page