|
|
`include "defines.v"
|
`include "defines.v"
|
|
|
module odd(clk, out, N, reset, enable);
|
module odd(clk, out, N, reset, enable);
|
|
|
input clk; // slow clock
|
input clk; // slow clock
|
output out; // fast output clock
|
output out; // fast output clock
|
input [`SIZE-1:0] N; // division factor
|
input [`SIZE-1:0] N; // division factor
|
input reset; // synchronous reset
|
input reset; // synchronous reset
|
input enable; // odd enable
|
input enable; // odd enable
|
|
|
reg [`SIZE-1:0] counter; // these 2 counters are used
|
reg [`SIZE-1:0] counter; // these 2 counters are used
|
reg [`SIZE-1:0] counter2; // to non-overlapping signals
|
reg [`SIZE-1:0] counter2; // to non-overlapping signals
|
reg out_counter; // positive edge triggered counter
|
reg out_counter; // positive edge triggered counter
|
reg out_counter2; // negative edge triggered counter
|
reg out_counter2; // negative edge triggered counter
|
reg rst_pulse; // pulse generated when vector N changes
|
reg rst_pulse; // pulse generated when vector N changes
|
reg [`SIZE-1:0] old_N; // gets set to old N when N is changed
|
reg [`SIZE-1:0] old_N; // gets set to old N when N is changed
|
wire not_zero; // if !not_zero, we devide by 1
|
wire not_zero; // if !not_zero, we devide by 1
|
|
|
assign out = out_counter2 ^ out_counter; // xor to generate 50% duty, half-period
|
assign out = out_counter2 ^ out_counter; // xor to generate 50% duty, half-period
|
// waves of final output
|
// waves of final output
|
// positive edge counter/divider
|
// positive edge counter/divider
|
always @(posedge clk)
|
always @(posedge clk)
|
begin
|
begin
|
if(reset | rst_pulse)
|
if(reset | rst_pulse)
|
begin
|
begin
|
counter <= N;
|
counter <= N;
|
out_counter <= 1;
|
out_counter <= 1;
|
end
|
end
|
else if (enable)
|
else if (enable)
|
begin
|
begin
|
if(counter == 1)
|
if(counter == 1)
|
begin
|
begin
|
counter <= N;
|
counter <= N;
|
out_counter <= ~out_counter;
|
out_counter <= ~out_counter;
|
end
|
end
|
else
|
else
|
begin
|
begin
|
counter <= counter-1;
|
counter <= counter - 1'b1;
|
end
|
end
|
end
|
end
|
end
|
end
|
|
|
reg [`SIZE-1:0] initial_begin; // this is used to offset the negative edge counter
|
reg [`SIZE-1:0] initial_begin; // this is used to offset the negative edge counter
|
wire [`SIZE:0] interm_3; // from the positive edge counter in order to
|
wire [`SIZE:0] interm_3; // from the positive edge counter in order to
|
assign interm_3 = {1'b0,N} + 3; // guarante 50% duty cycle.
|
assign interm_3 = {1'b0,N} + 2'b11; // guarante 50% duty cycle.
|
|
|
// counter driven by negative edge of clock.
|
// counter driven by negative edge of clock.
|
always @(negedge clk)
|
always @(negedge clk)
|
begin
|
begin
|
if(reset | rst_pulse) // reset the counter at system reset
|
if(reset | rst_pulse) // reset the counter at system reset
|
begin // or change of N.
|
begin // or change of N.
|
counter2 <= N;
|
counter2 <= N;
|
initial_begin <= interm_3[`SIZE:1];
|
initial_begin <= interm_3[`SIZE:1];
|
out_counter2 <= 1;
|
out_counter2 <= 1;
|
end
|
end
|
else if(initial_begin <= 1 && enable) // Do normal logic after odd calibration.
|
else if(initial_begin <= 1 && enable) // Do normal logic after odd calibration.
|
begin // This is the same as the even counter.
|
begin // This is the same as the even counter.
|
if(counter2 == 1)
|
if(counter2 == 1)
|
begin
|
begin
|
counter2 <= N;
|
counter2 <= N;
|
out_counter2 <= ~out_counter2;
|
out_counter2 <= ~out_counter2;
|
end
|
end
|
else
|
else
|
begin
|
begin
|
counter2 <= counter2-1;
|
counter2 <= counter2 - 1'b1;
|
end
|
end
|
end
|
end
|
else if(enable)
|
else if(enable)
|
begin
|
begin
|
initial_begin <= initial_begin - 1;
|
initial_begin <= initial_begin - 1'b1;
|
end
|
end
|
end
|
end
|
|
|
//
|
//
|
// reset pulse generator:
|
// reset pulse generator:
|
// __ __ __ __ _
|
// __ __ __ __ _
|
// clk: __/ \__/ \__/ \__/ \__/
|
// clk: __/ \__/ \__/ \__/ \__/
|
// _ __________________________
|
// _ __________________________
|
// N: _X__________________________
|
// N: _X__________________________
|
// _____
|
// _____
|
// rst_pulse: __/ \___________________
|
// rst_pulse: __/ \___________________
|
//
|
//
|
// This block generates an internal reset for the odd divider in the
|
// This block generates an internal reset for the odd divider in the
|
// form of a single pulse signal when the odd divider is enabled.
|
// form of a single pulse signal when the odd divider is enabled.
|
always @(posedge clk or posedge reset)
|
always @(posedge clk or posedge reset)
|
begin
|
begin
|
if(reset)
|
if(reset)
|
begin
|
begin
|
rst_pulse <= 0;
|
rst_pulse <= 0;
|
end
|
end
|
else if(enable)
|
else if(enable)
|
begin
|
begin
|
if(N != old_N) // pulse when reset changes
|
if(N != old_N) // pulse when reset changes
|
begin
|
begin
|
rst_pulse <= 1;
|
rst_pulse <= 1;
|
end
|
end
|
else
|
else
|
begin
|
begin
|
rst_pulse <= 0;
|
rst_pulse <= 0;
|
end
|
end
|
end
|
end
|
|
end
|
|
|
|
always @(posedge clk)
|
|
begin
|
old_N <= N; // always save the old N value to guarante reset from
|
old_N <= N; // always save the old N value to guarante reset from
|
end // an even-to-odd transition.
|
end // an even-to-odd transition.
|
|
|
endmodule //odd
|
endmodule //odd
|
|
|