pll_rtl.v

来自「各种基本单元的verilog模块.对初学者很有帮助的.」· Verilog 代码 · 共 111 行

V
111
字号
/*********************************************************/
// MODULE:		Phase Locked Loop (PLL)
//
// FILE NAME:	pll_rtl.v
// VERSION:		1.0
// DATE:		January 1, 1999
// AUTHOR:		Bob Zeidman, Zeidman Consulting
// 
// CODE TYPE:	Register Transfer 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.
//
/*********************************************************/

// 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.

// TOP MODULE
module	PLL(
		reset,
		limit,
		clk,
		clk_in,
		clk_out);

// INPUTS
input				reset; 		// Reset the PLL
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;
wire				clk_out;

reg  [`CNT_SZ-1:0]	counter; 	// Counter used to
							 	// lock onto the clock
reg					reg_in;	 	// Registered clock input

// PARAMETERS

// ASSIGN STATEMENTS
assign #`DEL clk_out = (counter > limit/`DUTY) ? 1'b1 : 1'b0;

// MAIN CODE

// Look at the rising edge of system clock
always @(posedge clk) begin
	if (reset) begin
		counter <= #`DEL 0;
	end
	else begin
 		// Store the clock input for finding rising edges
		reg_in <= #`DEL clk_in;

		// Look for the rising edge of the input clock which
		// ideally happens at the same time as
		// counter == limit. Add or remove counter cycles to
		// synchronize its phase with that of the input clock.
		if ((!reg_in & clk_in) && (counter != limit)) begin
			if (counter < limit/2) begin
				// The output clock edge came too late, so
				// subtract two from the counter instead of the
				// usual one.
				if (counter == 1)
					counter <= #`DEL limit;
				else if (counter == 0)
					counter <= #`DEL limit - 1;
				else
					counter <= #`DEL counter - 2;
			end
			// Otherwise add an extra cycle by not decrementing
			// the counter this cycle
		end
		else begin
			if (counter == 0)
				counter <= #`DEL limit;
			else
				counter <= #`DEL counter - 1;
		end
	end
end
endmodule		// PLL

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?