]>
Witch of Git - jade-rabbit/blob - core.py
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)
30 self
.reg_a
= Signal(range(8))
31 self
.reg_b
= Signal(range(8))
32 self
.reg_d
= Signal(range(8))
33 self
.offset
= Signal(16)
39 # Fetch - fetch data from memory
40 # Decode - read from registers
41 # Execute - do ALU work
42 # Memory (optional) - read/write memory if needed
44 self
.cycle
= Signal(range(5))
45 self
.regs
= Array(Signal(32) for _
in range(8))
47 def decode(self
, m
: Module
, inst
: Value
) -> None:
48 reg_a
, reg_b
= inst
[19:22], inst
[16:19]
50 self
.op
.eq(inst
[22:25]),
53 self
.reg_d
.eq(inst
[0:3]),
54 self
.offset
.eq(inst
[0:16]),
57 self
.a
.eq(self
.regs
[reg_a
]),
58 self
.b
.eq(self
.regs
[reg_b
]),
61 def elaborate(self
, platform
: Platform
) -> Module
:
63 with m
.If(~self
.halted
):
64 m
.d
.sync
+= self
.cycle
.eq(self
.cycle
+ 1)
65 with m
.If(self
.cycle
== 0):
66 m
.d
.sync
+= self
.addr
.eq(self
.pc
)
67 m
.d
.sync
+= self
.rw
.eq(Rw
.READ
)
68 m
.d
.sync
+= self
.en
.eq(True)
69 with m
.Elif(self
.cycle
== 1):
70 m
.d
.sync
+= self
.en
.eq(False)
71 self
.decode(m
, self
.d_in
)
73 with m
.Switch(self
.op
):
75 with m
.If(self
.cycle
== 2):
77 m
.d
.sync
+= self
.regs
[self
.reg_d
].eq(tmp
)
78 m
.d
.sync
+= self
.cycle
.eq(0)
79 m
.d
.sync
+= self
.pc
.eq(self
.pc
+ 1)
81 with m
.If(self
.cycle
== 2):
82 tmp
= ~
(self
.a | self
.b
)
83 m
.d
.sync
+= self
.regs
[self
.reg_d
].eq(tmp
)
84 m
.d
.sync
+= self
.cycle
.eq(0)
85 m
.d
.sync
+= self
.pc
.eq(self
.pc
+ 1)
87 with m
.If(self
.cycle
== 2):
88 m
.d
.sync
+= self
.addr
.eq(self
.a
+ self
.offset
)
89 m
.d
.sync
+= self
.en
.eq(True)
90 m
.d
.sync
+= self
.rw
.eq(Rw
.READ
)
91 with m
.If(self
.cycle
== 3):
92 m
.d
.sync
+= self
.regs
[self
.reg_b
].eq(self
.d_in
)
93 m
.d
.sync
+= self
.en
.eq(False)
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
.sync
+= self
.addr
.eq(self
.a
+ self
.offset
)
99 m
.d
.sync
+= self
.d_out
.eq(self
.b
)
100 m
.d
.sync
+= self
.en
.eq(True)
101 m
.d
.sync
+= self
.rw
.eq(Rw
.WRITE
)
102 with m
.If(self
.cycle
== 3):
103 m
.d
.sync
+= self
.en
.eq(False)
104 m
.d
.sync
+= self
.cycle
.eq(0)
105 m
.d
.sync
+= self
.pc
.eq(self
.pc
+ 1)
107 with m
.If(self
.cycle
== 2):
108 dest
= self
.pc
+ 1 + self
.offset
109 dest
= Mux(self
.a
== self
.b
, dest
, self
.pc
+ 1)
110 m
.d
.sync
+= self
.cycle
.eq(0)
111 m
.d
.sync
+= self
.pc
.eq(dest
)
112 with m
.Case(Op
.JALR
):
113 with m
.If(self
.cycle
== 2):
114 same_reg
= self
.reg_a
== self
.reg_b
115 dest
= Mux(same_reg
, self
.pc
+ 1, self
.a
)
116 m
.d
.sync
+= self
.regs
[self
.reg_b
].eq(self
.pc
+ 1)
117 m
.d
.sync
+= self
.cycle
.eq(0)
118 m
.d
.sync
+= self
.pc
.eq(dest
)
119 with m
.Case(Op
.HALT
):
120 with m
.If(self
.cycle
== 2):
121 m
.d
.sync
+= self
.halted
.eq(True)
122 m
.d
.sync
+= self
.cycle
.eq(0)
123 m
.d
.sync
+= self
.pc
.eq(self
.pc
+ 1)
124 with m
.Case(Op
.NOOP
):
125 with m
.If(self
.cycle
== 2):
126 m
.d
.sync
+= self
.cycle
.eq(0)
127 m
.d
.sync
+= self
.pc
.eq(self
.pc
+ 1)
134 return [self
.addr
, self
.d_out
, self
.rw
, self
.en
]
137 return self
.inputs() + self
.outputs()
140 if __name__
== '__main__':
141 core
= JadeRabbitCore()
142 main(core
, ports
=core
.ports())