Ano*_*ous 5 verilog clock fpga
设计要求在时钟的上升沿在特定情况下激活信号,并在时钟的下降沿在另一情况下停用.这就是我的想法:
always@(posedge CLK) begin
signal1 <= 1'b0; // reset flag
if(circumstance1) signal1 <=1'b1; // raise flag if circumstance occurs
end
always@(negedge CLK) begin
signal2 <= 1'b1; // reset flag (actually set alternate to signal1)
if(circumstance2) signal2 <=1'b0; // raise flag if circumstance occurs
end
always@(posedge signal1 or negedge signal2) begin
if(signal1) outsignal <= 1'b0; // activate outsignal
else outsignal <= 1'n1; // deactivate outsignal
end
Run Code Online (Sandbox Code Playgroud)
那会有用吗?是否有更好的选择(加倍时钟和捕捉单边不是一个选项).
罗素回复后编辑.拉塞尔,我想你提出以下建议:
wire nCLK = ~CLK;
always@(posedge CLK or posedge nCLK or negedge nRESET) begin
if(!nRESET) outsignal <= 1'b0;
else if(nCLK) outsignal <= 1'b1;
else outsignal <= 1'b0;
end
Run Code Online (Sandbox Code Playgroud)
我理解你了吗?
您需要所谓的“双边缘触发器”(DEFF)。尽管一些供应商在其 CPLD/FPGA 上提供 DEFF 作为原语,但大多数产品都没有。在这种情况下,您需要自己实现 DEFF。不幸的是,您帖子中的代码always@(posedge CLK or posedge nCLK or negedge nRESET)将无法工作,因为标准触发器的单边沿事件输入不超过两个。因此,该解决方案必须使用带有附加组合电路的标准触发器。图中的电路解决了这个问题。它保证了无故障操作,因为输出 XOR 元件在每次状态更改时仅具有单个输入转换。
下面是在我们的项目中验证并使用的实现此 DEFF 的 Verilog 代码:
module DEFF (
input clock, reset, in,
output out
);
reg trig1, trig2;
assign out = trig1^trig2;
always @(posedge clock, posedge reset) begin
if (reset) trig1 <= 0;
else trig1 <= in^trig2;
end
always @(negedge clock, posedge reset) begin
if (reset) trig2 <= 0;
else trig2 <= in^trig1;
end
endmodule
Run Code Online (Sandbox Code Playgroud)
这是片外信号吗?如果是这样,Xilinx 和其他芯片供应商提供的原语可以帮助您解决此问题。如果您连接 ODDR2 原语,您可能会有更好的运气。反转时钟。将正常时钟驱动到 C0,将反相时钟驱动到 C1。然后使用您的逻辑设置 D0 和 D1 输入。
您上面写的方式不是一个非常可靠的解决方案。
尝试使用结构基元来完成此任务。