from nmigen import *
from nmigen.build import Platform
from nmigen.cli import main
+from nmigen.hdl.ast import Statement
class Op(Enum):
ADD = 0b000
self.cycle = Signal(range(5))
self.regs = Array(Signal(32, name=f"r{i}") for i in range(8))
- def decode(self, m: Module, inst: Value) -> None:
+ def decode(self, m: Module, inst: Statement) -> None:
reg_a, reg_b = inst[19:22], inst[16:19]
m.d.sync += [
self.inst.eq(inst),
self.b.eq(self.regs[reg_b]),
]
+ def end_inst(self, m: Module, dest: Statement) -> None:
+ m.d.sync += self.cycle.eq(0)
+ m.d.sync += self.pc.eq(dest)
+
def elaborate(self, platform: Platform) -> Module:
m = Module()
with m.If(~self.halted):
with m.If(self.cycle == 2):
tmp = self.a + self.b
m.d.sync += self.regs[self.reg_d].eq(tmp)
- m.d.sync += self.cycle.eq(0)
- m.d.sync += self.pc.eq(self.pc + 1)
+ self.end_inst(m, self.pc + 1)
with m.Case(Op.NOR):
with m.If(self.cycle == 2):
tmp = ~(self.a | self.b)
m.d.sync += self.regs[self.reg_d].eq(tmp)
- m.d.sync += self.cycle.eq(0)
- m.d.sync += self.pc.eq(self.pc + 1)
+ self.end_inst(m, self.pc + 1)
with m.Case(Op.LW):
with m.If(self.cycle == 2):
m.d.comb += self.en.eq(True)
m.d.comb += self.rw.eq(Rw.READ)
with m.If(self.cycle == 3):
m.d.sync += self.regs[self.reg_b].eq(self.d_in)
- m.d.sync += self.cycle.eq(0)
- m.d.sync += self.pc.eq(self.pc + 1)
+ self.end_inst(m, self.pc + 1)
with m.Case(Op.SW):
with m.If(self.cycle == 2):
m.d.comb += self.addr.eq(self.a + self.offset)
m.d.comb += self.rw.eq(Rw.WRITE)
m.d.comb += self.d_out.eq(self.b)
with m.If(self.cycle == 3):
- m.d.sync += self.cycle.eq(0)
- m.d.sync += self.pc.eq(self.pc + 1)
+ self.end_inst(m, self.pc + 1)
with m.Case(Op.BEQ):
with m.If(self.cycle == 2):
dest = self.pc + 1 + self.offset
dest = Mux(self.a == self.b, dest, self.pc + 1)
- m.d.sync += self.cycle.eq(0)
- m.d.sync += self.pc.eq(dest)
+ self.end_inst(m, dest)
with m.Case(Op.JALR):
with m.If(self.cycle == 2):
same_reg = self.reg_a == self.reg_b
dest = Mux(same_reg, self.pc + 1, self.a)
m.d.sync += self.regs[self.reg_b].eq(self.pc + 1)
- m.d.sync += self.cycle.eq(0)
- m.d.sync += self.pc.eq(dest)
+ self.end_inst(m, dest)
with m.Case(Op.HALT):
with m.If(self.cycle == 2):
m.d.sync += self.halted.eq(True)
- m.d.sync += self.cycle.eq(0)
- m.d.sync += self.pc.eq(self.pc + 1)
+ self.end_inst(m, self.pc + 1)
with m.Case(Op.NOOP):
with m.If(self.cycle == 2):
- m.d.sync += self.cycle.eq(0)
- m.d.sync += self.pc.eq(self.pc + 1)
+ self.end_inst(m, self.pc + 1)
return m
def inputs(self):