Verilog 从模块参数选择posedge/negedge灵敏度的最短版本?
我想建立一个Verilog模块,这样用户就可以通过模块参数选择一些输入时钟信号的灵敏度。作为一个例子,我编写了以下计数器,它可以在参数Verilog 从模块参数选择posedge/negedge灵敏度的最短版本?,verilog,Verilog,我想建立一个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; gene
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
模块计数器(时钟、复位、值);
参数clockEdge=1;//默认情况下对上升沿作出反应
输入时钟;
输入复位;
输出reg[7:0]值;
生成
如果(时钟边缘==1)开始
始终@(posedge clk或posedge重置)开始
如果(重置)开始
value实现clk的posedge或NEGDEDGE之后的自定义时钟reg可能是一种方法。这似乎在我的机器上运行良好:)
reg myclk;
始终@(clk)开始
如果(时钟)开始
myclk=时钟边缘?1 : 0; #1 myclk=0;
结束,否则开始
myclk=时钟边缘?0 : 1; #1 myclk=0;
结束
结束
始终@(posedge myclk或posedge重置)开始
如果(重置)
cnt最简单的方法是使用exor门反转时钟。然后在“始终”部分中使用该时钟:
wire user_clock;
assign user_clock = clk ^ falling_edge;
always @(posedge user_clock) // or posedge/negedge reset/_n etc.
test_signal <= ~ test_signal;
有线用户时钟;
分配用户时钟=时钟下降沿;
始终@(posedge用户时钟)//或posedge/NEGFEDGE重置/\n等。
test_signal我认为这个小例子中的cut-n-paste是可以的,尽管verilog有一些工具使它更容易处理更复杂的情况,即函数和宏。你也可以使用它们,即
function newValue(input reset, input reg[7:0] oldValue);
if (reset) begin
newValue = 0;
end else begin
newValue = value + 1;
end
endfunction
generate
if(clockEdge == 1) begin
always @(posedge clk or posedge reset) begin
value <= newValue(reset, value);
end
end else begin
always @(negedge clk or posedge reset) begin
value <= newValue(reset, value);
end
end
endgenerate
功能新值(输入复位,输入reg[7:0]旧值);
如果(重置)开始
newValue=0;
结束,否则开始
newValue=value+1;
结束
端功能
生成
如果(时钟边缘==1)开始
始终@(posedge clk或posedge重置)开始
值正如我的问题所说,时钟选择由模块参数控制。所以我要求一个解决方案,它在编译时控制这种行为,而不是作为电路的一部分。因此,一个额外的门是不可接受的,尽管它可能会被合成优化掉。你所要做的就是把下降沿
作为一个参数。大门将被优化掉。如果在设计中使用posedge和NEGDEDGE,您永远不知道是否添加了门延迟。e、 g.您的库可能只有posedge FFs,在这种情况下,您将在时钟线或正负时钟树中使用反相器。在所有情况下,合成工具都会意识到这一点,并调整您的计时。如果你的设计不能复制一个反相器的时钟偏差,你就有一个大问题。你的答案意味着使用门控时钟。这意味着额外的传播延迟被添加到时钟路径,这在时序方面是有问题的。
function newValue(input reset, input reg[7:0] oldValue);
if (reset) begin
newValue = 0;
end else begin
newValue = value + 1;
end
endfunction
generate
if(clockEdge == 1) begin
always @(posedge clk or posedge reset) begin
value <= newValue(reset, value);
end
end else begin
always @(negedge clk or posedge reset) begin
value <= newValue(reset, value);
end
end
endgenerate
`define NEW_VALUE(clk_edge) \
always @(clk_edge clk or posedge reset) begin\
if (reset) begin\
value <= 0;\
end else begin\
value <= value + 1;\
end\
end
generate
if(clockEdge == 1) begin
`NEW_VALUE(posedge)
end else begin
`NEW_VALUE(negedge)
end
endgenerate