版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/u012369580/article/details/85311876
从 基于片上时钟的速测试电路的设计 这个文章里面看到了下面这个图
前四个shift_reg[0]-shift_reg[3]作为synchonizer
shift_reg[4]作为launch clock enable,脉冲宽度为一个pll clk,
因为shift_reg[4] & !shift_reg[5]
shift_reg[5]作为 capture clock enable,脉冲宽度为一个pll clk
尝试写了一个简化版的verilog model, 并作了简单的仿真
`timescale 1ps/1ps
module occ (//input
scan_en,pll_clk,ate_clk,pll_bypass,rst_n,
//output
pll_clk_g
);
input scan_en;
input pll_clk;
input ate_clk;
input pll_bypass;
//
input rst_n;
output pll_clk_g;
//shift reg
reg [5:0] shift_reg;
reg at_spd_en_p;
always @(posedge pll_clk or negedge rst_n) begin
if (~rst_n)
shift_reg <= #1 6'b0;
else
shift_reg <= #1 {shift_reg[4:0],~scan_en};
end
// reg0/1 for synchronizing the scan_en while reg2/3/4 used for generating occ clock
// gating check between shift_reg[*] and pll_clk
// delay pll_clk
// wire #2 pll_clk_dly = pll_clk;
// wire launch_en = pll_clk_dly&shift_reg[2]&~shift_reg[3];
// wire capture_en = pll_clk_dly&shift_reg[3]&~shift_reg[4];
wire launch_en = shift_reg[2]&~shift_reg[3];
wire capture_en = shift_reg[3]&~shift_reg[4];
//
wire launch_clk_g;
wire capture_clk_g;
icg_user icg_launch(//input
.EN(launch_en),//clock gater enable
.CLK(pll_clk),// source clock
.GCLK(launch_clk_g));
icg_user icg_capture(//input
.EN(capture_en),//clock gater enable
.CLK(pll_clk),// source clock
.GCLK(capture_clk_g));
wire at_speed_en = launch_en|capture_en;
//wire at_speed_en = launch_clk_g||capture_clk_g;
always @(negedge pll_clk or negedge rst_n) begin
if (~rst_n)
at_spd_en_p <= 1'b0;
else
at_spd_en_p <= at_speed_en ;
end
// generation of at speed clock
wire at_spd_clk = at_spd_en_p? pll_clk:1'b0;
// test mode
wire internal_clk = scan_en ? ate_clk:at_spd_clk;
//
endmodule
其中,icg_user 即 clock gating cell;
仿真波形