def _example_AxiLiteEndpoint(): from hwt.hdl.types.struct import HStruct from hwtLib.types.ctypes import uint32_t, uint16_t t = HStruct( (uint32_t[4], "data0"), # optimized address selection because data are aligned (uint32_t[4], "data1"), (uint32_t[2], "data2"), (uint32_t, "data3"), # padding (uint32_t[32], None), # type can be any type (HStruct((uint16_t, "data4a"), (uint16_t, "data4b"), (uint32_t, "data4c")), "data4"), ) # type flattening can be specified by shouldEnterFn parameter # target interface can be overriden by _mkFieldInterface function # There are other bus endpoints, for example: # IpifEndpoint, I2cEndpoint, AvalonMmEndpoint and others # decoded interfaces for data type will be same just bus interface # will difer u = AxiLiteEndpoint(t) # configuration u.ADDR_WIDTH.set(8) u.DATA_WIDTH.set(32) return u
def _impl(self): t = self.a._dtype tmp_t = \ HStruct( (t, "a0"), (t, "a1"), (t[2], "a2_3"), (HStruct( (t, "a4"), (t[2], "a5_6"), ), "a4_5_6" ), ) tmp = self._sig("tmp", tmp_t) self.connect_tmp_chain(tmp, self.a, self.b) tmp_reg = self._reg("tmp_reg", tmp_t, def_val={ "a0": 0, "a1": 1, "a2_3": [2, 3], "a4_5_6": { "a4": 4, "a5_6": [5, 6], } }) self.connect_tmp_chain(tmp_reg, self.c, self.d)
def _example_AxiS_frameDeparser(): from hwtLib.types.ctypes import uint64_t, uint8_t, uint16_t, uint32_t # t = HStruct( # (uint64_t, "item0"), # (uint64_t, None), # name = None means field is padding # (uint64_t, "item1"), # (uint8_t, "item2"), (uint8_t, "item3"), (uint16_t, "item4") # ) # t = HUnion( # (HStruct( # (uint64_t, "itemA0"), # (uint64_t, "itemA1") # ), "frameA"), # (HStruct( # (uint32_t, "itemB0"), # (uint32_t, "itemB1"), # (uint32_t, "itemB2"), # (uint32_t, "itemB3") # ), "frameB") # ) t = HUnion( (HStruct((uint8_t, "data"), (uint8_t, None)), "u0"), (HStruct((uint8_t, None), (uint8_t, "data")), "u1"), ) u = AxiS_frameDeparser(t) u.DATA_WIDTH = 16 return u
def _example_AxiLiteEndpoint(): from hwt.hdl.types.struct import HStruct from hwtLib.types.ctypes import uint32_t, uint16_t t = HStruct( (uint32_t[4], "data0"), # optimized address selection because data are aligned (uint32_t[4], "data1"), (uint32_t[2], "data2"), (uint32_t, "data3"), # padding (uint32_t[32], None), # type can be any type (HStruct( (uint16_t, "data4a"), (uint16_t, "data4b"), (uint32_t, "data4c") ), "data4"), ) u = AxiLiteEndpoint(t) # configuration u.ADDR_WIDTH = 8 u.DATA_WIDTH = 32 return u
def test_HTypeFromIntfMap_ArrayOfStructs(self): DATA_WIDTH = 32 t = HTypeFromIntfMap( IntfMap([ regCntr("a", DATA_WIDTH), (Bits(4 * DATA_WIDTH), None), ([IntfMap([ vldSynced("c", DATA_WIDTH), vldSynced("d", DATA_WIDTH) ]) for _ in range(4)], "ds") ])) _t = Bits(DATA_WIDTH) _t2 = HStruct( (_t, "c"), (_t, "d") ) t2 = HStruct( (_t, "a"), (Bits(4 * DATA_WIDTH), None), (_t2[4], "ds", HStructFieldMeta(split=True)), ) self.assertEqual(t, t2)
def test_HTypeFromIntfMap_StructArray(self): DATA_WIDTH = 32 t = HTypeFromIntfMap( IntfMap([ regCntr("a", DATA_WIDTH), (Bits(4 * DATA_WIDTH), None), ([ IntfMap([ vldSynced("d", DATA_WIDTH), sig("e", DATA_WIDTH), (Bits(DATA_WIDTH * 2), None), sig("f", DATA_WIDTH), ]) for _ in range(4)], "ds") ])) _t = Bits(DATA_WIDTH) self.assertEqual(t, HStruct( (_t, "a"), (Bits(4 * DATA_WIDTH), None), (HStruct( (_t, "d"), (_t, "e"), (Bits(2 * DATA_WIDTH), None), (_t, "f"), )[4], "ds", HStructFieldMeta(split=True)), ))
def test_separate_streams_simple(self): t = HStruct( (HStream(Bits(8)), "data"), (Bits(32), "footer"), ) sep = list(separate_streams(t)) self.assertSequenceEqual(sep, [(True, HStruct( (HStream(Bits(8)), "data"), )), (False, HStruct((Bits(32), "footer"), ))])
def connect_update_port(self, update: AxiCacheTagArrayUpdateIntf, tag_mem_port_w: BramPort_withoutClk): update_tmp = self._reg("update_tmp", HStruct( (update.addr._dtype, "addr"), (BIT, "delete"), (update.way_en._dtype, "way_en"), (BIT, "vld"), ), def_val={"vld": 0}) update_tmp(update) tag, index, _ = self.parse_addr(update.addr) tag_mem_port_w.en(update.vld) tag_mem_port_w.addr(index) # construct the byte enable mask for various tag enable configurations # prepare write tag in every way but byte enable only requested ways tag_record = self.tag_record_t.from_py({ "tag": tag, "valid": ~update.delete, }) tag_record = tag_record._reinterpret_cast( Bits(self.tag_record_t.bit_length())) tag_mem_port_w.din(Concat(*(tag_record for _ in range(self.WAY_CNT)))) tag_be_t = Bits(self.tag_record_t.bit_length() // 8) tag_en = tag_be_t.from_py(tag_be_t.all_mask()) tag_not_en = tag_be_t.from_py(0) tag_mem_port_w.we( Concat(*reversed( [en._ternary(tag_en, tag_not_en) for en in update.way_en]))) return update_tmp
def _example_AvalonMmEndpoint(): from hwt.hdl.types.struct import HStruct from hwtLib.types.ctypes import uint32_t u = AvalonMmEndpoint( HStruct((uint32_t, "field0"), (uint32_t, "field1"), (uint32_t[32], "bramMapped"))) return u
class AxiS_FrameJoin_3x_in_1B_on_5B_TC(AxiS_FrameJoin_1x_2B_TC): D_B = 5 T = HStruct( (HStream(Bits(8 * 1), (1, inf), [0]), "frame0"), (HStream(Bits(8 * 1), (1, inf), [0]), "frame1"), (HStream(Bits(8 * 1), (1, inf), [0]), "frame2"), )
def _example_StructReader(): from hwtLib.types.ctypes import uint16_t, uint32_t, uint64_t s = HStruct( (uint64_t, "item0"), # tuples (type, name) where type has to be instance of Bits type (uint64_t, None), # name = None means this field will be ignored (uint64_t, "item1"), (uint64_t, None), (uint16_t, "item2"), (uint16_t, "item3"), (uint32_t, "item4"), (uint32_t, None), (uint64_t, "item5"), # this word is split on two bus words (uint32_t, None), (uint64_t, None), (uint64_t, None), (uint64_t, None), (uint64_t, "item6"), (uint64_t, "item7"), ) u = StructReader(s) return u
def test_holeOnStart(self): MAGIC = 54 MAGIC2 = 0x1000 s = HStruct((uint64_t, None), (uint64_t, None), (uint64_t, None), (uint64_t, None), (uint64_t, "field0"), (uint64_t, "field1"), (uint64_t, "field2")) m = self.buildEnv(s) u = self.u dIn = u.dataIn dIn.field0._ag.data.append(MAGIC) dIn.field1._ag.data.append(MAGIC + 1) dIn.field2._ag.data.append(MAGIC + 2) u.set._ag.data.append(MAGIC2) self.runSim(100 * Time.ns) self.assertEmpty(dIn.field0._ag.data) self.assertEmpty(dIn.field1._ag.data) self.assertEmpty(dIn.field2._ag.data) self.assertEmpty(u.set._ag.data) s_got = m.getStruct(MAGIC2, s) self.assertValEqual(s_got.field0, MAGIC) self.assertValEqual(s_got.field1, MAGIC + 1) self.assertValEqual(s_got.field2, MAGIC + 2)
def dispatch_addr(self, id_to_use: RtlSignal, addr: RtlSignal, a: Axi4_addr): """ * if there is a valid item in buffer dispatch read request """ a_ld = self._sig("a_ld") a_tmp = self._reg("ar_tmp", HStruct( (a.id._dtype, "id"), (addr._dtype, "addr"), (BIT, "vld"), ), def_val={"vld": 0}) If(a_ld, a_tmp.id(id_to_use), a_tmp.addr(addr), a_tmp.vld(1)).Else(a_tmp.vld(a_tmp.vld & ~a.ready)) a.id(a_tmp.id) a.addr(Concat(a_tmp.addr, Bits(self.CACHE_LINE_OFFSET_BITS).from_py(0))) a.len(self.BUS_WORDS_IN_CACHE_LINE - 1) a.burst(BURST_INCR) a.prot(PROT_DEFAULT) a.size(BYTES_IN_TRANS(self.DATA_WIDTH // 8)) a.lock(LOCK_DEFAULT) a.cache(CACHE_DEFAULT) a.qos(QOS_DEFAULT) a.valid(a_tmp.vld) return a_ld
def test_itIsPossibleToSerializeIpcores(self): f = Fifo() f.DEPTH = 16 en0 = AxiS_en() en0.USE_STRB = True en0.USE_KEEP = True en0.ID_WIDTH = 8 en0.DEST_WIDTH = 4 en0.USER_WIDTH = 12 u0 = SimpleUnitWithParam() u0.DATA_WIDTH = 2 u1 = SimpleUnitWithParam() u1.DATA_WIDTH = 3 u_with_hdl_params = MultiConfigUnitWrapper([u0, u1]) testUnits = [ AxiS_en(), en0, AxiLiteEndpoint(HStruct((uint64_t, "f0"), (uint64_t[10], "arr0"))), I2cMasterBitCtrl(), f, Axi4streamToMem(), IpCoreIntfTest(), u_with_hdl_params, ] for u in testUnits: serializeAsIpcore(u, folderName=self.test_dir)
def read_logic(self, r: RamHsR, ram: BramPort_withoutClk): readDataPending = self._reg("readDataPending", def_val=0) readData = self._reg("readData", HStruct((r.data.data._dtype, "data"), (BIT, "vld")), def_val={"vld": 0}) readDataOverflow = self._reg("readDataOverflow", readData._dtype, def_val={"vld": 0}) rEn = ~readDataOverflow.vld & (~readData.vld | r.data.rd) readDataPending(r.addr.vld & rEn) If( readDataPending, If( ~readData.vld | r.data.rd, # can store directly to readData register readData.data(ram.dout), readData.vld(1), readDataOverflow.vld(0), ).Else( # need to store to overflow register readDataOverflow.data(ram.dout), readDataOverflow.vld(1), ), ).Else( If(r.data.rd, readData.data(readDataOverflow.data), readData.vld(readDataOverflow.vld), readDataOverflow.vld(0))) r.addr.rd(rEn) return rEn, readData
def get_packet_data_t(usb_ver: USB_VER): max_frame_len = USB_MAX_FRAME_LEN[usb_ver] # pid has to be one of DATA_0, DATA_1, DATA_2, DATA_M return HStruct( (pid_t, "pid"), (HStream(Bits(8), frame_len=(1, max_frame_len)), "data"), (crc16_t, "crc"), )
def HdlType_select(t: HStruct, fieldsToUse: filed_filter_t): """ Select fields from type structure (rest will become padding) :param t: HdlType type instance :param fieldsToUse: dict {name:{...}} or set of names to select, dictionary is used to select nested fields in HStruct/HUnion fields/array items (f.e. {"struct1": {"field1", "field2"}, "field3":{}} will select field1 and 2 from struct1 and field3 from root) """ template = [] fieldsToUse = fieldsToUse foundNames = set() if isinstance(t, (HArray, HStream)): assert len(fieldsToUse) <= 1, ( "select only on item 0, because it has to be same for all array items", fieldsToUse) k, v = list(fieldsToUse.items())[0] assert k == 0 new_t = copy(t) new_t.elment = HdlType_select(t.element_t, v) return new_t elif isinstance(t, (Bits, HEnum)): # scalar return t else: # struct/Union for f in t.fields: name = None subfields = [] if f.name is not None: try: if isinstance(fieldsToUse, dict): subfields = fieldsToUse[f.name] name = f.name else: if f.name in fieldsToUse: name = f.name except KeyError: name = None if name is not None and subfields: new_t = HdlType_select(f.dtype, subfields) template.append(HStructField(new_t, name)) else: template.append(HStructField(f.dtype, name)) if f.name is not None: foundNames.add(f.name) if isinstance(fieldsToUse, dict): fieldsToUse = set(fieldsToUse.keys()) assert fieldsToUse.issubset(foundNames) return t.__class__(*template)
def _example_OooOpExampleCounterHashTable(): u = OooOpExampleCounterHashTable() u.ID_WIDTH = 6 u.ADDR_WIDTH = 16 + 3 u.MAIN_STATE_T = HStruct( (BIT, "item_valid"), (Bits(256), "key"), (Bits(32), "value"), (Bits(512 - 256 - 32 - 1), "padding"), ) u.TRANSACTION_STATE_T = HStruct( (BIT, "reset"), (u.MAIN_STATE_T, "original_data"), (BIT, "key_match"), (Bits(2), "operation"), # :see: :class:`~.OPERATION` ) u.DATA_WIDTH = u.MAIN_STATE_T.bit_length() return u
def _example_AxiS_frameParser(): from hwtLib.types.ctypes import uint32_t, uint64_t # t = HStruct( # (uint64_t, "item0"), # tuples (type, name) where type has to be instance of Bits type # (uint64_t, None), # name = None means this field will be ignored # (uint64_t, "item1"), # (uint64_t, None), # (uint16_t, "item2"), # (uint16_t, "item3"), # (uint32_t, "item4"), # (uint32_t, None), # (uint64_t, "item5"), # this word is split on two bus words # (uint32_t, None), # (uint64_t, None), # (uint64_t, None), # (uint64_t, None), # (uint64_t, "item6"), # (uint64_t, "item7"), # (HStruct( # (uint64_t, "item0"), # (uint64_t, "item1"), # ), # "struct0") # ) # t = HUnion( # (uint32_t, "a"), # (int32_t, "b") # ) t = HUnion( (HStruct( (uint64_t, "itemA0"), (uint64_t, "itemA1") ), "frameA"), (HStruct( (uint32_t, "itemB0"), (uint32_t, "itemB1"), (uint32_t, "itemB2"), (uint32_t, "itemB3") ), "frameB") ) u = AxiS_frameParser(t) u.DATA_WIDTH.set(64) return u
def test_hunion_type_eq(self): t0 = HUnion((HStruct( (uint16_t, "a"), (uint8_t, "b"), )[3], "arr"), (Bits(24 * 3), "bits")) t1 = HUnion((HStruct( (uint16_t, "a"), (uint8_t, "b"), )[3], "arr"), (Bits(24 * 3), "bits")) self.assertEqual(t0, t1) self.assertEqual(t1, t0) t1 = HUnion((Bits(24 * 3), "bits"), (HStruct( (uint16_t, "a"), (uint8_t, "b"), )[3], "arr")) self.assertEqual(t0, t1) self.assertEqual(t1, t0) t1 = HUnion( (uint32_t, "bits"), (uint8_t[4], "arr"), ) self.assertNotEqual(t0, t1) self.assertNotEqual(t1, t0) t1 = HUnion((Bits(24 * 3), "bbits"), (HStruct( (uint16_t, "a"), (uint8_t, "b"), )[3], "arr")) self.assertNotEqual(t0, t1) self.assertNotEqual(t1, t0) t1 = Bits(24 * 3) self.assertNotEqual(t0, t1) self.assertNotEqual(t1, t0) t1 = HUnion((Bits(24 * 3, signed=False), "bits"), (HStruct( (uint16_t, "a"), (uint8_t, "b"), )[3], "arr")) self.assertNotEqual(t0, t1) self.assertNotEqual(t1, t0)
def _config(self): self.T = Param(HStruct( (HStream(Bits(8), frame_len=(1, inf), start_offsets=[0]), "f0"), (HStream(Bits(16), frame_len=(1, 1)), "f1"), )) AxiStream._config(self) self.DATA_WIDTH = 16 self.USE_KEEP = True self.OUT_OFFSET = Param(0)
def _config(self): self.ADDR_WIDTH = Param(32) self.DATA_WIDTH = Param(32) self.CNTRL_AW = Param(5) # size of data which should be transfered in worlds self.DATA_LEN = Param(33) self.MAX_BUTST_LEN = Param(16) self.REGISTER_MAP = HStruct((uint32_t, "control"), (uint32_t, "baseAddr"))
def HdlType_separate(t: HdlType, do_separate_query: Callable[[HdlType], bool])\ -> Generator[Tuple[bool, HdlType], None, None]: """ Split HStruct type hierachy on the specified fields to multiple type definitions. """ sep = do_separate_query(t) if sep: yield (True, t) elif isinstance(t, HStruct): # fields which were generated by field spliting and are not yet in output HStruct leftovers = [] any_split = False for f in t.fields: for separate_field, _t in HdlType_separate(f.dtype, do_separate_query): if t is f.dtype: leftovers.append(f) else: # the type was spltited somewhere _f = copy(f) _f.dtype = _t if separate_field: if leftovers: new_t = HStruct(*leftovers, name=t.name) yield (False, new_t) leftovers.clear() # create a new HStruct from previous fields new_t = HStruct(_f, name=t.name) leftovers.clear() yield (True, new_t) any_split = True else: leftovers.append(_f) if any_split: if leftovers: new_t = HStruct(*leftovers, name=t.name) yield (False, new_t) else: yield (False, t) else: yield (False, t)
def _impl(self) -> None: ram = self.ram al = AxiBuilder(self, self.s).to_axi(Axi4Lite).end with self._paramsShared(): dec = self.decoder = AxiLiteEndpoint( HStruct((ram.port[0].dout._dtype[2**ram.ADDR_WIDTH], "ram"))) dec.bus(al) ram.port[0](dec.decoded.ram) propagateClkRstn(self)
def _config(self): self.DATA_WIDTH = Param(8) self.FORMAT = Param( ("AxiS_strFormat" ": hex: 0x", AxiS_strFormatItem(TypePath("data"), 'x', 32 // 4), ", dec: ", AxiS_strFormatItem(TypePath("data"), 'd', BinToBcd.decadic_deciamls_for_bin(32)), " is the value of data from example")) self.INPUT_T = Param(HStruct((uint32_t, "data"), )) self.ENCODING = Param("utf-8")
def _declr(self): addClkRstn(self) with self._paramsShared(): self.axi = Axi4Lite() with self._paramsShared(): # this structure is configuration of interfaces # fields can also be arrays and metaclass can be used # to specify field interface and R/W access to field self.conv = AxiLiteEndpoint( HStruct((uint32_t, "reg0"), (uint32_t, "reg1")))
def _declr(self): addClkRstn(self) with self._paramsShared(): self.axis_out = AxiStream()._m() with self._paramsShared(prefix="CNTRL_"): self.cntrl = Axi4Lite() reg_t = Bits(self.CNTRL_DATA_WIDTH) self.conv = AxiLiteEndpoint( HStruct((reg_t, "enable"), (reg_t, "len")))
def _config(self): OutOfOrderCummulativeOp._config(self) # state in main memory self.MAIN_STATE_T = HStruct( (BIT, "item_valid"), (Bits(32), "key"), (Bits(self.DATA_WIDTH - 32 - 1), "value"), ) # the transaction always just increments the counter # so there is no need for transaction state self.TRANSACTION_STATE_T = HStruct( # if true the key was modified during processing # and we need to recirculate the transaction in pipeline # (which should be done by parent component and it does not happen automatically) (BIT, "reset"), # container of original key and data for insert or match (self.MAIN_STATE_T, "original_data"), # for output 1 if key was same as key in lookup transaction (BIT, "key_match"), (Bits(2), "operation"), # :see: :class:`~.OPERATION` )
def test_singleField(self): MAGIC = 54 MAGIC2 = 0x1000 s = HStruct((uint64_t, "field0")) m = self.buildEnv(s) self.u.dataIn.field0._ag.data.append(MAGIC) self.u.set._ag.data.append(MAGIC2) self.runSim(100 * Time.ns) s_got = m.getStruct(MAGIC2, s) self.assertValEqual(s_got.field0, MAGIC)
def _add_ep(self): strb_w = self.DATA_WIDTH // 8 # [TODO] hotfix, should be self.DATA_WIDTH DATA_FIELD_W = self.CNTRL_DATA_WIDTH LEN_WIDTH = self.m_axi.LEN_WIDTH LOCK_WIDTH = self.m_axi.LOCK_WIDTH mem_space = HStruct( (Bits(32), "id_reg"), # 0x00 (Bits(32), "cmd_and_status"), (Bits(self.ADDR_WIDTH), "addr"), # a or w id (Bits(self.ID_WIDTH), "ar_aw_w_id"), (Bits(32 - int(self.ID_WIDTH)), None), (Bits(2), "burst"), # 0x10 (Bits(32 - 2), None), (Bits(4), "cache"), (Bits(32 - 4), None), (Bits(LEN_WIDTH), "len"), (Bits(32 - LEN_WIDTH), None), (Bits(LOCK_WIDTH), "lock"), (Bits(32 - LOCK_WIDTH), None), (Bits(3), "prot"), # 0x20 (Bits(32 - 3), None), (Bits(3), "size"), (Bits(32 - 3), None), (Bits(4), "qos"), (Bits(32 - 4), None), (Bits(self.ID_WIDTH), "r_id"), (Bits(32 - int(self.ID_WIDTH)), None), (Bits(DATA_FIELD_W), "r_data"), # 0x30 (Bits(2), "r_resp"), (Bits(32 - 2), None), (BIT, "r_last"), (Bits(32 - 1), None), (Bits(self.ID_WIDTH), "b_id"), (Bits(32 - int(self.ID_WIDTH)), None), (Bits(2), "b_resp"), # 0x40 (Bits(32 - 2), None), (Bits(DATA_FIELD_W), "w_data"), (BIT, "w_last"), (Bits(32 - 1), None), (Bits(strb_w), "w_strb"), (Bits(32 - int(strb_w)), None), # 0x50 (Bits(5 * 2), "hs"), (Bits(5 * 2 - 1), None), ) ep = self.axi_ep = AxiLiteEndpoint(mem_space, intfCls=self._cntrlCls) ep.DATA_WIDTH.set(self.CNTRL_DATA_WIDTH) ep.ADDR_WIDTH.set(self.CNTRL_ADDR_WIDTH)
from hwt.hdl.types.struct import HStruct from hwtLib.types.ctypes import uint16_t, uint8_t, uint32_t from hwtLib.types.net.ip import ipv4_t, ipv6_t, l4port_t from hwt.hdl.types.bits import Bits UDP_header_t = HStruct( (l4port_t, "srcp"), (l4port_t, "dstp"), (uint16_t, "length"), (Bits(16), "checksum"), name="UDP_header_t" ) UDP_IPv4PseudoHeader_t = HStruct( (ipv4_t, "src"), (ipv4_t, "dst"), (Bits(8), "zeros"), (uint8_t, "protocol"), (uint16_t, "udpLength") ) + UDP_header_t UDP_IPv4PseudoHeader_t.name = "UDP_IPv4PseudoHeader_t" UDP_IPv6PseudoHeader_t = HStruct( (ipv6_t, "src"), (ipv6_t, "dst"), (uint32_t, "udpLength"), (Bits(24), "zeros"), (Bits(8), "nextHeader") ) + UDP_header_t UDP_IPv6PseudoHeader_t.name = "UDP_IPv6PseudoHeader_t"