aboutsummaryrefslogblamecommitdiff
path: root/rtl/src/verilog/novena_clkmgr.v
blob: 5713383bf106d0595be3b8e4b9f5b7672d69cbf0 (plain) (tree)
1
2
3
4
5
6



                    

                               
























                                                                                        




                                         




















                                                                       

                                  





                                                                                                      



                                                                                                                                                                                                       



                                             

                                     



                                                                               
                                                                                
 


                                                                                                                              















                                                                                                                                                                                                                               
`timescale 1ns / 1ps

module novena_clkmgr
	(
		gclk_p, gclk_n,
		reset_mcu_b,
		sys_clk, sys_rst,
		bclk_in, bclk_out
	);

		//
		// Ports
		//
	input		wire	gclk_p;			// signal from clock pins
	input		wire	gclk_n;			//

	input		wire	reset_mcu_b;	// cpu reset (async)

	output	wire	sys_clk;			// buffered system clock output
	output	wire	sys_rst;			// system reset output (sync)

	input		wire	bclk_in;			// signal from clock pin
	output	wire	bclk_out;		// buffered clock output


		//
		// IBUFGDS
		//
	(* BUFFER_TYPE="NONE" *)
	wire gclk;

	IBUFGDS IBUFGDS_gclk
	(
		.I		(gclk_p),
		.IB	(gclk_n),
		.O		(gclk)
	);


		//
		// DCM
		//
	wire	dcm_reset;		// dcm reset
	wire	dcm_locked;		// output clock valid
	wire	gclk_missing;	// no input clock

	clkmgr_dcm dcm
	(
		.CLK_IN1					(gclk),
		.RESET					(dcm_reset),
		.INPUT_CLK_STOPPED	(gclk_missing),

		.CLK_OUT1				(sys_clk),
		.CLK_VALID				(dcm_locked)
	);


		//
		// DCM Reset Logic
		//

	/* DCM should be reset on power-up, when input clock is stopped or when the CPU gets reset. */

	reg	[15: 0]	dcm_rst_shreg	= {16{1'b1}};	// 16-bit shift register

	always @(posedge gclk or negedge reset_mcu_b or posedge gclk_missing)
		//
		if ((reset_mcu_b == 1'b0) || (gclk_missing == 1'b1))	dcm_rst_shreg	<= {16{1'b1}};
		else																	dcm_rst_shreg	<= {dcm_rst_shreg[14:0], 1'b0};

	assign dcm_reset = dcm_rst_shreg[15];


		//
		// System Reset Logic
		//

	/* System reset is asserted for 16 cycles whenever DCM aquires lock. */

	reg	[15: 0]	sys_rst_shreg	= {16{1'b1}};	// 16-bit shift register

	always @(posedge sys_clk or negedge reset_mcu_b or posedge gclk_missing or negedge dcm_locked)
		//
		if ((reset_mcu_b == 1'b0) || (gclk_missing == 1'b1) || (dcm_locked == 1'b0))	sys_rst_shreg	<= {16{1'b1}};
		else if (dcm_locked == 1'b1)																	sys_rst_shreg	<= {sys_rst_shreg[14:0], 1'b0};

	assign sys_rst = sys_rst_shreg[15];


		//
		// BCLK BUFG
		//
	BUFG BUFG_BCLK
	(
		.I		(bclk_in),
		.O		(bclk_out)
	);


endmodule