From 38a16263dcd364010a059e6ff59762564a1c2b5f Mon Sep 17 00:00:00 2001 From: Cassie Jones Date: Sun, 5 Jan 2020 06:30:58 -0500 Subject: [PATCH] Add simulation, make address lines combinatorial Adding a clocked memory unit exposed a timing issue in the previous implementation of the memory ports. When the core used synchronous address lines, it seemed to end up interpreting a loaded value from an LW as an instruction word. --- .gitignore | 1 + core.py | 116 +++++++++++++++++++++++++++++++++++++++++++++-------- 2 files changed, 100 insertions(+), 17 deletions(-) create mode 100644 .gitignore diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..f6a0f81 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +*.vcd diff --git a/core.py b/core.py index 5d870fc..fc8913a 100644 --- a/core.py +++ b/core.py @@ -26,6 +26,7 @@ class JadeRabbitCore(Elaboratable): self.d_out = Signal(32) self.en = Signal() self.rw = Signal(Rw) + self.inst = Signal(32) self.op = Signal(Op) self.reg_a = Signal(range(8)) self.reg_b = Signal(range(8)) @@ -42,11 +43,12 @@ class JadeRabbitCore(Elaboratable): # Memory (optional) - read/write memory if needed # Halt self.cycle = Signal(range(5)) - self.regs = Array(Signal(32) for _ in range(8)) + self.regs = Array(Signal(32, name=f"r{i}") for i in range(8)) def decode(self, m: Module, inst: Value) -> None: reg_a, reg_b = inst[19:22], inst[16:19] m.d.sync += [ + self.inst.eq(inst), self.op.eq(inst[22:25]), self.reg_a.eq(reg_a), self.reg_b.eq(reg_b), @@ -63,11 +65,10 @@ class JadeRabbitCore(Elaboratable): with m.If(~self.halted): m.d.sync += self.cycle.eq(self.cycle + 1) with m.If(self.cycle == 0): - m.d.sync += self.addr.eq(self.pc) - m.d.sync += self.rw.eq(Rw.READ) - m.d.sync += self.en.eq(True) + m.d.comb += self.en.eq(True) + m.d.comb += self.rw.eq(Rw.READ) + m.d.comb += self.addr.eq(self.pc) with m.Elif(self.cycle == 1): - m.d.sync += self.en.eq(False) self.decode(m, self.d_in) with m.Else(): with m.Switch(self.op): @@ -85,22 +86,20 @@ class JadeRabbitCore(Elaboratable): m.d.sync += self.pc.eq(self.pc + 1) with m.Case(Op.LW): with m.If(self.cycle == 2): - m.d.sync += self.addr.eq(self.a + self.offset) - m.d.sync += self.en.eq(True) - m.d.sync += self.rw.eq(Rw.READ) + m.d.comb += self.en.eq(True) + m.d.comb += self.addr.eq(self.a + self.offset) + 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.en.eq(False) m.d.sync += self.cycle.eq(0) m.d.sync += self.pc.eq(self.pc + 1) with m.Case(Op.SW): with m.If(self.cycle == 2): - m.d.sync += self.addr.eq(self.a + self.offset) - m.d.sync += self.d_out.eq(self.b) - m.d.sync += self.en.eq(True) - m.d.sync += self.rw.eq(Rw.WRITE) + m.d.comb += self.addr.eq(self.a + self.offset) + m.d.comb += self.en.eq(True) + 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.en.eq(False) m.d.sync += self.cycle.eq(0) m.d.sync += self.pc.eq(self.pc + 1) with m.Case(Op.BEQ): @@ -131,12 +130,95 @@ class JadeRabbitCore(Elaboratable): return [self.d_in] def outputs(self): - return [self.addr, self.d_out, self.rw, self.en] + return [self.addr, self.d_out, self.rw, self.en, self.halted] def ports(self): return self.inputs() + self.outputs() +class FakeRam(Elaboratable): + def __init__(self, data): + self.data = list(data) + self.addr = Signal(16) + self.d_in = Signal(32) + self.d_out = Signal(32) + self.en = Signal() + self.rw = Signal(Rw) + self.mem = Memory(width=32, depth=2**8, init=self.data) + + def elaborate(self, platform: Platform) -> Module: + m = Module() + m.submodules.rdport = rdport = self.mem.read_port() + m.submodules.wrport = wrport = self.mem.write_port() + m.d.comb += [ + rdport.addr.eq(self.addr), + self.d_out.eq(rdport.data), + wrport.addr.eq(self.addr), + wrport.data.eq(self.d_in), + wrport.en.eq(self.en & (self.rw == Rw.WRITE)), + ] + return m + + +CODE = """ +8454186 +8519723 +8650796 +23527424 +25165824 +8781869 +20054049 +16908318 +17432605 +8781870 +917505 +8781869 +15663151 +3014661 +15269935 +3014661 +15335471 +3014661 +8650796 +23527424 +8781870 +3014661 +11141167 +1441794 +3014661 +11075631 +8781869 +15401007 +3014661 +8650796 +23527424 +8781870 +3014661 +11272239 +3014661 +11468847 +2293763 +24903680 +8585261 +24903680 +65539 +24903680 +5 +3 +5 +1 +-1 +""" + if __name__ == '__main__': - core = JadeRabbitCore() - main(core, ports=core.ports()) + m = Module() + m.submodules.core = core = JadeRabbitCore() + m.submodules.ram = ram = FakeRam(int(x) for x in CODE.strip().split()) + m.d.comb += [ + ram.addr.eq(core.addr), + ram.d_in.eq(core.d_out), + core.d_in.eq(ram.d_out), + ram.rw.eq(core.rw), + ram.en.eq(core.en), + ] + main(m, ports=core.ports()) -- 2.47.0