![]() |
|
|
|
#1 |
|
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! Hammer |
|
|
|
|
#2 |
|
Posts: n/a
|
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. Colin Paul Gloster |
|
|
|
#3 |
|
Posts: n/a
|
Hammer wrote:
> 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 Ralf Hildebrandt |
|
|
|
#4 |
|
Posts: n/a
|
Ralf Hildebrandt wrote:
> Hammer wrote: > >> 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 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; Hammer |
|
|
|
#5 |
|
Posts: n/a
|
Ralf Hildebrandt wrote:
> Hammer wrote: > >> 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 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; Hammer |
|
|
|
#6 |
|
Posts: n/a
|
Colin Paul Gloster wrote:
> 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) Hammer |
|
|
|
#7 |
|
Posts: n/a
|
On Thu, 15 Jun 2006 18:09:34 +0200, Hammer <> wrote:
>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 http://www.MYCOMPANY.com The contents of this message may contain personal views which are not the views of Doulos Ltd., unless specifically stated. Jonathan Bromley |
|
|
|
#8 |
|
Posts: n/a
|
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. jens |
|
|
|
#9 |
|
Posts: n/a
|
jens wrote:
> 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". Hammer |
|
|
|
#10 |
|
Posts: n/a
|
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 Nicolas Matringe |
|
![]() |
| Thread Tools | Search this Thread |
|
|
Similar Threads
|
||||
| Thread | Thread Starter | Forum | Replies | Last Post |
| Pioneer Dreambook Light IL1 | Admin | Front Page News | 1 | 07-06-2008 02:08 AM |
| Classifying video and voice traffic using DSCP(COS,IPrecedence) on catalyst switch | dorjko | Hardware | 1 | 12-12-2007 02:35 PM |
| LED Light Bulb @ A True Review | Silverstrand | Front Page News | 0 | 10-27-2006 07:45 PM |
| DVD VERDICT | Lookingglass | DVD Video | 15 | 06-24-2004 07:54 AM |
| OT: Traffic: The Miniseries (2003) Review @ GENRE ONLINE.NET | Writer R5 | DVD Video | 0 | 12-21-2003 11:08 PM |