May 2, 2011, 11:43 p.m.

posted by nfrank

## Clock Generation and SynchronizationClocks are the main synchronizing signals to which all other signals reference. In a majority of situations, clock waveforms are deterministic and periodic. Therefore, if you know how to write RTL code for one period, the complete waveform can be generated by embedding the one period inside a loop. To create one period of clock, there are two methods: explicit and toggle. With the explicit method, you specify rising and falling times of the clock and assign a value to it at each of the transition times. With the toggle method, you also specify rising and falling times of the clock, but invert the clock at the transition times. ## Explicit and Toggle MethodsConsider generating the clock waveform in Figure. First, one period of a clock is generated. Using the explicit method, one period of clock has the RTL codes #1 clock = 1'b1; #1 clock = 1'b0; #2 clock = 1'b1; #2 clock = 1'b0; ## 6. Generating a clock signal
The delays before the assignments are delay intervals between successive transitions. Putting this period inside a loop and initializing the clock produces the complete waveform, as shown here: initial clock = 1'b0; always begin #1 clock = 1'b1; #1 clock = 1'b0; #2 clock = 1'b1; #2 clock = 1'b0; end The same clock waveform can also be generated using the toggle method: initial clock = 1'b0; always begin #1 clock = ~clock; // rising #1 clock = ~clock; // falling #2 clock = ~clock; // rising #2 clock = ~clock; // falling end This toggle method can be difficult to see the value of Note that we used blocking assignment operator ## Absolute Transition DelayIn the previous example, the delays are interval delays between successive transitions, and there are situations when absolute transition times are desired. To do so, nonblocking intraassignment delay can be used. The following code representing the waveform shown in Figure uses nonblocking intraassignment delays: initial begin clock <= #0 1'b0; clock <= #1 1'b1; clock <= #2 1'b0; clock <= #4 1'b1; clock <= #6 1'b0; clock <= #7 1'b1; ... end Statement Because the delays are absolute transition times, all transitions have to be explicitly specified, as opposed to embedding one period in a loop. Hence, generating waveforms using absolute times is used only for aperiodic waveforms such as reset signals. It's important to note that if the nonblocking assignments are replaced by blocking assignments, the next statement must wait until the current statement is executed, meaning the delays now have become interval delays. ## Time Zero Clock TransitionSimilar to the time zero initialization problem, the very first transition of ## Time Unit and ResolutionDuring verification, the clock period or duty cycle may change. It is beneficial to use parameters to represent the delays, instead of hard coding them. For example, to generate a clock starting with zero that has a 50% duty cycle, one may code as follows: define PERIOD 4 initial clock = 1'b0; always #('PERIOD/2) clock = ~clock; Caution should be exercised when In Verilog, the unit for delay (for example, #3) is specified using 'timescale unit/resolution where ## Clock Multiplier and DividerA complex chip often uses multiple clocks generated from a phase lock loop (PLL) block. The analog behavior of PLL is not modeled in HDL, but is abstracted to generate clock waveforms using delays and assigns. When multiple clock waveforms are generated, their relationship needs to be determined (for example, whether their transitions are independent, whether some clocks are derived from others). A clock can be derived from another via a frequency divider or multiplier. If the frequency ratio is an integer, it is easy to generate a derived clock from the base clock. For frequency division, the derived clock can be generated from base clock without knowing the base clock's frequency. To divide initial i = 0; always @( base_clock ) begin i = i % N; if (i == 0) derived_clock = ~derived_clock; i = i + 1; end Multiplying a clock frequency by N can be achieved using Verilog's always @(posedge base_clock) begin repeat (2N) clock = #(period/(2N)) ~clock; end If the period of the base clock is not known or is changing constantly, and/or the ratio is not an integer, a different technique is required. First, the base clock's period is measured on the fly and then the derived clock is generated using forever clock = #(period/(2N)) ~clock; A sample code to implement this general clock divider/multiplier is as follows: // measure the first period of base_clock initial begin derived_clock = 1'b0; // assume starting 0 @(posedge base_clock) T1 = $realtime; @(posedge base_clock) T2 = $realtime; period = T2 - T1; T1 = T2; ->start; // start generating derived_clock end // continuously measure base_clock's period always @(start) forever @(posedge base_clock) begin T2 = $realtime; period = T2 - T1; T1 = T2; end // generate derived_clock N times the frequency of base_clock always @(start) forever derived_clock = #(period/(2N)) ~ derived_clock; Make sure that the proper time scale is used so that the division of the period by 2N has the correct precision. ## Clock Independence and JitterIf the clocks are independent, each of them should be modeled with its own initial clock1 = 1'b0; always clock1 = #1 ~clock1; initial clock2 = 1'b0; always clock2 = #2 ~clock2; An incorrect way to produce these two clocks is to use one clock to generate the other, as illustrated here: initial clock1 = 1'b0; always clock1 = #1 ~clock1; initial clock2 = 1'b0; always @ (negedge clock1) clock2 = ~clock2; Although any waveform viewer shows that this set of clocks has the same transitions as the previous set, they are fundamentally different. To emphasize more the relative independence of two clocks, jitter can be introduced to one of the clocks to simulate the nondeterministic relative phase. This can be done with a random generator: ```
initial clock1 = 1'b0;
always clock1 = #1 ~clock1;
jitter = $random(seed) % RANGE;
assign clock1_jittered = #(jitter) clock1;
``` The modulo operator % returns the remainder when divided by ## Clock Synchronization and Delta DelayBecause independent waveforms are not locked in phase, they can drift relative to each other. Jittering models this phase-drifting phenomenon. When two independent waveforms arrive at the same gate, glitches can come and go depending on the input's relative phase, creating intermittent behavior. Therefore, independent waveforms should be first synchronized before propagation. A synchronizer uses a signal, the synchronizing signal, to trigger sampling of another to create a dependency between them, hence removing the uncertainty in their relative phase. The following code is a simple synchronizer. On every transition of signal always (fast_clock) clock_synchronized <= clock1; If the synchronizing signal's transitions do not align with those of the synchronized signal, some transitions will be missed, as shown in Figure. Because transitions will be missed if the synchronizing signal has a lower frequency, the signal with the highest frequency is usually chosen as the synchronizing signal. ## 7. Intermittent glitches and synchronizing independent signals
Because of the nonblocking always @(posedge clock) begin x <= v; y = x; end In the previous synchronizer example, the synchronized signal, ## Clock Generator OrganizationA central clock module generates various clock waveforms from the same clock source. During circuit implementation, the clock source is a PLL, and various clock signals are derived from the PLL output. In RTL, clock generation should be encapsulated as a module with parameters to change clock frequencies, phases, and jitter ranges, among others. A typical block diagram for a clock generation network is shown in Figure. The primary clock source is a simple waveform generator, modeling a PLL. The secondary clock generation block derives clocks of various frequencies and phases with frequency multipliers, dividers, and phase shifters. Frequency, phase, and random distribution are controlled through parameters and variables. Finally, the clock distributor multiplexes the clocks to appropriate clock domains. In RTL, the clock generation network is ## 8. A typical clock generation network
module clock_generation_network (clk1, clk2,...); output clk1, clk2,...; parameter DISTRIBUTION 1; parameter JITTER_RANGE 2; ... primary_clock pc (.clock_src(csrc)); clock_gen cg(.in_clock(csrc),.freq1(freq1),.phase1(.ph1),...); clock_distributor cd (.outclk1(clk1),..., .inclk1(freq1),...); endmodule |

- Comment