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:
parent
015b969ac2
commit
e5a8227509
@ -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. //
|
||||
// //
|
||||
// //
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user