Skip to content
Permalink

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: whitequark/Boneless-CPU
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: 9a3b0e75b07a
Choose a base ref
...
head repository: whitequark/Boneless-CPU
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: f1a113bd6e0e
Choose a head ref
  • 2 commits
  • 7 files changed
  • 1 contributor

Commits on Jul 12, 2019

  1. Copy the full SHA
    649e050 View commit details
  2. gateware.{core,decoder}_v3: implement window instructions.

    Change: +1 LUT.
    
    (Really?? *Now* abc decides to be efficient?)
    whitequark committed Jul 12, 2019
    Copy the full SHA
    f1a113b View commit details
Showing with 91 additions and 74 deletions.
  1. +21 −18 boneless/arch/opcode_v3.py
  2. +12 −12 boneless/gateware/core_fsm.py
  3. +2 −0 boneless/gateware/core_v3.py
  4. +51 −39 boneless/gateware/decoder_v3.py
  5. +2 −2 boneless/gateware/formal.py
  6. +3 −3 boneless/test/test_core.py
  7. BIN doc/design.ods
39 changes: 21 additions & 18 deletions boneless/arch/opcode_v3.py
Original file line number Diff line number Diff line change
@@ -31,7 +31,9 @@ class F_XR3A (Instr): coding = "-----000AAA--iii"; operands = "{ra:R}, {imm:I3AL
class F_RR3S (Instr): coding = "-----DDDAAA--iii"; operands = "{rsd:R}, {ra:R}, {imm:I3SR}"
class F_RR5 (Instr): coding = "-----DDDAAAiiiii"; operands = "{rsd:R}, {ra:R}, {imm:I5}"
class F_RR (Instr): coding = "-----DDD---00BBB"; operands = "{rsd:R}, {rb:R}"
class F_XR (Instr): coding = "-----000---00BBB"; operands = "{rb:R}"
class F_R5 (Instr): coding = "-----DDD---iiiii"; operands = "{rsd:R}, {imm:I5}"
class F_X5 (Instr): coding = "-----000---iiiii"; operands = "{imm:I5}"
class F_R8 (Instr): coding = "-----DDDiiiiiiii"; operands = "{rsd:R}, {imm:I8}"
class F_8 (Instr): coding = "--------iiiiiiii"; operands = "{imm:I8}"
class F_13 (Instr): coding = "---iiiiiiiiiiiii"; operands = "{imm:I13}"
@@ -65,16 +67,17 @@ class C_LDX (Instr): coding = "0110------------"
class C_STX (Instr): coding = "0111------------"
class C_MOVE (Instr): coding = "1000------------"

# Flow opcodes
class C_FLOW (Instr): coding = "10100-----------"
class T_STW (Instr): coding = "--------000-----"
class T_SWPW (Instr): coding = "--------001-----"
class T_ADJW (Instr): coding = "--------010-----"
class T_LDW (Instr): coding = "--------011-----"
class T_JR (Instr): coding = "--------100-----"
# class T_? (Instr): coding = "--------101-----"
class T_JV (Instr): coding = "--------110-----"
class T_JT (Instr): coding = "--------111-----"; pc_rel_ops = {"imm"}
# Window opcodes
class C_STW (Instr): coding = "10100---000-----"
class C_SWPW (Instr): coding = "10100---001-----"
class C_ADJW (Instr): coding = "10100---010-----"
class C_LDW (Instr): coding = "10100---011-----"

# Jump opcodes
class C_JR (Instr): coding = "10100---100-----"
# class C_? (Instr): coding = "10100---101-----"
class C_JV (Instr): coding = "10100---110-----"
class C_JT (Instr): coding = "10100---111-----"; pc_rel_ops = {"imm"}
class C_JAL (Instr): coding = "10101-----------"; pc_rel_ops = {"imm"}

# Conditional opcode
@@ -143,16 +146,16 @@ class MOVI(C_MOVE, M_ABS, F_R8 ): pass
class MOVR(C_MOVE, M_REL, F_R8 ): pass

# Window instructions
class STW (C_FLOW, T_STW, F_RR ): pass
class SWPW(C_FLOW, T_SWPW, F_RR ): pass
class ADJW(C_FLOW, T_ADJW, F_R5 ): pass
class LDW (C_FLOW, T_LDW, F_R5 ): pass
class STW (C_STW, F_XR ): pass
class SWPW(C_SWPW, F_RR ): pass
class ADJW(C_ADJW, F_X5 ): pass
class LDW (C_LDW, F_R5 ): pass

# Jump instructions
class JR (C_FLOW, T_JR, F_R5 ): pass
# class ? (C_FLOW, T_?, F_R5 ): pass
class JV (C_FLOW, T_JV, F_R5 ): pass
class JT (C_FLOW, T_JT, F_R5 ): pass
class JR (C_JR, F_R5 ): pass
# class ? (C_?, F_R5 ): pass
class JV (C_JV, F_R5 ): pass
class JT (C_JT, F_R5 ): pass
class JAL (C_JAL, F_R8 ): pass

# Conditional instructions
24 changes: 12 additions & 12 deletions boneless/gateware/core_fsm.py
Original file line number Diff line number Diff line change
@@ -16,7 +16,7 @@ def AddSignedImm(v, i):
return v + Cat(i, Repl(i[i_nbits - 1], v.nbits - i_nbits))


class _MemoryPort:
class _MemoryPort(Elaboratable):
def __init__(self, name):
self.addr = Signal(16, name=name + "_addr")
self.en = Signal(1, name=name + "_en")
@@ -26,7 +26,7 @@ def elaborate(self, platform):
return Fragment()


class _ExternalPort:
class _ExternalPort(Elaboratable):
def __init__(self):
self.addr = Signal(16, name="ext_addr")
self.r_en = Signal(1, name="ext_r_en")
@@ -38,7 +38,7 @@ def elaborate(self, platform):
return Fragment()


class _ALU:
class _ALU(Elaboratable):
SEL_AND = 0b1000
SEL_OR = 0b1001
SEL_XOR = 0b1010
@@ -75,10 +75,10 @@ def elaborate(self, platform):
s_m1n0.eq(Mux(self.c_sel[3], s_m2n0, s_m2n0 + s_m2n1 + self.c_sel[2])),
self.s_o.eq(s_m1n0),
]
return m.lower(platform)
return m


class _SRU:
class _SRU(Elaboratable):
DIR_L = 0b0
DIR_R = 0b1

@@ -108,10 +108,10 @@ def elaborate(self, platform):
s_m1n0.eq(Mux(self.c_ld, self.s_i, s_m2n0)),
]
m.d.sync += self.r_o.eq(s_m1n0)
return m.lower(platform)
return m


class BonelessCoreFSM:
class BonelessCoreFSM(Elaboratable):
def __init__(self, reset_addr, mem_rdport, mem_wrport, ext_port=None):
self.reset_addr = reset_addr

@@ -444,15 +444,15 @@ def decode(v):
m.d.sync += r_pc.eq(AddSignedImm(mem_r.data, i_imm8))
m.next = "FETCH"

return m.lower(platform)
return m

# -------------------------------------------------------------------------------------------------

import argparse
from nmigen import cli


class BonelessFSMTestbench:
class BonelessFSMTestbench(Elaboratable):
def __init__(self, has_pins=False):
self.memory = Memory(width=16, depth=256)
self.ext_port = _ExternalPort()
@@ -510,10 +510,10 @@ def elaborate(self, platform):
mem_rdport=mem_rdport,
mem_wrport=mem_wrport,
ext_port =self.ext_port)
return m.lower(platform)
return m


class BonelessFSMFormal:
class BonelessFSMFormal(Elaboratable):
def __init__(self):
self.mem_rdport = _MemoryPort("mem_r")
self.mem_wrport = _MemoryPort("mem_w")
@@ -526,7 +526,7 @@ def __init__(self):
def elaborate(self, platform):
m = Module()
m.submodules += self.mem_rdport, self.mem_wrport, self.core
return m.lower(platform)
return m


if __name__ == "__main__":
2 changes: 2 additions & 0 deletions boneless/gateware/core_v3.py
Original file line number Diff line number Diff line change
@@ -342,6 +342,8 @@ def elaborate(self, platform):
m.d.comb += m_shift.c_en.eq(1)
m.d.comb += m_shift.c_load.eq(self.r_cycle == 0)
m.d.comb += self.o_done.eq(m_shift.o_done)
with m.Elif(m_dec.o_multi):
m.d.comb += self.o_done.eq(self.r_cycle == 1)
with m.Else():
m.d.comb += self.o_done.eq(1)
with m.If(self.o_done):
90 changes: 51 additions & 39 deletions boneless/gateware/decoder_v3.py
Original file line number Diff line number Diff line change
@@ -282,7 +282,6 @@ def elaborate(self, platform):
with m.Case(opcode.C_SHIFT.coding):
m.d.comb += [
m_imm.c_width.eq(m_imm.Width.IMM3),
self.o_multi.eq(1),
self.o_shift.eq(1),
self.o_ld_a.eq(self.LdA.RA),
self.o_st_r.eq(self.StR.RSD),
@@ -382,63 +381,76 @@ def elaborate(self, platform):
self.o_st_r.eq(self.StR.RSD),
]

with m.Case(opcode.C_FLOW.coding):
with m.Switch(self.i_insn):
with m.Case(opcode.T_STW.coding, opcode.T_SWPW.coding,
opcode.T_ADJW.coding, opcode.T_LDW.coding):
m.d.comb += [
self.o_multi.eq(1),
self.o_ld_a.eq(self.LdA.W),
self.o_st_w.eq(1),
]
with m.Case(opcode.C_STW.coding, opcode.C_SWPW.coding,
opcode.C_ADJW.coding, opcode.C_LDW.coding):
m.d.comb += [
m_imm.c_width.eq(m_imm.Width.IMM5),
self.o_multi.eq(1),
self.o_ld_a.eq(self.LdA.W),
]
with m.Switch(self.i_insn):
# Window operations
with m.Case(opcode.T_STW.coding):
with m.Case(opcode.C_STW.coding):
m.d.comb += [
self.o_ld_b.eq(self.LdB.RB),
self.o_op.eq(alsru_cls.Op.B),
]
with m.Case(opcode.T_SWPW.coding):
with m.Case(opcode.C_SWPW.coding):
m.d.comb += [
self.o_ld_b.eq(self.LdB.RB),
self.o_op.eq(alsru_cls.Op.B),
self.o_st_r.eq(self.StR.RSD),
]
with m.Case(opcode.T_ADJW.coding):
with m.Case(opcode.C_ADJW.coding):
m.d.comb += [
self.o_ld_b.eq(self.LdB.IMM),
self.o_op.eq(alsru_cls.Op.ApB),
]
with m.Case(opcode.T_LDW.coding):
with m.Case(opcode.C_LDW.coding):
m.d.comb += [
self.o_ld_b.eq(self.LdB.IMM),
self.o_op.eq(alsru_cls.Op.ApB),
self.o_st_r.eq(self.StR.RSD),
]
# Jumps
with m.Case(opcode.T_JR.coding):
m.d.comb += [
self.o_ld_a.eq(self.LdA.RSD),
self.o_ld_b.eq(self.LdB.IMM),
self.o_op.eq(alsru_cls.Op.ApB),
self.o_st_pc.eq(1),
]
with m.Case(opcode.T_JV.coding):
m.d.comb += [
self.o_ld_a.eq(self.LdA.RSD),
self.o_ld_b.eq(self.LdB.ApI),
self.o_op.eq(alsru_cls.Op.ApB),
self.o_st_pc.eq(1),
]
with m.Case(opcode.T_JT.coding):
m.d.comb += [
m_imm.c_pcrel.eq(1),
self.o_multi.eq(1),
self.o_ld_a.eq(self.LdA.RSD),
self.o_ld_b.eq(self.LdB.ApI),
self.o_op.eq(alsru_cls.Op.ApB),
self.o_st_pc.eq(1),
]
with m.If(self.c_cycle == 0):
m.d.comb += [
self.o_st_w.eq(1),
self.o_st_r.eq(self.StR.x),
]
with m.Else():
m.d.comb += [
self.o_op.eq(alsru_cls.Op.A),
]

with m.Case(opcode.C_JR.coding):
m.d.comb += [
m_imm.c_width.eq(m_imm.Width.IMM5),
self.o_ld_a.eq(self.LdA.RSD),
self.o_ld_b.eq(self.LdB.IMM),
self.o_op.eq(alsru_cls.Op.ApB),
self.o_st_pc.eq(1),
]

# with m.Case(opcode.C_J?.coding):

with m.Case(opcode.C_JV.coding):
m.d.comb += [
m_imm.c_width.eq(m_imm.Width.IMM5),
self.o_ld_a.eq(self.LdA.RSD),
self.o_ld_b.eq(self.LdB.ApI),
self.o_op.eq(alsru_cls.Op.ApB),
self.o_st_pc.eq(1),
]

with m.Case(opcode.C_JT.coding):
m.d.comb += [
m_imm.c_width.eq(m_imm.Width.IMM5),
m_imm.c_pcrel.eq(1),
self.o_multi.eq(1),
self.o_ld_a.eq(self.LdA.RSD),
self.o_ld_b.eq(self.LdB.ApI),
self.o_op.eq(alsru_cls.Op.ApB),
self.o_st_pc.eq(1),
]

with m.Case(opcode.C_JAL.coding):
m.d.comb += [
4 changes: 2 additions & 2 deletions boneless/gateware/formal.py
Original file line number Diff line number Diff line change
@@ -4,7 +4,7 @@
__all__ = ["BonelessFormalInterface"]


class BonelessFormalInterface:
class BonelessFormalInterface(Elaboratable):
def __init__(self, mem_wrport=None, ext_port=None):
self.mem_wrport = mem_wrport
self.ext_port = ext_port
@@ -52,4 +52,4 @@ def elaborate(self, platform):
self.ext_w_data.eq(self.ext_port.w_data),
self.ext_w_en .eq(self.ext_port.w_en),
]
return m.lower(platform)
return m
6 changes: 3 additions & 3 deletions boneless/test/test_core.py
Original file line number Diff line number Diff line change
@@ -20,12 +20,12 @@ def wrapper(self):
return configure_wrapper


class BonelessSimulationTestbench(Module):
class BonelessSimulationTestbench(Elaboratable):
def __init__(self):
self.mem_init = []
self.ext_init = []

def get_fragment(self, platform):
def elaborate(self, platform):
m = Module()

mem = self.mem = Memory(width=16, depth=len(self.mem_init), init=self.mem_init)
@@ -54,7 +54,7 @@ def get_fragment(self, platform):
mem_wrport=mem_wrport,
ext_port =ext_port)

return m.lower(platform)
return m


class BonelessTestCase(unittest.TestCase):
Binary file modified doc/design.ods
Binary file not shown.