我不明白如何在我的ASM设计中避免推断锁存器 这是我的代码。
module ASM (
input[7:0] SW,
input Start, Reset, Clock,
output reg Led,
output reg[3:0] result);
reg[2:0] state, next_state;
reg[7:0] A;
wire Done;
parameter S1 = 3'd1;
parameter S2 = 3'd2;
parameter S3 = 3'd3;
parameter S4 = 3'd4;
parameter S5 = 3'd5;
parameter S6 = 3'd6;
always @(posedge Clock)
begin
if (!Reset)
state <= next_state;
else
state <= S1;
end
always @(state, Start, A)
begin
case(state)
S1: begin
if (Start)
next_state = S2;
else
next_state = S1;
end
S2: begin //check A == 0
if (A == 8'd0)
next_state = S6; //done
else
next_state = S3;//check A0
end
S3: begin //check A0
if (A[0])
next_state = S4; //result++
else
next_state = S5; //A>>1
end
S4: begin //result++
next_state = S5;
end
S5: begin //A>>1
next_state = S2;
end
S6: begin //done
if (Start)
next_state = S6;
else
next_state = S1;
end
default: begin
next_state = S1;
end
endcase
end
always @(state, SW)
begin
//result = 4'b0;
//A = 8'd0;
//Led = 1'b0;
case (state)
S1: begin
A = SW;
result = 4'b0;
Led = 1'b0;
end
S2: begin
end
S3: begin
end
S4: begin
result <= result + 4'd1;
end
S5: begin
A = A >> 1;
end
S6: begin
Led = 1'b1;
end
default: begin
result = 4'b0;
Led = 1'b0;
end
endcase
end
endmodule
我理解我应该在第二个“always”块中的“case”语句之前初始化变量“A”,“result”和“led”。但是如果每次“始终”块处于活动状态时都这样做,我会松开以前的变量结果并再次将它们分配给初始值,因此整个设计是错误的。这样我就无法避免使用锁存器而只是不应该初始化这些变量。但是锁存是不好的做法。所以你能解释我应该如何改变代码来避免这种情况吗?
答案 0 :(得分:0)
嗯,你想要获得的行为(仅对某些输入进行更改并保留其值)是锁存器的行为。如果你想避免使用锁存器并且使用内存变量,则使用同步始终阻塞。
always @(posedge Clock)
begin
case (next_state)
S1: begin
A <= SW;
result <= 4'b0;
Led <= 1'b0;
end
S2, S3: begin
end
S4: begin
result <= result + 4'd1;
end
S5: begin
A <= A >> 1;
end
S6: begin
Led <= 1'b1;
end
default: begin
result <= 4'b0;
Led <= 1'b0;
end
endcase
end
答案 1 :(得分:0)
合成器只关心同步逻辑的灵敏度列表。 @(state, SW)
仅触发模拟中的特定变量。合成器基本上看@(state, SW, result)
。这种方式@*
(同义@(*)
)是组合逻辑和有意锁存的首选。
有关推断锁存器的详细信息,请阅读:What is inferred latch and how it is created when it is missing else statement in if condition.can anybody explain briefly?
对于您的情况,您应该使块同步。将@(state, SW)
更改为@(posedge Clock)
。要缩短时序延迟,请在同一个始终阻止中将case (state)
更改为case (next_state)
。您应该使用非阻止分配A
,result
和Led
。您可能想要添加重置条件。
答案 2 :(得分:0)
从示例中的第二个case语句中推断出锁存器。原因是所有3个变量都在某些条件下分配(S1)而在其他条件下没有分配(S2,S3,...),这意味着它们在这种情况下保留旧值。这是典型的锁存行为。因此,您推断了锁存器。
我认为这种说法在任何情况下都不适合修复。你有一堆错误,使用的操作只能在同步块中完成,比如A = A >> 1
或混合阻塞和非阻塞分配。它不是设计状态机的方法。那么,看看@Hans的Lehnert的回答来获得一个想法。