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)
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)
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
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)
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
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
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
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)
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)
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)
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)
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()
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)
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)
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)
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)
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
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)
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)
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)
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)
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'))
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)
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)
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)
def definition(io): reg = mantle.Register(2, has_ce=True, name="conf_reg") io.Q <= reg(io.D, CE=io.CE)
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