Exemple #1
0
class UARTCommWriter(BusDriver):

    _signals = ["wr_stb", "wr_data", "wr_busy"]

    def __init__(self, entity, name, clock):
        BusDriver.__init__(self, entity, name, clock)
        self.bus.wr_stb     <=  0
        self.bus.wr_data    <=  0
        self.write_data_busy = Lock("%s_wbusy" % name)


    @cocotb.coroutine
    def write(self, data):
        yield self.write_data_busy.acquire()
        i = 0
        while i < len(data):
            yield ReadOnly()
            yield RisingEdge(self.clock)
            if not (self.bus.wr_busy.value):
                if i == len(data):
                    break
                self.bus.wr_data    <=  data[i]
                self.bus.wr_stb     <=  1
                i = i + 1

            yield RisingEdge(self.clock)
            self.bus.wr_stb     <=  0

        self.write_data_busy.release()
Exemple #2
0
class semaphore():
    def __init__(self, count=1):
        self.max_count = count
        self.count = count
        self.lock = Lock("sem_lock")
        self.locked = False

    async def get(self, count=1):
        if self.count > count:
            self.count -= count
            await Timer(0, "NS")
        elif count > self.max_count:
            raise Exception("Tried to get {} > max count {}".format(
                count, self.max_count))
        else:
            await self.lock.acquire()
            self.locked = True
            self.count -= count

    def put(self, count=1):
        if self.count < self.max_count:
            self.count += count
            if self.locked is True:
                self.locked = False
                self.lock.release()

    def try_get(self, count=1):
        if self.count >= count:
            self.count -= count
            return True
        return False
Exemple #3
0
    def __init__(self,
                 entity,
                 name,
                 clock,
                 memory,
                 callback=None,
                 event=None,
                 big_endian=False,
                 **kwargs):

        BusDriver.__init__(self, entity, name, clock, **kwargs)
        self.clock = clock

        self.big_endian = big_endian
        self.bus.ARREADY.setimmediatevalue(1)
        self.bus.RVALID.setimmediatevalue(0)
        self.bus.RLAST.setimmediatevalue(0)
        self.bus.AWREADY.setimmediatevalue(1)
        self._memory = memory

        self.write_address_busy = Lock("%s_wabusy" % name)
        self.read_address_busy = Lock("%s_rabusy" % name)
        self.write_data_busy = Lock("%s_wbusy" % name)

        cocotb.fork(self._read_data())
        cocotb.fork(self._write_data())
Exemple #4
0
 def __init__(self, entity, name, clock):
     BusDriver.__init__(self, entity, name, clock)
     self.busy_channel = Lock("%s_busy"%(name))
     self.bus.wr.setimmediatevalue(0)
     self.bus.rd.setimmediatevalue(0)
     _float_signals((self.bus.addr, self.bus.din))
     self.name = name
Exemple #5
0
    def __init__(self, entity: SimHandleBase, name: str, clock: SimHandleBase,
                 **kwargs: Any):
        BusDriver.__init__(self, entity, name, clock, **kwargs)

        # Drive some sensible defaults (setimmediatevalue to avoid x asserts)
        self.bus.AWVALID.setimmediatevalue(0)
        self.bus.WVALID.setimmediatevalue(0)
        self.bus.ARVALID.setimmediatevalue(0)
        self.bus.BREADY.setimmediatevalue(1)
        self.bus.RREADY.setimmediatevalue(1)

        # Set the default value (0) for the unsupported signals, which
        # translate to:
        #  * Transaction IDs to 0
        #  * Region identifier to 0
        #  * Normal (non-exclusive) access
        #  * Device non-bufferable access
        #  * Unprivileged, secure data access
        #  * No QoS
        unsupported_signals = [
            "AWID", "AWREGION", "AWLOCK", "AWCACHE", "AWPROT", "AWQOS",
            "ARID", "ARREGION", "ARLOCK", "ARCACHE", "ARPROT", "ARQOS"]
        for signal in unsupported_signals:
            try:
                getattr(self.bus, signal).setimmediatevalue(0)
            except AttributeError:
                pass

        # Mutex for each channel to prevent contention
        self.write_address_busy = Lock(name + "_awbusy")
        self.read_address_busy = Lock(name + "_arbusy")
        self.write_data_busy = Lock(name + "_wbusy")
        self.read_data_busy = Lock(name + "_rbusy")
        self.write_response_busy = Lock(name + "_bbusy")
 def __init__(self, scope):
     self.listener_l = []
     self.lock = Lock()
     self.ev = Event()
     self.scope = scope
     cocotb.fork(self.run())
     pass
Exemple #7
0
class UARTCommReader(BusDriver):

    _signals = ["rd_data", "rd_stb"]

    def __init__(self, entity, name, clock):
        BusDriver.__init__(self, entity, name, clock)
        self.read_data_busy = Lock("%s_wbusy" % name)
        self.data = Array('B')

    @cocotb.coroutine
    def read(self, size):
        yield self.read_data_busy.acquire()
        self.data = Array('B')
        count = 0
        while count < size:
            yield ReadOnly()
            yield RisingEdge(self.clock)
            if self.bus.rd_stb.value == 1:
                self.data.append(self.bus.rd_data.value)
                count += 1

        yield RisingEdge(self.clock)
        self.read_data_busy.release()

    def get_data(self):
        return self.data
class VideoOutBus(BusDriver):
    """
    Generate RGB Video Signals
    """

    _signals = ["RGB", "HSYNC", "VSYNC", "DATA_EN", "HBLANK", "VBLANK"]

    def __init__(self, entity, name, clock, width, height, hblank, vblank):
        BusDriver.__init__(self, entity, name, clock)

        #Drive some sensible defaults
        self.bus.RGB.setimmediatevalue(0)
        self.bus.HSYNC.setimmediatevalue(0)
        self.bus.VSYNC.setimmediatevalue(0)
        self.bus.DATA_EN.setimmediatevalue(0)

        self.bus.HBLANK.setimmediatevalue(1)
        self.bus.VBLANK.setimmediatevalue(1)

        self.width = width
        self.height = height
        self.hblank = hblank
        self.vblank = vblank

        self.write_lock = Lock("%s_busy" % name)

    @cocotb.coroutine
    def write(self, video):
        #print "Video: %s" % video
        yield self.write_lock.acquire()
        yield RisingEdge(self.clock)
        self.bus.DATA_EN <= 1
        for frame in video:
            for line in frame:
                for pixel in line:
                    self.bus.HBLANK <= 0
                    self.bus.VBLANK <= 0
                    self.bus.HSYNC <= 1
                    self.bus.VSYNC <= 1

                    self.bus.RGB <= pixel
                    yield RisingEdge(self.clock)

                #Horizontal Blank
                self.bus.HSYNC <= 0
                self.bus.HBLANK <= 1
                for i in range(self.hblank):
                    yield RisingEdge(self.clock)

                self.bus.VSYNC <= 0
                self.bus.VBLANK <= 1

            #Vertical Blank
            for i in range(self.vblank):
                yield RisingEdge(self.clock)

        self.bus.DATA_EN <= 0
        self.write_lock.release()
Exemple #9
0
    def __init__(self, entity, name, clock):
        BusDriver.__init__(self, entity, name, clock)

        # Drive some sensible defaults (setimmediatevalue to avoid x asserts)
        self.bus.rd_en.setimmediatevalue(0)
        self.bus.wr_strb.setimmediatevalue(0)

        # Mutex for each channel that we master to prevent contention
        self.write_busy = Lock("%s_wbusy" % name)
        self.read_busy = Lock("%s_rbusy" % name)
class BlockFIFOReadPath(BusDriver):
    _signals = ["RDY", "ACT", "STB", "SIZE", "DATA"]
    _optional_signals = ["INACTIVE"]

    def __init__(self, entity, name, clock):
        BusDriver.__init__(self, entity, name, clock)
        self.bus.ACT.setimmediatevalue(0)
        self.bus.STB.setimmediatevalue(0)
        self.busy = Lock("%s_busy" % name)

    @cocotb.coroutine
    def read(self, size=None):
        """
        If set to None just keep reading
        """
        fifo_size = 0
        data = []
        yield self.busy.acquire()
        pos = 0
        while (size is None) or (pos < size):
            print "Within read loop: Pos: %d" % pos
            yield ReadOnly()
            #while True:
            while self.bus.ACT == 0:
                if self.bus.RDY == 1:
                    yield RisingEdge(self.clock)
                    self.bus.ACT <= 1
                yield RisingEdge(self.clock)
                yield ReadOnly()

            print "Got act!"
            yield RisingEdge(self.clock)
            count = 0
            yield ReadOnly()
            fifo_size = int(self.bus.SIZE)
            #print "FIFO Size: %d" % fifo_size
            while count < fifo_size:
                #print "Count: %d" % count
                yield RisingEdge(self.clock)
                self.bus.STB <= 1
                yield ReadOnly()
                if size is not None:
                    d = int(self.bus.DATA)
                    #print "Data: %08X" % d
                    data.append(d)
                count += 1
                pos += 1
            yield RisingEdge(self.clock)
            self.bus.STB <= 0
            self.bus.ACT <= 0
            yield RisingEdge(self.clock)

        self.busy.release()

        raise ReturnValue(data)
class BlockFIFOReadPath(BusDriver):
    _signals = ["RDY", "ACT", "STB", "SIZE", "DATA"]
    _optional_signals = ["INACTIVE"]

    def __init__(self, entity, name, clock):
        BusDriver.__init__(self, entity, name, clock)
        self.bus.ACT.setimmediatevalue(0)
        self.bus.STB.setimmediatevalue(0)
        self.busy = Lock("%s_busy" % name)

    @cocotb.coroutine
    def read(self, size=None):
        """
        If set to None just keep reading
        """
        fifo_size = 0
        data = []
        yield self.busy.acquire()
        pos = 0
        while (size is None) or (pos < size):
            print "Within read loop: Pos: %d" % pos
            yield ReadOnly()
            #while True:
            while self.bus.ACT == 0:
                if self.bus.RDY == 1:
                    yield RisingEdge(self.clock)
                    self.bus.ACT    <=  1
                yield RisingEdge(self.clock)
                yield ReadOnly()

            print "Got act!"
            yield RisingEdge(self.clock)
            count = 0
            yield ReadOnly()
            fifo_size = int(self.bus.SIZE)
            #print "FIFO Size: %d" % fifo_size
            while count < fifo_size:
                #print "Count: %d" % count
                yield RisingEdge(self.clock)
                self.bus.STB    <=  1
                yield ReadOnly()
                if size is not None:
                    d = int(self.bus.DATA)
                    #print "Data: %08X" % d
                    data.append(d)
                count   += 1
                pos     += 1
            yield RisingEdge(self.clock)
            self.bus.STB    <=  0
            self.bus.ACT    <=  0
            yield RisingEdge(self.clock)

        self.busy.release()

        raise ReturnValue(data)
    def __init__(self, entity, name, clock):
        BusDriver.__init__(self, entity, name, clock)
        self.bus.EN.setimmediatevalue(0)
        self.bus.ADR.setimmediatevalue(0)
        self.bus.WR_RD.setimmediatevalue(0)
        self.bus.BYTE_EN.setimmediatevalue(0)
        self.bus.WR_DATA.setimmediatevalue(0)

        # Mutex for each channel that we master to prevent contention
        self.rd_busy = Lock("%s_wbusy" % name)
        self.wr_busy = Lock("%s_rbusy" % name)
Exemple #13
0
class AXI4StreamSlave(BusDriver):

    _signals = ["tvalid", "tready", "tdata"]
    _optional_signals = ["tlast", "tkeep", "tstrb", "tid", "tdest", "tuser"]

    def __init__(self, entity, name, clock, width = 32):
        BusDriver.__init__(self, entity, name, clock)
        self.width = width
        self.bus.tready <= 0;
        self.read_data_busy = Lock("%s_wbusy" % name)
        self.data = []

    @cocotb.coroutine
    def read(self, wait_for_valid=True):
        """Read a packe of data from the Axi Ingress stream"""
        yield self.read_data_busy.acquire()
        try:
            # clear the data register and signal we're ready to receive some data
            self.data = []
            self.bus.tready <=  1

            if wait_for_valid:
                while not self.bus.tvalid.value:
                    yield RisingEdge(self.clock)

                # while self.bus.tvalid.value and self.bus.tready.value:
                while True:

                    if self.bus.tvalid.value and self.bus.tready.value:
                        self.data.append(self.bus.tdata.value.integer)

                        if self.bus.tlast.value:
                            self.bus.tready <= 0
                            break
                    
                    yield RisingEdge(self.clock)
                
                
            else:
                self.bus.tready <= 1

                while not self.bus.tlast.value:
                    
                    if self.bus.tvalid.value and self.bus.tready.value:
                        self.data.append(self.bus.tdata.value.integer)
                    
                    yield RisingEdge(self.clock)

                self.bus.tready <= 0
        
        finally:
            self.read_data_busy.release()
                
class PPFIFOWritePath(BusDriver):
    _signals = ["RDY", "ACT", "STB", "SIZE", "DATA"]
    _optional_signals = ["STARVED"]

    def __init__(self, entity, name, clock):
        BusDriver.__init__(self, entity, name, clock)
        self.bus.ACT.setimmediatevalue(0)
        self.bus.DATA.setimmediatevalue(0)
        self.bus.STB.setimmediatevalue(0)
        self.busy = Lock("%s_busy" % name)

    @cocotb.coroutine
    def write(self, data):
        yield self.busy.acquire()
        pos = 0
        count = 0
        total_length = len(data)
        rdy = 0

        while pos < total_length:
            while True:
                yield ReadOnly()
                rdy = int(self.bus.RDY)
                if rdy != 0:
                    yield RisingEdge(self.clock)
                    break
                yield RisingEdge(self.clock)

            if (rdy & 0x01) > 0:
                self.bus.ACT <= 0x01
            else:
                self.bus.ACT <= 0x02

            yield RisingEdge(self.clock)
            length  = total_length
            if length > int(self.bus.SIZE):
                length = self.bus.SIZE

            print "Length: %d" % length

            for d in data[pos:length]:
                self.bus.STB    <=  1
                self.bus.DATA   <=  d
                yield RisingEdge(self.clock)

            self.bus.STB        <=  0
            pos += length
            yield RisingEdge(self.clock)
            self.bus.ACT        <=  0
            yield RisingEdge(self.clock)

        self.busy.release()
Exemple #15
0
class PPFIFOWritePath(BusDriver):
    _signals = ["RDY", "ACT", "STB", "SIZE", "DATA"]
    _optional_signals = ["STARVED"]

    def __init__(self, entity, name, clock):
        BusDriver.__init__(self, entity, name, clock)
        self.bus.ACT.setimmediatevalue(0)
        self.bus.DATA.setimmediatevalue(0)
        self.bus.STB.setimmediatevalue(0)
        self.busy = Lock("%s_busy" % name)

    @cocotb.coroutine
    def write(self, data):
        yield self.busy.acquire()
        pos = 0
        count = 0
        total_length = len(data)
        rdy = 0

        while pos < total_length:
            while True:
                yield ReadOnly()
                rdy = int(self.bus.RDY)
                if rdy != 0:
                    yield RisingEdge(self.clock)
                    break
                yield RisingEdge(self.clock)

            if (rdy & 0x01) > 0:
                self.bus.ACT <= 0x01
            else:
                self.bus.ACT <= 0x02

            yield RisingEdge(self.clock)
            length = total_length
            if length > int(self.bus.SIZE):
                length = self.bus.SIZE

            print "Length: %d" % length

            for d in data[pos:length]:
                self.bus.STB <= 1
                self.bus.DATA <= d
                yield RisingEdge(self.clock)

            self.bus.STB <= 0
            pos += length
            yield RisingEdge(self.clock)
            self.bus.ACT <= 0
            yield RisingEdge(self.clock)

        self.busy.release()
Exemple #16
0
    def __init__(self, entity, name, clock):
        BusDriver.__init__(self, entity, name, clock)

        # Drive some sensible defaults (setimmediatevalue to avoid x asserts)
        self.bus.AWVALID.setimmediatevalue(0)
        self.bus.WVALID.setimmediatevalue(0)
        self.bus.ARVALID.setimmediatevalue(0)
        self.bus.BREADY.setimmediatevalue(1)
        self.bus.RREADY.setimmediatevalue(1)

        # Mutex for each channel that we master to prevent contention
        self.write_address_busy = Lock("%s_wabusy" % name)
        self.read_address_busy = Lock("%s_rabusy" % name)
        self.write_data_busy = Lock("%s_wbusy" % name)
Exemple #17
0
    def __init__(self, entity, name, clock):
        BusDriver.__init__(self, entity, name, clock)

        # Drive some sensible defaults (setimmediatevalue to avoid x asserts)
        self.bus.AWVALID.setimmediatevalue(0)
        self.bus.WVALID.setimmediatevalue(0)
        self.bus.ARVALID.setimmediatevalue(0)
        self.bus.BREADY.setimmediatevalue(1)
        self.bus.RREADY.setimmediatevalue(1)

        # Mutex for each channel that we master to prevent contention
        self.write_address_busy = Lock("%s_wabusy" % name)
        self.read_address_busy = Lock("%s_rabusy" % name)
        self.write_data_busy = Lock("%s_wbusy" % name)
Exemple #18
0
    def __init__(self, entity, name, clock, width=32):
        BusDriver.__init__(self, entity, name, clock)
        #Drive default values onto bus
        self.width = width
        self.strobe_width = width / 8
        self.bus.TVALID.setimmediatevalue(0)
        self.bus.TLAST.setimmediatevalue(0)
        self.bus.TDATA.setimmediatevalue(0)
        self.bus.TKEEP.setimmediatevalue(0)
        self.bus.TID.setimmediatevalue(0)
        self.bus.TDEST.setimmediatevalue(0)
        self.bus.TUSER.setimmediatevalue(0)

        self.write_data_busy = Lock("%s_wbusy" % name)
    def __init__(self,
                 entity,
                 name,
                 clock):
        BusDriver.__init__(self, entity, name, clock)
        self.bus.EN.setimmediatevalue(0)
        self.bus.ADR.setimmediatevalue(0)
        self.bus.WR_RD.setimmediatevalue(0)
        self.bus.BYTE_EN.setimmediatevalue(0)
        self.bus.WR_DATA.setimmediatevalue(0)

        # Mutex for each channel that we master to prevent contention
        self.rd_busy = Lock("%s_wbusy" % name)
        self.wr_busy = Lock("%s_rbusy" % name)
    def __init__(self,
                 entity,
                 name,
                 clock,
                 wr_fifo_name = "WR",
                 wr_fifo_clk = None,
                 wr_fifo_clk_period = 10,
                 rd_fifo_name = "RD",
                 rd_fifo_clk = None,
                 rd_fifo_clk_period = 10):
        BusDriver.__init__(self, entity, name, clock)
        if wr_fifo_clk is None:
            wr_fifo_clk = entity.WR_CLK
        if rd_fifo_clk is None:
            rd_fifo_clk = entity.RD_CLK

        self.bus.EN.setimmediatevalue(0)
        self.bus.ADR.setimmediatevalue(0)
        self.bus.ADR_FIXED.setimmediatevalue(0)
        self.bus.ADR_WRAP.setimmediatevalue(0)
        self.bus.WR_RD.setimmediatevalue(0)
        self.bus.COUNT.setimmediatevalue(0)

        # Mutex for each channel that we master to prevent contention
        self.command_busy = Lock("%s_wabusy" % name)
        cocotb.fork(Clock(wr_fifo_clk, wr_fifo_clk_period).start())
        cocotb.fork(Clock(rd_fifo_clk, rd_fifo_clk_period).start())

        self.write_fifo = PPFIFOWritePath(entity, wr_fifo_name, wr_fifo_clk)
        self.read_fifo = PPFIFOReadPath(entity, rd_fifo_name, rd_fifo_clk)
Exemple #21
0
async def test_trigger_lock(dut):
    """
    Simple test that checks to see if context management is kept. The
    resource value is checked at certain points if it equals the expected
    amount, which is easily predictable if the context management is working.
    """
    resource = 0
    lock = Lock()

    async def co():
        nonlocal resource
        await Timer(10, "ns")
        async with lock:
            for i in range(4):
                await Timer(10, "ns")
                resource += 1

    cocotb.fork(co())
    async with lock:
        for i in range(4):
            resource += 1
            await Timer(10, "ns")
    assert resource == 4
    await Timer(10, "ns")
    async with lock:
        assert resource == 8
Exemple #22
0
    def __init__(self, entity, name, clock, rdlag=None, blag=None):
        BusDriver.__init__(self, entity, name, clock)
        self.name = name
        # set read and write back channels simulation lag between AXI sets valid and host responds with
        # ready. If None - drive these signals  
        self.log.debug ("MAXIGPMaster.__init__(): super done")

        if rdlag is None:
            self.bus.rready.setimmediatevalue(1)
        else:    
            self.bus.xtra_rdlag.setimmediatevalue(rdlag)
        if blag is None:
            self.bus.bready.setimmediatevalue(1)
        else:    
            self.bus.xtra_blag.setimmediatevalue(blag)
        self.bus.awvalid.setimmediatevalue(0)
        self.bus.wvalid.setimmediatevalue(0)
        self.bus.arvalid.setimmediatevalue(0)
        #just in case - set unimplemented in Zynq
        self.bus.arlock.setimmediatevalue(0)
        self.bus.arcache.setimmediatevalue(0)
        self.bus.arprot.setimmediatevalue(0)
        self.bus.arqos.setimmediatevalue(0)
        self.bus.awlock.setimmediatevalue(0)
        self.bus.awcache.setimmediatevalue(0)
        self.bus.awprot.setimmediatevalue(0)
        self.bus.awqos.setimmediatevalue(0)
        self.busy_channels = {}
        self.log.debug ("MAXIGPMaster.__init__(): pre-lock done")

        #Locks on each subchannel
        for chn in self._channels:
            self.log.debug ("MAXIGPMaster.__init__(): chn = %s"%(chn))
            self.busy_channels[chn]=Lock("%s_%s_busy"%(name,chn))
    def __init__(self, entity, name, clock, width, height, hblank, vblank):
        BusDriver.__init__(self, entity, name, clock)

        #Drive some sensible defaults
        self.bus.RGB.setimmediatevalue(0)
        self.bus.HSYNC.setimmediatevalue(0)
        self.bus.VSYNC.setimmediatevalue(0)
        self.bus.DATA_EN.setimmediatevalue(0)

        self.bus.HBLANK.setimmediatevalue(1)
        self.bus.VBLANK.setimmediatevalue(1)

        self.width = width
        self.height = height
        self.hblank = hblank
        self.vblank = vblank

        self.write_lock = Lock("%s_busy" % name)
Exemple #24
0
class NESPPU(BusDriver):
    _signals = [
        "X_OUT", "Y_OUT", "Y_NEXT_OUT", "PULSE_OUT", "VBLANK", "SYS_PALETTE"
    ]

    def __init__(self, entity, name, clock, width, height):
        BusDriver.__init__(self, entity, name, clock)
        self.width = width
        self.height = height
        self.bus.SYS_PALETTE.setimmediatevalue(0)
        self.busy = Lock("%s_busy" % name)

    @cocotb.coroutine
    def run(self, data=None):

        if data is None:
            #Generate a test image
            data = [[0] * self.width] * self.height
            for y in range(self.height):
                for x in range(self.width):
                    #data[y][x] = x % 0x03F
                    data[y][x] = 0x00

        yield self.busy.acquire()

        print "Wait for pulse out to go high"
        while True:
            yield ReadOnly()
            if not self.bus.PULSE_OUT:
                print "Pulse out went high"
                yield RisingEdge(self.clock)
                continue
            yield RisingEdge(self.clock)

            ypos = int(self.bus.Y_OUT)
            xpos = int(self.bus.X_OUT)
            self.bus.SYS_PALETTE <= data[ypos][xpos]

        print "Exiting run..."
        self.busy.release()
Exemple #25
0
    def __init__(self, entity, name, clock, width=32):
        BusDriver.__init__(self, entity, name, clock)
        #drive default values onto bus
        self.width = width
        self.strobe_width = width / 8
        self.bus.tvalid.setimmediatevalue(0)
        self.bus.tlast.setimmediatevalue(0)
        self.bus.tdata.setimmediatevalue(0)

        if hasattr(self.bus, 'tkeep'):
            self.bus.tkeep.setimmediatevalue(0)

        if hasattr(self.bus, 'tid'):
            self.bus.tid.setimmediatevalue(0)

        if hasattr(self.bus, 'tdest'):
            self.bus.tdest.setimmediatevalue(0)

        if hasattr(self.bus, 'tuser'):
            self.bus.tuser.setimmediatevalue(0)

        self.write_data_busy = Lock("%s_wbusy" % name)
Exemple #26
0
    def __init__(self, entity, name, clock, **kwargs):
        BusDriver.__init__(self, entity, name, clock)

        # Drive some sensible defaults (setimmediatevalue to avoid x asserts)
        self.bus.AWVALID.setimmediatevalue(0)
        self.bus.WVALID.setimmediatevalue(0)
        self.bus.ARVALID.setimmediatevalue(0)
        self.bus.BREADY.setimmediatevalue(1)
        self.bus.RREADY.setimmediatevalue(1)

        # Mutex for each channel that we master to prevent contention
        self.write_address_busy = Lock("%s_wabusy" % name)
        self.read_address_busy = Lock("%s_rabusy" % name)
        self.write_data_busy = Lock("%s_wbusy" % name)

        config = kwargs.pop('config', {})
        self.config = AXI4LiteMaster._default_config.copy()

        for configoption, value in config.items():
            self.config[configoption] = value
            self.log.debug("Setting config option %s to %s" %
                           (configoption, str(value)))
Exemple #27
0
    def __init__(self, entity, name, clock, **kwargs):
        BusDriver.__init__(self, entity, name, clock)

        # Drive some sensible defaults (setimmediatevalue to avoid x asserts)
        self.bus.AWVALID.setimmediatevalue(0)
        self.bus.WVALID.setimmediatevalue(0)
        self.bus.ARVALID.setimmediatevalue(0)
        self.bus.BREADY.setimmediatevalue(1)
        self.bus.RREADY.setimmediatevalue(1)

        # Mutex for each channel that we master to prevent contention
        self.write_address_busy = Lock("%s_wabusy" % name)
        self.read_address_busy = Lock("%s_rabusy" % name)
        self.write_data_busy = Lock("%s_wbusy" % name)

        config = kwargs.pop('config', {})
        self.config = AXI4LiteMaster._default_config.copy()

        for configoption, value in config.items():
            self.config[configoption] = value
            self.log.debug("Setting config option %s to %s" %
                           (configoption, str(value)))
Exemple #28
0
async def test_except_lock(dut):
    """
    Checks to see if exceptions cause the lock to be
    released.
    """
    lock = Lock()
    try:
        async with lock:
            raise RuntimeError()
    except RuntimeError:
        pass
    async with lock:
        pass
Exemple #29
0
class GlobalBuffer(BusDriver):
    _signals = ["rd_addr", "rd_data", "rd_en", "wr_addr", "wr_data", "wr_strb"]

    def __init__(self, entity, name, clock):
        BusDriver.__init__(self, entity, name, clock)

        # Drive some sensible defaults (setimmediatevalue to avoid x asserts)
        self.bus.rd_en.setimmediatevalue(0)
        self.bus.wr_strb.setimmediatevalue(0)

        # Mutex for each channel that we master to prevent contention
        self.write_busy = Lock("%s_wbusy" % name)
        self.read_busy = Lock("%s_rbusy" % name)

    @cocotb.coroutine
    def write(self, address, data, byte_enable=0b11111111, sync=True):
        """Write a value to an address.
        """
        if sync:
            yield RisingEdge(self.clock)

        yield self.write_busy.acquire()

        self.bus.wr_addr <= address
        self.bus.wr_data <= data
        self.bus.wr_strb <= byte_enable

        yield RisingEdge(self.clock)

        self.bus.wr_strb <= 0
        self.write_busy.release()

    @cocotb.coroutine
    def read(self, address, sync=True):
        """Read from an address.
        Returns:
            BinaryValue: The read data value.
        """
        if sync:
            yield RisingEdge(self.clock)

        yield self.read_busy.acquire()

        self.bus.rd_addr <= address
        self.bus.rd_en <= 1

        yield RisingEdge(self.clock)

        self.bus.rd_en <= 0
        self.read_busy.release()

        # 2 cycle read latency
        yield RisingEdge(self.clock)

        yield ReadOnly()
        data = self.bus.rd_data

        raise ReturnValue(data)
 def __init__(self, entity, name, clock, width = 100, height = 100, y_fp = 10, y_bp = 10, x_fp = 10, x_bp = 10):
     BusDriver.__init__(self, entity, name, clock)
     self.width = width
     self.height = height
     self.y_fp = y_fp
     self.y_bp = y_bp
     self.x_fp = x_fp
     self.x_bp = x_bp
     self.bus.SOF_STB.setimmediatevalue(0)
     self.bus.HSYNC.setimmediatevalue(0)
     self.bus.RED.setimmediatevalue(0)
     self.bus.BLUE.setimmediatevalue(0)
     self.bus.GREEN.setimmediatevalue(0)
     self.busy = Lock("%s_busy" % name)
Exemple #31
0
    def __init__(self, entity, name, clock, width=32):
        BusDriver.__init__(self, entity, name, clock)
        #Drive default values onto bus
        self.width = width
        self.strobe_width = width / 8
        self.bus.TVALID.setimmediatevalue(0)
        self.bus.TLAST.setimmediatevalue(0)
        self.bus.TDATA.setimmediatevalue(0)
        self.bus.TKEEP.setimmediatevalue(0)
        self.bus.TID.setimmediatevalue(0)
        self.bus.TDEST.setimmediatevalue(0)
        self.bus.TUSER.setimmediatevalue(0)

        self.write_data_busy = Lock("%s_wbusy" % name)
Exemple #32
0
 def __init__(self,
              entity,
              name,
              clock,
              width=100,
              height=100,
              y_fp=10,
              y_bp=10,
              x_fp=10,
              x_bp=10):
     BusDriver.__init__(self, entity, name, clock)
     self.width = width
     self.height = height
     self.y_fp = y_fp
     self.y_bp = y_bp
     self.x_fp = x_fp
     self.x_bp = x_bp
     self.bus.SOF_STB.setimmediatevalue(0)
     self.bus.HSYNC.setimmediatevalue(0)
     self.bus.RED.setimmediatevalue(0)
     self.bus.BLUE.setimmediatevalue(0)
     self.bus.GREEN.setimmediatevalue(0)
     self.busy = Lock("%s_busy" % name)
Exemple #33
0
class AXI4StreamSlave(BusDriver):

    _signals = ["TVALID", "TREADY", "TDATA"]
    _optional_signals = ["TLAST", "TKEEP", "TSTRB", "TID", "TDEST", "TUSER"]

    def __init__(self, entity, name, clock, width = 32):
        BusDriver.__init__(self, entity, name, clock)
        self.width = width
        self.bus.TREADY <= 0;
        self.read_data_busy = Lock("%s_wbusy" % name)
        self.data = []

    @cocotb.coroutine
    def read(self, wait_for_valid = False):
        """Read a packe of data from the Axi Ingress stream"""
        yield self.read_data_busy.acquire()
        yield RisingEdge(self.clock)

        if wait_for_valid:
            while not self.bus.TVALID.value:
                #cocotb.log.info("Valid Not Detected")
                yield RisingEdge(self.clock)

            #cocotb.log.info("Found valid!")
            yield RisingEdge(self.clock)
            self.bus.TREADY <=  1

            while self.bus.TVALID.value:
                yield RisingEdge(self.clock)
                self.data.extend(self.bus.TDATA.value)
                if self.bus.TLAST.value:
                    break
        else:
            self.bus.TREADY <= 1

            while True:
                yield ReadOnly()
                yield RisingEdge(self.clock)
                if self.bus.TVALID.value:
                    cocotb.log.debug("Found Valid")
                    break
                yield RisingEdge(self.clock)


            while self.bus.TVALID.value:
                yield RisingEdge(self.clock)
                self.data.extend(self.bus.TDATA.value)
                if self.bus.TLAST.value:
                    break
Exemple #34
0
class AXI4StreamSlave(BusDriver):

    _signals = ["TVALID", "TREADY", "TDATA"]
    _optional_signals = ["TLAST", "TKEEP", "TSTRB", "TID", "TDEST", "TUSER"]

    def __init__(self, entity, name, clock, width = 32):
        BusDriver.__init__(self, entity, name, clock)
        self.width = width
        self.bus.TREADY <= 0;
        self.read_data_busy = Lock("%s_wbusy" % name)
        self.data = []

    @cocotb.coroutine
    def read(self, wait_for_valid = False):
        """Read a packe of data from the Axi Ingress stream"""
        yield self.read_data_busy.acquire()
        yield RisingEdge(self.clock)

        if wait_for_valid:
            while not self.bus.TVALID.value:
                #cocotb.log.info("Valid Not Detected")
                yield RisingEdge(self.clock)

            #cocotb.log.info("Found valid!")
            yield RisingEdge(self.clock)
            self.bus.TREADY <=  1

            while self.bus.TVALID.value:
                yield RisingEdge(self.clock)
                self.data.extend(self.bus.TDATA.value)
                if self.bus.TLAST.value:
                    break
        else:
            self.bus.TREADY <= 1

            while True:
                yield ReadOnly()
                yield RisingEdge(self.clock)
                if self.bus.TVALID.value:
                    cocotb.log.debug("Found Valid")
                    break
                yield RisingEdge(self.clock)


            while self.bus.TVALID.value:
                yield RisingEdge(self.clock)
                self.data.extend(self.bus.TDATA.value)
                if self.bus.TLAST.value:
                    break
Exemple #35
0
class PSBus(BusDriver):
    """
    Small subset of Zynq registers, used to access SAXI_HP* registers
    """
    _signals=[ # i/o from the DUT side
        "clk",    # output    
        "addr",   # input [31:0]
        "wr",     # input
        "rd",     # input
        "din",    # input [31:0]
        "dout"]   #output [31:0]
    def __init__(self, entity, name, clock):
        BusDriver.__init__(self, entity, name, clock)
        self.busy_channel = Lock("%s_busy"%(name))
        self.bus.wr.setimmediatevalue(0)
        self.bus.rd.setimmediatevalue(0)
        _float_signals((self.bus.addr, self.bus.din))
        self.name = name

    @cocotb.coroutine
    def write_reg(self,addr,data):
        yield self.busy_channel.acquire()
        #Only wait if it is too late (<1/2 cycle)
        if not int(self.clock):
            yield RisingEdge(self.clock)
        self.bus.addr <= addr
        self.bus.din <= data
        self.bus.wr <= 1
        yield RisingEdge(self.clock)
        self.bus.wr <= 0
        _float_signals((self.bus.addr, self.bus.din))
        self.busy_channel.release()

    @cocotb.coroutine
    def read_reg(self,addr):
        yield self.busy_channel.acquire()
        #Only wait if it is too late (<1/2 cycle)
        if not int(self.clock):
            yield RisingEdge(self.clock)
        self.bus.addr <= addr
        self.bus.rd <= 1
        yield RisingEdge(self.clock)
        try:
            data = self.bus.dout.value.integer
        except:
            bv = self.bus.dout.value
            bv.binstr = re.sub("[^1]","0",bv.binstr)
            data = bv.integer
        self.bus.rd <= 0
        _float_signals((self.bus.addr, ))
        self.busy_channel.release()
        raise ReturnValue(data)
    def __init__(self, entity, name, clock, width, height, hblank, vblank):
        BusDriver.__init__(self, entity, name, clock)

        #Drive some sensible defaults
        self.bus.RGB.setimmediatevalue(0)
        self.bus.HSYNC.setimmediatevalue(0)
        self.bus.VSYNC.setimmediatevalue(0)
        self.bus.DATA_EN.setimmediatevalue(0)

        self.bus.HBLANK.setimmediatevalue(1)
        self.bus.VBLANK.setimmediatevalue(1)

        self.width = width
        self.height = height
        self.hblank = hblank
        self.vblank = vblank

        self.write_lock = Lock("%s_busy" % name)
Exemple #37
0
class AXI4LiteMaster(BusDriver):
    """
    AXI4-Lite Master

    TODO: Kill all pending transactions if reset is asserted...
    """
    _signals = ["AWVALID", "AWADDR", "AWREADY",        # Write address channel
                "WVALID", "WREADY", "WDATA", "WSTRB",  # Write data channel
                "BVALID", "BREADY", "BRESP",           # Write response channel
                "ARVALID", "ARADDR", "ARREADY",        # Read address channel
                "RVALID", "RREADY", "RRESP", "RDATA"]  # Read data channel

    _default_config = {
        "address_latency" : 0,
        "data_latency" : 0,
    }

    def __init__(self, entity, name, clock, **kwargs):
        BusDriver.__init__(self, entity, name, clock)

        # Drive some sensible defaults (setimmediatevalue to avoid x asserts)
        self.bus.AWVALID.setimmediatevalue(0)
        self.bus.WVALID.setimmediatevalue(0)
        self.bus.ARVALID.setimmediatevalue(0)
        self.bus.BREADY.setimmediatevalue(1)
        self.bus.RREADY.setimmediatevalue(1)

        # Mutex for each channel that we master to prevent contention
        self.write_address_busy = Lock("%s_wabusy" % name)
        self.read_address_busy = Lock("%s_rabusy" % name)
        self.write_data_busy = Lock("%s_wbusy" % name)

        config = kwargs.pop('config', {})
        self.config = AXI4LiteMaster._default_config.copy()

        for configoption, value in config.items():
            self.config[configoption] = value
            self.log.debug("Setting config option %s to %s" %
                           (configoption, str(value)))
    @cocotb.coroutine
    def _send_write_address(self, address, delay=0):
        """
        Send the write address, with optional delay (in clocks)
        """
        yield self.write_address_busy.acquire()
        for cycle in range(max(self.config["address_latency"], delay)):
            yield RisingEdge(self.clock)

        self.bus.AWADDR <= address
        self.bus.AWVALID <= 1

        while True:
            yield ReadOnly()
            if self.bus.AWREADY.value:
                break
            yield RisingEdge(self.clock)
        yield RisingEdge(self.clock)
        self.bus.AWVALID <= 0
        self.write_address_busy.release()

    @cocotb.coroutine
    def _send_write_data(self, data, delay=0, byte_enable=0xF):
        """
        Send the write address, with optional delay (in clocks)
        """
        yield self.write_data_busy.acquire()
        for cycle in range(max(self.config["data_latency"], delay)):
            yield RisingEdge(self.clock)

        self.bus.WDATA <= data
        self.bus.WVALID <= 1
        self.bus.WSTRB <= byte_enable

        while True:
            yield ReadOnly()
            if self.bus.WREADY.value:
                break
            yield RisingEdge(self.clock)
        yield RisingEdge(self.clock)
        self.bus.WVALID <= 0
        self.write_data_busy.release()

    @cocotb.coroutine
    def write(self, address, value, byte_enable=0xf, address_latency=0,
              data_latency=0, sync=True):
        """
        Write a value to an address.

        Args:
            address (int): The address to write to
            value (int): The data value to write
            byte_enable (int, optional): Which bytes in value to actually write.
                Default is to write all bytes.
            address_latency (int, optional): Delay before setting the address (in clock cycles).
                Default is no delay.
            data_latency (int, optional): Delay before setting the data value (in clock cycles).
                Default is no delay.
            sync (bool, optional): Wait for rising edge on clock initially.
                Defaults to True.
            
        Returns:
            BinaryValue: The write response value
            
        Raises:
            AXIProtocolError: If write response from AXI is not ``OKAY``
        """
        if sync:
            yield RisingEdge(self.clock)

        c_addr = cocotb.fork(self._send_write_address(address,
                                                      delay=address_latency))
        c_data = cocotb.fork(self._send_write_data(value,
                                                   byte_enable=byte_enable,
                                                   delay=data_latency))

        if c_addr:
            yield c_addr.join()
        if c_data:
            yield c_data.join()

        # Wait for the response
        while True:
            yield ReadOnly()
            if self.bus.BVALID.value and self.bus.BREADY.value:
                result = self.bus.BRESP.value
                self.log.debug("Writing to address 0x%08x with 0x%08x" %
                               (address, value))
                break
            yield RisingEdge(self.clock)

        yield RisingEdge(self.clock)

        if int(result):
            raise AXIProtocolError("Write to address 0x%08x failed with BRESP: %d"
                               % (address, int(result)))

        raise ReturnValue(result)

    @cocotb.coroutine
    def read(self, address, sync=True):
        """
        Read from an address.
        
        Args:
            address (int): The address to read from
            sync (bool, optional): Wait for rising edge on clock initially.
                Defaults to True.
            
        Returns:
            BinaryValue: The read data value
            
        Raises:
            AXIProtocolError: If read response from AXI is not ``OKAY``
        """
        if sync:
            yield RisingEdge(self.clock)

        self.bus.ARADDR <= address
        self.bus.ARVALID <= 1

        while True:
            yield ReadOnly()
            if self.bus.ARREADY.value:
                break
            yield RisingEdge(self.clock)

        yield RisingEdge(self.clock)
        self.bus.ARVALID <= 0

        while True:
            yield ReadOnly()
            if self.bus.RVALID.value and self.bus.RREADY.value:
                data = self.bus.RDATA.value
                result = self.bus.RRESP.value
                self.log.debug("Data at address 0x%08x is 0x%08x" %
                               (address, data))
                break
            yield RisingEdge(self.clock)

        if int(result):
            raise AXIProtocolError("Read address 0x%08x failed with RRESP: %d" %
                               (address, int(result)))

        raise ReturnValue(data)

    def __len__(self):
        return 2**len(self.bus.ARADDR)
Exemple #38
0
class AXI4StreamMaster(BusDriver):

    _signals = ["TVALID", "TREADY", "TDATA"]  # Write data channel
    _optional_signals = ["TLAST", "TKEEP", "TSTRB", "TID", "TDEST", "TUSER"]

    def __init__(self, entity, name, clock, width=32):
        BusDriver.__init__(self, entity, name, clock)
        #Drive default values onto bus
        self.width = width
        self.strobe_width = width / 8
        self.bus.TVALID.setimmediatevalue(0)
        self.bus.TLAST.setimmediatevalue(0)
        self.bus.TDATA.setimmediatevalue(0)
        self.bus.TKEEP.setimmediatevalue(0)
        self.bus.TID.setimmediatevalue(0)
        self.bus.TDEST.setimmediatevalue(0)
        self.bus.TUSER.setimmediatevalue(0)

        self.write_data_busy = Lock("%s_wbusy" % name)

    @cocotb.coroutine
    def write(self, data, byte_enable=-1, keep=1, tid=0, dest=0, user=0):
        """
        Send the write data, with optional delay
        """
        yield self.write_data_busy.acquire()
        self.bus.TVALID <=  0
        self.bus.TLAST  <=  0
        self.bus.TID    <=  tid
        self.bus.TDEST  <=  dest
        self.bus.TUSER  <=  user
        self.bus.TSTRB  <=  (1 << self.strobe_width) - 1
        if byte_enable == -1:
            byte_enable = (self.width >> 3) - 1

        #Wait for the slave to assert tready
        while True:
            yield ReadOnly()
            if self.bus.TREADY.value:
                break
            yield RisingEdge(self.clock)

        yield RisingEdge(self.clock)
        #every clock cycle update the data
        for i in range (len(data)):
            self.bus.TVALID <=  1
            self.bus.TDATA  <= data[i]
            if i >= len(data) - 1:
                self.bus.TLAST  <=  1;
            yield ReadOnly()
            if not self.bus.TREADY.value:
                while True:
                    yield RisingEdge(self.clock)
                    yield ReadOnly()
                    if self.bus.TREADY.value:
                        yield RisingEdge(self.clock)
                        break
                continue
            yield RisingEdge(self.clock)

        self.bus.TLAST  <=  0;
        self.bus.TVALID <=  0;
        yield RisingEdge(self.clock)
        self.write_data_busy.release()
        self.bus.TSTRB  <=  0
 def __init__(self, entity, name, clock):
     BusDriver.__init__(self, entity, name, clock)
     self.read_data_busy = Lock("%s_wbusy" % name)
     self.data = Array('B')
Exemple #40
0
class AXI4LiteMaster(BusDriver):
    """
    AXI4-Lite Master

    TODO: Kill all pending transactions if reset is asserted...
    """
    _signals = ["AWVALID", "AWADDR", "AWREADY",         # Write address channel
                "WVALID", "WREADY", "WDATA", "WSTRB",   # Write data channel
                "BVALID", "BREADY", "BRESP",            # Write response channel
                "ARVALID", "ARADDR", "ARREADY",         # Read address channel
                "RVALID", "RREADY", "RRESP", "RDATA"]   # Read data channel

    def __init__(self, entity, name, clock):
        BusDriver.__init__(self, entity, name, clock)

        # Drive some sensible defaults (setimmediatevalue to avoid x asserts)
        self.bus.AWVALID.setimmediatevalue(0)
        self.bus.WVALID.setimmediatevalue(0)
        self.bus.ARVALID.setimmediatevalue(0)
        self.bus.BREADY.setimmediatevalue(1)
        self.bus.RREADY.setimmediatevalue(1)

        # Mutex for each channel that we master to prevent contention
        self.write_address_busy = Lock("%s_wabusy" % name)
        self.read_address_busy = Lock("%s_rabusy" % name)
        self.write_data_busy = Lock("%s_wbusy" % name)


    @cocotb.coroutine
    def _send_write_address(self, address, delay=0):
        """
        Send the write address, with optional delay
        """
        yield self.write_address_busy.acquire()
        for cycle in range(delay):
            yield RisingEdge(self.clock)

        self.bus.AWADDR         <= address
        self.bus.AWVALID        <= 1

        while True:
            yield ReadOnly()
            if self.bus.AWREADY.value:
                break
            yield RisingEdge(self.clock)
        yield RisingEdge(self.clock)
        self.bus.AWVALID        <= 0
        self.write_address_busy.release()

    @cocotb.coroutine
    def _send_write_data(self, data, delay=0, byte_enable=0xF):
        """
        Send the write address, with optional delay
        """
        yield self.write_data_busy.acquire()
        for cycle in range(delay):
            yield RisingEdge(self.clock)

        self.bus.WDATA          <= data
        self.bus.WVALID         <= 1
        self.bus.WSTRB          <= byte_enable

        while True:
            yield ReadOnly()
            if self.bus.WREADY.value:
                break
            yield RisingEdge(self.clock)
        yield RisingEdge(self.clock)
        self.bus.WVALID        <= 0
        self.write_data_busy.release()


    @cocotb.coroutine
    def write(self, address, value, byte_enable=0xf, address_latency=0, data_latency=0):
        """
        Write a value to an address.

        The *_latency KWargs allow control over the delta 
        """
        

        c_addr = cocotb.fork(self._send_write_address(address, delay=address_latency))
        c_data = cocotb.fork(self._send_write_data(value, byte_enable=byte_enable, delay=data_latency))



        if c_addr:
            yield c_addr.join()
        if c_data:
            yield c_data.join()

        # Wait for the response
        while True:
            yield ReadOnly()
            if self.bus.BVALID.value and self.bus.BREADY.value:
                result = self.bus.BRESP.value
                break
            yield RisingEdge(self.clock)
        
        yield RisingEdge(self.clock)  
        
        if int(result):
            raise AXIReadError("Write to address 0x%08x failed with BRESP: %d" %(
                address, int(result)))

        raise ReturnValue(result)


    @cocotb.coroutine
    def read(self, address, sync=True):
        """
        Read from an address.
        """
        if sync:
            yield RisingEdge(self.clock)

        self.bus.ARADDR         <= address
        self.bus.ARVALID        <= 1

        while True:
            yield ReadOnly()
            if self.bus.ARREADY.value:
                break
            yield RisingEdge(self.clock)

        yield RisingEdge(self.clock)
        self.bus.ARVALID        <= 0

        while True:
            yield ReadOnly()
            if self.bus.RVALID.value and self.bus.RREADY.value:
                data = self.bus.RDATA.value
                result = self.bus.RRESP.value
                break
            yield RisingEdge(self.clock)

        if int(result):
            raise AXIReadError("Read address 0x%08x failed with RRESP: %d" %(
                address, int(result)))

        raise ReturnValue(data)
class CommandMaster (BusDriver):
    _signals = ["EN", "ERROR", "ACK", "STATUS", "INTERRUPT",
                "ADR", "WR_RD", "BYTE_EN",
                "WR_DATA", "RD_DATA"]

    def __init__(self,
                 entity,
                 name,
                 clock):
        BusDriver.__init__(self, entity, name, clock)
        self.bus.EN.setimmediatevalue(0)
        self.bus.ADR.setimmediatevalue(0)
        self.bus.WR_RD.setimmediatevalue(0)
        self.bus.BYTE_EN.setimmediatevalue(0)
        self.bus.WR_DATA.setimmediatevalue(0)

        # Mutex for each channel that we master to prevent contention
        self.rd_busy = Lock("%s_wbusy" % name)
        self.wr_busy = Lock("%s_rbusy" % name)

    @cocotb.coroutine
    def write(self, address, data, byte_en = 0xF):
        yield self.wr_busy.acquire()
        yield RisingEdge(self.clock)
        self.bus.ADR        <= address
        self.bus.WR_RD      <=  1
        self.bus.EN         <=  1
        self.bus.ADR        <=  address
        self.bus.WR_DATA    <=  data
        self.bus.BYTE_EN    <=  byte_en

        yield RisingEdge(self.clock)

        yield ReadOnly()
        rdy = int(self.bus.ACK)

        while (rdy == 0):
            yield RisingEdge(self.clock)
            yield ReadOnly()
            rdy = int(self.bus.ACK)

        yield RisingEdge(self.clock)
        self.bus.EN         <=  0
        self.wr_busy.release()

    @cocotb.coroutine
    def read(self, address):
        data = []
        yield self.rd_busy.acquire()
        self.bus.ADR        <= address
        self.bus.EN         <= 1
        self.bus.WR_RD      <= 0
        self.bus.BYTE_EN    <= 0
        yield RisingEdge(self.clock)

        yield ReadOnly()
        rdy = int(self.bus.ACK)

        while (rdy == 0):
            yield RisingEdge(self.clock)
            yield ReadOnly()
            rdy = int(self.bus.ACK)

        yield RisingEdge(self.clock)
        self.bus.EN         <=  0
Exemple #42
0
class AXI4LiteMaster(BusDriver):
    """AXI4-Lite Master.

    TODO: Kill all pending transactions if reset is asserted.
    """

    _signals = [
        "AWVALID",
        "AWADDR",
        "AWREADY",  # Write address channel
        "WVALID",
        "WREADY",
        "WDATA",
        "WSTRB",  # Write data channel
        "BVALID",
        "BREADY",
        "BRESP",  # Write response channel
        "ARVALID",
        "ARADDR",
        "ARREADY",  # Read address channel
        "RVALID",
        "RREADY",
        "RRESP",
        "RDATA"
    ]  # Read data channel

    def __init__(self, entity, name, clock, **kwargs):
        BusDriver.__init__(self, entity, name, clock, **kwargs)

        # Drive some sensible defaults (setimmediatevalue to avoid x asserts)
        self.bus.AWVALID.setimmediatevalue(0)
        self.bus.WVALID.setimmediatevalue(0)
        self.bus.ARVALID.setimmediatevalue(0)
        self.bus.BREADY.setimmediatevalue(1)
        self.bus.RREADY.setimmediatevalue(1)

        # Mutex for each channel that we master to prevent contention
        self.write_address_busy = Lock("%s_wabusy" % name)
        self.read_address_busy = Lock("%s_rabusy" % name)
        self.write_data_busy = Lock("%s_wbusy" % name)

    @cocotb.coroutine
    def _send_write_address(self, address, delay=0):
        """
        Send the write address, with optional delay (in clocks)
        """
        yield self.write_address_busy.acquire()
        for cycle in range(delay):
            yield RisingEdge(self.clock)

        self.bus.AWADDR <= address
        self.bus.AWVALID <= 1

        while True:
            yield ReadOnly()
            if self.bus.AWREADY.value:
                break
            yield RisingEdge(self.clock)
        yield RisingEdge(self.clock)
        self.bus.AWVALID <= 0
        self.write_address_busy.release()

    @cocotb.coroutine
    def _send_write_data(self, data, delay=0, byte_enable=0xF):
        """Send the write address, with optional delay (in clocks)."""
        yield self.write_data_busy.acquire()
        for cycle in range(delay):
            yield RisingEdge(self.clock)

        self.bus.WDATA <= data
        self.bus.WVALID <= 1
        self.bus.WSTRB <= byte_enable

        while True:
            yield ReadOnly()
            if self.bus.WREADY.value:
                break
            yield RisingEdge(self.clock)
        yield RisingEdge(self.clock)
        self.bus.WVALID <= 0
        self.write_data_busy.release()

    @cocotb.coroutine
    def write(self,
              address,
              value,
              byte_enable=0xf,
              address_latency=0,
              data_latency=0,
              sync=True):
        """Write a value to an address.

        Args:
            address (int): The address to write to.
            value (int): The data value to write.
            byte_enable (int, optional): Which bytes in value to actually write.
                Default is to write all bytes.
            address_latency (int, optional): Delay before setting the address (in clock cycles).
                Default is no delay.
            data_latency (int, optional): Delay before setting the data value (in clock cycles).
                Default is no delay.
            sync (bool, optional): Wait for rising edge on clock initially.
                Defaults to True.

        Returns:
            BinaryValue: The write response value.

        Raises:
            AXIProtocolError: If write response from AXI is not ``OKAY``.
        """
        if sync:
            yield RisingEdge(self.clock)

        c_addr = cocotb.fork(
            self._send_write_address(address, delay=address_latency))
        c_data = cocotb.fork(
            self._send_write_data(value,
                                  byte_enable=byte_enable,
                                  delay=data_latency))

        if c_addr:
            yield c_addr.join()
        if c_data:
            yield c_data.join()

        # Wait for the response
        while True:
            yield ReadOnly()
            if self.bus.BVALID.value and self.bus.BREADY.value:
                result = self.bus.BRESP.value
                break
            yield RisingEdge(self.clock)

        yield RisingEdge(self.clock)

        if int(result):
            raise AXIProtocolError(
                "Write to address 0x%08x failed with BRESP: %d" %
                (address, int(result)))

        return result

    @cocotb.coroutine
    def read(self, address, sync=True):
        """Read from an address.

        Args:
            address (int): The address to read from.
            sync (bool, optional): Wait for rising edge on clock initially.
                Defaults to True.

        Returns:
            BinaryValue: The read data value.

        Raises:
            AXIProtocolError: If read response from AXI is not ``OKAY``.
        """
        if sync:
            yield RisingEdge(self.clock)

        self.bus.ARADDR <= address
        self.bus.ARVALID <= 1

        while True:
            yield ReadOnly()
            if self.bus.ARREADY.value:
                break
            yield RisingEdge(self.clock)

        yield RisingEdge(self.clock)
        self.bus.ARVALID <= 0

        while True:
            yield ReadOnly()
            if self.bus.RVALID.value and self.bus.RREADY.value:
                data = self.bus.RDATA.value
                result = self.bus.RRESP.value
                break
            yield RisingEdge(self.clock)

        if int(result):
            raise AXIProtocolError(
                "Read address 0x%08x failed with RRESP: %d" %
                (address, int(result)))

        return data

    def __len__(self):
        return 2**len(self.bus.ARADDR)
class BlockFIFOWritePath(BusDriver):
    _signals = ["HSYNC", "SOF_STB", "RED", "GREEN", "BLUE"]

    def __init__(self, entity, name, clock, width = 100, height = 100, y_fp = 10, y_bp = 10, x_fp = 10, x_bp = 10):
        BusDriver.__init__(self, entity, name, clock)
        self.width = width
        self.height = height
        self.y_fp = y_fp
        self.y_bp = y_bp
        self.x_fp = x_fp
        self.x_bp = x_bp
        self.bus.SOF_STB.setimmediatevalue(0)
        self.bus.HSYNC.setimmediatevalue(0)
        self.bus.RED.setimmediatevalue(0)
        self.bus.BLUE.setimmediatevalue(0)
        self.bus.GREEN.setimmediatevalue(0)
        self.busy = Lock("%s_busy" % name)

    @cocotb.coroutine
    def write(self, data = None):

        if data is None:
            #Generate a test image
            data = [[0] * width] * height
            for y in range(height):
                for x in range(width):
                    data[y][x] = i % 256

        yield self.busy.acquire()

        yield RisingEdge(self.clock)
        '''
        self.bus.SOF_STB <= 1
        yield RisingEdge(self.clock)
        self.bus.SOF_STB <= 0
        '''

        #Perform Y Front Porch Delay
        for i in range (self.y_fp):
           yield RisingEdge(self.clock)
           yield ReadOnly()

        for y in range(self.height):
            #Perform X Front Porch Delay
            for i in range (self.x_fp):
                yield RisingEdge(self.clock)
                yield ReadOnly()

            yield RisingEdge(self.clock)
            self.bus.SOF_STB    <=  1
            yield RisingEdge(self.clock)
            self.bus.SOF_STB    <=  0

            for x in range(self.width):
                yield RisingEdge()
                self.busy.HSYNC <=  1
                self.bus.RED    <=  (data[y][x] >> 5) & 0x5
                self.bus.GREEN  <=  (data[y][x] >> 2) & 0x5
                self.bus.BLUE   <=  (data[y][x] >> 0) & 0x3

            yield RisingEdge()
            self.busy.HSYNC <=  0


            #Perform X Back Porch Delay
            for i in range (self.x_bp):
                yield RisingEdge(self.clock)
                yield ReadOnly()

        #Perform Y Back Porch Delay
        for i in range (self.y_bp):
           yield RisingEdge(self.clock)
           yield ReadOnly()
class CommandMaster (BusDriver):
    _signals = ["EN", "ERROR", "ACK", "STATUS", "INTERRUPT",
                "ADR", "ADR_FIXED", "ADR_WRAP",
                "WR_RD", "COUNT"]

    def __init__(self,
                 entity,
                 name,
                 clock,
                 wr_fifo_name = "WR",
                 wr_fifo_clk = None,
                 wr_fifo_clk_period = 10,
                 rd_fifo_name = "RD",
                 rd_fifo_clk = None,
                 rd_fifo_clk_period = 10):
        BusDriver.__init__(self, entity, name, clock)
        if wr_fifo_clk is None:
            wr_fifo_clk = entity.WR_CLK
        if rd_fifo_clk is None:
            rd_fifo_clk = entity.RD_CLK

        self.bus.EN.setimmediatevalue(0)
        self.bus.ADR.setimmediatevalue(0)
        self.bus.ADR_FIXED.setimmediatevalue(0)
        self.bus.ADR_WRAP.setimmediatevalue(0)
        self.bus.WR_RD.setimmediatevalue(0)
        self.bus.COUNT.setimmediatevalue(0)

        # Mutex for each channel that we master to prevent contention
        self.command_busy = Lock("%s_wabusy" % name)
        cocotb.fork(Clock(wr_fifo_clk, wr_fifo_clk_period).start())
        cocotb.fork(Clock(rd_fifo_clk, rd_fifo_clk_period).start())

        self.write_fifo = PPFIFOWritePath(entity, wr_fifo_name, wr_fifo_clk)
        self.read_fifo = PPFIFOReadPath(entity, rd_fifo_name, rd_fifo_clk)

    @cocotb.coroutine
    def write(self, address, data):
        count = 0
        yield self.command_busy.acquire()
        yield RisingEdge(self.clock)
        self.bus.ADR    <= address
        self.bus.COUNT  <=  len(data)
        self.bus.WR_RD  <=  1
        self.bus.EN     <=  1
        yield RisingEdge(self.clock)
        print "Length of data: %d" % len(data)

        yield self.write_fifo.write(data)

        yield RisingEdge(self.clock)
        self.bus.EN     <=  0
        self.command_busy.release()

    @cocotb.coroutine
    def read(self, address, size, sync=True):
        count = 0
        data = []
        yield self.command_busy.acquire()
        self.bus.ADR <= address
        self.bus.COUNT  <=  size
        self.bus.EN <= 1
        yield RisingEdge(self.clock)

        yield RisingEdge(self.clock)
        self.bus.EN <=  0

        yield ReadOnly()
        self.command_busy.release()
Exemple #45
0
 def __init__(self, entity, name, clock, width = 32):
     BusDriver.__init__(self, entity, name, clock)
     self.width = width
     self.bus.TREADY <= 0;
     self.read_data_busy = Lock("%s_wbusy" % name)
     self.data = []
Exemple #46
0
class AXI4LiteMaster(BusDriver):
    """
    AXI4-Lite Master

    TODO: Kill all pending transactions if reset is asserted...
    """
    _signals = ["AWVALID", "AWADDR", "AWREADY",        # Write address channel
                "WVALID", "WREADY", "WDATA", "WSTRB",  # Write data channel
                "BVALID", "BREADY", "BRESP",           # Write response channel
                "ARVALID", "ARADDR", "ARREADY",        # Read address channel
                "RVALID", "RREADY", "RRESP", "RDATA"]  # Read data channel

    def __init__(self, entity, name, clock):
        BusDriver.__init__(self, entity, name, clock)

        # Drive some sensible defaults (setimmediatevalue to avoid x asserts)
        self.bus.AWVALID.setimmediatevalue(0)
        self.bus.WVALID.setimmediatevalue(0)
        self.bus.ARVALID.setimmediatevalue(0)
        self.bus.BREADY.setimmediatevalue(1)
        self.bus.RREADY.setimmediatevalue(1)

        # Mutex for each channel that we master to prevent contention
        self.write_address_busy = Lock("%s_wabusy" % name)
        self.read_address_busy = Lock("%s_rabusy" % name)
        self.write_data_busy = Lock("%s_wbusy" % name)

    @cocotb.coroutine
    def _send_write_address(self, address, delay=0):
        """
        Send the write address, with optional delay
        """
        yield self.write_address_busy.acquire()
        for cycle in range(delay):
            yield RisingEdge(self.clock)

        self.bus.AWADDR <= address
        self.bus.AWVALID <= 1

        while True:
            yield ReadOnly()
            if self.bus.AWREADY.value:
                break
            yield RisingEdge(self.clock)
        yield RisingEdge(self.clock)
        self.bus.AWVALID <= 0
        self.write_address_busy.release()

    @cocotb.coroutine
    def _send_write_data(self, data, delay=0, byte_enable=0xF):
        """
        Send the write address, with optional delay
        """
        yield self.write_data_busy.acquire()
        for cycle in range(delay):
            yield RisingEdge(self.clock)

        self.bus.WDATA <= data
        self.bus.WVALID <= 1
        self.bus.WSTRB <= byte_enable

        while True:
            yield ReadOnly()
            if self.bus.WREADY.value:
                break
            yield RisingEdge(self.clock)
        yield RisingEdge(self.clock)
        self.bus.WVALID <= 0
        self.write_data_busy.release()

    @cocotb.coroutine
    def write(self, address, value, byte_enable=0xf, address_latency=0,
              data_latency=0):
        """
        Write a value to an address.

        The *_latency KWargs allow control over the delta
        """

        c_addr = cocotb.fork(self._send_write_address(address,
                                                      delay=address_latency))
        c_data = cocotb.fork(self._send_write_data(value,
                                                   byte_enable=byte_enable,
                                                   delay=data_latency))

        if c_addr:
            yield c_addr.join()
        if c_data:
            yield c_data.join()

        # Wait for the response
        while True:
            yield ReadOnly()
            if self.bus.BVALID.value and self.bus.BREADY.value:
                result = self.bus.BRESP.value
                break
            yield RisingEdge(self.clock)

        yield RisingEdge(self.clock)

        if int(result):
            raise AXIProtocolError("Write to address 0x%08x failed with BRESP: %d"
                               % (address, int(result)))

        raise ReturnValue(result)

    @cocotb.coroutine
    def read(self, address, sync=True):
        """
        Read from an address.
        """
        if sync:
            yield RisingEdge(self.clock)

        self.bus.ARADDR <= address
        self.bus.ARVALID <= 1

        while True:
            yield ReadOnly()
            if self.bus.ARREADY.value:
                break
            yield RisingEdge(self.clock)

        yield RisingEdge(self.clock)
        self.bus.ARVALID <= 0

        while True:
            yield ReadOnly()
            if self.bus.RVALID.value and self.bus.RREADY.value:
                data = self.bus.RDATA.value
                result = self.bus.RRESP.value
                break
            yield RisingEdge(self.clock)

        if int(result):
            raise AXIProtocolError("Read address 0x%08x failed with RRESP: %d" %
                               (address, int(result)))

        raise ReturnValue(data)
 def __init__(self, entity, name, clock):
     BusDriver.__init__(self, entity, name, clock)
     self.bus.ACT.setimmediatevalue(0)
     self.bus.STB.setimmediatevalue(0)
     self.busy = Lock("%s_busy" % name)
Exemple #48
0
 def __init__(self, entity, name, clock, width = 32):
     BusDriver.__init__(self, entity, name, clock)
     self.width = width
     self.bus.TREADY <= 0;
     self.read_data_busy = Lock("%s_wbusy" % name)
     self.data = []
 def __init__(self, entity, name, clock):
     BusDriver.__init__(self, entity, name, clock)
     self.bus.wr_stb     <=  0
     self.bus.wr_data    <=  0
     self.write_data_busy = Lock("%s_wbusy" % name)
class VideoOutBus(BusDriver):
    """
    Generate RGB Video Signals
    """

    _signals = [
        "RGB",
        "HSYNC",
        "VSYNC",
        "DATA_EN",
        "HBLANK",
        "VBLANK"
    ]

    def __init__(self, entity, name, clock, width, height, hblank, vblank):
        BusDriver.__init__(self, entity, name, clock)

        #Drive some sensible defaults
        self.bus.RGB.setimmediatevalue(0)
        self.bus.HSYNC.setimmediatevalue(0)
        self.bus.VSYNC.setimmediatevalue(0)
        self.bus.DATA_EN.setimmediatevalue(0)

        self.bus.HBLANK.setimmediatevalue(1)
        self.bus.VBLANK.setimmediatevalue(1)

        self.width = width
        self.height = height
        self.hblank = hblank
        self.vblank = vblank

        self.write_lock = Lock("%s_busy" % name)

    @cocotb.coroutine
    def write(self, video):
        #print "Video: %s" % video
        yield self.write_lock.acquire()
        yield RisingEdge(self.clock)
        self.bus.DATA_EN               <=  1
        for frame in video:
            for line in frame:
                for pixel in line:
                    self.bus.HBLANK    <=  0
                    self.bus.VBLANK    <=  0
                    self.bus.HSYNC     <=  1
                    self.bus.VSYNC     <=  1

                    self.bus.RGB        <= pixel
                    yield RisingEdge(self.clock)

                #Horizontal Blank
                self.bus.HSYNC         <=  0
                self.bus.HBLANK        <=  1
                for i in range(self.hblank):
                    yield RisingEdge(self.clock)

                self.bus.VSYNC         <=  0
                self.bus.VBLANK        <=  1

            #Vertical Blank
            for i in range(self.vblank):
                yield RisingEdge(self.clock)

        self.bus.DATA_EN                <=  0
        self.write_lock.release()
Exemple #51
0
class AXI4StreamMaster(BusDriver):

    _signals = ["TVALID", "TREADY", "TDATA"]  # Write data channel
    _optional_signals = ["TLAST", "TKEEP", "TSTRB", "TID", "TDEST", "TUSER"]

    def __init__(self, entity, name, clock, width=32):
        BusDriver.__init__(self, entity, name, clock)
        #Drive default values onto bus
        self.width = width
        self.strobe_width = width / 8
        self.bus.TVALID.setimmediatevalue(0)
        self.bus.TLAST.setimmediatevalue(0)
        self.bus.TDATA.setimmediatevalue(0)
        self.bus.TKEEP.setimmediatevalue(0)
        self.bus.TID.setimmediatevalue(0)
        self.bus.TDEST.setimmediatevalue(0)
        self.bus.TUSER.setimmediatevalue(0)

        self.write_data_busy = Lock("%s_wbusy" % name)

    @cocotb.coroutine
    def write(self, data, byte_enable=-1, keep=1, tid=0, dest=0, user=0):
        """
        Send the write data, with optional delay
        """
        yield self.write_data_busy.acquire()
        self.bus.TVALID <=  0
        self.bus.TLAST  <=  0
        self.bus.TID    <=  tid
        self.bus.TDEST  <=  dest
        self.bus.TUSER  <=  user
        self.bus.TSTRB  <=  (1 << self.strobe_width) - 1
        if byte_enable == -1:
            byte_enable = (self.width >> 3) - 1

        #Wait for the slave to assert tready
        while True:
            yield ReadOnly()
            if self.bus.TREADY.value:
                break
            yield RisingEdge(self.clock)

        yield RisingEdge(self.clock)
        #every clock cycle update the data
        for i in range (len(data)):
            self.bus.TVALID <=  1
            self.bus.TDATA  <= data[i]
            if i >= len(data) - 1:
                self.bus.TLAST  <=  1;
            yield ReadOnly()
            if not self.bus.TREADY.value:
                while True:
                    yield RisingEdge(self.clock)
                    yield ReadOnly()
                    if self.bus.TREADY.value:
                        yield RisingEdge(self.clock)
                        break
                continue
            yield RisingEdge(self.clock)

        self.bus.TLAST  <=  0;
        self.bus.TVALID <=  0;
        yield RisingEdge(self.clock)
        self.write_data_busy.release()
        self.bus.TSTRB  <=  0