1
0
mirror of https://github.com/aolofsson/oh.git synced 2025-01-17 20:02:53 +08:00

Adding features to clock divider

-splitting out period from phase
-adding a second phase shifted clock (running off one counter)
-adding orthogonal control of rising and falling edge
This commit is contained in:
Andreas Olofsson 2016-03-20 18:17:26 -04:00
parent 015b969ac2
commit e5a8227509

View File

@ -1,9 +1,6 @@
//#############################################################################
//# Purpose: Simple clock divider (modulo 2) #
//# clkdiv: 0-->divide by 1 #
//# clkdiv: 1-->divide by 2 #
//# clkdiv: 2-->divide by 4 #
//# clkdiv: 2-->divide by 8 etc.. #
//# Purpose: Clock divider with 2 outputs #
// Secondary clock must be multiple of first clock #
//#############################################################################
//# Author: Andreas Olofsson #
//# License: MIT (see below) #
@ -11,51 +8,85 @@
module oh_clockdiv(/*AUTOARG*/
// Outputs
period_match, phase_match, clkout,
clkout0, clkrise0, clkfall0, clkout1, clkrise1, clkfall1,
// Inputs
clk, nreset, en, clkdiv
clk, nreset, clken, clkdiv, clkphase0, clkphase1
);
//parameters
parameter DW = 8; // divider counter width
parameter CW = $clog2(DW); // config width
//inputs
input clk; // main clock
input nreset; // async active low reset
input en; // counter enable
input [CW-1:0] clkdiv; // counter width
input clken; // clock enable enable
input [7:0] clkdiv; // [7:0]=period
input [15:0] clkphase0; // [7:0]=rising,[15:8]=falling
input [15:0] clkphase1; // [7:0]=rising,[15:8]=falling
output period_match; // period match
output phase_match; // phase match
output clkout; // output clock
//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
reg [DW-1:0] counter; //free running counter!
reg clkout;
//################################
//# BODY
//################################
//regs
reg [DW-1:0] counter; // free running counter
reg clkout0;
reg clkout1_reg;
reg clkout1_shift;
//baud counter
always @ (posedge clk or negedge nreset)
if(!nreset)
counter[7:0] <= 'b0;
else if(en)
if (~nreset)
counter[DW-1:0] <= 'b0;
else if(clken)
if(period_match)
counter[7:0] <= 'b0;
counter[DW-1:0] <= 'b0;
else
counter[7:0] <= counter[7:0] + 1'b1;
assign period_match=(counter[DW-1:0]==((1<<clkdiv[CW-1:0])-1'b1));
assign phase_match =(counter[DW-1:0]==((1<<(clkdiv[CW-1:0])>> 1)-1'b1));
//clock generator
counter[DW-1:0] <= counter[DW-1:0] + 1'b1;
assign period_match = (counter[DW-1:0]==clkdiv[7:0]);
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]);
//clock generators
always @ (posedge clk or negedge nreset)
if(!nreset)
clkout <= 1'b0;
else if(phase_match)
clkout <= 1'b1;
else if(period_match)
clkout <= 1'b0;
clkout0 <= 1'b0;
else if(clkrise0)
clkout0 <= 1'b1;
else if(clkfall0)
clkout0 <= 1'b0;
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;
// creating shifted clock for divide by 2
always @ (negedge clk)
clkout1_shift <= clkout1_reg;
//special case for divide by 2
assign clkout1 = (clkdiv[7:0]==8'd1) ? clkout1_shift:
clkout1_reg;
endmodule // oh_clockdiv
///////////////////////////////////////////////////////////////////////////////
// The MIT License (MIT) //
// //
@ -78,7 +109,7 @@ endmodule // oh_clockdiv
// 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. //
// //
// //
///////////////////////////////////////////////////////////////////////////////