Hardware SystemVerilog是否可以表示具有异步设置和重置的触发器,而不添加不可合成的代码?

Hardware SystemVerilog是否可以表示具有异步设置和重置的触发器,而不添加不可合成的代码?,hardware,verilog,system-verilog,hdl,flip-flop,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 是否有一个System

我来自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
是否有一个SystemVerilog构造可以让您在不使用这些额外垃圾的情况下执行此操作?更好的是,在Verilog-95中有没有一种简单的方法可以做到这一点?

试试这个: 始终\u ff@(posedge clk或NEGDEDGE resetb或NEGDEDGE setb)


systemverilog对时钟触发逻辑使用always\u ff,对组合逻辑使用always\u comb这是我希望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
始终\u ff@(posedge clk、NEGDEDGE resetb、NEGDEDGE setb)开始:dff\u asyncRbSb

最好避免使用带有多个异步控制的if(!resetb)q触发器。确保其正常运行所需的定时检查非常复杂,而且容易出错。如果您真的需要使用它们,那么最好在需要的地方手动实例化它们。如果您让合成工具推断它们,它可能会在您不打算的地方使用它们,这会增加计时检查无法正确完成的风险

最后一点,如果复位的活动边在时间零点,并且在触发器初始化为x之前进行了模拟,并且时钟没有在复位中运行,则所有异步触发器都存在类似的模拟合成不匹配问题。我相信一些模拟器有特殊情况,以确保逻辑不是按此顺序初始化的

也就是说,我很幸运地将优先级逻辑移到了sequential
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
分配s_int=s&&!C
始终@(posedge clk或posedge s_int或posedge c)开始
如果(c)

我不知道任何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水平,希望这足以做到这一点 工作。一般来说,不是这样,但是你的例子是唯一的实际案例(I (思考)这会导致问题

VHDL通过具有信号属性来处理此问题,该属性允许您确定 一个信号导致了一个事件。在VHDL中,当任何信号进入 您的敏感度列表发生更改,然后您将其
“事件”
属性检查为 确定他们是否启动了进程。没有混淆,没有posedge或nedge, 这一切都很有效

我刚刚快速查看了SV LRM,SV属性似乎是
与Verilog属性相同,因此我认为您运气不好。

如果没有定义边缘,重置和设置信号的断言和反断言应该能够在模拟中触发此代码

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
始终\u ff@(posedge clk、resetb、setb)开始

如果(!resetb)q,那么这将如何改变行为?如果我们同时断言resetb和setb,然后取消断言setb,posedge setb甚至不会触发模拟,模拟也不会匹配合成,不是吗?always\u ff是否更改always块的语义?我的印象是,它只是有检查,以防止你做某些坏事。当然,一般来说,使用always_ff是个好建议,但这似乎与问题正交。
always_ff @(posedge clk, resetb,  setb) begin 
  if (!resetb)      q <= 0;
  else if (!setb)   q <= 1;
  else              q <= d;
end