2016-03-10 11:06:28 -05:00
|
|
|
//#############################################################################
|
2016-03-20 18:17:26 -04:00
|
|
|
//# Purpose: Clock divider with 2 outputs #
|
|
|
|
// Secondary clock must be multiple of first clock #
|
2016-03-10 11:06:28 -05:00
|
|
|
//#############################################################################
|
|
|
|
//# Author: Andreas Olofsson #
|
|
|
|
//# License: MIT (see below) #
|
|
|
|
//#############################################################################
|
|
|
|
|
2015-11-30 13:45:49 -05:00
|
|
|
module oh_clockdiv(/*AUTOARG*/
|
2015-04-15 11:54:43 -04:00
|
|
|
// Outputs
|
2016-03-20 18:17:26 -04:00
|
|
|
clkout0, clkrise0, clkfall0, clkout1, clkrise1, clkfall1,
|
2015-04-15 11:54:43 -04:00
|
|
|
// Inputs
|
2016-03-20 18:17:26 -04:00
|
|
|
clk, nreset, clken, clkdiv, clkphase0, clkphase1
|
2015-04-15 11:54:43 -04:00
|
|
|
);
|
|
|
|
|
2016-03-20 18:17:26 -04:00
|
|
|
//parameters
|
2016-03-10 11:06:28 -05:00
|
|
|
parameter DW = 8; // divider counter width
|
|
|
|
|
2016-03-20 18:17:26 -04:00
|
|
|
//inputs
|
2016-03-10 11:06:28 -05:00
|
|
|
input clk; // main clock
|
|
|
|
input nreset; // async active low reset
|
2016-03-20 18:17:26 -04:00
|
|
|
input clken; // clock enable enable
|
2016-03-21 11:19:25 -04:00
|
|
|
input [7:0] clkdiv; // [7:0]=period (0==off, 1=div/2, 2=div/3, etc)
|
2016-03-20 18:17:26 -04:00
|
|
|
input [15:0] clkphase0; // [7:0]=rising,[15:8]=falling
|
|
|
|
input [15:0] clkphase1; // [7:0]=rising,[15:8]=falling
|
2015-04-18 16:12:43 -04:00
|
|
|
|
2016-03-20 18:17:26 -04:00
|
|
|
//primary clock
|
|
|
|
output clkout0; // primary output clock
|
|
|
|
output clkrise0; // rising edge match
|
|
|
|
output clkfall0; // falling edge match
|
|
|
|
|
|
|
|
//secondary clock
|
|
|
|
output clkout1; // secondary output clock
|
|
|
|
output clkrise1; // rising edge match
|
|
|
|
output clkfall1; // falling edge match
|
2015-04-15 11:54:43 -04:00
|
|
|
|
2016-03-20 18:17:26 -04:00
|
|
|
//################################
|
|
|
|
//# BODY
|
|
|
|
//################################
|
|
|
|
|
|
|
|
//regs
|
|
|
|
reg [DW-1:0] counter; // free running counter
|
2016-03-21 11:19:25 -04:00
|
|
|
reg clkout0_reg;
|
2016-03-20 18:17:26 -04:00
|
|
|
reg clkout1_reg;
|
|
|
|
reg clkout1_shift;
|
2015-04-15 11:54:43 -04:00
|
|
|
|
2016-03-21 11:19:25 -04:00
|
|
|
//###########################################
|
|
|
|
//# CYCLE COUNTER
|
|
|
|
//###########################################
|
2016-02-23 17:49:08 -05:00
|
|
|
always @ (posedge clk or negedge nreset)
|
2016-03-20 18:17:26 -04:00
|
|
|
if (~nreset)
|
|
|
|
counter[DW-1:0] <= 'b0;
|
|
|
|
else if(clken)
|
2016-03-10 11:06:28 -05:00
|
|
|
if(period_match)
|
2016-03-20 18:17:26 -04:00
|
|
|
counter[DW-1:0] <= 'b0;
|
2016-03-10 11:06:28 -05:00
|
|
|
else
|
2016-03-20 18:17:26 -04:00
|
|
|
counter[DW-1:0] <= counter[DW-1:0] + 1'b1;
|
|
|
|
assign period_match = (counter[DW-1:0]==clkdiv[7:0]);
|
2016-03-21 11:19:25 -04:00
|
|
|
|
|
|
|
//###########################################
|
|
|
|
//# RISING/FALLING EDGE SELECTORS
|
|
|
|
//###########################################
|
|
|
|
|
2016-03-20 18:17:26 -04:00
|
|
|
assign clkrise0 = (counter[DW-1:0]==clkphase0[7:0]);
|
|
|
|
assign clkfall0 = (counter[DW-1:0]==clkphase0[15:8]);
|
|
|
|
assign clkrise1 = (counter[DW-1:0]==clkphase1[7:0]);
|
|
|
|
assign clkfall1 = (counter[DW-1:0]==clkphase1[15:8]);
|
|
|
|
|
2016-03-21 11:19:25 -04:00
|
|
|
//###########################################
|
|
|
|
//# CLKOUT0
|
|
|
|
//###########################################
|
2016-02-23 17:49:08 -05:00
|
|
|
always @ (posedge clk or negedge nreset)
|
|
|
|
if(!nreset)
|
2016-03-21 11:19:25 -04:00
|
|
|
clkout0_reg <= 1'b0;
|
2016-03-20 18:17:26 -04:00
|
|
|
else if(clkrise0)
|
2016-03-21 11:19:25 -04:00
|
|
|
clkout0_reg <= 1'b1;
|
2016-03-20 18:17:26 -04:00
|
|
|
else if(clkfall0)
|
2016-03-21 11:19:25 -04:00
|
|
|
clkout0_reg <= 1'b0;
|
|
|
|
|
|
|
|
//bypass divider on "divide by 1"
|
|
|
|
assign clkout0 = (clkdiv[7:0]==8'd0) ? clk : clkout0_reg;
|
|
|
|
|
|
|
|
//###########################################
|
|
|
|
//# CLKOUT1
|
|
|
|
//###########################################
|
2016-03-20 18:17:26 -04:00
|
|
|
always @ (posedge clk or negedge nreset)
|
|
|
|
if(!nreset)
|
|
|
|
clkout1_reg <= 1'b0;
|
|
|
|
else if(clkrise1)
|
|
|
|
clkout1_reg <= 1'b1;
|
|
|
|
else if(clkfall1)
|
|
|
|
clkout1_reg <= 1'b0;
|
|
|
|
|
2016-03-21 11:19:25 -04:00
|
|
|
// creating divide by 2 shifted clock with negedge
|
2016-03-20 18:17:26 -04:00
|
|
|
always @ (negedge clk)
|
|
|
|
clkout1_shift <= clkout1_reg;
|
|
|
|
|
|
|
|
assign clkout1 = (clkdiv[7:0]==8'd1) ? clkout1_shift:
|
|
|
|
clkout1_reg;
|
|
|
|
|
2015-11-30 13:45:49 -05:00
|
|
|
endmodule // oh_clockdiv
|
|
|
|
|
2016-03-10 11:06:28 -05:00
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
|
|
// The MIT License (MIT) //
|
|
|
|
// //
|
|
|
|
// Copyright (c) 2015-2016, Adapteva, Inc. //
|
|
|
|
// //
|
|
|
|
// Permission is hereby granted, free of charge, to any person obtaining a //
|
|
|
|
// copy of this software and associated documentation files (the "Software") //
|
|
|
|
// to deal in the Software without restriction, including without limitation //
|
|
|
|
// the rights to use, copy, modify, merge, publish, distribute, sublicense, //
|
|
|
|
// and/or sell copies of the Software, and to permit persons to whom the //
|
|
|
|
// Software is furnished to do so, subject to the following conditions: //
|
|
|
|
// //
|
|
|
|
// The above copyright notice and this permission notice shall be included //
|
|
|
|
// in all copies or substantial portions of the Software. //
|
|
|
|
// //
|
|
|
|
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS //
|
|
|
|
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF //
|
|
|
|
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. //
|
|
|
|
// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY //
|
|
|
|
// CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT //
|
|
|
|
// OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR //
|
|
|
|
// THE USE OR OTHER DEALINGS IN THE SOFTWARE. //
|
2016-03-20 18:17:26 -04:00
|
|
|
// //
|
2016-03-10 11:06:28 -05:00
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
|
|
|
|
|
|
|
2015-04-15 11:54:43 -04:00
|
|
|
|