def __init__(self, config_addr_width: int, config_data_width: int): super().__init__() self.config_addr_width = config_addr_width self.config_data_width = config_data_width config_type = ConfigurationType(config_addr_width, config_data_width) self.add_ports(clk=magma.In(magma.Clock), config=magma.In(config_type), config_out=magma.Out(config_type)) # Pipeline registers config_addr_reg = FromMagma(DefineRegister(config_addr_width)) config_data_reg = FromMagma(DefineRegister(config_data_width)) config_read_reg = FromMagma(DefineRegister(1)) config_write_reg = FromMagma(DefineRegister(1)) # Wire pipeline reg inputs self.wire(self.ports.config.config_addr, config_addr_reg.ports.I) self.wire(self.ports.config.config_data, config_data_reg.ports.I) self.wire(self.ports.config.read, config_read_reg.ports.I) self.wire(self.ports.config.write, config_write_reg.ports.I) # Wire pipeline reg outputs self.wire(config_addr_reg.ports.O, self.ports.config_out.config_addr) self.wire(config_data_reg.ports.O, self.ports.config_out.config_data) self.wire(config_read_reg.ports.O, self.ports.config_out.read) self.wire(config_write_reg.ports.O, self.ports.config_out.write)
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 test_shift_register(): N = 4 Register4 = DefineRegister(4) T = m.Bits[ N ] class ShiftRegister(m.Circuit): name = "ShiftRegister" IO = ["I", m.In(T), "O", m.Out(T), "CLK", m.In(m.Clock)] @classmethod def definition(io): regs = [Register4() for _ in range(N)] m.wire(io.I, regs[0].I) m.fold(regs, foldargs={"I": "O"}) m.wire(regs[-1].O, io.O) simulator = PythonSimulator(ShiftRegister, clock=ShiftRegister.CLK) expected = [0, 0, 0] + list(range(0, 1 << N, 3))[:-3] actual = [] for i in range(0, 1 << N, 3): simulator.set_value(ShiftRegister.I, i) simulator.advance(2) actual.append(simulator.get_value(ShiftRegister.O)) assert actual == expected m.compile("build/ShiftRegister", ShiftRegister, output="coreir") assert m.testing.check_files_equal(__file__, "build/ShiftRegister.json", "gold/ShiftRegister.json")
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 test_shift_register(): N = 4 Register4 = DefineRegister(4) T = Bits(N) class ShiftRegister(Circuit): name = "ShiftRegister" IO = ["I", In(T), "O", Out(T), "CLK", In(Clock)] @classmethod def definition(io): regs = [Register4() for _ in range(N)] wireclock(io, regs) wire(io.I, regs[0].I) fold(regs, foldargs={"I": "O"}) wire(regs[-1].O, io.O) simulator = PythonSimulator(ShiftRegister, clock=ShiftRegister.CLK) expected = [0, 0, 0] + list(range(0, 1 << N, 3))[:-3] actual = [] for i in range(0, 1 << N, 3): simulator.set_value(ShiftRegister.I, uint(i, N)) simulator.advance(2) actual.append(seq2int(simulator.get_value(ShiftRegister.O))) assert actual == expected
def __create_reg(self): for reg_name, reg_node in self.switchbox.registers.items(): reg_cls = DefineRegister(reg_node.width, has_ce=True) reg = FromMagma(reg_cls) reg.instance_name = create_name(str(reg_node)) self.regs[reg_name] = reg_node, reg # add stall ports if len(self.regs) > 0: self.add_port("stall", magma.In(magma.Bits[self.stall_signal_width]))
def __make_register_buffer(self, unbuffered_mux): signal_in = unbuffered_mux.ports.O width = get_width(signal_in.type()) # register = Register(width) RegisterCls = DefineRegister(width) register = FromMagma(RegisterCls) mux = MuxWrapper(2, width) self.wire(signal_in, mux.ports.I[0]) self.wire(signal_in, register.ports.I) self.wire(register.ports.O, mux.ports.I[1]) return mux
def definition(io): en = DefineRegister(1, init=0, has_ce=False, has_reset=True, _type=m.Bits)(name="en") # wire clock m.wireclock(en, io) # wire reset m.wire(io.rst, en.RESET) # enable only goes high once, then stays high m.wire(en.O | m.bits(io.start), en.I) mpt = DefineMagicPacketTracker(DEPTH)() # wire up magic packet tracker m.wire(en.O, m.bits(mpt.captured)) m.wire(io.rst, mpt.rst) m.wireclock(io, mpt) if not ARBITER: m.wire(io.push, mpt.push) m.wire(io.pop, mpt.pop) fifo = DefineFIFO(DATAWID, DEPTH)() # wire up fifo m.wire(io.push, fifo.push) m.wire(io.pop, fifo.pop) m.wire(io.rst, fifo.rst) m.wire(io.data_in, fifo.data_in) m.wireclock(io, fifo) else: m.wire(io.push[0], mpt.push) fifos = list() for i in range(NUM_REQS): f = DefineFIFO(DATAWID, DEPTH)(name="fifo_{}".format(i)) fifos.append(f) m.wire(io.push[i], f.push) m.wire(io.rst, f.rst) m.wire(io.data_in[i], f.data_in) m.wireclock(io, f) # Need to wire things up if ARBITER: arb = DefineDWRR(NUM_REQS, QWID, DATAWID)(name="arb") m.wire(io.rst, arb.rst) m.wire(io.input_quantums, arb.quantums) for i in range(NUM_REQS): m.wire(~fifos[i].empty, arb.reqs[i]) m.wire(arb.gnt[i], fifos[i].pop) m.wire(arb.gnt[0], mpt.pop) # vld out # TODO handle missing magic packet -- need to reset everything. Or keep as an assumption/restriction m.wire( m.bit(en.O) & eq(m.uint(mpt.next_cnt), m.uint(0, (DEPTH - 1).bit_length())) & eq(m.uint(mpt.cnt), m.uint(1, (DEPTH - 1).bit_length())), io.data_out_vld)