]>
Witch of Git - jade-rose/blob - hardware/core.py
13 class Core(Elaboratable
):
15 self
.regs
= Array(Signal(8, reset
=0) for _
in range(4))
16 self
.it
= Signal(8, reset
=0)
17 self
.data1
= Signal(8, reset
=255)
18 self
.data2
= Signal(8, reset
=254)
19 self
.code
= Signal(8, reset
=1)
20 self
.link
= Signal(8, reset
=0)
22 self
.pc
= Signal(16, reset
=0)
23 self
.state
= Signal(CpuState
)
26 self
.addr
= Signal(16)
30 self
.d_out
= Signal(8)
31 self
.debug
= Signal(8)
32 self
.debug_en
= Signal()
34 def elaborate(self
, platform
):
36 with m
.If(self
.state
== CpuState
.HALT
):
37 pass # We're halted :)
38 with m
.Elif(self
.state
== CpuState
.READ
):
39 m
.d
.sync
+= self
.state
.eq(CpuState
.EXEC
)
40 m
.d
.sync
+= self
.pc
.eq(self
.pc
+ 1)
42 self
.addr
.eq(self
.pc
),
45 with m
.Elif(self
.state
== CpuState
.EXEC
):
46 m
.d
.sync
+= self
.state
.eq(CpuState
.READ
)
47 m
.d
.sync
+= self
.inst
.eq(self
.d_in
)
48 m
.d
.sync
+= self
.pc
.eq(self
.pc
+ 2)
50 self
.addr
.eq(self
.pc
+ 1),
53 self
.execute(m
, self
.d_in
)
54 with m
.Elif(self
.state
== CpuState
.EXEC2
):
55 m
.d
.sync
+= self
.state
.eq(CpuState
.READ
)
56 self
.execute2(m
, self
.inst
, self
.d_in
)
57 with m
.Elif(self
.state
== CpuState
.WAIT
):
58 # This should be changed to avoid reading from memory every cycle
59 # for power purposes. Instead in the wait state we should just
60 # leave the address line set and the output line high, and let an
61 # external interrupt controller send back a wake signal.
62 m
.d
.comb
+= self
.addr
.eq(Cat(self
.it
, self
.data1
))
63 m
.d
.comb
+= self
.r_en
.eq(True)
65 m
.d
.sync
+= self
.state
.eq(CpuState
.READ
)
69 self
.d_out
.eq(self
.d_in
- 1),
73 def execute(self
, m
, inst
):
74 m
.d
.sync
+= self
.state
.eq(CpuState
.READ
)
76 with m
.Case("00000000"): # HALT
77 m
.d
.sync
+= self
.state
.eq(CpuState
.HALT
)
78 with m
.Case("00000001"): # NOPE
80 with m
.Case("00000010"): # PRNT
82 self
.debug
.eq(self
.it
),
83 self
.debug_en
.eq(True),
85 with m
.Case("00000011"): # WAIT
86 m
.d
.sync
+= self
.state
.eq(CpuState
.WAIT
)
88 self
.addr
.eq(Cat(self
.it
, self
.data1
),
91 with m
.Case("0000010-"): # reserved
92 m
.d
.sync
+= self
.state
.eq(CpuState
.HALT
)
93 with m
.Case("00000110"): # CABA
94 pass # @TODO: Implement CABA
95 with m
.Case("00000111"): # COFA
96 pass # @TODO: Implement COFA
97 with m
.Case("00001---"): # ALU1
98 self
.inst_alu1(m
, inst
)
99 with m
.Case("000100--"): # GET?
101 with m
.Case("000101--"): # UNSPECIFIED
102 m
.d
.sync
+= self
.state
.eq(CpuState
.HALT
)
103 with m
.Case("000110--"): # SET?
105 with m
.Case("000111--"): # UNSPECIFIED
106 m
.d
.sync
+= self
.state
.eq(CpuState
.HALT
)
107 with m
.Case("000111--"): # UNSPECIFIED
109 with m
.Case("00100---"): # GETR
111 with m
.Case("00101---"): # SETR
113 with m
.Case("00110---"): # SWAP
115 with m
.Case("00111---"): # ISLT
117 with m
.Case("01------"): # ALUR
119 with m
.Case("10------"): # LD/ST [12][UR}
121 with m
.Case("110-----"): # RESERVED
122 m
.d
.sync
+= self
.state
.eq(CpuState
.HALT
)
123 with m
.Case("11100---"): # LD2D
125 with m
.Case("11101---"): # ST2D
127 with m
.Case("1111----"): # WITH-IMM
128 m
.d
.sync
+= self
.state
.eq(CpuState
.EXEC2
)
129 m
.d
.sync
+= self
.pc
.eq(self
.pc
)
132 def execute2(self
, m
, base
, imm
):
133 with m
.Switch(Cat(imm
, base
)):
134 with m
.Case("111100----------"): # ALUI
136 with m
.Case("11110100--------"): # BEZI
138 with m
.Case("11110101--------"): # JOFI
140 with m
.Case("11110110--------"): # CABI
142 with m
.Case("11110111--------"): # COFI
144 with m
.Case("111110----------"): # Reserved
145 m
.d
.sync
+= self
.state
.eq(CpuState
.HALT
)
146 with m
.Case("1111110---------"): # Reserved
147 m
.d
.sync
+= self
.state
.eq(CpuState
.HALT
)
148 with m
.Case("11111110--------"): # GETI
149 m
.d
.sync
+= self
.it
.eq(imm
)
150 with m
.Case("11111111--------"): # EXT1 (reserved)
151 m
.d
.sync
+= self
.state
.eq(CpuState
.HALT
)
153 def inst_alu1(self
, m
, inst
):
157 m
.d
.sync
+= self
.it
.eq(0)
159 m
.d
.sync
+= self
.it
.eq(self
.it
<< 1)
161 m
.d
.sync
+= self
.it
.eq(self
.it
>> 1)
163 m
.d
.sync
+= self
.it
.eq(self
.it
// 2)
165 m
.d
.sync
+= self
.it
.eq(self
.it
+ 1)
167 m
.d
.sync
+= self
.it
.eq(self
.it
- 1)
169 m
.d
.sync
+= self
.it
.eq(~self
.it
)
171 m
.d
.sync
+= self
.it
.eq(-self
.it
)
177 return [self
.addr
, self
.d_out
, self
.r_en
, self
.w_en
, self
.debug
]
180 return self
.inputs() + self
.outputs()