3

我来自 Verilog-95 背景,我正试图弄清楚我不必再跳过哪些 Verilog-95 箍。

在 Verilog-95 中编写带有异步设置和复位的触发器的明显方法是:

always @(posedge clk or negedge resetb or negedge setb) begin
  if (!resetb)      q <= 0;
  else if (!setb)   q <= 1;
  else              q <= d;
end

这适用于综合。但是,如果我们同时断言 resetb 和 setb,然后在取消断言 setb 之前取消断言 resetb,这在模拟中不起作用,因为这些信号中的任何一个都没有姿势触发。我们需要添加以下内容(取决于您的综合工具),以使模拟与综合相匹配:

// synopsys translate_off
always @(resetb or setb)
  if (resetb && !setb) force q = 1;
  else               release q;
// synopsys translate_on

是否有一个 SystemVerilog 结构可以让您在没有这些额外垃圾的情况下做到这一点?更好的是,在 Verilog-95 中是否有一种直接的方法?

4

5 回答 5

4

Flip-flops with multiple asynchronous controls are best avoided. The timing checks necessary to ensure they function properly are complex and easy to mess up. If you really need to use them, then it's probably best to instantiate them by hand where needed. If you let your synthesis tool infer them, it may use them in places you don't intend, which increases the risk that the timing checks don't get done properly.

One final aside, there is a similar simulation-synthesis mismatch issue with all asynchronous flops, if the active edge of reset is at time zero and is simulated before the flop is initialized to x, and the clock isn't running in reset. I believe some simulators have special cases to ensure the logic is not initialized in this order.

That said, I had luck moving the priority logic outside the sequential always block. Note I'm using active-high signals for simplicity.

assign s_int = s && !c;

always @(posedge clk or posedge s_int or posedge c) begin
        if (c)
                q <= 1'b0;
        else if (s_int)
                q <= 1'b1;
        else
                q <= d;
end
于 2013-09-05T18:35:24.573 回答
3

这是我希望 SystemVerilog 改进的地方。如果您想让两者同时处于低位,请坚持使用当前方法。

另一种选择是创建一个设计规则,说明异步信号不能同时处于活动状态,并通过断言强制执行该规则。假设合成器会忽略断言,因此不需要 translate_off/ on

下面是一个使用内联断言的例子:

always_ff @(posedge clk, negedge resetb, negedge setb) begin : dff_asyncRbSb
  if (!resetb)      q <= 0;
  else if (!setb)   q <= 1;
  else              q <= d;
  asrt_setrst : assert(resetb||setb)
     else $error("resetb and setb can not be low at the same time.");
end : dff_asyncRbSb
于 2013-09-05T18:05:41.340 回答
2

我不知道任何 SV,所以这不是一个答案,但这里的问题是 Verilog(并且,我认为是 SV)事件表达式基本上被破坏了。问题是,当您在事件表达式中有多个条件时:

event_expression ::=
  expression 
  | hierarchical_identifier
  | posedge expression
  | negedge expression
  | event_expression or event_expression
  | event_expression , event_expression

那么就没有万无一失的方法来确定哪个表达式导致了事件,因为您唯一能做的就是检查表达式的当前状态。因此,例如,如果您有@(posedge clk, posedge rst),请查看 clk 和 rst 的当前级别,并希望这足以完成这项工作。一般来说,它不是,但你的例子是唯一导致问题的实际案例(我认为)。

VHDL 通过具有信号属性来处理这个问题,这使您可以确定信号是否引起了事件。在 VHDL 中,当敏感度列表中的任何信号发生变化时,您都会收到一个事件,然后您检查它们的'event属性以确定它们是否触发了该过程。没有混淆,没有姿势或否定,这一切都有效。

我刚刚快速浏览了 SV LRM,SV 属性似乎与 Verilog 属性相同,所以我认为你不走运。

于 2013-09-06T08:48:36.847 回答
0

在没有定义边沿的情况下,复位和设置信号的断言和取消断言应该能够在仿真中触发此代码。

always_ff should be able to create a flop at synthesis.

下面的代码是使用 synopsys VCS 工具编译干净的。

always_ff @(posedge clk, resetb,  setb) begin 
  if (!resetb)      q <= 0;
  else if (!setb)   q <= 1;
  else              q <= d;
end
于 2016-02-18T08:22:57.293 回答
-2

试试这个: always_ff @(posedge clk or negedge resetb or negedge setb)

systemverilog 将 always_ff 用于时钟触发逻辑,将 always_comb 用于组合逻辑

于 2013-09-05T16:38:27.293 回答