VHDL procedure that simulates the lock function of a PLL
Hello,
I'm trying to write a procedure that will simulate a clock.
If reset is asserted, the clock output should be '0' and so it the lock signal.
If reset isn't de-asserted, the lock signal should rise and the clock should start to oscillate after a certain time.
This is what I wrote so far:
Code:
procedure clock_generation
(
constant frequency : real ;
constant time_lock : time ;
signal reset : in std_logic ;
signal clock : out std_logic ;
signal lock : out std_logic
) is
constant high_time : time := 0.5 sec / frequency ;
variable low_time : time ;
begin
low_time := 1 sec * ( 1.0 / frequency ) - high_time ;
clock <= '0' ;
lock <= '0' ;
if reset = '1' then
clock <= '0' ;
lock <= '0' ;
else
wait for time_lock ;
lock <= '1' ;
loop
wait for low_time ;
clock <= '1' ;
wait for high_time ;
clock <= '0' ;
end loop ;
end if ;
end procedure ;
;
Unfortunately it doesn't work.
The clock output is a stable 'U'.
What's wrong?
library ieee ;
use ieee.std_logic_1164.all ;
use ieee.numeric_std.all ;
use ieee.math_real.all ;
entity simulated_pll is
generic
(
FREQUENCY : real := 50000000.0 ;
TIME_LOCK : time := 112 ns
) ;
port
(
IN_CLOCK : in std_logic ;
IN_RESET : in std_logic ;
OUT_CLOCK : out std_logic ;
OUT_LOCK : out std_logic
) ;
end entity simulated_pll ;
architecture rtl_simulated_pll of simulated_pll is
begin
clock_generation
(
FREQUENCY ,
TIME_LOCK ,
IN_RESET ,
OUT_CLOCK ,
OUT_LOCK
) ;
end architecture rtl_simulated_pll ;
Won't the procedure only be executed once at 0, and never again as it's not in any kind of procedural block (e.g. process, for loop, etc), which would call the procedure again?
Won't the procedure only be executed once at 0, and never again as it's not in any kind of procedural block (e.g. process, for loop, etc), which would call the procedure again?
It will execute at time zero, but like all one liners in VHDL, you actually have an infered process that is sensitive to all signals on the RHS. So here, it should get called whenever the reset changes. With the code below:
Code VHDL - [expand]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
architecture test of proc_test isprocedure pr (signal a :inbit)isbeginif a = '1' thenreport"a = 1";elsereport"a = 0";endif;endprocedure;signal s :bit;begin
s <= '1', '0' after10ns;
pr(s);endarchitecture;
I'd gladly use a process - but it has the limitation of mixing "wait for" together with a sensitivity list...
Can you post an example of how to achieve the functionality I want with a process (and not a procedure) ?
Something in the spirit of this code snippet :
Code:
process ( reset ) is
begin
if reset = '1' then
lock <= '0' ;
clock <= '0' ;
elsif lock = '0' then
wait for lock_time ;
lock <= '1' ;
else
wait for low_time ;
clock <= '1' ;
wait for high_time ;
clock <= '0' ;
end if ;
end process ;
Can you post an example of that code?
I think if I do it the way you suggest I won't be able to use any arbitrary lock time - as I'll be limited to the resolution of my clock.
It depends what you did with the reset.
If you initialised it to '0' and left it there, because of VHDL mechanics it will wait forever. When you hit a wait until, you need an 'event to trigger it and stop waiting. If its already '0', it wont ever exit the wait.
If you leave it unitialised, and then assign it elswhere:
Code:
signal reset : std_logic;
reset <= '0';
Then you get a 'event in the first delta of simulation, kicking the waits out.
I usually expect a reset at the start of simulation, hence my code.
You really need to post your "it didnt work" statements in context.
- - - Updated - - -
maybe I should have put:
Code:
if reset /= '0' then
wait until reset = '0';
end if;