From 758ea6d7da07fced61f2dfc2f7e52977518b5ebf Mon Sep 17 00:00:00 2001 From: Teguh Hofstee Date: Wed, 26 Feb 2020 16:31:50 -0800 Subject: [PATCH 1/4] update magma IO syntax --- examples/coreir/counters.py | 6 +-- examples/coreir/counters_wire.py | 6 +-- examples/fsm/top.py | 10 ++--- mantle/common/RAM.py | 8 ++-- mantle/common/ROM.py | 2 +- mantle/common/arbiter.py | 2 +- mantle/common/barrel.py | 8 ++-- mantle/common/counter.py | 2 +- mantle/common/decoder.py | 2 +- mantle/common/encoder.py | 2 +- mantle/common/fulladder.py | 4 +- mantle/common/halfadder.py | 4 +- mantle/common/johnson.py | 2 +- mantle/common/pipo.py | 4 +- mantle/common/piso.py | 4 +- mantle/common/register.py | 2 +- mantle/common/ring.py | 2 +- mantle/common/sipo.py | 2 +- mantle/common/siso.py | 2 +- mantle/coreir/FF.py | 2 +- mantle/coreir/logic.py | 14 +++---- mantle/coreir/memory.py | 12 +++--- mantle/coreir/register.py | 2 +- mantle/experimental/fifo.py | 12 +++--- mantle/lattice/ice40/BUF.py | 2 +- mantle/lattice/mantle40/MUX.py | 8 ++-- mantle/lattice/mantle40/arith.py | 2 +- mantle/lattice/mantle40/compare.py | 18 ++++----- mantle/lattice/mantle40/fulladder.py | 2 +- mantle/lattice/mantle40/halfadder.py | 2 +- mantle/lattice/mantle40/logic.py | 4 +- mantle/primitives/arith.py | 4 +- mantle/util/compressor/pop.py | 2 +- mantle/util/sort/bitonic.py | 6 +-- mantle/util/sort/brick.py | 2 +- mantle/util/sort/evenodd.py | 4 +- mantle/util/sort/permute.py | 2 +- mantle/util/sort/swap.py | 6 +-- mantle/xilinx/mantle3/MUX.py | 8 ++-- mantle/xilinx/mantle3/arith.py | 2 +- mantle/xilinx/mantle3/compare.py | 16 ++++---- mantle/xilinx/mantle3/decode.py | 2 +- mantle/xilinx/mantle3/fulladder.py | 2 +- mantle/xilinx/mantle3/halfadder.py | 2 +- mantle/xilinx/mantle3/logic.py | 6 +-- .../xilinx/mantle3/mothball/_halfcascade.py | 2 +- mantle/xilinx/mantle6/MUX.py | 8 ++-- mantle/xilinx/mantle6/arith.py | 2 +- mantle/xilinx/mantle6/compare.py | 16 ++++---- mantle/xilinx/mantle6/decode.py | 2 +- mantle/xilinx/mantle6/fulladder.py | 2 +- mantle/xilinx/mantle6/halfadder.py | 2 +- mantle/xilinx/mantle6/logic.py | 6 +-- mantle/xilinx/mantle6/mothball/flatcascade.py | 2 +- mantle/xilinx/mantle6/mothball/halfadder.py | 2 +- mantle/xilinx/mantle6/mothball/logic.py | 40 +++++++++---------- tests/test_coreir/test_compare.py | 2 +- tests/test_coreir/test_conv.py | 10 ++--- .../test_coreir/test_coreir_shift_register.py | 2 +- tests/test_coreir/test_logic.py | 20 +++++----- tests/test_coreir/test_lut.py | 2 +- tests/test_coreir/test_memory.py | 12 +++--- tests/test_coreir/test_mux.py | 12 +++--- tests/test_coreir/test_operator.py | 2 +- tests/test_coreir/test_register.py | 2 +- tests/test_coreir/util.py | 2 +- tests/test_mantle/test_operator.py | 8 ++-- 67 files changed, 188 insertions(+), 188 deletions(-) diff --git a/examples/coreir/counters.py b/examples/coreir/counters.py index 2b3ec81..8270ff0 100644 --- a/examples/coreir/counters.py +++ b/examples/coreir/counters.py @@ -8,7 +8,7 @@ def DefineMantleReg(init): class MantleReg(Circuit): name = f"MantleReg{init}" - IO = ["in", In(Bits(16)), "clk", In(Clock), "out", Out(Bits(16)), "clr", In(Bit)] + io = m.IO(in=In(Bits(16)), clk=In(Clock), out=Out(Bits(16)), clr=In(Bit)) @classmethod def definition(io): c0 = bits(0, 16) @@ -25,7 +25,7 @@ def definition(io): class Counter(Circuit): name = "Counter16" - IO = ["clk", In(Clock), "clr", In(Bit), "out", Out(Bits(16))] + io = m.IO(clk=In(Clock), clr=In(Bit), out=Out(Bits(16))) @classmethod def definition(io): @@ -41,7 +41,7 @@ def definition(io): class Counters(Circuit): name = "Counters" - IO = ["clk", In(Clock)] + io = m.IO(clk=In(Clock)) @classmethod def definition(io): count0 = Counter(16) diff --git a/examples/coreir/counters_wire.py b/examples/coreir/counters_wire.py index c0c6f9b..71aeb11 100644 --- a/examples/coreir/counters_wire.py +++ b/examples/coreir/counters_wire.py @@ -8,7 +8,7 @@ def DefineMantleReg(init): class MantleReg(Circuit): name = f"MantleReg{init}" - IO = ["in", In(Bits(16)), "clk", In(Clock), "out", Out(Bits(16)), "clr", In(Bit)] + io = m.IO(in=In(Bits(16)), clk=In(Clock), out=Out(Bits(16)), clr=In(Bit)) @classmethod def definition(io): c0 = bits(0, 16) @@ -25,7 +25,7 @@ def definition(io): class Counter(Circuit): name = "Counter16" - IO = ["clk", In(Clock), "clr", In(Bit), "out", Out(Bits(16))] + io = m.IO(clk=In(Clock), clr=In(Bit), out=Out(Bits(16))) @classmethod def definition(io): @@ -41,7 +41,7 @@ def definition(io): class Counters(Circuit): name = "Counters_wire" - IO = ["clk", In(Clock)] + io = m.IO(clk=In(Clock)) @classmethod def definition(io): count0_out = DefineWire(16)(name="mywire0") diff --git a/examples/fsm/top.py b/examples/fsm/top.py index 5b6a0cf..e42ee7d 100644 --- a/examples/fsm/top.py +++ b/examples/fsm/top.py @@ -39,11 +39,11 @@ def fsm_logic(current_state: m.Bits(2), class MagmaFSM(m.Circuit): - IO = ["frameValid", m.In(m.Bit), - "clk", m.In(m.Clock), - "rst", m.In(m.AsyncReset), - "real_href", m.In(m.Bit), - "pixel_valid", m.Out(m.Bit)] + io = m.IO(frameValid=m.In(m.Bit), + clk=m.In(m.Clock), + rst=m.In(m.AsyncReset), + real_href=m.In(m.Bit), + pixel_valid=m.Out(m.Bit)) @classmethod def definition(io): diff --git a/mantle/common/RAM.py b/mantle/common/RAM.py index c4e8089..62280f1 100644 --- a/mantle/common/RAM.py +++ b/mantle/common/RAM.py @@ -49,13 +49,13 @@ def DefineRAM(height, width): class _RAM(Circuit): name = f'RAM{height}x{width}' - IO = ['RADDR', In(TADDR), + io = m.IO('RADDR', In(TADDR), 'RDATA', Out(TDATA), 'WADDR', In(TADDR), 'WDATA', In(TDATA), 'WE', In(Bit), 'CLK', In(Clock) - ] + ) @classmethod def definition(io): @@ -73,14 +73,14 @@ def DefineDualRAM(height, width): class _DualRAM(Circuit): name = f'DualRAM{height}x{width}' - IO = ['RADDR0', In(TADDR), + io = m.IO('RADDR0', In(TADDR), 'RDATA0', Out(TDATA), 'RADDR1', In(TADDR), 'RDATA1', Out(TDATA), 'WADDR', In(TADDR), 'WDATA', In(TDATA), 'WE', In(Bit), - 'CLK', In(Clock)] + 'CLK', In(Clock)) @classmethod def definition(io): diff --git a/mantle/common/ROM.py b/mantle/common/ROM.py index e8c5a67..f1095b3 100644 --- a/mantle/common/ROM.py +++ b/mantle/common/ROM.py @@ -35,7 +35,7 @@ def DefineROM(height, width, data): class _ROM(Circuit): name = f'ROM{n}x{width}' - IO = ['RADDR', In(TADDR), 'RDATA', Out(TDATA)] + io = m.IO('RADDR', In(TADDR), 'RDATA', Out(TDATA)) @classmethod def definition(io): diff --git a/mantle/common/arbiter.py b/mantle/common/arbiter.py index 8e7bf3e..df0e463 100644 --- a/mantle/common/arbiter.py +++ b/mantle/common/arbiter.py @@ -12,7 +12,7 @@ def DefineArbiter(n): T = Bits[ n ] class _Arbiter(Circuit): name = 'Arbiter'+str(n) - IO = ['I', In(T), 'O', Out(T)] + io = m.IO('I', In(T), 'O', Out(T)) @classmethod def definition(Arb): ones = n * [1] diff --git a/mantle/common/barrel.py b/mantle/common/barrel.py index 98fc00a..b692fa8 100644 --- a/mantle/common/barrel.py +++ b/mantle/common/barrel.py @@ -16,7 +16,7 @@ def DefineShiftK(n, k, op): T = Bits[ n ] class _ShiftK(Circuit): name = f'{op.upper()}{n}_{k}' - IO = ['I', In(T), 'S', In(Bit), "O", Out(T)] + io = m.IO('I', In(T), 'S', In(Bit), O=Out(T)) @classmethod def definition(io): Is = [io.I[i] for i in range(n)] @@ -48,7 +48,7 @@ def DefineShift(n, op): T = Bits[ n ] class _Shift(Circuit): name = f'{op.upper()}{n}' - IO = ['I', In(T), 'S', In(Bits[ logn ]), "O", Out(T)] + io = m.IO('I', In(T), 'S', In(Bits[ logn ]), O=Out(T)) @classmethod def definition(io): I = io.I @@ -86,7 +86,7 @@ def DefineRotateK(n, k, op): T = Bits[ n ] class _RotateK(Circuit): name = f'{op.upper()}{n}_{k}' - IO = ['I', In(T), 'S', In(Bit), "O", Out(T)] + io = m.IO('I', In(T), 'S', In(Bit), O=Out(T)) @classmethod def definition(io): Is = [io.I[i] for i in range(n)] @@ -115,7 +115,7 @@ def DefineRotate(n, op): T = Bits[ n ] class _Rotate(Circuit): name = f'{op.upper()}{n}' - IO = ['I', In(T), 'S', In(Bits[ logn ]), "O", Out(T)] + io = m.IO('I', In(T), 'S', In(Bits[ logn ]), O=Out(T)) @classmethod def definition(io): I = io.I diff --git a/mantle/common/counter.py b/mantle/common/counter.py index 683cb85..ef64324 100644 --- a/mantle/common/counter.py +++ b/mantle/common/counter.py @@ -163,7 +163,7 @@ def DefineCeilFloorUpDownCounter(m, has_ce=False, has_reset=False): class CeilFloorUpDownCounter(Circuit): num_bits = math.ceil(math.log(m, 2)) name = "CeilFloorUpDownCounter_m{}_hasCE{}_hasReset{}".format(str(m), str(has_ce), str(has_reset)) - IO = ['U', In(Bit), 'D', In(Bit), 'O', Out(UInt[num_bits])] + ClockInterface(has_ce, has_reset) + io = m.IO('U', In(Bit), 'D', In(Bit), 'O', Out(UInt[num_bits])) + ClockInterface(has_ce, has_reset) @classmethod def definition(ceilFloorUpDownCounter): diff --git a/mantle/common/decoder.py b/mantle/common/decoder.py index c08fd43..b29df56 100644 --- a/mantle/common/decoder.py +++ b/mantle/common/decoder.py @@ -10,7 +10,7 @@ def DefineDecoder(n, invert=False): class _Decoder(Circuit): name = 'Decoder'+str(n)+("Invert" if invert else "") - IO = ['I', In(Bits[ n ]), 'O', Out(Bits[ 1< Date: Wed, 26 Feb 2020 16:32:38 -0800 Subject: [PATCH 2/4] autopep8 --- examples/coreir/counters.py | 10 +- examples/coreir/counters_wire.py | 14 +- examples/fsm/top.py | 11 +- mantle/common/RAM.py | 46 +-- mantle/common/ROM.py | 17 +- mantle/common/arbiter.py | 10 +- mantle/common/barrel.py | 53 ++- mantle/common/counter.py | 83 +++-- mantle/common/decoder.py | 9 +- mantle/common/encoder.py | 12 +- mantle/common/fulladder.py | 13 +- mantle/common/halfadder.py | 9 +- mantle/common/johnson.py | 6 +- mantle/common/pipo.py | 11 +- mantle/common/piso.py | 11 +- mantle/common/register.py | 27 +- mantle/common/ring.py | 8 +- mantle/common/sipo.py | 7 +- mantle/common/siso.py | 7 +- mantle/coreir/FF.py | 23 +- mantle/coreir/logic.py | 90 +++-- mantle/coreir/memory.py | 60 ++-- mantle/coreir/register.py | 3 +- mantle/experimental/fifo.py | 16 +- mantle/lattice/ice40/BUF.py | 7 +- mantle/lattice/mantle40/MUX.py | 73 ++-- mantle/lattice/mantle40/arith.py | 36 +- mantle/lattice/mantle40/compare.py | 84 +++-- mantle/lattice/mantle40/fulladder.py | 12 +- mantle/lattice/mantle40/halfadder.py | 13 +- mantle/lattice/mantle40/logic.py | 98 ++++-- mantle/primitives/arith.py | 9 +- mantle/util/compressor/pop.py | 7 +- mantle/util/sort/bitonic.py | 41 ++- mantle/util/sort/brick.py | 7 +- mantle/util/sort/evenodd.py | 45 ++- mantle/util/sort/permute.py | 43 ++- mantle/util/sort/swap.py | 17 +- mantle/xilinx/mantle3/MUX.py | 94 ++--- mantle/xilinx/mantle3/arith.py | 23 +- mantle/xilinx/mantle3/compare.py | 90 +++-- mantle/xilinx/mantle3/decode.py | 7 +- mantle/xilinx/mantle3/fulladder.py | 11 +- mantle/xilinx/mantle3/halfadder.py | 15 +- mantle/xilinx/mantle3/logic.py | 106 ++++-- .../xilinx/mantle3/mothball/_halfcascade.py | 126 +++---- mantle/xilinx/mantle6/MUX.py | 81 +++-- mantle/xilinx/mantle6/arith.py | 26 +- mantle/xilinx/mantle6/compare.py | 94 +++-- mantle/xilinx/mantle6/decode.py | 9 +- mantle/xilinx/mantle6/fulladder.py | 11 +- mantle/xilinx/mantle6/halfadder.py | 15 +- mantle/xilinx/mantle6/logic.py | 107 ++++-- mantle/xilinx/mantle6/mothball/flatcascade.py | 16 +- mantle/xilinx/mantle6/mothball/halfadder.py | 11 +- mantle/xilinx/mantle6/mothball/logic.py | 321 +++++++++++------- tests/test_coreir/test_compare.py | 19 +- tests/test_coreir/test_conv.py | 236 +++++++------ .../test_coreir/test_coreir_shift_register.py | 2 +- tests/test_coreir/test_logic.py | 77 +++-- tests/test_coreir/test_lut.py | 2 +- tests/test_coreir/test_memory.py | 38 ++- tests/test_coreir/test_operator.py | 2 +- tests/test_coreir/test_register.py | 7 +- tests/test_mantle/test_operator.py | 7 +- 65 files changed, 1602 insertions(+), 999 deletions(-) diff --git a/examples/coreir/counters.py b/examples/coreir/counters.py index 8270ff0..29b15b4 100644 --- a/examples/coreir/counters.py +++ b/examples/coreir/counters.py @@ -1,8 +1,8 @@ +import mantle.coreir +from mantle import * +from magma import * import os os.environ['MANTLE'] = 'coreir' -from magma import * -from mantle import * -import mantle.coreir def DefineMantleReg(init): @@ -35,10 +35,12 @@ def definition(io): wire(c1, a.in0) wire(r.out, a.in1) wire(r.clk, io.clk) - wire(a.out, getattr(r, "in")) # r.in doesn't work because in is a keyword + # r.in doesn't work because in is a keyword + wire(a.out, getattr(r, "in")) wire(r.out, io.out) wire(io.clr, r.clr) + class Counters(Circuit): name = "Counters" io = m.IO(clk=In(Clock)) diff --git a/examples/coreir/counters_wire.py b/examples/coreir/counters_wire.py index 71aeb11..415a98e 100644 --- a/examples/coreir/counters_wire.py +++ b/examples/coreir/counters_wire.py @@ -1,8 +1,8 @@ +import mantle.coreir +from mantle import * +from magma import * import os os.environ['MANTLE'] = 'coreir' -from magma import * -from mantle import * -import mantle.coreir def DefineMantleReg(init): @@ -35,10 +35,12 @@ def definition(io): wire(c1, a.in0) wire(r.out, a.in1) wire(r.clk, io.clk) - wire(a.out, getattr(r, "in")) # r.in doesn't work because in is a keyword + # r.in doesn't work because in is a keyword + wire(a.out, getattr(r, "in")) wire(r.out, io.out) wire(io.clr, r.clr) + class Counters(Circuit): name = "Counters_wire" io = m.IO(clk=In(Clock)) @@ -48,8 +50,8 @@ def definition(io): count1_out = DefineWire(16)(name="mywire1") count0_clr = count1_out.O[8] count1_clr = count0_out.O[4] - count0 = Counter(16,name="count0") - count1 = Counter(16,name="count1") + count0 = Counter(16, name="count0") + count1 = Counter(16, name="count1") count0( clk=io.clk, out=count0_out.I, diff --git a/examples/fsm/top.py b/examples/fsm/top.py index e42ee7d..221d617 100644 --- a/examples/fsm/top.py +++ b/examples/fsm/top.py @@ -28,7 +28,8 @@ def fsm_logic(current_state: m.Bits(2), next_state = State.HBLANK next_pixel_count = m.bits(0, 11) elif current_state == State.HACT: - next_state = State.HBLANK if pixel_count == m.bits(1, 11) else State.HACT + next_state = State.HBLANK if pixel_count == m.bits( + 1, 11) else State.HACT # TODO: Support AugAssign node # next_pixel_count -= 1 next_pixel_count = pixel_count - m.uint(1, 11) @@ -40,10 +41,10 @@ def fsm_logic(current_state: m.Bits(2), class MagmaFSM(m.Circuit): io = m.IO(frameValid=m.In(m.Bit), - clk=m.In(m.Clock), - rst=m.In(m.AsyncReset), - real_href=m.In(m.Bit), - pixel_valid=m.Out(m.Bit)) + clk=m.In(m.Clock), + rst=m.In(m.AsyncReset), + real_href=m.In(m.Bit), + pixel_valid=m.Out(m.Bit)) @classmethod def definition(io): diff --git a/mantle/common/RAM.py b/mantle/common/RAM.py index 62280f1..4ce2720 100644 --- a/mantle/common/RAM.py +++ b/mantle/common/RAM.py @@ -6,11 +6,13 @@ __all__ = ["DefineRAM", "DefineDualRAM"] + def REGs(n, width, has_ce): return [Register(width, has_ce=has_ce) for i in range(n)] + def MUXs(n, width): - return [Mux(2,width) for i in range(n)] + return [Mux(2, width) for i in range(n)] def readport(addr_width, width, regs, raddr): @@ -35,7 +37,7 @@ def writeport(addr_width, width, regs, WADDR, I, WE): n = 1 << addr_width decoder = Decoder(addr_width) - enable = And(2,n) + enable = And(2, n) enable(decoder(WADDR), repeat(WE, n)) for i in range(n): @@ -44,49 +46,49 @@ def writeport(addr_width, width, regs, WADDR, I, WE): def DefineRAM(height, width): addr_width = clog2(height) - TADDR = Bits[ addr_width ] - TDATA = Bits[ width ] + TADDR = Bits[addr_width] + TDATA = Bits[width] class _RAM(Circuit): name = f'RAM{height}x{width}' io = m.IO('RADDR', In(TADDR), - 'RDATA', Out(TDATA), - 'WADDR', In(TADDR), - 'WDATA', In(TDATA), - 'WE', In(Bit), - 'CLK', In(Clock) - ) + 'RDATA', Out(TDATA), + 'WADDR', In(TADDR), + 'WDATA', In(TDATA), + 'WE', In(Bit), + 'CLK', In(Clock) + ) @classmethod def definition(io): regs = REGs(height, width, has_ce=True) writeport(addr_width, width, regs, io.WADDR, io.WDATA, io.WE) - wire( readport(addr_width, width, regs, io.RADDR), io.RDATA ) + wire(readport(addr_width, width, regs, io.RADDR), io.RDATA) return _RAM def DefineDualRAM(height, width): addr_width = clog2(height) - TADDR = Bits[ addr_width ] - TDATA = Bits[ width ] + TADDR = Bits[addr_width] + TDATA = Bits[width] class _DualRAM(Circuit): name = f'DualRAM{height}x{width}' io = m.IO('RADDR0', In(TADDR), - 'RDATA0', Out(TDATA), - 'RADDR1', In(TADDR), - 'RDATA1', Out(TDATA), - 'WADDR', In(TADDR), - 'WDATA', In(TDATA), - 'WE', In(Bit), - 'CLK', In(Clock)) + 'RDATA0', Out(TDATA), + 'RADDR1', In(TADDR), + 'RDATA1', Out(TDATA), + 'WADDR', In(TADDR), + 'WDATA', In(TDATA), + 'WE', In(Bit), + 'CLK', In(Clock)) @classmethod def definition(io): regs = REGs(n, width, has_ce=True) writeport(addr_width, width, regs, io.WADDR, io.WDATA, io.WE) - wire( readport(addr_width, width, regs, io.RADDR0), io.RDATA0 ) - wire( readport(addr_width, width, regs, io.RADDR1), io.RDATA1 ) + wire(readport(addr_width, width, regs, io.RADDR0), io.RDATA0) + wire(readport(addr_width, width, regs, io.RADDR1), io.RDATA1) return _DualRAM diff --git a/mantle/common/ROM.py b/mantle/common/ROM.py index f1095b3..bcbdb27 100644 --- a/mantle/common/ROM.py +++ b/mantle/common/ROM.py @@ -4,26 +4,31 @@ from mantle import Mux from .RAM import readport -__all__ = ['DefineROM', 'ROM'] +__all__ = ['DefineROM', 'ROM'] + def ROM4(data, i, width): return fork([uncurry(LUT(data[i][w], 4)) for w in range(width)]) + def ROM4s(n, width, data): return [ROM4(data, i, width) for i in range(n//16)] + def MUXs(n, width): - return [Mux(2,width) for i in range(n)] + return [Mux(2, width) for i in range(n)] + def interleave16(data, width): n = len(data) bits = [int2seq(data[i], width) for i in range(n)] #print(n, bits) - data = [ [ [bits[i+j][w] for j in range(16)] for w in range(width)] \ - for i in range(0,n,16) ] + data = [[[bits[i+j][w] for j in range(16)] for w in range(width)] + for i in range(0, n, 16)] #print(len(data), data) return data + def DefineROM(height, width, data): assert height >= 4 n = 1 << height @@ -41,10 +46,10 @@ class _ROM(Circuit): def definition(io): roms = ROM4s(n, width, data) [roms[i](io.RADDR[0:4]) for i in range(n//16)] - wire( readport(height-4, width, roms, io.RADDR[4:]), io.RDATA ) + wire(readport(height-4, width, roms, io.RADDR[4:]), io.RDATA) return _ROM + def ROM(height, width, data=None): return DefineROM(height, width, data=data)() - diff --git a/mantle/common/arbiter.py b/mantle/common/arbiter.py index df0e463..8320c7e 100644 --- a/mantle/common/arbiter.py +++ b/mantle/common/arbiter.py @@ -8,8 +8,11 @@ # an Arbiter returns an array with only a single bit set, # in this case the lowest bit set is retained # + + def DefineArbiter(n): - T = Bits[ n ] + T = Bits[n] + class _Arbiter(Circuit): name = 'Arbiter'+str(n) io = m.IO('I', In(T), 'O', Out(T)) @@ -17,15 +20,18 @@ class _Arbiter(Circuit): def definition(Arb): ones = n * [1] y = DefineAdd(n)()(Arb.I, array(ones)) # y = x - 1 + def a(y): - return LUT([0, 1, 0, 0]) # A0 & ~A1 + return LUT([0, 1, 0, 0]) # A0 & ~A1 arb = join(col(a, n)) arb(Arb.I, y) wire(arb.O, Arb.O) return _Arbiter + def Arbiter(n, **kwargs): return DefineArbiter(n)(**kwargs) + def arbiter(I, **kwargs): return Arbiter(len(I), **kwargs)(I) diff --git a/mantle/common/barrel.py b/mantle/common/barrel.py index b692fa8..8e3c0c6 100644 --- a/mantle/common/barrel.py +++ b/mantle/common/barrel.py @@ -2,8 +2,8 @@ from magma.bitutils import log2 from mantle import Mux2 -__all__ = ['DefineShift', 'Shift'] -__all__ = ['DefineLSL', 'LSL'] +__all__ = ['DefineShift', 'Shift'] +__all__ = ['DefineLSL', 'LSL'] __all__ += ['DefineLSR', 'LSR'] __all__ += ['DefineASR', 'ASR'] @@ -11,9 +11,11 @@ __all__ += ['DefineROL', 'ROL'] __all__ += ['DefineROR', 'ROR'] + def DefineShiftK(n, k, op): assert k < n - T = Bits[ n ] + T = Bits[n] + class _ShiftK(Circuit): name = f'{op.upper()}{n}_{k}' io = m.IO('I', In(T), 'S', In(Bit), O=Out(T)) @@ -22,41 +24,45 @@ def definition(io): Is = [io.I[i] for i in range(n)] muxes = map_(Mux2, n) for i in range(n): - if op == 'lsl': + if op == 'lsl': shifti = i - k I = bits([Is[i], Is[shifti] if shifti >= 0 else 0]) elif op == 'lsr': shifti = i + k - I = bits([Is[i], Is[shifti] if shifti < n else 0]) + I = bits([Is[i], Is[shifti] if shifti < n else 0]) elif op == 'asr': shifti = i + k - I = bits([Is[i], Is[shifti] if shifti < n else Is[n-1]]) + I = bits([Is[i], Is[shifti] if shifti < n else Is[n-1]]) else: assert False - muxes[i]( I, io.S ) + muxes[i](I, io.S) for i in range(n): Is[i] = muxes[i].O wire(bits(Is), io.O) return _ShiftK + def ShiftK(n, k, op): return DefineShiftK(n, k, op)() + def DefineShift(n, op): assert n in [2, 4, 8, 16] logn = log2(n) - T = Bits[ n ] + T = Bits[n] + class _Shift(Circuit): name = f'{op.upper()}{n}' - io = m.IO('I', In(T), 'S', In(Bits[ logn ]), O=Out(T)) + io = m.IO('I', In(T), 'S', In(Bits[logn]), O=Out(T)) @classmethod def definition(io): I = io.I for k in range(logn): - I = ShiftK(n, 1< 0: args += ["I0", cascade.I1] - if k > 1: args += ["I1", cascade.I2] - if k > 2: args += ["I2", cascade.I3] + if k > 0: + args += ["I0", cascade.I1] + if k > 1: + args += ["I1", cascade.I2] + if k > 2: + args += ["I2", cascade.I3] args += ["O", cascade.O] return AnonymousCircuit(*args) + class EQNone(Circuit): io = m.IO(I0=In(Bit), I1=In(Bit), O=Out(Bit)) @classmethod def definition(io): - EQ1LUT = ((A0&A1)|(~A0&~A1)) - wire( LUT2(EQ1LUT)(io.I0, io.I1), io.O ) + EQ1LUT = ((A0 & A1) | (~A0 & ~A1)) + wire(LUT2(EQ1LUT)(io.I0, io.I1), io.O) + class EQ1(Circuit): - io = m.IO(I0=In(Bits[ 1 ]), I1=In(Bits[ 1 ]), O=Out(Bit)) + io = m.IO(I0=In(Bits[1]), I1=In(Bits[1]), O=Out(Bit)) @classmethod def definition(io): wire(EQNone()(io.I0[0], io.I1[0]), io.O) + class EQ2(Circuit): - T = Bits[ 2 ] + T = Bits[2] io = m.IO(I0=In(T), I1=In(T), O=Out(Bit)) @classmethod def definition(io): - EQ2LUT = ((A0&A1)|(~A0&~A1)) & ((A2&A3)|(~A2&~A3)) - wire( LUT4(EQ2LUT)(io.I0[0], io.I1[0], io.I0[1], io.I1[1]), io.O ) + EQ2LUT = ((A0 & A1) | (~A0 & ~A1)) & ((A2 & A3) | (~A2 & ~A3)) + wire(LUT4(EQ2LUT)(io.I0[0], io.I1[0], io.I0[1], io.I1[1]), io.O) + def DefineEQ(n): - T = Bits[ n ] + T = Bits[n] + class _EQ(Circuit): name = "EQ{}".format(n) io = m.IO('I0', In(T), 'I1', In(T), O=Out(Bit)) @classmethod def definition(io): - eq = _Cascade(n, 2, A0&((A1&A2)|(~A1&~A2)), 1) - wire(eq(io.I0, io.I1), io.O) + eq = _Cascade(n, 2, A0 & ((A1 & A2) | (~A1 & ~A2)), 1) + wire(eq(io.I0, io.I1), io.O) return _EQ + def EQ(n, **kwargs): - if n == None: + if n == None: return EQNone(**kwargs) elif n == 1: return EQ1(**kwargs) @@ -86,30 +97,34 @@ class NE1(Circuit): io = m.IO(I0=In(Bit), I1=In(Bit), O=Out(Bit)) @classmethod def definition(io): - NE1LUT = (A0^A1) - wire( LUT2(NE1LUT)(io.I0, io.I1), io.O ) + NE1LUT = (A0 ^ A1) + wire(LUT2(NE1LUT)(io.I0, io.I1), io.O) + class NE2(Circuit): - T = Bits[ 2 ] + T = Bits[2] io = m.IO(I0=In(T), I1=In(T), O=Out(Bit)) @classmethod def definition(io): - NE2LUT = (A0^A1)|(A2^A3) - wire( LUT4(NE2LUT)(io.I0[0], io.I1[0], io.I0[1], io.I1[1]), io.O ) + NE2LUT = (A0 ^ A1) | (A2 ^ A3) + wire(LUT4(NE2LUT)(io.I0[0], io.I1[0], io.I0[1], io.I1[1]), io.O) + def DefineNE(n): - T = Bits[ n ] + T = Bits[n] + class _NE(Circuit): name = "NE{}".format(n) io = m.IO('I0', In(T), 'I1', In(T), O=Out(Bit)) @classmethod def definition(io): - ne = _Cascade(n, 2, A0|(A1^A2), 0) - wire(ne(io.I0, io.I1), io.O) + ne = _Cascade(n, 2, A0 | (A1 ^ A2), 0) + wire(ne(io.I0, io.I1), io.O) return _NE + def NE(n, **kwargs): - if n == 1: + if n == 1: return NE1(**kwargs) elif n == 2: return NE2(**kwargs) @@ -120,6 +135,7 @@ def NE(n, **kwargs): def DefineUCMP(opname, reverse, negate, n): T = UInt[n] + class _UCMP(Circuit): name = "{}{}".format(opname, n) io = m.IO('I0', In(T), 'I1', In(T), O=Out(Bit)) @@ -136,15 +152,19 @@ def definition(io): wire(Not()(sub.COUT), io.O) return _UCMP + def DefineUGE(n): return DefineUCMP('UGE', False, False, n) + def DefineULE(n): return DefineUCMP('ULE', True, False, n) + def DefineULT(n): return DefineUCMP('ULT', False, True, n) + def DefineUGT(n): return DefineUCMP('UGT', True, True, n) @@ -154,33 +174,39 @@ def DefineUGT(n): def _sge(c_msb, a_msb, b_msb): return int((~(a_msb ^ b_msb) & ~c_msb) | (~a_msb & b_msb)) & 1 + def _slt(c_msb, a_msb, b_msb): return int((~(a_msb ^ b_msb) & c_msb) | (a_msb & ~b_msb)) & 1 + def DefineSCMP(opname, op, reverse, n): T = SInt[n] + class _SCMP(Circuit): - name = "{}{}".format(opname,n) + name = "{}{}".format(opname, n) io = m.IO('I0', In(T), 'I1', In(T), O=Out(Bit)) @classmethod def definition(io): sub = DefineSub(n)() cmp = LUT3(op) if not reverse: - wire(cmp( sub(io.I0, io.I1)[-1], io.I0[-1], io.I1[-1] ), io.O) + wire(cmp(sub(io.I0, io.I1)[-1], io.I0[-1], io.I1[-1]), io.O) else: - wire(cmp( sub(io.I1, io.I0)[-1], io.I1[-1], io.I0[-1] ), io.O) + wire(cmp(sub(io.I1, io.I0)[-1], io.I1[-1], io.I0[-1]), io.O) return _SCMP + def DefineSGE(n): return DefineSCMP('SGE', _sge, False, n) + def DefineSLE(n): return DefineSCMP('SLE', _sge, True, n) + def DefineSLT(n): return DefineSCMP('SLT', _slt, False, n) + def DefineSGT(n): return DefineSCMP('SGT', _slt, True, n) - diff --git a/mantle/lattice/mantle40/fulladder.py b/mantle/lattice/mantle40/fulladder.py index 9ee9629..7a65217 100644 --- a/mantle/lattice/mantle40/fulladder.py +++ b/mantle/lattice/mantle40/fulladder.py @@ -2,16 +2,18 @@ from ..ice40.PLB import SB_CARRY, A0, A1, A2 from .LUT import LUT3 -__all__ = ["FullAdder", 'fulladder'] +__all__ = ["FullAdder", 'fulladder'] + class FullAdder(Circuit): io = m.IO(I0=In(Bit), I1=In(Bit), CIN=In(Bit), O=Out(Bit), COUT=Out(Bit)) @classmethod def definition(io): - sum = LUT3(A0^A1^A2) - carry = SB_CARRY() # (A0&A1)|(A1&A2)|(A2&A0) - wire( sum(io.I0,io.I1,io.CIN), io.O ) - wire( carry(io.I0,io.I1,io.CIN), io.COUT ) + sum = LUT3(A0 ^ A1 ^ A2) + carry = SB_CARRY() # (A0&A1)|(A1&A2)|(A2&A0) + wire(sum(io.I0, io.I1, io.CIN), io.O) + wire(carry(io.I0, io.I1, io.CIN), io.COUT) + def fulladder(a, b, c, **kwargs): return FullAdder()(a, b, c, **kwargs) diff --git a/mantle/lattice/mantle40/halfadder.py b/mantle/lattice/mantle40/halfadder.py index 536a33d..9c56240 100644 --- a/mantle/lattice/mantle40/halfadder.py +++ b/mantle/lattice/mantle40/halfadder.py @@ -2,17 +2,18 @@ from ..ice40.PLB import SB_CARRY, A0, A1, A2, A3 from .LUT import LUT2 -__all__ = ["HalfAdder", 'halfadder'] +__all__ = ["HalfAdder", 'halfadder'] + class HalfAdder(Circuit): io = m.IO(I0=In(Bit), I1=In(Bit), O=Out(Bit), COUT=Out(Bit)) @classmethod def definition(io): - sum = LUT2(A0^A1) - carry = SB_CARRY() # (A0&A1)|(A1&A2)|(A2&A0) - wire( sum(io.I0,io.I1), io.O ) - wire( carry(io.I0,io.I1,0), io.COUT ) + sum = LUT2(A0 ^ A1) + carry = SB_CARRY() # (A0&A1)|(A1&A2)|(A2&A0) + wire(sum(io.I0, io.I1), io.O) + wire(carry(io.I0, io.I1, 0), io.COUT) + def halfadder(a, b, **kwargs): return HalfAdder()(a, b, **kwargs) - diff --git a/mantle/lattice/mantle40/logic.py b/mantle/lattice/mantle40/logic.py index fe47b87..41409b2 100644 --- a/mantle/lattice/mantle40/logic.py +++ b/mantle/lattice/mantle40/logic.py @@ -1,14 +1,14 @@ from __future__ import division +from .LUT import LUT, LUT1, LUT2, LUT3, LUT4, A0, A1, A2, A3 +from magma import * +from collections.abc import Sequence import sys if sys.version_info > (3, 0): from functools import reduce from functools import lru_cache -from collections.abc import Sequence -from magma import * -from .LUT import LUT, LUT1, LUT2, LUT3, LUT4, A0, A1, A2, A3 # unary operators -__all__ = ['DefineReduceAnd', 'ReduceAnd'] +__all__ = ['DefineReduceAnd', 'ReduceAnd'] __all__ += ['DefineReduceNAnd', 'ReduceNAnd'] __all__ += ['DefineReduceOr', 'ReduceOr'] __all__ += ['DefineReduceNOr', 'ReduceNOr'] @@ -27,80 +27,100 @@ __all__ += ['DefineInvert', 'Invert'] __all__ += ['Not'] + def FlatCascade(n, k, expr, cin, **kwargs): - def f(y): - e = expr[y] if isinstance(expr, Sequence) else expr - return LUT( e, n=k+1 ) + def f(y): + e = expr[y] if isinstance(expr, Sequence) else expr + return LUT(e, n=k+1) + + # number of luts + m = (n+k-1) // k + c = braid(col(f, m), foldargs={"I0": "O"}) - # number of luts - m = (n+k-1) // k - c = braid( col(f, m), foldargs={"I0":"O"}) + wire(cin, c.I0) - wire(cin, c.I0) + c = flat(uncurry(c)) - c = flat(uncurry(c)) + for i in range(n, len(c.I)): + wire(cin, c.I[i]) - for i in range(n, len(c.I)): - wire(cin, c.I[i]) + return AnonymousCircuit(['I', c.I[0:n], 'O', c.O]) - return AnonymousCircuit( ['I', c.I[0:n], 'O', c.O] ) def DefineReduceOp(opname, n, luts, cascadeexpr, cin): - T = Bits[ n ] + T = Bits[n] + class _ReduceOp(Circuit): name = '{}{}'.format(opname, n) io = m.IO('I', In(T), 'O', Out(Bit)) @classmethod def definition(io): - if n == 1: a = uncurry(LUT1(luts[n - 1])) - elif n == 2: a = uncurry(LUT2(luts[n - 1])) - elif n == 3: a = uncurry(LUT3(luts[n - 1])) - elif n == 4: a = uncurry(LUT4(luts[n - 1])) - else: a = FlatCascade(n, 1, cascadeexpr, cin) + if n == 1: + a = uncurry(LUT1(luts[n - 1])) + elif n == 2: + a = uncurry(LUT2(luts[n - 1])) + elif n == 3: + a = uncurry(LUT3(luts[n - 1])) + elif n == 4: + a = uncurry(LUT4(luts[n - 1])) + else: + a = FlatCascade(n, 1, cascadeexpr, cin) wire(a(io.I), io.O) return _ReduceOp + def DefineReduceAnd(n): - luts = [A0, A0&A1, A0&A1&A2, A0&A1&A2&A3] + luts = [A0, A0 & A1, A0 & A1 & A2, A0 & A1 & A2 & A3] return DefineReduceOp('And', n, luts, A0 & A1, 1) + def ReduceAnd(height=2, **kwargs): return DefineReduceAnd(height)(**kwargs) + def DefineReduceNAnd(n): - luts = [~A0, ~(A0&A1), ~(A0&A1&A2), ~(A0&A1&A2&A3)] + luts = [~A0, ~(A0 & A1), ~(A0 & A1 & A2), ~(A0 & A1 & A2 & A3)] return DefineReduceOp('NAnd', n, luts, A0 & ~A1, 0) + def ReduceNAnd(height=2, **kwargs): return DefineReduceNAnd(height)(**kwargs) + def DefineReduceOr(n): - luts = [A0, A0|A1, A0|A1|A2, A0|A1|A2|A3] + luts = [A0, A0 | A1, A0 | A1 | A2, A0 | A1 | A2 | A3] return DefineReduceOp('Or', n, luts, A0 | A1, 0) + def ReduceOr(height=2, **kwargs): return DefineReduceOr(height)(**kwargs) + def DefineReduceNOr(n): - luts = [~A0, ~(A0|A1), ~(A0|A1|A2), ~(A0|A1|A2|A3)] + luts = [~A0, ~(A0 | A1), ~(A0 | A1 | A2), ~(A0 | A1 | A2 | A3)] return DefineReduceOp('NOr', n, luts, A0 | ~A1, 1) + def ReduceNOr(height=2, **kwargs): return DefineReduceNOr(height)(**kwargs) + def DefineReduceXOr(n): - luts = [A0, A0^A1, A0^A1^A2, A0^A1^A2^A3] + luts = [A0, A0 ^ A1, A0 ^ A1 ^ A2, A0 ^ A1 ^ A2 ^ A3] return DefineReduceOp('XOr', n, luts, A0 ^ A1, 0) + def ReduceXOr(height=2, **kwargs): return DefineReduceXOr(height)(**kwargs) + def DefineReduceNXOr(n): - luts = [~A0, ~(A0^A1), ~(A0^A1^A2), ~(A0^A1^A2^A3)] + luts = [~A0, ~(A0 ^ A1), ~(A0 ^ A1 ^ A2), ~(A0 ^ A1 ^ A2 ^ A3)] return DefineReduceOp('NXOr', n, luts, A0 ^ ~A1, 1) + def ReduceNXOr(height=2, **kwargs): return DefineReduceNXOr(height)(**kwargs) @@ -111,13 +131,13 @@ def DefineOp(opname, op, height=2, width=1): I0 : In(Bits(width)), I1 : In(Bits(width)), O : Out(Bits(width)) """ - T = Bits[ width ] + T = Bits[width] class _Op(Circuit): name = '{}{}x{}'.format(opname, height, width) IO = sum([['I{}'.format(i), In(T)] for i in range(height)], []) - IO += ['O', Out(T)] + IO += ['O', Out(T)] @classmethod def definition(io): @@ -129,49 +149,61 @@ def opm(y): wire(opmxn.O, io.O) return _Op + def DefineAnd(height=2, width=1): return DefineOp('And', ReduceAnd, height, width) + def And(height=2, width=None, **kwargs): if width is None: return curry(ReduceAnd(height, **kwargs)) return DefineAnd(height, width)(**kwargs) + def DefineNAnd(height=2, width=None): return DefineOp('NAnd', ReduceNAnd, height, width) + def NAnd(height=2, width=None, **kwargs): if width is None: return curry(ReduceNAnd(height, **kwargs)) return DefineNAnd(height, width)(**kwargs) + def DefineOr(height=2, width=None): return DefineOp('Or', ReduceOr, height, width) + def Or(height=2, width=None, **kwargs): if width is None: return curry(ReduceOr(height, **kwargs)) return DefineOr(height, width)(**kwargs) + def DefineNOr(height=2, width=None): return DefineOp('NOr', ReduceNOr, height, width) + def NOr(height=2, width=None, **kwargs): if width is None: return curry(ReduceNOr(height, **kwargs)) return DefineNOr(height, width)(**kwargs) + def DefineXOr(height=2, width=None): return DefineOp('XOr', ReduceXOr, height, width) + def XOr(height=2, width=None, **kwargs): if width is None: return curry(ReduceXOr(height, **kwargs)) return DefineXOr(height, width)(**kwargs) + def DefineNXOr(height=2, width=None): return DefineOp('NXOr', ReduceNXOr, height, width) + def NXOr(height=2, width=None, **kwargs): if width is None: return curry(ReduceNXOr(height, **kwargs)) @@ -185,7 +217,8 @@ def DefineInvert(width): I0 : Bits(width) -> O : Bits(width) """ - T = Bits[ width ] + T = Bits[width] + class _Invert(Circuit): name = 'Invert%d' % width @@ -194,13 +227,14 @@ class _Invert(Circuit): @classmethod def definition(def_): def not_(y): - return Not(loc=(0,y/8, y%8)) + return Not(loc=(0, y/8, y % 8)) invert = join(col(not_, width)) wire(def_.I, invert.I0) wire(invert.O, def_.O) return _Invert + def Invert(n, **kwargs): return DefineInvert(n)(**kwargs) @@ -208,5 +242,3 @@ def Invert(n, **kwargs): def Not(**kwargs): """Not gate - 1-bit input.""" return LUT1(~A0, **kwargs) - - diff --git a/mantle/primitives/arith.py b/mantle/primitives/arith.py index a9f0685..ab13b8e 100644 --- a/mantle/primitives/arith.py +++ b/mantle/primitives/arith.py @@ -15,6 +15,7 @@ def DeclareAdd(N, cin=False, cout=False): if has_cin: IO_ += ['CIN', In(Bit)] name_ += "_cin" + class Add(Circuit): # Underscores because there's some weird scoping issue here with Python # when trying to capture name and IO @@ -31,7 +32,7 @@ def add(*args, **kwargs): if not all(isinstance(arg, BitsType) for arg in args): # TODO: Something more specific than a ValueError? raise ValueError("Arguments to add should be all Bits" - " {}".format([(arg, type(arg)) for arg in args])) + " {}".format([(arg, type(arg)) for arg in args])) adders = [Add(width, **kwargs) for _ in range(len(args) - 1)] curr = adders[0] wire(args[0], curr.I0) @@ -59,6 +60,7 @@ def DeclareSub(N, cin=False, cout=False, T=m.Bits): if has_cin: IO_ += ['CIN', In(Bit)] name_ += "_cin" + class Sub(Circuit): # Underscores because there's some weird scoping issue here with Python # when trying to capture name and IO @@ -75,7 +77,7 @@ def sub(*args, **kwargs): if not all(isinstance(arg, BitsType) for arg in args): # TODO: Something more specific than a ValueError? raise ValueError("Arguments to sub should be all Bits" - " {}".format([(arg, type(arg)) for arg in args])) + " {}".format([(arg, type(arg)) for arg in args])) subbers = [Sub(width, **kwargs) for _ in range(len(args) - 1)] curr = subbers[0] wire(args[0], curr.I0) @@ -89,8 +91,10 @@ def sub(*args, **kwargs): curr = next_ return curr.O + def DeclareNegate(width): T = Bits[width] + class _Negate(Circuit): name = 'Negate{}'.format(width) io = m.IO('I', In(T), 'O', Out(T)) @@ -99,6 +103,7 @@ class _Negate(Circuit): def DeclareASR(width): T = Bits[width] + class _ASR(Circuit): name = 'ASR{}'.format(width) io = m.IO(I0=In(T), I1=In(T), O=Out(T)) diff --git a/mantle/util/compressor/pop.py b/mantle/util/compressor/pop.py index cbdc89a..afd4a77 100644 --- a/mantle/util/compressor/pop.py +++ b/mantle/util/compressor/pop.py @@ -4,18 +4,21 @@ __all__ = ['DefinePopCount', 'PopCount', 'popcount'] + def DefinePopCount(n): class _PopCount(Circuit): name = 'PopCount{}'.format(n) - io = m.IO('I', In(Bits[ n ]), 'O', Out(Bits[ log2(n)+1 ])) + io = m.IO('I', In(Bits[n]), 'O', Out(Bits[log2(n)+1])) @classmethod def definition(io): r = compressor([io.I.as_list()]) - wire( bits(r), io.O ) + wire(bits(r), io.O) return _PopCount + def PopCount(n, **kwargs): return DefinePopCount(n)(**kwargs) + def popcount(I, **kwargs): return PopCount(len(I), **kwargs)(I) diff --git a/mantle/util/sort/bitonic.py b/mantle/util/sort/bitonic.py index 809591c..3a737e5 100644 --- a/mantle/util/sort/bitonic.py +++ b/mantle/util/sort/bitonic.py @@ -2,7 +2,7 @@ from .swap import swap from .halfcleaner import HalfCleaner, ReverseHalfCleaner -__all__ = ['DefineBitonicSorter', 'BitonicSorter', 'bitonicsorter'] +__all__ = ['DefineBitonicSorter', 'BitonicSorter', 'bitonicsorter'] __all__ += ['DefineMerger', 'Merger', 'merger'] __all__ += ['DefineSorter', 'Sorter', 'sorter'] @@ -10,9 +10,12 @@ # # HalfCleaner(n) => 2 BitonicSorter(n//2) # + + def DefineBitonicSorter(n): assert n in [2, 4, 8, 16] T = Bits(n) + class _BitonicSorter(Circuit): name = 'BitonicSorter{}'.format(n) io = m.IO('I', In(T), O=Out(T)) @@ -24,14 +27,16 @@ def definition(io): halfcleaner = HalfCleaner(n) bitonic0 = BitonicSorter(n//2) bitonic1 = BitonicSorter(n//2) - bitonic = flat( join(bitonic0, bitonic1), flatargs=['I','O'] ) - s = compose( bitonic, halfcleaner ) - wire( s(io.I), io.O ) + bitonic = flat(join(bitonic0, bitonic1), flatargs=['I', 'O']) + s = compose(bitonic, halfcleaner) + wire(s(io.I), io.O) return _BitonicSorter + def BitonicSorter(n): return DefineBitonicSorter(n)() + def bitonicsorter(I): return BitonicSorter(len(I))(I) @@ -44,6 +49,7 @@ def bitonicsorter(I): def DefineMerger(n): assert n in [2, 4, 8, 16] T = Bits(n) + class _Merger(Circuit): name = 'Merger{}'.format(n) io = m.IO('I', In(T), O=Out(T)) @@ -55,43 +61,50 @@ def definition(io): revhalfcleaner = ReverseHalfCleaner(n) bitonic0 = BitonicSorter(n//2) bitonic1 = BitonicSorter(n//2) - bitonic = flat( join(bitonic0, bitonic1), flatargs=['I','O'] ) - s = compose( bitonic, revhalfcleaner ) - wire( s(io.I), io.O ) + bitonic = flat(join(bitonic0, bitonic1), flatargs=['I', 'O']) + s = compose(bitonic, revhalfcleaner) + wire(s(io.I), io.O) return _Merger + def Merger(n): return DefineMerger(n)() + def merger(I): return Merger(len(I))(I) # # Convert an unsorted sequence into a sorted sequence # -# 2 Sorters(n/2) => Merger(n) +# 2 Sorters(n/2) => Merger(n) # + + def DefineSorter(n): assert n in [2, 4, 8, 16] T = Bits(n) + class _Sorter(Circuit): name = 'Sorter{}'.format(n) io = m.IO('I', In(T), O=Out(T)) @classmethod def definition(io): - if n == 2: # Sort 2 element sequences + if n == 2: # Sort 2 element sequences wire(swap(io.I), io.O) else: merger = Merger(n) - sorter0 = Sorter(n//2) # bot sorter - sorter1 = Sorter(n//2) # top sorter - sorter = flat( join(sorter0, sorter1), flatargs=['I','O'] ) - s = compose( merger, sorter ) - wire( s(io.I), io.O ) + sorter0 = Sorter(n//2) # bot sorter + sorter1 = Sorter(n//2) # top sorter + sorter = flat(join(sorter0, sorter1), flatargs=['I', 'O']) + s = compose(merger, sorter) + wire(s(io.I), io.O) return _Sorter + def Sorter(n): return DefineSorter(n)() + def sorter(I): return Sorter(len(I))(I) diff --git a/mantle/util/sort/brick.py b/mantle/util/sort/brick.py index 0f809a8..a272ad8 100644 --- a/mantle/util/sort/brick.py +++ b/mantle/util/sort/brick.py @@ -3,14 +3,17 @@ from mantle import * from .swap import swaps, evenoddswaps -__all__ = ['DefineBrickSorter', 'BrickSorter', 'bricksorter'] +__all__ = ['DefineBrickSorter', 'BrickSorter', 'bricksorter'] # # Brick Sorter # + + def DefineBrickSorter(n): assert n % 2 == 0 T = Bits(n) + class _BrickSorter(Circuit): name = 'BrickSorter{}'.format(n) io = m.IO('I', In(T), O=Out(T)) @@ -23,8 +26,10 @@ def definition(io): wire(I, io.O) return _BrickSorter + def BrickSorter(n): return DefineBrickSorter(n)() + def bricksorter(I): return BrickSorter(len(I))(I) diff --git a/mantle/util/sort/evenodd.py b/mantle/util/sort/evenodd.py index e44ae96..b4d5b50 100644 --- a/mantle/util/sort/evenodd.py +++ b/mantle/util/sort/evenodd.py @@ -2,69 +2,78 @@ from .swap import swap, EvenOddSwaps from .permute import Riffle, UnRiffle -__all__ = ['DefineEvenOddMerger', 'EvenOddMerger', 'evenoddmerger'] -__all__ = ['DefineEvenOddSorter', 'EvenOddSorter', 'evenoddsorter'] +__all__ = ['DefineEvenOddMerger', 'EvenOddMerger', 'evenoddmerger'] +__all__ = ['DefineEvenOddSorter', 'EvenOddSorter', 'evenoddsorter'] # # Convert an unsorted sequence into a sorted sequence # -# EvenOdd(n) => 2 EvenOddMerger(n//2) => EvenOddSwaps(n)) +# EvenOdd(n) => 2 EvenOddMerger(n//2) => EvenOddSwaps(n)) # + + def DefineEvenOddMerger(n): assert n in [2, 4, 8, 16] T = Bits(n) + class _EvenOddMerger(Circuit): name = 'EvenOddMerger{}'.format(n) io = m.IO('I', In(T), O=Out(T)) @classmethod def definition(io): - if n == 2: # Sort 2 element sequences + if n == 2: # Sort 2 element sequences wire(swap(io.I), io.O) else: unriffle = UnRiffle(n) - merger0 = EvenOddMerger(n//2) # bot merger - merger1 = EvenOddMerger(n//2) # top merger - merger = flat( join(merger0, merger1) ) + merger0 = EvenOddMerger(n//2) # bot merger + merger1 = EvenOddMerger(n//2) # top merger + merger = flat(join(merger0, merger1)) riffle = Riffle(n) - merger = compose( riffle, compose( merger, unriffle ) ) + merger = compose(riffle, compose(merger, unriffle)) evenoddswap = EvenOddSwaps(n) - merger = compose( evenoddswap, merger ) - wire( merger(io.I), io.O ) + merger = compose(evenoddswap, merger) + wire(merger(io.I), io.O) return _EvenOddMerger + def EvenOddMerger(n): return DefineEvenOddMerger(n)() + def evenoddmerger(I): return EvenOddMerger(len(I))(I) # # Convert an unsorted sequence into a sorted sequence # -# 2 EvenOddSorter(n//2) => EvenOddMerger(n)) +# 2 EvenOddSorter(n//2) => EvenOddMerger(n)) # + + def DefineEvenOddSorter(n): assert n in [2, 4, 8, 16] T = Bits(n) + class _EvenOddSorter(Circuit): name = 'EvenOddSorter{}'.format(n) io = m.IO('I', In(T), O=Out(T)) @classmethod def definition(io): - if n == 2: # Sort 2 element sequences + if n == 2: # Sort 2 element sequences wire(swap(io.I), io.O) else: - sorter0 = EvenOddSorter(n//2) # bot sorter - sorter1 = EvenOddSorter(n//2) # top sorter - sorter = flat( join(sorter0, sorter1) ) + sorter0 = EvenOddSorter(n//2) # bot sorter + sorter1 = EvenOddSorter(n//2) # top sorter + sorter = flat(join(sorter0, sorter1)) merger = EvenOddMerger(n) - sorter = compose( merger, sorter ) - wire( sorter(io.I), io.O ) + sorter = compose(merger, sorter) + wire(sorter(io.I), io.O) return _EvenOddSorter + def EvenOddSorter(n): return DefineEvenOddSorter(n)() + def evenoddsorter(I): return EvenOddSorter(len(I))(I) - diff --git a/mantle/util/sort/permute.py b/mantle/util/sort/permute.py index edd7505..cd007a7 100644 --- a/mantle/util/sort/permute.py +++ b/mantle/util/sort/permute.py @@ -1,20 +1,24 @@ from magma import In, Out, Bits, Circuit, wire, cache_definition -__all__ = ['DefinePermute', 'Permute'] +__all__ = ['DefinePermute', 'Permute'] __all__ += ['Reverse'] __all__ += ['Riffle', 'UnRiffle'] __all__ += ['ReverseRiffle', 'UnReverseRiffle'] __all__ += ['EvenOdd'] + def flatten(l): return sum(l, []) + def shuffle(l, r): return flatten([[l[i], r[i]] for i in range(n//2)]) + def concat(l, r): return l+r + def inverse(l): return [l.index(i) for i in range(len(l))] @@ -22,38 +26,50 @@ def inverse(l): def _identity(n): return range(n) + def _reverse(n): return list(reversed(range(n))) + def _even(n): return [2*i for i in range(n//2)] + def _odd(n): return [2*i+1 for i in range(n//2)] + def _bottom(n): return [i for i in range(n//2)] + def _top(n): return [n//2+i for i in range(n//2)] + def _evenodd(n): return _even(n) + _odd(n) + def _riffle(n): return flatten([[i, i+n//2] for i in range(n//2)]) + def _unriffle(n): return inverse(_riffle(n)) + def _reverseriffle(n): return flatten([[i, n-1-i] for i in range(n//2)]) + def _unreverseriffle(n): return inverse(_reverseriffle(n)) -def DefinePermute(na,permutation): + +def DefinePermute(na, permutation): n = len(permutation) + class Permute(Circuit): name = na io = m.IO(I=In(Bits(n)), O=Out(Bits(n))) @@ -62,25 +78,30 @@ def definition(io): [wire(io.I[permutation[i]], io.O[i]) for i in range(len(io.I))] return Permute -def Permute(name,permutation): - return DefinePermute(name,tuple(permutation))() + +def Permute(name, permutation): + return DefinePermute(name, tuple(permutation))() def Reverse(n): - return Permute('Reverse{}'.format(n),_reverse(n)) + return Permute('Reverse{}'.format(n), _reverse(n)) + def Riffle(n): - return Permute('Riffle{}'.format(n),_riffle(n)) + return Permute('Riffle{}'.format(n), _riffle(n)) + def UnRiffle(n): - return Permute('UnRiffle{}'.format(n),_unriffle(n)) + return Permute('UnRiffle{}'.format(n), _unriffle(n)) + def ReverseRiffle(n): - return Permute('ReverseRiffle{}'.format(n),_reverseriffle(n)) + return Permute('ReverseRiffle{}'.format(n), _reverseriffle(n)) + def UnReverseRiffle(n): - return Permute('UnReverseRiffle{}'.format(n),_unreverseriffle(n)) + return Permute('UnReverseRiffle{}'.format(n), _unreverseriffle(n)) -def EvenOdd(n): - return Permute('EvenOdd{}'.format(n),_evenodd(n)) +def EvenOdd(n): + return Permute('EvenOdd{}'.format(n), _evenodd(n)) diff --git a/mantle/util/sort/swap.py b/mantle/util/sort/swap.py index 7223e90..7ef27e7 100644 --- a/mantle/util/sort/swap.py +++ b/mantle/util/sort/swap.py @@ -1,20 +1,23 @@ from magma import Circuit, Bits, In, Out, wire, fork, join, flat, uncurry, map_, cache_definition from mantle import And, Or -__all__ = ['Swap', 'swap'] +__all__ = ['Swap', 'swap'] __all__ += ['Swaps', 'swaps'] __all__ += ['DefineEvenOddSwaps', 'EvenOddSwaps', 'evenoddswaps'] # # Binary swap circuit # + + class Swap(Circuit): io = m.IO('I', In(Bits(2)), O=Out(Bits(2))) @classmethod def definition(io): - swap = uncurry( fork( And(2), Or(2) ) , prefix="I") + swap = uncurry(fork(And(2), Or(2)), prefix="I") #swap = uncurry( fork( And(2), Or(2) ) , prefix="in") - wire( swap( io.I ), io.O ) + wire(swap(io.I), io.O) + def swap(I): return Swap()(I) @@ -26,13 +29,15 @@ class Swaps(Circuit): io = m.IO('I', In(Bits(n)), O=Out(Bits(n))) @classmethod def definition(io): - s = flat( join( map_(Swap, n//2) ), flatargs = ['I', 'O'] ) + s = flat(join(map_(Swap, n//2)), flatargs=['I', 'O']) wire(s(io.I), io.O) return Swaps + def Swaps(n): return DefineSwaps(n)() + def swaps(I): return Swaps(len(I))(I) @@ -43,14 +48,16 @@ class EvenOddSwaps(Circuit): io = m.IO('I', In(Bits(n)), O=Out(Bits(n))) @classmethod def definition(io): - s = flat( join( map_(Swap, n//2-1) ), flatargs = ['I', 'O'] ) + s = flat(join(map_(Swap, n//2-1)), flatargs=['I', 'O']) wire(io.I[0], io.O[0]) wire(s(io.I[1:-1]), io.O[1:-1]) wire(io.I[-1], io.O[-1]) return EvenOddSwaps + def EvenOddSwaps(n): return DefineEvenOddSwaps(n)() + def evenoddswaps(I): return EvenOddSwaps(len(I))(I) diff --git a/mantle/xilinx/mantle3/MUX.py b/mantle/xilinx/mantle3/MUX.py index 25ea1e8..502f717 100644 --- a/mantle/xilinx/mantle3/MUX.py +++ b/mantle/xilinx/mantle3/MUX.py @@ -3,27 +3,31 @@ from magma.bitutils import lutinit from ..spartan3.CLB import * -__all__ = ['Mux2', 'Mux4', 'Mux8', 'Mux16'] +__all__ = ['Mux2', 'Mux4', 'Mux8', 'Mux16'] __all__ += ['DefineMux', 'Mux'] # # C ? B : A # -MUX2DATA = (~A2&A0)|(A2&A1) +MUX2DATA = (~A2 & A0) | (A2 & A1) # """Construct a Mux with 2 1-bit inputs.""" + + class Mux2(Circuit): - io = m.IO(I=In(Bits[ 2 ]), S=In(Bit), O=Out(Bit) ) - + io = m.IO(I=In(Bits[2]), S=In(Bit), O=Out(Bit)) + @classmethod def definition(io): - lut = _LUT3(INIT=lutinit(MUX2DATA,1<<3)) - wire( lut(io.I[0], io.I[1], io.S), io.O) + lut = _LUT3(INIT=lutinit(MUX2DATA, 1 << 3)) + wire(lut(io.I[0], io.I[1], io.S), io.O) # """Construct a Mux with 4 1-bit inputs.""" + + class Mux4(Circuit): - io = m.IO(I=In(Bits[ 4 ]), S=In(Bits[ 2 ]), O=Out(Bit) ) - + io = m.IO(I=In(Bits[4]), S=In(Bits[2]), O=Out(Bit)) + @classmethod def definition(mux4): @@ -31,15 +35,17 @@ def definition(mux4): mux1 = Mux2() mux = MUXF5() - mux0(mux4.I[0:2],mux4.S[0]) - mux1(mux4.I[2:4],mux4.S[0]) - mux( mux0.O, mux1.O, mux4.S[1] ) - wire( mux.O, mux4.O ) + mux0(mux4.I[0:2], mux4.S[0]) + mux1(mux4.I[2:4], mux4.S[0]) + mux(mux0.O, mux1.O, mux4.S[1]) + wire(mux.O, mux4.O) # """Construct a Mux with 8 1-bit inputs.""" + + class Mux8(Circuit): - io = m.IO(I=In(Bits[ 8 ]), S=In(Bits[ 3 ]), O=Out(Bit) ) - + io = m.IO(I=In(Bits[8]), S=In(Bits[3]), O=Out(Bit)) + @classmethod def definition(mux8): @@ -47,15 +53,17 @@ def definition(mux8): mux1 = Mux4() mux = MUXF6() - mux0(mux8.I[0:4], mux8.S[0:2]) + mux0(mux8.I[0:4], mux8.S[0:2]) mux1(mux8.I[4:8], mux8.S[0:2]) - mux( mux0.O, mux1.O, mux8.S[2] ) - wire( mux.O, mux8.O ) + mux(mux0.O, mux1.O, mux8.S[2]) + wire(mux.O, mux8.O) # """Construct a Mux with 16 1-bit inputs.""" + + class Mux16(Circuit): - io = m.IO(I=In(Bits[ 16 ]), S=In(Bits[ 4 ]), O=Out(Bit) ) - + io = m.IO(I=In(Bits[16]), S=In(Bits[4]), O=Out(Bit)) + @classmethod def definition(mux16): @@ -73,20 +81,21 @@ def definition(mux16): def _MuxName(height, width): return f'Mux{height}x{width}' + def _MuxInterface(height, width): - AW = In(Bits[ width ]) - if height == 2: - args = ['I0', AW, + AW = In(Bits[width]) + if height == 2: + args = ['I0', AW, 'I1', AW] args += ['S', In(Bit)] elif height == 4: - args = ['I0', AW, + args = ['I0', AW, 'I1', AW, 'I2', AW, 'I3', AW] - args += ['S', In(Bits[ 2 ])] + args += ['S', In(Bits[2])] elif height == 8: - args = ['I0', AW, + args = ['I0', AW, 'I1', AW, 'I2', AW, 'I3', AW, @@ -94,9 +103,9 @@ def _MuxInterface(height, width): 'I5', AW, 'I6', AW, 'I7', AW] - args += ['S', In(Bits[ 3 ])] + args += ['S', In(Bits[3])] elif height == 16: - args = ['I0', AW, + args = ['I0', AW, 'I1', AW, 'I2', AW, 'I3', AW, @@ -104,7 +113,7 @@ def _MuxInterface(height, width): 'I5', AW, 'I6', AW, 'I7', AW, - 'I8', AW, + 'I8', AW, 'I9', AW, 'I10', AW, 'I11', AW, @@ -112,12 +121,13 @@ def _MuxInterface(height, width): 'I13', AW, 'I14', AW, 'I15', AW] - args += ['S', In(Bits[ 4 ])] + args += ['S', In(Bits[4])] args += ['O', Out(AW)] return args + def MuxN(height, **kwargs): assert height in [2, 4, 8, 16] @@ -130,8 +140,8 @@ def MuxN(height, **kwargs): elif height == 16: return Mux16(**kwargs) -def DefineMux(height=2, width=1, T=None): +def DefineMux(height=2, width=1, T=None): """ Construct a Mux. Height inputs are width bits wide. """ @@ -161,17 +171,21 @@ def amux(y): return curry(MuxN(height), prefix='I') mux = braid(col(amux, width), forkargs=['S']) - if height == 2: mux( Mux.I0, Mux.I1, Mux.S ) - elif height == 4: mux( Mux.I0, Mux.I1, Mux.I2, Mux.I3, Mux.S ) - elif height == 8: mux( Mux.I0, Mux.I1, Mux.I2, Mux.I3, - Mux.I4, Mux.I5, Mux.I6, Mux.I7, Mux.S ) - elif height == 16: mux( Mux.I0, Mux.I1, Mux.I2, Mux.I3, - Mux.I4, Mux.I5, Mux.I6, Mux.I7, - Mux.I8, Mux.I9, Mux.I10, Mux.I11, - Mux.I12, Mux.I13, Mux.I14, Mux.I15, Mux.S ) - wire( mux.O, Mux.O ) + if height == 2: + mux(Mux.I0, Mux.I1, Mux.S) + elif height == 4: + mux(Mux.I0, Mux.I1, Mux.I2, Mux.I3, Mux.S) + elif height == 8: + mux(Mux.I0, Mux.I1, Mux.I2, Mux.I3, + Mux.I4, Mux.I5, Mux.I6, Mux.I7, Mux.S) + elif height == 16: + mux(Mux.I0, Mux.I1, Mux.I2, Mux.I3, + Mux.I4, Mux.I5, Mux.I6, Mux.I7, + Mux.I8, Mux.I9, Mux.I10, Mux.I11, + Mux.I12, Mux.I13, Mux.I14, Mux.I15, Mux.S) + wire(mux.O, Mux.O) return _Mux + def Mux(height=2, width=None, T=None, **kwargs): return DefineMux(height, width, T)(**kwargs) - diff --git a/mantle/xilinx/mantle3/arith.py b/mantle/xilinx/mantle3/arith.py index d7c66e7..16fe117 100644 --- a/mantle/xilinx/mantle3/arith.py +++ b/mantle/xilinx/mantle3/arith.py @@ -3,10 +3,11 @@ from .logic import Not from .cascade import FullCascade -__all__ = ['DefineAdd'] +__all__ = ['DefineAdd'] __all__ += ['DefineSub'] __all__ += ['DefineNegate'] + def _Name(basename, n, cin, cout): name = basename + str(n) if cin is 0 or cin is 1: @@ -17,6 +18,7 @@ def _Name(basename, n, cin, cout): name += '_cout' return name + def _Args(n, cin, cout): T = Bits[n] @@ -33,20 +35,22 @@ def _Args(n, cin, cout): return args # -# Create an n-bit Add +# Create an n-bit Add # # I0:In(Bits(n)), I1:In(Bits(n)), CIN:In(Bit), O:Out(Bits(n)), COUT:Out(Bit) # # if cin, CIN is added to the circuit # if cout: COUT is added to the circuit # + + def DefineAdd(n, cin=0, cout=False): class _Add(Circuit): name = _Name('Add', n, cin, cout) IO = _Args(n, cin, cout) @classmethod def definition(io): - add = FullCascade(n, 2, A0^A1, A0, cin, cout) + add = FullCascade(n, 2, A0 ^ A1, A0, cin, cout) wire(io.I0, add.I0) wire(io.I1, add.I1) wire(add.O, io.O) @@ -55,7 +59,7 @@ def definition(io): if cout is True: wire(add.COUT, io.COUT) return _Add - + def DefineSub(n, cin=1, cout=False): class _Sub(Circuit): @@ -63,24 +67,25 @@ class _Sub(Circuit): IO = _Args(n, cin, cout) @classmethod def definition(io): - sub = FullCascade(n, 2, A0^~A1, A0, cin, cout) + sub = FullCascade(n, 2, A0 ^ ~A1, A0, cin, cout) wire(io.I0, sub.I0) wire(io.I1, sub.I1) wire(sub.O, io.O) if cin is True: - wire( Not()(io.CIN), sub.CIN ) + wire(Not()(io.CIN), sub.CIN) if cout is True: wire(sub.COUT, io.COUT) return _Sub + def DefineNegate(n): T = Bits[n] + class _Negate(Circuit): name = 'Negate{}'.format(n) io = m.IO('I', In(T), 'O', Out(T)) @classmethod def definition(io): - sub = DefineSub(n)() - wire( sub( uint(0,n), io.I ), io.O ) + sub = DefineSub(n)() + wire(sub(uint(0, n), io.I), io.O) return _Negate - diff --git a/mantle/xilinx/mantle3/compare.py b/mantle/xilinx/mantle3/compare.py index 961ff2c..f8f6bee 100644 --- a/mantle/xilinx/mantle3/compare.py +++ b/mantle/xilinx/mantle3/compare.py @@ -4,7 +4,7 @@ from .logic import Not from .cascade import HalfCascade -__all__ = ['DefineEQ', 'EQ'] +__all__ = ['DefineEQ', 'EQ'] __all__ += ['DefineNE', 'NE'] __all__ += ['DefineUGE'] __all__ += ['DefineULE'] @@ -15,81 +15,92 @@ __all__ += ['DefineSGT'] __all__ += ['DefineSLT'] -EQ1LUT = ((A0&A1)|(~A0&~A1)) -EQ2LUT = ((A0&A1)|(~A0&~A1)) & ((A2&A3)|(~A2&~A3)) +EQ1LUT = ((A0 & A1) | (~A0 & ~A1)) +EQ2LUT = ((A0 & A1) | (~A0 & ~A1)) & ((A2 & A3) | (~A2 & ~A3)) + class EQ1(Circuit): io = m.IO(I0=In(Bit), I1=In(Bit), O=Out(Bit)) @classmethod def definition(io): - wire( LUT2(EQ1LUT)(io.I0, io.I1), io.O ) + wire(LUT2(EQ1LUT)(io.I0, io.I1), io.O) + class EQ2(Circuit): - T = Bits[ 2 ] + T = Bits[2] io = m.IO(I0=In(T), I1=In(T), O=Out(Bit)) @classmethod def definition(io): - wire( LUT4(EQ2LUT)(io.I0[0], io.I1[0], io.I0[1], io.I1[1]), io.O ) + wire(LUT4(EQ2LUT)(io.I0[0], io.I1[0], io.I0[1], io.I1[1]), io.O) + def DefineEQ(n): assert n % 2 == 0 - T = Bits[ n ] + T = Bits[n] + class _EQ(Circuit): name = "EQ{}".format(n) io = m.IO('I0', In(T), 'I1', In(T), O=Out(Bit)) @classmethod def definition(io): - eq = HalfCascade(n//2, 4, EQ2LUT, ZERO, 1) - for i in range(n//2): - wire(io.I0[2*i], eq.I0[i]) - wire(io.I1[2*i], eq.I1[i]) - wire(io.I0[2*i+1], eq.I2[i]) - wire(io.I1[2*i+1], eq.I3[i]) - wire(eq.O, io.O) + eq = HalfCascade(n//2, 4, EQ2LUT, ZERO, 1) + for i in range(n//2): + wire(io.I0[2*i], eq.I0[i]) + wire(io.I1[2*i], eq.I1[i]) + wire(io.I0[2*i+1], eq.I2[i]) + wire(io.I1[2*i+1], eq.I3[i]) + wire(eq.O, io.O) return _EQ + def EQ(n, **kwargs): - if n == 1: + if n == 1: return EQ1(**kwargs) elif n == 2: return EQ2(**kwargs) return DefineEQ(n)(**kwargs) -NE1LUT = (A0^A1) -NE2LUT = (A0^A1)|(A2^A3) + +NE1LUT = (A0 ^ A1) +NE2LUT = (A0 ^ A1) | (A2 ^ A3) + class NE1(Circuit): io = m.IO(I0=In(Bit), I1=In(Bit), O=Out(Bit)) @classmethod def definition(io): - wire( LUT2(NE1LUT)(io.I0, io.I1), io.O ) + wire(LUT2(NE1LUT)(io.I0, io.I1), io.O) + class NE2(Circuit): - T = Bits[ 2 ] + T = Bits[2] io = m.IO(I0=In(T), I1=In(T), O=Out(Bit)) @classmethod def definition(io): - wire( LUT4(NE2LUT)(io.I0[0], io.I1[0], io.I0[1], io.I1[1]), io.O ) + wire(LUT4(NE2LUT)(io.I0[0], io.I1[0], io.I0[1], io.I1[1]), io.O) + def DefineNE(n): assert n % 2 == 0 - T = Bits[ n ] + T = Bits[n] + class _NE(Circuit): name = "NE{}".format(n) io = m.IO('I0', In(T), 'I1', In(T), O=Out(Bit)) @classmethod def definition(io): - ne = HalfCascade(n//2, 4, NE2LUT, ZERO, 1) - for i in range(n//2): - wire(io.I0[2*i], ne.I0[i]) - wire(io.I1[2*i], ne.I1[i]) - wire(io.I0[2*i+1], ne.I2[i]) - wire(io.I1[2*i+1], ne.I3[i]) - wire(ne.O, io.O) + ne = HalfCascade(n//2, 4, NE2LUT, ZERO, 1) + for i in range(n//2): + wire(io.I0[2*i], ne.I0[i]) + wire(io.I1[2*i], ne.I1[i]) + wire(io.I0[2*i+1], ne.I2[i]) + wire(io.I1[2*i+1], ne.I3[i]) + wire(ne.O, io.O) return _NE + def NE(n, **kwargs): - if n == 1: + if n == 1: return NE1(**kwargs) elif n == 2: return NE2(**kwargs) @@ -100,12 +111,13 @@ def NE(n, **kwargs): def DefineUCMP(opname, reverse, negate, n): T = UInt[n] + class _UCMP(Circuit): name = "{}{}".format(opname, n) io = m.IO('I0', In(T), 'I1', In(T), O=Out(Bit)) @classmethod def definition(io): - sub = DefineSub(n,1,True)() + sub = DefineSub(n, 1, True)() if not reverse: sub(io.I0, io.I1) else: @@ -116,15 +128,19 @@ def definition(io): wire(Not()(sub.COUT), io.O) return _UCMP + def DefineUGE(n): return DefineUCMP('UGE', False, False, n) + def DefineULE(n): return DefineUCMP('ULE', True, False, n) + def DefineULT(n): return DefineUCMP('ULT', False, True, n) + def DefineUGT(n): return DefineUCMP('UGT', True, True, n) @@ -134,33 +150,39 @@ def DefineUGT(n): def _sge(c_msb, a_msb, b_msb): return int((~(a_msb ^ b_msb) & ~c_msb) | (~a_msb & b_msb)) & 1 + def _slt(c_msb, a_msb, b_msb): return int((~(a_msb ^ b_msb) & c_msb) | (a_msb & ~b_msb)) & 1 + def DefineSCMP(opname, op, reverse, n): T = SInt[n] + class _SCMP(Circuit): - name = "{}{}".format(opname,n) + name = "{}{}".format(opname, n) io = m.IO('I0', In(T), 'I1', In(T), O=Out(Bit)) @classmethod def definition(io): sub = DefineSub(n)() cmp = LUT3(op) if not reverse: - wire(cmp( sub(io.I0, io.I1)[-1], io.I0[-1], io.I1[-1] ), io.O) + wire(cmp(sub(io.I0, io.I1)[-1], io.I0[-1], io.I1[-1]), io.O) else: - wire(cmp( sub(io.I1, io.I0)[-1], io.I1[-1], io.I0[-1] ), io.O) + wire(cmp(sub(io.I1, io.I0)[-1], io.I1[-1], io.I0[-1]), io.O) return _SCMP + def DefineSGE(n): return DefineSCMP('SGE', _sge, False, n) + def DefineSLE(n): return DefineSCMP('SLE', _sge, True, n) + def DefineSLT(n): return DefineSCMP('SLT', _slt, False, n) + def DefineSGT(n): return DefineSCMP('SGT', _slt, True, n) - diff --git a/mantle/xilinx/mantle3/decode.py b/mantle/xilinx/mantle3/decode.py index 67f386c..343619a 100644 --- a/mantle/xilinx/mantle3/decode.py +++ b/mantle/xilinx/mantle3/decode.py @@ -3,7 +3,8 @@ from .ROM import ROMN from .cascade import FlatHalfCascade -__all__ = ['DefineDecode', 'Decode', 'decode'] +__all__ = ['DefineDecode', 'Decode', 'decode'] + def DefineDecode(i, n, invert=False): """ @@ -29,15 +30,17 @@ def definition(io): nluts = (n + 3) // 4 data = nluts * [0] for j in range(nluts): - data[j] = (i >> 4*j) & 0xf # 4-bit pieces + data[j] = (i >> 4*j) & 0xf # 4-bit pieces decode = FlatHalfCascade(n, 4, data, ZERO, 1) wire(io.I, decode.I) wire(decode.O, io.O) return _Decode + def Decode(i, n, invert=False): return DefineDecode(i, n, invert=invert)() + def decode(I, i, invert=False): return Decode(i, len(I), invert=invert)(I) diff --git a/mantle/xilinx/mantle3/fulladder.py b/mantle/xilinx/mantle3/fulladder.py index f0d0dc1..277e3be 100644 --- a/mantle/xilinx/mantle3/fulladder.py +++ b/mantle/xilinx/mantle3/fulladder.py @@ -3,15 +3,16 @@ __all__ = ['FullAdder', 'fulladder'] + class FullAdder(Circuit): io = m.IO(I0=In(Bit), I1=In(Bit), I2=In(Bit), O=Out(Bit), COUT=Out(Bit)) @classmethod def definition(io): - s = LUT3(A0^A1^A2) - c = LUT3(A0&A1|A1&A2|A2&A0) - wire( s(io.I0, io.I1, io.I2), io.O ) - wire( c(io.I0, io.I1, io.I2), io.COUT ) + s = LUT3(A0 ^ A1 ^ A2) + c = LUT3(A0 & A1 | A1 & A2 | A2 & A0) + wire(s(io.I0, io.I1, io.I2), io.O) + wire(c(io.I0, io.I1, io.I2), io.COUT) + def fulladder(a, b, c): return FullAdder()(a, b, c) - diff --git a/mantle/xilinx/mantle3/halfadder.py b/mantle/xilinx/mantle3/halfadder.py index 56bfaea..c20972d 100644 --- a/mantle/xilinx/mantle3/halfadder.py +++ b/mantle/xilinx/mantle3/halfadder.py @@ -1,17 +1,18 @@ from magma import * from .LUT import LUT2, A0, A1 -__all__ = ["HalfAdder", 'halfadder'] +__all__ = ["HalfAdder", 'halfadder'] + class HalfAdder(Circuit): io = m.IO(I0=In(Bit), I1=In(Bit), O=Out(Bit), COUT=Out(Bit)) @classmethod def definition(io): - s = LUT2(A0^A1) - c = LUT2(A0&A1) - wire( s(io.I0, io.I1), io.O ) - wire( c(io.I0, io.I1), io.COUT ) - + s = LUT2(A0 ^ A1) + c = LUT2(A0 & A1) + wire(s(io.I0, io.I1), io.O) + wire(c(io.I0, io.I1), io.COUT) + + def halfadder(a, b): return HalfAdder()(a, b) - diff --git a/mantle/xilinx/mantle3/logic.py b/mantle/xilinx/mantle3/logic.py index a12a793..d3218cc 100644 --- a/mantle/xilinx/mantle3/logic.py +++ b/mantle/xilinx/mantle3/logic.py @@ -1,17 +1,17 @@ from __future__ import division +from .cascade import FlatHalfCascade +from .ROM import ROMN +from .LUT import LUT, LUT1, LUT2, LUT3, LUT4, A0, A1, A2, A3, ZERO, ONE +from magma import * +from collections.abc import Sequence import sys if sys.version_info > (3, 0): from functools import reduce from functools import lru_cache -from collections.abc import Sequence -from magma import * -from .LUT import LUT, LUT1, LUT2, LUT3, LUT4, A0, A1, A2, A3, ZERO, ONE -from .ROM import ROMN -from .cascade import FlatHalfCascade # unary operators -__all__ = ['DefineReduceAnd', 'ReduceAnd'] +__all__ = ['DefineReduceAnd', 'ReduceAnd'] __all__ += ['DefineReduceNAnd', 'ReduceNAnd'] __all__ += ['DefineReduceOr', 'ReduceOr'] __all__ += ['DefineReduceNOr', 'ReduceNOr'] @@ -33,9 +33,12 @@ # # Efficient Reduction using carry chain and FlatHalfCascade # + + def DefineReduceOp(opname, n, lutexprs, andexpr, cin): #assert n % 4 == 0 - T = Bits[ n ] + T = Bits[n] + class _ReduceOp(Circuit): name = '{}{}'.format(opname, n) io = m.IO('I', In(T), 'O', Out(Bit)) @@ -43,7 +46,7 @@ class _ReduceOp(Circuit): @classmethod def definition(io): I = io.I - if n <= 4: #8? + if n <= 4: # 8? a = ROMN(lutexprs[n - 1], n) else: nluts = 4 * ((n + 3) // 4) @@ -53,80 +56,100 @@ def definition(io): wire(a(I), io.O) return _ReduceOp + def DefineReduceAnd(n): - luts = [A0, A0&A1, A0&A1&A2, A0&A1&A2&A3] + luts = [A0, A0 & A1, A0 & A1 & A2, A0 & A1 & A2 & A3] return DefineReduceOp('And', n, luts, ZERO, 1) + def ReduceAnd(height=2, **kwargs): return DefineReduceAnd(height)(**kwargs) + def DefineReduceNAnd(n): - luts = [A0, A0&A1, A0&A1&A2, A0&A1&A2&A3] + luts = [A0, A0 & A1, A0 & A1 & A2, A0 & A1 & A2 & A3] return DefineReduceOp('NAnd', n, luts, ONE, 0) + def ReduceNAnd(height=2, **kwargs): return DefineReduceNAnd(height)(**kwargs) + def DefineReduceOr(n): - luts = [~A0, ~(A0|A1), ~(A0|A1|A2), ~(A0|A1|A2|A3)] + luts = [~A0, ~(A0 | A1), ~(A0 | A1 | A2), ~(A0 | A1 | A2 | A3)] return DefineReduceOp('Or', n, luts, ONE, 0) + def ReduceOr(height=2, **kwargs): return DefineReduceOr(height)(**kwargs) + def DefineReduceNOr(n): - luts = [~A0, ~(A0|A1), ~(A0|A1|A2), ~(A0|A1|A2|A3)] + luts = [~A0, ~(A0 | A1), ~(A0 | A1 | A2), ~(A0 | A1 | A2 | A3)] return DefineReduceOp('NOr', n, luts, ZERO, 1) + def ReduceNOr(height=2, **kwargs): return DefineReduceNOr(height)(**kwargs) + def LUTCascade(n, k, expr, cin): - def f(y): - e = expr[y] if isinstance(expr, Sequence) else expr - return LUT( e, n=k+1 ) + def f(y): + e = expr[y] if isinstance(expr, Sequence) else expr + return LUT(e, n=k+1) - # number of luts - m = (n+k-1) // k - c = braid( col(f, m), foldargs={"I0":"O"}) + # number of luts + m = (n+k-1) // k + c = braid(col(f, m), foldargs={"I0": "O"}) - wire(cin, c.I0) + wire(cin, c.I0) - c = flat(uncurry(c)) + c = flat(uncurry(c)) - for i in range(n, len(c.I)): - wire(cin, c.I[i]) + for i in range(n, len(c.I)): + wire(cin, c.I[i]) + + return AnonymousCircuit(['I', c.I[0:n], 'O', c.O]) - return AnonymousCircuit( ['I', c.I[0:n], 'O', c.O] ) def DefineReduceLUT(opname, n, luts, cascadeexpr, cin): - T = Bits[ n ] + T = Bits[n] + class _ReduceLUT(Circuit): name = '{}{}'.format(opname, n) io = m.IO('I', In(T), 'O', Out(Bit)) @classmethod def definition(io): - if n == 1: a = uncurry(LUT1(luts[n - 1])) - elif n == 2: a = uncurry(LUT2(luts[n - 1])) - elif n == 3: a = uncurry(LUT3(luts[n - 1])) - elif n == 4: a = uncurry(LUT4(luts[n - 1])) - else: a = LUTCascade(n, 1, cascadeexpr, cin) + if n == 1: + a = uncurry(LUT1(luts[n - 1])) + elif n == 2: + a = uncurry(LUT2(luts[n - 1])) + elif n == 3: + a = uncurry(LUT3(luts[n - 1])) + elif n == 4: + a = uncurry(LUT4(luts[n - 1])) + else: + a = LUTCascade(n, 1, cascadeexpr, cin) wire(a(io.I), io.O) return _ReduceLUT + def DefineReduceXOr(n): - luts = [A0, A0^A1, A0^A1^A2, A0^A1^A2^A3] + luts = [A0, A0 ^ A1, A0 ^ A1 ^ A2, A0 ^ A1 ^ A2 ^ A3] return DefineReduceLUT('XOr', n, luts, A0 ^ A1, 0) + def ReduceXOr(height=2, **kwargs): return DefineReduceXOr(height)(**kwargs) + def DefineReduceNXOr(n): - luts = [~A0, ~(A0^A1), ~(A0^A1^A2), ~(A0^A1^A2^A3)] + luts = [~A0, ~(A0 ^ A1), ~(A0 ^ A1 ^ A2), ~(A0 ^ A1 ^ A2 ^ A3)] return DefineReduceLUT('NXOr', n, luts, A0 ^ ~A1, 1) + def ReduceNXOr(height=2, **kwargs): return DefineReduceNXOr(height)(**kwargs) @@ -137,13 +160,13 @@ def DefineOp(opname, op, height=2, width=1): I0 : In(Bits(width)), I1 : In(Bits(width)), O : Out(Bits(width)) """ - T = Bits[ width ] + T = Bits[width] class _Op(Circuit): name = '{}{}x{}'.format(opname, height, width) IO = sum([['I{}'.format(i), In(T)] for i in range(height)], []) - IO += ['O', Out(T)] + IO += ['O', Out(T)] @classmethod def definition(io): @@ -155,49 +178,61 @@ def opm(y): wire(opmxn.O, io.O) return _Op + def DefineAnd(height=2, width=1): return DefineOp('And', ReduceAnd, height, width) + def And(height=2, width=None, **kwargs): if width is None: return curry(ReduceAnd(height, **kwargs)) return DefineAnd(height, width)(**kwargs) + def DefineNAnd(height=2, width=None): return DefineOp('NAnd', ReduceNAnd, height, width) + def NAnd(height=2, width=None, **kwargs): if width is None: return curry(ReduceNAnd(height, **kwargs)) return DefineNAnd(height, width)(**kwargs) + def DefineOr(height=2, width=None): return DefineOp('Or', ReduceOr, height, width) + def Or(height=2, width=None, **kwargs): if width is None: return curry(ReduceOr(height, **kwargs)) return DefineOr(height, width)(**kwargs) + def DefineNOr(height=2, width=None): return DefineOp('NOr', ReduceNOr, height, width) + def NOr(height=2, width=None, **kwargs): if width is None: return curry(ReduceNOr(height, **kwargs)) return DefineNOr(height, width)(**kwargs) + def DefineXOr(height=2, width=None): return DefineOp('XOr', ReduceXOr, height, width) + def XOr(height=2, width=None, **kwargs): if width is None: return curry(ReduceXOr(height, **kwargs)) return DefineXOr(height, width)(**kwargs) + def DefineNXOr(height=2, width=None): return DefineOp('NXOr', ReduceNXOr, height, width) + def NXOr(height=2, width=None, **kwargs): if width is None: return curry(ReduceNXOr(height, **kwargs)) @@ -211,7 +246,8 @@ def DefineInvert(width): I0 : Bits(width) -> O : Bits(width) """ - T = Bits[ width ] + T = Bits[width] + class _Invert(Circuit): name = 'Invert%d' % width io = m.IO('I', In(T), 'O', Out(T)) @@ -226,6 +262,7 @@ def not_(y): return _Invert + def Invert(n, **kwargs): return DefineInvert(n)(**kwargs) @@ -233,4 +270,3 @@ def Invert(n, **kwargs): def Not(**kwargs): """Not gate - 1-bit input.""" return LUT1(~A0, **kwargs) - diff --git a/mantle/xilinx/mantle3/mothball/_halfcascade.py b/mantle/xilinx/mantle3/mothball/_halfcascade.py index c76de16..6236c03 100644 --- a/mantle/xilinx/mantle3/mothball/_halfcascade.py +++ b/mantle/xilinx/mantle3/mothball/_halfcascade.py @@ -3,27 +3,29 @@ from .LUT import LUTN, LOG_BITS_PER_LUT, A0, A1, A2, A3, ZERO, ONE from .carry import HalfCarry -__all__ = ['DefineFlatHalfCascade', 'FlatCascade'] +__all__ = ['DefineFlatHalfCascade', 'FlatCascade'] #__all__ += ['AndCascade', 'NAndCascade', 'OrCascade', 'NOrCascade'] __all__ += ['DefineHalfCascade', 'HalfCascade'] + def InputArgs(n, k, forkargs): T = Bits(n) I = [] for i in range(k): - name = "I{}".format(i) - I.append(name) - I.append(In(Bit) if name in forkargs else In(T)) + name = "I{}".format(i) + I.append(name) + I.append(In(Bit) if name in forkargs else In(T)) return I + def _CascadeName(name, n, lutexpr, andexpr, cin): if isinstance(lutexpr, Sequence): lutexpr = "_".join(["%04X" % (e & 0xffff) for e in lutexpr]) else: lutexpr = "%04X" % (lutexpr & 0xffff) andexpr = "%04X" % (andexpr & 0xffff) - return '%s%d_%s_%s_%d' % (name ,n, lutexpr, andexpr, cin) + return '%s%d_%s_%s_%d' % (name, n, lutexpr, andexpr, cin) # # Build a column of LUTs feeding into MUXCY. In the Half version @@ -37,13 +39,16 @@ def _CascadeName(name, n, lutexpr, andexpr, cin): # lutexpr is the expression that goes into each LUT # # The output of MUXCY is selected by the output of the LUT -# cin is the value going into the first MUXCY in the column +# cin is the value going into the first MUXCY in the column # + + def DefineFlatHalfCascade(n, k, lutexpr, andexpr, cin, name=None): if name is None: nm = _CascadeName('FlatHalfCascade', n, lutexpr, andexpr, cin) else: nm = name + str(n) + class _FlatHalfCascade(Circuit): name = nm io = m.IO(I=In(Bits(n)), O=Out(Bit)) @@ -56,9 +61,9 @@ def f(y): # calculate number of LUTs nluts = (n+LOG_BITS_PER_LUT-1)//LOG_BITS_PER_LUT - c = braid( col(f, nluts), foldargs={"CIN":"COUT"}) + c = braid(col(f, nluts), foldargs={"CIN": "COUT"}) c = flat(c) - #print(repr(c)) + # print(repr(c)) for i in range(LOG_BITS_PER_LUT*nluts): wire(io.I[i], c.I[i]) @@ -67,19 +72,20 @@ def f(y): return _FlatHalfCascade + def FlatHalfCascade(n, k, lutexpr, andexpr, cin, name=None): return DefineFlatHalfCascade(n, k, lutexpr, andexpr, cin, name=name)() -#def AndCascade( n ): +# def AndCascade( n ): # return FlatHalfCascade(n, 4, A0&A1&A2&A3, ZERO, 1, 'AndCascade') # -#def NAndCascade( n ): +# def NAndCascade( n ): # return FlatHalfCascade(n, 4, A0&A1&A2&A3, ONE, 0) # -#def OrCascade( n ): +# def OrCascade( n ): # return FlatHalfCascade(n, 4, ~(A0|A1|A2|A3), ONE, 0) # -#def NOrCascade( n ): +# def NOrCascade( n ): # return FlatHalfCascade(n, 4, ~(A0|A1|A2|A3), ZERO, 1) @@ -88,6 +94,7 @@ def DefineHalfCascade(n, k, lutexpr, andexpr, cin, forkargs={}, name=None): nm = _CascadeName('HalfCascade', n, lutexpr, andexpr, cin) else: nm = '{}_{}'.format(name, n) + class _HalfCascade(Circuit): name = nm IO = InputArgs(n, k, forkargs) + ["O", Out(Bit)] @@ -97,23 +104,28 @@ def f(y): e = lutexpr[y] if isinstance(lutexpr, Sequence) else lutexpr return HalfCarry(k, e, andexpr) - c = braid( col(f, n), foldargs={"CIN":"COUT"}, forkargs=forkargs) - #print(repr(c)) - if k >= 1: wire(io.I0, c.I0) - if k >= 2: wire(io.I1, c.I1) - if k >= 3: wire(io.I2, c.I2) - if k >= 4: wire(io.I3, c.I3) + c = braid(col(f, n), foldargs={"CIN": "COUT"}, forkargs=forkargs) + # print(repr(c)) + if k >= 1: + wire(io.I0, c.I0) + if k >= 2: + wire(io.I1, c.I1) + if k >= 3: + wire(io.I2, c.I2) + if k >= 4: + wire(io.I3, c.I3) wire(c.COUT, io.O) wire(cin, c.CIN) return _HalfCascade + def HalfCascade(n, k, lutexpr, andexpr, cin, forkargs={}, name=None): return DefineHalfCascade(n, k, lutexpr, andexpr, cin, forkargs, name)() # -#def _Name(n, k, expr1, expr2, cin): +# def _Name(n, k, expr1, expr2, cin): # assert not isinstance(expr1, Sequence) # #if isinstance(expr1, Sequence): # # expr1 = seq2int(expr1) @@ -123,39 +135,39 @@ def HalfCascade(n, k, lutexpr, andexpr, cin, forkargs={}, name=None): # return 'Cascade%dx%d_%X_%X_%d' % (n, k, expr1, expr2, cin) # ## -## Create circuit consisting of an LUT feeding into MUXCY. +# Create circuit consisting of an LUT feeding into MUXCY. ## ## -## LUT -## k is the number of input bits -## expr1 is what goes into the LUT +# LUT +# k is the number of input bits +# expr1 is what goes into the LUT ## -## MUXCY -## the output of the LUT selects the output -## expr2 selects what goes into the 0 slot -## A0 -## A1 -## A0&A1 -## ZERO -## ONE -## CIN goes into the 1 slot +# MUXCY +# the output of the LUT selects the output +# expr2 selects what goes into the 0 slot +# A0 +# A1 +# A0&A1 +# ZERO +# ONE +# CIN goes into the 1 slot ## -## The resulting circuit has the following interface +# The resulting circuit has the following interface ## -## ['I0', rom.I0, ..., 'Ik", rom.Ik, "COUT", mux.COUT, "CIN", CIN] +# ['I0', rom.I0, ..., 'Ik", rom.Ik, "COUT", mux.COUT, "CIN", CIN] ## -##def FullCascade(k, expr1, expr2): +# def FullCascade(k, expr1, expr2): ## ## assert k <= 4 ## ## lut = LUTN(expr1, k) ## ## args = [] -## if k >= 1: +# if k >= 1: ## I0 = Bit() ## wire(I0, lut.I0) ## args += ['I0', I0] -## if k >= 2: +# if k >= 2: ## I1 = Bit() ## wire(I1, lut.I1) ## args += ['I1', I1] @@ -163,18 +175,18 @@ def HalfCascade(n, k, lutexpr, andexpr, cin, forkargs={}, name=None): ## if k >= 4: args += ['I3', lut.I3] ## ## -## if expr2 == A0&A1: +# if expr2 == A0&A1: ## and1 = ANDCY() ## wire(I0, and1.I0) ## wire(I1, and1.I1) ## DI = and1.LO -## elif expr2 == A0: +# elif expr2 == A0: ## DI = I0 -## elif expr2 == A1: +# elif expr2 == A1: ## DI = I1 -## elif expr2 == ZERO: +# elif expr2 == ZERO: ## DI = 0 -## elif expr2 == ONE: +# elif expr2 == ONE: ## DI = 1 ## ## CIN = Bit() @@ -185,21 +197,21 @@ def HalfCascade(n, k, lutexpr, andexpr, cin, forkargs={}, name=None): ## wire(CIN, mux.CI) ## ## args += ["COUT", mux.O, "CIN", CIN] -## return AnonymousCircuit( args ) +# return AnonymousCircuit( args ) # # ## -## k is the number of bits per input -## n is the number of inputs -## expr1 goes into LUT -## expr2 goes into DIN +# k is the number of bits per input +# n is the number of inputs +# expr1 goes into LUT +# expr2 goes into DIN # -## cin is a constant carry in: 0 or 1 +# cin is a constant carry in: 0 or 1 ## -## the inputs are either forked or joined, depending on forkargs -## I0 : Bit/Array(n,Bit), ..., Ik : Bit/Array(n,Bit) -> O : Bit +# the inputs are either forked or joined, depending on forkargs +# I0 : Bit/Array(n,Bit), ..., Ik : Bit/Array(n,Bit) -> O : Bit ## -##def DefineHalfCascade(n, k, expr1, expr2, cin, forkargs={}): +# def DefineHalfCascade(n, k, expr1, expr2, cin, forkargs={}): ## ## T = In(Bits(n)) ## args = [] @@ -209,15 +221,15 @@ def HalfCascade(n, k, lutexpr, andexpr, cin, forkargs={}, name=None): ## if k >= 4: args += ["I3", In(Bit) if 'I3' in forkargs else T] ## args += ["O", Out(Bit)] ## -## class _HalfCascade(Circuit): +# class _HalfCascade(Circuit): ## name = _CascadeName('HalfCascade', n, k, expr1, expr2, cin, 0) ## IO = args ## -## @classmethod -## def definition(io): +# @classmethod +# def definition(io): ## -## def f(y): -## return HalfCarry(k, expr1, expr2) +# def f(y): +# return HalfCarry(k, expr1, expr2) ## ## c = braid( col(f, n), foldargs={"CIN":"COUT"}, forkargs=forkargs ) ## @@ -228,7 +240,7 @@ def HalfCascade(n, k, lutexpr, andexpr, cin, forkargs={}, name=None): ## wire(c.COUT, io.O) ## wire(cin, c.CIN) ## -## return _HalfCascade +# return _HalfCascade ## # # diff --git a/mantle/xilinx/mantle6/MUX.py b/mantle/xilinx/mantle6/MUX.py index dc4bb42..fbf4b51 100644 --- a/mantle/xilinx/mantle6/MUX.py +++ b/mantle/xilinx/mantle6/MUX.py @@ -3,33 +3,38 @@ from magma.bitutils import lutinit from ..spartan6.CLB import * -__all__ = ['Mux2', 'Mux4', 'Mux8', 'Mux16'] +__all__ = ['Mux2', 'Mux4', 'Mux8', 'Mux16'] __all__ += ['DefineMux', 'Mux'] # """Construct a Mux with 2 1-bit inputs.""" class Mux2(Circuit): - io = m.IO(I=In(Bits[ 2 ]), S=In(Bit), O=Out(Bit) ) + io = m.IO(I=In(Bits[2]), S=In(Bit), O=Out(Bit)) @classmethod def definition(io): - MUX2DATA = (~A2&A0)|(A2&A1) - lut = _LUT3(INIT=lutinit(MUX2DATA,1<<3)) - wire( lut(io.I[0], io.I[1], io.S), io.O) + MUX2DATA = (~A2 & A0) | (A2 & A1) + lut = _LUT3(INIT=lutinit(MUX2DATA, 1 << 3)) + wire(lut(io.I[0], io.I[1], io.S), io.O) # """Construct a Mux with 4 1-bit inputs.""" + + class Mux4(Circuit): - io = m.IO(I=In(Bits[ 4 ]), S=In(Bits[ 2 ]), O=Out(Bit) ) + io = m.IO(I=In(Bits[4]), S=In(Bits[2]), O=Out(Bit)) @classmethod def definition(io): - MUX4DATA = (~A4&~A5&A0)|(A4&~A5&A1)|(~A4&A5&A2)|(A4&A5&A3) - lut = _LUT6(INIT=lutinit(MUX4DATA,1<<6)) - wire( lut(io.I[0], io.I[1], io.I[2], io.I[3], io.S[0], io.S[1]), io.O) + MUX4DATA = (~A4 & ~A5 & A0) | (A4 & ~A5 & A1) | ( + ~A4 & A5 & A2) | (A4 & A5 & A3) + lut = _LUT6(INIT=lutinit(MUX4DATA, 1 << 6)) + wire(lut(io.I[0], io.I[1], io.I[2], io.I[3], io.S[0], io.S[1]), io.O) # """Construct a Mux with 8 1-bit inputs.""" + + class Mux8(Circuit): - io = m.IO(I=In(Bits[ 8 ]), S=In(Bits[ 3 ]), O=Out(Bit) ) + io = m.IO(I=In(Bits[8]), S=In(Bits[3]), O=Out(Bit)) @classmethod def definition(mux8): @@ -40,12 +45,14 @@ def definition(mux8): mux0(mux8.I[0:4], mux8.S[0:2]) mux1(mux8.I[4:8], mux8.S[0:2]) - mux( mux0.O, mux1.O, mux8.S[2] ) - wire( mux.O, mux8.O ) + mux(mux0.O, mux1.O, mux8.S[2]) + wire(mux.O, mux8.O) # """Construct a Mux with 16 1-bit inputs.""" + + class Mux16(Circuit): - io = m.IO(I=In(Bits[ 16 ]), S=In(Bits[ 4 ]), O=Out(Bit) ) + io = m.IO(I=In(Bits[16]), S=In(Bits[4]), O=Out(Bit)) @classmethod def definition(mux16): @@ -64,20 +71,21 @@ def definition(mux16): def _MuxName(height, width): return f'Mux{height}x{width}' + def _MuxInterface(height, width): - AW = In(Bits[ width ]) - if height == 2: - args = ['I0', AW, + AW = In(Bits[width]) + if height == 2: + args = ['I0', AW, 'I1', AW] args += ['S', In(Bit)] elif height == 4: - args = ['I0', AW, + args = ['I0', AW, 'I1', AW, 'I2', AW, 'I3', AW] - args += ['S', In(Bits[ 2 ])] + args += ['S', In(Bits[2])] elif height == 8: - args = ['I0', AW, + args = ['I0', AW, 'I1', AW, 'I2', AW, 'I3', AW, @@ -85,9 +93,9 @@ def _MuxInterface(height, width): 'I5', AW, 'I6', AW, 'I7', AW] - args += ['S', In(Bits[ 3 ])] + args += ['S', In(Bits[3])] elif height == 16: - args = ['I0', AW, + args = ['I0', AW, 'I1', AW, 'I2', AW, 'I3', AW, @@ -95,7 +103,7 @@ def _MuxInterface(height, width): 'I5', AW, 'I6', AW, 'I7', AW, - 'I8', AW, + 'I8', AW, 'I9', AW, 'I10', AW, 'I11', AW, @@ -103,12 +111,13 @@ def _MuxInterface(height, width): 'I13', AW, 'I14', AW, 'I15', AW] - args += ['S', In(Bits[ 4 ])] + args += ['S', In(Bits[4])] args += ['O', Out(AW)] return args + def MuxN(height, **kwargs): assert height in [2, 4, 8, 16] @@ -121,8 +130,8 @@ def MuxN(height, **kwargs): elif height == 16: return Mux16(**kwargs) -def DefineMux(height=2, width=1, T=None): +def DefineMux(height=2, width=1, T=None): """ Construct a Mux. Height inputs are width bits wide. """ @@ -152,17 +161,21 @@ def amux(y): return curry(MuxN(height), prefix='I') mux = braid(col(amux, width), forkargs=['S']) - if height == 2: mux( Mux.I0, Mux.I1, Mux.S ) - elif height == 4: mux( Mux.I0, Mux.I1, Mux.I2, Mux.I3, Mux.S ) - elif height == 8: mux( Mux.I0, Mux.I1, Mux.I2, Mux.I3, - Mux.I4, Mux.I5, Mux.I6, Mux.I7, Mux.S ) - elif height == 16: mux( Mux.I0, Mux.I1, Mux.I2, Mux.I3, - Mux.I4, Mux.I5, Mux.I6, Mux.I7, - Mux.I8, Mux.I9, Mux.I10, Mux.I11, - Mux.I12, Mux.I13, Mux.I14, Mux.I15, Mux.S ) - wire( mux.O, Mux.O ) + if height == 2: + mux(Mux.I0, Mux.I1, Mux.S) + elif height == 4: + mux(Mux.I0, Mux.I1, Mux.I2, Mux.I3, Mux.S) + elif height == 8: + mux(Mux.I0, Mux.I1, Mux.I2, Mux.I3, + Mux.I4, Mux.I5, Mux.I6, Mux.I7, Mux.S) + elif height == 16: + mux(Mux.I0, Mux.I1, Mux.I2, Mux.I3, + Mux.I4, Mux.I5, Mux.I6, Mux.I7, + Mux.I8, Mux.I9, Mux.I10, Mux.I11, + Mux.I12, Mux.I13, Mux.I14, Mux.I15, Mux.S) + wire(mux.O, Mux.O) return _Mux + def Mux(height=2, width=None, T=None, **kwargs): return DefineMux(height, width, T)(**kwargs) - diff --git a/mantle/xilinx/mantle6/arith.py b/mantle/xilinx/mantle6/arith.py index c457105..29da45e 100644 --- a/mantle/xilinx/mantle6/arith.py +++ b/mantle/xilinx/mantle6/arith.py @@ -3,10 +3,11 @@ from .logic import Not from .cascade import FullCascade -__all__ = ['DefineAdd'] +__all__ = ['DefineAdd'] __all__ += ['DefineSub'] __all__ += ['DefineNegate'] + def _Name(basename, n, cin, cout): name = basename + str(n) if cin is 0 or cin is 1: @@ -17,8 +18,9 @@ def _Name(basename, n, cin, cout): name += '_cout'.format(cout) return name + def _Args(n, cin, cout): - T = Bits[ n ] + T = Bits[n] args = ["I0", In(T), "I1", In(T)] @@ -40,13 +42,15 @@ def _Args(n, cin, cout): # if cin, CIN is added to the circuit # if cout: COUT is added to the circuit # + + def DefineAdd(n, cin=False, cout=False): class _Add(Circuit): name = _Name('Add', n, cin, cout) IO = _Args(n, cin, cout) @classmethod def definition(io): - add = FullCascade(n, 2, A0^A1, A0, cin, cout) + add = FullCascade(n, 2, A0 ^ A1, A0, cin, cout) wire(io.I0, add.I0) wire(io.I1, add.I1) wire(add.O, io.O) @@ -55,7 +59,7 @@ def definition(io): if cout is True: wire(add.COUT, io.COUT) return _Add - + def DefineSub(n, cin=1, cout=False): class _Sub(Circuit): @@ -63,25 +67,25 @@ class _Sub(Circuit): IO = _Args(n, cin, cout) @classmethod def definition(io): - sub = FullCascade(n, 2, A0^~A1, A0, cin, cout) + sub = FullCascade(n, 2, A0 ^ ~A1, A0, cin, cout) wire(io.I0, sub.I0) wire(io.I1, sub.I1) wire(sub.O, io.O) if cin is True: - wire( Not()(io.CIN), sub.CIN ) + wire(Not()(io.CIN), sub.CIN) if cout is True: wire(sub.COUT, io.COUT) return _Sub + def DefineNegate(n): - T = Bits[ n ] + T = Bits[n] + class _Negate(Circuit): name = 'Negate{}'.format(n) io = m.IO('I', In(T), 'O', Out(T)) @classmethod def definition(io): - sub = DefineSub(n)() - wire( sub( uint(0,n), io.I ), io.O ) + sub = DefineSub(n)() + wire(sub(uint(0, n), io.I), io.O) return _Negate - - diff --git a/mantle/xilinx/mantle6/compare.py b/mantle/xilinx/mantle6/compare.py index 04365d9..f8f6bee 100644 --- a/mantle/xilinx/mantle6/compare.py +++ b/mantle/xilinx/mantle6/compare.py @@ -4,7 +4,7 @@ from .logic import Not from .cascade import HalfCascade -__all__ = ['DefineEQ', 'EQ'] +__all__ = ['DefineEQ', 'EQ'] __all__ += ['DefineNE', 'NE'] __all__ += ['DefineUGE'] __all__ += ['DefineULE'] @@ -15,81 +15,92 @@ __all__ += ['DefineSGT'] __all__ += ['DefineSLT'] -EQ1LUT = ((A0&A1)|(~A0&~A1)) -EQ2LUT = ((A0&A1)|(~A0&~A1)) & ((A2&A3)|(~A2&~A3)) +EQ1LUT = ((A0 & A1) | (~A0 & ~A1)) +EQ2LUT = ((A0 & A1) | (~A0 & ~A1)) & ((A2 & A3) | (~A2 & ~A3)) + class EQ1(Circuit): io = m.IO(I0=In(Bit), I1=In(Bit), O=Out(Bit)) @classmethod def definition(io): - wire( LUT2(EQ1LUT)(io.I0, io.I1), io.O ) + wire(LUT2(EQ1LUT)(io.I0, io.I1), io.O) + class EQ2(Circuit): - T = Bits[ 2 ] + T = Bits[2] io = m.IO(I0=In(T), I1=In(T), O=Out(Bit)) @classmethod def definition(io): - wire( LUT4(EQ2LUT)(io.I0[0], io.I1[0], io.I0[1], io.I1[1]), io.O ) + wire(LUT4(EQ2LUT)(io.I0[0], io.I1[0], io.I0[1], io.I1[1]), io.O) + def DefineEQ(n): assert n % 2 == 0 - T = Bits[ n ] + T = Bits[n] + class _EQ(Circuit): name = "EQ{}".format(n) io = m.IO('I0', In(T), 'I1', In(T), O=Out(Bit)) @classmethod def definition(io): - eq = HalfCascade(n//2, 4, EQ2LUT, ZERO, 1) - for i in range(n//2): - wire(io.I0[2*i], eq.I0[i]) - wire(io.I1[2*i], eq.I1[i]) - wire(io.I0[2*i+1], eq.I2[i]) - wire(io.I1[2*i+1], eq.I3[i]) - wire(eq.O, io.O) + eq = HalfCascade(n//2, 4, EQ2LUT, ZERO, 1) + for i in range(n//2): + wire(io.I0[2*i], eq.I0[i]) + wire(io.I1[2*i], eq.I1[i]) + wire(io.I0[2*i+1], eq.I2[i]) + wire(io.I1[2*i+1], eq.I3[i]) + wire(eq.O, io.O) return _EQ + def EQ(n, **kwargs): - if n == 1: + if n == 1: return EQ1(**kwargs) elif n == 2: return EQ2(**kwargs) return DefineEQ(n)(**kwargs) -NE1LUT = (A0^A1) -NE2LUT = (A0^A1)|(A2^A3) + +NE1LUT = (A0 ^ A1) +NE2LUT = (A0 ^ A1) | (A2 ^ A3) + class NE1(Circuit): io = m.IO(I0=In(Bit), I1=In(Bit), O=Out(Bit)) @classmethod def definition(io): - wire( LUT2(NE1LUT)(io.I0, io.I1), io.O ) + wire(LUT2(NE1LUT)(io.I0, io.I1), io.O) + class NE2(Circuit): - T = Bits[ 2 ] + T = Bits[2] io = m.IO(I0=In(T), I1=In(T), O=Out(Bit)) @classmethod def definition(io): - wire( LUT4(NE2LUT)(io.I0[0], io.I1[0], io.I0[1], io.I1[1]), io.O ) + wire(LUT4(NE2LUT)(io.I0[0], io.I1[0], io.I0[1], io.I1[1]), io.O) + def DefineNE(n): assert n % 2 == 0 - T = Bits[ n ] + T = Bits[n] + class _NE(Circuit): name = "NE{}".format(n) io = m.IO('I0', In(T), 'I1', In(T), O=Out(Bit)) @classmethod def definition(io): - ne = HalfCascade(n//2, 4, NE2LUT, ZERO, 1) - for i in range(n//2): - wire(io.I0[2*i], ne.I0[i]) - wire(io.I1[2*i], ne.I1[i]) - wire(io.I0[2*i+1], ne.I2[i]) - wire(io.I1[2*i+1], ne.I3[i]) - wire(ne.O, io.O) + ne = HalfCascade(n//2, 4, NE2LUT, ZERO, 1) + for i in range(n//2): + wire(io.I0[2*i], ne.I0[i]) + wire(io.I1[2*i], ne.I1[i]) + wire(io.I0[2*i+1], ne.I2[i]) + wire(io.I1[2*i+1], ne.I3[i]) + wire(ne.O, io.O) return _NE + def NE(n, **kwargs): - if n == 1: + if n == 1: return NE1(**kwargs) elif n == 2: return NE2(**kwargs) @@ -99,13 +110,14 @@ def NE(n, **kwargs): # unsigned comparisons def DefineUCMP(opname, reverse, negate, n): - T = UInt[ n ] + T = UInt[n] + class _UCMP(Circuit): name = "{}{}".format(opname, n) io = m.IO('I0', In(T), 'I1', In(T), O=Out(Bit)) @classmethod def definition(io): - sub = DefineSub(n,1,True)() + sub = DefineSub(n, 1, True)() if not reverse: sub(io.I0, io.I1) else: @@ -116,15 +128,19 @@ def definition(io): wire(Not()(sub.COUT), io.O) return _UCMP + def DefineUGE(n): return DefineUCMP('UGE', False, False, n) + def DefineULE(n): return DefineUCMP('ULE', True, False, n) + def DefineULT(n): return DefineUCMP('ULT', False, True, n) + def DefineUGT(n): return DefineUCMP('UGT', True, True, n) @@ -134,33 +150,39 @@ def DefineUGT(n): def _sge(c_msb, a_msb, b_msb): return int((~(a_msb ^ b_msb) & ~c_msb) | (~a_msb & b_msb)) & 1 + def _slt(c_msb, a_msb, b_msb): return int((~(a_msb ^ b_msb) & c_msb) | (a_msb & ~b_msb)) & 1 + def DefineSCMP(opname, op, reverse, n): - T = SInt[ n ] + T = SInt[n] + class _SCMP(Circuit): - name = "{}{}".format(opname,n) + name = "{}{}".format(opname, n) io = m.IO('I0', In(T), 'I1', In(T), O=Out(Bit)) @classmethod def definition(io): sub = DefineSub(n)() cmp = LUT3(op) if not reverse: - wire(cmp( sub(io.I0, io.I1)[-1], io.I0[-1], io.I1[-1] ), io.O) + wire(cmp(sub(io.I0, io.I1)[-1], io.I0[-1], io.I1[-1]), io.O) else: - wire(cmp( sub(io.I1, io.I0)[-1], io.I1[-1], io.I0[-1] ), io.O) + wire(cmp(sub(io.I1, io.I0)[-1], io.I1[-1], io.I0[-1]), io.O) return _SCMP + def DefineSGE(n): return DefineSCMP('SGE', _sge, False, n) + def DefineSLE(n): return DefineSCMP('SLE', _sge, True, n) + def DefineSLT(n): return DefineSCMP('SLT', _slt, False, n) + def DefineSGT(n): return DefineSCMP('SGT', _slt, True, n) - diff --git a/mantle/xilinx/mantle6/decode.py b/mantle/xilinx/mantle6/decode.py index 7cd1030..343619a 100644 --- a/mantle/xilinx/mantle6/decode.py +++ b/mantle/xilinx/mantle6/decode.py @@ -3,7 +3,8 @@ from .ROM import ROMN from .cascade import FlatHalfCascade -__all__ = ['DefineDecode', 'Decode', 'decode'] +__all__ = ['DefineDecode', 'Decode', 'decode'] + def DefineDecode(i, n, invert=False): """ @@ -14,7 +15,7 @@ def DefineDecode(i, n, invert=False): class _Decode(Circuit): name = 'Decode_{}_{}'.format(i, n) - io = m.IO('I', In(Bits[ n ]), 'O', Out(Bit)) + io = m.IO('I', In(Bits[n]), 'O', Out(Bit)) @classmethod def definition(io): @@ -29,15 +30,17 @@ def definition(io): nluts = (n + 3) // 4 data = nluts * [0] for j in range(nluts): - data[j] = (i >> 4*j) & 0xf # 4-bit pieces + data[j] = (i >> 4*j) & 0xf # 4-bit pieces decode = FlatHalfCascade(n, 4, data, ZERO, 1) wire(io.I, decode.I) wire(decode.O, io.O) return _Decode + def Decode(i, n, invert=False): return DefineDecode(i, n, invert=invert)() + def decode(I, i, invert=False): return Decode(i, len(I), invert=invert)(I) diff --git a/mantle/xilinx/mantle6/fulladder.py b/mantle/xilinx/mantle6/fulladder.py index f0d0dc1..277e3be 100644 --- a/mantle/xilinx/mantle6/fulladder.py +++ b/mantle/xilinx/mantle6/fulladder.py @@ -3,15 +3,16 @@ __all__ = ['FullAdder', 'fulladder'] + class FullAdder(Circuit): io = m.IO(I0=In(Bit), I1=In(Bit), I2=In(Bit), O=Out(Bit), COUT=Out(Bit)) @classmethod def definition(io): - s = LUT3(A0^A1^A2) - c = LUT3(A0&A1|A1&A2|A2&A0) - wire( s(io.I0, io.I1, io.I2), io.O ) - wire( c(io.I0, io.I1, io.I2), io.COUT ) + s = LUT3(A0 ^ A1 ^ A2) + c = LUT3(A0 & A1 | A1 & A2 | A2 & A0) + wire(s(io.I0, io.I1, io.I2), io.O) + wire(c(io.I0, io.I1, io.I2), io.COUT) + def fulladder(a, b, c): return FullAdder()(a, b, c) - diff --git a/mantle/xilinx/mantle6/halfadder.py b/mantle/xilinx/mantle6/halfadder.py index 56bfaea..c20972d 100644 --- a/mantle/xilinx/mantle6/halfadder.py +++ b/mantle/xilinx/mantle6/halfadder.py @@ -1,17 +1,18 @@ from magma import * from .LUT import LUT2, A0, A1 -__all__ = ["HalfAdder", 'halfadder'] +__all__ = ["HalfAdder", 'halfadder'] + class HalfAdder(Circuit): io = m.IO(I0=In(Bit), I1=In(Bit), O=Out(Bit), COUT=Out(Bit)) @classmethod def definition(io): - s = LUT2(A0^A1) - c = LUT2(A0&A1) - wire( s(io.I0, io.I1), io.O ) - wire( c(io.I0, io.I1), io.COUT ) - + s = LUT2(A0 ^ A1) + c = LUT2(A0 & A1) + wire(s(io.I0, io.I1), io.O) + wire(c(io.I0, io.I1), io.COUT) + + def halfadder(a, b): return HalfAdder()(a, b) - diff --git a/mantle/xilinx/mantle6/logic.py b/mantle/xilinx/mantle6/logic.py index fb8345f..6435331 100644 --- a/mantle/xilinx/mantle6/logic.py +++ b/mantle/xilinx/mantle6/logic.py @@ -1,17 +1,17 @@ from __future__ import division +from .cascade import FlatHalfCascade +from .ROM import ROMN +from .LUT import LUT, LUT1, LUT2, LUT3, LUT4, A0, A1, A2, A3, ZERO, ONE +from magma import * +from collections.abc import Sequence import sys if sys.version_info > (3, 0): from functools import reduce from functools import lru_cache -from collections.abc import Sequence -from magma import * -from .LUT import LUT, LUT1, LUT2, LUT3, LUT4, A0, A1, A2, A3, ZERO, ONE -from .ROM import ROMN -from .cascade import FlatHalfCascade # unary operators -__all__ = ['DefineReduceAnd', 'ReduceAnd'] +__all__ = ['DefineReduceAnd', 'ReduceAnd'] __all__ += ['DefineReduceNAnd', 'ReduceNAnd'] __all__ += ['DefineReduceOr', 'ReduceOr'] __all__ += ['DefineReduceNOr', 'ReduceNOr'] @@ -33,8 +33,11 @@ # # Efficient Reduction using carry chain and FlatHalfCascade # + + def DefineReduceOp(opname, n, lutexprs, andexpr, cin): - T = Bits[ n ] + T = Bits[n] + class _ReduceOp(Circuit): name = f'{opname}{n}' io = m.IO('I', In(T), 'O', Out(Bit)) @@ -42,7 +45,7 @@ class _ReduceOp(Circuit): @classmethod def definition(io): I = io.I - if n <= 4: #8? + if n <= 4: # 8? a = ROMN(lutexprs[n - 1], n) else: nluts = 4 * ((n + 3) // 4) @@ -53,80 +56,100 @@ def definition(io): wire(a(I), io.O) return _ReduceOp + def DefineReduceAnd(n): - luts = [A0, A0&A1, A0&A1&A2, A0&A1&A2&A3] + luts = [A0, A0 & A1, A0 & A1 & A2, A0 & A1 & A2 & A3] return DefineReduceOp('And', n, luts, ZERO, 1) + def ReduceAnd(height=2, **kwargs): return DefineReduceAnd(height)(**kwargs) + def DefineReduceNAnd(n): - luts = [A0, A0&A1, A0&A1&A2, A0&A1&A2&A3] + luts = [A0, A0 & A1, A0 & A1 & A2, A0 & A1 & A2 & A3] return DefineReduceOp('NAnd', n, luts, ONE, 0) + def ReduceNAnd(height=2, **kwargs): return DefineReduceNAnd(height)(**kwargs) + def DefineReduceOr(n): - luts = [~A0, ~(A0|A1), ~(A0|A1|A2), ~(A0|A1|A2|A3)] + luts = [~A0, ~(A0 | A1), ~(A0 | A1 | A2), ~(A0 | A1 | A2 | A3)] return DefineReduceOp('Or', n, luts, ONE, 0) + def ReduceOr(height=2, **kwargs): return DefineReduceOr(height)(**kwargs) + def DefineReduceNOr(n): - luts = [~A0, ~(A0|A1), ~(A0|A1|A2), ~(A0|A1|A2|A3)] + luts = [~A0, ~(A0 | A1), ~(A0 | A1 | A2), ~(A0 | A1 | A2 | A3)] return DefineReduceOp('NOr', n, luts, ZERO, 1) + def ReduceNOr(height=2, **kwargs): return DefineReduceNOr(height)(**kwargs) + def LUTCascade(n, k, expr, cin): - def f(y): - e = expr[y] if isinstance(expr, Sequence) else expr - return LUT( e, n=k+1 ) + def f(y): + e = expr[y] if isinstance(expr, Sequence) else expr + return LUT(e, n=k+1) + + # number of luts + m = (n+k-1) // k + c = braid(col(f, m), foldargs={"I0": "O"}) - # number of luts - m = (n+k-1) // k - c = braid( col(f, m), foldargs={"I0":"O"}) + wire(cin, c.I0) - wire(cin, c.I0) + c = flat(uncurry(c)) - c = flat(uncurry(c)) + for i in range(n, len(c.I)): + wire(cin, c.I[i]) - for i in range(n, len(c.I)): - wire(cin, c.I[i]) + return AnonymousCircuit(['I', c.I[0:n], 'O', c.O]) - return AnonymousCircuit( ['I', c.I[0:n], 'O', c.O] ) def DefineReduceLUT(opname, n, luts, cascadeexpr, cin): - T = Bits[ n ] + T = Bits[n] + class _ReduceLUT(Circuit): name = '{}{}'.format(opname, n) io = m.IO('I', In(T), 'O', Out(Bit)) @classmethod def definition(io): - if n == 1: a = uncurry(LUT1(luts[n - 1])) - elif n == 2: a = uncurry(LUT2(luts[n - 1])) - elif n == 3: a = uncurry(LUT3(luts[n - 1])) - elif n == 4: a = uncurry(LUT4(luts[n - 1])) - else: a = LUTCascade(n, 1, cascadeexpr, cin) + if n == 1: + a = uncurry(LUT1(luts[n - 1])) + elif n == 2: + a = uncurry(LUT2(luts[n - 1])) + elif n == 3: + a = uncurry(LUT3(luts[n - 1])) + elif n == 4: + a = uncurry(LUT4(luts[n - 1])) + else: + a = LUTCascade(n, 1, cascadeexpr, cin) wire(a(io.I), io.O) return _ReduceLUT + def DefineReduceXOr(n): - luts = [A0, A0^A1, A0^A1^A2, A0^A1^A2^A3] + luts = [A0, A0 ^ A1, A0 ^ A1 ^ A2, A0 ^ A1 ^ A2 ^ A3] return DefineReduceLUT('XOr', n, luts, A0 ^ A1, 0) + def ReduceXOr(height=2, **kwargs): return DefineReduceXOr(height)(**kwargs) + def DefineReduceNXOr(n): - luts = [~A0, ~(A0^A1), ~(A0^A1^A2), ~(A0^A1^A2^A3)] + luts = [~A0, ~(A0 ^ A1), ~(A0 ^ A1 ^ A2), ~(A0 ^ A1 ^ A2 ^ A3)] return DefineReduceLUT('NXOr', n, luts, A0 ^ ~A1, 1) + def ReduceNXOr(height=2, **kwargs): return DefineReduceNXOr(height)(**kwargs) @@ -137,13 +160,13 @@ def DefineOp(opname, op, height=2, width=1): I0 : In(Bits(width)), I1 : In(Bits(width)), O : Out(Bits(width)) """ - T = Bits[ width ] + T = Bits[width] class _Op(Circuit): name = '{}{}x{}'.format(opname, height, width) IO = sum([['I{}'.format(i), In(T)] for i in range(height)], []) - IO += ['O', Out(T)] + IO += ['O', Out(T)] @classmethod def definition(io): @@ -155,49 +178,61 @@ def opm(y): wire(opmxn.O, io.O) return _Op + def DefineAnd(height=2, width=1): return DefineOp('And', ReduceAnd, height, width) + def And(height=2, width=None, **kwargs): if width is None: return curry(ReduceAnd(height, **kwargs)) return DefineAnd(height, width)(**kwargs) + def DefineNAnd(height=2, width=None): return DefineOp('NAnd', ReduceNAnd, height, width) + def NAnd(height=2, width=None, **kwargs): if width is None: return curry(ReduceNAnd(height, **kwargs)) return DefineNAnd(height, width)(**kwargs) + def DefineOr(height=2, width=None): return DefineOp('Or', ReduceOr, height, width) + def Or(height=2, width=None, **kwargs): if width is None: return curry(ReduceOr(height, **kwargs)) return DefineOr(height, width)(**kwargs) + def DefineNOr(height=2, width=None): return DefineOp('NOr', ReduceNOr, height, width) + def NOr(height=2, width=None, **kwargs): if width is None: return curry(ReduceNOr(height, **kwargs)) return DefineNOr(height, width)(**kwargs) + def DefineXOr(height=2, width=None): return DefineOp('XOr', ReduceXOr, height, width) + def XOr(height=2, width=None, **kwargs): if width is None: return curry(ReduceXOr(height, **kwargs)) return DefineXOr(height, width)(**kwargs) + def DefineNXOr(height=2, width=None): return DefineOp('NXOr', ReduceNXOr, height, width) + def NXOr(height=2, width=None, **kwargs): if width is None: return curry(ReduceNXOr(height, **kwargs)) @@ -211,7 +246,8 @@ def DefineInvert(width): I0 : Bits(width) -> O : Bits(width) """ - T = Bits[ width ] + T = Bits[width] + class _Invert(Circuit): name = 'Invert%d' % width io = m.IO('I', In(T), 'O', Out(T)) @@ -226,6 +262,7 @@ def not_(y): return _Invert + def Invert(n, **kwargs): return DefineInvert(n)(**kwargs) @@ -233,5 +270,3 @@ def Invert(n, **kwargs): def Not(**kwargs): """Not gate - 1-bit input.""" return LUT1(~A0, **kwargs) - - diff --git a/mantle/xilinx/mantle6/mothball/flatcascade.py b/mantle/xilinx/mantle6/mothball/flatcascade.py index 6f27d96..32db66c 100644 --- a/mantle/xilinx/mantle6/mothball/flatcascade.py +++ b/mantle/xilinx/mantle6/mothball/flatcascade.py @@ -5,18 +5,21 @@ __all__ = ['FlatCascade', 'DefineFlatCascade'] + def _Name(n, k, expr, input, din, cin): if isinstance(expr, Sequence): - expr = "_".join(["%X" % uint(e, 1< 1 and height <= 4 name = 'And%dx%d' % (height, width) - if height == 2: + if height == 2: io = m.IO('input I0', T, 'input I1', T) elif height == 3: io = m.IO('input I0', T, 'input I1', T, 'input I2', T) elif height == 4: - io = m.IO('input I0', T, 'input I1', T, 'input I2', T, 'input I3', T) - IO += ['output O', T] + io = m.IO('input I0', T, 'input I1', T, + 'input I2', T, 'input I3', T) + IO += ['output O', T] @classmethod def definition(def_): def andm(y): - if height == 2: return And2(loc=(0,y/8, y%8)) - if height == 3: return And3(loc=(0,y/8, y%8)) - if height == 4: return And4(loc=(0,y/8, y%8)) - if height == 5: return And5(loc=(0,y/8, y%8)) - if height == 6: return And6(loc=(0,y/8, y%8)) + if height == 2: + return And2(loc=(0, y/8, y % 8)) + if height == 3: + return And3(loc=(0, y/8, y % 8)) + if height == 4: + return And4(loc=(0, y/8, y % 8)) + if height == 5: + return And5(loc=(0, y/8, y % 8)) + if height == 6: + return And6(loc=(0, y/8, y % 8)) andmxn = join(col(andm, width)) wire(def_.I0, andmxn.I0) wire(def_.I1, andmxn.I1) @@ -66,9 +78,11 @@ def andm(y): return _And + def And(height, width=2, **kwargs): return DefineAnd(height, width)(**kwargs) + def AndN(n, **kwargs): """And gate with n-bit input.""" @@ -76,34 +90,38 @@ def AndN(n, **kwargs): if n == 1: return ROM1(~(A0), **kwargs) if n == 2: - return ROM2(~(A0&A1), **kwargs) + return ROM2(~(A0 & A1), **kwargs) if n == 3: - return ROM3(~(A0&A1&A2), **kwargs) + return ROM3(~(A0 & A1 & A2), **kwargs) if n == 4: - return ROM4(~(A0&A1&A2&A3), **kwargs) + return ROM4(~(A0 & A1 & A2 & A3), **kwargs) if n == 5: - return ROM5(A0&A1&A2&A3&A4, **kwargs) + return ROM5(A0 & A1 & A2 & A3 & A4, **kwargs) if n == 6: - return ROM6(A0&A1&A2&A3&A4&A5, **kwargs) + return ROM6(A0 & A1 & A2 & A3 & A4 & A5, **kwargs) else: - return FlatCascade(n, 6, A0&A1&A2&A3&A4&A5, 1, 0, 1, **kwargs) - + return FlatCascade(n, 6, A0 & A1 & A2 & A3 & A4 & A5, 1, 0, 1, **kwargs) def NAnd2(**kwargs): - return LUT2(~(A0&A1), **kwargs ) + return LUT2(~(A0 & A1), **kwargs) + def NAnd3(**kwargs): - return LUT3(~(A0&A1&A2), **kwargs) + return LUT3(~(A0 & A1 & A2), **kwargs) + def NAnd4(**kwargs): - return LUT4(~(A0&A1&A2&A3), **kwargs) + return LUT4(~(A0 & A1 & A2 & A3), **kwargs) + def NAnd5(**kwargs): - return LUT5(~(A0&A1&A2&A3&A4), **kwargs) + return LUT5(~(A0 & A1 & A2 & A3 & A4), **kwargs) + def NAnd6(**kwargs): - return LUT6(~(A0&A1&A2&A3&A4&A5), **kwargs) + return LUT6(~(A0 & A1 & A2 & A3 & A4 & A5), **kwargs) + def DefineNAnd(height, width): """ @@ -113,27 +131,34 @@ def DefineNAnd(height, width): """ T = Array(width, Bit) + class _NAnd(Circuit): assert height > 1 and height <= 4 name = 'NAnd%dx%d' % (height, width) - if height == 2: + if height == 2: io = m.IO('input I0', T, 'input I1', T) elif height == 3: io = m.IO('input I0', T, 'input I1', T, 'input I2', T) elif height == 4: - io = m.IO('input I0', T, 'input I1', T, 'input I2', T, 'input I3', T) - IO += ['output O', T] + io = m.IO('input I0', T, 'input I1', T, + 'input I2', T, 'input I3', T) + IO += ['output O', T] @classmethod def definition(def_): def nandm(y): - if height == 2: return NAnd2(loc=(0,y/8, y%8)) - if height == 3: return NAnd3(loc=(0,y/8, y%8)) - if height == 4: return NAnd4(loc=(0,y/8, y%8)) - if height == 5: return NAnd5(loc=(0,y/8, y%8)) - if height == 6: return NAnd6(loc=(0,y/8, y%8)) + if height == 2: + return NAnd2(loc=(0, y/8, y % 8)) + if height == 3: + return NAnd3(loc=(0, y/8, y % 8)) + if height == 4: + return NAnd4(loc=(0, y/8, y % 8)) + if height == 5: + return NAnd5(loc=(0, y/8, y % 8)) + if height == 6: + return NAnd6(loc=(0, y/8, y % 8)) nandmxn = join(col(nandm, width)) wire(def_.I0, nandmxn.I0) wire(def_.I1, nandmxn.I1) @@ -141,9 +166,11 @@ def nandm(y): return _NAnd + def NAnd(height, width=2, **kwargs): return DefineNAnd(height, width)(**kwargs) + def NAndN(n, **kwargs): """NAnd gate with n-bit input.""" @@ -151,33 +178,38 @@ def NAndN(n, **kwargs): if n == 1: return ROM1(~(A0), **kwargs) if n == 2: - return ROM2(~(A0&A1), **kwargs) + return ROM2(~(A0 & A1), **kwargs) if n == 3: - return ROM3(~(A0&A1&A2), **kwargs) + return ROM3(~(A0 & A1 & A2), **kwargs) if n == 4: - return ROM4(~(A0&A1&A2&A3), **kwargs) + return ROM4(~(A0 & A1 & A2 & A3), **kwargs) if n == 5: - return ROM5(~(A0&A1&A2&A3&A4), **kwargs) + return ROM5(~(A0 & A1 & A2 & A3 & A4), **kwargs) if n == 6: - return ROM6(~(A0&A1&A2&A3&A4&A5), **kwargs) + return ROM6(~(A0 & A1 & A2 & A3 & A4 & A5), **kwargs) else: - return FlatCascade(n, 6, A0&A1&A2&A3&A4&A5, 1, 1, 0, **kwargs) + return FlatCascade(n, 6, A0 & A1 & A2 & A3 & A4 & A5, 1, 1, 0, **kwargs) def Or2(**kwargs): - return LUT2(A0|A1, **kwargs) + return LUT2(A0 | A1, **kwargs) + def Or3(**kwargs): - return LUT3(A0|A1|A2, **kwargs) + return LUT3(A0 | A1 | A2, **kwargs) + def Or4(**kwargs): - return LUT4(A0|A1|A2|A3, **kwargs) + return LUT4(A0 | A1 | A2 | A3, **kwargs) + def Or5(**kwargs): - return LUT5(A0|A1|A2|A3|A4, **kwargs) + return LUT5(A0 | A1 | A2 | A3 | A4, **kwargs) + def Or6(**kwargs): - return LUT6(A0|A1|A2|A3|A4|A5, **kwargs) + return LUT6(A0 | A1 | A2 | A3 | A4 | A5, **kwargs) + def DefineOr(height, width): """ @@ -187,27 +219,34 @@ def DefineOr(height, width): """ T = Array(width, Bit) + class _Or(Circuit): assert height > 1 and height <= 4 name = 'Or%dx%d' % (height, width) - if height == 2: + if height == 2: io = m.IO('input I0', T, 'input I1', T) elif height == 3: io = m.IO('input I0', T, 'input I1', T, 'input I2', T) elif height == 4: - io = m.IO('input I0', T, 'input I1', T, 'input I2', T, 'input I3', T) - IO += ['output O', T] + io = m.IO('input I0', T, 'input I1', T, + 'input I2', T, 'input I3', T) + IO += ['output O', T] @classmethod def definition(def_): def orm(y): - if height == 2: return Or2(loc=(0,y/8, y%8)) - if height == 3: return Or3(loc=(0,y/8, y%8)) - if height == 4: return Or4(loc=(0,y/8, y%8)) - if height == 5: return Or5(loc=(0,y/8, y%8)) - if height == 6: return Or6(loc=(0,y/8, y%8)) + if height == 2: + return Or2(loc=(0, y/8, y % 8)) + if height == 3: + return Or3(loc=(0, y/8, y % 8)) + if height == 4: + return Or4(loc=(0, y/8, y % 8)) + if height == 5: + return Or5(loc=(0, y/8, y % 8)) + if height == 6: + return Or6(loc=(0, y/8, y % 8)) ormxn = join(col(orm, width)) wire(def_.I0, ormxn.I0) wire(def_.I1, ormxn.I1) @@ -215,9 +254,11 @@ def orm(y): return _Or + def Or(height, width=2, **kwargs): return DefineOr(height, width)(**kwargs) + def OrN(n, **kwargs): """Or gate with n-bit input.""" @@ -225,33 +266,38 @@ def OrN(n, **kwargs): if n == 1: return ROM1(A0, **kwargs) if n == 2: - return ROM2(A0|A1, **kwargs) + return ROM2(A0 | A1, **kwargs) if n == 3: - return ROM3(A0|A1|A2, **kwargs) + return ROM3(A0 | A1 | A2, **kwargs) if n == 4: - return ROM4(A0|A1|A2|A3, **kwargs) + return ROM4(A0 | A1 | A2 | A3, **kwargs) if n == 5: - return ROM5(A0|A1|A2|A3|A4, **kwargs) + return ROM5(A0 | A1 | A2 | A3 | A4, **kwargs) if n == 6: - return ROM6(A0|A1|A2|A3|A4|A5, **kwargs) + return ROM6(A0 | A1 | A2 | A3 | A4 | A5, **kwargs) else: - return FlatCascade(n, 6, ~(A0|A1|A2|A3|A4|A5), 0, 1, 0, **kwargs) + return FlatCascade(n, 6, ~(A0 | A1 | A2 | A3 | A4 | A5), 0, 1, 0, **kwargs) def Nor2(**kwargs): - return LUT2(~(A0|A1), **kwargs) + return LUT2(~(A0 | A1), **kwargs) + def Nor3(**kwargs): - return LUT3(~(A0|A1|A2), **kwargs) + return LUT3(~(A0 | A1 | A2), **kwargs) + def Nor4(**kwargs): - return LUT4(~(A0|A1|A2|A3), **kwargs) + return LUT4(~(A0 | A1 | A2 | A3), **kwargs) + def Nor5(): - return LUT5(~(A0|A1|A2|A3|A4)) + return LUT5(~(A0 | A1 | A2 | A3 | A4)) + def Nor6(): - return LUT6(~(A0|A1|A2|A3|A4|A5)) + return LUT6(~(A0 | A1 | A2 | A3 | A4 | A5)) + def DefineNor(height, width): """ @@ -261,27 +307,34 @@ def DefineNor(height, width): """ T = Array(width, Bit) + class _Nor(Circuit): assert height > 1 and height <= 4 name = 'Nor%dx%d' % (height, width) - if height == 2: + if height == 2: io = m.IO('input I0', T, 'input I1', T) elif height == 3: io = m.IO('input I0', T, 'input I1', T, 'input I2', T) elif height == 4: - io = m.IO('input I0', T, 'input I1', T, 'input I2', T, 'input I3', T) - IO += ['output O', T] + io = m.IO('input I0', T, 'input I1', T, + 'input I2', T, 'input I3', T) + IO += ['output O', T] @classmethod def definition(def_): def orm(y): - if height == 2: return Nor2(loc=(0,y/8, y%8)) - if height == 3: return Nor3(loc=(0,y/8, y%8)) - if height == 4: return Nor4(loc=(0,y/8, y%8)) - if height == 5: return Nor5(loc=(0,y/8, y%8)) - if height == 6: return Nor6(loc=(0,y/8, y%8)) + if height == 2: + return Nor2(loc=(0, y/8, y % 8)) + if height == 3: + return Nor3(loc=(0, y/8, y % 8)) + if height == 4: + return Nor4(loc=(0, y/8, y % 8)) + if height == 5: + return Nor5(loc=(0, y/8, y % 8)) + if height == 6: + return Nor6(loc=(0, y/8, y % 8)) normxn = join(col(norm, width)) wire(def_.I0, normxn.I0) wire(def_.I1, normxn.I1) @@ -289,9 +342,11 @@ def orm(y): return _Nor + def Nor(height, width=2, **kwargs): return DefineNor(height, width)(**kwargs) + def NorN(n, **kwargs): """Nor gate with n-bit input.""" @@ -299,33 +354,38 @@ def NorN(n, **kwargs): if n == 1: return ROM1(~(A0), **kwargs) if n == 2: - return ROM2(~(A0|A1), **kwargs) + return ROM2(~(A0 | A1), **kwargs) if n == 3: - return ROM3(~(A0|A1|A2), **kwargs) + return ROM3(~(A0 | A1 | A2), **kwargs) if n == 4: - return ROM4(~(A0|A1|A2|A3), **kwargs) + return ROM4(~(A0 | A1 | A2 | A3), **kwargs) if n == 5: - return ROM5(~(A0|A1|A2|A3|A4), **kwargs) + return ROM5(~(A0 | A1 | A2 | A3 | A4), **kwargs) if n == 6: - return ROM6(~(A0|A1|A2|A3|A4|A5), **kwargs) + return ROM6(~(A0 | A1 | A2 | A3 | A4 | A5), **kwargs) else: - return FlatCascade(n, 6, ~(A0|A1|A2|A3|A4|A5), 0, 0, 1, **kwargs) + return FlatCascade(n, 6, ~(A0 | A1 | A2 | A3 | A4 | A5), 0, 0, 1, **kwargs) def Xor2(**kwargs): - return LUT2(A0^A1, **kwargs) + return LUT2(A0 ^ A1, **kwargs) + def Xor3(**kwargs): - return LUT3(A0^A1^A2, **kwargs) + return LUT3(A0 ^ A1 ^ A2, **kwargs) + def Xor4(**kwargs): - return LUT4(A0^A1^A2^A3, **kwargs) + return LUT4(A0 ^ A1 ^ A2 ^ A3, **kwargs) + def Xor5(): - return LUT5(A0^A1^A2^A3^A4, **kwargs) + return LUT5(A0 ^ A1 ^ A2 ^ A3 ^ A4, **kwargs) + def Xor6(): - return LUT6(A0^A1^A2^A3^A4^A5, **kwargs) + return LUT6(A0 ^ A1 ^ A2 ^ A3 ^ A4 ^ A5, **kwargs) + def DefineXor(height, width): """ @@ -335,27 +395,34 @@ def DefineXor(height, width): """ T = Array(width, Bit) + class _Xor(Circuit): assert height > 1 and height <= 4 name = 'Xor%dx%d' % (height, width) - if height == 2: + if height == 2: io = m.IO('input I0', T, 'input I1', T) elif height == 3: io = m.IO('input I0', T, 'input I1', T, 'input I2', T) elif height == 4: - io = m.IO('input I0', T, 'input I1', T, 'input I2', T, 'input I3', T) - IO += ['output O', T] + io = m.IO('input I0', T, 'input I1', T, + 'input I2', T, 'input I3', T) + IO += ['output O', T] @classmethod def definition(def_): def xorm(y): - if height == 2: return Xor2(loc=(0,y/8, y%8)) - if height == 3: return Xor3(loc=(0,y/8, y%8)) - if height == 4: return Xor4(loc=(0,y/8, y%8)) - if height == 5: return Xor5(loc=(0,y/8, y%8)) - if height == 6: return Xor6(loc=(0,y/8, y%8)) + if height == 2: + return Xor2(loc=(0, y/8, y % 8)) + if height == 3: + return Xor3(loc=(0, y/8, y % 8)) + if height == 4: + return Xor4(loc=(0, y/8, y % 8)) + if height == 5: + return Xor5(loc=(0, y/8, y % 8)) + if height == 6: + return Xor6(loc=(0, y/8, y % 8)) xormxn = join(col(xorm, width)) wire(def_.I0, xormxn.I0) wire(def_.I1, xormxn.I1) @@ -363,9 +430,11 @@ def xorm(y): return _Xor + def Xor(height, width=2, **kwargs): return DefineXor(height, width)(**kwargs) + def XorN(n, **kwargs): """XNor gate with n-bit input.""" @@ -373,32 +442,37 @@ def XorN(n, **kwargs): if n == 1: return ROM1(A0, **kwargs) if n == 2: - return ROM2(A0^A1, **kwargs) + return ROM2(A0 ^ A1, **kwargs) if n == 3: - return ROM3(A0^A1^A2, **kwargs) + return ROM3(A0 ^ A1 ^ A2, **kwargs) if n == 4: - return ROM4(A0^A1^A2^A3, **kwargs) + return ROM4(A0 ^ A1 ^ A2 ^ A3, **kwargs) if n == 5: - return ROM5(A0^A1^A2^A3^A4, **kwargs) + return ROM5(A0 ^ A1 ^ A2 ^ A3 ^ A4, **kwargs) if n == 6: - return ROM6(A0^A1^A2^A3^A4^A5, **kwargs) + return ROM6(A0 ^ A1 ^ A2 ^ A3 ^ A4 ^ A5, **kwargs) return None def NXor2(**kwargs): - return LUT2(~(A0^A1), **kwargs) + return LUT2(~(A0 ^ A1), **kwargs) + def NXor3(**kwargs): - return LUT3(~(A0^A1^A2), **kwargs) + return LUT3(~(A0 ^ A1 ^ A2), **kwargs) + def NXor4(**kwargs): - return LUT4(~(A0^A1^A2^A3), **kwargs) + return LUT4(~(A0 ^ A1 ^ A2 ^ A3), **kwargs) + def NXor5(**kwargs): - return LUT5(~(A0^A1^A2^A3^A4), **kwargs) + return LUT5(~(A0 ^ A1 ^ A2 ^ A3 ^ A4), **kwargs) + def NXor6(): - return LUT6(~(A0^A1^A2^A3^A4^A5), **kwargs) + return LUT6(~(A0 ^ A1 ^ A2 ^ A3 ^ A4 ^ A5), **kwargs) + def DefineNXor(height, width): """ @@ -408,27 +482,34 @@ def DefineNXor(height, width): """ T = Array(width, Bit) + class _NXor(Circuit): assert height > 1 and height <= 4 name = 'NXor%dx%d' % (height, width) - if height == 2: + if height == 2: io = m.IO('input I0', T, 'input I1', T) elif height == 3: io = m.IO('input I0', T, 'input I1', T, 'input I2', T) elif height == 4: - io = m.IO('input I0', T, 'input I1', T, 'input I2', T, 'input I3', T) - IO += ['output O', T] + io = m.IO('input I0', T, 'input I1', T, + 'input I2', T, 'input I3', T) + IO += ['output O', T] @classmethod def definition(def_): def nxorm(y): - if height == 2: return NXor2(loc=(0,y/8, y%8)) - if height == 3: return NXor3(loc=(0,y/8, y%8)) - if height == 4: return NXor4(loc=(0,y/8, y%8)) - if height == 5: return NXor5(loc=(0,y/8, y%8)) - if height == 6: return NXor6(loc=(0,y/8, y%8)) + if height == 2: + return NXor2(loc=(0, y/8, y % 8)) + if height == 3: + return NXor3(loc=(0, y/8, y % 8)) + if height == 4: + return NXor4(loc=(0, y/8, y % 8)) + if height == 5: + return NXor5(loc=(0, y/8, y % 8)) + if height == 6: + return NXor6(loc=(0, y/8, y % 8)) nxormxn = join(col(nxorm, width)) wire(def_.I0, nxormxn.I0) wire(def_.I1, nxormxn.I1) @@ -436,9 +517,11 @@ def nxorm(y): return _NXor + def NXor(height, width=2, **kwargs): return DefineNXor(height, width)(**kwargs) + def NXorN(n, **kwargs): """XNor gate with n-bit input.""" @@ -446,15 +529,15 @@ def NXorN(n, **kwargs): if n == 1: return ROM1(~(A0), **kwargs) if n == 2: - return ROM2(~(A0^A1), **kwargs) + return ROM2(~(A0 ^ A1), **kwargs) if n == 3: - return ROM3(~(A0^A1^A2), **kwargs) + return ROM3(~(A0 ^ A1 ^ A2), **kwargs) if n == 4: - return ROM4(~(A0^A1^A2^A3), **kwargs) + return ROM4(~(A0 ^ A1 ^ A2 ^ A3), **kwargs) if n == 5: - return ROM5(~(A0^A1^A2^A3^A4), **kwargs) + return ROM5(~(A0 ^ A1 ^ A2 ^ A3 ^ A4), **kwargs) if n == 6: - return ROM6(~(A0^A1^A2^A3^A4^A5), **kwargs) + return ROM6(~(A0 ^ A1 ^ A2 ^ A3 ^ A4 ^ A5), **kwargs) return None @@ -462,6 +545,7 @@ def Buf(**kwargs): """Buffer - 1-bit input.""" return LUT1(A0, **kwargs) + def DefineBuffer(width): """ Generate Buffer module @@ -477,13 +561,14 @@ class _Buffer(Circuit): @classmethod def definition(def_): def buf(y): - return Buf(loc=(0,y/8, y%8)) + return Buf(loc=(0, y/8, y % 8)) buffer = join(col(buf, width)) wire(def_.I, buffer.I0) wire(buffer.O, def_.O) return _Buffer + def Buffer(n, **kwargs): return DefineBuffer(n)(**kwargs) @@ -492,6 +577,7 @@ def Not(**kwargs): """Not gate - 1-bit input.""" return LUT1(~A0, **kwargs) + def DefineInvert(width): """ Generate Invert module @@ -500,6 +586,7 @@ def DefineInvert(width): """ T = Array(width, Bit) + class _Invert(Circuit): name = 'Invert%d' % width @@ -508,13 +595,13 @@ class _Invert(Circuit): @classmethod def definition(def_): def not_(y): - return Not(loc=(0,y/8, y%8)) + return Not(loc=(0, y/8, y % 8)) invert = join(col(not_, width)) wire(def_.I, invert.I0) wire(invert.O, def_.O) return _Invert + def Invert(n, **kwargs): return DefineInvert(n)(**kwargs) - diff --git a/tests/test_coreir/test_compare.py b/tests/test_coreir/test_compare.py index 7775fdf..268b5fd 100644 --- a/tests/test_coreir/test_compare.py +++ b/tests/test_coreir/test_compare.py @@ -3,10 +3,12 @@ from mantle.coreir.compare import EQ, NE, ULT, ULE, UGT, UGE, SLT, SLE, SGT, \ SGE + def check(circuit_type): circuit_type_name = circuit_type.__name__ print(circuit_type_name) - T = UInt[ 4 ] + T = UInt[4] + class TestCircuit(Circuit): name = "test_{}_two".format(circuit_type_name) io = m.IO(a=In(T), b=In(T), c=Out(Bit)) @@ -20,35 +22,46 @@ def definition(circuit): compile("build/test_{}_two".format(circuit_type_name), TestCircuit, output="coreir") assert check_files_equal(__file__, - "build/test_{}_two.json".format(circuit_type_name), - "gold/test_{}_two.json".format(circuit_type_name)) + "build/test_{}_two.json".format( + circuit_type_name), + "gold/test_{}_two.json".format(circuit_type_name)) + def test_eq(): check(EQ) + def test_ne(): check(NE) + def test_ult(): check(ULT) + def test_ule(): check(ULE) + def test_ugt(): check(UGT) + def test_uge(): check(UGE) + def test_slt(): check(SLT) + def test_sle(): check(SLE) + def test_sgt(): check(SGT) + def test_sge(): check(SGE) diff --git a/tests/test_coreir/test_conv.py b/tests/test_coreir/test_conv.py index 7501236..9d3fd4d 100644 --- a/tests/test_coreir/test_conv.py +++ b/tests/test_coreir/test_conv.py @@ -3,122 +3,148 @@ from mantle import * import mantle.coreir + def Define_mantle_reg_U6(init): - class mantle_reg_U6(Circuit): - name = f"mantle_reg_U6_{init}" - io = m.IO(I=Array[ 4,In(Bit) ], clk=In(Clock), O=Array[ 4,Out(Bit) ], en=In(Bit)) + class mantle_reg_U6(Circuit): + name = f"mantle_reg_U6_{init}" + io = m.IO(I=Array[4, In(Bit)], clk=In(Clock), + O=Array[4, Out(Bit)], en=In(Bit)) + + @classmethod + def definition(io): + enMux = mantle.coreir.DefineCoreirMux(width=4)(name="enMux") + reg0 = mantle.coreir.DefineCoreirReg( + init=init, width=4)(name="reg0") + wire(enMux.I0, reg0.O) + wire(enMux.I1, io.I) + wire(reg0.I, enMux.O) + wire(enMux.S, io.en) + wire(reg0.CLK, io.clk) + wire(io.O, reg0.O) + return mantle_reg_U6 + + +class commonlib_LinebufferMem_U5(Circuit): + name = "commonlib_LinebufferMem_U5" + io = m.IO(clk=In(Clock), rdata=Array[16, Out(Bit)], valid=Out( + Bit), wdata=Array[16, In(Bit)], wen=In(Bit)) + @classmethod def definition(io): - enMux = mantle.coreir.DefineCoreirMux(width=4)(name="enMux") - reg0 = mantle.coreir.DefineCoreirReg(init=init, width=4)(name="reg0") - wire(enMux.I0, reg0.O) - wire(enMux.I1, io.I) - wire(reg0.I, enMux.O) - wire(enMux.S, io.en) - wire(reg0.CLK, io.clk) - wire(io.O, reg0.O) - return mantle_reg_U6 + add_r = mantle.coreir.DefineCoreirAdd(width=4)(name="add_r") + add_w = mantle.coreir.DefineCoreirAdd(width=4)(name="add_w") + c1 = mantle.coreir.DefineCoreirConst(value=1, width=4)(name="c1") + max_const = mantle.coreir.DefineCoreirConst( + value=10, width=4)(name="max_const") + mem = mantle.coreir.DefineCoreirMem(depth=10, width=16)(name="mem") + raddr = Define_mantle_reg_U6(init=0)() + raddr_eq = mantle.coreir.DefineCoreirEq(width=4)(name="raddr_eq") + raddr_mux = mantle.coreir.DefineCoreirMux(width=4)(name="raddr_mux") + veq = mantle.coreir.DefineCoreirNeq(width=4)(name="veq") + waddr = Define_mantle_reg_U6(init=0)() + waddr_eq = mantle.coreir.DefineCoreirEq(width=4)(name="waddr_eq") + waddr_mux = mantle.coreir.DefineCoreirMux(width=4)(name="waddr_mux") + zero_const = mantle.coreir.DefineCoreirConst( + value=0, width=4)(name="zero_const") + wire(add_r.I0, raddr.O) + wire(add_r.I1, c1.O) + wire(raddr_eq.I0, add_r.O) + wire(raddr_mux.I0, add_r.O) + wire(add_w.I0, waddr.O) + wire(add_w.I1, c1.O) + wire(waddr_eq.I0, add_w.O) + wire(waddr_mux.I0, add_w.O) + wire(raddr_eq.I1, max_const.O) + wire(waddr_eq.I1, max_const.O) + wire(mem.clk, io.clk) + wire(mem.raddr, raddr.O) + wire(io.rdata, mem.rdata) + wire(mem.waddr, waddr.O) + wire(mem.wdata, io.wdata) + wire(mem.wen, io.wen) + wire(raddr.clk, io.clk) + wire(raddr.en, io.wen) + wire(raddr.I, raddr_mux.O) + wire(veq.I0, raddr.O) + wire(raddr_mux.S, raddr_eq.O) + wire(raddr_mux.I1, zero_const.O) + wire(waddr.clk, io.clk) + wire(io.valid, veq.O) + wire(waddr.en, io.wen) + wire(veq.I1, waddr.O) + wire(waddr.I, waddr_mux.O) + wire(waddr_mux.S, waddr_eq.O) + wire(waddr_mux.I1, zero_const.O) -class commonlib_LinebufferMem_U5(Circuit): - name = "commonlib_LinebufferMem_U5" - io = m.IO(clk=In(Clock), rdata=Array[ 16,Out(Bit) ], valid=Out(Bit), wdata=Array[ 16,In(Bit) ], wen=In(Bit)) - @classmethod - def definition(io): - add_r = mantle.coreir.DefineCoreirAdd(width=4)(name="add_r") - add_w = mantle.coreir.DefineCoreirAdd(width=4)(name="add_w") - c1 = mantle.coreir.DefineCoreirConst(value=1, width=4)(name="c1") - max_const = mantle.coreir.DefineCoreirConst(value=10, width=4)(name="max_const") - mem = mantle.coreir.DefineCoreirMem(depth=10, width=16)(name="mem") - raddr = Define_mantle_reg_U6(init=0)() - raddr_eq = mantle.coreir.DefineCoreirEq(width=4)(name="raddr_eq") - raddr_mux = mantle.coreir.DefineCoreirMux(width=4)(name="raddr_mux") - veq = mantle.coreir.DefineCoreirNeq(width=4)(name="veq") - waddr = Define_mantle_reg_U6(init=0)() - waddr_eq = mantle.coreir.DefineCoreirEq(width=4)(name="waddr_eq") - waddr_mux = mantle.coreir.DefineCoreirMux(width=4)(name="waddr_mux") - zero_const = mantle.coreir.DefineCoreirConst(value=0, width=4)(name="zero_const") - wire(add_r.I0, raddr.O) - wire(add_r.I1, c1.O) - wire(raddr_eq.I0, add_r.O) - wire(raddr_mux.I0, add_r.O) - wire(add_w.I0, waddr.O) - wire(add_w.I1, c1.O) - wire(waddr_eq.I0, add_w.O) - wire(waddr_mux.I0, add_w.O) - wire(raddr_eq.I1, max_const.O) - wire(waddr_eq.I1, max_const.O) - wire(mem.clk, io.clk) - wire(mem.raddr, raddr.O) - wire(io.rdata, mem.rdata) - wire(mem.waddr, waddr.O) - wire(mem.wdata, io.wdata) - wire(mem.wen, io.wen) - wire(raddr.clk, io.clk) - wire(raddr.en, io.wen) - wire(raddr.I, raddr_mux.O) - wire(veq.I0, raddr.O) - wire(raddr_mux.S, raddr_eq.O) - wire(raddr_mux.I1, zero_const.O) - wire(waddr.clk, io.clk) - wire(io.valid, veq.O) - wire(waddr.en, io.wen) - wire(veq.I1, waddr.O) - wire(waddr.I, waddr_mux.O) - wire(waddr_mux.S, waddr_eq.O) - wire(waddr_mux.I1, zero_const.O) class commonlib_Linebuffer_U3(Circuit): - name = "commonlib_Linebuffer_U3" - io = m.IO(clk=In(Clock), I=Array[ 16,In(Bit) ], wen=In(Bit), O=Array[ 2,Array[ 1,Array[ 16,Out(Bit) ] ] ]) - @classmethod - def definition(io): - mem_1 = commonlib_LinebufferMem_U5() - mem_1_valid_term = mantle.coreir.DefineCorebitTerm()(name="mem_1_valid_term") - wire(io.O[0][0], mem_1.rdata) - wire(mem_1_valid_term.I, mem_1.valid) - wire(mem_1.wdata, io.I) - wire(mem_1.wen, io.wen) - wire(io.O[1][0], io.I) + name = "commonlib_Linebuffer_U3" + io = m.IO(clk=In(Clock), I=Array[16, In(Bit)], wen=In( + Bit), O=Array[2, Array[1, Array[16, Out(Bit)]]]) + + @classmethod + def definition(io): + mem_1 = commonlib_LinebufferMem_U5() + mem_1_valid_term = mantle.coreir.DefineCorebitTerm()(name="mem_1_valid_term") + wire(io.O[0][0], mem_1.rdata) + wire(mem_1_valid_term.I, mem_1.valid) + wire(mem_1.wdata, io.I) + wire(mem_1.wen, io.wen) + wire(io.O[1][0], io.I) + class mantle_wire_U0(Circuit): - name = "mantle_wire_U0" - io = m.IO(I=Array[ 16,In(Bit) ], O=Array[ 16,Out(Bit) ]) - @classmethod - def definition(io): - wire(io.O, io.I) + name = "mantle_wire_U0" + io = m.IO(I=Array[16, In(Bit)], O=Array[16, Out(Bit)]) + @classmethod + def definition(io): + wire(io.O, io.I) + class global_DesignTop(Circuit): - name = "global_DesignTop" - io = m.IO(clk=In(Clock), I=Array[ 1,Array[ 16,In(Bit) ] ], O=Array[ 16,Out(Bit) ]) - @classmethod - def definition(io): - _336_pt = mantle_wire_U0() - _341_pt = mantle_wire_U0() - add_335_339_340 = mantle.coreir.DefineCoreirAdd(width=16)(name="add_335_339_340") - add_335_343_344 = mantle.coreir.DefineCoreirAdd(width=16)(name="add_335_343_344") - const0__334 = mantle.coreir.DefineCoreirConst(value=0, width=16)(name="const0__334") - const7__338 = mantle.coreir.DefineCoreirConst(value=7, width=16)(name="const7__338") - const7__338__ds__1 = mantle.coreir.DefineCoreirConst(value=7, width=16)(name="const7__338__ds__1") - lb_p4_clamped_stencil_update_stream = commonlib_Linebuffer_U3() - lb_p4_clamped_stencil_update_stream_wen = mantle.coreir.DefineCorebitConst(value=1)(name="lb_p4_clamped_stencil_update_stream_wen") - mul_337_338_339 = mantle.coreir.DefineCoreirMul(width=16)(name="mul_337_338_339") - mul_342_338_343 = mantle.coreir.DefineCoreirMul(width=16)(name="mul_342_338_343") - wire(_336_pt.I, lb_p4_clamped_stencil_update_stream.O[0][0]) - wire(mul_337_338_339.I0, _336_pt.O) - wire(_341_pt.I, lb_p4_clamped_stencil_update_stream.O[1][0]) - wire(mul_342_338_343.I0, _341_pt.O) - wire(add_335_339_340.I0, const0__334.O) - wire(add_335_339_340.I1, mul_337_338_339.O) - wire(add_335_343_344.I0, add_335_339_340.O) - wire(add_335_343_344.I1, mul_342_338_343.O) - wire(io.O, add_335_343_344.O) - wire(mul_337_338_339.I1, const7__338.O) - wire(mul_342_338_343.I1, const7__338__ds__1.O) - wire(lb_p4_clamped_stencil_update_stream.clk, io.clk) - wire(lb_p4_clamped_stencil_update_stream.I, io.I[0]) - wire(lb_p4_clamped_stencil_update_stream.wen, lb_p4_clamped_stencil_update_stream_wen.O) + name = "global_DesignTop" + io = m.IO(clk=In(Clock), + I=Array[1, Array[16, In(Bit)]], O=Array[16, Out(Bit)]) + + @classmethod + def definition(io): + _336_pt = mantle_wire_U0() + _341_pt = mantle_wire_U0() + add_335_339_340 = mantle.coreir.DefineCoreirAdd( + width=16)(name="add_335_339_340") + add_335_343_344 = mantle.coreir.DefineCoreirAdd( + width=16)(name="add_335_343_344") + const0__334 = mantle.coreir.DefineCoreirConst( + value=0, width=16)(name="const0__334") + const7__338 = mantle.coreir.DefineCoreirConst( + value=7, width=16)(name="const7__338") + const7__338__ds__1 = mantle.coreir.DefineCoreirConst( + value=7, width=16)(name="const7__338__ds__1") + lb_p4_clamped_stencil_update_stream = commonlib_Linebuffer_U3() + lb_p4_clamped_stencil_update_stream_wen = mantle.coreir.DefineCorebitConst( + value=1)(name="lb_p4_clamped_stencil_update_stream_wen") + mul_337_338_339 = mantle.coreir.DefineCoreirMul( + width=16)(name="mul_337_338_339") + mul_342_338_343 = mantle.coreir.DefineCoreirMul( + width=16)(name="mul_342_338_343") + wire(_336_pt.I, lb_p4_clamped_stencil_update_stream.O[0][0]) + wire(mul_337_338_339.I0, _336_pt.O) + wire(_341_pt.I, lb_p4_clamped_stencil_update_stream.O[1][0]) + wire(mul_342_338_343.I0, _341_pt.O) + wire(add_335_339_340.I0, const0__334.O) + wire(add_335_339_340.I1, mul_337_338_339.O) + wire(add_335_343_344.I0, add_335_339_340.O) + wire(add_335_343_344.I1, mul_342_338_343.O) + wire(io.O, add_335_343_344.O) + wire(mul_337_338_339.I1, const7__338.O) + wire(mul_342_338_343.I1, const7__338__ds__1.O) + wire(lb_p4_clamped_stencil_update_stream.clk, io.clk) + wire(lb_p4_clamped_stencil_update_stream.I, io.I[0]) + wire(lb_p4_clamped_stencil_update_stream.wen, + lb_p4_clamped_stencil_update_stream_wen.O) + def test_conv(): compile("build/test_coreir_conv", global_DesignTop, output="coreir") assert check_files_equal(__file__, - "build/test_coreir_conv.json", "gold/test_coreir_conv.json") + "build/test_coreir_conv.json", "gold/test_coreir_conv.json") diff --git a/tests/test_coreir/test_coreir_shift_register.py b/tests/test_coreir/test_coreir_shift_register.py index ba0e7f3..50fd85d 100644 --- a/tests/test_coreir/test_coreir_shift_register.py +++ b/tests/test_coreir/test_coreir_shift_register.py @@ -6,7 +6,7 @@ def test_shift_register(): N = 4 Register4 = DefineRegister(4) - T = m.Bits[ N ] + T = m.Bits[N] class ShiftRegister(m.Circuit): name = "ShiftRegister" diff --git a/tests/test_coreir/test_logic.py b/tests/test_coreir/test_logic.py index 469e4cb..b397db2 100644 --- a/tests/test_coreir/test_logic.py +++ b/tests/test_coreir/test_logic.py @@ -1,12 +1,12 @@ +import fault +from mantle import lsl, lsr +from mantle.coreir import static_left_shift, static_right_shift, Wire +from mantle.coreir import NAnd, NOr, NXOr, ReduceNAnd, ReduceNOr, ReduceNXOr +from mantle.coreir import And, Or, XOr, Not, Invert, ReduceAnd, ReduceOr, ReduceXOr +from magma.testing import check_files_equal +from magma import * import pytest coreir = pytest.importorskip("coreir") -from magma import * -from magma.testing import check_files_equal -from mantle.coreir import And, Or, XOr, Not, Invert, ReduceAnd, ReduceOr, ReduceXOr -from mantle.coreir import NAnd, NOr, NXOr, ReduceNAnd, ReduceNOr, ReduceNXOr -from mantle.coreir import static_left_shift, static_right_shift, Wire -from mantle import lsl, lsr -import fault def test_coreir_bit(): @@ -20,7 +20,7 @@ def definition(circuit): wire(d, circuit.d) compile("build/test_coreir_bit", TestCircuit, output="coreir") assert check_files_equal(__file__, - "build/test_coreir_bit.json", "gold/test_coreir_bit.json") + "build/test_coreir_bit.json", "gold/test_coreir_bit.json") def test_coreir_bit_2(): @@ -30,64 +30,77 @@ class TestCircuit(Circuit): @classmethod def definition(circuit): d = NOr(2)((NAnd(2)(circuit.a, circuit.b)), - NXOr(2)(circuit.b, circuit.c)) + NXOr(2)(circuit.b, circuit.c)) wire(d, circuit.d) compile("build/test_coreir_bit_2", TestCircuit, output="coreir") assert check_files_equal(__file__, - "build/test_coreir_bit_2.json", "gold/test_coreir_bit_2.json") + "build/test_coreir_bit_2.json", "gold/test_coreir_bit_2.json") def test_coreir_bits(): width = 4 + class TestCircuit(Circuit): name = "test_coreir_bits" - io = m.IO(a=In(Bits[ width ]), b=In(Bits[ width ]), c=In(Bits[ width ]), d=Out(Bits[ width ])) + io = m.IO(a=In(Bits[width]), b=In(Bits[width]), + c=In(Bits[width]), d=Out(Bits[width])) + @classmethod def definition(circuit): d = Or(2, width)(Invert(width)(And(2, width)(circuit.a, circuit.b)), - XOr(2, width)(circuit.b, circuit.c)) + XOr(2, width)(circuit.b, circuit.c)) wire(d, circuit.d) compile("build/test_coreir_bits", TestCircuit, output="coreir") assert check_files_equal(__file__, - "build/test_coreir_bits.json", "gold/test_coreir_bits.json") + "build/test_coreir_bits.json", "gold/test_coreir_bits.json") def test_coreir_bits_2(): width = 4 + class TestCircuit(Circuit): name = "test_coreir_bits_2" - io = m.IO(a=In(Bits[ width ]), b=In(Bits[ width ]), c=In(Bits[ width ]), d=Out(Bits[ width ])) + io = m.IO(a=In(Bits[width]), b=In(Bits[width]), + c=In(Bits[width]), d=Out(Bits[width])) + @classmethod def definition(circuit): d = NOr(2, width)(NAnd(2, width)(circuit.a, circuit.b), - NXOr(2, width)(circuit.b, circuit.c)) + NXOr(2, width)(circuit.b, circuit.c)) wire(d, circuit.d) compile("build/test_coreir_bits_2", TestCircuit, output="coreir") assert check_files_equal(__file__, - "build/test_coreir_bits_2.json", "gold/test_coreir_bits_2.json") + "build/test_coreir_bits_2.json", "gold/test_coreir_bits_2.json") def test_three_args(): width = 4 + class TestCircuit(Circuit): name = "test_coreir_three_args" - io = m.IO(a=In(Bits[ width ]), b=In(Bits[ width ]), c=In(Bits[ width ]), d=Out(Bits[ width ])) + io = m.IO(a=In(Bits[width]), b=In(Bits[width]), + c=In(Bits[width]), d=Out(Bits[width])) + @classmethod def definition(circuit): d = Or(3, width)(circuit.a, - Invert(width)(And(3, width)(circuit.a, circuit.b, circuit.c)), + Invert(width)(And(3, width)( + circuit.a, circuit.b, circuit.c)), XOr(3, width)(circuit.b, circuit.c, circuit.a)) wire(d, circuit.d) compile("build/test_coreir_three_args", TestCircuit, output="coreir") assert check_files_equal(__file__, - "build/test_coreir_three_args.json", "gold/test_coreir_three_args.json") + "build/test_coreir_three_args.json", "gold/test_coreir_three_args.json") def test_reduce(): width = 4 + class TestCircuit(Circuit): name = "test_coreir_reduce" - io = m.IO(a=In(Bits[ width ]), b=In(Bits[ width ]), c=In(Bits[ width ]), d=Out(Bit)) + io = m.IO(a=In(Bits[width]), b=In(Bits[width]), + c=In(Bits[width]), d=Out(Bit)) + @classmethod def definition(circuit): d = Or(3, None)(ReduceAnd(width)(circuit.a), @@ -96,14 +109,17 @@ def definition(circuit): wire(d, circuit.d) compile("build/test_coreir_reduce", TestCircuit, output="coreir") assert check_files_equal(__file__, - "build/test_coreir_reduce.json", "gold/test_coreir_reduce.json") + "build/test_coreir_reduce.json", "gold/test_coreir_reduce.json") def test_reduce_2(): width = 4 + class TestCircuit(Circuit): name = "test_coreir_reduce_2" - io = m.IO(a=In(Bits[ width ]), b=In(Bits[ width ]), c=In(Bits[ width ]), d=Out(Bit)) + io = m.IO(a=In(Bits[width]), b=In(Bits[width]), + c=In(Bits[width]), d=Out(Bit)) + @classmethod def definition(circuit): d = Or(3, None)(ReduceNAnd(width)(circuit.a), @@ -112,14 +128,15 @@ def definition(circuit): wire(d, circuit.d) compile("build/test_coreir_reduce_2", TestCircuit, output="coreir") assert check_files_equal(__file__, - "build/test_coreir_reduce_2.json", "gold/test_coreir_reduce_2.json") + "build/test_coreir_reduce_2.json", "gold/test_coreir_reduce_2.json") def test_static_shift(): width = 4 + class TestCircuit(Circuit): name = "test_coreir_static_shift" - io = m.IO(a=In(Bits[ width ]), b=In(Bits[ width ]), c=Out(Bits[ width ])) + io = m.IO(a=In(Bits[width]), b=In(Bits[width]), c=Out(Bits[width])) @classmethod def definition(circuit): c = Or(2, width)(static_left_shift(circuit.a, 2), @@ -127,14 +144,15 @@ def definition(circuit): wire(c, circuit.c) compile("build/test_coreir_static_shift", TestCircuit, output="coreir") assert check_files_equal(__file__, - "build/test_coreir_static_shift.json", "gold/test_coreir_static_shift.json") + "build/test_coreir_static_shift.json", "gold/test_coreir_static_shift.json") def test_ls(): width = 4 + class TestCircuit(Circuit): name = "test_coreir_ls" - io = m.IO(a=In(Bits[ width ]), b=In(UInt[ width ]), c=Out(Bits[ width ])) + io = m.IO(a=In(Bits[width]), b=In(UInt[width]), c=Out(Bits[width])) @classmethod def definition(circuit): c = Or(2, width)(lsl(circuit.a, circuit.b), @@ -142,14 +160,15 @@ def definition(circuit): wire(c, circuit.c) compile("build/test_coreir_ls", TestCircuit, output="coreir") assert check_files_equal(__file__, - "build/test_coreir_ls.json", "gold/test_coreir_ls.json") + "build/test_coreir_ls.json", "gold/test_coreir_ls.json") def test_wire(): width = 4 + class TestCircuit(Circuit): name = "test_coreir_wire" - io = m.IO(a=In(Bits[ width ]), b=Out(Bits[ width ]), e=Out(Bit)) + io = m.IO(a=In(Bits[width]), b=Out(Bits[width]), e=Out(Bit)) @classmethod def definition(circuit): c = Wire(width, name="c") @@ -158,7 +177,7 @@ def definition(circuit): wire(d(circuit.a[0]), circuit.e) compile("build/test_coreir_wire", TestCircuit, output="coreir") assert check_files_equal(__file__, - "build/test_coreir_wire.json", "gold/test_coreir_wire.json") + "build/test_coreir_wire.json", "gold/test_coreir_wire.json") tester = fault.Tester(TestCircuit) for i in range(0, 1 << 4): tester.poke(TestCircuit.a, i) diff --git a/tests/test_coreir/test_lut.py b/tests/test_coreir/test_lut.py index 729a782..7ad72d7 100644 --- a/tests/test_coreir/test_lut.py +++ b/tests/test_coreir/test_lut.py @@ -18,4 +18,4 @@ def definition(cls): m.compile("build/test_lut3", Test, output="coreir") assert check_files_equal(__file__, - "build/test_lut3.json", "gold/test_lut3.json") + "build/test_lut3.json", "gold/test_lut3.json") diff --git a/tests/test_coreir/test_memory.py b/tests/test_coreir/test_memory.py index 3376b30..18cc1fb 100644 --- a/tests/test_coreir/test_memory.py +++ b/tests/test_coreir/test_memory.py @@ -1,24 +1,27 @@ +import os +from magma.backend.coreir_ import CoreIRBackend +from magma.simulator.coreir_simulator import CoreIRSimulator +from mantle import RAM +from mantle.coreir.memory import DefineCoreirMem, DefineRAM, DefineMemory +from magma.testing import check_files_equal +from magma import * import pytest coreir = pytest.importorskip("coreir") -from magma import * -from magma.testing import check_files_equal -from mantle.coreir.memory import DefineCoreirMem, DefineRAM, DefineMemory -from mantle import RAM -from magma.simulator.coreir_simulator import CoreIRSimulator -from magma.backend.coreir_ import CoreIRBackend -import os + def test_coreir_rom(): addr_width = 2 width = 16 + class Mem(Circuit): name = "test_coreir_mem" - io = m.IO(raddr=In(Bits[ addr_width ]), - rdata=Out(Bits[ width ]), - waddr=In(Bits[ addr_width ]), - wdata=In(Bits[ width ]), - clk=In(Clock), - wen=In(Bit) ) + io = m.IO(raddr=In(Bits[addr_width]), + rdata=Out(Bits[width]), + waddr=In(Bits[addr_width]), + wdata=In(Bits[width]), + clk=In(Clock), + wen=In(Bit)) + @classmethod def definition(io): mem = DefineCoreirMem(4, 16)() @@ -30,7 +33,8 @@ def definition(io): wire(io.wen, mem.wen) compile("build/test_coreir_mem", Mem, output="coreir") assert check_files_equal(__file__, - "build/test_coreir_mem.json", "gold/test_coreir_mem.json") + "build/test_coreir_mem.json", "gold/test_coreir_mem.json") + def test_ram1x8(): c = coreir.Context() @@ -39,10 +43,12 @@ def test_ram1x8(): testcircuit = DefineRAM(1, 8) CoreIRSimulator(testcircuit, testcircuit.CLK, context=cirb.context) + def test_ram_latency1(): - mem = DefineMemory(height=256,width=16,read_latency=1) + mem = DefineMemory(height=256, width=16, read_latency=1) compile("build/test_latency", mem, output='coreir-verilog') - assert check_files_equal(__file__,"build/test_latency.v","gold/test_latency.v") + assert check_files_equal( + __file__, "build/test_latency.v", "gold/test_latency.v") def test_generic_memory_import(): diff --git a/tests/test_coreir/test_operator.py b/tests/test_coreir/test_operator.py index 34a6a00..f5c21f0 100644 --- a/tests/test_coreir/test_operator.py +++ b/tests/test_coreir/test_operator.py @@ -6,7 +6,7 @@ def test_dyanmic_mux_getitem(): class TestDynamicMuxGetItem(m.Circuit): - io = m.IO(I=m.In(m.Bits[ 2 ]), S=m.In(m.Bit), O=m.Out(m.Bit)) + io = m.IO(I=m.In(m.Bits[2]), S=m.In(m.Bit), O=m.Out(m.Bit)) @classmethod def definition(io): diff --git a/tests/test_coreir/test_register.py b/tests/test_coreir/test_register.py index 5bd64f9..1a86b1b 100644 --- a/tests/test_coreir/test_register.py +++ b/tests/test_coreir/test_register.py @@ -6,8 +6,8 @@ @pytest.mark.parametrize("has_ce", [True, False]) @pytest.mark.parametrize("has_async_reset,has_async_resetn", [(True, False), - (False, True), - (False, False)]) + (False, True), + (False, False)]) def test_reg(has_ce, has_async_reset, has_async_resetn): def DefineReg(): @@ -31,7 +31,8 @@ def definition(io): return testReg test = DefineReg() - m.compile(f"build/testReg-{has_ce}-{has_async_reset}-{has_async_resetn}", test, output="coreir-verilog") + m.compile( + f"build/testReg-{has_ce}-{has_async_reset}-{has_async_resetn}", test, output="coreir-verilog") assert check_files_equal( __file__, diff --git a/tests/test_mantle/test_operator.py b/tests/test_mantle/test_operator.py index ebf41b9..eefcf51 100644 --- a/tests/test_mantle/test_operator.py +++ b/tests/test_mantle/test_operator.py @@ -6,9 +6,10 @@ def test_mux(): class Test(m.Circuit): io = m.IO(I0=m.In(m.Bits[10]), - I1=m.In(m.Bits[10]), - S=m.In(m.Bit), - O=m.Out(m.Bits[10])) + I1=m.In(m.Bits[10]), + S=m.In(m.Bit), + O=m.Out(m.Bits[10])) + @classmethod def definition(io): io.O <= mantle.mux([io.I0, io.I1], io.S, name="my_mux") From fd9773180a8a7c384f033785ab318259f84c9653 Mon Sep 17 00:00:00 2001 From: Teguh Hofstee Date: Wed, 26 Feb 2020 17:14:21 -0800 Subject: [PATCH 3/4] fix single quotes --- mantle/common/RAM.py | 28 ++++++++++++++-------------- mantle/common/ROM.py | 2 +- mantle/common/arbiter.py | 2 +- mantle/common/barrel.py | 8 ++++---- mantle/common/counter.py | 2 +- mantle/common/decoder.py | 2 +- mantle/common/encoder.py | 2 +- mantle/common/johnson.py | 2 +- mantle/common/pipo.py | 4 ++-- mantle/common/piso.py | 4 ++-- mantle/common/register.py | 2 +- mantle/common/ring.py | 2 +- mantle/common/sipo.py | 2 +- mantle/common/siso.py | 2 +- mantle/lattice/ice40/BUF.py | 2 +- mantle/lattice/mantle40/arith.py | 2 +- mantle/lattice/mantle40/compare.py | 8 ++++---- mantle/lattice/mantle40/logic.py | 4 ++-- mantle/primitives/arith.py | 2 +- mantle/util/compressor/pop.py | 2 +- mantle/util/sort/bitonic.py | 6 +++--- mantle/util/sort/brick.py | 2 +- mantle/util/sort/evenodd.py | 4 ++-- mantle/util/sort/swap.py | 6 +++--- mantle/xilinx/mantle3/arith.py | 2 +- mantle/xilinx/mantle3/compare.py | 8 ++++---- mantle/xilinx/mantle3/decode.py | 2 +- mantle/xilinx/mantle3/logic.py | 6 +++--- mantle/xilinx/mantle6/arith.py | 2 +- mantle/xilinx/mantle6/compare.py | 8 ++++---- mantle/xilinx/mantle6/decode.py | 2 +- mantle/xilinx/mantle6/logic.py | 6 +++--- 32 files changed, 69 insertions(+), 69 deletions(-) diff --git a/mantle/common/RAM.py b/mantle/common/RAM.py index 4ce2720..a3545f9 100644 --- a/mantle/common/RAM.py +++ b/mantle/common/RAM.py @@ -51,12 +51,12 @@ def DefineRAM(height, width): class _RAM(Circuit): name = f'RAM{height}x{width}' - io = m.IO('RADDR', In(TADDR), - 'RDATA', Out(TDATA), - 'WADDR', In(TADDR), - 'WDATA', In(TDATA), - 'WE', In(Bit), - 'CLK', In(Clock) + io = m.IO(RADDR=In(TADDR), + RDATA=Out(TDATA), + WADDR=In(TADDR), + WDATA=In(TDATA), + WE=In(Bit), + CLK=In(Clock) ) @classmethod @@ -75,14 +75,14 @@ def DefineDualRAM(height, width): class _DualRAM(Circuit): name = f'DualRAM{height}x{width}' - io = m.IO('RADDR0', In(TADDR), - 'RDATA0', Out(TDATA), - 'RADDR1', In(TADDR), - 'RDATA1', Out(TDATA), - 'WADDR', In(TADDR), - 'WDATA', In(TDATA), - 'WE', In(Bit), - 'CLK', In(Clock)) + io = m.IO(RADDR0=In(TADDR), + RDATA0=Out(TDATA), + RADDR1=In(TADDR), + RDATA1=Out(TDATA), + WADDR=In(TADDR), + WDATA=In(TDATA), + WE=In(Bit), + CLK=In(Clock)) @classmethod def definition(io): diff --git a/mantle/common/ROM.py b/mantle/common/ROM.py index bcbdb27..e0f14f1 100644 --- a/mantle/common/ROM.py +++ b/mantle/common/ROM.py @@ -40,7 +40,7 @@ def DefineROM(height, width, data): class _ROM(Circuit): name = f'ROM{n}x{width}' - io = m.IO('RADDR', In(TADDR), 'RDATA', Out(TDATA)) + io = m.IO(RADDR=In(TADDR), RDATA=Out(TDATA)) @classmethod def definition(io): diff --git a/mantle/common/arbiter.py b/mantle/common/arbiter.py index 8320c7e..7ae383d 100644 --- a/mantle/common/arbiter.py +++ b/mantle/common/arbiter.py @@ -15,7 +15,7 @@ def DefineArbiter(n): class _Arbiter(Circuit): name = 'Arbiter'+str(n) - io = m.IO('I', In(T), 'O', Out(T)) + io = m.IO(I=In(T), O=Out(T)) @classmethod def definition(Arb): ones = n * [1] diff --git a/mantle/common/barrel.py b/mantle/common/barrel.py index 8e3c0c6..19d5e51 100644 --- a/mantle/common/barrel.py +++ b/mantle/common/barrel.py @@ -18,7 +18,7 @@ def DefineShiftK(n, k, op): class _ShiftK(Circuit): name = f'{op.upper()}{n}_{k}' - io = m.IO('I', In(T), 'S', In(Bit), O=Out(T)) + io = m.IO(I=In(T), S=In(Bit), O=Out(T)) @classmethod def definition(io): Is = [io.I[i] for i in range(n)] @@ -53,7 +53,7 @@ def DefineShift(n, op): class _Shift(Circuit): name = f'{op.upper()}{n}' - io = m.IO('I', In(T), 'S', In(Bits[logn]), O=Out(T)) + io = m.IO(I=In(T), S=In(Bits[logn]), O=Out(T)) @classmethod def definition(io): I = io.I @@ -97,7 +97,7 @@ def DefineRotateK(n, k, op): class _RotateK(Circuit): name = f'{op.upper()}{n}_{k}' - io = m.IO('I', In(T), 'S', In(Bit), O=Out(T)) + io = m.IO(I=In(T), S=In(Bit), O=Out(T)) @classmethod def definition(io): Is = [io.I[i] for i in range(n)] @@ -129,7 +129,7 @@ def DefineRotate(n, op): class _Rotate(Circuit): name = f'{op.upper()}{n}' - io = m.IO('I', In(T), 'S', In(Bits[logn]), O=Out(T)) + io = m.IO(I=In(T), S=In(Bits[logn]), O=Out(T)) @classmethod def definition(io): I = io.I diff --git a/mantle/common/counter.py b/mantle/common/counter.py index bbc091a..fd7ab3f 100644 --- a/mantle/common/counter.py +++ b/mantle/common/counter.py @@ -177,7 +177,7 @@ class CeilFloorUpDownCounter(Circuit): num_bits = math.ceil(math.log(m, 2)) name = "CeilFloorUpDownCounter_m{}_hasCE{}_hasReset{}".format( str(m), str(has_ce), str(has_reset)) - io = m.IO('U', In(Bit), 'D', In(Bit), 'O', Out( + io = m.IO(U=In(Bit), D=In(Bit), O=Out( UInt[num_bits])) + ClockInterface(has_ce, has_reset) @classmethod diff --git a/mantle/common/decoder.py b/mantle/common/decoder.py index ea77066..e87c056 100644 --- a/mantle/common/decoder.py +++ b/mantle/common/decoder.py @@ -11,7 +11,7 @@ def DefineDecoder(n, invert=False): class _Decoder(Circuit): name = 'Decoder'+str(n)+("Invert" if invert else "") - io = m.IO('I', In(Bits[n]), 'O', Out(Bits[1 << n])) + io = m.IO(I=In(Bits[n]), O=Out(Bits[1 << n])) @classmethod def definition(io): def decode(y): diff --git a/mantle/common/encoder.py b/mantle/common/encoder.py index f6a54d9..1118114 100644 --- a/mantle/common/encoder.py +++ b/mantle/common/encoder.py @@ -18,7 +18,7 @@ def DefineEncoder(n): class _Encoder(Circuit): name = 'Encoder'+str(n) - io = m.IO('I', In(Bits[n]), 'O', Out(Bits[logn])) + io = m.IO(I=In(Bits[n]), O=Out(Bits[logn])) @classmethod def definition(Enc): def f(y): diff --git a/mantle/common/johnson.py b/mantle/common/johnson.py index 84450b4..3f8ba35 100644 --- a/mantle/common/johnson.py +++ b/mantle/common/johnson.py @@ -15,7 +15,7 @@ def DefineJohnson(n, has_ce=False, has_reset=False): """ class Johnson(Circuit): name = _RegisterName('Johnson', n, 0, has_ce, has_reset) - io = m.IO('O', Out(Bits[n])) + ClockInterface(has_ce, has_reset) + io = m.IO(O=Out(Bits[n])) + ClockInterface(has_ce, has_reset) @classmethod def definition(johnson): ffs = FFs(n, has_ce=has_ce, has_reset=has_reset) diff --git a/mantle/common/pipo.py b/mantle/common/pipo.py index 956642d..1855a62 100644 --- a/mantle/common/pipo.py +++ b/mantle/common/pipo.py @@ -16,8 +16,8 @@ def DefinePIPO(n, init=0, has_ce=False, has_reset=False): class _PIPO(Circuit): name = _RegisterName('PIPO', n, init, has_ce, has_reset) - io = m.IO('SI', In(Bit), 'PI', In(T), 'LOAD', In(Bit), - 'O', Out(T)) + ClockInterface(has_ce, has_reset) + io = m.IO(SI=In(Bit), PI=In(T), LOAD=In(Bit), + O=Out(T)) + ClockInterface(has_ce, has_reset) @classmethod def definition(pipo): diff --git a/mantle/common/piso.py b/mantle/common/piso.py index ee2a001..47b7aed 100644 --- a/mantle/common/piso.py +++ b/mantle/common/piso.py @@ -16,8 +16,8 @@ def DefinePISO(n, init=0, has_ce=False, has_reset=False): class _PISO(Circuit): name = _RegisterName('PISO', n, init, has_ce, has_reset) - io = m.IO('SI', In(Bit), 'PI', In(T), 'LOAD', In(Bit), - 'O', Out(Bit)) + ClockInterface(has_ce, has_reset) + io = m.IO(SI=In(Bit), PI=In(T), LOAD=In(Bit), + O=Out(Bit)) + ClockInterface(has_ce, has_reset) @classmethod def definition(piso): diff --git a/mantle/common/register.py b/mantle/common/register.py index b49da66..aa6da3a 100644 --- a/mantle/common/register.py +++ b/mantle/common/register.py @@ -67,7 +67,7 @@ def DefineRegister(n, init=0, has_ce=False, has_reset=False, has_async_reset=Fal class _Register(Circuit): name = _RegisterName('Register', n, init, has_ce, has_reset) - io = m.IO('I', In(T), 'O', Out(T)) + ClockInterface(has_ce=has_ce, + io = m.IO(I=In(T), O=Out(T)) + ClockInterface(has_ce=has_ce, has_reset=has_reset, has_async_reset=has_async_reset) @classmethod diff --git a/mantle/common/ring.py b/mantle/common/ring.py index 6068b96..826221a 100644 --- a/mantle/common/ring.py +++ b/mantle/common/ring.py @@ -12,7 +12,7 @@ def DefineRing(n, init=1, has_ce=False, has_reset=False): """ class Ring(Circuit): name = _RegisterName('Ring', n, init, has_ce, has_reset) - io = m.IO('O', Out(Bits[n])) + ClockInterface(has_ce, has_reset) + io = m.IO(O=Out(Bits[n])) + ClockInterface(has_ce, has_reset) @classmethod def definition(ring): ffs = FFs(n, init=init, has_ce=has_ce, has_reset=has_reset) diff --git a/mantle/common/sipo.py b/mantle/common/sipo.py index 6d71b96..5a1a047 100644 --- a/mantle/common/sipo.py +++ b/mantle/common/sipo.py @@ -13,7 +13,7 @@ def DefineSIPO(n, init=0, has_ce=False, has_reset=False): class _SIPO(Circuit): name = _RegisterName('SIPO', n, init, has_ce, has_reset) - io = m.IO('I', In(Bit), 'O', Out(Bits[n])) + \ + io = m.IO(I=In(Bit), O=Out(Bits[n])) + \ ClockInterface(has_ce, has_reset) @classmethod diff --git a/mantle/common/siso.py b/mantle/common/siso.py index 7284465..d97a031 100644 --- a/mantle/common/siso.py +++ b/mantle/common/siso.py @@ -13,7 +13,7 @@ def DefineSISO(n, init=0, has_ce=False, has_reset=False): class _SISO(Circuit): name = _RegisterName('SISO', n, init, has_ce, has_reset) - io = m.IO('I', In(Bit), 'O', Out(Bit)) + \ + io = m.IO(I=In(Bit), O=Out(Bit)) + \ ClockInterface(has_ce, has_reset) @classmethod diff --git a/mantle/lattice/ice40/BUF.py b/mantle/lattice/ice40/BUF.py index 0f1f0d1..b06614a 100644 --- a/mantle/lattice/ice40/BUF.py +++ b/mantle/lattice/ice40/BUF.py @@ -14,7 +14,7 @@ def DefineBuf(width=1): class BufN(Circuit): name = 'Buf{}'.format(width) - io = m.IO('I', In(T), 'O', Out(T)) + io = m.IO(I=In(T), O=Out(T)) @classmethod def definition(def_): diff --git a/mantle/lattice/mantle40/arith.py b/mantle/lattice/mantle40/arith.py index fc25992..f6ad425 100644 --- a/mantle/lattice/mantle40/arith.py +++ b/mantle/lattice/mantle40/arith.py @@ -109,7 +109,7 @@ def DefineNegate(width): class _Negate(Circuit): name = 'Negate{}'.format(width) - io = m.IO('I', In(T), 'O', Out(T)) + io = m.IO(I=In(T), O=Out(T)) @classmethod def definition(io): invert = DefineInvert(width)() diff --git a/mantle/lattice/mantle40/compare.py b/mantle/lattice/mantle40/compare.py index d386949..9354ea8 100644 --- a/mantle/lattice/mantle40/compare.py +++ b/mantle/lattice/mantle40/compare.py @@ -75,7 +75,7 @@ def DefineEQ(n): class _EQ(Circuit): name = "EQ{}".format(n) - io = m.IO('I0', In(T), 'I1', In(T), O=Out(Bit)) + io = m.IO(I0=In(T), I1=In(T), O=Out(Bit)) @classmethod def definition(io): eq = _Cascade(n, 2, A0 & ((A1 & A2) | (~A1 & ~A2)), 1) @@ -115,7 +115,7 @@ def DefineNE(n): class _NE(Circuit): name = "NE{}".format(n) - io = m.IO('I0', In(T), 'I1', In(T), O=Out(Bit)) + io = m.IO(I0=In(T), I1=In(T), O=Out(Bit)) @classmethod def definition(io): ne = _Cascade(n, 2, A0 | (A1 ^ A2), 0) @@ -138,7 +138,7 @@ def DefineUCMP(opname, reverse, negate, n): class _UCMP(Circuit): name = "{}{}".format(opname, n) - io = m.IO('I0', In(T), 'I1', In(T), O=Out(Bit)) + io = m.IO(I0=In(T), I1=In(T), O=Out(Bit)) @classmethod def definition(io): sub = DefineSub(n, False, True)() @@ -184,7 +184,7 @@ def DefineSCMP(opname, op, reverse, n): class _SCMP(Circuit): name = "{}{}".format(opname, n) - io = m.IO('I0', In(T), 'I1', In(T), O=Out(Bit)) + io = m.IO(I0=In(T), I1=In(T), O=Out(Bit)) @classmethod def definition(io): sub = DefineSub(n)() diff --git a/mantle/lattice/mantle40/logic.py b/mantle/lattice/mantle40/logic.py index 41409b2..24e76ec 100644 --- a/mantle/lattice/mantle40/logic.py +++ b/mantle/lattice/mantle40/logic.py @@ -53,7 +53,7 @@ def DefineReduceOp(opname, n, luts, cascadeexpr, cin): class _ReduceOp(Circuit): name = '{}{}'.format(opname, n) - io = m.IO('I', In(T), 'O', Out(Bit)) + io = m.IO(I=In(T), O=Out(Bit)) @classmethod def definition(io): @@ -222,7 +222,7 @@ def DefineInvert(width): class _Invert(Circuit): name = 'Invert%d' % width - io = m.IO('I', In(T), 'O', Out(T)) + io = m.IO(I=In(T), O=Out(T)) @classmethod def definition(def_): diff --git a/mantle/primitives/arith.py b/mantle/primitives/arith.py index ab13b8e..68f5704 100644 --- a/mantle/primitives/arith.py +++ b/mantle/primitives/arith.py @@ -97,7 +97,7 @@ def DeclareNegate(width): class _Negate(Circuit): name = 'Negate{}'.format(width) - io = m.IO('I', In(T), 'O', Out(T)) + io = m.IO(I=In(T), O=Out(T)) return _Negate diff --git a/mantle/util/compressor/pop.py b/mantle/util/compressor/pop.py index afd4a77..df49720 100644 --- a/mantle/util/compressor/pop.py +++ b/mantle/util/compressor/pop.py @@ -8,7 +8,7 @@ def DefinePopCount(n): class _PopCount(Circuit): name = 'PopCount{}'.format(n) - io = m.IO('I', In(Bits[n]), 'O', Out(Bits[log2(n)+1])) + io = m.IO(I=In(Bits[n]), O=Out(Bits[log2(n)+1])) @classmethod def definition(io): r = compressor([io.I.as_list()]) diff --git a/mantle/util/sort/bitonic.py b/mantle/util/sort/bitonic.py index 3a737e5..7345e7d 100644 --- a/mantle/util/sort/bitonic.py +++ b/mantle/util/sort/bitonic.py @@ -18,7 +18,7 @@ def DefineBitonicSorter(n): class _BitonicSorter(Circuit): name = 'BitonicSorter{}'.format(n) - io = m.IO('I', In(T), O=Out(T)) + io = m.IO(I=In(T), O=Out(T)) @classmethod def definition(io): if n == 2: @@ -52,7 +52,7 @@ def DefineMerger(n): class _Merger(Circuit): name = 'Merger{}'.format(n) - io = m.IO('I', In(T), O=Out(T)) + io = m.IO(I=In(T), O=Out(T)) @classmethod def definition(io): if n == 2: @@ -87,7 +87,7 @@ def DefineSorter(n): class _Sorter(Circuit): name = 'Sorter{}'.format(n) - io = m.IO('I', In(T), O=Out(T)) + io = m.IO(I=In(T), O=Out(T)) @classmethod def definition(io): if n == 2: # Sort 2 element sequences diff --git a/mantle/util/sort/brick.py b/mantle/util/sort/brick.py index a272ad8..70d6bfe 100644 --- a/mantle/util/sort/brick.py +++ b/mantle/util/sort/brick.py @@ -16,7 +16,7 @@ def DefineBrickSorter(n): class _BrickSorter(Circuit): name = 'BrickSorter{}'.format(n) - io = m.IO('I', In(T), O=Out(T)) + io = m.IO(I=In(T), O=Out(T)) @classmethod def definition(io): I = io.I diff --git a/mantle/util/sort/evenodd.py b/mantle/util/sort/evenodd.py index b4d5b50..142d492 100644 --- a/mantle/util/sort/evenodd.py +++ b/mantle/util/sort/evenodd.py @@ -18,7 +18,7 @@ def DefineEvenOddMerger(n): class _EvenOddMerger(Circuit): name = 'EvenOddMerger{}'.format(n) - io = m.IO('I', In(T), O=Out(T)) + io = m.IO(I=In(T), O=Out(T)) @classmethod def definition(io): if n == 2: # Sort 2 element sequences @@ -56,7 +56,7 @@ def DefineEvenOddSorter(n): class _EvenOddSorter(Circuit): name = 'EvenOddSorter{}'.format(n) - io = m.IO('I', In(T), O=Out(T)) + io = m.IO(I=In(T), O=Out(T)) @classmethod def definition(io): if n == 2: # Sort 2 element sequences diff --git a/mantle/util/sort/swap.py b/mantle/util/sort/swap.py index 7ef27e7..0155ad0 100644 --- a/mantle/util/sort/swap.py +++ b/mantle/util/sort/swap.py @@ -11,7 +11,7 @@ class Swap(Circuit): - io = m.IO('I', In(Bits(2)), O=Out(Bits(2))) + io = m.IO(I=In(Bits(2)), O=Out(Bits(2))) @classmethod def definition(io): swap = uncurry(fork(And(2), Or(2)), prefix="I") @@ -26,7 +26,7 @@ def swap(I): def DefineSwaps(n): class Swaps(Circuit): name = 'Swap{}'.format(n) - io = m.IO('I', In(Bits(n)), O=Out(Bits(n))) + io = m.IO(I=In(Bits(n)), O=Out(Bits(n))) @classmethod def definition(io): s = flat(join(map_(Swap, n//2)), flatargs=['I', 'O']) @@ -45,7 +45,7 @@ def swaps(I): def DefineEvenOddSwaps(n): class EvenOddSwaps(Circuit): name = 'EvenOddSwap{}'.format(n) - io = m.IO('I', In(Bits(n)), O=Out(Bits(n))) + io = m.IO(I=In(Bits(n)), O=Out(Bits(n))) @classmethod def definition(io): s = flat(join(map_(Swap, n//2-1)), flatargs=['I', 'O']) diff --git a/mantle/xilinx/mantle3/arith.py b/mantle/xilinx/mantle3/arith.py index 16fe117..2637e91 100644 --- a/mantle/xilinx/mantle3/arith.py +++ b/mantle/xilinx/mantle3/arith.py @@ -83,7 +83,7 @@ def DefineNegate(n): class _Negate(Circuit): name = 'Negate{}'.format(n) - io = m.IO('I', In(T), 'O', Out(T)) + io = m.IO(I=In(T), O=Out(T)) @classmethod def definition(io): sub = DefineSub(n)() diff --git a/mantle/xilinx/mantle3/compare.py b/mantle/xilinx/mantle3/compare.py index f8f6bee..bc6298a 100644 --- a/mantle/xilinx/mantle3/compare.py +++ b/mantle/xilinx/mantle3/compare.py @@ -40,7 +40,7 @@ def DefineEQ(n): class _EQ(Circuit): name = "EQ{}".format(n) - io = m.IO('I0', In(T), 'I1', In(T), O=Out(Bit)) + io = m.IO(I0=In(T), I1=In(T), O=Out(Bit)) @classmethod def definition(io): eq = HalfCascade(n//2, 4, EQ2LUT, ZERO, 1) @@ -86,7 +86,7 @@ def DefineNE(n): class _NE(Circuit): name = "NE{}".format(n) - io = m.IO('I0', In(T), 'I1', In(T), O=Out(Bit)) + io = m.IO(I0=In(T), I1=In(T), O=Out(Bit)) @classmethod def definition(io): ne = HalfCascade(n//2, 4, NE2LUT, ZERO, 1) @@ -114,7 +114,7 @@ def DefineUCMP(opname, reverse, negate, n): class _UCMP(Circuit): name = "{}{}".format(opname, n) - io = m.IO('I0', In(T), 'I1', In(T), O=Out(Bit)) + io = m.IO(I0=In(T), I1=In(T), O=Out(Bit)) @classmethod def definition(io): sub = DefineSub(n, 1, True)() @@ -160,7 +160,7 @@ def DefineSCMP(opname, op, reverse, n): class _SCMP(Circuit): name = "{}{}".format(opname, n) - io = m.IO('I0', In(T), 'I1', In(T), O=Out(Bit)) + io = m.IO(I0=In(T), I1=In(T), O=Out(Bit)) @classmethod def definition(io): sub = DefineSub(n)() diff --git a/mantle/xilinx/mantle3/decode.py b/mantle/xilinx/mantle3/decode.py index 343619a..4af397e 100644 --- a/mantle/xilinx/mantle3/decode.py +++ b/mantle/xilinx/mantle3/decode.py @@ -15,7 +15,7 @@ def DefineDecode(i, n, invert=False): class _Decode(Circuit): name = 'Decode_{}_{}'.format(i, n) - io = m.IO('I', In(Bits[n]), 'O', Out(Bit)) + io = m.IO(I=In(Bits[n]), O=Out(Bit)) @classmethod def definition(io): diff --git a/mantle/xilinx/mantle3/logic.py b/mantle/xilinx/mantle3/logic.py index d3218cc..a9534fc 100644 --- a/mantle/xilinx/mantle3/logic.py +++ b/mantle/xilinx/mantle3/logic.py @@ -41,7 +41,7 @@ def DefineReduceOp(opname, n, lutexprs, andexpr, cin): class _ReduceOp(Circuit): name = '{}{}'.format(opname, n) - io = m.IO('I', In(T), 'O', Out(Bit)) + io = m.IO(I=In(T), O=Out(Bit)) @classmethod def definition(io): @@ -118,7 +118,7 @@ def DefineReduceLUT(opname, n, luts, cascadeexpr, cin): class _ReduceLUT(Circuit): name = '{}{}'.format(opname, n) - io = m.IO('I', In(T), 'O', Out(Bit)) + io = m.IO(I=In(T), O=Out(Bit)) @classmethod def definition(io): @@ -250,7 +250,7 @@ def DefineInvert(width): class _Invert(Circuit): name = 'Invert%d' % width - io = m.IO('I', In(T), 'O', Out(T)) + io = m.IO(I=In(T), O=Out(T)) @classmethod def definition(def_): diff --git a/mantle/xilinx/mantle6/arith.py b/mantle/xilinx/mantle6/arith.py index 29da45e..b29a73c 100644 --- a/mantle/xilinx/mantle6/arith.py +++ b/mantle/xilinx/mantle6/arith.py @@ -83,7 +83,7 @@ def DefineNegate(n): class _Negate(Circuit): name = 'Negate{}'.format(n) - io = m.IO('I', In(T), 'O', Out(T)) + io = m.IO(I=In(T), O=Out(T)) @classmethod def definition(io): sub = DefineSub(n)() diff --git a/mantle/xilinx/mantle6/compare.py b/mantle/xilinx/mantle6/compare.py index f8f6bee..bc6298a 100644 --- a/mantle/xilinx/mantle6/compare.py +++ b/mantle/xilinx/mantle6/compare.py @@ -40,7 +40,7 @@ def DefineEQ(n): class _EQ(Circuit): name = "EQ{}".format(n) - io = m.IO('I0', In(T), 'I1', In(T), O=Out(Bit)) + io = m.IO(I0=In(T), I1=In(T), O=Out(Bit)) @classmethod def definition(io): eq = HalfCascade(n//2, 4, EQ2LUT, ZERO, 1) @@ -86,7 +86,7 @@ def DefineNE(n): class _NE(Circuit): name = "NE{}".format(n) - io = m.IO('I0', In(T), 'I1', In(T), O=Out(Bit)) + io = m.IO(I0=In(T), I1=In(T), O=Out(Bit)) @classmethod def definition(io): ne = HalfCascade(n//2, 4, NE2LUT, ZERO, 1) @@ -114,7 +114,7 @@ def DefineUCMP(opname, reverse, negate, n): class _UCMP(Circuit): name = "{}{}".format(opname, n) - io = m.IO('I0', In(T), 'I1', In(T), O=Out(Bit)) + io = m.IO(I0=In(T), I1=In(T), O=Out(Bit)) @classmethod def definition(io): sub = DefineSub(n, 1, True)() @@ -160,7 +160,7 @@ def DefineSCMP(opname, op, reverse, n): class _SCMP(Circuit): name = "{}{}".format(opname, n) - io = m.IO('I0', In(T), 'I1', In(T), O=Out(Bit)) + io = m.IO(I0=In(T), I1=In(T), O=Out(Bit)) @classmethod def definition(io): sub = DefineSub(n)() diff --git a/mantle/xilinx/mantle6/decode.py b/mantle/xilinx/mantle6/decode.py index 343619a..4af397e 100644 --- a/mantle/xilinx/mantle6/decode.py +++ b/mantle/xilinx/mantle6/decode.py @@ -15,7 +15,7 @@ def DefineDecode(i, n, invert=False): class _Decode(Circuit): name = 'Decode_{}_{}'.format(i, n) - io = m.IO('I', In(Bits[n]), 'O', Out(Bit)) + io = m.IO(I=In(Bits[n]), O=Out(Bit)) @classmethod def definition(io): diff --git a/mantle/xilinx/mantle6/logic.py b/mantle/xilinx/mantle6/logic.py index 6435331..4ab34a9 100644 --- a/mantle/xilinx/mantle6/logic.py +++ b/mantle/xilinx/mantle6/logic.py @@ -40,7 +40,7 @@ def DefineReduceOp(opname, n, lutexprs, andexpr, cin): class _ReduceOp(Circuit): name = f'{opname}{n}' - io = m.IO('I', In(T), 'O', Out(Bit)) + io = m.IO(I=In(T), O=Out(Bit)) @classmethod def definition(io): @@ -118,7 +118,7 @@ def DefineReduceLUT(opname, n, luts, cascadeexpr, cin): class _ReduceLUT(Circuit): name = '{}{}'.format(opname, n) - io = m.IO('I', In(T), 'O', Out(Bit)) + io = m.IO(I=In(T), O=Out(Bit)) @classmethod def definition(io): @@ -250,7 +250,7 @@ def DefineInvert(width): class _Invert(Circuit): name = 'Invert%d' % width - io = m.IO('I', In(T), 'O', Out(T)) + io = m.IO(I=In(T), O=Out(T)) @classmethod def definition(def_): From 9010de787ec161e04f19af76f344b325eceb9b1f Mon Sep 17 00:00:00 2001 From: Teguh Hofstee Date: Wed, 26 Feb 2020 17:14:53 -0800 Subject: [PATCH 4/4] autopep8 --- mantle/common/register.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mantle/common/register.py b/mantle/common/register.py index aa6da3a..4300cc2 100644 --- a/mantle/common/register.py +++ b/mantle/common/register.py @@ -68,7 +68,7 @@ def DefineRegister(n, init=0, has_ce=False, has_reset=False, has_async_reset=Fal class _Register(Circuit): name = _RegisterName('Register', n, init, has_ce, has_reset) io = m.IO(I=In(T), O=Out(T)) + ClockInterface(has_ce=has_ce, - has_reset=has_reset, has_async_reset=has_async_reset) + has_reset=has_reset, has_async_reset=has_async_reset) @classmethod def definition(reg):