📄 pll_beh.v
字号:
/*********************************************************/
// MODULE: Phase Locked Loop (PLL)
//
// FILE NAME: pll_beh.v
// VERSION: 1.0
// DATE: January 1, 1999
// AUTHOR: Bob Zeidman, Zeidman Consulting
//
// CODE TYPE: Behavioral Level
//
// DESCRIPTION: This module defines a phase locked loop
// (PLL) with a synchronous reset. This PLL looks only at
// the rising edge of the input clock for synchronization.
// It is possible for a PLL to look at the falling edge or
// both edges also. Note that this code evaluates most
// inputs on the input and output clock edges, rather than
// the system clock. This speeds up execution since the input
// and output clocks are much slower than the system clock.
//
/*********************************************************/
// DEFINES
`define DEL 1 // Clock-to-output delay. Zero
// time delays can be confusing
// and sometimes cause problems.
`define CNT_SZ 4 // The number of bits in the counter.
// This determines the maximum
// frequency of the PLL.
`define DUTY 2 // This determines the duty cycle of
// the output clock.
// 2 = 50% low, 50% high
// 3 = 33% low, 67% high
// 4 = 25% low, 75% high
// etc.
`define CYCLE_TIME 200 // System clock cycle time
// TOP MODULE
module PLL(
reset,
limit,
clk,
clk_in,
clk_out);
// INPUTS
input reset; // We don't use this input,
// but keep it for compatibility
// with the RTL code
input [`CNT_SZ-1:0] limit; // The upper limit for the counter
// which determines the output
// clock frequency. This must be
// close to the input clock
// frequency.
input clk; // Fast system clock
input clk_in; // Clock input
// OUTPUTS
output clk_out; // Clock output
// INOUTS
// SIGNAL DECLARATIONS
wire reset;
wire [`CNT_SZ-1:0] limit;
wire clk;
wire clk_in;
reg clk_out;
time edge_time; // Keep track of clock edge time
time period; // Target output clock period
time clk_high; // Used to store the most
// up-to-date time value for the
// output clock to go high
time high_time; // This value changes at the time
// that the output clock is to go
// high
// PARAMETERS
// ASSIGN STATEMENTS
// MAIN CODE
// Initialize regs
initial begin
// Wait for the clock frequency to be defined
wait (period !== 64'hxxxxxxxxxxxxxxxx);
// Wait for the system clock, then start the output clock
// in order to synchronize it to the system clock
@(posedge clk);
#`DEL;
clk_high = $time;
high_time = $time;
end
// Generate the output clock
always @(clk_high) begin
// Only generate a clock edge if this is the correct
// time to do so.
if (clk_high == high_time) begin
// Store the time of this edge
edge_time = $time;
// Generate the output clock rising edge
clk_out <= 1'b1;
// Generate the output clock falling edge
clk_out <= #(period - period/`DUTY) 1'b0;
// Set up the next clock period
high_time = $time + period;
clk_high <= #period (high_time);
end
end
// Look at the rising edge of the input clock
always @(posedge clk_in) begin
// Look for the rising edge of the input clock which
// ideally happens exactly one period after the previous
// rising edge of the output clock. If the time to the
// previous rising edge is one period, we have
// synchronized. Also, if the time to the previous rising
// edge is 0 we have synchronized. This is because we
// never know which always block will be executed first.
if (($time-edge_time != 0) && ($time-edge_time != period)) begin
if (period-($time-edge_time) > `CYCLE_TIME/2) begin
// The output clock edge came too late, so subtract
// a system clock cycle to the output clock period.
high_time = high_time - `CYCLE_TIME;
clk_high <= #(high_time-$time) high_time;
end
else if (($time-edge_time) >= `CYCLE_TIME/2) begin
// The output clock edge came too early, so add a
// system clock cycle to the output clock period.
high_time = high_time + `CYCLE_TIME;
clk_high <= #(high_time-$time) high_time;
end
end
end
// Look for changes in the target clock period
always @(limit) begin
@(posedge clk)
period <= #`DEL (limit+1)*`CYCLE_TIME;
end
endmodule // PLL
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -