Continue to Site

Welcome to EDAboard.com

Welcome to our site! EDAboard.com is an international Electronics Discussion Forum focused on EDA software, circuits, schematics, books, theory, papers, asic, pld, 8051, DSP, Network, RF, Analog Design, PCB, Service Manuals... and a whole lot more! To participate you need to register. Registration is free. Click here to register now.

VHDL procedure that simulate the lock function a PLL

Status
Not open for further replies.

shaiko

Advanced Member level 5
Joined
Aug 20, 2011
Messages
2,644
Helped
303
Reputation
608
Reaction score
297
Trophy points
1,363
Activity points
18,302
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?
 

How is this procedure called?
How do you expected it to be reset if the clock is clocking - it is stuck in an infinite loop?
 

This is how:
Code:
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 ;

What should I change in the code to make it work?
 

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 is
  procedure pr ( signal a : in bit ) is
  begin
    if a = '1' then
      report "a = 1";
    else
      report "a = 0";
    end if;
  end procedure;
 
  signal s : bit;
 
begin
 
  s <= '1', '0' after 10 ns;
 
  pr(s);
end architecture;



you get this output:

Code:
EXECUTION:: NOTE   : a = 0
EXECUTION:: Time: 0 ps,  Iteration: 0,  Instance: /proc_test,  Process: line__20.
EXECUTION:: NOTE   : a = 1
EXECUTION:: Time: 0 ps,  Iteration: 1,  Instance: /proc_test,  Process: line__20.
EXECUTION:: NOTE   : a = 0
EXECUTION:: Time: 10 ns,  Iteration: 0,  Instance: /proc_test,  Process: line__20.
KERNEL: stopped at time: 15 ns

Can you post the code that drives this entity?

I do wonder though why you want it in a procedure, and not just some processes?
 
  • Like
Reactions: shaiko

    shaiko

    Points: 2
    Helpful Answer Positive Rating
I do wonder though why you want it in a procedure, and not just some processes?
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 ;
 

Why does it have to be done in 1 process? You could have lock in one process waiting for the clock with the clock generated in another.
 
  • Like
Reactions: shaiko

    shaiko

    Points: 2
    Helpful Answer Positive Rating
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.
 


Code VHDL - [expand]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
process
begin
  lock <= '0';
  wait until reset = '0';
  wait for lock_time;
  lock <= '1'
  wait until reset = '1';
end process;
 
clk_proc : process
begin
  wait until reset = '0';
 
  while reset = '0' loop
    clk <= '1';
    wait for clk_period;
    clk <= '0';
    wait for clk_period;
  end loop;
end process;

 
  • Like
Reactions: shaiko

    shaiko

    Points: 2
    Helpful Answer Positive Rating
I tried to simulate it. It doesn't work.
I should note that in my simulation - I didn't assert the reset signal
 

Indeed. A reset would be pretty vital!
But why?
1. At T=0 the process is entered.
2. You schedule it to wait until reset = '0'

Question #1
What section of your code implies that a reset = '1' is necessary for a proper function?

Question #2
What should be changed in the code so that reset effects when it's '1' but isn't absolutely required for things to start rolling?
 

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;
 
  • Like
Reactions: shaiko

    shaiko

    Points: 2
    Helpful Answer Positive Rating
Status
Not open for further replies.

Similar threads

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top