]>
Witch of Git - jade-rabbit/blob - core.py
fc8913ad43d024661828898c9b878caeec5618e2
3 from nmigen
.build
import Platform
4 from nmigen
.cli
import main
20 class JadeRabbitCore(Elaboratable
):
23 self
.halted
= Signal()
24 self
.addr
= Signal(16)
25 self
.d_in
= Signal(32)
26 self
.d_out
= Signal(32)
29 self
.inst
= Signal(32)
31 self
.reg_a
= Signal(range(8))
32 self
.reg_b
= Signal(range(8))
33 self
.reg_d
= Signal(range(8))
34 self
.offset
= Signal(16)
40 # Fetch - fetch data from memory
41 # Decode - read from registers
42 # Execute - do ALU work
43 # Memory (optional) - read/write memory if needed
45 self
.cycle
= Signal(range(5))
46 self
.regs
= Array(Signal(32, name
=f
"r{i}") for i
in range(8))
48 def decode(self
, m
: Module
, inst
: Value
) -> None:
49 reg_a
, reg_b
= inst
[19:22], inst
[16:19]
52 self
.op
.eq(inst
[22:25]),
55 self
.reg_d
.eq(inst
[0:3]),
56 self
.offset
.eq(inst
[0:16]),
59 self
.a
.eq(self
.regs
[reg_a
]),
60 self
.b
.eq(self
.regs
[reg_b
]),
63 def elaborate(self
, platform
: Platform
) -> Module
:
65 with m
.If(~self
.halted
):
66 m
.d
.sync
+= self
.cycle
.eq(self
.cycle
+ 1)
67 with m
.If(self
.cycle
== 0):
68 m
.d
.comb
+= self
.en
.eq(True)
69 m
.d
.comb
+= self
.rw
.eq(Rw
.READ
)
70 m
.d
.comb
+= self
.addr
.eq(self
.pc
)
71 with m
.Elif(self
.cycle
== 1):
72 self
.decode(m
, self
.d_in
)
74 with m
.Switch(self
.op
):
76 with m
.If(self
.cycle
== 2):
78 m
.d
.sync
+= self
.regs
[self
.reg_d
].eq(tmp
)
79 m
.d
.sync
+= self
.cycle
.eq(0)
80 m
.d
.sync
+= self
.pc
.eq(self
.pc
+ 1)
82 with m
.If(self
.cycle
== 2):
83 tmp
= ~
(self
.a | self
.b
)
84 m
.d
.sync
+= self
.regs
[self
.reg_d
].eq(tmp
)
85 m
.d
.sync
+= self
.cycle
.eq(0)
86 m
.d
.sync
+= self
.pc
.eq(self
.pc
+ 1)
88 with m
.If(self
.cycle
== 2):
89 m
.d
.comb
+= self
.en
.eq(True)
90 m
.d
.comb
+= self
.addr
.eq(self
.a
+ self
.offset
)
91 m
.d
.comb
+= self
.rw
.eq(Rw
.READ
)
92 with m
.If(self
.cycle
== 3):
93 m
.d
.sync
+= self
.regs
[self
.reg_b
].eq(self
.d_in
)
94 m
.d
.sync
+= self
.cycle
.eq(0)
95 m
.d
.sync
+= self
.pc
.eq(self
.pc
+ 1)
97 with m
.If(self
.cycle
== 2):
98 m
.d
.comb
+= self
.addr
.eq(self
.a
+ self
.offset
)
99 m
.d
.comb
+= self
.en
.eq(True)
100 m
.d
.comb
+= self
.rw
.eq(Rw
.WRITE
)
101 m
.d
.comb
+= self
.d_out
.eq(self
.b
)
102 with m
.If(self
.cycle
== 3):
103 m
.d
.sync
+= self
.cycle
.eq(0)
104 m
.d
.sync
+= self
.pc
.eq(self
.pc
+ 1)
106 with m
.If(self
.cycle
== 2):
107 dest
= self
.pc
+ 1 + self
.offset
108 dest
= Mux(self
.a
== self
.b
, dest
, self
.pc
+ 1)
109 m
.d
.sync
+= self
.cycle
.eq(0)
110 m
.d
.sync
+= self
.pc
.eq(dest
)
111 with m
.Case(Op
.JALR
):
112 with m
.If(self
.cycle
== 2):
113 same_reg
= self
.reg_a
== self
.reg_b
114 dest
= Mux(same_reg
, self
.pc
+ 1, self
.a
)
115 m
.d
.sync
+= self
.regs
[self
.reg_b
].eq(self
.pc
+ 1)
116 m
.d
.sync
+= self
.cycle
.eq(0)
117 m
.d
.sync
+= self
.pc
.eq(dest
)
118 with m
.Case(Op
.HALT
):
119 with m
.If(self
.cycle
== 2):
120 m
.d
.sync
+= self
.halted
.eq(True)
121 m
.d
.sync
+= self
.cycle
.eq(0)
122 m
.d
.sync
+= self
.pc
.eq(self
.pc
+ 1)
123 with m
.Case(Op
.NOOP
):
124 with m
.If(self
.cycle
== 2):
125 m
.d
.sync
+= self
.cycle
.eq(0)
126 m
.d
.sync
+= self
.pc
.eq(self
.pc
+ 1)
133 return [self
.addr
, self
.d_out
, self
.rw
, self
.en
, self
.halted
]
136 return self
.inputs() + self
.outputs()
139 class FakeRam(Elaboratable
):
140 def __init__(self
, data
):
141 self
.data
= list(data
)
142 self
.addr
= Signal(16)
143 self
.d_in
= Signal(32)
144 self
.d_out
= Signal(32)
147 self
.mem
= Memory(width
=32, depth
=2**8, init
=self
.data
)
149 def elaborate(self
, platform
: Platform
) -> Module
:
151 m
.submodules
.rdport
= rdport
= self
.mem
.read_port()
152 m
.submodules
.wrport
= wrport
= self
.mem
.write_port()
154 rdport
.addr
.eq(self
.addr
),
155 self
.d_out
.eq(rdport
.data
),
156 wrport
.addr
.eq(self
.addr
),
157 wrport
.data
.eq(self
.d_in
),
158 wrport
.en
.eq(self
.en
& (self
.rw
== Rw
.WRITE
)),
213 if __name__
== '__main__':
215 m
.submodules
.core
= core
= JadeRabbitCore()
216 m
.submodules
.ram
= ram
= FakeRam(int(x
) for x
in CODE
.strip().split())
218 ram
.addr
.eq(core
.addr
),
219 ram
.d_in
.eq(core
.d_out
),
220 core
.d_in
.eq(ram
.d_out
),
224 main(m
, ports
=core
.ports())