Skip to content

Commit 1b9e071

Browse files
committed
1 parent 22a649b commit 1b9e071

File tree

1 file changed

+128
-0
lines changed

1 file changed

+128
-0
lines changed
Lines changed: 128 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,128 @@
1+
package hdlbits.circuits
2+
3+
import chisel3._
4+
import chisel3.util._
5+
6+
// _root_ disambiguates from package chisel3.util.circt if user imports chisel3.util._
7+
import _root_.circt.stage.ChiselStage
8+
9+
// Generate Verilog sources and save it in file Lemmings4.sv
10+
object Lemmings4 extends App {
11+
ChiselStage.emitSystemVerilogFile(
12+
new Lemmings4,
13+
firtoolOpts = Array(
14+
"-disable-all-randomization",
15+
"-strip-debug-info"
16+
),
17+
args = Array("--target-dir", "gen/hdlbits/circuits")
18+
)
19+
}
20+
21+
// https://hdlbits.01xz.net/wiki/Lemmings4
22+
class Lemmings4 extends RawModule {
23+
val clk = IO(Input(Clock()))
24+
val areset = IO(
25+
Input(AsyncReset())
26+
) // Freshly brainwashed Lemmings walk left.
27+
val bump_left = IO(Input(Bool()))
28+
val bump_right = IO(Input(Bool()))
29+
val ground = IO(Input(Bool()))
30+
val dig = IO(Input(Bool()))
31+
val walk_left = IO(Output(Bool()))
32+
val walk_right = IO(Output(Bool()))
33+
val aaah = IO(Output(Bool()))
34+
val digging = IO(Output(Bool()))
35+
36+
// Define state parameters
37+
val walkingLeft :: walkingRight :: fallingLeft :: fallingRight :: diggingLeft :: diggingRight :: splat :: dead :: Nil =
38+
Enum(8)
39+
val nextState = WireInit(walkingLeft)
40+
41+
// State register with clock and reset
42+
val state =
43+
withClockAndReset(clk, areset) { RegInit(walkingLeft) }
44+
val counter =
45+
withClockAndReset(clk, areset) { RegInit(0.U(5.W)) }
46+
47+
// State transition logic
48+
switch(state) {
49+
is(walkingLeft) {
50+
when(!ground) {
51+
nextState := fallingLeft
52+
}.elsewhen(dig) {
53+
nextState := diggingLeft
54+
}.elsewhen(bump_left) {
55+
nextState := walkingRight
56+
}.otherwise {
57+
nextState := walkingLeft
58+
}
59+
}
60+
is(walkingRight) {
61+
when(!ground) {
62+
nextState := fallingRight
63+
}.elsewhen(dig) {
64+
nextState := diggingRight
65+
}.elsewhen(bump_right) {
66+
nextState := walkingLeft
67+
}.otherwise {
68+
nextState := walkingRight
69+
}
70+
}
71+
is(fallingLeft) {
72+
when(!ground & counter <= 20.U) {
73+
nextState := fallingLeft
74+
}.elsewhen(!ground & counter > 20.U) {
75+
nextState := splat
76+
}.otherwise {
77+
nextState := walkingLeft
78+
}
79+
}
80+
is(fallingRight) {
81+
when(!ground & counter <= 20.U) {
82+
nextState := fallingRight
83+
}.elsewhen(!ground & counter > 20.U) {
84+
nextState := splat
85+
}.otherwise {
86+
nextState := walkingRight
87+
}
88+
}
89+
is(diggingLeft) {
90+
when(!ground) {
91+
nextState := fallingLeft
92+
} otherwise {
93+
nextState := diggingLeft
94+
}
95+
}
96+
is(diggingRight) {
97+
when(!ground) {
98+
nextState := fallingRight
99+
} otherwise {
100+
nextState := diggingRight
101+
}
102+
}
103+
is(splat) {
104+
when(ground) {
105+
nextState := dead
106+
} otherwise {
107+
nextState := splat
108+
}
109+
}
110+
is(dead) {
111+
nextState := dead
112+
}
113+
}
114+
115+
// State flip-flops with asynchronous reset
116+
state := nextState
117+
when(nextState === fallingLeft | nextState === fallingRight) {
118+
counter := counter + 1.U
119+
} otherwise {
120+
counter := 1.U
121+
}
122+
123+
// Output logic
124+
walk_left := state === walkingLeft
125+
walk_right := state === walkingRight
126+
aaah := state === fallingLeft | state === fallingRight | state === splat
127+
digging := state === diggingLeft | state === diggingRight
128+
}

0 commit comments

Comments
 (0)