Beispiel #1
0
 def definition(io):
     comparison = mantle.UGT(n_bc_adder)
     reg_count = mantle.Register(n_bc_adder, has_ce=True)
     reg_idx = mantle.Register(b, has_ce=True)
     wire(io.I, comparison.I0)
     wire(reg_count.O, comparison.I1)
     wire(comparison.O, reg_count.CE)
     wire(comparison.O, reg_idx.CE)
     wire(io.CLK, reg_count.CLK)
     wire(io.CLK, reg_idx.CLK)
     wire(io.I, reg_count.I)
     wire(io.IDX, reg_idx.I)
     wire(reg_idx.O, io.O)
Beispiel #2
0
	def __init__(self, ARES_design_type, depth):
		#这个self.name 和self.io必须得有
		#self.name = "ARES_FIFO_DESIGN"
		self.io = io = m.IO(ARES_design = ARES_design_type)
		#io += m.ClockIO()
		
		addr_width = m.bitutils.clog2(depth)
		print ("ARES addr width : " + str(addr_width) )
		buffer = mantle.RAM(2**addr_width, io.ARES_design.WData.flat_length())
		
		buffer.WDATA @= m.as_bits(io.ARES_design.WData)
		io.ARES_design.RData @= buffer.RDATA
		
		read_pointer = mantle.Register(addr_width + 1)
		write_pointer = mantle.Register(addr_width + 1)
		buffer.RADDR @= read_pointer.O[:addr_width]
		buffer.WADDR @= write_pointer.O[:addr_width]
		
		reset = io.ARES_design.RESET

		full = \
			(read_pointer.O[:addr_width] == write_pointer.O[:addr_width]) \
			& \
			(read_pointer.O[addr_width] != write_pointer.O[addr_width])
		
		empty = read_pointer.O == write_pointer.O
		write_valid = io.ARES_design.Write & ~full
		read_valid = io.ARES_design.Read & ~empty
	
		io.ARES_design.Full @= full
		
		buffer.WE @= write_valid

		write_p = mantle.mux([
			write_pointer.O, m.uint(write_pointer.O) + 1
		], write_valid)
		
		write_pointer.I @= mantle.mux([
			write_p, 0
		], reset)
	
		io.ARES_design.Empty @= empty
		
		read_p = mantle.mux([
			read_pointer.O, m.uint(read_pointer.O) + 1
		], read_valid)

		read_pointer.I @= mantle.mux([
			read_p, 0 
		], reset)
Beispiel #3
0
def create_io1out_pad():
    cb = m.DefineCircuit("io1out_pad", "clk", m.In(m.Clock), "rst",
                         m.In(m.Reset), "config_data", m.In(m.Bits(32)),
                         "config_addr", m.In(m.Bits(32)), "tile_id",
                         m.In(m.Bits(16)), "pin_0", m.In(m.Bit), "pin_1",
                         m.In(m.Bit), "pin_2", m.In(m.Bit), "pin_3",
                         m.In(m.Bit), "top_pin", m.Out(m.Bits(1)))

    # Configuration data
    config_reg = mantle.Register(32, init=0, has_ce=True, has_reset=True)
    addr_match = mantle.EQ(16)
    m.wire(addr_match.I0, cb.config_addr[0:16])
    m.wire(addr_match.I1, cb.tile_id)
    m.wire(addr_match.O, config_reg.CE)

    m.wire(cb.config_data, config_reg.I)
    m.wire(cb.clk, config_reg.CLK)

    rst_inv = mantle.Invert(1)
    m.wire(rst_inv.I[0], cb.rst)
    m.wire(rst_inv.O[0], config_reg.RESET)

    # Config mux
    config_mux = mantle.Mux(height=4, width=1)
    m.wire(config_mux.O, cb.top_pin)
    m.wire(config_mux.S, config_reg.O[0:2])

    m.wire(cb.pin_0, config_mux.I0[0])
    m.wire(cb.pin_1, config_mux.I1[0])
    m.wire(cb.pin_2, config_mux.I2[0])
    m.wire(cb.pin_3, config_mux.I3[0])

    m.EndDefine()

    return cb
Beispiel #4
0
        def definition(io):
            # Configuration data
            config_reg = mantle.Register(32,
                                         init=0,
                                         has_ce=True,
                                         has_reset=True)

            m.wire(io.config_data, config_reg.I)
            m.wire(io.clk, config_reg.CLK)
            m.wire(io.config_en, config_reg.CE)

            rst_inv = mantle.Invert(1)
            m.wire(rst_inv.I[0], io.rst)
            m.wire(rst_inv.O[0], config_reg.RESET)

            # Config mux
            config_mux = mantle.Mux(height=8, width=1)
            m.wire(config_mux.O, io.out)
            m.wire(config_mux.S, config_reg.O[0:3])

            m.wire(io.track_0_in, config_mux.I0)
            m.wire(io.track_1_in, config_mux.I1)
            m.wire(io.track_2_in, config_mux.I2)
            m.wire(io.track_3_in, config_mux.I3)

            m.wire(io.track_0_out, config_mux.I4)
            m.wire(io.track_1_out, config_mux.I5)
            m.wire(io.track_2_out, config_mux.I6)
            m.wire(io.track_3_out, config_mux.I7)
Beispiel #5
0
        def definition(io):

            config_reg_reset_bit_vector = \
                generate_reset_value(constant_bit_count, default_value,
                                     reset_val, mux_sel_bit_count)

            config_cb = mantle.Register(config_reg_width,
                                        init=config_reg_reset_bit_vector,
                                        has_ce=True,
                                        has_async_reset=True)

            config_addr_zero = m.bits(0, 8) == io.config_addr[24:32]

            config_cb(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, 32), config_cb.O], config_addr_zero))

            output_mux = generate_output_mux(num_tracks, feedthrough_outputs,
                                             has_constant, width,
                                             mux_sel_bit_count,
                                             constant_bit_count, io, config_cb)

            # NOTE: This is a dummy! fix it later!
            m.wire(output_mux.O, io.out)
            return
Beispiel #6
0
        def definition(io):
            PSEL = getattr(io.apb, f"PSEL{apb_slave_id}")
            registers = [
                mantle.Register(data_width,
                                init=reg.init,
                                has_ce=True,
                                has_reset=True,
                                name=reg.name) for reg in reg_list
            ]
            is_write = io.apb.PENABLE & io.apb.PWRITE & PSEL
            ready = None
            for i, reg in enumerate(registers):
                reg.I <= mantle.mux(
                    [getattr(io, reg.name + "_d"), io.apb.PWDATA], is_write)
                getattr(io, reg.name + "_q") <= reg.O
                reg.CLK <= io.apb.PCLK
                reg.RESET <= ~m.bit(io.apb.PRESETn)
                ce = is_write & (io.apb.PADDR == i)
                if reg_list[i].has_ce:
                    reg.CE <= ce | m.bit(getattr(io, reg.name + "_en"))
                else:
                    reg.CE <= ce
                if ready is not None:
                    ready |= ce
                else:
                    ready = ce
            is_read = io.apb.PENABLE & ~io.apb.PWRITE & PSEL
            io.apb.PREADY <= ready | is_read
            io.apb.PRDATA <= mantle.mux([reg.O
                                         for reg in registers], io.apb.PADDR)
            io.apb.PSLVERR <= 0

            # Unused
            CorebitTerm().I <= io.apb.PPROT
            Term(len(io.apb.PSTRB)).I <= io.apb.PSTRB
Beispiel #7
0
class TFF(m.Circuit):
    io = m.IO(O=m.Out(m.Bit), CLK=m.In(m.Clock))

    reg = mantle.Register(None, name="tff_reg")
    reg.CLK <= io.CLK
    reg.I <= ~reg.O
    io.O <= reg.O
Beispiel #8
0
	class FIFO(m.Circuit):
		io = m.IO(ARES_design = ARES_design_type)
		#io += m.ClockIO()
		
		addr_width = m.bitutils.clog2(depth)
		buffer = mantle.RAM(2**addr_width, io.ARES_design.WData.flat_length())
		
		buffer.WDATA @= m.as_bits(io.ARES_design.WData)
		io.ARES_design.RData @= buffer.RDATA
		
		read_pointer = mantle.Register(addr_width + 1)
		write_pointer = mantle.Register(addr_width + 1)
		buffer.RADDR @= read_pointer.O[:addr_width]
		buffer.WADDR @= write_pointer.O[:addr_width]
		
		reset = io.ARES_design.RESET

		full = \
			(read_pointer.O[:addr_width] == write_pointer.O[:addr_width]) \
			& \
			(read_pointer.O[addr_width] != write_pointer.O[addr_width])
		
		empty = read_pointer.O == write_pointer.O
		write_valid = io.ARES_design.Write & ~full
		read_valid = io.ARES_design.Read & ~empty
	
		io.ARES_design.Full @= full
		
		buffer.WE @= write_valid

		write_p = mantle.mux([
			write_pointer.O, m.uint(write_pointer.O) + 1
		], write_valid)
		
		write_pointer.I @= mantle.mux([
			write_p, 0
		], reset)
	
		io.ARES_design.Empty @= empty
		
		read_p = mantle.mux([
			read_pointer.O, m.uint(read_pointer.O) + 1
		], read_valid)

		read_pointer.I @= mantle.mux([
			read_p, 0 
		], reset)
Beispiel #9
0
 def definition(io):
     regs = [
         mantle.Register(data_width, init=int(init[i]))
         for i in range(1 << addr_width)
     ]
     for reg in regs:
         reg.I <= reg.O
     io.RDATA <= mantle.mux([reg.O for reg in regs], io.RADDR)
Beispiel #10
0
 def definition(io):
     reg = mantle.Register(self.width, has_ce=True)
     ce = (io.addr_in == magma.bits(self.addr, self.addr_width))
     if self.config_en:
         ce = ce & io.ce
     magma.wire(io.data_in[0:self.width], reg.I)
     magma.wire(ce, reg.CE)
     magma.wire(reg.O, io.O)
Beispiel #11
0
 def definition(io):
     reg0 = mantle.Register(1,
                            has_ce=has_ce,
                            has_async_reset=has_async_reset,
                            has_async_resetn=has_async_resetn)
     m.wire(reg0.CLK, io.clk)
     m.wire(reg0.I, io.In0)
     m.wire(reg0.O, io.Out0)
Beispiel #12
0
 def definition(io):
     reg = mantle.Register(n=width,
                           init=0,
                           has_ce=True,
                           has_reset=has_reset)
     CE = (io.addr == address) & m.bit(io.CE)
     m.wire(reg(io.I, CE=CE), io.O)
     if has_reset:
         m.wire(io.RESET, reg.RESET)
    def __init__(self, regs, data_width, apb_slave_id=0):
        #起名,用到regs的信息
        self.name = "RegFile_" + "_".join(reg.name for reg in regs)

        self.io = io = make_reg_file_interface(regs, data_width, apb_slave_id)

        for name, port in io.ports.items():
            print(f"port_name = \"{name}\"")
            print(f"port_type = ", end="")
            m.util.pretty_print_type(type(port))
            print()

        PSEL = getattr(io.apb, f"PSEL{apb_slave_id}")

        #这里又用了mantle.Register,这个东西能声明成design内部的reg,有五个signal,I,O,CLK,CE,RESET
        #所以有了后面的reg.I怎么怎么样
        registers = [
            mantle.Register(data_width,
                            init=reg.init,
                            has_ce=True,
                            has_reset=True,
                            name=reg.name) for reg in regs
        ]
        #is_write应该是一个内部的状态
        is_write = io.apb.PENABLE & io.apb.PWRITE & PSEL

        ready = None
        for i, reg in enumerate(registers):
            reg.I @= mantle.mux([getattr(io, reg.name + "_d"), io.apb.PWDATA],
                                is_write)

            getattr(io, reg.name + "_q") <= reg.O

            reg.CLK @= io.apb.PCLK
            reg.RESET @= ~m.bit(io.apb.PRESETn)

            ce = is_write & (io.apb.PADDR == i)
            if regs[i].has_ce:
                reg.CE @= ce | m.bit(getattr(io, reg.name + "_en"))
            else:
                reg.CE @= ce

            if ready is not None:
                ready |= ce
            else:
                ready = ce

        is_read = io.apb.PENABLE & ~io.apb.PWRITE & PSEL

        io.apb.PREADY @= ready | is_read

        io.apb.PRDATA @= mantle.mux([reg.O for reg in registers], io.apb.PADDR)

        io.apb.PSLVERR.undriven()
        io.apb.PPROT.unused()
        io.apb.PSTRB.unused()
Beispiel #14
0
 def definition(io):
     reg = mantle.Register(width, has_ce=True, has_async_reset=True)
     magma.wire(io.clk, reg.CLK)
     ce = (io.config_addr == magma.bits(addr, addr_width))
     magma.wire(io.reset, reg.ASYNCRESET)
     if use_config_en:
         ce = ce & io.config_en
     magma.wire(io.config_data[0:width], reg.I)
     magma.wire(ce, reg.CE)
     magma.wire(reg.O, io.O)
Beispiel #15
0
 def definition(io):
     regs = [
         mantle.Register(data_width,
                         init=int(init[i]),
                         has_ce=True,
                         has_reset=True) for i in range(1 << addr_width)
     ]
     for i, reg in enumerate(regs):
         reg.I <= io.WDATA
         reg.CE <= (io.WADDR == m.bits(i, addr_width)) & io.WE
     io.RDATA <= mantle.mux([reg.O for reg in regs], io.RADDR)
Beispiel #16
0
class ROM(m.Circuit):
    io = m.IO(
        RADDR=m.In(m.Bits[addr_width]),
        RDATA=m.Out(m.Bits[data_width]),
        CLK=m.In(m.Clock)
    )

    regs = [mantle.Register(data_width, init=int(init[i]))
            for i in range(1 << addr_width)]
    for reg in regs:
        reg.I <= reg.O
    io.RDATA <= mantle.mux([reg.O for reg in regs], io.RADDR)
Beispiel #17
0
        def definition(io):
            config = mantle.Register(opcode_width,
                                     has_ce=True,
                                     has_async_reset=True)

            config_addr_zero = m.bits(0, config_addr_width) == io.config_addr
            opcode = config(io.config_data,
                            CE=(m.bit(io.config_en) & config_addr_zero))
            # TODO: Automatically create instances and wires for configuration
            # logic. E.g. it could automatically create the register and wire
            # it up to read_data
            m.wire(opcode, io.read_data)
            m.wire(PECore()(opcode, io.I0, io.I1), io.O)
Beispiel #18
0
def create_connect_box():
    cb = m.DefineCircuit("connect_box",
                          "operand0", m.In(m.Bits(1)),
                          "operand1", m.In(m.Bits(1)),
                          "result", m.Out(m.Bits(1)),
                          "clk", m.In(m.Clock),
                          "rst", m.In(m.Reset),
                          "config_data", m.In(m.Bits(32)),
                          "config_en", m.In(m.Bit))

    # Configuration data
    config_reg = mantle.Register(32, init=0, has_ce=True, has_reset=True)

    m.wire(cb.config_data, config_reg.I)
    m.wire(cb.clk, config_reg.CLK)
    m.wire(cb.config_en, config_reg.CE)

    rst_inv = mantle.Invert(1)
    m.wire(rst_inv.I[0], cb.rst)
    m.wire(rst_inv.O[0], config_reg.RESET)

    # Operations in CB
    and_op = mantle.And(2, 1)
    m.wire(cb.operand0, and_op.I0)
    m.wire(cb.operand1, and_op.I1)

    or_op = mantle.Or(2, 1)
    m.wire(cb.operand0, or_op.I0)
    m.wire(cb.operand1, or_op.I1)

    xor_op = mantle.XOr(2, 1)
    m.wire(cb.operand0, xor_op.I0)
    m.wire(cb.operand1, xor_op.I1)

    not_op = mantle.Invert(1)
    m.wire(cb.operand0, not_op.I)
    
    # Config mux
    config_mux = mantle.Mux(height=4, width=1)
    m.wire(config_mux.O, cb.result)
    m.wire(config_mux.S, config_reg.O[0:2])
    
    m.wire(and_op.O, config_mux.I0)
    m.wire(or_op.O, config_mux.I1)
    m.wire(xor_op.O, config_mux.I2)
    m.wire(not_op.O, config_mux.I3)


    return cb
Beispiel #19
0
        def definition(io):
            addr_width = m.bitutils.clog2(depth)

            buffer = mantle.RAM(addr_width, flat_length(io.data_in.data))

            # pack data into bits
            buffer.WDATA <= flatten_fields_to_bits(io.data_in.data)

            # unpack bits into tuple
            io.data_out.data <= unflatten_bits_to_fields(
                io.data_out.data, buffer.RDATA)

            read_pointer = mantle.Register(addr_width + 1)
            write_pointer = mantle.Register(addr_width + 1)
            buffer.RADDR <= read_pointer.O[:addr_width]
            buffer.WADDR <= write_pointer.O[:addr_width]

            full = \
                (read_pointer.O[:addr_width] == write_pointer.O[:addr_width]) \
                & \
                (read_pointer.O[addr_width] != write_pointer.O[addr_width])

            empty = read_pointer == write_pointer
            write_valid = io.data_in.valid & ~full
            read_valid = io.data_out.ready & ~empty

            io.data_in.ready <= ~full

            buffer.WE <= write_valid
            write_pointer.I <= mantle.mux(
                [write_pointer.O, m.uint(write_pointer.O) + 1], write_valid)

            io.data_out.valid <= read_valid

            read_pointer.I <= mantle.mux(
                [read_pointer.O, m.uint(read_pointer.O) + 1], read_valid)
Beispiel #20
0
class RAM(m.Circuit):
    io = m.IO(
        RADDR=m.In(m.Bits[addr_width]),
        RDATA=m.Out(m.Bits[data_width]),
        WADDR=m.In(m.Bits[addr_width]),
        WDATA=m.In(m.Bits[data_width]),
        WE=m.In(m.Bit),
        CLK=m.In(m.Clock),
        RESET=m.In(m.Reset)
    )

    regs = [mantle.Register(data_width, init=int(init[i]), has_ce=True,
                            has_reset=True)
            for i in range(1 << addr_width)]
    for i, reg in enumerate(regs):
        reg.I <= io.WDATA
        reg.CE <= (io.WADDR == m.bits(i, addr_width)) & io.WE
    io.RDATA <= mantle.mux([reg.O for reg in regs], io.RADDR)
Beispiel #21
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)
Beispiel #22
0
        def definition(io):

            # Configuration data
            config_reg = mantle.Register(32,
                                         init=0,
                                         has_ce=True,
                                         has_reset=True)

            m.wire(io.config_data, config_reg.I)
            m.wire(io.clk, config_reg.CLK)
            m.wire(io.config_en, config_reg.CE)

            rst_inv = mantle.Invert(1)
            m.wire(rst_inv.I[0], io.rst)
            m.wire(rst_inv.O[0], config_reg.RESET)

            # Operations in CLB
            and_op = mantle.And(2, 1)
            m.wire(io.operand0, and_op.I0)
            m.wire(io.operand1, and_op.I1)

            or_op = mantle.Or(2, 1)
            m.wire(io.operand0, or_op.I0)
            m.wire(io.operand1, or_op.I1)

            xor_op = mantle.XOr(2, 1)
            m.wire(io.operand0, xor_op.I0)
            m.wire(io.operand1, xor_op.I1)

            not_op = mantle.Invert(1)
            m.wire(io.operand0, not_op.I)

            # Config mux
            config_mux = mantle.Mux(height=4, width=1)
            m.wire(config_mux.O, io.result)
            m.wire(config_mux.S, config_reg.O[0:2])

            m.wire(and_op.O, config_mux.I0)
            m.wire(or_op.O, config_mux.I1)
            m.wire(xor_op.O, config_mux.I2)
            m.wire(not_op.O, config_mux.I3)
        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)
Beispiel #24
0
        def definition(io):
            # Configuration data
            config_reg = mantle.Register(32,
                                         init=0,
                                         has_ce=True,
                                         has_reset=True)

            m.wire(io.config_data, config_reg.I)
            m.wire(io.clk, config_reg.CLK)
            m.wire(io.config_en, config_reg.CE)

            rst_inv = mantle.Invert(1)
            m.wire(rst_inv.I[0], io.rst)
            m.wire(rst_inv.O[0], config_reg.RESET)

            # switch muxes

            config_offset = 0
            for side in range(0, 4):
                for track in range(0, 4):
                    switch_mux = mantle.Mux(height=4, width=1)
                    m.wire(
                        switch_mux.O,
                        getattr(
                            io, 'side_' + str(side) + '_track_' + str(track) +
                            '_out'))
                    m.wire(switch_mux.S,
                           config_reg.O[config_offset:(config_offset + 2)])
                    config_offset += 2

                    for in_side in range(0, 4):
                        if in_side == side:
                            m.wire(getattr(switch_mux, "I" + str(in_side)),
                                   io.clb_result)
                        else:
                            m.wire(
                                getattr(switch_mux, "I" + str(in_side)),
                                getattr(
                                    io, 'side_' + str(in_side) + '_track_' +
                                    str(track) + '_in'))
Beispiel #25
0
 def definition(io):
     # IF - get cycle_id, label_index_id
     controller = Controller()
     reg_1_cycle = mantle.Register(n)
     reg_1_control = mantle.DFF(init=1)
     wire(io.CLK, controller.CLK)
     wire(io.CLK, reg_1_cycle.CLK)
     wire(io.CLK, reg_1_control.CLK)
     reg_1_idx = controller.IDX
     wire(controller.CYCLE, reg_1_cycle.I)
     wire(1, reg_1_control.I)
     # RR - get weight block, image block of N bits
     readROM = ReadROM()
     wire(reg_1_idx, readROM.IDX)
     wire(reg_1_cycle.O, readROM.CYCLE)
     reg_2 = mantle.Register(N + b + n)
     reg_2_control = mantle.DFF()
     reg_2_weight = readROM.WEIGHT
     wire(io.CLK, reg_2.CLK)
     wire(io.CLK, readROM.CLK)
     wire(io.CLK, reg_2_control.CLK)
     wire(readROM.IMAGE, reg_2.I[:N])
     wire(reg_1_idx, reg_2.I[N:N + b])
     wire(reg_1_cycle.O, reg_2.I[N + b:])
     wire(reg_1_control.O, reg_2_control.I)
     # EX - NXOr for multiplication, pop count and accumulate the result for activation
     multiplier = mantle.NXOr(height=2, width=N)
     bit_counter = DefineBitCounter(N)()
     adder = mantle.Add(n_bc_adder, cin=False, cout=False)
     mux_for_adder_0 = mantle.Mux(height=2, width=n_bc_adder)
     mux_for_adder_1 = mantle.Mux(height=2, width=n_bc_adder)
     reg_3_1 = mantle.Register(n_bc_adder)
     reg_3_2 = mantle.Register(b + n)
     wire(io.CLK, reg_3_1.CLK)
     wire(io.CLK, reg_3_2.CLK)
     wire(reg_2_weight, multiplier.I0)
     wire(reg_2.O[:N], multiplier.I1)
     wire(multiplier.O, bit_counter.I)
     wire(bits(0, n_bc_adder), mux_for_adder_0.I0)
     wire(bit_counter.O, mux_for_adder_0.I1[:n_bc])
     if n_bc_adder > n_bc:
         wire(bits(0, n_bc_adder - n_bc), mux_for_adder_0.I1[n_bc:])
     # only when data read is ready (i.e. control signal is high), accumulate the pop count result
     wire(reg_2_control.O, mux_for_adder_0.S)
     wire(reg_3_1.O, mux_for_adder_1.I0)
     wire(bits(0, n_bc_adder), mux_for_adder_1.I1)
     if n == 4:
         comparison_3 = SB_LUT4(LUT_INIT=int('0' * 15 + '1', 2))
         wire(
             reg_2.O[N + b:],
             bits([
                 comparison_3.I0, comparison_3.I1, comparison_3.I2,
                 comparison_3.I3
             ]))
     else:
         comparison_3 = mantle.EQ(n)
         wire(reg_2.O[N + b:], comparison_3.I0)
         wire(bits(0, n), comparison_3.I1)
     wire(comparison_3.O, mux_for_adder_1.S)
     wire(mux_for_adder_0.O, adder.I0)
     wire(mux_for_adder_1.O, adder.I1)
     wire(adder.O, reg_3_1.I)
     wire(reg_2.O[N:], reg_3_2.I)
     # CF - classify the image
     classifier = Classifier()
     reg_4 = mantle.Register(n + b)
     reg_4_idx = classifier.O
     wire(io.CLK, classifier.CLK)
     wire(io.CLK, reg_4.CLK)
     wire(reg_3_1.O, classifier.I)
     wire(reg_3_2.O[:b], classifier.IDX)
     wire(reg_3_2.O, reg_4.I)
     # WB - wait to show the result until the end
     reg_5 = mantle.Register(b, has_ce=True)
     comparison_5_1 = mantle.EQ(b)
     comparison_5_2 = mantle.EQ(n)
     and_gate = mantle.And()
     wire(io.CLK, reg_5.CLK)
     wire(reg_4_idx, reg_5.I)
     wire(reg_4.O[:b], comparison_5_1.I0)
     wire(bits(num_classes - 1, b), comparison_5_1.I1)
     wire(reg_4.O[b:], comparison_5_2.I0)
     wire(bits(num_cycles - 1, n), comparison_5_2.I1)
     wire(comparison_5_1.O, and_gate.I0)
     wire(comparison_5_2.O, and_gate.I1)
     wire(and_gate.O, reg_5.CE)
     wire(reg_5.O, io.O)
     # latch the light indicating the end
     reg_6 = mantle.DFF()
     wire(io.CLK, reg_6.CLK)
     or_gate = mantle.Or()
     wire(and_gate.O, or_gate.I0)
     wire(reg_6.O, or_gate.I1)
     wire(or_gate.O, reg_6.I)
     wire(reg_6.O, io.D)
Beispiel #26
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)
        def definition(io):
            reg = mantle.Register(32, has_ce=True)

            reg(io.config_data,
                CE=(io.config_addr == m.bits(1, 32)) & m.bit(io.config_en))
            m.wire(reg.O, io.O)
Beispiel #28
0
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)]  # len = 16

valid = m.GND

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)
Beispiel #29
0
 def definition(io):
     reg = mantle.Register(2, has_ce=True, name="conf_reg")
     io.Q <= reg(io.D, CE=io.CE)
Beispiel #30
0
def create_pe_tile():
    pe = m.DefineCircuit(
        "pe_tile", "clk", m.In(m.Clock), "rst", m.In(m.Reset), "config_data",
        m.In(m.Bits(32)), "config_addr", m.In(m.Bits(32)), "tile_id",
        m.In(m.Bits(16)), "side_0_track_0_in", m.In(m.Bits(1)),
        "side_0_track_1_in", m.In(m.Bits(1)), "side_0_track_2_in",
        m.In(m.Bits(1)), "side_0_track_3_in", m.In(m.Bits(1)),
        "side_1_track_0_in", m.In(m.Bits(1)), "side_1_track_1_in",
        m.In(m.Bits(1)), "side_1_track_2_in", m.In(m.Bits(1)),
        "side_1_track_3_in", m.In(m.Bits(1)), "side_2_track_0_in",
        m.In(m.Bits(1)), "side_2_track_1_in", m.In(m.Bits(1)),
        "side_2_track_2_in", m.In(m.Bits(1)), "side_2_track_3_in",
        m.In(m.Bits(1)), "side_3_track_0_in", m.In(m.Bits(1)),
        "side_3_track_1_in", m.In(m.Bits(1)), "side_3_track_2_in",
        m.In(m.Bits(1)), "side_3_track_3_in", m.In(m.Bits(1)),
        "side_0_track_0_out", m.Out(m.Bits(1)), "side_0_track_1_out",
        m.Out(m.Bits(1)), "side_0_track_2_out", m.Out(m.Bits(1)),
        "side_0_track_3_out", m.Out(m.Bits(1)), "side_1_track_0_out",
        m.Out(m.Bits(1)), "side_1_track_1_out", m.Out(m.Bits(1)),
        "side_1_track_2_out", m.Out(m.Bits(1)), "side_1_track_3_out",
        m.Out(m.Bits(1)), "side_2_track_0_out", m.Out(m.Bits(1)),
        "side_2_track_1_out", m.Out(m.Bits(1)), "side_2_track_2_out",
        m.Out(m.Bits(1)), "side_2_track_3_out", m.Out(m.Bits(1)),
        "side_3_track_0_out", m.Out(m.Bits(1)), "side_3_track_1_out",
        m.Out(m.Bits(1)), "side_3_track_2_out", m.Out(
            m.Bits(1)), "side_3_track_3_out", m.Out(m.Bits(1)))

    # Configuration data
    config_reg = mantle.Register(32, init=0, has_ce=True, has_reset=True)
    addr_match = mantle.EQ(16)
    m.wire(addr_match.I0, pe.config_addr[0:16])
    m.wire(addr_match.I1, pe.tile_id)
    m.wire(addr_match.O, config_reg.CE)

    m.wire(pe.config_data, config_reg.I)
    m.wire(pe.clk, config_reg.CLK)

    rst_inv = mantle.Invert(1)
    m.wire(rst_inv.I[0], pe.rst)
    m.wire(rst_inv.O[0], config_reg.RESET)

    # Configure sb = 6, cb0 = 4, cb1 = 5, clb = 7
    config_cb0_eq = mantle.EQ(16)
    m.wire(m.uint(4, 16), config_cb0_eq.I0)
    m.wire(pe.config_addr[16:32], config_cb0_eq.I1)

    config_cb1_eq = mantle.EQ(16)
    m.wire(m.uint(5, 16), config_cb1_eq.I0)
    m.wire(pe.config_addr[16:32], config_cb1_eq.I1)

    config_clb_eq = mantle.EQ(16)
    m.wire(m.uint(7, 16), config_clb_eq.I0)
    m.wire(pe.config_addr[16:32], config_clb_eq.I1)

    config_sb_eq = mantle.EQ(16)
    m.wire(m.uint(6, 16), config_sb_eq.I0)
    m.wire(pe.config_addr[16:32], config_sb_eq.I1)

    config_cb0 = mantle.And(2, 1)
    m.wire(config_cb0.I0[0], config_cb0_eq.O)
    m.wire(config_cb0.I1[0], addr_match.O)

    config_cb1 = mantle.And(2, 1)
    m.wire(config_cb1.I0[0], config_cb1_eq.O)
    m.wire(config_cb1.I1[0], addr_match.O)

    config_clb = mantle.And(2, 1)
    m.wire(config_clb.I0[0], config_clb_eq.O)
    m.wire(config_clb.I1[0], addr_match.O)

    config_sb = mantle.And(2, 1)
    m.wire(config_sb.I0[0], config_sb_eq.O)
    m.wire(config_sb.I1[0], addr_match.O)

    # Add ands!

    # # CB0
    cb0 = create_connect_box(1)()
    m.wire(pe.clk, cb0.clk)
    m.wire(pe.rst, cb0.rst)
    m.wire(pe.config_data, cb0.config_data)
    m.wire(config_cb0.O[0], cb0.config_en)

    # CB1
    cb1 = create_connect_box(1)()
    m.wire(pe.clk, cb1.clk)
    m.wire(pe.rst, cb1.rst)
    m.wire(pe.config_data, cb1.config_data)
    m.wire(config_cb1.O[0], cb1.config_en)

    # CLB
    clb = create_clb(1)()
    m.wire(pe.clk, clb.clk)
    m.wire(pe.rst, clb.rst)
    m.wire(pe.config_data, clb.config_data)
    m.wire(config_clb.O[0], clb.config_en)

    # Switch box
    sb = create_switch_box(1)()
    m.wire(pe.clk, sb.clk)
    m.wire(pe.rst, sb.rst)
    m.wire(pe.config_data, sb.config_data)
    m.wire(config_sb.O[0], sb.config_en)

    m.wire(clb.result, sb.clb_result)

    for side in range(0, 4):
        for track in range(0, 4):
            m.wire(
                getattr(pe,
                        'side_' + str(side) + '_track_' + str(track) + '_in'),
                getattr(sb,
                        'side_' + str(side) + '_track_' + str(track) + '_in'))

    for side in range(0, 4):
        for track in range(0, 4):
            m.wire(
                getattr(pe,
                        'side_' + str(side) + '_track_' + str(track) + '_out'),
                getattr(sb,
                        'side_' + str(side) + '_track_' + str(track) + '_out'))

    # Wiring up CLB, SB and CBs
    m.wire(pe.side_0_track_0_in, cb0.track_0_in)
    m.wire(pe.side_0_track_1_in, cb0.track_1_in)
    m.wire(pe.side_0_track_2_in, cb0.track_2_in)
    m.wire(pe.side_0_track_3_in, cb0.track_3_in)

    m.wire(sb.side_0_track_0_out, cb0.track_0_out)
    m.wire(sb.side_0_track_1_out, cb0.track_1_out)
    m.wire(sb.side_0_track_2_out, cb0.track_2_out)
    m.wire(sb.side_0_track_3_out, cb0.track_3_out)

    m.wire(cb0.out, clb.operand0)

    m.wire(pe.side_1_track_0_in, cb1.track_0_in)
    m.wire(pe.side_1_track_1_in, cb1.track_1_in)
    m.wire(pe.side_1_track_2_in, cb1.track_2_in)
    m.wire(pe.side_1_track_3_in, cb1.track_3_in)

    m.wire(sb.side_1_track_0_out, cb1.track_0_out)
    m.wire(sb.side_1_track_1_out, cb1.track_1_out)
    m.wire(sb.side_1_track_2_out, cb1.track_2_out)
    m.wire(sb.side_1_track_3_out, cb1.track_3_out)

    m.wire(cb1.out, clb.operand1)

    m.EndDefine()

    return pe