def _impl(self): DW = int(self.DATA_WIDTH) polyBits, PW = self.parsePoly(self.POLY, self.POLY_WIDTH) # xorMatrix = buildCrcMatrix_dataMatrix(polyCoefs, PW, DW) # initXorMatrix = buildCrcMatrix_reg0Matrix(polyCoefs, PW, DW) XOROUT = int(self.XOROUT) _INIT = int(self.INIT) initBits = [hBit(selectBit(_INIT, i)) for i in range(PW)] finBits = [hBit(selectBit(XOROUT, i)) for i in range(PW)] # rename to have shorter code _inD = self._sig("d", self.dataIn._dtype) _inD(self.dataIn) inBits = list(iterBits(_inD)) if not self.IN_IS_BIGENDIAN: inBits = reversedEndianity(inBits) outBits = iterBits(self.dataOut) crcMatrix = self.buildCrcXorMatrix(DW, polyBits) res = self.applyCrcXorMatrix( crcMatrix, inBits, initBits, bool(self.REFIN)) if self.REFOUT: res = list(reversed(res)) finBits = reversedBitsInBytes(finBits) for ob, b, fb in zip(outBits, res, finBits): ob(b ^ fb)
def _impl(self): propagateClkRstn(self) r = self._reg START_BIT = hBit(0) STOP_BIT = hBit(1) BITS_TO_SEND = 1 + 8 + 1 BIT_RATE = self.FREQ // self.BAUD assert BIT_RATE >= 1 din = self.dataIn data = r("data", Bits(BITS_TO_SEND)) # data + start bit + stop bit en = r("en", defVal=False) tick, last = ClkBuilder(self, self.clk).timers( [BIT_RATE, BIT_RATE * BITS_TO_SEND], en) If(~en & din.vld, data(Concat(STOP_BIT, din.data, START_BIT)), en(1)).Elif( tick & en, # srl where 1 is shifted from left data(hBit(1)._concat(data[:1])), If( last, en(0), )) din.rd(~en) txd = r("reg_txd", defVal=1) If(tick & en, txd(data[0])) self.txd(txd)
def _impl(self): DW = int(self.DATA_WIDTH) polyBits, PW = self.parsePoly(self.POLY, self.POLY_WIDTH) # xorMatrix = buildCrcMatrix_dataMatrix(polyCoefs, PW, DW) # initXorMatrix = buildCrcMatrix_reg0Matrix(polyCoefs, PW, DW) XOROUT = int(self.XOROUT) _INIT = int(self.INIT) initBits = [hBit(selectBit(_INIT, i)) for i in range(PW)] finBits = [hBit(selectBit(XOROUT, i)) for i in range(PW)] # rename to have shorter code _inD = self._sig("d", self.dataIn._dtype) _inD(self.dataIn) inBits = list(iterBits(_inD)) if not self.IN_IS_BIGENDIAN: inBits = reversedEndianity(inBits) outBits = iterBits(self.dataOut) crcMatrix = self.buildCrcXorMatrix(DW, polyBits) res = self.applyCrcXorMatrix(crcMatrix, inBits, initBits, bool(self.REFIN)) if self.REFOUT: res = list(reversed(res)) finBits = reversedBitsInBytes(finBits) for ob, b, fb in zip(outBits, res, finBits): ob(b ^ fb)
def test_AND_eval(self): for a_in, b_in, out in [(0, 0, 0), (0, 1, 0), (1, 0, 0), (1, 1, 1)]: res = hBit(a_in) & hBit(b_in) self.assertEqual(res.vldMask, 1) self.assertEqual( res.val, out, "a_in %d, b_in %d, out %d" % (a_in, b_in, out))
def test_slice_bits_sig(self): n = RtlNetlist() sig = n.sig("sig", uint8_t, defVal=128) with self.assertRaises(IndexError): self.assertEqual(sig[8], hBit(1)) self.assertEqual(sig[7], hBit(1)) self.assertStrEq(sig[7], "sig(7)") self.assertEqual(sig[1], hBit(0)) self.assertStrEq(sig[1], "sig(1)") self.assertEqual(sig[0], hBit(0)) self.assertStrEq(sig[0], "sig(0)") with self.assertRaises(IndexError): self.assertEqual(sig[-1], hBit(0)) with self.assertRaises(IndexError): self.assertEqual(sig[9:-1], hBit(0)) with self.assertRaises(IndexError): self.assertEqual(sig[9:], hBit(0)) with self.assertRaises(IndexError): self.assertEqual(sig[9:0], hBit(0)) with self.assertRaises(IndexError): self.assertEqual(sig[0:], hBit(0)) with self.assertRaises(IndexError): self.assertEqual(sig[0:0], hBit(0)) self.assertEqual(sig[8:], sig) self.assertStrEq(sig[8:], "sig") self.assertEqual(sig[8:0], sig) self.assertStrEq(sig[8:0], "sig") self.assertEqual(sig[:0], sig) self.assertStrEq(sig[:0], "sig") self.assertEqual(sig[:1], vec(64, 7)) self.assertStrEq(sig[:1], "sig(7DOWNTO1)") self.assertEqual(sig[:2], vec(32, 6)) self.assertStrEq(sig[:2], "sig(7DOWNTO2)") self.assertEqual(sig[:7], vec(1, 1)) self.assertStrEq(sig[:7], "sig(7DOWNTO7)") self.assertEqual(sig[7:6], vec(0, 1)) self.assertStrEq(sig[7:6], "sig(6DOWNTO6)")
def test_slice_bits_sig(self): n = RtlNetlist() sig = n.sig("sig", uint8_t, defVal=128) with self.assertRaises(IndexError): self.assertEqual(sig[8], hBit(1)) self.assertEqual(sig[7], hBit(1)) self.assertStrEq(sig[7], "sig(7)") self.assertEqual(sig[1], hBit(0)) self.assertStrEq(sig[1], "sig(1)") self.assertEqual(sig[0], hBit(0)) self.assertStrEq(sig[0], "sig(0)") with self.assertRaises(IndexError): self.assertEqual(sig[-1], hBit(0)) with self.assertRaises(IndexError): self.assertEqual(sig[9:-1], hBit(0)) with self.assertRaises(IndexError): self.assertEqual(sig[9:], hBit(0)) with self.assertRaises(IndexError): self.assertEqual(sig[9:0], hBit(0)) with self.assertRaises(IndexError): self.assertEqual(sig[0:], hBit(0)) with self.assertRaises(IndexError): self.assertEqual(sig[0:0], hBit(0)) self.assertEqual(sig[8:], sig) self.assertStrEq(sig[8:], "sig") self.assertEqual(sig[8:0], sig) self.assertStrEq(sig[8:0], "sig") self.assertEqual(sig[:0], sig) self.assertStrEq(sig[:0], "sig") self.assertEqual(sig[:1], vec(64, 7)) self.assertStrEq(sig[:1], "sig(7DOWNTO1)") self.assertEqual(sig[:2], vec(32, 6)) self.assertStrEq(sig[:2], "sig(7DOWNTO2)") self.assertEqual(sig[:7], vec(1, 1)) self.assertStrEq(sig[:7], "sig(7DOWNTO7)") self.assertEqual(sig[7:6], vec(0, 1)) self.assertStrEq(sig[7:6], "sig(6DOWNTO6)")
def as_hdl_Assignment(self, a: Assignment): _dst = dst = a.dst assert isinstance(dst, SignalItem) if a.indexes is not None: for i in a.indexes: if isinstance(i, SliceVal): i = i.__copy__() dst = dst[i] src_t = a.src._dtype dst_t = dst._dtype correct = False src = a.src if dst_t == src_t: correct = True else: src = a.src if (isinstance(dst_t, Bits) and isinstance(src_t, Bits)): # std_logic <-> std_logic_vector(0 downto 0) auto conversions if dst_t.bit_length() == src_t.bit_length() == 1: if dst_t.force_vector and not src_t.force_vector: dst = dst[0] correct = True elif not dst_t.force_vector and src_t.force_vector: src = src[0] correct = True elif src_t == BOOL: src = src._ternary(hBit(1), hBit(0)) correct = True elif not src_t.strict_width: if isinstance(src, Value): src = copy(src) if a.indexes: raise NotImplementedError() src._dtype = dst_t correct = True else: raise NotImplementedError() pass if correct: src = self.as_hdl(src) hdl_a = HdlStmAssign(src, self.as_hdl(dst)) hdl_a.is_blocking = _dst.virtual_only return hdl_a raise SerializerException( "%s = %s is not valid assignment\n" " because types are different (%r; %r) " % (dst, a.src, dst._dtype, a.src._dtype))
def test_BitNot(self): for v in [False, True]: res = ~hBit(v) self.assertEqual(res.val, int(not v)) self.assertEqual(res.vldMask, 1) self.assertEqual(res.updateTime, -1)
def ack(self) -> RtlSignal: ack = hBit(1) if self: acks = list(map(lambda x: x[1].ack() & self.selectorIntf.data._eq(x[0]), self)) ack = Or(*acks) return ack & self.selectorIntf.vld
def test_BitNot(self): for v in [False, True]: res = ~hBit(v) self.assertEqual(res.val, int(not v)) self.assertEqual(res.vldMask, 1) self.assertEqual(res.updateTime, -1)
def test_syncSigWithReset(self): c = self.n clk = c.sig("ap_clk") rst = c.sig("ap_rst") a = c.sig("a", clk=clk, syncRst=rst, defVal=0) self.assertEqual(len(a.drivers), 1) _if = a.drivers[0] self.assertIsInstance(_if, If) self.assertIs(_if.cond, clk._onRisingEdge()) self.assertEqual(len(_if.ifTrue), 1) self.assertEqual(_if.ifFalse, None) self.assertEqual(len(_if.elIfs), 0) if_reset = _if.ifTrue[0] self.assertIs(if_reset.cond, rst._isOn()) self.assertEqual(len(if_reset.ifTrue), 1) self.assertEqual(len(if_reset.ifFalse), 1) self.assertEqual(len(if_reset.elIfs), 0) a_reset = if_reset.ifTrue[0] a_next = if_reset.ifFalse[0] self.assertIsInstance(a_reset, Assignment) self.assertEqual(a_reset.src, hBit(0)) self.assertIsInstance(a_next, Assignment) self.assertEqual(a_next.src, a.next)
def ack(self) -> RtlSignal: ack = hBit(1) if self: acks = list( map(lambda x: x[1].ack() & self.selectorIntf.data._eq(x[0]), self)) ack = Or(*acks) return ack & self.selectorIntf.vld
def test_BitsIndexOnSingleBit(self): t = Bits(1) v = t.fromPy(1) with self.assertRaises(TypeError): v[0] t = Bits(1, forceVector=True) v = t.fromPy(1) self.assertEqual(v[0], hBit(1))
def test_BitsIndexOnSingleBit(self): t = Bits(1) v = t.fromPy(1) with self.assertRaises(TypeError): v[0] t = Bits(1, forceVector=True) v = t.fromPy(1) self.assertEqual(v[0], hBit(1))
def connectParts(self, allOutNodes: ListOfOutNodeInfos, words, wordIndexReg: Optional[RtlSignal]): """ Create main datamux from dataIn to dataOut """ for wIndx, transParts, _ in words: # each word index is used and there may be TransParts which are # representation of padding outNondes = ListOfOutNodeInfos() if wordIndexReg is None: isThisWord = hBit(1) else: isThisWord = wordIndexReg._eq(wIndx) for part in transParts: self.connectPart(outNondes, part, isThisWord, hBit(1)) allOutNodes.addWord(wIndx, outNondes)
def _impl(self) -> None: if len(self._masters) > 1: raise NotImplementedError() m_offset, _ = self._masters[0] if m_offset != 0: raise NotImplementedError() m = self.s[0] err = hBit(0) rdack = hBit(0) wrack = hBit(0) AW = int(self.ADDR_WIDTH) wdata = [] for i, (s, (s_offset, s_size, _)) in enumerate(zip(self.m, self._slaves)): connect(m.bus2ip_addr, s.bus2ip_addr, fit=True) s.bus2ip_be(m.bus2ip_be) s.bus2ip_rnw(m.bus2ip_rnw) s.bus2ip_data(m.bus2ip_data) bitsOfSubAddr = int(log2ceil(s_size - 1)) prefix = selectBitRange( s_offset, bitsOfSubAddr, AW - bitsOfSubAddr) cs = self._sig("m_cs_%d" % i) cs(m.bus2ip_addr[AW:bitsOfSubAddr]._eq(prefix)) s.bus2ip_cs(m.bus2ip_cs & cs) err = err | (cs & s.ip2bus_error) rdack = rdack | (cs & s.ip2bus_rdack) wrack = wrack | (cs & s.ip2bus_wrack) wdata.append((cs, s.ip2bus_data)) m.ip2bus_error(err) m.ip2bus_rdack(rdack) m.ip2bus_wrack(wrack) SwitchLogic( [(sel, m.ip2bus_data(data)) for sel, data in wdata], default=m.ip2bus_data(None) )
def _impl(self) -> None: if len(self._masters) > 1: raise NotImplementedError() m_offset, _ = self._masters[0] if m_offset != 0: raise NotImplementedError() m = self.s[0] err = hBit(0) rdack = hBit(0) wrack = hBit(0) AW = int(self.ADDR_WIDTH) wdata = [] for i, (s, (s_offset, s_size, _)) in enumerate(zip(self.m, self._slaves)): connect(m.bus2ip_addr, s.bus2ip_addr, fit=True) s.bus2ip_be(m.bus2ip_be) s.bus2ip_rnw(m.bus2ip_rnw) s.bus2ip_data(m.bus2ip_data) bitsOfSubAddr = int(log2ceil(s_size - 1)) prefix = selectBitRange(s_offset, bitsOfSubAddr, AW - bitsOfSubAddr) cs = self._sig("m_cs_%d" % i) cs(m.bus2ip_addr[AW:bitsOfSubAddr]._eq(prefix)) s.bus2ip_cs(m.bus2ip_cs & cs) err = err | (cs & s.ip2bus_error) rdack = rdack | (cs & s.ip2bus_rdack) wrack = wrack | (cs & s.ip2bus_wrack) wdata.append((cs, s.ip2bus_data)) m.ip2bus_error(err) m.ip2bus_rdack(rdack) m.ip2bus_wrack(wrack) SwitchLogic([(sel, m.ip2bus_data(data)) for sel, data in wdata], default=m.ip2bus_data(None))
def test_ifContSeqEval(self): for a_in, b_in in [(0, 0), (0, 1), (1, 0), (1, 1)]: resT = Bits(2) nl = RtlNetlist() res = nl.sig("res", resT) a = nl.sig("a", BIT) b = nl.sig("b", BIT) def w(val): return res(val) a.defVal = hBit(a_in) b.defVal = hBit(b_in) stm = IfContainer(a & b, ifTrue=[ res(0), ], elIfs=[ (a, [res(1)]), ], ifFalse=[ res(2), ]) if a_in and b_in: expected = 0 elif a_in: expected = 1 else: expected = 2 stm.seqEval() newVal = res._val self.assertEqual(newVal.val, expected) self.assertEqual(newVal.vldMask, 3)
def test_slice_bits(self): v128 = uint8_t.fromPy(128) v1 = uint8_t.fromPy(1) with self.assertRaises(IndexError): self.assertEqual(v128[8], hBit(1)) self.assertEqual(v128[7], hBit(1)) self.assertEqual(v128[1], hBit(0)) self.assertEqual(v128[0], hBit(0)) with self.assertRaises(IndexError): self.assertEqual(v128[-1], hBit(0)) with self.assertRaises(IndexError): self.assertEqual(v128[9:-1], hBit(0)) with self.assertRaises(IndexError): self.assertEqual(v128[9:], hBit(0)) with self.assertRaises(IndexError): self.assertEqual(v128[9:0], hBit(0)) with self.assertRaises(IndexError): self.assertEqual(v128[0:], hBit(0)) with self.assertRaises(IndexError): self.assertEqual(v128[0:0], hBit(0)) self.assertEqual(v128[8:], v128) self.assertEqual(v128[8:0], v128) self.assertEqual(v128[:0], v128) self.assertEqual(v128[:1], vec(64, 7)) self.assertEqual(v128[:2], vec(32, 6)) self.assertEqual(v128[:7], vec(1, 1)) self.assertEqual(v1[1:], vec(1, 1)) self.assertEqual(v1[2:], vec(1, 2)) self.assertEqual(v1[8:], vec(1, 8))
def test_slice_bits(self): v128 = uint8_t.fromPy(128) v1 = uint8_t.fromPy(1) with self.assertRaises(IndexError): self.assertEqual(v128[8], hBit(1)) self.assertEqual(v128[7], hBit(1)) self.assertEqual(v128[1], hBit(0)) self.assertEqual(v128[0], hBit(0)) with self.assertRaises(IndexError): self.assertEqual(v128[-1], hBit(0)) with self.assertRaises(IndexError): self.assertEqual(v128[9:-1], hBit(0)) with self.assertRaises(IndexError): self.assertEqual(v128[9:], hBit(0)) with self.assertRaises(IndexError): self.assertEqual(v128[9:0], hBit(0)) with self.assertRaises(IndexError): self.assertEqual(v128[0:], hBit(0)) with self.assertRaises(IndexError): self.assertEqual(v128[0:0], hBit(0)) self.assertEqual(v128[8:], v128) self.assertEqual(v128[8:0], v128) self.assertEqual(v128[:0], v128) self.assertEqual(v128[:1], vec(64, 7)) self.assertEqual(v128[:2], vec(32, 6)) self.assertEqual(v128[:7], vec(1, 1)) self.assertEqual(v1[1:], vec(1, 1)) self.assertEqual(v1[2:], vec(1, 2)) self.assertEqual(v1[8:], vec(1, 8))
def ack(self) -> RtlSignal: if self.wordIndexReg is None: def getAck(x): return x[1].ack() else: def getAck(x): return self.wordIndexReg._eq(x[0]) & x[1].ack() acks = list(map(getAck, self.words)) if acks: return Or(*acks) else: return hBit(1)
def test_ifContSeqEval(self): for a_in, b_in in [(0, 0), (0, 1), (1, 0), (1, 1)]: resT = Bits(2) nl = RtlNetlist() res = nl.sig("res", resT) a = nl.sig("a", BIT) b = nl.sig("b", BIT) def w(val): return res(val) a.defVal = hBit(a_in) b.defVal = hBit(b_in) stm = IfContainer(a & b, ifTrue=[res(0), ], elIfs=[(a, [res(1)]), ], ifFalse=[res(2), ] ) if a_in and b_in: expected = 0 elif a_in: expected = 1 else: expected = 2 stm.seqEval() newVal = res._val self.assertEqual(newVal.val, expected) self.assertEqual(newVal.vldMask, 3)
def _impl(self): # prepare constants and bit arrays for inputs DW = int(self.DATA_WIDTH) polyBits, PW = CrcComb.parsePoly(self.POLY, self.POLY_WIDTH) XOROUT = int(self.XOROUT) finBits = [hBit(selectBit(XOROUT, i)) for i in range(PW)] # rename "dataIn_data" to "d" to make code shorter _d = self.wrapWithName(self.dataIn.data, "d") inBits = list(iterBits(_d)) if not self.IN_IS_BIGENDIAN: inBits = reversedEndianity(inBits) state = self._reg("c", Bits(self.POLY_WIDTH), self.INIT) stateBits = list(iterBits(state)) # build xor tree for CRC computation crcMatrix = CrcComb.buildCrcXorMatrix(DW, polyBits) res = CrcComb.applyCrcXorMatrix( crcMatrix, inBits, stateBits, bool(self.REFIN)) # next state logic # wrap crc next signals to separate signal to have nice code stateNext = [] for i, crcbit in enumerate(res): b = self.wrapWithName(crcbit, "crc_%d" % i) stateNext.append(b) If(self.dataIn.vld, # regNext is in format 0 ... N, we need to reverse it to litle # endian state(Concat(*reversed(stateNext))) ) # output connection if self.REFOUT: finBits = reversed(finBits) self.dataOut( Concat(*[rb ^ fb for rb, fb in zip(iterBits(state), finBits)] ) ) else: self.dataOut(state ^ Concat(*finBits))
def _impl(self): propagateClkRstn(self) r = self._reg START_BIT = hBit(0) STOP_BIT = hBit(1) BITS_TO_SEND = 1 + 8 + 1 BIT_RATE = self.FREQ // self.BAUD assert BIT_RATE >= 1 din = self.dataIn data = r("data", Bits(BITS_TO_SEND)) # data + start bit + stop bit en = r("en", defVal=False) tick, last = ClkBuilder(self, self.clk).timers( [BIT_RATE, BIT_RATE * BITS_TO_SEND], en) If(~en & din.vld, data(Concat(STOP_BIT, din.data, START_BIT)), en(1) ).Elif(tick & en, # srl where 1 is shifted from left data(hBit(1)._concat(data[:1])), If(last, en(0), ) ) din.rd(~en) txd = r("reg_txd", defVal=1) If(tick & en, txd(data[0]) ) self.txd(txd)
def matchHandler(self, mem): key = self.match out = self._reg("out_reg", self.out.data._dtype, defVal=0) outNext = out.next outVld = self._reg("out_vld_reg", defVal=0) key.rd(1) outVld(key.vld) for i in range(int(self.ITEMS)): outNext[i](mem[i]._eq(Concat(key.data, hBit(1)))) self.out.data(out) self.out.vld(outVld)
def _impl(self): a = self.a b = self.b self.c( Concat( hBit(1), vec(7, 3), a != b, a < b, a <= b, a._eq(b), a >= b, a > b, vec(0, 22), ))
def _impl(self): a = self.a b = self.b self.c( Concat( hBit(1), vec(7, 3), a != b, a < b, a <= b, a._eq(b), a >= b, a > b, vec(0, 22), ) )
def ack(self) -> RtlSignal: if self.wordIndexReg is None: def getAck(x): return x[1].ack() else: def getAck(x): return self.wordIndexReg._eq(x[0]) & x[1].ack() acks = list(map(getAck, self.words)) if acks: return Or(*acks) else: return hBit(1)
def hw_raise(self, exception: InHwError, pending_flag: Optional[RtlSignalBase] = None, raising_flag: Optional[RtlSignalBase] = None): """ Construct a logic to raise an exception in generated hardware. This creates a flag and IO for exception handling status. :param pending_flag: An optional flag which should be set to 1 if exception was raised in some previous clock cycle an it has not beed catched yet. :param raising_flag: An optional flag which should be set to 1 if exception exception is beeing raised in this clock cycle. :attention: The arguments specified in the exception has to remain stable until the excetion is handled. :returns: An expression which triggers the exception handling. """ assert isinstance(exception, InHwError) err_name = exception.__class__.__name__ p = self.parent # add a raise interace in impl phase of the Unit instance raise_intf = ExceptionHandleInterface(exception)._m() self._Unit_registerPublicIntfInImpl( raise_intf, AbstractComponentBuilder._findSuitableName(self, err_name)) object.__setattr__(p, raise_intf._name, raise_intf) # create a flag which means that the error is waiting err_pending = p._reg(f"{self.name:s}_{err_name:s}_pending", def_val=0) if pending_flag is not None: pending_flag(err_pending) If( err_pending, err_pending(~raise_intf.rd), ).Else(err_pending(raise_intf.vld & ~raise_intf.rd), ) raise_intf.vld._sig._nop_val = hBit(0) if exception.hw_args: for a_src, a_dst in zip(exception.hw_args, raise_intf.args): connect_to_MonitorIntf(a_src, a_dst) if raising_flag is not None: raising_flag(raise_intf.vld) return [ raise_intf.vld(1), ]
def ackForSlave(self, slave): """ :return: driver of valid signal for slave """ otherSlaves = where(self.slaves, lambda x: x is not slave) extra, skip = self.getExtraAndSkip(slave) conds = [ *map(self.vld, self.masters), *map(self.rd, otherSlaves), *extra ] if conds: v = And(*conds) else: v = hBit(1) if skip is not None: v = v & ~skip return v
def ackForMaster(self, master): """ :return: driver of ready signal for master """ otherMasters = where(self.masters, lambda x: x is not master) extra, skip = self.getExtraAndSkip(master) conds = [ *map(self.vld, otherMasters), *map(self.rd, self.slaves), *extra ] if conds: r = And(*conds) else: r = hBit(1) if skip is not None: r = r & ~skip return r
def ackForMaster(self, master): """ :return: driver of ready signal for master """ otherMasters = where(self.masters, lambda x: x is not master) extra, skip = self.getExtraAndSkip(master) conds = [*map(self.vld, otherMasters), *map(self.rd, self.slaves), *extra] if conds: r = And(*conds) else: r = hBit(1) if skip is not None: r = r & ~skip return r
def ackForSlave(self, slave): """ :return: driver of valid signal for slave """ otherSlaves = where(self.slaves, lambda x: x is not slave) extra, skip = self.getExtraAndSkip(slave) conds = [*map(self.vld, self.masters), *map(self.rd, otherSlaves), *extra] if conds: v = And(*conds) else: v = hBit(1) if skip is not None: v = v & ~skip return v
def _impl(self): # prepare constants and bit arrays for inputs DW = int(self.DATA_WIDTH) polyBits, PW = CrcComb.parsePoly(self.POLY, self.POLY_WIDTH) XOROUT = int(self.XOROUT) finBits = [hBit(selectBit(XOROUT, i)) for i in range(PW)] # rename "dataIn_data" to "d" to make code shorter _d = self.wrapWithName(self.dataIn.data, "d") inBits = list(iterBits(_d)) if not self.IN_IS_BIGENDIAN: inBits = reversedEndianity(inBits) state = self._reg("c", Bits(self.POLY_WIDTH), self.INIT) stateBits = list(iterBits(state)) # build xor tree for CRC computation crcMatrix = CrcComb.buildCrcXorMatrix(DW, polyBits) res = CrcComb.applyCrcXorMatrix(crcMatrix, inBits, stateBits, bool(self.REFIN)) # next state logic # wrap crc next signals to separate signal to have nice code stateNext = [] for i, crcbit in enumerate(res): b = self.wrapWithName(crcbit, "crc_%d" % i) stateNext.append(b) If( self.dataIn.vld, # regNext is in format 0 ... N, we need to reverse it to litle # endian state(Concat(*reversed(stateNext)))) # output connection if self.REFOUT: finBits = reversed(finBits) self.dataOut( Concat(*[rb ^ fb for rb, fb in zip(iterBits(state), finBits)])) else: self.dataOut(state ^ Concat(*finBits))
def _impl(self): s = self._sig wclk_in = s("wclk_in") mem = self._ctx.sig("mem", Bits(DATA_WIDTH + 1), defVal=hBit(None)._concat(self.INIT)) a_in = s("a_in", Bits(6)) d_in = s("d_in") we_in = s("we_in") wclk_in(self.wclk ^ self.IS_WCLK_INVERTED) we_in(self.we) a_in(Concat(self.a5, self.a4, self.a3, self.a2, self.a1, self.a0)) d_in(self.d) # ReadBehavior self.o(mem[a_in]) # WriteBehavior If(wclk_in._onRisingEdge() & we_in, mem[a_in](d_in) )
def applyCrcXorMatrix(cls, crcMatrix: List, inBits: List, stateBits: List, refin: bool) -> List: if refin: inBits = reversedBitsInBytes(inBits) #stateBits = list(reversed(stateBits)) outBits = [] for (stateMask, dataMask) in crcMatrix: v = hBit(0) # neutral value for XOR assert len(stateMask) == len(stateBits) for useBit, b in zip(stateMask, stateBits): if useBit: v = v ^ b assert len(dataMask) == len(inBits), (len(dataMask), len(inBits)) for useBit, b in zip(dataMask, inBits): if useBit: v = v ^ b outBits.append(v) assert len(outBits) == len(stateBits) return outBits
def applyCrcXorMatrix(cls, crcMatrix: List, inBits: List, stateBits: List, refin: bool) -> List: if refin: inBits = reversedBitsInBytes(inBits) #stateBits = list(reversed(stateBits)) outBits = [] for (stateMask, dataMask) in crcMatrix: v = hBit(0) # neutral value for XOR assert len(stateMask) == len(stateBits) for useBit, b in zip(stateMask, stateBits): if useBit: v = v ^ b assert len(dataMask) == len(inBits), (len(dataMask), len(inBits)) for useBit, b in zip(dataMask, inBits): if useBit: v = v ^ b outBits.append(v) assert len(outBits) == len(stateBits) return outBits
def _config(self): self.INIT = Param(vec(0, DATA_WIDTH)) self.IS_WCLK_INVERTED = Param(hBit(0))
def getAckOfOthers(self: OutNodeInfo, others: List[OutNodeInfo]): ackOfOthers = [hBit(1) if o is self else o.ack() for o in others] if ackOfOthers: return And(*ackOfOthers) else: return hBit(1)
def ack(self) -> RtlSignal: if self: return And(*map(lambda x: x.ack(), self)) else: return hBit(1)
def getAckOfOthers(self: OutNodeInfo, others: List[OutNodeInfo]): ackOfOthers = [hBit(1) if o is self else o.ack() for o in others] if ackOfOthers: return And(*ackOfOthers) else: return hBit(1)
] xorTable = [(None, None, None), (None, 0, None), (None, 1, None), (0, None, None), (0, 0, 0), (0, 1, 1), (1, 1, 0), (s0, 1, ~s0), (s0, 0, s0), (1, s0, ~s0), (0, s0, s0), ] bitvals = { 1: hBit(1), 0: hBit(0), None: hBit(None), s0: s1, ~ s0: ~s1 } boolvals = { 1: hBool(1), 0: hBool(0), None: hBool(None), s0: s0, ~ s0: ~s0 }
def connectPart(self, hsNondes: list, part: Union[TransPart, ChoicesOfFrameParts], en: Union[RtlSignal, bool], exclusiveEn: Optional[RtlSignal]=hBit(1)): """ Create datamux for one word in main fsm and colect metainformations for handshake logic :param hsNondes: list of nodes of handshaked logic """ busVld = self.dataIn.valid tToIntf = self.dataOut._fieldsToInterfaces if isinstance(part, ChoicesOfFrameParts): parentIntf = tToIntf[part.origin.parent.origin] try: sel = self._tmpRegsForSelect[parentIntf] except KeyError: sel = HsBuilder(self, parentIntf._select).buff().end self._tmpRegsForSelect[parentIntf] = sel unionGroup = ExclusieveListOfHsNodes(sel) # for unions for choice in part: # connect data signals of choices and collect info about # streams intfOfChoice = tToIntf[choice.tmpl.origin] selIndex, isSelected, isSelectValid = self.choiceIsSelected( intfOfChoice) _exclusiveEn = isSelectValid & isSelected & exclusiveEn unionMemberPart = ListOfOutNodeInfos() for p in choice: self.connectPart(unionMemberPart, p, en, _exclusiveEn) unionGroup.append(selIndex, unionMemberPart) hsNondes.append(unionGroup) if part.isLastPart(): # synchronization of reading from _select register for unions selNode = InNodeInfo(sel, en) else: selNode = InNodeReadOnlyInfo(sel, en) hsNondes.append(selNode) return if part.isPadding: return fPartSig = self.getInDataSignal(part) fieldInfo = part.tmpl.origin try: signalsOfParts = self._signalsOfParts[part.tmpl] except KeyError: signalsOfParts = [] self._signalsOfParts[part.tmpl] = signalsOfParts if part.isLastPart(): # connect all parts in this group to output stream signalsOfParts.append(fPartSig) intf = self.dataOut._fieldsToInterfaces[fieldInfo] intf.data(self.byteOrderCare( Concat( *reversed(signalsOfParts) )) ) on = OutNodeInfo(self, intf, en, exclusiveEn) hsNondes.append(on) else: dataVld = busVld & en & exclusiveEn # part is in some word as last part, we have to store its value to register # until the last part arrive fPartReg = self._reg("%s_part_%d" % (fieldInfo.name, len(signalsOfParts)), fPartSig._dtype) If(dataVld, fPartReg(fPartSig) ) signalsOfParts.append(fPartReg)
def ack(self) -> RtlSignal: if self: return And(*map(lambda x: x.ack(), self)) else: return hBit(1)
def test_AND_eval(self): for a_in, b_in, out in [(0, 0, 0), (0, 1, 0), (1, 0, 0), (1, 1, 1)]: res = hBit(a_in) & hBit(b_in) self.assertEqual(res.vldMask, 1) self.assertEqual(res.val, out, "a_in %d, b_in %d, out %d" % (a_in, b_in, out))
] xorTable = [ (None, None, None), (None, 0, None), (None, 1, None), (0, None, None), (0, 0, 0), (0, 1, 1), (1, 1, 0), (s0, 1, ~s0), (s0, 0, s0), (1, s0, ~s0), (0, s0, s0), ] bitvals = {1: hBit(1), 0: hBit(0), None: hBit(None), s0: s1, ~s0: ~s1} boolvals = {1: hBool(1), 0: hBool(0), None: hBool(None), s0: s0, ~s0: ~s0} class OperatorTC(unittest.TestCase): def setUp(self): unittest.TestCase.setUp(self) self.n = RtlNetlist() def test_BoolNot(self): for v in [True, False]: res = ~hBool(v) self.assertEqual(res.val, not v) self.assertEqual(res.vldMask, 1) self.assertEqual(res.updateTime, -1)