Hi everyone, I have just started using VHDL and I am trying to understand a piece of code I code I was handed. The counter must count up to 0xBEBC200 (which is equal to 200,000,000) and whenever there is a change in the clock signal, the program will enter the process statement to assess wether the counter has reached 0xBEBC200 and reset the counter and if not, increase the counter by 1. However, my friend has put the increment statement inside the if statement assessing whether 0xBEBC200 has been reached or not. For me this makes no sense since this means the counter will not be incremented unless it is equal to 0xBEBC200. He has told me the code is alright but could someone please tell me if the code is right or not ? Thanks. P.d. The clock is 100MHz and this section of the code acts as delay in a larger system.
Hi Jefazo if I understand you right, you want to program a simple counter. If you want to stop the delay at 200 000 000, then you must use
1 | if rising_edge(clk) then |
2 | if counter < X"BEBC200" - X"01" then |
3 | delay <= '0'; --if low active |
4 | counter <= counter + X"01"; |
5 | |
6 | else
|
7 | counter <= X"00"; |
8 | delay <= '1'; --if low active |
9 | end if; |
10 | end if; |
Why
1 | counter < X"BEBC200" - X"01" |
You must set delay <= '1' before the last clock (199 999 999) because the new signal value is only available at the next clock (200 000 000).
Hi oberheld, Thank you for your reply but could the program use this somehow:
1 | process(clk) |
2 | begin
|
3 | if rising_edge(clk)then |
4 | if(counter <=X"BEBC200" ) then |
5 | delay<='0'; |
6 | counter_2000ms <=counter+x"000001"; |
7 | else
|
8 | delay<='1'; |
9 | counter<=x"000000"; |
10 | |
11 | end if; |
12 | end if; |
13 | end process; |
Testing if the value of counter is equal to X"BEBC200" and incrementing from inside the condition ? Or is that part wrong ? Also I not understanding why the next signal value is available from 200 000 000, could you elaborate more on it please ? Thanks in advance.
:
Edited by User
I don't know what you are doing with counter_2000ms but now you assign the value of counter + 1 to "counter_2000ms". With this code the signal "counter" does not increment itself. Jefazo J. wrote: > Testing if the value of counter is equal to X"BEBC200" and incrementing > from inside the condition ? Or is that part wrong ? It is right to increment the counter inside the if statement but your if condition is not right.
1 | if(counter <=X"BEBC200" ) then |
Jefazo J. wrote: > Also I not understanding why the next signal value is available from 200 > 000 000, could you elaborate more on it please ? I hope you can understand my little sketch ;D clk is your 100mhz clock. counter and delay show the current values at the BEGINNING of each clk. So if you want to stop the delay in clk 2, you must set delay to 1 before clk 2 starts.
1 | clk 0 clk 1 clk 2 (last clk) |
2 | _____ _____ _____ |
3 | clk | |_____| |_____| |_____ |
4 | |
5 | counter | 199999998 | 199999999 | 0 | |
6 | |
7 | delay | 0 | 0 | 1 | |
Hi oberheld, Again, thanks a lot for your reply. It was all very clearly explained above. Just one little thing more about the counter, the next signal value is available from 200 000 000 since the counter starts at a value of 0 and when counter is equal 199 999 999, it actually means 200 000 000 cycles have already passed, right ? Apologies if my question seems too simple or dumb. Thanks.
:
Edited by User
If clk 2 starts, then already 2 seconds have passed. Therefore you reset the counter in clk 1 and restart counting in clk 2. So at the Beginning of clk 3 the counter value is 1 again.
If you use this desgin you get a continuous counter. To disable the counter after 2 sec you have to create something like an enable signal.
1 | if rising_edge(clk) then |
2 | if En = '1' and counter < X"BEBC200" - X"01" then |
3 | delay <= '0'; --if low active |
4 | counter <= counter + X"01"; |
5 | |
6 | else
|
7 | counter <= X"00"; |
8 | delay <= '1'; --if low active |
9 | end if; |
10 | end if; |
Hi oberheld, As always thank you for your great explanations. I understood it perfectly now. The only issue is trying to link the state machine with the delays. I am not sure if there is a keyword in VHDL. Please would you mind telling me if there is somthing like that ? I have attached the VHDL code for the state machine. Thanks.
:
Edited by User
Jefazo J. wrote: > The counter must count up to 0xBEBC200 Why digging around with such unreadable values instead of simply using an integer for the counter? That leads to a much more readable code for human beings:
1 | library ieee; |
2 | use ieee.std_logic_1164.all; |
3 | use ieee.numeric_std.all; |
4 | |
5 | :
|
6 | :
|
7 | |
8 | signal counter : integer range 0 to 199999999 := 0; |
9 | process(clk) |
10 | begin
|
11 | if rising_edge(clk)then |
12 | if counter < 200000000-1 then -- 0..199999999 are 200000000 steps |
13 | delay<='0'; |
14 | counter <= counter+1; |
15 | else
|
16 | delay<='1'; |
17 | counter <= 0; |
18 | end if; |
19 | end if; |
20 | end process; |
Some comments on your comments: -- start the process when clk when edge is detected. The sensitivity list is only for the simulator. Any change on any of the signals in that list leads to a recalculation of the process. For generating hardware for the FPGA the synthesizer simply ignores that list and invokes all of the necessary signals to implement the described hardware. Only a info/warning about "simulation does not match hardware due to incomplete sensitivity list" may be given. -- if rising edge detected The rising edge is not "detected", thats not a kind of passvie "wating for anything happening". Instead the text these must be "due to a rising edge", because exactly that rising edge does something with the flipflops. --reset the counte immediately There is no such a thing linke "immediately" to signals inside a process. In the simulator all signals inside a process keep their old value till the end of the process or the next wait statement. In real hardware you must see, what you describe: logic and flipflops. --and restart the process There is no way to "restart" a process. Forget this "starting" at all. See it more like a process is "triggered" due to a change of any signal in its sensitivity list (as already said). And forget about finfing a process on a real FPGA: there is only logic (= LUTs) and flipflops to build the hardware doing what you describe with your process. Jefazo J. wrote: > I have attached the VHDL code for the state machine. This is no state machine, as the synthesizer invokes no flipflop, because no clock is used inside the description. It may be the combinatorial part of a state machine, but a complete FSM needs flipflops for storing its state. A flipflop would be generated if there would be some 'event or rising_edge() or falling_edge() in the code. Where did you find that FSM coding style? Why not doing it like all the others with a one-process or two-process description? > Delay.txt > STATEMACHINE.txt Pls attach your VHDL code as *.vhd or *vhdl files. You will get some kind of magic called "syntax highlighting" as a bonus. BTW: each VHDL description starts with "library ieee;" and the few lines behind
Please log in before posting. Registration is free and takes only a minute.
Existing account
Do you have a Google/GoogleMail account? No registration required!
Log in with Google account
Log in with Google account
No account? Register here.