SystemVerilog可以表示具有异步设置和复位的触发器而无需添加不可合成的代码吗?

时间:2013-09-05 16:09:26

标签: hardware verilog system-verilog hdl flip-flop

我来自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中有一种直接的方法吗?

5 个答案:

答案 0 :(得分:4)

最好避免使用具有多个异步控件的触发器。确保它们正常运行所需的时序检查很复杂,容易搞砸。如果你真的需要使用它们,那么最好在需要时手动实例化它们。如果您让综合工具推断它们,它可能会在您不想要的地方使用它们,这会增加定时检查无法正确完成的风险。

最后一点,如果复位的有效边沿时间为0并且在触发器初始化为x之前模拟,并且时钟未在运行中,则所有异步触发器都存在类似的模拟 - 合成失配问题。重启。我相信一些模拟器有特殊情况可以确保逻辑没有按此顺序初始化。

也就是说,我很幸运地将优先级逻辑移到了顺序always块之外。注意我使用高电平信号是为了简单起见。

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

答案 1 :(得分:2)

这是我希望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

答案 2 :(得分: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属性相同,所以我认为你运气不好。

答案 3 :(得分: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

答案 4 :(得分:-2)

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

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