以下是顺序逻辑中案例的简化示例
always @ (posedge clk or negedge rst_n) begin
if (!rst_n) begin
enable <= 1'b0;
t_A <= 1'b0;
t_B <= 1'b0;
t_C <= 1'b0;
end
else begin
case (nxt_state)
IDLE: begin
enable <= 1'b0;
t_A <= 1'b0;
t_B <= 1'b0;
t_C <= 1'b0;
end
LOAD: begin
enable <= 1'b0;
t_A <= A;
t_B <= B;
t_C <= C;
end
BUSY: begin
enable <= 1'b1;
end
DONE: begin
enable <= 1'b0;
end
default: begin
enable <= enable;
t_A <= t_A;
t_B <= t_B;
t_C <= t_C;
end
endcase
end
信号t_ *仅在nxt_state为“LOAD”时加载新值。如果我没有在“忙”和“完成”的情况下列出信号t_ *,他们会保留他们的价值吗?
我已尝试在case子句之前添加一些代码,如下所示,但它在运行linting工具时显示一些警告
always @ (posedge clk or negedge rst_n) begin
if (!rst_n) begin
enable <= 1'b0;
t_A <= 1'b0;
t_B <= 1'b0;
t_C <= 1'b0;
end
else begin
enable <= enable;
t_A <= t_A;
t_B <= t_B;
t_C <= t_C;
case (nxt_state)
IDLE: begin
enable <= 1'b0;
t_A <= 1'b0;
t_B <= 1'b0;
t_C <= 1'b0;
end
LOAD: begin
enable <= 1'b0;
t_A <= A;
t_B <= B;
t_C <= C;
end
BUSY: begin
enable <= 1'b1;
end
DONE: begin
enable <= 1'b0;
end
default: begin
enable <= enable;
t_A <= t_A;
t_B <= t_B;
t_C <= t_C;
end
endcase
end
如何修复它以保持代码简单明了?
答案 0 :(得分:0)
您已经声明要将之前的值保留为默认选项。这绰绰有余。此外,如果信号在一个&#34;中被指定值,如果&#34;阻止,但没有出现在其其他计数器部分,合成器通常会合成一个锁存器以保留其先前的值。
答案 1 :(得分:0)
你真正在这里做的是创建一堆翻牌来保持状态机运行。触发器的定义是它将输出值保持到时钟的下一个边沿(或者rst,或者其他)。所以,这是一个简单的翻牌模型:
reg q;
always @(posedge clk)
q <= d;
在上述情况下,q
将在时钟边沿之间保持稳定,这意味着它的值将保存在寄存器中。
使用启用信号编译的更多内容:
always @(posedge clk)
if (en)
q <= d;
在上面,q
的值在时钟边沿之间将保持稳定,并且只有在en
为高时才会在clk边缘处发生变化。在所有其他情况下,它将保持价值。
因此,在您的情况下,首先要做不需要default
子句。没有它,价值将是稳定的。
如果未在BUSY和DONE中列出信号,则值不会从之前的状态改变。所以,你的初始变体是正确的,除了那里不需要默认值。
always @ (posedge clk or negedge rst_n) begin
if (!rst_n) begin
enable <= 1'b0;
t_A <= 1'b0;
t_B <= 1'b0;
t_C <= 1'b0;
end
else begin
case (nxt_state)
IDLE: begin
enable <= 1'b0;
t_A <= 1'b0;
t_B <= 1'b0;
t_C <= 1'b0;
end
LOAD: begin
enable <= 1'b0;
t_A <= A;
t_B <= B;
t_C <= C;
end
BUSY: begin
enable <= 1'b1;
end
DONE: begin
enable <= 1'b0;
end
endcase
end
我注意到的一件事是你没有在这里更新next_state
。你应该弄明白该怎么做。