]>
Witch of Git - jade-rabbit/blob - core.py
   3 from nmigen
.build 
import Platform
 
   4 from nmigen
.cli 
import main
 
   5 from nmigen
.hdl
.ast 
import Statement
 
  21 class JadeRabbitCore(Elaboratable
): 
  24         self
.halted 
= Signal() 
  25         self
.addr 
= Signal(16) 
  26         self
.d_in 
= Signal(32) 
  27         self
.d_out 
= Signal(32) 
  30         self
.inst 
= Signal(32) 
  32         self
.reg_a 
= Signal(range(8)) 
  33         self
.reg_b 
= Signal(range(8)) 
  34         self
.reg_d 
= Signal(range(8)) 
  35         self
.offset 
= Signal(16) 
  41         # Fetch - fetch data from memory 
  42         # Decode - read from registers 
  43         # Execute - do ALU work 
  44         # Memory (optional) - read/write memory if needed 
  46         self
.cycle 
= Signal(range(5)) 
  47         self
.regs 
= Array(Signal(32, name
=f
"r{i}") for i 
in range(8)) 
  49     def decode(self
, m
: Module
, inst
: Statement
) -> None: 
  50         reg_a
, reg_b 
= inst
[19:22], inst
[16:19] 
  53             self
.op
.eq(inst
[22:25]), 
  56             self
.reg_d
.eq(inst
[0:3]), 
  57             self
.offset
.eq(inst
[0:16]), 
  60             self
.a
.eq(self
.regs
[reg_a
]), 
  61             self
.b
.eq(self
.regs
[reg_b
]), 
  64     def end_inst(self
, m
: Module
, dest
: Statement
) -> None: 
  65         m
.d
.sync 
+= self
.cycle
.eq(0) 
  66         m
.d
.sync 
+= self
.pc
.eq(dest
) 
  68     def elaborate(self
, platform
: Platform
) -> Module
: 
  70         with m
.If(~self
.halted
): 
  71             m
.d
.sync 
+= self
.cycle
.eq(self
.cycle 
+ 1) 
  72             with m
.If(self
.cycle 
== 0): 
  73                 m
.d
.comb 
+= self
.en
.eq(True) 
  74                 m
.d
.comb 
+= self
.rw
.eq(Rw
.READ
) 
  75                 m
.d
.comb 
+= self
.addr
.eq(self
.pc
) 
  76             with m
.Elif(self
.cycle 
== 1): 
  77                 self
.decode(m
, self
.d_in
) 
  79                 with m
.Switch(self
.op
): 
  81                         with m
.If(self
.cycle 
== 2): 
  83                             m
.d
.sync 
+= self
.regs
[self
.reg_d
].eq(tmp
) 
  84                             self
.end_inst(m
, self
.pc 
+ 1) 
  86                         with m
.If(self
.cycle 
== 2): 
  87                             tmp 
= ~
(self
.a | self
.b
) 
  88                             m
.d
.sync 
+= self
.regs
[self
.reg_d
].eq(tmp
) 
  89                             self
.end_inst(m
, self
.pc 
+ 1) 
  91                         with m
.If(self
.cycle 
== 2): 
  92                             m
.d
.comb 
+= self
.en
.eq(True) 
  93                             m
.d
.comb 
+= self
.addr
.eq(self
.a 
+ self
.offset
) 
  94                             m
.d
.comb 
+= self
.rw
.eq(Rw
.READ
) 
  95                         with m
.If(self
.cycle 
== 3): 
  96                             m
.d
.sync 
+= self
.regs
[self
.reg_b
].eq(self
.d_in
) 
  97                             self
.end_inst(m
, self
.pc 
+ 1) 
  99                         with m
.If(self
.cycle 
== 2): 
 100                             m
.d
.comb 
+= self
.addr
.eq(self
.a 
+ self
.offset
) 
 101                             m
.d
.comb 
+= self
.en
.eq(True) 
 102                             m
.d
.comb 
+= self
.rw
.eq(Rw
.WRITE
) 
 103                             m
.d
.comb 
+= self
.d_out
.eq(self
.b
) 
 104                         with m
.If(self
.cycle 
== 3): 
 105                             self
.end_inst(m
, 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                             self
.end_inst(m
, 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                             self
.end_inst(m
, dest
) 
 117                     with m
.Case(Op
.HALT
): 
 118                         with m
.If(self
.cycle 
== 2): 
 119                             m
.d
.sync 
+= self
.halted
.eq(True) 
 120                             self
.end_inst(m
, self
.pc 
+ 1) 
 121                     with m
.Case(Op
.NOOP
): 
 122                         with m
.If(self
.cycle 
== 2): 
 123                             self
.end_inst(m
, self
.pc 
+ 1) 
 130         return [self
.addr
, self
.d_out
, self
.rw
, self
.en
, self
.halted
] 
 133         return self
.inputs() + self
.outputs() 
 136 class FakeRam(Elaboratable
): 
 137     def __init__(self
, data
): 
 138         self
.data 
= list(data
) 
 139         self
.addr 
= Signal(16) 
 140         self
.d_in 
= Signal(32) 
 141         self
.d_out 
= Signal(32) 
 144         self
.mem 
= Memory(width
=32, depth
=2**8, init
=self
.data
) 
 146     def elaborate(self
, platform
: Platform
) -> Module
: 
 148         m
.submodules
.rdport 
= rdport 
= self
.mem
.read_port() 
 149         m
.submodules
.wrport 
= wrport 
= self
.mem
.write_port() 
 151             rdport
.addr
.eq(self
.addr
), 
 152             self
.d_out
.eq(rdport
.data
), 
 153             wrport
.addr
.eq(self
.addr
), 
 154             wrport
.data
.eq(self
.d_in
), 
 155             wrport
.en
.eq(self
.en 
& (self
.rw 
== Rw
.WRITE
)), 
 210 if __name__ 
== '__main__': 
 212     m
.submodules
.core 
= core 
= JadeRabbitCore() 
 213     m
.submodules
.ram 
= ram 
= FakeRam(int(x
) for x 
in CODE
.strip().split()) 
 215         ram
.addr
.eq(core
.addr
), 
 216         ram
.d_in
.eq(core
.d_out
), 
 217         core
.d_in
.eq(ram
.d_out
), 
 221     main(m
, ports
=core
.ports()) 
 
This page took 0.064644 seconds  and 5 git commands  to generate.