我想构建一个 Verilog 模块,以便用户可以通过模块参数选择某些输入时钟信号的灵敏度。作为示例,我编写了以下计数器,它可以根据参数 clockEdge
选择的 posedge 或 negedge 进行计数。
module Counter (clk, reset, value);
parameter clockEdge = 1; // react to rising edge by default
input clk;
input reset;
output reg [7:0] value;
generate
if(clockEdge == 1) begin
always @(posedge clk or posedge reset) begin
if (reset) begin
value <= 0;
end else begin
value <= value + 1;
end
end
end else begin
always @(negedge clk or posedge reset) begin
if (reset) begin
value <= 0;
end else begin
value <= value + 1;
end
end
end
endgenerate
endmodule
这个原则是有效的,但我不喜欢这两种变体的实现基本上都是复制和粘贴。什么是没有重复的更短版本?
最佳答案
最简单的方法是用异或门反转时钟。然后在 always 部分使用该时钟:
wire user_clock;
assign user_clock = clk ^ falling_edge;
always @(posedge user_clock) // or posedge/negedge reset/_n etc.
test_signal <= ~ test_signal;
如果 falling_edge
为 0,则 user_clock 和 clk 具有相同的极性,并且数据的时钟几乎与 clk 的上升沿同时出现。
如果 falling_edge
为 1,则 user_clock 和 clk 具有相反的极性,数据的计时时间几乎与 clk 的下降沿相同。
更改 falling_edge
的极性时要小心,因为它会产生欠幅时钟脉冲!最安全的是使用门控时钟:停止时钟,切换极性,然后重新启动。
在这两种情况下,user_clock 都会稍微滞后系统时钟。数量取决于异或门的延迟。 这是一个模拟+:
+test_signal 在初始语句中设置为零。
关于verilog - 从模块参数中选择 posedge/negedge 灵敏度的最短版本?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49998405/