pluto_hdl_adi/library/ip_pid_controller/hdl/xlclockdriver_rd.v

190 lines
5.2 KiB
Verilog

//-----------------------------------------------------------------
//
// Filename : xlclockdriver.v
//
// Date : 6/29/2004
//
// Description : Verilog description of a clock enable generator block.
// This code is synthesizable.
//
// Assumptions : period >= 1
//
// Mod. History : Translated VHDL clockdriver to Verilog
// : Added pipeline registers
//
// Mod. Dates : 6/29/2004
// : 12/14/2004
//
//-------------------------------------------------------------------
`timescale 1 ns / 10 ps
module xlclockdriver (sysclk, sysclr, sysce, clk, clr, ce, ce_logic);
parameter signed [31:0] log_2_period = 1;
parameter signed [31:0] period = 2;
parameter signed [31:0] use_bufg = 1'b0;
parameter signed [31:0] pipeline_regs = 5;
input sysclk;
input sysclr;
input sysce;
output clk;
output clr;
output ce;
output ce_logic;
//A maximum value of 8 would allow register balancing to the tune of 10^8
//It is set to 8 since we do not have more than 10^8 nets in an FPGA
parameter signed [31:0] max_pipeline_regs = 8;
//Check if requested pipeline regs are greater than the max amount
parameter signed [31:0] num_pipeline_regs = (max_pipeline_regs > pipeline_regs)? pipeline_regs : max_pipeline_regs;
parameter signed [31:0] factor = num_pipeline_regs/period;
parameter signed [31:0] rem_pipeline_regs = num_pipeline_regs - (period * factor) + 1;
//Old constant values
parameter [log_2_period-1:0] trunc_period = ~period + 1;
parameter signed [31:0] period_floor = (period>2)? period : 2;
parameter signed [31:0] power_of_2_counter = (trunc_period == period) ? 1 : 0;
parameter signed [31:0] cnt_width = (power_of_2_counter & (log_2_period>1)) ? (log_2_period - 1) : log_2_period;
parameter [cnt_width-1:0] clk_for_ce_pulse_minus1 = period_floor-2;
parameter [cnt_width-1:0] clk_for_ce_pulse_minus2 = (period-3>0)? period-3 : 0;
parameter [cnt_width-1:0] clk_for_ce_pulse_minus_regs = ((period-rem_pipeline_regs)>0)? (period-rem_pipeline_regs) : 0;
reg [cnt_width-1:0] clk_num;
reg temp_ce_vec;
wire [num_pipeline_regs:0] ce_vec;
wire [num_pipeline_regs:0] ce_vec_logic;
wire internal_ce;
wire internal_ce_logic;
reg cnt_clr;
wire cnt_clr_dly;
genvar index;
initial
begin
clk_num = 'b0;
end
assign clk = sysclk ;
assign clr = sysclr ;
// Clock Number Counter
always @(posedge sysclk)
begin : cntr_gen
if (sysce == 1'b1)
begin:hc
if ((cnt_clr_dly == 1'b1) || (sysclr == 1'b1))
begin:u1
clk_num = {cnt_width{1'b0}};
end
else
begin:u2
clk_num = clk_num + 1 ;
end
end
end
// Clear logic for counter
generate
if (power_of_2_counter == 1)
begin:clr_gen_p2
always @(sysclr)
begin:u1
cnt_clr = sysclr;
end
end
endgenerate
generate
if (power_of_2_counter == 0)
begin:clr_gen
always @(clk_num or sysclr)
begin:u1
if ( (clk_num == clk_for_ce_pulse_minus1) | (sysclr == 1'b1) )
begin:u2
cnt_clr = 1'b1 ;
end
else
begin:u3
cnt_clr = 1'b0 ;
end
end
end // block: clr_gen
endgenerate
synth_reg_w_init #(1, 0, 'b0000, 1)
clr_reg(.i(cnt_clr),
.ce(sysce),
.clr(sysclr),
.clk(sysclk),
.o(cnt_clr_dly));
//Clock Enable Generation
generate
if (period > 1)
begin:pipelined_ce
always @(clk_num)
begin:np_ce_gen
if (clk_num == clk_for_ce_pulse_minus_regs)
begin
temp_ce_vec = 1'b1 ;
end
else
begin
temp_ce_vec = 1'b0 ;
end
end
for(index=0; index<num_pipeline_regs; index=index+1)
begin:ce_pipeline
synth_reg_w_init #(1, ((((index+1)%period)>0)?0:1), 1'b0, 1)
ce_reg(.i(ce_vec[index+1]),
.ce(sysce),
.clr(sysclr),
.clk(sysclk),
.o(ce_vec[index]));
end //block ce_pipeline
for(index=0; index<num_pipeline_regs; index=index+1)
begin:ce_pipeline_logic
synth_reg_w_init #(1, ((((index+1)%period)>0)?0:1), 1'b0, 1)
ce_reg_logic(.i(ce_vec_logic[index+1]),
.ce(sysce),
.clr(sysclr),
.clk(sysclk),
.o(ce_vec_logic[index]));
end //block ce_pipeline
assign ce_vec_logic[num_pipeline_regs] = temp_ce_vec;
assign ce_vec[num_pipeline_regs] = temp_ce_vec;
assign internal_ce = ce_vec[0];
assign internal_ce_logic = ce_vec_logic[0];
end // block: pipelined_ce
endgenerate
generate
if (period > 1)
begin:period_greater_than_1
if (use_bufg == 1'b1)
begin:use_bufg
BUFG ce_bufg_inst(.I(internal_ce), .O(ce));
BUFG ce_logic_bufg_inst(.I(internal_ce_logic), .O(ce_logic));
end
else
begin:no_bufg
assign ce = internal_ce;
assign ce_logic = internal_ce_logic;
end
end
endgenerate
generate
if (period == 1)
begin:period_1
assign ce = sysce;
assign ce_logic = sysce;
end
endgenerate
endmodule