PROGRAMMABLE CLOCK GENERATOR MODULE
(Last Modified: 04 November 2010 06:08:55 PM )
//
======================================================================
// Master Event Clock
// ======================================================================
wire [15:0] MclkDiv;
wire Mclk, MclkRise, MclkFall;
ClockGen MCLK (
.Q(Mclk), .Rise(MclkRise), .Fall(MclkFall),
.ClkDiv(MclkDiv), .rst(rst), .clk(clk)
);
The Clock Generator Module produces a square wave output at a frequency that
is a even integer divisor of the frequency of clk
(which
should be the system clock) . While is it possible to then send this clock to a
global clock buffer (since it is a registered signal and not a logic-gated
clock), the overall philosophy of the Drive Electronics is for all logic to be
fully synchronous with the system clock. To support this philosophy, the clock
generator not only produces the clock signal itself, but also Rise and Fall
pulses that signal when the clock edges will occur. In short, if the
Rise
signal is asserted, then the Q
output of the
generator will transition from LO to HI on the next rising edge of the system
clock. Conversely, if the Fall
output is asserted, the
Q
output will transition from HI to LO on the next rising edge.
The frequency of the clock can be controlled via the value of ClkDiv
,
which is a 16-bit value. If F(clk) is the frequency of the system clock, the F(Q),
the frequency of the output clock, is given by:
F(Q) = F(clk)/[2*(ClkDiv + 1)]
With a 16-bit value, this means that all even divisors from 2 through 131,072 are achievable. For a 50 MHz system clock, this translates into Mclk frequencies from 25 MHz down to about 381 Hz.
In the nominal DE248 implementation, the ClkDiv
value is
programmed via two HOST registers; the lower byte is assigned to HR2E while the
upper byte is assigned to HR2F.
Other modules that are intended to work with this clock have a clkR
and/or a clkF
input. To have these modules behave as though
they were being clocked by Mclk
, simply apply the
MclkRise
and/or MclkFall
signals to these inputs,
respectively. If a module only has a clkR
input (i.e., no
clkF
input) then it is possible to run the logic in that module
at the full system clock rate by tying clkR
HI. Note that
this should be done only if no modules in the associated logic have a
clkF
input. The reason is that all modules are internally synchronous
with the rising edge of the system clock and so events that are synchronous with
the falling edge of Mclk
(and hence require a clkF
input) cannot me made to function at the full system clock speed.
// The output
frequency of the Clock Generator is F(clk)/(2*(ClkDiv+1)).
// where F(clk)
is the frequency of the 'clk' signal.
// All even
divisors from 2 to 131,072 are possible.
module
ClockGen(Q, Rise, Fall, ClkDiv, rst, clk);
output Q;
// Clock Output
output Rise;
// HI when Q will rise on next rising clk edge
output Fall;
// HI when Q will fall on next rising clk edge
input [15:0] ClkDiv; // Clock Divider Value
input rst, clk;
wire Q_reg, Tick;
PulseGen16 CLKGEN (.Q(Tick), .Period(ClkDiv), .en(HI), .rst(rst),
.clk(clk));
DFFRen MCLK (.Q(Q_reg), .D(~Q_reg), .en(Tick), .rst(rst), .clk(clk));
assign Rise = ((Tick == HI)&&(Q_reg == LO));
assign Fall = ((Tick == HI)&&(Q_reg == HI));
endmodule
The PulseGen16 module produces output pulses that are one system clock period in duration every (ClkDiv + 1) system clocks. These 'tick' pulses are then used to enable a D-type Flip Flop configured as a T-type Flip Flop - in other words, the output of the flip flop toggles, synchronously with the rising edge of the system clock, each time it received an enabling tick pulse.
The Rise
and Fall
signals are simply the tick pulses gated by the present state of the flip flop
so as to indicate whether the pulse will cause the flip flop's output to rise or
fall on the next rising clock edge.