Example #1
0
    class DFF3(m.Circuit):
        name = make_name_dff3(array_size_2, array_size_1, width, pipe_depth,
                              retime_status)

        IO = [
            "data_in",
            m.Array(array_size_2, m.Array(array_size_1, m.In(m.Bits(width)))),
            "clk",
            m.In(m.Clock), "reset",
            m.In(m.Reset), "en",
            m.In(m.Bit), "data_out",
            m.Array(array_size_2, m.Array(array_size_1, m.Out(m.Bits(width))))
        ]

        @classmethod
        def definition(io):
            dffs = m.braid(m.map_(
                DefineDFF2(array_size_1, width, pipe_depth, retime_status),
                array_size_2),
                           joinargs=["data_in", "data_out"],
                           forkargs=["clk", "en", "reset"])
            m.wire(dffs.data_in, io.data_in)
            m.wire(dffs.data_out, io.data_out)
            m.wire(dffs.clk, io.clk)
            m.wire(dffs.en, io.en)
            m.wire(dffs.reset, io.reset)
Example #2
0
def wrap(index_list, argtype):
    if len(index_list) == 1:
        index = index_list[0] + 1
        return m.Array(index, argtype)
    else:
        index = index_list.pop(0) + 1
        return m.Array(index, wrap(index_list, argtype))
Example #3
0
    def __init__(self, height, width):
        super().__init__()

        self.height = height
        self.width = width

        T = magma.Bits(self.width)

        # In the case that @height <= 1, we make this circuit a simple
        # pass-through circuit.
        if self.height <= 1:
            self.add_ports(
                I=magma.In(magma.Array(1, T)),
                O=magma.Out(T),
            )
            self.wire(self.ports.I[0], self.ports.O)
            self.sel_bits = 0
            return

        MuxCls = mantle.DefineMux(self.height, self.width)
        self.mux = FromMagma(MuxCls)

        self.sel_bits = magma.bitutils.clog2(self.height)

        self.add_ports(
            I=magma.In(magma.Array(self.height, T)),
            S=magma.In(magma.Bits(self.sel_bits)),
            O=magma.Out(T),
        )

        for i in range(self.height):
            self.wire(self.ports.I[i], self.mux.ports[f"I{i}"])
        mux_in = self.ports.S if self.sel_bits > 1 else self.ports.S[0]
        self.wire(mux_in, self.mux.ports.S)
        self.wire(self.mux.ports.O, self.ports.O)
Example #4
0
    def __init__(self, width, num_tracks, core_inputs):
        super().__init__()

        self.width = width
        self.num_tracks = num_tracks
        assert core_inputs == 1
        self.core_inputs = core_inputs
        self.muxs = [MuxWrapper(self.num_tracks, self.width) \
                     for _ in range(self.num_tracks)]
        T = magma.Array(self.num_tracks, magma.Bits(self.width))
        bits_per_sel = math.ceil(math.log(self.num_tracks, 2))

        self.add_ports(
            I=magma.In(T),
            core_in=magma.In(magma.Array(self.core_inputs, T.T)),
            O=magma.Out(T),
        )
        for i in range(self.num_tracks):
            self.add_config(f"sel_{i}", bits_per_sel)
        self.selects = [getattr(self, f"sel_{i}") \
                        for i in range(self.num_tracks)]

        for i in range(self.num_tracks):
            mux = self.muxs[i]
            for j in range(self.num_tracks):
                mux_in = self.I[j] if i != j else self.core_in[0]
                self.wire(mux_in, mux.I[j])
            self.wire(self.selects[i], mux.S)
            self.wire(mux.O, self.O[i])
Example #5
0
class Foo(m.Circuit):
    IO = [
        "a",
        m.In(m.Bit), "b",
        m.In(m.Bits(8)), "c",
        m.In(m.Array(12, m.Bit)), "d",
        m.In(m.Array(16, m.Array(20, m.Bit)))
    ]
Example #6
0
def SideType(num_tracks, layers):
    layers_dict = {
        f"layer{l}": magma.Array(num_tracks, magma.Bits(l))
        for l in layers
    }
    T = magma.Tuple(**layers_dict)
    return magma.Tuple(I=magma.In(T), O=magma.Out(T))
Example #7
0
    def __init__(self, width, num_tracks, core):
        super().__init__()

        self.width = width
        self.num_tracks = num_tracks
        self.core = core
        self.sb = SBGenerator(self.width, self.num_tracks,
                              len(self.core.outputs()))
        self.cbs = [CBGenerator(self.width, self.num_tracks) \
                    for _ in range(len(self.core.inputs()))]
        T = magma.Array(self.num_tracks, magma.Bits(self.width))

        self.add_ports(
            I=magma.In(T),
            O=magma.Out(T),
        )

        self.wire(self.I, self.sb.I)
        for cb in self.cbs:
            self.wire(self.I, cb.I)
        for i, core_in in enumerate(self.core.inputs()):
            self.wire(self.cbs[i].O, core_in)
        for i, core_out in enumerate(self.core.outputs()):
            self.wire(core_out, self.sb.core_in[i])
        self.wire(self.sb.O, self.O)
Example #8
0
    class _SimpleCB(m.Circuit):
        name = make_name(width, num_tracks)

        IO = [
            "I",
            m.In(m.Array(num_tracks, T)),
            "O",
            m.Out(T),
        ]
        IO += ConfigInterface(CONFIG_ADDR_WIDTH, CONFIG_DATA_WIDTH)
        IO += m.ClockInterface(has_async_reset=True)

        @classmethod
        def definition(io):
            config = mantle.Register(CONFIG_DATA_WIDTH,
                                     init=config_reset,
                                     has_ce=True,
                                     has_async_reset=True)

            config_addr_zero = m.bits(0, 8) == io.config_addr[24:32]
            config(io.config_data, CE=(m.bit(io.config_en) & config_addr_zero))

            # If the top 8 bits of config_addr are 0, then read_data is equal
            # to the value of the config register, otherwise it is 0.
            m.wire(
                io.read_data,
                mantle.mux([m.uint(0, CONFIG_DATA_WIDTH), config.O],
                           config_addr_zero))

            # NOTE: This is not robust in the case that the mux which needs more
            # than 32 select bits (i.e. >= 2^32 inputs). This is unlikely to
            # happen, but this code is not general.
            out = generate_mux(io.I, config.O[:sel_bits], m.uint(0, width))
            m.wire(out, io.O)
Example #9
0
    def __init__(self):
        super().__init__()

        width = 16
        num_tracks = 4
        num_tiles = 10
        T = magma.Array(num_tracks, magma.Bits(width))

        self.tiles = []
        for i in range(num_tiles):
            if i % 2 == 0:
                core = PECoreGenerator(width)
            else:
                core = MemCoreGenerator(width)
            self.tiles.append(TileGenerator(width, num_tracks, core))

        self.add_ports(
            I=magma.In(T),
            O=magma.Out(T),
        )

        self.wire(self.I, self.tiles[0].I)
        self.wire(self.tiles[-1].O, self.O)
        for i in range(1, len(self.tiles)):
            t0 = self.tiles[i - 1]
            t1 = self.tiles[i]
            self.wire(t0.O, t1.I)
Example #10
0
    def __init__(self):
        super().__init__()

        width = 16
        num_tracks = 4
        num_tiles = 10
        T = magma.Array(num_tracks, magma.Bits(width))

        self.tiles = [TileGenerator(width, num_tracks) \
                      for _ in range(num_tiles)]

        self.add_ports(
            I=magma.In(T),
            O=magma.Out(T),
        )

        # for tile in self.tiles:
        #    self.wire(self.config_addr, tile.config_addr)
        #    self.wire(self.config_data, tile.config_data)
        self.wire(self.I, self.tiles[0].I)
        self.wire(self.tiles[-1].O, self.O)
        for i in range(1, len(self.tiles)):
            t0 = self.tiles[i - 1]
            t1 = self.tiles[i]
            self.wire(t0.O, t1.I)
Example #11
0
    def __init__(self, width, num_tracks):
        super().__init__()

        self.width = width
        self.num_tracks = num_tracks
        core = PECoreGenerator(self.width)
        sb = SBGenerator(self.width, self.num_tracks, len(core.outputs()))
        self.add_features(
            core=core,
            sb=sb,
        )
        for i in range(len(self.features.core.inputs())):
            cb = CBGenerator(self.width, self.num_tracks)
            self.add_feature(f"cb{i}", cb)
        T = magma.Array(self.num_tracks, magma.Bits(self.width))

        self.add_ports(
            I=magma.In(T),
            O=magma.Out(T),
        )

        self.wire(self.I, self.features.sb.I)
        for i in range(len(self.features.core.inputs())):
            cb = getattr(self.features, f"cb{i}")
            self.wire(self.I, cb.I)
        for i, core_in in enumerate(self.features.core.inputs()):
            cb = getattr(self.features, f"cb{i}")
            self.wire(cb.O, core_in)
        for i, core_out in enumerate(self.features.core.outputs()):
            self.wire(core_out, self.features.sb.core_in[i])
        self.wire(self.features.sb.O, self.O)
Example #12
0
    def __init__(self, columns):
        super().__init__()

        assert all([c.height == columns[0].height for c in columns])
        self.width = len(columns)
        self.height = columns[0].height
        self.columns = columns
        self.side_type = SideType(5, (1, 16))

        self.add_ports(
            north=magma.Array(self.width, self.side_type),
            south=magma.Array(self.width, self.side_type),
            west=magma.Array(self.height, self.side_type),
            east=magma.Array(self.height, self.side_type),
            config=magma.In(ConfigurationType(32, 32)),
            clk=magma.In(magma.Clock),
            reset=magma.In(magma.AsyncReset),
            read_config_data=magma.Out(magma.Bits(32)),
            # TODO: make number of stall domains a param
            stall=magma.In(magma.Bits(4)))

        for column in self.columns:
            self.wire(self.ports.config, column.ports.config)
            self.wire(self.ports.reset, column.ports.reset)
            self.wire(self.ports.stall, column.ports.stall)
        self.wire(self.ports.west, self.columns[0].ports.west)
        self.wire(self.ports.east, self.columns[-1].ports.east)
        for i, column in enumerate(self.columns):
            self.wire(self.ports.north[i], column.ports.north)
            self.wire(self.ports.south[i], column.ports.south)
        for i in range(1, self.width):
            c0 = self.columns[i - 1]
            c1 = self.columns[i]
            for j in range(self.height):
                self.wire(c1.ports.west[j].O, c0.ports.east[j].I)
                self.wire(c0.ports.east[j].O, c1.ports.west[j].I)

        # OR together read_data outputs from each column
        # number of inputs = number of columns
        self.read_data_OR = FromMagma(mantle.DefineOr(len(self.columns), 32))
        for i, col in enumerate(columns):
            self.wire(self.read_data_OR.ports[f"I{i}"],
                      col.ports.read_config_data)
            # wire up column number input
            self.wire(col.ports.column_num, Const(magma.bits(i, 8)))
        self.wire(self.read_data_OR.ports.O, self.ports.read_config_data)
Example #13
0
    def __init__(self, width, height):
        super().__init__()

        self.global_controller = GlobalController(32, 32)
        columns = []
        for i in range(width):
            tiles = []
            for j in range(height):
                core = MemCore(16, 1024) if (i % 2) else PECore()
                tiles.append(Tile(core))
            columns.append(ColumnMeso(tiles))
        self.interconnect = Interconnect(columns)

        side_type = self.interconnect.side_type
        self.add_ports(
            north=magma.Array(width, side_type),
            south=magma.Array(width, side_type),
            west=magma.Array(height, side_type),
            east=magma.Array(height, side_type),
            jtag=JTAGType,
            clk_in=magma.In(magma.Clock),
            reset_in=magma.In(magma.AsyncReset),
        )

        self.wire(self.ports.north, self.interconnect.ports.north)
        self.wire(self.ports.south, self.interconnect.ports.south)
        self.wire(self.ports.west, self.interconnect.ports.west)
        self.wire(self.ports.east, self.interconnect.ports.east)

        self.wire(self.ports.jtag, self.global_controller.ports.jtag)
        self.wire(self.ports.clk_in, self.global_controller.ports.clk_in)
        self.wire(self.ports.reset_in, self.global_controller.ports.reset_in)

        self.wire(self.global_controller.ports.config,
                  self.interconnect.ports.config)
        self.wire(self.global_controller.ports.clk_out,
                  self.interconnect.ports.clk)
        self.wire(self.global_controller.ports.reset_out,
                  self.interconnect.ports.reset)
        self.wire(self.global_controller.ports.stall,
                  self.interconnect.ports.stall)

        self.wire(self.interconnect.ports.read_config_data,
                  self.global_controller.ports.read_data_in)
Example #14
0
    def definition(io):
        load = io.LOAD
        baud = rising(io.SCK) | falling(io.SCK)

        valid_counter = mantle.CounterModM(buf_size, 12, has_ce=True)
        m.wire(load & baud, valid_counter.CE)

        valid_list = [wi * (b - 1) + i * a - 1
                      for i in range(1, wo + 1)]  # len = 32

        valid = m.GND

        for i in valid_list:
            valid = valid | mantle.Decode(i, 12)(valid_counter.O)

        # register on input
        st_in = mantle.Register(width, has_ce=True)
        st_in(io.DATA)
        m.wire(load, st_in.CE)

        # --------------------------DOWNSCALING----------------------------- #
        # downscale the image from 352x288 to 32x32
        Downscale = m.DeclareCircuit(
            'Downscale', "I_0_0",
            m.In(m.Array(1, m.Array(1, m.Array(width, m.Bit)))), "WE",
            m.In(m.Bit), "CLK", m.In(m.Clock), "O",
            m.Out(m.Array(width, m.Bit)), "V", m.Out(m.Bit))

        dscale = Downscale()

        m.wire(st_in.O, dscale.I_0_0[0][0])
        m.wire(1, dscale.WE)
        m.wire(load, dscale.CLK)

        add16 = mantle.Add(width)  # needed for Add16 definition

        # threshold the downscale output
        px_bit = mantle.ULE(16)(dscale.O, m.uint(THRESH, 16)) & valid

        # ---------------------------UART OUTPUT----------------------------- #

        m.wire(px_bit, io.O)
        m.wire(valid, io.VALID)
Example #15
0
    def __init__(self, num_tracks, width):
        super().__init__()

        if num_tracks <= 1:
            raise ValueError("num_tracks must be > 1")
        self.num_tracks = num_tracks
        self.width = width
        sel_bits = magma.bitutils.clog2(self.num_tracks)

        self.mux = MuxWrapper(self.num_tracks, self.width)

        T = magma.Bits(self.width)

        self.add_ports(
            I=magma.In(magma.Array(self.num_tracks, T)),
            O=magma.Out(T),
            clk=magma.In(magma.Clock),
            reset=magma.In(magma.AsyncReset),
            config=magma.In(ConfigurationType(8, 32)),
            read_config_data=magma.Out(magma.Bits(32)),
        )
        self.add_configs(S=sel_bits)
        # read_config_data output
        num_config_reg = len(self.registers)
        if (num_config_reg > 1):
            self.read_config_data_mux = MuxWrapper(num_config_reg, 32)
            self.wire(self.ports.config.config_addr,
                      self.read_config_data_mux.ports.S)
            self.wire(self.read_config_data_mux.ports.O,
                      self.ports.read_config_data)
            for idx, reg in enumerate(self.registers.values()):
                self.wire(reg.ports.O, self.read_config_data_mux.ports.I[idx])
                # Wire up config register resets
                self.wire(reg.ports.reset, self.ports.reset)
        # If we only have 1 config register, we don't need a mux
        # Wire sole config register directly to read_config_data_output
        else:
            reg = list(self.registers.values())[0]
            zext = ZextWrapper(reg.width, 32)
            self.wire(reg.ports.O, zext.ports.I)
            zext_out = zext.ports.O
            self.wire(zext_out, self.ports.read_config_data)

        self.wire(self.ports.I, self.mux.ports.I)
        self.wire(self.registers.S.ports.O, self.mux.ports.S)
        self.wire(self.mux.ports.O, self.ports.O)

        for idx, reg in enumerate(self.registers.values()):
            reg.set_addr(idx)
            reg.set_addr_width(8)
            reg.set_data_width(32)
            self.wire(self.ports.config.config_addr, reg.ports.config_addr)
            self.wire(self.ports.config.config_data, reg.ports.config_data)
            # Connect config_en for each config reg
            self.wire(reg.ports.config_en, self.ports.config.write[0])
Example #16
0
    def __init__(self, num_inputs, width, sel_bits, default):
        super().__init__()

        self.num_inputs = num_inputs
        self.width = width
        self.sel_bits = sel_bits
        self.default = default

        if 2**self.sel_bits <= self.num_inputs:
            raise ValueError(f"(2 ^ sel_bits) must be > num_inputs "
                             f"(sel_bits={self.sel_bits}, "
                             f"num_inputs={self.num_inputs})")

        self.data_mux = MuxWrapper(self.num_inputs, self.width)
        self.default_mux = MuxWrapper(2, self.width)
        lt = mantle.DefineULT(self.sel_bits)
        and_gate = mantle.DefineAnd(2)
        self.lt = FromMagma(lt)
        self.and_gate = FromMagma(and_gate)

        T = magma.Bits(self.width)
        self.add_ports(
            I=magma.In(magma.Array(self.num_inputs, T)),
            S=magma.In(magma.Bits(self.sel_bits)),
            EN=magma.In(magma.Bits(1)),
            O=magma.Out(T),
        )

        # Wire data inputs to data mux.
        for i in range(self.num_inputs):
            self.wire(self.ports.I[i], self.data_mux.ports.I[i])

        # Wire select input to select input of data_mux. Note that we only wire
        # the first clog2(num_inputs) bits of the select input.
        self.wire(self.ports.S[:self.data_mux.sel_bits], self.data_mux.ports.S)

        # Wire default value to first input of default mux, and output of
        # data_mux to second input of default mux.
        default_mux_inputs = [
            Const(magma.bits(self.default, self.width)),
            self.data_mux.ports.O,
        ]
        for i, mux_in in enumerate(default_mux_inputs):
            self.wire(mux_in, self.default_mux.ports.I[i])

        # Generate select logic for default mux:
        #   sel = (S < num_inputs) & EN
        self.wire(self.ports.S, self.lt.ports.I0)
        self.wire(Const(magma.bits(self.num_inputs, self.sel_bits)),
                  self.lt.ports.I1)
        self.wire(self.lt.ports.O, self.and_gate.ports.I0)
        self.wire(self.ports.EN[0], self.and_gate.ports.I1)
        self.wire(self.and_gate.ports.O, self.default_mux.ports.S[0])
        self.wire(self.default_mux.ports.O, self.ports.O)
def test_binary_primitive(binary_primitive, width):

    primitive_name, primitive_op, signed = binary_primitive
    prim = m.DeclareCircuit(f"primitive_name",
                            "in0",
                            m.In(m.Array(width, m.Bit)),
                            "in1",
                            m.In(m.Array(width, m.Bit)),
                            "out",
                            m.Out(m.Array(width, m.Bit)),
                            coreir_lib="coreir",
                            coreir_name=primitive_name,
                            coreir_genargs={"width": width})
    circ = m.DefineCircuit(f"DesignTop", "I0", m.In(m.Array(width, m.Bit)),
                           "I1", m.In(m.Array(width, m.Bit)), "O",
                           m.Out(m.Array(width, m.Bit)))
    inst = prim()
    m.wire(circ.I0, inst.in0)
    m.wire(circ.I1, inst.in1)
    m.wire(circ.O, inst.out)
    m.EndDefine()
    m.compile(f"build/{primitive_name}", circ, output="coreir")

    dir_path = os.path.dirname(os.path.realpath(__file__))
    result = delegator.run(
        f"CGRAMapper/bin/cgra-mapper build/{primitive_name}.json build/{primitive_name}_mapped.json",
        cwd=dir_path)
    assert not result.return_code, result.out + "\n" + result.err

    result = delegator.run(f"./CGRAGenerator/bin/generate.csh")
    assert not result.return_code, result.out + "\n" + result.err
    result = delegator.run(
        f"CGRAGenerator/bitstream/bsbuilder/serpent.csh build/{primitive_name}_mapped.json -cgra_info CGRAGenerator/hardware/generator_z/top/cgra_info.txt -o build/{primitive_name}_mapped_annotated"
    )
    assert not result.return_code, result.out + "\n" + result.err
Example #18
0
    def __init__(self, tiles):
        super().__init__()

        self.tiles = tiles
        self.height = len(tiles)

        self.add_ports(
            north=SideType(5, (1, 16)),
            south=SideType(5, (1, 16)),
            west=magma.Array(self.height, SideType(5, (1, 16))),
            east=magma.Array(self.height, SideType(5, (1, 16))),
            config=magma.In(ConfigurationType(32, 32)),
            clk=magma.In(magma.Clock),
            reset=magma.In(magma.AsyncReset),
            read_config_data=magma.Out(magma.Bits(32)),
            column_num=magma.In(magma.Bits(8)),
            # TODO (alexcarsello): make number of stall domains a param
            stall=magma.In(magma.Bits(4)))

        self.wire(self.ports.north, self.tiles[0].ports.north)
        self.wire(self.ports.south, self.tiles[-1].ports.south)
        for i, tile in enumerate(self.tiles):
            self.wire(self.ports.west[i], tile.ports.west)
            self.wire(self.ports.east[i], tile.ports.east)
            # Wire upper 8 bits of tile ID to row number
            self.wire(tile.ports.tile_id[8:16], Const(magma.bits(i, 8)))
            # Wire lower 8 bits of tile ID to col number
            self.wire(tile.ports.tile_id[0:8], self.ports.column_num)
        for i in range(1, self.height):
            t0 = self.tiles[i - 1]
            t1 = self.tiles[i]
            self.wire(t1.ports.north.O, t0.ports.south.I)
            self.wire(t0.ports.south.O, t1.ports.north.I)

        # Call abstract functions
        # distribute global inputs to all tiles in column
        self.wire_global_signals()
        # OR-combine each tile's read_data to form column read_data
        self.combine_read_data_outputs()
Example #19
0
def DefineTester(cgra_file, collateral_file, wrapped_name):

    cgra_def = m.DeclareFromVerilogFile(cgra_file)[0]

    with open(collateral_file, 'r') as f:
        io_d = json.load(f)

    ios = _flatten(
        chain(_CGRA_SIGNAL_PORTS,
              ((mod, m.Array(int(c['width']), _s2b(c['mode'])))
               for mod, c in io_d.items())))

    class Tester(m.Circuit):
        name = wrapped_name
        IO = ios

        @classmethod
        def definition(io):
            cgra = cgra_def()

            for port in io.interface:
                if port in io_d:
                    #port is a pin
                    direct = io_d[port]['mode']
                    for bit, pad in io_d[port]['bits'].items():
                        try:
                            #pad + '_' + direct is the 'de-tristated' name
                            m.wire(cgra.interface[pad + '_' + direct],
                                   io.interface[port][int(bit)])
                        except KeyError as e:
                            Print(
                                'Looks like their is some sort of inconsistency between the cgra_info (or at least the collateral) and top.v'
                            )
                            raise e
                else:
                    #port is a control signal
                    try:
                        m.wire(cgra.interface[port], io.interface[port])
                    except KeyError as e:
                        Print(
                            'Looks like _CGRA_SIGNAL_PORTS is no longer correct'
                        )
                        raise e

            for port in cgra.interface:
                if cgra.interface[port].value() is None and isinstance(
                        cgra.interface[port], m.BitIn):
                    m.wire(cgra.interface[port], m.GND)

    return Tester
Example #20
0
    def __init__(self, width, num_tracks):
        super().__init__()

        self.width = width
        self.num_tracks = num_tracks
        is_power_of_two = lambda x: x != 0 and ((x & (x - 1)) == 0)
        assert is_power_of_two(self.num_tracks)
        self.mux = MuxWrapper(self.num_tracks, self.width)

        T = magma.Bits(self.width)
        sel_bits = magma.bitutils.clog2(self.num_tracks)

        self.add_ports(
            I=magma.In(magma.Array(self.num_tracks, T)),
            O=magma.Out(T),
        )
        self.add_configs(sel=sel_bits, )

        self.wire(self.I, self.mux.I)
        self.wire(self.sel, self.mux.S)
        self.wire(self.mux.O, self.O)
Example #21
0
    def __init__(self, height, width):
        super().__init__()

        self.height = height
        self.width = width
        MuxCls = mantle.DefineMux(self.height, self.width)
        self.mux = FromMagma(MuxCls)

        T = magma.Bits(width)
        sel_bits = magma.bitutils.clog2(self.height)

        self.add_ports(
            I=magma.In(magma.Array(self.height, T)),
            S=magma.In(magma.Bits(sel_bits)),
            O=magma.Out(T),
        )

        for i in range(self.height):
            self.wire(self.I[i], getattr(self.mux, f"I{i}"))
        self.wire(self.S, self.mux.S)
        self.wire(self.mux.O, self.O)
Example #22
0
    def __init__(self, width, num_tracks):
        super().__init__()

        self.width = width
        self.num_tracks = num_tracks
        is_power_of_two = lambda x: x != 0 and ((x & (x - 1)) == 0)
        assert is_power_of_two(self.num_tracks)
        self.mux = FromMagma(mantle.DefineMux(self.num_tracks, self.width))
        T = magma.Bits(self.width)
        sel_bits = math.ceil(math.log(self.num_tracks, 2))

        self.add_ports(
            I=magma.In(magma.Array(self.num_tracks, T)),
            O=magma.Out(T),
        )
        self.add_configs(sel=sel_bits, )

        for i in range(self.num_tracks):
            self.wire(self.I[i], getattr(self.mux, f"I{i}"))
        self.wire(self.sel, self.mux.S)
        self.wire(self.mux.O, self.O)
Example #23
0
import magma as m
from magma.bitutils import int2seq
import mantle
from rom import ROM8, ROM16
from loam.boards.icestick import IceStick
from uart import UART

a = 2
b = 2

width = 16
TIN = m.Array(width, m.BitIn)
TOUT = m.Array(width, m.Out(m.Bit))

icestick = IceStick()
icestick.Clock.on()
for i in range(3):
    icestick.J3[i].output().on()

main = icestick.main()

# baud for uart output
clock = mantle.CounterModM(103, 8)
baud = clock.COUT

bit_counter = mantle.Counter(5, has_ce=True)
m.wire(baud, bit_counter.CE)

load = mantle.Decode(0, 5)(bit_counter.O)

# # "test" data
Example #24
0
    def definition(io):
        load = io.LOAD
        baud = rising(io.SCK) | falling(io.SCK)

        valid_counter = mantle.CounterModM(buf_size, 12, has_ce=True)
        m.wire(load & baud, valid_counter.CE)

        valid_list = [wi * (b - 1) + i * a - 1 for i in range(1, wo + 1)]  # len = 32

        valid = m.GND

        for i in valid_list:
            valid = valid | mantle.Decode(i, 12)(valid_counter.O)

        # register on input
        st_in = mantle.Register(width, has_ce=True)
        st_in(io.DATA)
        m.wire(load, st_in.CE)

        # --------------------------DOWNSCALING----------------------------- #
        # downscale the image from 352x288 to 32x32
        Downscale = m.DeclareCircuit(
                    'Downscale',
                    "I_0_0", m.In(m.Array(1, m.Array(1, m.Array(width, m.Bit)))),
                    "WE", m.In(m.Bit), "CLK", m.In(m.Clock),
                    "O", m.Out(m.Array(width, m.Bit)), "V", m.Out(m.Bit))

        dscale = Downscale()

        m.wire(st_in.O, dscale.I_0_0[0][0])
        m.wire(1, dscale.WE)
        m.wire(load, dscale.CLK)

        add16 = mantle.Add(width)  # needed for Add16 definition

        # --------------------------FILL IMG RAM--------------------------- #
        # each valid output of dscale represents an entry of 32x32 binary image
        # accumulate each group of 32 entries into a 32-bit value representing a row
        col = mantle.CounterModM(32, 6, has_ce=True) 
        col_ce = rising(valid) 
        m.wire(col_ce, col.CE)

        # shift each bit in one at a time until we get an entire row
        px_bit = mantle.ULE(16)(dscale.O, m.uint(THRESH, 16)) & valid
        row_reg = mantle.SIPO(32, has_ce=True)
        row_reg(px_bit)
        m.wire(col_ce, row_reg.CE)

        # reverse the row bits since the image is flipped
        row = reverse(row_reg.O)

        rowaddr = mantle.Counter(6, has_ce=True)

        img_full = mantle.SRFF(has_ce=True)
        img_full(mantle.EQ(6)(rowaddr.O, m.bits(32, 6)), 0)
        m.wire(falling(col.COUT), img_full.CE)
        row_ce = rising(col.COUT) & ~img_full.O
        m.wire(row_ce, rowaddr.CE)

        waddr = rowaddr.O[:5]

        rdy = col.COUT & ~img_full.O
        pulse_count = mantle.Counter(2, has_ce=True)
        we = mantle.UGE(2)(pulse_count.O, m.uint(1, 2))
        pulse_count(CE=(we|rdy))

        # ---------------------------UART OUTPUT----------------------------- #

        row_load = row_ce
        row_baud = mantle.FF()(baud)
        uart_row = UART(32)
        uart_row(CLK=io.CLK, BAUD=row_baud, DATA=row, LOAD=row_load)

        uart_addr = UART(5)
        uart_addr(CLK=io.CLK, BAUD=row_baud, DATA=waddr, LOAD=row_load)

        m.wire(waddr, io.WADDR)
        m.wire(img_full, io.DONE) #img_full
        m.wire(uart_row, io.UART) #uart_st
        m.wire(row, io.O)
        m.wire(we, io.VALID)

        m.wire(valid, io.T0)
        m.wire(uart_addr, io.T1)
Example #25
0
for i in valid_list:
    valid = valid | mantle.Decode(i, 13)(valid_counter.O)

m.wire(load & baud, printf.CE)

px_val = rom.O

# register on input
st_in = mantle.Register(16, has_ce=True)
st_in(px_val)
m.wire(load, st_in.CE)

# ---------------------------STENCILING----------------------------- #

Downscale = m.DeclareCircuit('Downscale', "I_0_0",
                             m.In(m.Array(1, m.Array(1, m.Array(16, m.Bit)))),
                             "WE", m.In(m.Bit), "CLK", m.In(m.Clock), "O",
                             m.Out(m.Array(16, m.Bit)), "V", m.Out(m.Bit))

dscale = Downscale()

m.wire(st_in.O, dscale.I_0_0[0][0])
m.wire(1, dscale.WE)
m.wire(load, dscale.CLK)

add16 = mantle.Add(16)  # needed for Add16 definition

# ---------------------------UART OUTPUT----------------------------- #

uart_px = UART(16)
uart_px(CLK=main.CLKIN, BAUD=baud, DATA=px_val, LOAD=load)
Example #26
0
    def definition(io):
        load = io.LOAD
        baud = io.BAUD

        valid_counter = mantle.CounterModM(buf_size, 13, has_ce=True)
        m.wire(load & baud, valid_counter.CE)

        valid_list = [wi * (b - 1) + i * a - 1 for i in range(1, wo + 1)]
        valid = m.GND

        for i in valid_list:
            valid = valid | mantle.Decode(i, 13)(valid_counter.O)

        # register on input
        st_in = mantle.Register(16, has_ce=True)
        st_in(io.DATA)
        m.wire(load, st_in.CE)

        # --------------------------DOWNSCALING----------------------------- #
        # downscale the image from 320x240 to 16x16
        Downscale = m.DeclareCircuit(
                    'Downscale',
                    "I_0_0", m.In(m.Array(1, m.Array(1, m.Array(16, m.Bit)))),
                    "WE", m.In(m.Bit), "CLK", m.In(m.Clock),
                    "O", m.Out(m.Array(16, m.Bit)), "V", m.Out(m.Bit))

        dscale = Downscale()

        m.wire(st_in.O, dscale.I_0_0[0][0])
        m.wire(1, dscale.WE)
        m.wire(load, dscale.CLK)

        add16 = mantle.Add(16)  # needed for Add16 definition

        # --------------------------FILL IMG RAM--------------------------- #
        # each valid output of dscale represents an entry of 16x16 binary image
        # accumulate each group of 16 entries into a 16-bit value representing
        # a row of the image
        col = mantle.Counter(4, has_ce=True)

        row_full = mantle.SRFF(has_ce=True)
        row_full(mantle.EQ(4)(col.O, m.bits(15, 4)), 0)
        m.wire(falling(dscale.V), row_full.CE)
        col_ce = rising(dscale.V) & ~row_full.O
        m.wire(col_ce, col.CE)

        row = mantle.Counter(4, has_ce=True)

        img_full = mantle.SRFF(has_ce=True)
        img_full(mantle.EQ(4)(row.O, m.bits(15, 4)), 0)
        m.wire(falling(col.COUT), img_full.CE)
        row_ce = rising(col.COUT) & ~img_full.O
        m.wire(row_ce, row.CE)

        # ---------------------------UART OUTPUT----------------------------- #

        uart_st = UART(16)
        uart_st(CLK=io.CLK, BAUD=baud, DATA=dscale.O, LOAD=load)

        m.wire(row.O, io.ROW)
        m.wire(img_full.O, io.DONE)
        m.wire(uart_st.O, io.UART)
Example #27
0
for i in valid_list:
    valid = valid | mantle.Decode(i, 3)(valid_counter.O)

m.wire(load & baud, printf.CE)

px_val = rom.O

st_in = mantle.Register(16, has_ce=True)
st_in(px_val)
m.wire(load, st_in.CE)

# ---------------------------STENCILING----------------------------- #

STEN = m.DeclareCircuit('STEN', "I_0_0",
                        m.In(m.Array(1, m.Array(1, m.Array(16, m.Bit)))), "O",
                        m.Out(m.Array(16, m.Bit)), "WE", m.In(m.Bit), "V",
                        m.Out(m.Bit), "CLK", m.In(m.Clock), "CLKOut",
                        m.Out(m.Clock), "L00", m.Out(m.Array(16, m.Bit)),
                        "L01", m.Out(m.Array(16, m.Bit)), "L10",
                        m.Out(m.Array(16, m.Bit)), "L11",
                        m.Out(m.Array(16, m.Bit)))

stencil = STEN()

m.wire(st_in.O, stencil.I_0_0[0][0])
m.wire(1, stencil.WE)
m.wire(load, stencil.CLK)

add16 = mantle.CounterModM(1, 16)  # needed for Add16 definition
Example #28
0
# downscale factor (a x b)
a = 11
b = 9
samples = 16

# image dimensions (height and width)
im_w = 320
im_h = 240

c = coreir.Context()
cirb = CoreIRBackend(c)

# 8-bit values but extend to 16-bit to avoid carryover in addition
width = 16
TIN = m.Array(width, m.BitIn)
TOUT = m.Array(width, m.Out(m.Bit))

# Line Buffer interface
inType = m.Array(1, m.Array(1, TIN))  # one pixel in per clock
outType = m.Array(b, m.Array(a, TOUT))  # downscale window
imgType = m.Array(im_h, m.Array(im_w, TIN))  # image dimensions

# Reduce interface
inType2 = m.In(m.Array(a * b, TIN))
outType2 = TOUT

# Top level module: line buffer input, reduce output
args = ['I', inType, 'O', outType2, 'WE', m.BitIn, 'V', m.Out(m.Bit)] + \
        m.ClockInterface(False, False)
dscale = m.DefineCircuit('Downscale', *args)
    class Scoreboard(m.Circuit):
        NUM_REQS = 4
        name = "Scoreboard"
        assert not ARBITER or NUM_REQS is not None, "If using arbiter, need to supply NUM_REQS"
        assert not ARBITER or QWID is not None, "If using arbiter, need to supply QWID"

        if ARBITER:
            IO = [
                "push",
                m.In(m.Bits(NUM_REQS)),
                "start",
                m.In(m.Bit),
                "rst",
                m.In(m.Reset),  # include blk sometime in the future
                "data_in",
                m.In(m.Array(N=NUM_REQS, T=m.Bits(DATAWID))),
                "input_quantums",
                m.In(m.Array(N=NUM_REQS, T=m.UInt(QWID))),
                "data_out_vld",
                m.Out(m.Bit)
            ] + m.ClockInterface()
        else:
            IO = [
                "push",
                m.In(m.Bit), "pop",
                m.In(m.Bit), "start",
                m.In(m.Bit), "rst",
                m.In(m.Reset), "data_in",
                m.In(m.Bits(DATAWID)), "data_out_vld",
                m.Out(m.Bit)
            ] + m.ClockInterface()

        if NUM_REQS is None:
            NUM_REQS = 1

        @classmethod
        def definition(io):
            en = DefineRegister(1,
                                init=0,
                                has_ce=False,
                                has_reset=True,
                                _type=m.Bits)(name="en")
            # wire clock
            m.wireclock(en, io)

            # wire reset
            m.wire(io.rst, en.RESET)

            # enable only goes high once, then stays high
            m.wire(en.O | m.bits(io.start), en.I)

            mpt = DefineMagicPacketTracker(DEPTH)()

            # wire up magic packet tracker
            m.wire(en.O, m.bits(mpt.captured))
            m.wire(io.rst, mpt.rst)
            m.wireclock(io, mpt)

            if not ARBITER:
                m.wire(io.push, mpt.push)
                m.wire(io.pop, mpt.pop)

                fifo = DefineFIFO(DATAWID, DEPTH)()
                # wire up fifo
                m.wire(io.push, fifo.push)
                m.wire(io.pop, fifo.pop)
                m.wire(io.rst, fifo.rst)
                m.wire(io.data_in, fifo.data_in)
                m.wireclock(io, fifo)
            else:
                m.wire(io.push[0], mpt.push)
                fifos = list()
                for i in range(NUM_REQS):
                    f = DefineFIFO(DATAWID, DEPTH)(name="fifo_{}".format(i))
                    fifos.append(f)
                    m.wire(io.push[i], f.push)
                    m.wire(io.rst, f.rst)
                    m.wire(io.data_in[i], f.data_in)
                    m.wireclock(io, f)

            # Need to wire things up
            if ARBITER:
                arb = DefineDWRR(NUM_REQS, QWID, DATAWID)(name="arb")
                m.wire(io.rst, arb.rst)
                m.wire(io.input_quantums, arb.quantums)
                for i in range(NUM_REQS):
                    m.wire(~fifos[i].empty, arb.reqs[i])
                    m.wire(arb.gnt[i], fifos[i].pop)
                m.wire(arb.gnt[0], mpt.pop)

            # vld out
            # TODO handle missing magic packet -- need to reset everything. Or keep as an assumption/restriction

            m.wire(
                m.bit(en.O)
                & eq(m.uint(mpt.next_cnt), m.uint(0, (DEPTH - 1).bit_length()))
                & eq(m.uint(mpt.cnt), m.uint(1, (DEPTH - 1).bit_length())),
                io.data_out_vld)
Example #30
0
from coreir.context import *
from magma.simulator.coreir_simulator import CoreIRSimulator
import coreir
from magma.scope import Scope
from mantle.coreir import DefineCoreirConst
from mantle import CounterModM, Decode, SIPO
from magma.frontend.coreir_ import GetCoreIRModule
from mantle.coreir.arith import *
from mantle.primitives import DeclareAdd


c = coreir.Context()
cirb = CoreIRBackend(c)
scope = Scope()

TIN = m.Array(16, m.BitIn)
TOUT = m.Array(16, m.Out(Bit))

# Line Buffer interface
inType = m.Array(1, m.Array(1, TIN))
outType = m.Array(2, m.Array(2, TOUT))
imgType = m.Array(4, m.Array(4, TIN))

# Reduce interface
inType2 = m.In(m.Array(4, TIN))
outType2 = m.Out(m.Array(16, Bit))

# Test circuit has line buffer's input and reduce's output
args = ['I', inType, 'O', outType2, 'WE', BitIn, 'V', m.Out(m.Bit),
        'L00', TOUT, 'L01', TOUT, 'L10', TOUT, 'L11', TOUT] + \
        m.ClockInterface(False, False)