Traffic light

H

Hammer

Hi all
I'm new to VHDL and if someone can help me. I tried to design one
traffic light for cars and one for pedestrian.
I was using FPGA from my university and it has 50 MHz kvartz so I had to
count 50000000 low to high transitions to get one second

but I want that counter to start counting after the key is pressed and
that sec counts to 37! I tried to do it the way it writes down.

entity count1 is
Port ( clock : in STD_LOGIC;
key : in STD_LOGIC;
yellow : out STD_LOGIC :='0';
green : out STD_LOGIC :='1';
red : out STD_LOGIC :='0';
pred : out STD_LOGIC :='1';
pgreen : out STD_LOGIC :='0');
end count1;

architecture Behavioral of count1 is
signal sec : integer range 0 to 50 :=0;
signal nsec : integer range 0 to 50000000 :=1;
begin
process (clock,key)
begin
if rising_edge(key) then <---THIS IS WHAT I TRIED(DOESN'T WORK)
if rising_edge(clock) then
if nsec = 50000000 then
nsec <= 1;
sec <= sec+1;
else
nsec <= nsec + 1;
end if;
end if;
end if;
end process;
end Behavioral;

IF I REMOVE CODE *** if rising_edge(key) then *** COUNTER WILL COUNT AS
LONG AS THERE IS CLOCK!

Thanks in advance!
 
C

Colin Paul Gloster

On Thu, 15 Jun 2006, Hammer wrote:

"[..]

but I want that counter to start counting after the key is pressed and that sec
counts to 37! [..]"

It is not relevant to your problem but I have noticed that in your example
the range of nsec starts at 0 but nsec never has the value 0.

Of relevance to your problem is why did you try
if rising_edge(key) then
? You probably want for the user to keep the button pressed once for all
the 38 clock cycles instead of pressing the button (impossibly quickly) 38
times in 38 clock cycles. If the signal key changes from 0 to 1 then
rising_edge(key) is true, but ideally this will happen only once (in
reality jitter from what is called "bounce" will cause key'event to
happen a few more times than the ideal minimum which is perhaps why you
are smart enough to count to 37) and (ideally) key will stay at 1 during
your counting. So perhaps you should try replacing
if rising_edge(key) then
with
if '1'=key then
instead.
 
R

Ralf Hildebrandt

Hammer said:
process (clock,key)
begin
if rising_edge(key) then <---THIS IS WHAT I TRIED(DOESN'T WORK)
if rising_edge(clock) then ....
end process;
end Behavioral;

IF I REMOVE CODE *** if rising_edge(key) then *** COUNTER WILL COUNT AS
LONG AS THERE IS CLOCK!


Think about, what you have written: an rising_edge(key) and at exactly
the same time a rising_edge(clock). This will never happen.

For synthesizable HDL code only one 'event (edge) is allowed inside a
process.
=> * Make the process synchronous to the clock.
* Test synchronously with the clock, if the key is pressed. (key='1')
* If pressed, start this counter and store an information, that the
counter should run now.
* If the counter has reached its limit - do whatever you want to do.

Ralf
 
H

Hammer

Ralf said:
Think about, what you have written: an rising_edge(key) and at exactly
the same time a rising_edge(clock). This will never happen.

For synthesizable HDL code only one 'event (edge) is allowed inside a
process.
=> * Make the process synchronous to the clock.
* Test synchronously with the clock, if the key is pressed. (key='1')
* If pressed, start this counter and store an information, that the
counter should run now.
* If the counter has reached its limit - do whatever you want to do.

Ralf

Well, all what I want to do is when the key is pressed I want counter to
start counting to 37 seconds

LOOK AT MY CODE WHICH WORKS ONLY IN SIMULATION BUT WHEN I WANT TO PUT IT
ON FPGA IT DOESN'T WORK:

entity test1 is
Port ( clock : in STD_LOGIC;
key : in STD_LOGIC;
yellow : out STD_LOGIC :='0';
green : out STD_LOGIC :='1';
red : out STD_LOGIC :='0';
pred : out STD_LOGIC :='1';
pgreen : out STD_LOGIC :='0');
end test1;

architecture Behavioral of test1 is
signal sec : integer range 0 to 50 :=0;
signal nsec : integer range 0 to 50 :=0;
begin
process
begin
wait until key='1';
for j in 1 to 38 loop
for i in 1 to 5 loop
wait until clock='1';
nsec<=nsec+1;
end loop;
sec<=sec+1;
nsec<=0;
if ((sec<=2) or (sec>=34 and sec<=36)) then
yellow<='1';
else
yellow<='0';
end if;

if (sec>2 and sec<=36) then
red<='1';
else
red<='0';
end if;

if (sec>2 and sec<=36) then
red<='1';
else
red<='0';
end if;

if (sec>36) then
green<='1';
else
green<='0';
end if;
if (sec>5 and sec<=30) then
pgreen<='1';
pred<='0';
else
pgreen<='0';
pred<='1';
end if;
end loop;
end process;
end Behavioral;
 
H

Hammer

Ralf said:
Think about, what you have written: an rising_edge(key) and at exactly
the same time a rising_edge(clock). This will never happen.

For synthesizable HDL code only one 'event (edge) is allowed inside a
process.
=> * Make the process synchronous to the clock.
* Test synchronously with the clock, if the key is pressed. (key='1')
* If pressed, start this counter and store an information, that the
counter should run now.
* If the counter has reached its limit - do whatever you want to do.

Ralf

Well, all what I want to do is when the key is pressed I want counter to
start counting to 37 seconds

LOOK AT MY CODE WHICH WORKS ONLY IN SIMULATION BUT WHEN I WANT TO PUT IT
ON FPGA IT DOESN'T WORK, I GET AN ERROR:

ERROR:Xst:825 - "C:/sustav/semworking/test1.vhd" line 49: Wait statement
in a procedure is not accepted.

entity test1 is
Port ( clock : in STD_LOGIC;
key : in STD_LOGIC;
yellow : out STD_LOGIC :='0';
green : out STD_LOGIC :='1';
red : out STD_LOGIC :='0';
pred : out STD_LOGIC :='1';
pgreen : out STD_LOGIC :='0');
end test1;

architecture Behavioral of test1 is
signal sec : integer range 0 to 50 :=0;
signal nsec : integer range 0 to 50 :=0;
begin
process
begin
wait until key='1';
for j in 1 to 38 loop
for i in 1 to 5 loop
wait until clock='1'; <--- LINE 49
nsec<=nsec+1;
end loop;
sec<=sec+1;
nsec<=0;
if ((sec<=2) or (sec>=34 and sec<=36)) then
yellow<='1';
else
yellow<='0';
end if;

if (sec>2 and sec<=36) then
red<='1';
else
red<='0';
end if;

if (sec>2 and sec<=36) then
red<='1';
else
red<='0';
end if;

if (sec>36) then
green<='1';
else
green<='0';
end if;
if (sec>5 and sec<=30) then
pgreen<='1';
pred<='0';
else
pgreen<='0';
pred<='1';
end if;
end loop;
end process;
end Behavioral;
 
H

Hammer

Colin said:
On Thu, 15 Jun 2006, Hammer wrote:

"[..]

but I want that counter to start counting after the key is pressed and that sec
counts to 37! [..]"

It is not relevant to your problem but I have noticed that in your example
the range of nsec starts at 0 but nsec never has the value 0.

Of relevance to your problem is why did you try
if rising_edge(key) then
? You probably want for the user to keep the button pressed once for all
the 38 clock cycles instead of pressing the button (impossibly quickly) 38
times in 38 clock cycles. If the signal key changes from 0 to 1 then
rising_edge(key) is true, but ideally this will happen only once (in
reality jitter from what is called "bounce" will cause key'event to
happen a few more times than the ideal minimum which is perhaps why you
are smart enough to count to 37) and (ideally) key will stay at 1 during
your counting. So perhaps you should try replacing
if rising_edge(key) then
with
if '1'=key then
instead.

No, I don't want to press the key 38 times nor to hold the key. Only
what I need it when the key is pressed once (like when you press the key
on keyboard once and counter will start counting)
 
J

Jonathan Bromley

LOOK AT MY CODE WHICH WORKS ONLY IN SIMULATION BUT WHEN I WANT TO PUT IT
ON FPGA IT DOESN'T WORK:

Synthesis is not the same as magic. Try to get hold of a good book on
using VHDL for design - I like

Rushton, A: VHDL for Logic Synthesis

or

Zwolinski, M: Digital System Design using VHDL

Before trying to write VHDL for design, you need a good understanding
of the type of hardware you are trying to create. Right now, you are
treating VHDL as a programming language that understands time -
and this is fine when you're using a simulator, because that is
exactly what VHDL was intended to be! But synthesis tools can
process only a tiny subset of the language, with each
synthesisable code pattern mapping directly on to a well-
understood arrangement of hardware. Your code is very,
very far from being a useful hardware design.

The KnowHow section of our website has some code fragments
and tutorials that you can use as a starting point.
--
Jonathan Bromley, Consultant

DOULOS - Developing Design Know-how
VHDL * Verilog * SystemC * e * Perl * Tcl/Tk * Project Services

Doulos Ltd., 22 Market Place, Ringwood, BH24 1AW, UK
(e-mail address removed)
http://www.MYCOMPANY.com

The contents of this message may contain personal views which
are not the views of Doulos Ltd., unless specifically stated.
 
J

jens

You'll probably want to use a synchronous process template if you want
it to synthesize...

synchronous_process_template: process(clock, reset)
begin
if reset = '1' then
-- initialize registers here
elsif rising_edge(clock) then
-- assign registers here
end if;
end process synchronous_process_template;

Put your code in the "assign registers here" part (after it's
appropriately modified, of course), use "if key = '1' then..." to start
the counter, and you'll probably want some sort of lockout in there to
keep the counter from re-starting if the key is pressed again.
 
H

Hammer

jens said:
You'll probably want to use a synchronous process template if you want
it to synthesize...

synchronous_process_template: process(clock, reset)
begin
if reset = '1' then
-- initialize registers here
elsif rising_edge(clock) then
-- assign registers here
end if;
end process synchronous_process_template;

Put your code in the "assign registers here" part (after it's
appropriately modified, of course), use "if key = '1' then..." to start
the counter, and you'll probably want some sort of lockout in there to
keep the counter from re-starting if the key is pressed again.

I followed your example and key MUST stay pressed all the time. If you
release the key counter stops counting.
The key is of type impulse(just pressed once).

****I need counter to keep counting till 38 seconds****

entity count1 is
Port ( clock : in STD_LOGIC;
key : in STD_LOGIC;
yellow : out STD_LOGIC :='0';
green : out STD_LOGIC :='1';
red : out STD_LOGIC :='0';
pred : out STD_LOGIC :='1';
pgreen : out STD_LOGIC :='0');
end count1;

architecture Behavioral of count1 is
signal sec : integer range 0 to 50 :=0;
signal nsec : integer range 1 to 50000000 :=1;
signal zel : std_logic;
begin
process (clock)
begin
if key='0' then <- x line
nsec<=1;
sec<=0;
else
if rising_edge(clock) then
if nsec = 50000000 then
-- if nsec was 50M before clock,
-- set to 1 after clock.
nsec <= 1;
sec <= sec+1;
else
nsec <= nsec + 1;
end if;
end if;
end if;
end process;
end Behavioral;

And also I managed to get Pedroni book called "Circuit design with VHDL".
 
N

Nicolas Matringe

Hammer a écrit :
I followed your example and key MUST stay pressed all the time. If you
release the key counter stops counting.
The key is of type impulse(just pressed once).

****I need counter to keep counting till 38 seconds****


So you need to keep a memory of what happened. Use something like a
D-flipflop, or even a synchronous RS-latch.
If you've never heard of these words you're a long way away ...

Nicolas
 
H

Hammer

Nicolas said:
Hammer a écrit :



So you need to keep a memory of what happened. Use something like a
D-flipflop, or even a synchronous RS-latch.
If you've never heard of these words you're a long way away ...

Nicolas
I heard and know of them. Thanks
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,755
Messages
2,569,536
Members
45,020
Latest member
GenesisGai

Latest Threads

Top