记录一下这道题的解题思路,一开始审题状态机部分很明确,主要是计数器怎么和状态机融合
先贴出最终成功的代码。
module top_module(
input clk,
input areset, // Freshly brainwashed Lemmings walk left.
input bump_left,
input bump_right,
input ground,
input dig,
output walk_left,
output walk_right,
output aaah,
output digging );
parameter LEFT = 3'd0, RIGHT = 3'd1, DIGL = 3'd2, DIGR = 3'd3, AHL = 3'd4, AHR = 3'd5, SPLAT = 3'd6;
reg [3:0] STATE, NEXT_STATE;
reg [4:0]count1;
reg splatter;
always @ (*) begin
case(STATE)
LEFT:NEXT_STATE = ground ? (dig ? DIGL : (bump_left ? RIGHT : LEFT) ): AHL;
RIGHT: NEXT_STATE = ground ?(dig ? DIGR :(bump_right ? LEFT : RIGHT)) :AHR;
DIGL: NEXT_STATE = ground ? DIGL : AHL;
DIGR: NEXT_STATE = ground ? DIGR : AHR;
AHL: NEXT_STATE = ground ? (splatter ? SPLAT : LEFT) : AHL;
AHR: NEXT_STATE = ground ? (splatter ? SPLAT : RIGHT) : AHR;
SPLAT: NEXT_STATE = SPLAT;
default: NEXT_STATE = LEFT;
endcase
end
always @ (posedge clk,posedge areset)begin
if(areset)begin
STATE <= LEFT;
end
else begin
STATE <= NEXT_STATE;
end
end
always @ (posedge clk, posedge areset)begin
if(areset)begin
count1 <= 1'b0;
splatter <= 1'b0;
end
else if(count1 == 5'd20)begin
splatter <= 1'b1;
count1 <= 5'd0;
end
else if(NEXT_STATE == AHL | NEXT_STATE == AHR)begin
count1 <= count1 + 1'b1;
end
else begin
count1 <= 1'b0;
end
end
assign walk_left = (STATE != SPLAT) & (STATE == LEFT);
assign walk_right = (STATE != SPLAT) & (STATE == RIGHT);
assign aaah = (STATE == AHL)|(STATE == AHR);
assign digging = (STATE == DIGL) | (STATE == DIGR);
endmodule
有两个部分导致最后总有一两个mismatch,首先是计数器判断条件(错误代码)
else if(STATE == AHL | STATE == AHR)begin
count1 <= count1 + 1'b1;
end
其次是最后的assign部分,一开始用这种条件会偶尔导致mismatch,还是直接用状态判断最稳妥
assign walk_left = (~splatter) & (STATE == LEFT);
assign walk_right = (~splatter) & (STATE == RIGHT);