📄 pll_sim.v
字号:
/*********************************************************/
// MODULE: Phase Locked Loop (PLL)
//
// FILE NAME: pll_sim.v
// VERSION: 1.0
// DATE: January 1, 1999
// AUTHOR: Bob Zeidman, Zeidman Consulting
//
// CODE TYPE: Simulation
//
// DESCRIPTION: This module provides stimuli for simulating
// a Phase Locked Loop. It uses a down counter to generate a
// clock input. When the output rising edge occurs during the
// same cycle as an input rising edge, three times in a row,
// we consider the PLL to have locked. We attempt to get the
// PLL to lock onto several different frequencies by changing
// the counter limit. If all of the frequencies can be
// locked, the simulation ends successfully. If the PLL does
// not lock within a certain large number of cycles, the
// simulation stops and reports an error.
//
/*********************************************************/
// 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 CYCLE_TIME 200 // System clock cycle time
// TOP MODULE
module pll_sim();
// INPUTS
// OUTPUTS
// INOUTS
// SIGNAL DECLARATIONS
reg reset;
reg clk;
wire clk_in;
wire clk_out;
integer counter; // Counter used to generate
// the input clock
reg [`CNT_SZ-1:0] limit; // Limit for counter to
// generate input clock
integer cycle_count; // Cycle counter
integer case_count; // Counts each test case
// until we are done
integer lock_count; // Counts each time the
// clocks are locked
reg reg_in; // Registered clock input
// PARAMETERS
// ASSIGN STATEMENTS
// Create a very lopsided clock input signal and see if the
// output is a square wave.
assign #`DEL clk_in = (counter == 0) ? 1'b1 : 1'b0;
// MAIN CODE
// Instantiate the PLL
PLL pll(
.reset(reset),
.limit(limit),
.clk(clk),
.clk_in(clk_in),
.clk_out(clk_out));
// Initialize regs
initial begin
clk = 0;
cycle_count = 0;
case_count = 0;
lock_count = 0;
counter = 0;
reset = 1;
limit = 15;
// Hold the synchronous reset for more than one clock
// period
#120 reset = 0;
end
// Generate the clock
always #(`CYCLE_TIME/2) clk = ~clk;
// Simulate
always @(posedge clk) begin
if (lock_count === 3) begin
// We've locked
$display(
"PLL has locked onto clock after %d cycles\n:",
cycle_count);
case (case_count)
0: begin
limit = 10;
end
1: begin
limit = 5;
end
2: begin
limit = 7;
end
3: begin
limit = 6;
end
4: begin
limit = 12;
end
5: begin
limit = 10;
end
6: begin
$display("\nSimulation complete - no errors\n");
$finish;
end
endcase
lock_count = 0;
counter <= #`DEL 0;
case_count = case_count + 1;
cycle_count = 0;
end
// Check for no clock output
if (cycle_count >= 16*16) begin
// We lost the lock
$display("\nERROR at time %0t:", $time);
$display(" Clock is not locking\n");
// Use $stop for debugging
$stop;
end
// Decrement the counter
if (counter === 0)
counter <= #`DEL limit;
else
counter <= #`DEL counter - 1;
// Increment the cycle count
cycle_count = cycle_count + 1;
end
always @(negedge clk) begin
// Look for the rising edge
if (!reg_in & clk_out) begin
if (counter === 0) begin
// We got an edge correct
lock_count = lock_count + 1;
end
else if (lock_count !== 0) begin
// We lost the lock
lock_count = 0;
end
end
// Store the previous value of the clock
reg_in <= clk_out;
end
endmodule // pll_sim
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -