本帖最后由 @HDL现场 于 2012-7-25 18:15 编辑
/****************************************
Module name : test_period
Project name : test_period
Description : 检测时钟周期
Property : 范围 时钟为100khz以下,最大2^32 us , 误差为10us (1/100khz(s))
****************************************/
module test_period(
input wire sys_clk, // 100khz
input wire reset,
input wire test_clk, //
output wire [31:0] period_us //输出数据,单位为us
);
/******************低电平计数*********************/
reg [31:0] cnt_l,
cnt_h;
always @(posedge sys_clk)
if(!reset)
cnt_l <= 32'd0;
else if(!test_clk)
cnt_l <= cnt_l + 1'b1;
else
cnt_l <= 32'd0;
reg [31:0] cnt_l_reg;
always @(posedge sys_clk)
cnt_l_reg <= cnt_l;
/******************高电平计数**********************/
always @(posedge sys_clk)
if(!reset)
cnt_h <= 32'd0;
else if(test_clk)
cnt_h <= cnt_h + 1'b1;
else
cnt_h<= 32'd0;
reg [31:0] cnt_h_reg;
always @(posedge sys_clk)
cnt_h_reg <= cnt_h;
/***************检测下降沿*********************/
reg h2l_1,
h2l_2;
always @(posedge sys_clk)
if(!reset)
begin
h2l_1 <= 1'b1;
h2l_2 <= 1'b1;
end
else
begin
h2l_1 <= test_clk;
h2l_2 <= h2l_1;
end
wire h2l = h2l_2 & (!h2l_1);
/**************检测上升沿*******************/
reg l2h_1,
l2h_2;
always @(posedge sys_clk)
if(!reset)
begin
l2h_1 <= 1'b0;
l2h_2 <= 1'b0;
end
else
begin
l2h_1 <= test_clk;
l2h_2 <= l2h_1;
end
wire l2h = l2h_2 & (!l2h_1);
/*****************锁存数据*****************/
reg [31:0] rec_cnt_l,
rec_cnt_h;
always @(posedge clk)
if(!reset)
rec_cnt_l <= 32'd0;
else
if(l2h)
rec_cnt_l <= cnt_l_reg;
else
rec_cnt_l <= rec_cnt_l;
always @(posedge clk)
if(!reset)
rec_cnt_h <= 32'd0;
else
if(h2l)
rec_cnt_h <= cnt_h_reg;
else
rec_cnt_h <= rec_cnt_h;
/************************************************/
wire [32:0] count = rec_cnt_l + rec_cnt_h; // 高低电平相加
wire [31:0] result = count[32:1]; // 结果除以2(左移一位即可)
assign period_us = result;
endmodule |