SUPPORT: PULSE GENERATOR MODULES
(Last Modified: 04 November 2010 06:09:13 PM )
Since this is general purpose module, the following are just typical-use instantiation templates.
pulse_gen_8 inst_name (.q(),
.period(), .en(HI), .rst(rst), .clk(clk));
pulse_gen_16 inst_name (.q(), .period(), .en(HI), .rst(rst),
.clk(clk));
pulse_gen_24 inst_name (.q(), .period(), .en(HI), .rst(rst),
.clk(clk));
The modules in this family produce an output pulse that is nominally one master clock cycle in duration every N+1 master clock cycles where the allowable values of N range from 0 to 2s-1 where s is the size of the generator. Presently the values of s are {8,16,24}.
Each module also has a count enable input which gates both the internal counter and the pulse output logic. As a result, the counter only decrements when the generator is enabled and its output pulse is only high both when the internal counter is zero and the generator is enabled. However, it should be kept in mind that the output pulse is a registered signal and hence will have a one clock cycle latency relative to the logic that generates it.
If the period is set to zero, then the output will track the enable input (with a one master clock latency).
If the period is N (with N non-zero) and the enable is held HI, then the output will produce a pulse every (N+1)th master clock cycle that is one master clock cycle in duration.
If the period is N (with N non-zero) and the enable is HI once every M master clocks, then the output will produce a pulse every M*(N+1)th master clock cycle that is one master clock cycle in duration.
It should be noted that, following a reset (which is asynchronous) that an output pulse will be immediately produced the next time the module is enabled.
module
pulse_gen_8(q, period, en, rst, clk);
output q;
input [7:0] period;
input en, rst, clk;
parameter hi = 1'b1, lo = 1'b0;
parameter zero = 8'd0;
wire d;
reg [7:0] count, new_count;
assign d = ((count == zero)&&(en = hi))? hi : lo;
dffr_en dff (.q(q), .d(d), .en(hi), .rst(rst), .clk(clk));
always @(posedge clk or posedge rst)
begin
if (rst == hi)
count <=
zero;
else
count <=
new_count;
end
always @(count or period or en)
begin
if (en == hi)
if (count ==
zero)
new_count <= period;
else
new_count <= count - 1;
else
new_count <=
count;
end
endmodule
The first thing to note is that the only difference between the
modules of different sizes are in the widths of period
,
count
, and new_count
as well as the
zero
parameter.
output
q;
input [7:0] period;
input en, rst, clk;
parameter hi = 1'b1, lo = 1'b0;
parameter zero = 8'd0;
wire d;
reg [7:0] count, new_count;
The remainder of the module code is identical for all variants.
The output of the module is controlled by the following statements.
assign d = ((count == zero)&&(en =
hi))? hi : lo;
dffr_en dff (.q(q), .d(d), .en(hi), .rst(rst), .clk(clk));
The value of d
is HI only when both the
module is enabled and
count
is zero. The output, q
, is a
registered copy of d
which is asynchronously reset by
rst
, as is
count
itself. This results in a one-master-clock latency in the
output and also the behavior that, after a reset, the output will go HI the next
time the module is enabled.
The remainder of the module code is nothing more than a typical enable-able down counter
always @(posedge clk or posedge rst)
begin
if (rst == hi)
count <=
zero;
else
count <=
new_count;
end
always @(count or period or en)
begin
if (en == hi)
if (count ==
zero)
new_count <= period;
else
new_count <= count - 1;
else
new_count <=
count;
end
Under the special case that the period is equal to zero, the counter will remain stalled at a value of zero and the output will be a copy of the enable input delayed by one master clock period. If the module is constantly enabled, then this means that the module will produce a constant HI output.