当下一状态组合逻辑块转换中的“当前状态”值时,系统Verilog FSM“下一状态”不转换-三值运算符
在我的Verilog代码中,当下一状态组合逻辑块转换中的“当前状态”值时,系统Verilog FSM“下一状态”不转换-三值运算符,verilog,system-verilog,xilinx,hdl,vivado,Verilog,System Verilog,Xilinx,Hdl,Vivado,在我的Verilog代码中,ns值没有分配给下一状态逻辑中的任何值。当我对下一个状态逻辑进行编码时,每当ps中发生转换时,就为ns状态变量分配一个值 以下是FSM代码片段 // State registers always@(posedge clk, negedge rst) begin if(!rst) ps <= S1; else ps <= ns; end assign present_state = ps;
ns
值没有分配给下一状态逻辑中的任何值。当我对下一个状态逻辑进行编码时,每当ps
中发生转换时,就为ns
状态变量分配一个值
以下是FSM代码片段
// State registers
always@(posedge clk, negedge rst) begin
if(!rst) ps <= S1;
else ps <= ns;
end
assign present_state = ps;
assign next_state = ns;
// Next state logic
always@(ps, start) begin
case(ps)
S1: ns = start ? S2 : S1;
S2: ns = S3;
S3: ns = S1;
//default : ns = S1;
endcase
end
initial begin
#0 rst = 0; start = 0;
#2 rst = 1;
#10 a = 3; b = 4;
#10 start = 1;
最后输出波形
我的意图是为了ps我可能是错的,但我认为您有一个从ns到ns的意外隐含闩锁。因为您注释掉了缺省值,所以当ps不是{S1,S2,S3}中的任何一个时,ns会被锁存回自身。在模拟开始时处理这些块的顺序可能会改变,因此这可能就是为什么ns开始时为X
由于ns以X开头,这就解释了为什么X在第一个上升时钟边缘上的门是ps而不是reset;从这里开始,ps将不匹配(因为您使用了case而不是casex),并且两者都将保持X,就像您在这里看到的那样
我认为解决这个问题的最简单方法是在case语句中指定默认值,使ns不是闩锁
(使用always\u ff和always\u comb可以让编译器帮助警告您类似的事情)感谢您的回复,我已经找到了原因。它是三元运算符()?x:y代码>冒号,未正确括起,导致编译器错误地推断三元运算符()?x:y代码>冒号是的大小写。。。endcase
冒号。我通过使用if-else
语句来避免歧义,从而解决了这个问题。我想三元运算符()?x:y如果写得恰当,code>可以用在case
语句中,但我只是用if-else
语句来避免歧义
// Next state logic
always@(ps, start) begin
case(ps)
//S1: begin ns = (start ? S2 : S1); end // old code
S1: begin if(start) ns = S2; else ns = S1; end // new code
S2: ns = S3;
S3: ns = S4;
S4: ns = S1;
//default : ns = S1;
endcase
end
这看起来有点奇怪。根据您的V95代码片段,ns的值应该在ps更新后不久发生更改。还有一些事情正在进行,你需要提供完整的复制机。顺便说一句,如果你在标签中有系统verilog,为什么不使用它呢。