目录
Lemmings2
题链接:Lemmings2 - HDLBits (01xz.net)
较之上一题引入一个 fall 态,题目看起来有点绕,从题中给定的提示图很容易理解。
- 由 fall 态返回需要保持原本掉落时的移动方向,于是将 fall 态巧妙地分为左、右移动时不同的两种 fall 状态,直观。
- 处于 fall 态时 walk_left、walk_right 同时为低电平。
module top_module(
input clk,
input areset, // Freshly brainwashed Lemmings walk left.
input bump_left,
input bump_right,
input ground,
output walk_left,
output walk_right,
output aaah );
parameter L=2'b00, R=2'b01, L_fall=2'b10, R_fall=2'b11;
reg [1:0] state, next_state;
// state transition logic
always @(*) begin
case(state)
L: next_state = ~ground ? L_fall : (bump_left ? R : L);
R: next_state = ~ground ? R_fall : (bump_right ? L : R);
L_fall: next_state = ~ground ? L_fall : L;
R_fall: next_state = ~ground ? R_fall : R;
endcase
end
always @(posedge clk or posedge areset) begin
if(areset) state <= L;
else begin
aaah <= ~ground;
state <= next_state;
end
end
// walk_right = ~walk_left 不正确,和上题不同,此题左右移动不再全程相反
// fall 时 walk_left 和 walk_right 都是低电平
assign walk_left = (state == L);
assign walk_right = (state == R);
endmodule
Lemmings3
同理上一题,引入两个新的分左右 dig 状态即可。
Lemmings4
题链接:Lemmings4 - HDLBits (01xz.net)
- 较之题 Lemmings3 引入新状态 die,特点在于该状态不存在状态转移,进入该态则一直保持直到 areset。
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 L=3'd0, R=3'd1, L_fall=3'd2, R_fall=3'd3;
parameter L_dig=3'd4, R_dig=3'd5;
parameter die=3'd6; // cease 4 outputs state
int count; // fall-clock
reg [2:0] state, next_state;
// state transition logic
always @(*) begin
case(state)
L_dig: next_state = ground ? L_dig : L_fall;
R_dig: next_state = ground ? R_dig : R_fall;
L: next_state = ~ground ? L_fall : (dig ? L_dig : (bump_left ? R : L)); // fall > dig > switch
R: next_state = ~ground ? R_fall : (dig ? R_dig : (bump_right ? L : R));
L_fall: next_state = ~ground ? L_fall : (count>=20 ? die : L); // go to die when "count>=20" and "ground==1"
R_fall: next_state = ~ground ? R_fall : (count>=20 ? die : R);
die: next_state = die; // keep wait until areset
endcase
end
always @(posedge clk or posedge areset) begin
if(areset) begin
state <= L;
count = 0; // fall-clock clear
end
else begin
if(state==next_state && (state==L_fall || state==R_fall))
count <= count + 1;
else count = 0;
aaah <= (~ground & state!=die); // aaah 受 die 状态影响
state <= next_state;
end
end
assign walk_left = (state == L);
assign walk_right = (state == R);
assign digging = (state == L_dig) | (state == R_dig);
endmodule