我来自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中有一种直接的方法吗?
答案 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用于组合逻辑