7

设计要求在时钟上升沿的特定情况下激活信号,并在时钟下降沿的另一种情况下停用信号。这是我的想法:

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

那会奏效吗?是否有更好的选择(加倍时钟和捕捉单边不是这里的选择)。

在罗素的回复后进行编辑。罗素,我认为您提出以下建议:

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

我理解正确吗?

4

2 回答 2

3

这是片外信号吗?如果是这样,Xilinx 和其他芯片供应商会提供可以帮助您解决此问题的原语。如果你连接一个 ODDR2 原语,你可能会有更好的运气。倒转时钟。将正常时钟驱动到 C0,然后将时钟反转到 C1。然后使用您的逻辑设置 D0 和 D1 输入。

您在上面编写的方式不是一个非常强大的解决方案。

尝试使用结构基元来完成此任务。

于 2013-10-26T15:39:42.400 回答
3

您需要所谓的“双沿触发器”(DEFF)。尽管一些供应商在其 CPLD/FPGA 上提供 DEFF 作为原语,但大多数产品都没有。在这种情况下,您需要自己实现 DEFF。不幸的是,您帖子中的代码always@(posedge CLK or posedge nCLK or negedge nRESET)不起作用,因为标准触发器的输入不超过两个单边沿事件。因此解决方案必须使用带有附加组合电路的标准触发器。图片中的电路解决了这个问题。它保证了无故障操作,因为输出 XOR 元素在每次状态更改时不超过单个输入转换。

DEFF 原理图

这是在我们的项目中验证并使用了实现此 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
于 2018-05-04T09:57:42.573 回答