示例#1
0
 def top_to_tile(top, tile, tile_idx):
     tile.add_ports(tile_id=magma.In(magma.Bits(16)))
     top.wire(Const(magma.bits(tile_idx, 16)), tile.tile_id)
     tile_eq = FromMagma(mantle.DefineEQ(16))
     tile.wire(tile.tile_id, tile_eq.I0)
     tile.wire(tile.config.config_addr[0:16], tile_eq.I1)
     return tile_eq
示例#2
0
 def tile_to_feature(tile, tile_eq, feature, feature_idx):
     feature.add_ports(config_en=magma.In(magma.Bit))
     feature_eq = FromMagma(mantle.DefineEQ(8))
     tile.wire(tile.config.config_addr[16:24], feature_eq.I0)
     tile.wire(Const(magma.bits(feature_idx, 8)), feature_eq.I1)
     feature_en = FromMagma(mantle.DefineAnd())
     tile.wire(feature_eq.O, feature_en.I0)
     tile.wire(tile_eq.O, feature_en.I1)
     tile.wire(feature_en.O, feature.config_en)
示例#3
0
 def tile_to_feature(tile, tile_eq, feature, feature_idx):
     feature.add_ports(
         config=magma.In(ConfigurationType(8, 32)),
         config_en=magma.In(magma.Bit),
     )
     tile.wire(tile.config.config_addr[24:], feature.config.config_addr)
     tile.wire(tile.config.config_data, feature.config.config_data)
     feature_eq = FromMagma(mantle.DefineEQ(8))
     tile.wire(tile.config.config_addr[16:24], feature_eq.I0)
     tile.wire(Const(magma.bits(feature_idx, 8)), feature_eq.I1)
     feature_en = FromMagma(mantle.DefineAnd())
     tile.wire(feature_eq.O, feature_en.I0)
     tile.wire(tile_eq.O, feature_en.I1)
     tile.wire(feature_en.O, feature.config_en)
示例#4
0
 def __wire_config_ce(self):
     if len(self.regs) == 0:
         return
     # fanout the stall signals to registers
     # invert the stall signal to clk_en
     invert = FromMagma(mantle.DefineInvert(1))
     # FIXME: use the low bits of stall signal to stall
     self.wire(invert.ports.I[0], self.ports.stall[0])
     for (reg_node, reg) in self.regs.values():
         rmux: RegisterMuxNode = list(reg_node)[0]
         # get rmux address
         config_name = get_mux_sel_name(rmux)
         config_reg = self.registers[config_name]
         index_val = rmux.get_conn_in().index(reg_node)
         eq_gate = FromMagma(mantle.DefineEQ(config_reg.width))
         self.wire(eq_gate.ports.I0, Const(index_val))
         self.wire(eq_gate.ports.I1, config_reg.ports.O)
         and_gate = FromMagma(mantle.DefineAnd(2, 1))
         self.wire(and_gate.ports.I0[0], eq_gate.ports.O)
         self.wire(and_gate.ports.I1, invert.ports.O)
         self.wire(reg.ports.CE,
                   self.convert(and_gate.ports.O[0], magma.enable))
示例#5
0
    def finalize(self):
        if self.finalized:
            raise Exception("Circuit already finalized")
        self.finalized = True
        # add stall and reset signal
        self.__add_stall()
        self.__add_reset()

        # see if we really need to add config or not
        if not self.__should_add_config():
            return

        self.add_ports(config=magma.In(
            ConfigurationType(self.full_config_addr_width,
                              self.config_data_width)),
                       clk=magma.In(magma.Clock),
                       read_config_data=magma.Out(
                           magma.Bits[self.config_data_width]))
        # double buffer ports
        if self.double_buffer:
            self.add_ports(config_db=magma.In(magma.Bit),
                           use_db=magma.In(magma.Bit))

        features = self.features()
        num_features = len(features)
        self.read_data_mux = MuxWithDefaultWrapper(num_features,
                                                   self.config_data_width,
                                                   self.config_addr_width, 0)
        self.read_data_mux.instance_name = "read_data_mux"
        # most of the logic copied from tile_magma.py
        # remove all hardcoded values
        for feature in self.features():
            if "config" not in feature.ports:
                continue
            self.wire(self.ports.config.config_addr[self.feature_config_slice],
                      feature.ports.config.config_addr)
            self.wire(self.ports.config.config_data,
                      feature.ports.config.config_data)
            self.wire(self.ports.config.read, feature.ports.config.read)

            if self.double_buffer and "config_db" in feature.ports:
                self.wire(self.ports.config_db, feature.ports.config_db)
                self.wire(self.ports.use_db, feature.ports.use_db)

        # Connect S input to config_addr.feature.
        self.wire(self.ports.config.config_addr[self.feature_addr_slice],
                  self.read_data_mux.ports.S)
        self.wire(self.read_data_mux.ports.O, self.ports.read_config_data)

        # Logic to generate EN input for read_data_mux
        read_and_tile = FromMagma(mantle.DefineAnd(2))
        eq_tile = FromMagma(mantle.DefineEQ(self.tile_id_width))
        # config_addr.tile_id == self.tile_id?
        self.wire(self.ports.tile_id, eq_tile.ports.I0)
        self.wire(self.ports.config.config_addr[self.tile_id_slice],
                  eq_tile.ports.I1)
        # (config_addr.tile_id == self.tile_id) & READ
        self.wire(read_and_tile.ports.I0, eq_tile.ports.O)
        self.wire(read_and_tile.ports.I1, self.ports.config.read[0])
        # read_data_mux.EN = (config_addr.tile_id == self.tile_id) & READ
        self.wire(read_and_tile.ports.O, self.read_data_mux.ports.EN[0])

        # Logic for writing to config registers
        # Config_en_tile = (config_addr.tile_id == self.tile_id & WRITE)
        write_and_tile = FromMagma(mantle.DefineAnd(2))
        self.wire(write_and_tile.ports.I0, eq_tile.ports.O)
        self.wire(write_and_tile.ports.I1, self.ports.config.write[0])
        decode_feat = []
        feat_and_config_en_tile = []
        for i, feat in enumerate(self.features()):
            # wire each feature's read_data output to
            # read_data_mux inputs
            if "read_config_data" in feat.ports:
                self.wire(feat.ports.read_config_data,
                          self.read_data_mux.ports.I[i])
            else:
                # wire constant
                self.wire(Const(0), self.read_data_mux.ports.I[i])
            # for each feature,
            # config_en = (config_addr.feature == feature_num) & config_en_tile
            decode_feat.append(
                FromMagma(mantle.DefineDecode(i, self.config_addr_width)))
            decode_feat[-1].instance_name = f"DECODE_FEATURE_{i}"
            feat_and_config_en_tile.append(FromMagma(mantle.DefineAnd(2)))
            feat_and_config_en_tile[-1].instance_name = f"FEATURE_AND_{i}"
            self.wire(decode_feat[i].ports.I,
                      self.ports.config.config_addr[self.feature_addr_slice])
            self.wire(decode_feat[i].ports.O,
                      feat_and_config_en_tile[i].ports.I0)
            self.wire(write_and_tile.ports.O,
                      feat_and_config_en_tile[i].ports.I1)
            if "config" in feat.ports:
                self.wire(feat_and_config_en_tile[i].ports.O,
                          feat.ports.config.write[0])
            if "config_en" in feat.ports:
                self.wire(decode_feat[i].ports.O, feat.ports["config_en"])
示例#6
0
    def __add_config(self):
        self.add_ports(config=magma.In(
            ConfigurationType(self.config_data_width, self.config_data_width)),
                       tile_id=magma.In(magma.Bits(self.tile_id_width)),
                       clk=magma.In(magma.Clock),
                       reset=magma.In(magma.AsyncReset),
                       read_config_data=magma.Out(
                           magma.Bits(self.config_data_width)))

        features = self.features()
        num_features = len(features)
        self.read_data_mux = MuxWithDefaultWrapper(num_features,
                                                   self.config_data_width,
                                                   self.config_addr_width, 0)
        # most of the logic copied from tile_magma.py
        # remove all hardcoded values
        for feature in self.features():
            self.wire(self.ports.config.config_addr[self.feature_config_slice],
                      feature.ports.config.config_addr)
            self.wire(self.ports.config.config_data,
                      feature.ports.config.config_data)
            self.wire(self.ports.config.read, feature.ports.config.read)

        # Connect S input to config_addr.feature.
        self.wire(self.ports.config.config_addr[self.feature_addr_slice],
                  self.read_data_mux.ports.S)
        self.wire(self.read_data_mux.ports.O, self.ports.read_config_data)

        # Logic to generate EN input for read_data_mux
        self.read_and_tile = FromMagma(mantle.DefineAnd(2))
        self.eq_tile = FromMagma(mantle.DefineEQ(self.tile_id_width))
        # config_addr.tile_id == self.tile_id?
        self.wire(self.ports.tile_id, self.eq_tile.ports.I0)
        self.wire(self.ports.config.config_addr[self.tile_id_slice],
                  self.eq_tile.ports.I1)
        # (config_addr.tile_id == self.tile_id) & READ
        self.wire(self.read_and_tile.ports.I0, self.eq_tile.ports.O)
        self.wire(self.read_and_tile.ports.I1, self.ports.config.read[0])
        # read_data_mux.EN = (config_addr.tile_id == self.tile_id) & READ
        self.wire(self.read_and_tile.ports.O, self.read_data_mux.ports.EN[0])

        # Logic for writing to config registers
        # Config_en_tile = (config_addr.tile_id == self.tile_id & WRITE)
        self.write_and_tile = FromMagma(mantle.DefineAnd(2))
        self.wire(self.write_and_tile.ports.I0, self.eq_tile.ports.O)
        self.wire(self.write_and_tile.ports.I1, self.ports.config.write[0])
        self.decode_feat = []
        self.feat_and_config_en_tile = []
        for i, feat in enumerate(self.features()):
            # wire each feature's read_data output to
            # read_data_mux inputs
            self.wire(feat.ports.read_config_data,
                      self.read_data_mux.ports.I[i])
            # for each feature,
            # config_en = (config_addr.feature == feature_num) & config_en_tile
            self.decode_feat.append(
                FromMagma(mantle.DefineDecode(i, self.config_addr_width)))
            self.feat_and_config_en_tile.append(FromMagma(mantle.DefineAnd(2)))
            self.wire(self.decode_feat[i].ports.I,
                      self.ports.config.config_addr[self.feature_addr_slice])
            self.wire(self.decode_feat[i].ports.O,
                      self.feat_and_config_en_tile[i].ports.I0)
            self.wire(self.write_and_tile.ports.O,
                      self.feat_and_config_en_tile[i].ports.I1)
            self.wire(self.feat_and_config_en_tile[i].ports.O,
                      feat.ports.config.write[0])
示例#7
0
    def __init__(self, core):
        super().__init__()

        self.core = core
        self.sb = SB(self.core.outputs())
        widths = [get_width(i.type()) for i in self.core.inputs()]
        self.cbs = [CB(10, w) for w in widths]

        self.add_ports(
            north=SideType(5, (1, 16)),
            west=SideType(5, (1, 16)),
            south=SideType(5, (1, 16)),
            east=SideType(5, (1, 16)),
            config=magma.In(ConfigurationType(32, 32)),
            tile_id=magma.In(magma.Bits(16)),
            clk=magma.In(magma.Clock),
            reset=magma.In(magma.AsyncReset),
            read_config_data=magma.Out(magma.Bits(32)),
            stall=magma.In(magma.Bits(4))
        )

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

        # this is hacky, but connect stall if the core has a stall input
        if "stall" in self.core.ports:
            self.wire(self.ports.stall, core.ports.stall)

        sides = (self.ports.north, self.ports.west)
        for i, cb in enumerate(self.cbs):
            side = sides[i % len(sides)]
            self.__wire_cb(side, cb)

        for i, input_ in enumerate(self.core.inputs()):
            self.wire(self.cbs[i].ports.O, input_)

        for i, out in enumerate(self.core.outputs()):
            self.wire(out, self.sb.ports[out._name])

        for feature in self.features():
            self.wire(self.ports.config.config_addr[24:32],
                      feature.ports.config.config_addr)
            self.wire(self.ports.config.config_data,
                      feature.ports.config.config_data)
            self.wire(self.ports.config.read, feature.ports.config.read)

        # read_data mux
        num_mux_inputs = len(self.features())
        self.read_data_mux = MuxWithDefaultWrapper(num_mux_inputs, 32, 8, 0)

        # Connect S input to config_addr.feature.
        self.wire(self.ports.config.config_addr[16:24],
                  self.read_data_mux.ports.S)
        self.wire(self.read_data_mux.ports.O, self.ports.read_config_data)

        # Logic to generate EN input for read_data_mux
        self.read_and_tile = FromMagma(mantle.DefineAnd(2))
        self.eq_tile = FromMagma(mantle.DefineEQ(16))
        # config_addr.tile_id == self.tile_id?
        self.wire(self.ports.tile_id, self.eq_tile.ports.I0)
        self.wire(self.ports.config.config_addr[0:16], self.eq_tile.ports.I1)
        # (config_addr.tile_id == self.tile_id) & READ
        self.wire(self.read_and_tile.ports.I0, self.eq_tile.ports.O)
        self.wire(self.read_and_tile.ports.I1, self.ports.config.read[0])
        # read_data_mux.EN = (config_addr.tile_id == self.tile_id) & READ
        self.wire(self.read_and_tile.ports.O, self.read_data_mux.ports.EN[0])

        # Logic for writing to config registers
        # Config_en_tile = (config_addr.tile_id == self.tile_id & WRITE)
        self.write_and_tile = FromMagma(mantle.DefineAnd(2))
        self.wire(self.write_and_tile.ports.I0, self.eq_tile.ports.O)
        self.wire(self.write_and_tile.ports.I1, self.ports.config.write[0])
        self.decode_feat = []
        self.feat_and_config_en_tile = []
        for i, feat in enumerate(self.features()):
            # wire each feature's read_data output to
            # read_data_mux inputs
            self.wire(feat.ports.read_config_data,
                      self.read_data_mux.ports.I[i])
            # for each feature,
            # config_en = (config_addr.feature == feature_num) & config_en_tile
            self.decode_feat.append(FromMagma(mantle.DefineDecode(i, 8)))
            self.feat_and_config_en_tile.append(FromMagma(mantle.DefineAnd(2)))
            self.wire(self.decode_feat[i].ports.I,
                      self.ports.config.config_addr[16:24])
            self.wire(self.decode_feat[i].ports.O,
                      self.feat_and_config_en_tile[i].ports.I0)
            self.wire(self.write_and_tile.ports.O,
                      self.feat_and_config_en_tile[i].ports.I1)
            self.wire(self.feat_and_config_en_tile[i].ports.O,
                      feat.ports.config.write[0])