def definition(io): # didn't work with coreir because the rst/bit conversion # clkEn = io.push | io.pop | m.bit(io.rst) ########################## pointer logic ############################## ptrreg = DefineRegister(PTRWID, init=0, has_ce=True, has_reset=True, _type=m.UInt) wrPtr = ptrreg(name="wrPtr") rdPtr = ptrreg(name="rdPtr") # wire clocks m.wireclock(io, wrPtr) m.wireclock(io, rdPtr) # wire resets m.wire(wrPtr.RESET, io.rst) m.wire(rdPtr.RESET, io.rst) # wire enables m.wire(wrPtr.CE, io.push) m.wire(rdPtr.CE, io.pop) # next values increment by one m.wire(wrPtr.I, wrPtr.O + m.uint(1, PTRWID)) m.wire(rdPtr.I, rdPtr.O + m.uint(1, PTRWID)) ######################### end pointer logic ########################### ######################### full and empty logic ######################## m.wire(io.empty, wrPtr.O == rdPtr.O) m.wire(io.full, (wrPtr.O[1:PTRWID] == rdPtr.O[1:PTRWID]) & (wrPtr.O[0] != rdPtr.O[0])) ######################### end full and empty logic #################### ########################### entry logic ############################### # Create and write entries = [] entryReg = DefineRegister(WIDTH, init=0, has_ce=True, has_reset=False, _type=m.Bits) for i in range(DEPTH): entry = entryReg(name="entry" + str(i)) m.wire( entry.CE, io.push & m.bit(m.uint(wrPtr.O[1:PTRWID]) == m.uint(i, PTRWID - 1))) m.wire(entry.I, io.data_in) entries.append(entry) # Connect mux outmux = Mux(DEPTH, WIDTH) for i in range(DEPTH): m.wire(getattr(outmux, "I" + str(i)), entries[i].O) m.wire(rdPtr.O[1:PTRWID], outmux.S) m.wire(outmux.O, io.data_out)
def __init__(self, x_len: int): super().__init__(x_len) io = self.io sum_ = io.A + m.mux([io.B, -io.B], io.op[0]) cmp = m.uint(m.mux([m.mux([io.A[-1], io.B[-1]], io.op[1]), sum_[-1]], io.A[-1] == io.B[-1]), x_len) shin = m.mux([io.A[::-1], io.A], io.op[3]) shiftr = m.uint(m.sint( m.concat(shin, io.op[0] & shin[x_len - 1]) ) >> m.sint(m.zext(io.B, 1)))[:x_len] shiftl = shiftr[::-1] @m.inline_combinational() def alu(): if (io.op == ALUOP.ADD) | (io.op == ALUOP.SUB): io.O @= sum_ elif (io.op == ALUOP.SLT) | (io.op == ALUOP.SLTU): io.O @= cmp elif (io.op == ALUOP.SRA) | (io.op == ALUOP.SRL): io.O @= shiftr elif io.op == ALUOP.SLL: io.O @= shiftl elif io.op == ALUOP.AND: io.O @= io.A & io.B elif io.op == ALUOP.OR: io.O @= io.A | io.B elif io.op == ALUOP.XOR: io.O @= io.A ^ io.B elif io.op == ALUOP.COPY_A: io.O @= io.A else: io.O @= io.B io.sum_ @= sum_
def alu(): if io.op == ALUOP.ADD: io.O @= io.A + io.B elif io.op == ALUOP.SUB: io.O @= io.A - io.B elif io.op == ALUOP.SRA: io.O @= m.uint(m.sint(io.A) >> m.sint(io.B)) elif io.op == ALUOP.SRL: io.O @= io.A >> io.B elif io.op == ALUOP.SLL: io.O @= io.A << io.B elif io.op == ALUOP.SLT: io.O @= m.uint(m.sint(io.A) < m.sint(io.B), x_len) elif io.op == ALUOP.SLTU: io.O @= m.uint(io.A < io.B, x_len) elif io.op == ALUOP.AND: io.O @= io.A & io.B elif io.op == ALUOP.OR: io.O @= io.A | io.B elif io.op == ALUOP.XOR: io.O @= io.A ^ io.B elif io.op == ALUOP.COPY_A: io.O @= io.A else: io.O @= io.B io.sum_ @= io.A + m.mux([io.B, -io.B], io.op[0])
def definition(io): enq_ptr = mantle.Register(address_width) deq_ptr = mantle.Register(address_width) is_full = mantle.FF() do_enq = ~is_full.O & io.enq_val is_empty = ~is_full.O & (enq_ptr.O == deq_ptr.O) do_deq = io.deq_rdy & ~is_empty deq_ptr_inc = m.uint(deq_ptr.O) + 1 enq_ptr_inc = m.uint(enq_ptr.O) + 1 is_full_next = mantle.mux([ mantle.mux([is_full.O, m.bit(False)], do_deq & is_full.O), m.bit(True) ], do_enq & ~do_deq & (enq_ptr_inc == deq_ptr.O)) enq_ptr(mantle.mux([enq_ptr.O, enq_ptr_inc], do_enq)) deq_ptr(mantle.mux([deq_ptr.O, deq_ptr_inc], do_deq)) is_full(is_full_next) ram = mantle.DefineMemory(height, width)() m.wire(ram.RADDR, deq_ptr.O) m.wire(ram.RDATA, io.deq_dat) m.wire(ram.WADDR, enq_ptr.O) m.wire(ram.WDATA, io.enq_dat) m.wire(ram.WE, do_enq) m.wire(io.enq_rdy, ~is_full.O) m.wire(io.deq_val, ~is_empty)
def txmod_logic( data: m.Bits(8), writing: m.Bit, valid: m.Bit, dataStore: m.Bits(11), writeClock: m.Bits(14), writeBit: m.Bits(4), ) -> ( m.Bit, m.Bits(11), m.Bits(14), m.Bits(4), m.Bit, ): if (writing == m.bit(0)) & (valid == m.bit(1)): writing_out = m.bit(1) dataStore_out = m.concat(dataStore[0:1], data, dataStore[9:]) writeClock_out = m.bits(100, 14) writeBit_out = m.bits(0, 4) TXReg_out = dataStore[0] elif (writing == m.bit(1)) & \ (writeClock == m.bits(0, 14)) & \ (writeBit == m.bits(9, 4)): dataStore_out = dataStore writeClock_out = writeClock writeBit_out = writeBit TXReg_out = m.bit(1) writing_out = m.bit(0) elif (writing == m.bit(1)) & (writeClock == m.bits(0, 14)): writing_out = writing dataStore_out = dataStore TXReg_out = dataStore[writeBit] writeBit_out = m.bits(m.uint(writeBit) + m.bits(1, 4)) writeClock_out = m.bits(100, 14) elif writing == m.bit(1): writing_out = writing dataStore_out = dataStore writeBit_out = writeBit TXReg_out = dataStore[writeBit] writeClock_out = m.bits(m.uint(writeClock) - m.bits(1, 14)) else: writing_out = writing dataStore_out = dataStore writeClock_out = writeClock writeBit_out = writeBit TXReg_out = m.bit(1) return ( writing_out, dataStore_out, writeClock_out, writeBit_out, TXReg_out, )
def definition(io): is_op0 = io.opcode == m.uint(0, n=2) is_op1 = io.opcode == m.uint(1, n=2) is_op2 = io.opcode == m.uint(2, n=2) is_op3 = io.opcode == m.uint(3, n=2) op0_out = io.a + io.b op1_out = io.a - io.b op2_out = io.a op3_out = io.b m.wire( io.out, one_hot_mux([is_op0, is_op1, is_op2, is_op3], [op0_out, op1_out, op2_out, op3_out]))
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 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 generate_output_mux(num_tracks, feedthrough_outputs, has_constant, width, mux_sel_bit_count, constant_bit_count, io, config_register): pow_2_tracks = 2**m.bitutils.clog2(num_tracks) print('# of tracks =', pow_2_tracks) output_mux = mantle.Mux(height=pow_2_tracks, width=width) m.wire(output_mux.S, config_register.O[:m.bitutils.clog2(pow_2_tracks)]) # This is only here because this is the way the switch box numbers # things. # We really should get rid of this feedthrough parameter sel_out = 0 for i in range(0, pow_2_tracks): # in_track = 'I' + str(i) if (i < num_tracks): if (feedthrough_outputs[i] == '1'): m.wire(getattr(output_mux, 'I' + str(sel_out)), getattr(io, 'in_' + str(i))) sel_out += 1 if (has_constant == 0): while (sel_out < pow_2_tracks): m.wire(getattr(output_mux, 'I' + str(sel_out)), m.uint(0, width)) sel_out += 1 else: const_val = config_register.O[mux_sel_bit_count:mux_sel_bit_count + constant_bit_count] while (sel_out < pow_2_tracks): m.wire(getattr(output_mux, 'I' + str(sel_out)), const_val) sel_out += 1 return output_mux
def __init__(self, x_len): super().__init__(x_len) inst = self.io.inst Iimm = m.sext_to(m.sint(inst[20:32]), x_len) Simm = m.sext_to(m.sint(m.concat(inst[7:12], inst[25:32])), x_len) Bimm = m.sext_to( m.sint( m.concat(m.bits(0, 1), inst[8:12], inst[25:31], inst[7], inst[31])), x_len) Uimm = m.concat(m.bits(0, 12), inst[12:32]) Jimm = m.sext_to( m.sint( m.concat(m.bits(0, 1), inst[21:25], inst[25:31], inst[20], inst[12:20], inst[31])), x_len) Zimm = m.sint(m.zext_to(inst[15:20], x_len)) self.io.O @= m.uint( m.dict_lookup( { IMM_I: Iimm, IMM_S: Simm, IMM_B: Bimm, IMM_U: Uimm, IMM_J: Jimm, IMM_Z: Zimm }, self.io.sel, Iimm & -2))
def __init__(self, x_len): super().__init__(x_len) inst = self.io.inst sel = self.io.sel is_i = sel == IMM_I is_s = sel == IMM_S is_b = sel == IMM_B is_u = sel == IMM_U is_j = sel == IMM_J is_z = sel == IMM_Z sign = is_z.ite(0, inst[31:32]) b0_1 = is_s.ite(inst[7:8], is_i.ite(inst[20:21], is_z.ite(inst[15:16], 0))) b1_5 = is_u.ite(0, (is_s | is_b).ite(inst[8:12], is_z.ite(inst[16:20], inst[21:25]))) b5_11 = (is_u | is_z).ite(0, inst[25:31]) b11_12 = (is_u | is_z).ite( 0, is_j.ite(inst[20:21], is_b.ite(inst[7:8], sign))) # the reference impl inverts this mux with (!is_u & !is_j) b12_20 = (is_u | is_j).ite(inst[12:20], sign.repeat(8)) b20_31 = is_u.ite(inst[20:31], sign.repeat(11)) self.io.O @= m.uint( reduce(m.Bits.concat, [b0_1, b1_5, b5_11, b11_12, b12_20, b20_31, sign]))
def test_array(): assert isinstance(array(1, 4), ArrayType) assert isinstance(array([1, 0, 0, 0]), ArrayType) assert isinstance(array(VCC), ArrayType) assert isinstance(array(array(1, 4)), ArrayType) assert isinstance(array(uint(1, 4)), ArrayType) assert isinstance(array(sint(1, 4)), ArrayType)
def test_bits(): assert isinstance(bits(1, 4), BitsType) assert isinstance(bits([1, 0, 0, 0]), BitsType) assert isinstance(bits(VCC), BitsType) assert isinstance(bits(array(1, 4)), BitsType) assert isinstance(bits(uint(1, 4)), BitsType) assert isinstance(bits(sint(1, 4)), BitsType)
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 test_tuple(): assert isinstance(tuple_(OrderedDict(x=0, y=1)), TupleType) assert isinstance(tuple_([0, 1]), TupleType) assert isinstance(tuple_(VCC), TupleType) assert isinstance(tuple_(array(1, 4)), TupleType) assert isinstance(tuple_(bits(1, 4)), TupleType) assert isinstance(tuple_(sint(1, 4)), TupleType) assert isinstance(tuple_(uint(1, 4)), TupleType)
def wrapper(*args, **kwargs): retval = fn(*args, **kwargs) T = type(args[0]) if isinstance(T, m.UIntKind): return m.uint(retval) elif isinstance(T, m.SIntKind): return m.sint(retval) return retval
def wrapper(*args, **kwargs): retval = fn(*args, **kwargs) T = type(args[0]) if issubclass(T, m.UInt): return m.uint(retval) elif issubclass(T, m.SInt): return m.sint(retval) return retval
def definition(io): cntreg = DefineRegister(CNTWID, init=0, has_ce=False, has_reset=True, _type=m.UInt) pop_cnt = cntreg(name="pop_cnt") # wire clock m.wireclock(io, pop_cnt) # wire reset m.wire(pop_cnt.RESET, io.rst) # increment enable logic incr_mask = m.bit((pop_cnt.O < m.uint(DEPTH, CNTWID)) & (io.push) & (~io.captured)) wide_incr_mask = repeat(incr_mask, CNTWID) # intermediate signal push_cnt = m.uint(pop_cnt.O + m.uint(m.uint(1, CNTWID) & wide_incr_mask)) # decrement enable logic decr_mask = m.bit((push_cnt > m.uint(0, CNTWID)) & (io.pop)) wide_decr_mask = repeat(decr_mask, CNTWID) # wire next state cnt_update = push_cnt - m.uint(m.uint(1, CNTWID) & wide_decr_mask) m.wire(pop_cnt.I, cnt_update) # wire output m.wire(pop_cnt.O, io.cnt) m.wire(cnt_update, io.next_cnt)
def definition(io): state = mantle.Register(2, has_async_reset=True, init=0) pixel_count = mantle.Register(11, has_async_reset=True, init=0) next_state, next_pixel_count = fsm_logic(state.O, m.uint(pixel_count.O), io.frameValid, io.real_href) m.wire(next_state, state.I) m.wire(next_pixel_count, pixel_count.I) m.wire(state.O == HACT, io.pixel_valid)
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 test_clock(): assert isinstance(clock(0), ClockType) assert isinstance(clock(1), ClockType) assert isinstance(clock(VCC), ClockType) assert isinstance(clock(GND), ClockType) assert isinstance(clock(bit(0)), ClockType) assert isinstance(clock(clock(0)), ClockType) assert isinstance(clock(reset(0)), ClockType) assert isinstance(clock(enable(0)), ClockType) assert isinstance(clock(bits(0, 1)), ClockType) assert isinstance(clock(uint(0, 1)), ClockType) assert isinstance(clock(sint(0, 1)), ClockType)
def test_reset(): assert isinstance(reset(0), ResetType) assert isinstance(reset(1), ResetType) assert isinstance(reset(VCC), ResetType) assert isinstance(reset(GND), ResetType) assert isinstance(reset(bit(0)), ResetType) assert isinstance(reset(clock(0)), ResetType) assert isinstance(reset(enable(0)), ResetType) assert isinstance(reset(reset(0)), ResetType) assert isinstance(reset(bits(0, 1)), ResetType) assert isinstance(reset(uint(0, 1)), ResetType) assert isinstance(reset(sint(0, 1)), ResetType)
def test_enable(): assert isinstance(enable(0), EnableType) assert isinstance(enable(1), EnableType) assert isinstance(enable(VCC), EnableType) assert isinstance(enable(GND), EnableType) assert isinstance(enable(bit(0)), EnableType) assert isinstance(enable(clock(0)), EnableType) assert isinstance(enable(reset(0)), EnableType) assert isinstance(enable(enable(0)), EnableType) assert isinstance(enable(bits(0, 1)), EnableType) assert isinstance(enable(uint(0, 1)), EnableType) assert isinstance(enable(sint(0, 1)), EnableType)
def definition(io): O = [] # Initialize COUT with the CIN COUT = io.CIN for i in range(n): # Create an instance fulladder = FullAdder_() # Wire up the i-th bits of the inputs and the previous COUT OI, COUT = fulladder(io.I0[i], io.I1[i], COUT) # Build up a list of full adder outputs O.append(OI) # Convert list of full adder outputs into a packed uint type io.O <= m.uint(O) io.COUT <= COUT
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)
def definition(io): edge_r = rising(io.SCK) edge_f = falling(io.SCK) # pixels come 16 bits (high and low byte) at a time bit_counter = mantle.Counter(4, has_ce=True, has_reset=True) m.wire(edge_r, bit_counter.CE) # find when the high and low byte are valid low = mantle.Decode(15, 4)(bit_counter.O) high = mantle.Decode(7, 4)(bit_counter.O) # shift registers to store high and low byte low_byte = mantle.PIPO(8, has_ce=True) high_byte = mantle.PIPO(8, has_ce=True) low_byte(0, io.DATA, low) high_byte(0, io.DATA, high) m.wire(low, low_byte.CE) m.wire(high, high_byte.CE) # assemble the 16-bit RGB565 value px_bits = (m.uint(mantle.LSL(16)((m.uint(m.concat(high_byte.O, zeros))), m.bits(8, 4))) + m.uint(m.concat(low_byte.O, zeros))) # extract the values for each color r_val = m.uint(mantle.LSR(16)((px_bits & RMASK), m.bits(11, 4))) g_val = m.uint(mantle.LSR(16)((px_bits & GMASK), m.bits(5, 4))) b_val = m.uint(px_bits & BMASK) # sum them to get grayscale (0 to 125) px_val = (r_val + g_val + b_val) # --------------------------UART OUTPUT---------------------------- # # run 16-bit UART at 2x speed baud = edge_r | edge_f # reset at start of pixel transfer ff1 = mantle.FF(has_ce=True) m.wire(baud, ff1.CE) u_reset = mantle.LUT2(I0 & ~I1)(io.VALID, ff1(io.VALID)) m.wire(u_reset, bit_counter.RESET) # generate load signal ff2 = mantle.FF(has_ce=True) m.wire(baud, ff2.CE) load = mantle.LUT3(I0 & I1 & ~I2)(io.VALID, high, ff2(high)) uart = UART(16) uart(CLK=io.CLK, BAUD=baud, DATA=px_val, LOAD=load) m.wire(px_val, io.PXV) m.wire(uart, io.UART) m.wire(load, io.LOAD)
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 test_const(): Top = m.DefineCircuit("test_const", "I0", m.In(m.UInt(8)), "I1", m.In(m.UInt(8)), "O", m.Out(m.UInt(8))) result = Top.I0 + Top.I1 * m.uint(3, 8) m.wire(result, Top.O) m.EndCircuit() m.compile("test_const", Top, output="coreir-verilog", inline=True) tester = fault.Tester(Top) for i in range(0, 16): I0 = fault.random.random_bv(8) I1 = fault.random.random_bv(8) tester.poke(Top.I0, I0) tester.poke(Top.I1, I1) tester.eval() tester.expect(Top.O, I0 + I1 * 3) tester.compile_and_run(target="verilator", skip_compile=True, directory=".")
def fsm_logic(current_state: m.Bits(2), pixel_count: m.UInt(11), frameValid: m.Bit, real_href: m.Bit) -> (m.Bits(2), m.UInt(11)): """Returns next_state, next_pixel_count""" if current_state == IDLE: next_state = HBLANK if frameValid else IDLE next_pixel_count = m.bits(0, 11) elif current_state == HBLANK: if real_href: next_state = HACT next_pixel_count = PIX_PER_LINE else: next_state = HBLANK next_pixel_count = m.bits(0, 11) elif current_state == HACT: next_state = HBLANK if pixel_count == m.bits(1, 11) else HACT # TODO: Support AugAssign node # next_pixel_count -= 1 next_pixel_count = pixel_count - m.uint(1, 11) else: next_state = IDLE next_pixel_count = m.bits(0, 11) return next_state, next_pixel_count
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): rm = RigelMod() m.wire(io.I,rm.process_input) out = rm.process_output+m.uint(10,8) m.wire(io.O,out) m.wire(rm.CE,m.bit(True))