def _declr(self): addClkRstn(self) self.dataOut = VldSynced()._m() self.dataOut.DATA_WIDTH.set(8) self.rxd = Signal()
def _declr(self): addClkRstn(self) with self._paramsShared(): self.a0 = VldSynced() self.a1 = VldSynced() self.a2 = VldSynced() self.b = HObjList(VldSynced() for _ in range(int(self.LEN)))._m()
def _declr(self): addClkRstn(self) with self._paramsShared(): self.a = HObjList(VldSynced() for _ in range(self.LEN)) self.b0 = VldSynced()._m() self.b1 = VldSynced()._m() self.b2 = VldSynced()._m()
def _declr(self): LEN = 2 addClkRstn(self) with self._paramsShared(): self.a = HObjList(VldSynced() for _ in range(LEN)) self.b = HObjList(VldSynced() for _ in range(LEN))._m() self.u0 = SimpleSubunit() self.u1 = SimpleSubunit()
def _mkFieldIntf(self, parent: Union[StructIntf, UnionSource], structField: HStructField): t = structField.dtype path = parent._field_path / structField.name if isinstance(t, HUnion): i = UnionSource(t, path, parent._instantiateFieldFn) i._fieldsToInterfaces = parent._fieldsToInterfaces return i elif isinstance(t, HStruct): i = StructIntf(t, path, parent._instantiateFieldFn) i._fieldsToInterfaces = parent._fieldsToInterfaces return i elif isinstance(t, HStream): if self.SHARED_READY: raise NotImplementedError(t) else: i = AxiStream() i._updateParamsFrom(self) return i else: if self.SHARED_READY: i = VldSynced() else: i = Handshaked() i.DATA_WIDTH = structField.dtype.bit_length() return i
def _declr(self): addClkRstn(self) with self._paramsShared(): if self.MASK_GRANULARITY is None: self.dataIn = VldSynced() else: self.dataIn = DataMaskLastHs() self.dataOut = VectSignal(self.POLY_WIDTH)._m()
class OneHotToBin(Unit): """ Converts one hot signal to binary, bin.vld is high when oneHot != 0 .. hwt-autodoc:: """ def _config(self): self.ONE_HOT_WIDTH = Param(8) def _declr(self): self.oneHot = VectSignal(self.ONE_HOT_WIDTH) self.bin = VldSynced()._m() self.bin.DATA_WIDTH = log2ceil(self.ONE_HOT_WIDTH) def _impl(self): self.bin.data(oneHotToBin(self, self.oneHot)) self.bin.vld(Or(*[bit for bit in iterBits(self.oneHot)]))
def _declr(self): addClkRstn(self) with self._paramsShared(): self.din = Handshaked() self.dout = VldSynced()._m() self.tx = UartTx() self.rx = UartRx()
class OneHotToBin(Unit): """ Converts one hot signal to binary, bin.vld is high when oneHot != 0 .. hwt-schematic:: """ def _config(self): self.ONE_HOT_WIDTH = Param(8) def _declr(self): self.oneHot = VectSignal(self.ONE_HOT_WIDTH) self.bin = VldSynced()._m() self.bin.DATA_WIDTH.set(log2ceil(self.ONE_HOT_WIDTH)) def _impl(self): self.bin.data(oneHotToBin(self, self.oneHot)) self.bin.vld(Or(*[bit for bit in iterBits(self.oneHot)]))
def _impl(self): ITEMS = self.addr_cam.ITEMS item_vld = self._reg("item_vld", Bits(ITEMS), def_val=0) waiting_transaction_id = self._sig("waiting_transaction_id", self.s.ar.id._dtype[ITEMS]) waiting_transaction_vld = self._reg("waiting_transaction_vld", Bits(ITEMS), def_val=0) read_ack = self._sig("read_ack") # if the parent transaction is about to finish how we need to copy the response now data_copy_override = VldSynced() data_copy_override.DATA_WIDTH = self.ID_WIDTH self.data_copy_override = data_copy_override self.read_request_section(read_ack, item_vld, waiting_transaction_id, waiting_transaction_vld, data_copy_override) self.read_data_section(read_ack, waiting_transaction_id, waiting_transaction_vld, data_copy_override) propagateClkRstn(self)
def _mkFieldIntf(self, parent: Union[StructIntf, UnionSource], structField: HStructField): t = structField.dtype if isinstance(t, HUnion): return UnionSource(t, parent._instantiateFieldFn) elif isinstance(t, HStruct): return StructIntf(t, parent._instantiateFieldFn) else: if self.SHARED_READY: i = VldSynced() else: i = Handshaked() i.DATA_WIDTH.set(structField.dtype.bit_length()) return i
def _declr(self): assert int(self.DEPTH) > 0, \ "Fifo is disabled in this case, do not use it entirely" assert int(self.DEPTH) > 1, \ "Use register instead" addClkRstn(self) with self._paramsShared(): self.dataIn = FifoWriter() self.dataOut = FifoReader()._m() fc = self.dataOut_copy_frame = VldSynced() fc.DATA_WIDTH = 1 self._declr_size_and_space() if self.EXPORT_SIZE or self.EXPORT_SPACE: raise NotImplementedError()
def _declr(self): addClkRstn(self) with self._paramsShared(): self.bus = Axi4Lite() self.signalLoop = SigLoop() self.signalIn = VectSignal(self.DATA_WIDTH) self.regCntrlLoop = Loop(RegCntrl) self.regCntrlOut = RegCntrl()._m() self.vldSyncedLoop = Loop(VldSynced) self.vldSyncedOut = VldSynced()._m() with self._paramsShared(exclude=({"ADDR_WIDTH"}, set())): self.bramLoop = Loop(BramPort_withoutClk) self.bramLoop.ADDR_WIDTH = 2 self.bramOut = BramPort_withoutClk()._m() self.bramOut.ADDR_WIDTH = 2
def _declr(self): VldSynced._declr(self) if self.DATA_WIDTH > 8: self.mask = VectSignal(self.DATA_WIDTH // 8) self.err = Signal() self.last = Signal()
def _declr(self): addClkRstn(self) with self._paramsShared(): self.dataIn = VldSynced() self.dataOut = VectSignal(self.POLY_WIDTH)._m()
def read_request_section(self, read_ack: RtlSignal, item_vld: RtlSignal, waiting_transaction_id: RtlSignal, waiting_transaction_vld: RtlSignal, data_copy_override: VldSynced): s = self.s m = self.m addr_cam = self.addr_cam ITEMS = addr_cam.ITEMS addr_cam_out = self.add_addr_cam_out_reg(item_vld) with self._paramsShared(): s_ar_tmp = self.s_ar_tmp = AxiSReg(s.AR_CLS) last_cam_insert_match = self._reg("last_cam_insert_match", Bits(ITEMS), def_val=0) match_res = rename_signal( self, item_vld & (addr_cam_out.data | last_cam_insert_match) & ~waiting_transaction_vld, "match_res") blocking_access = rename_signal( self, s.ar.valid & (item_vld[s.ar.id] | (s_ar_tmp.dataOut.valid & (s.ar.id._eq(s_ar_tmp.dataOut.id)))), "blocking_access") s_ar_node = StreamNode( [s.ar], [addr_cam.match[0], s_ar_tmp.dataIn], ) s_ar_node.sync(~blocking_access) # s_ar_node_ack = s_ar_node.ack() & ~blocking_access s_ar_tmp.dataIn(s.ar, exclude={s.ar.valid, s.ar.ready}) parent_transaction_id = oneHotToBin(self, match_res, "parent_transaction_id") m_ar_node = StreamNode( [s_ar_tmp.dataOut, addr_cam_out], [m.ar], extraConds={m.ar: match_res._eq(0)}, skipWhen={m.ar: match_res != 0}, ) m_ar_node.sync() m.ar(s_ar_tmp.dataOut, exclude={m.ar.valid, m.ar.ready}) addr_cam.match[0].data(s.ar.addr[:self.CACHE_LINE_OFFSET_BITS]) ar_ack = rename_signal(self, m_ar_node.ack(), "ar_ack") # insert into cam on empty position specified by id of this transaction acw = addr_cam.write acw.addr(s_ar_tmp.dataOut.id) acw.data(s_ar_tmp.dataOut.addr[:self.CACHE_LINE_OFFSET_BITS]) acw.vld(addr_cam_out.vld) #If(s_ar_node_ack, last_cam_insert_match( binToOneHot( s_ar_tmp.dataOut.id, en=~blocking_access & s.ar.valid & s_ar_tmp.dataOut.valid & s_ar_tmp.dataOut.addr[:self.CACHE_LINE_OFFSET_BITS]._eq( s.ar.addr[:self.CACHE_LINE_OFFSET_BITS]))) #) for trans_id in range(ITEMS): # it becomes ready if we are requested for it on "s" interface this_trans_start = s_ar_tmp.dataOut.id._eq(trans_id) & \ (data_copy_override.vld | ar_ack) # item becomes invalid if we read last data word this_trans_end = read_ack & s.r.id._eq(trans_id) & s.r.last this_trans_end = rename_signal(self, this_trans_end, f"this_trans_end{trans_id:d}") item_vld[trans_id](apply_set_and_clear(item_vld[trans_id], this_trans_start, this_trans_end)) waiting_transaction_start = (ar_ack & (match_res != 0) & parent_transaction_id._eq(trans_id) & ~this_trans_end) # note: this_trans_end in this context is for parent transactio # which was not started just now, so it may be ending just now waiting_transaction_start = rename_signal( self, waiting_transaction_start, f"waiting_transaction_start{trans_id:d}") _waiting_transaction_vld = apply_set_and_clear( waiting_transaction_vld[trans_id], waiting_transaction_start, this_trans_end) waiting_transaction_vld[trans_id](rename_signal( self, _waiting_transaction_vld, f"waiting_transaction_vld{trans_id:d}")) If( self.clk._onRisingEdge(), If((match_res != 0) & ar_ack, waiting_transaction_id[parent_transaction_id]( s_ar_tmp.dataOut.id))) # parent transaction is finishing just now # we need to quickly grab the data in data buffer and copy it also # for this transaction data_copy_override.vld(s_ar_tmp.dataOut.valid & read_ack & (match_res != 0) & s.r.id._eq(parent_transaction_id) & s.r.last) data_copy_override.data(s_ar_tmp.dataOut.id)
class UartRx(Unit): """ UART Rx channel controller .. hwt-schematic:: """ def _config(self): self.FREQ = Param(int(100e6)) self.BAUD = Param(115200) self.OVERSAMPLING = Param(16) def _declr(self): addClkRstn(self) self.dataOut = VldSynced()._m() self.dataOut.DATA_WIDTH.set(8) self.rxd = Signal() def _impl(self): START_BIT = 0 STOP_BIT = 1 os = int(self.OVERSAMPLING) baud = int(self.BAUD) freq = int(self.FREQ) assert freq >= baud * os, "Frequency too low for current Baud rate and oversampling" assert os >= 8 and (os & (os - 1)) == 0, "Invalid oversampling value" propagateClkRstn(self) clkBuilder = ClkBuilder(self, self.clk) en = self._reg("en", defVal=0) first = self._reg("first", defVal=1) RxD_data = self._reg("RxD_data", Bits(1 + 8)) startBitWasNotStartbit = self._sig("startBitWasNotStartbit") # it can happen that there is just glitch on wire and bit was not startbit only begin was resolved wrong # eval because otherwise vhdl int overflows sampleTick = clkBuilder.timer( ("sampleTick", self.FREQ // self.BAUD // self.OVERSAMPLING), enableSig=en, rstSig=~en) # synchronize RxD to our clk domain RxD_sync = self._reg("RxD_sync", defVal=1) RxD_sync(self.rxd) rxd, rxd_vld = clkBuilder.oversample(RxD_sync, self.OVERSAMPLING, sampleTick, rstSig=~en) isLastBit = clkBuilder.timer(("isLastBitTick", 10), enableSig=rxd_vld, rstSig=~en) If( en, If( rxd_vld, RxD_data(Concat(rxd, RxD_data[9:1])), # shift data from left If( startBitWasNotStartbit, en(0), first(1), ).Else( en(~isLastBit), first(isLastBit), ))).Elif( RxD_sync._eq(START_BIT), # potential start bit detected, begin scanning sequence en(1), ) startBitWasNotStartbit(first & rxd_vld & (rxd != START_BIT)) self.dataOut.vld(isLastBit & RxD_data[0]._eq(START_BIT) & rxd._eq(STOP_BIT)) self.dataOut.data(RxD_data[9:1])
def _declr(self): self.oneHot = VectSignal(self.ONE_HOT_WIDTH) self.bin = VldSynced()._m() self.bin.DATA_WIDTH.set(log2ceil(self.ONE_HOT_WIDTH))
def vldSynced(name, width): a = VldSynced() a.DATA_WIDTH = width a._name = name a._loadDeclarations() return a
def _declr(self): self.din = VldSynced() self.dout = VldSynced()._m()
def _declr(self): HsJoinPrioritized._declr(self) addClkRstn(self) if self.EXPORT_SELECTED: s = self.selectedOneHot = VldSynced()._m() s._replaceParam(s.DATA_WIDTH, self.INPUTS)
def _declr(self): with self._paramsShared(): self.c = VldSynced() self.d = VldSynced()._m()
def _declr(self): addClkRstn(self) with self._paramsShared(): L = int(self.LEN) self.a = HObjList(VldSynced() for _ in range(L)) self.b = HObjList(VldSynced() for _ in range(L))._m()
def _declr(self): self.oneHot = VectSignal(self.ONE_HOT_WIDTH) self.bin = VldSynced()._m() self.bin.DATA_WIDTH = log2ceil(self.ONE_HOT_WIDTH)
class UartRx(Unit): """ UART Rx channel controller .. hwt-schematic:: """ def _config(self): self.FREQ = Param(int(100e6)) self.BAUD = Param(115200) self.OVERSAMPLING = Param(16) def _declr(self): addClkRstn(self) self.dataOut = VldSynced()._m() self.dataOut.DATA_WIDTH.set(8) self.rxd = Signal() def _impl(self): START_BIT = 0 STOP_BIT = 1 os = int(self.OVERSAMPLING) baud = int(self.BAUD) freq = int(self.FREQ) assert freq >= baud * os, "Frequency too low for current Baud rate and oversampling" assert os >= 8 and (os & (os - 1)) == 0, "Invalid oversampling value" propagateClkRstn(self) clkBuilder = ClkBuilder(self, self.clk) en = self._reg("en", defVal=0) first = self._reg("first", defVal=1) RxD_data = self._reg("RxD_data", Bits(1 + 8)) startBitWasNotStartbit = self._sig("startBitWasNotStartbit") # it can happen that there is just glitch on wire and bit was not startbit only begin was resolved wrong # eval because otherwise vhdl int overflows sampleTick = clkBuilder.timer(("sampleTick", self.FREQ // self.BAUD // self.OVERSAMPLING), enableSig=en, rstSig=~en) # synchronize RxD to our clk domain RxD_sync = self._reg("RxD_sync", defVal=1) RxD_sync(self.rxd) rxd, rxd_vld = clkBuilder.oversample(RxD_sync, self.OVERSAMPLING, sampleTick, rstSig=~en) isLastBit = clkBuilder.timer(("isLastBitTick", 10), enableSig=rxd_vld, rstSig=~en) If(en, If(rxd_vld, RxD_data(Concat(rxd, RxD_data[9:1])), # shift data from left If(startBitWasNotStartbit, en(0), first(1), ).Else( en(~isLastBit), first(isLastBit), ) ) ).Elif(RxD_sync._eq(START_BIT), # potential start bit detected, begin scanning sequence en(1), ) startBitWasNotStartbit(first & rxd_vld & (rxd != START_BIT)) self.dataOut.vld(isLastBit & RxD_data[0]._eq(START_BIT) & rxd._eq(STOP_BIT)) self.dataOut.data(RxD_data[9:1])