我想测量信号的上升转换和下降转换的数量。我使用信号作为时钟并实现了2个计数器。一个计数器在每个上升沿递增,另一个在每个下降沿递增。我正在添加这两个计数器的结果以获得最终计数值。
有没有更好的方法来实现这个逻辑?什么是最强大的方法?
module clock_edge_counter (
clock_edge_count, // Output of the counter ,
clk , // clock Input
stop ,
reset
);
parameter CNTR_WIDTH = 16;
input clk ;
input stop ;
input reset ;
output [CNTR_WIDTH:0] clock_edge_count;
wire [CNTR_WIDTH:0] clock_edge_count;
reg [CNTR_WIDTH-1:0] clock_negedge_edge_count;
reg [CNTR_WIDTH-1:0] clock_posedge_edge_count;
always @(posedge clk or posedge reset)
if (reset) begin
clock_posedge_edge_count <= 0;
end
else if (!stop) begin
clock_posedge_edge_count <= clock_posedge_edge_count + 1;
end
always @(negedge clk or posedge reset)
if (reset) begin
clock_negedge_edge_count <= 0;
end
else if (!stop) begin
clock_negedge_edge_count <= clock_negedge_edge_count + 1;
end
assign clock_edge_count = clock_negedge_edge_count + clock_posedge_edge_count;
endmodule
答案 0 :(得分:3)
这种方法在理论上没有任何错误,但使用信号作为时钟并不是标准做法。这为您的时钟生成引入了逻辑,这对于物理设计或后端流程和工具来说是繁琐的(并非不可能)。
[至少有一个额外的逆变器和输入信号带来的逻辑]
以下链接中的示例 - Proper way for signal edge detection in Verilog
如果信号是异步的并且是从外部模块生成的,您可以同步它,然后使用边沿检测器逻辑。然后使用该输出来触发计数。 https://www.doulos.com/knowhow/fpga/synchronisation/
如果可以访问时钟,那么最好让时钟进入以检测信号的下降沿和上升沿并使用它来计数。 示例代码如下。
module clock_edge_counter (
clock_edge_count, // Output of the counter ,
clk , // clock
detect , // signal to be checked
stop ,
reset
);
parameter CNTR_WIDTH = 16;
input clk ;
input detect;
input stop ;
input reset ;
output [CNTR_WIDTH:0] clock_edge_count;
reg [CNTR_WIDTH:0] clock_edge_count;
reg detect_d;
always @(posedge clk or posedge reset)
begin
if (reset)
detect_d <= 0 ;
else
detect_d <= detect; // delay signal by one cycle
end
always @(posedge clk or posedge reset)
if (reset) begin
clock_edge_count <= 0;
end
// rising edge or falling edge ( xor logic )
else if (!stop && ( (!detect && detect_d ) || (detect && !detect_d ) ) )
begin
clock_edge_count <= clock_edge_count + 1;
end
endmodule
最后,输出(计数器)的使用将在同步块中,因此最好在clock_edge_counter中使用结果块的时钟。