⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 pll_beh.v

📁 各种基本单元的verilog模块.对初学者很有帮助的.
💻 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 + -