验证divider输出的时钟频率

  • 背景: 为了验证divider输出的时钟频率是否是理论值
  • 思路: 通过在同一段时间内对待测时钟和输入时钟计数, 然后检验待测时钟的计数值与输入时钟的计数值的比值关系是否为配置的divider的比例值
  • 方法: 以待测时钟域开始计数, 确定验证时间范围, 这个范围需要考虑2种情况, 一个是偶数个时钟周期, 另一个是奇数个时钟周期, 然后在这段范围内对输入时钟计数, 验证其比例关系
  • 注意: 针对偶数个时钟周期和奇数个时钟周期, 需要变动clk_cnt, 改为奇数的2倍值即可, 然后在period信号发生变化的地方改为奇数值, 最后clk_ref_cnt == (2*(denum+1)/(num+1))里面的2改为设置的奇数值即可.它们的判断条件是一样的.
reg     async_clk_flag;
wire    flexio_ref_clk;  // input clock source
wire    async_clk;       // output clock source
wire    async_clk0;
wire    async_clk1;
assign  flexio_ref_clk = `TOP_SCOPE.pcc_async_ungated_clk[90];
assign  async_clk0 = `TOP_SCOPE.pcc_async_ungated_clk[98];
assign  async_clk1 = `TOP_SCOPE.pcc_async_ungated_clk[99];
assign  async_clk = (SOC_TESTNAME == "flexio_trig_src_async_clock0")? async_clk0 : ((SOC_TESTNAME == "flexio_trig_src_async_clock1") ? async_clk1 : 1'b0);

reg [7:0] clk_cnt;
reg [31:0] clk_ref_cnt;
wire num;
wire [15:0] denum;
assign num = flexio_t_cmd[16];       // flexio_t_cmd[31:0] = 0x00070002, it is transmitted via mailbox from c case, so num=1
assign denum = flexio_t_cmd[15:0];   // denum=2
reg period = 0;

// Test trigger input source: async clock
always @(posedge async_clk or negedge flexio_cmd_get) begin
	if (IS_FLEXIO_PATTERN && flexio_trig_input_async_clock_en) begin
			if(!flexio_cmd_get)
				clk_cnt <= 0;
			else if(clk_cnt < 3)
				clk_cnt <= clk_cnt + 1;
			else
				clk_cnt <= 0;
	end
end

always @(posedge async_clk or negedge flexio_cmd_get) begin
	if (IS_FLEXIO_PATTERN && flexio_trig_input_async_clock_en) begin
			if(!flexio_cmd_get)
				period <= 0;
			else if(clk_cnt < 1)
				period <= 1;
			else 
				period <= 0;
	end
end

// flexio_ref_clk zone
always @(posedge flexio_ref_clk or negedge flexio_cmd_get) begin
	if (IS_FLEXIO_PATTERN && flexio_trig_input_async_clock_en) begin
			if(!flexio_cmd_get)
				clk_ref_cnt <= 0;
			else if(period)
				clk_ref_cnt <= clk_ref_cnt + 1;
			else
				clk_ref_cnt <= 0;
	end
end

property async_clk_assert;
    disable iff(!async_clk_flag)
    @(posedge flexio_ref_clk) $fell(period) |-> ((clk_ref_cnt == (2*(denum+1)/(num+1))));
endproperty

assert property(async_clk_assert) `INFO("The frequency of output async clk is expected!");
                             else `ERROR("Async clock is not correct, need to check!");
  • 波形如下

posted @ 2020-11-04 15:29  乔治是只猪  阅读(218)  评论(0编辑  收藏  举报