import cocotb from cocotb.triggers import Timer, RisingEdge from cocotb.drivers import BusDriver from cocotb.result import ReturnValue class SataHalfWord(BusDriver): ''' Every 8 bits -> 10 on phy line ''' def __init__(self, data, control): self.data = [].append(data) self.control = [].append(control) class SataPhyDriver(BusDriver): _signals = ['txp_out', 'txn_out', 'rxp_in', 'rxp_out'] def __init__(self, entity, name, clock, gen): ''' The clock shall be serial ''' BusDriver.__init__(self, entity, name, clock) # outcoming elecidle flag self.txelecidle = 1 # queue of *parallel* values to send self.sq = [] # stream trace of received parallel values self.rq = [] # sata generation (~ clock frequency) self.gen = gen self.driveBit(0) # Queues management section def addHalfWord(self, hword): self.sq = self.sq.append(hword) # elecidle management section def setElecIdle(self): self.txelecidle = 1 def unsetElecIdle(self): self.txelecidle = 0 # Data send section def driveBit(self, value): if txelecidle: self.bus.txp_out.setimmediatevalue('z') self.bus.txn_out.setimmediatevalue('z') elif value == 1: self.bus.txp_out.setimmediatevalue(1) self.bus.txn_out.setimmediatevalue(0) elif value == 0: self.bus.txp_out.setimmediatevalue(0) self.bus.txn_out.setimmediatevalue(1) else: self.bus.txp_out.setimmediatevalue(value) self.bus.txn_out.setimmediatevalue(value) yield RisingEdge(self.clock) def serial(self, parallel): for i in range(9, -1, -1): value = '{0:b}'.format(parallel)[i] driveBit(value) def sendQueue(self): for hword in self.sq: serial(self, hword) class SataPhyMonitor(BusMonitor): _signals = ['txp_out', 'txn_out', 'rxp_in', 'rxp_out'] def __init__(self, *args, **kwargs): BusMOnitor.__init__(self, *arggs, **kwargs) # Data receive section def getBit(self) yield RisingEdge(self.clock) return self.bus.txp_out.getValue() def getHalfWord(self): hword = '' for i in range(9, -1, -1): hword.append(getBit) return hword def alignReciever(self): ''' look for a comma character in a bitstream returns running disparity value, when comma occurs ''' # get an initial hword hword = '' for i in range(9, -1, -1): hword.append(getBit) # shift until we meet a comma while True: if hword == '0011111010': disparity = 1 break elif hword == '1100000101': disparity = 0 break else hword.pop(1) hword.append(getBit) return disparity def decodeHalfWord(self): pass # oob def monitorElecidle(self):