Exemplo n.º 1
0
 def rx_data_to_ad9361(
         self,
         i_data,
         q_data,
         i_data2=None,
         q_data2=None,
         binaryRepresentation=BinaryRepresentation.TWOS_COMPLEMENT):
     i_bin_val = BinaryValue(bits=12,
                             bigEndian=False,
                             binaryRepresentation=binaryRepresentation)
     q_bin_val = BinaryValue(bits=12,
                             bigEndian=False,
                             binaryRepresentation=binaryRepresentation)
     index = 0
     if i_data2 == None and q_data2 == None:
         while True:
             yield RisingEdge(self.dut.rx_clk_in_p)
             if self.rx_frame_asserted:
                 self.dut.rx_data_in_p <= i_bin_val[5:0]
                 self.dut.rx_data_in_n <= ~i_bin_val[5:0]
                 self.rx_frame_asserted = False
                 self.dut.rx_frame_in_p <= 0
                 self.dut.rx_frame_in_n <= 1
             else:
                 if index < len(i_data):
                     i_bin_val.set_value(i_data[index])
                     q_bin_val.set_value(q_data[index])
                     index += 1
                 else:
                     return
                 self.dut.rx_data_in_p <= i_bin_val[11:6]
                 self.dut.rx_data_in_n <= ~i_bin_val[11:6]
                 self.rx_frame_asserted = True
                 self.dut.rx_frame_in_p <= 1
                 self.dut.rx_frame_in_n <= 0
             yield RisingEdge(self.dut.rx_clk_in_n)
             if self.rx_frame_asserted:
                 self.dut.rx_data_in_p <= q_bin_val[11:6]
                 self.dut.rx_data_in_n <= ~q_bin_val[11:6]
             else:
                 self.dut.rx_data_in_p <= q_bin_val[5:0]
                 self.dut.rx_data_in_n <= ~q_bin_val[5:0]
     else:
         I_SEND_HIGH = True
         Q_SEND_HIGH = True
         channel = 1
         while True:
             yield RisingEdge(self.dut.rx_clk_in_p)
             if I_SEND_HIGH:
                 self.dut.rx_data_in_p <= i_bin_val[11:6]
                 self.dut.rx_data_in_n <= ~i_bin_val[11:6]
                 I_SEND_HIGH = False
                 if channel == 1:
                     self.dut.rx_frame_in_p <= 1
                     self.dut.rx_frame_in_n <= 0
                 elif channel == 2:
                     self.dut.rx_frame_in_p <= 0
                     self.dut.rx_frame_in_n <= 1
             else:
                 self.dut.rx_data_in_p <= i_bin_val[5:0]
                 self.dut.rx_data_in_n <= ~i_bin_val[5:0]
                 I_SEND_HIGH = True
             yield RisingEdge(self.dut.rx_clk_in_n)
             if Q_SEND_HIGH:
                 self.dut.rx_data_in_p <= q_bin_val[5:0]
                 self.dut.rx_data_in_n <= ~q_bin_val[5:0]
                 Q_SEND_HIGH = False
             else:
                 self.dut.rx_data_in_p <= q_bin_val[11:6]
                 self.dut.rx_data_in_n <= ~q_bin_val[11:6]
                 Q_SEND_HIGH = True
                 if index < len(i_data):
                     if channel == 1:
                         i_bin_val.set_value(i_data[index])
                         q_bin_val.set_value(q_data[index])
                         channel = 2
                     elif channel == 2:
                         i_bin_val.set_value(i_data2[index])
                         q_bin_val.set_value(q_data2[index])
                         channel = 1
                         index += 1
                 else:
                     return
Exemplo n.º 2
0
 def wait_for(clk, cycles):
     rising_edge = RisingEdge(clk)
     for _ in range(cycles):
         yield rising_edge
     return 3
Exemplo n.º 3
0
    async def _monitor_recv(self):
        """Watch the pins and reconstruct transactions."""

        # Avoid spurious object creation by recycling
        clkedge = RisingEdge(self.clock)
        rdonly = ReadOnly()
        pkt = b""
        in_pkt = False
        invalid_cyclecount = 0
        channel = None

        def valid():
            if hasattr(self.bus, 'ready'):
                return self.bus.valid.value and self.bus.ready.value
            return self.bus.valid.value

        while True:
            await clkedge
            await rdonly

            if self.in_reset:
                continue

            if valid():
                invalid_cyclecount = 0

                if self.bus.startofpacket.value:
                    if pkt:
                        raise AvalonProtocolError(
                            "Duplicate start-of-packet received on %s" %
                            str(self.bus.startofpacket))
                    pkt = b""
                    in_pkt = True

                if not in_pkt:
                    raise AvalonProtocolError("Data transfer outside of "
                                              "packet")

                # Handle empty and X's in empty / data
                vec = BinaryValue()
                if not self.bus.endofpacket.value:
                    vec = self.bus.data.value
                else:
                    value = self.bus.data.value.get_binstr()
                    if self.config["useEmpty"] and self.bus.empty.value.integer:
                        empty = self.bus.empty.value.integer * self.config[
                            "dataBitsPerSymbol"]
                        if self.config["firstSymbolInHighOrderBits"]:
                            value = value[:-empty]
                        else:
                            value = value[empty:]
                    vec.assign(value)
                    if not vec.is_resolvable:
                        raise AvalonProtocolError(
                            "After empty masking value is still bad?  "
                            "Had empty {:d}, got value {:s}".format(
                                empty, self.bus.data.value.get_binstr()))

                vec.big_endian = self.config['firstSymbolInHighOrderBits']
                pkt += vec.buff

                if hasattr(self.bus, 'channel'):
                    if channel is None:
                        channel = self.bus.channel.value.integer
                        if channel > self.config["maxChannel"]:
                            raise AvalonProtocolError(
                                "Channel value (%d) is greater than maxChannel (%d)"
                                % (channel, self.config["maxChannel"]))
                    elif self.bus.channel.value.integer != channel:
                        raise AvalonProtocolError(
                            "Channel value changed during packet")

                if self.bus.endofpacket.value:
                    self.log.info("Received a packet of %d bytes", len(pkt))
                    self.log.debug(hexdump(pkt))
                    self.channel = channel
                    if self.report_channel:
                        self._recv({"data": pkt, "channel": channel})
                    else:
                        self._recv(pkt)
                    pkt = b""
                    in_pkt = False
                    channel = None
            else:
                if in_pkt:
                    invalid_cyclecount += 1
                    if self.config["invalidTimeout"]:
                        if invalid_cyclecount >= self.config["invalidTimeout"]:
                            raise AvalonProtocolError(
                                "In-Packet Timeout. Didn't receive any valid data for %d cycles!"
                                % invalid_cyclecount)
Exemplo n.º 4
0
 async def wait_for(clk, cycles):
     rising_edge = RisingEdge(clk)
     for _ in range(cycles):
         await rising_edge
     return 3
Exemplo n.º 5
0
def do_test_afterdelay_in_readonly(dut, delay):
    global exited
    yield RisingEdge(dut.clk)
    yield ReadOnly()
    yield Timer(delay)
    exited = True
Exemplo n.º 6
0
    def _send_string(self, string, sync=True, channel=None):
        """Args:
            string (str): A string of bytes to send over the bus.
            channel (int): Channel to send the data on.
        """
        # Avoid spurious object creation by recycling
        clkedge = RisingEdge(self.clock)
        firstword = True

        # FIXME: buses that aren't an integer numbers of bytes
        bus_width = int(len(self.bus.data) / 8)

        word = BinaryValue(n_bits=len(self.bus.data),
                           bigEndian=self.config["firstSymbolInHighOrderBits"])

        single = BinaryValue(n_bits=1, bigEndian=False)
        if self.use_empty:
            empty = BinaryValue(n_bits=len(self.bus.empty), bigEndian=False)

        # Drive some defaults since we don't know what state we're in
        if self.use_empty:
            self.bus.empty <= 0
        self.bus.startofpacket <= 0
        self.bus.endofpacket <= 0
        self.bus.valid <= 0
        if hasattr(self.bus, 'error'):
            self.bus.error <= 0

        if hasattr(self.bus, 'channel'):
            self.bus.channel <= 0
        elif channel is not None:
            raise TestError("%s does not have a channel signal" % self.name)

        while string:
            if not firstword or (firstword and sync):
                yield clkedge

            # Insert a gap where valid is low
            if not self.on:
                self.bus.valid <= 0
                for _ in range(self.off):
                    yield clkedge

                # Grab the next set of on/off values
                self._next_valids()

            # Consume a valid cycle
            if self.on is not True and self.on:
                self.on -= 1

            self.bus.valid <= 1
            if hasattr(self.bus, 'channel'):
                if channel is None:
                    self.bus.channel <= 0
                elif channel > self.config['maxChannel'] or channel < 0:
                    raise TestError(
                        "%s: Channel value %d is outside range 0-%d" %
                        (self.name, channel, self.config['maxChannel']))
                else:
                    self.bus.channel <= channel

            if firstword:
                self.bus.startofpacket <= 1
                firstword = False
            else:
                self.bus.startofpacket <= 0

            nbytes = min(len(string), bus_width)
            data = string[:nbytes]
            word.buff = data

            if len(string) <= bus_width:
                self.bus.endofpacket <= 1
                if self.use_empty:
                    self.bus.empty <= bus_width - len(string)
                string = ""
            else:
                string = string[bus_width:]

            self.bus.data <= word

            # If this is a bus with a ready signal, wait for this word to
            # be acknowledged
            if hasattr(self.bus, "ready"):
                yield self._wait_ready()

        yield clkedge
        self.bus.valid <= 0
        self.bus.endofpacket <= 0
        word.binstr = "x" * len(self.bus.data)
        single.binstr = "x"
        self.bus.data <= word
        self.bus.startofpacket <= single
        self.bus.endofpacket <= single

        if self.use_empty:
            empty.binstr = "x" * len(self.bus.empty)
            self.bus.empty <= empty
        if hasattr(self.bus, 'channel'):
            channel_value = BinaryValue(n_bits=len(self.bus.channel),
                                        bigEndian=False,
                                        value="x" * len(self.bus.channel))
            self.bus.channel <= channel_value
Exemplo n.º 7
0
    def _send_string(self, string, sync=True):
        """
        Args:
            string (str): A string of bytes to send over the bus
        """
        # Avoid spurious object creation by recycling
        clkedge = RisingEdge(self.clock)
        firstword = True

        # FIXME busses that aren't integer numbers of bytes
        bus_width = int(len(self.bus.data) / 8)

        word = BinaryValue(bits=len(self.bus.data),
                           bigEndian=self.config['firstSymbolInHighOrderBits'])

        empty = BinaryValue(bits=len(self.bus.empty), bigEndian=False)
        single = BinaryValue(bits=1, bigEndian=False)

        # Drive some defaults since we don't know what state we're in
        # self.bus.empty <= 0
        self.bus.startofpacket <= 0
        self.bus.endofpacket <= 0
        self.bus.valid <= 0
        if hasattr(self.bus, 'error'):
            self.bus.error <= 0

        while string:
            if not firstword or (firstword and sync):
                yield clkedge

            # Insert a gap where valid is low
            if not self.on:
                self.bus.valid <= 0
                for i in range(self.off):
                    yield clkedge

                # Grab the next set of on/off values
                self._next_valids()

            # Consume a valid cycle
            if self.on is not True and self.on:
                self.on -= 1

            self.bus.valid <= 1

            if firstword:
                #self.bus.empty <= 0
                self.bus.startofpacket <= 1
                firstword = False
            else:
                self.bus.startofpacket <= 0

            nbytes = min(len(string), bus_width)
            data = string[:nbytes]
            word.buff = data

            if len(string) <= bus_width:
                self.bus.endofpacket <= 1
                self.bus.empty <= bus_width - len(string)
                string = ""
            else:
                string = string[bus_width:]

            self.bus.data <= word

            # If this is a bus with a ready signal, wait for this word to
            # be acknowledged
            if hasattr(self.bus, "ready"):
                yield self._wait_ready()

        yield clkedge
        self.bus.valid <= 0
        self.bus.endofpacket <= 0
        word.binstr = ("x" * len(self.bus.data))
        empty.binstr = ("x" * len(self.bus.empty))
        single.binstr = ("x")
        self.bus.data <= word
        self.bus.empty <= empty
        self.bus.startofpacket <= single
        self.bus.endofpacket <= single
Exemplo n.º 8
0
def write_reg(dut, addr, val):
    dut.addr_i <= addr
    dut.we_i <= 1
    dut.data_i <= val
    yield RisingEdge(dut.clk_i)
Exemplo n.º 9
0
    def scan_in(self, val, T = None, scan_clk = None, scan_in = None, scan_out = None,
        scan_en = None, scan_wen = None, fromMSB = None, verbosity = None, clk_running = None,
        clk_b = None, read_func = None):

        if T is None:
            T = self.T
            halfT = self.halfT
            quarterT = self.quarterT
        else:
            halfT = int(T/2)
            quarterT = int(T/4)

        if scan_clk is None:
            scan_clk = self._scan_clk
        if scan_in is None:
            scan_in = self._scan_in
        if scan_out is None:
            scan_out = self._scan_out
        if scan_en is None:
            scan_en = self._scan_en
        if scan_wen is None:
            scan_wen = self._scan_wen
        if fromMSB is None:
            fromMSB = self.fromMSB
        if verbosity is None:
            verbosity = self.verbosity
        if clk_running is None:
            clk_running = self.clk_running
        if clk_b is None:
            clk_b = self.clk_b
        if read_func is None:
            read_func = self.read_func

        if self.length is not None and len(val) != self.length:
            print(f'Warning: number of scanned bits ({len(val)}) is not equal to the scan chain length ({self.length})')

        if fromMSB:
            val = val[::-1]

        if Config.running_cocotb:
            if clk_running:
                if clk_b:
                    yield RisingEdge(scan_clk)
                else:
                    yield FallingEdge(scan_clk)
            else:
                yield Timer(halfT)

        if scan_en is not None:
            if Config.running_cocotb and read_func(scan_en) == '1':
                print('ERROR: scan enable is high, another chain might be using the scan ports')
                return None
            else:
                write_signal(scan_en, 1)

        outstr = ''
        for i, v in enumerate(val):
            if scan_out is not None:
                outstr = outstr + read_func(scan_out)

            if (verbosity == 1 and i%100 == 0) or (verbosity == 2 and i%10 == 0) or (verbosity > 2):
                print(f"Scanning bit {i} out of {len(val)-1}...")

            write_signal(scan_in, int(v, 2))

            if Config.running_cocotb:
                yield cycle(scan_clk, T, clk_running)
            else:
                cycle(scan_clk, T, clk_running)

        if fromMSB:
            outstr = outstr[::-1]

        if scan_en is not None:
            write_signal(scan_en, 0)

        if scan_wen is not None:
            write_signal(scan_wen, 1)
            if Config.running_cocotb:
                yield cycle(scan_clk, T, clk_running)
            else:
                cycle(scan_clk, T, clk_running)
            write_signal(scan_wen, 0)

        if Config.inv_outs:
            outstr = inv(outstr)

        return outstr
Exemplo n.º 10
0
    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)
Exemplo n.º 11
0
def read_reg(dut, addr):
    dut.addr_i <= addr
    yield RisingEdge(dut.clk_i)
    raise ReturnValue(dut.data_o.value)
Exemplo n.º 12
0
def test(dut):
    print "------------------------------------------- ONE -------------------------------------------"
    si_rx = SI_Master(dut.clk, dut.rst, dut.rx_data, dut.rx_rdy, dut.rx_ack)
    reg_10 = REG_SI_Slave(dut.clk, dut.rst, dut.register_addr,
                          dut.register_data, dut.register_rdy, 10)
    reg_13 = REG_SI_Slave(dut.clk, dut.rst, dut.register_addr,
                          dut.register_data, dut.register_rdy, 13)
    reg_200 = REG_SI_Slave(dut.clk, dut.rst, dut.register_addr,
                           dut.register_data, dut.register_rdy, 200)

    reg_mon = REG_SI_MON(dut.clk, dut.rst, dut.register_addr,
                         dut.register_data, dut.register_rdy)
    print "------------------------------------------- TWO -------------------------------------------"

    cocotb.fork(Clock(dut.clk, 10, units='ns').start())
    print "------------------------------------------- THREE -------------------------------------------"
    yield Reset(dut)

    print "------------------------------------------- FOUR -------------------------------------------"

    print "I'm writing the fifo"

    si_rx.write(13)
    si_rx.write(0xFF)
    si_rx.write(0xEE)
    si_rx.write(10)
    si_rx.write(0xDD)
    si_rx.write(0xCC)
    si_rx.write(200)
    si_rx.write(0xBB)
    si_rx.write(0xAA)
    si_rx.write(9)
    si_rx.write(0x99)
    si_rx.write(0x88)

    # requests_handler (addr=0x00)
    si_rx.write(0)
    si_rx.write(0x01)
    si_rx.write(0x00)

    cocotb.fork(si_rx.driver())
    cocotb.fork(reg_10.monitor())
    cocotb.fork(reg_13.monitor())
    cocotb.fork(reg_200.monitor())
    cocotb.fork(reg_mon.bus_monitor())

    print "I'm starting to send the data"
    for i in range(100):
        yield RisingEdge(dut.clk)

    # requests_handler (addr=12)
    si_rx.write(12)
    si_rx.write(0x02)
    si_rx.write(0x00)
    for i in range(10):
        yield RisingEdge(dut.clk)
    si_rx.write(12)
    si_rx.write(0x04)
    si_rx.write(0x00)
    for i in range(10):
        yield RisingEdge(dut.clk)
    si_rx.write(12)
    si_rx.write(0x08)
    si_rx.write(0x00)
    for i in range(10):
        yield RisingEdge(dut.clk)
    si_rx.write(12)
    si_rx.write(0xFF)
    si_rx.write(0xFF)
    for i in range(10):
        yield RisingEdge(dut.clk)

    print "Reg_10: " + repr(reg_10.fifo)
    print "Reg_13: " + repr(reg_13.fifo)
    print "Reg_200: " + repr(reg_200.fifo)
    print "Data: " + repr(reg_mon.fifo_addr)
    print "Addr: " + repr(reg_mon.fifo_data)
    print "I'm at the end"
Exemplo n.º 13
0
def cycleCounterAgent(dut, counter):
    while True:
        yield RisingEdge(dut.clk)
        counter[0] += 1
def test_controlLoop(dut):
    # Set up the clock
    fs = 2e6  # Hz

    # Generate the test waveforms
    sineFrq = 50e3  # Hz The frequency of the excitation wave
    cycles = 3  # The number of waves to use
    # timebase = np.arange(0, (cycles * (1 / sineFrq)), (1 / fs))
    # Stimulus = (2 ** 17) * (np.sin(2 * np.pi * sineFrq * timebase))

    # START Test
    dut.controlInput_i.value = 0
    dut.kp_i = 24
    dut.ki_i = 26

    # Create a clock from which we start everything
    c = Clock(dut.clock_i, 500, "ns")
    cocotb.fork(c.start())

    clkedge = RisingEdge(dut.clock_i)

    timebase = []
    stimulus = []

    inputSignal = []
    controllerError = []
    feedback = []
    plantOut = []
    Output = []

    controllerError.append(0)
    feedback.append(0)
    plantOut.append(0)
    controllerError.append(0)
    feedback.append(0)
    plantOut.append(0)

    # open file and read the content in a list
    with open("timebase.txt", "r") as filehandle:
        for line in filehandle:
            # remove linebreak which is the last character of the string
            currentPlace = line[:-1]

            # add item to the list
            timebase.append(currentPlace)

    with open("input.txt", "r") as filehandle:
        for line in filehandle:
            # remove linebreak which is the last character of the string
            currentPlace = line[:-1]

            # add item to the list
            stimulus.append(currentPlace)

    yield clkedge
    yield clkedge
    for i in range(1, len(timebase)):
        yield clkedge

        inputSignal.append(stimulus[i])
        controllerError.append(float(stimulus[i]) - float(feedback[i - 1]))
        # The plant is a sine wave
        plantOut.append(math.sin(controllerError[i]) * (2**17))
        dut.controlInput_i.value = int(plantOut[i])
        Output.append(dut.feedback_o.value.signed_integer)
        feedback.append((dut.feedback_o.value.signed_integer) / (2**17))

    controllerErrorList = list(controllerError)
    feedbackList = list(feedback)
    plantOutList = list(plantOut)

    with open("controllerError.txt", "w") as filehandle:
        for listitem in controllerErrorList:
            filehandle.write("%s\n" % listitem)

    with open("feedback.txt", "w") as filehandle:
        for listitem in feedbackList:
            filehandle.write("%s\n" % listitem)

    with open("plantOut.txt", "w") as filehandle:
        for listitem in plantOutList:
            filehandle.write("%s\n" % listitem)
Exemplo n.º 15
0
def n_cycles_clock(dut, n):
    for i in range(0, n):
        yield RisingEdge(dut.clk)
        yield FallingEdge(dut.clk)
Exemplo n.º 16
0
 def drive_high(self):
     yield RisingEdge(self.clock)
     self.bus.SCL <= 1
     self.bus.SDA <= 1
Exemplo n.º 17
0
    def read(self, address, sync=True):
        """Issue a request to the bus and block until this comes back.

        Simulation time still progresses
        but syntactically it blocks.

        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:
            :any:`TestError`: If master is write-only.
        """
        if not self._can_read:
            self.log.error("Cannot read - have no read signal")
            raise TestError("Attempt to read on a write-only AvalonMaster")

        yield self._acquire_lock()

        # Apply values for next clock edge
        if sync:
            yield RisingEdge(self.clock)
        self.bus.address <= address
        self.bus.read <= 1
        if hasattr(self.bus, "byteenable"):
            self.bus.byteenable <= int("1" * len(self.bus.byteenable), 2)
        if hasattr(self.bus, "cs"):
            self.bus.cs <= 1

        # Wait for waitrequest to be low
        if hasattr(self.bus, "waitrequest"):
            yield self._wait_for_nsignal(self.bus.waitrequest)
        yield RisingEdge(self.clock)

        # Deassert read
        self.bus.read <= 0
        if hasattr(self.bus, "byteenable"):
            self.bus.byteenable <= 0
        if hasattr(self.bus, "cs"):
            self.bus.cs <= 0
        v = self.bus.address.value
        v.binstr = "x" * len(self.bus.address)
        self.bus.address <= v

        if hasattr(self.bus, "readdatavalid"):
            while True:
                yield ReadOnly()
                if int(self.bus.readdatavalid):
                    break
                yield RisingEdge(self.clock)
        else:
            # Assume readLatency = 1 if no readdatavalid
            # FIXME need to configure this,
            # should take a dictionary of Avalon properties.
            yield ReadOnly()

        # Get the data
        data = self.bus.readdata.value

        self._release_lock()
        return data
Exemplo n.º 18
0
    async def await_all_clocks(self):
        trigs = []
        for clk in self.multiclock.clocks:
            trigs.append(RisingEdge(clk.clk))

        await Combine(*trigs)
Exemplo n.º 19
0
    def _respond(self):
        """
        Coroutine to response to the actual requests
        """
        edge = RisingEdge(self.clock)
        while True:
            yield edge
            self._do_response()

            yield ReadOnly()

            if self._readable and self.bus.read.value:
                if not self._burstread:
                    self._pad()
                    addr = self.bus.address.value.integer
                    if addr not in self._mem:
                        self.log.warning("Attempt to read from uninitialised "
                                         "address 0x%x" % addr)
                        self._responses.append(True)
                    else:
                        self.log.debug(
                            "Read from address 0x%x returning 0x%x" %
                            (addr, self._mem[addr]))
                        self._responses.append(self._mem[addr])
                else:
                    addr = self.bus.address.value.integer
                    if addr % self.dataByteSize != 0:
                        self.log.error(
                            "Address must be aligned to data width" +
                            "(addr = " + hex(addr) + ", width = " +
                            str(self._width))
                    addr = addr / self.dataByteSize
                    burstcount = self.bus.burstcount.value.integer
                    byteenable = self.bus.byteenable.value
                    if byteenable != int("1" * len(self.bus.byteenable), 2):
                        self.log.error("Only full word access is supported " +
                                       "for burst read (byteenable must be " +
                                       "0b" + "1" * len(self.bus.byteenable) +
                                       ")")
                    if burstcount == 0:
                        self.log.error("Burstcount must be 1 at least")

                    # toggle waitrequest
                    # TODO: configure waitrequest time with avalon properties
                    yield NextTimeStep()  # can't write during read-only phase
                    self.bus.waitrequest <= 1
                    yield edge
                    yield edge
                    self.bus.waitrequest <= 0

                    # wait for read data
                    for i in range(self._avalon_properties["readLatency"]):
                        yield edge
                    for count in range(burstcount):
                        if (addr + count) * self.dataByteSize not in self._mem:
                            self.log.warning(
                                "Attempt to burst read from uninitialised " +
                                "address 0x%x (addr 0x%x count 0x%x)" %
                                ((addr + count) * self.dataByteSize, addr,
                                 count))
                            self._responses.append(True)
                        else:
                            value = 0
                            for i in range(self.dataByteSize):
                                rvalue = self._mem[(addr + count) *
                                                   self.dataByteSize + i]
                                value += rvalue << i * 8
                            self.log.debug(
                                "Read from address 0x%x returning 0x%x" %
                                ((addr + count) * self.dataByteSize, value))
                            self._responses.append(value)
                        yield edge
                        self._do_response()

            if self._writeable and self.bus.write.value:
                if not self._burstwrite:
                    addr = self.bus.address.value.integer
                    data = self.bus.writedata.value.integer
                    if hasattr(self.bus, "byteenable"):
                        byteenable = int(self.bus.byteenable.value)
                        mask = 0
                        oldmask = 0
                        olddata = 0
                        if (addr in self._mem):
                            olddata = self._mem[addr]
                        self.log.debug("Old Data  : %x" % olddata)
                        self.log.debug("Data in   : %x" % data)
                        self.log.debug("Width     : %d" % self._width)
                        self.log.debug("Byteenable: %x" % byteenable)
                        for i in xrange(self._width / 8):
                            if (byteenable & 2**i):
                                mask |= 0xFF << (8 * i)
                            else:
                                oldmask |= 0xFF << (8 * i)

                        self.log.debug("Data mask : %x" % mask)
                        self.log.debug("Old mask  : %x" % oldmask)

                        data = (data & mask) | (olddata & oldmask)

                        self.log.debug("Data out  : %x" % data)

                    self.log.debug("Write to address 0x%x -> 0x%x" %
                                   (addr, data))
                    self._mem[addr] = data
                else:
                    self.log.debug("writing burst")
                    # maintain waitrequest high randomly
                    yield self._waitrequest()

                    addr, byteenable, burstcount = self._write_burst_addr()

                    count = 0
                    for count in range(burstcount):
                        while self.bus.write.value == 0:
                            yield NextTimeStep()
                        # self._mem is aligned on 8 bits words
                        yield self._writing_byte_value(addr + count *
                                                       self.dataByteSize)
                        self.log.debug("writing %016X @ %08X" %
                                       (self.bus.writedata.value.integer,
                                        addr + count * self.dataByteSize))
                        yield edge
                        # generate waitrequest randomly
                        yield self._waitrequest()

                    if self._avalon_properties.get("WriteBurstWaitReq", True):
                        self.bus.waitrequest <= 1
Exemplo n.º 20
0
def assertions(dut):

    for i in range(2500000):
        yield RisingEdge(dut.uut.io_vgaClk)
Exemplo n.º 21
0
    def _monitor_recv(self):
        clk = RisingEdge(self.clock)
        self._pkt = bytearray()

        while True:
            yield clk
            ctrl, bytes = self._get_bytes()

            if ctrl[0] and bytes[0] == _XGMII_START:

                ctrl, bytes = ctrl[1:], bytes[1:]

                while self._add_payload(ctrl, bytes):
                    yield clk
                    ctrl, bytes = self._get_bytes()

            elif self.bytes == 8:
                if ctrl[4] and bytes[4] == _XGMII_START:

                    ctrl, bytes = ctrl[5:], bytes[5:]

                    while self._add_payload(ctrl, bytes):
                        yield clk
                        ctrl, bytes = self._get_bytes()

            if self._pkt:

                self.log.debug("Received:\n%s" % (hexdump(self._pkt)))

                if len(self._pkt) < 64 + 7:
                    self.log.error("Received a runt frame!")
                if len(self._pkt) < 12:
                    self.log.error("No data to extract")
                    self._pkt = bytearray()
                    continue

                preamble_sfd = self._pkt[0:7]
                crc32 = self._pkt[-4:]
                payload = self._pkt[7:-4]

                if preamble_sfd != _PREAMBLE_SFD:
                    self.log.error("Got a frame with unknown preamble/SFD")
                    self.log.error(hexdump(preamble_sfd))
                    self._pkt = bytearray()
                    continue

                expected_crc = struct.pack("<I",
                                           (zlib.crc32(payload) & 0xFFFFFFFF))

                if crc32 != expected_crc:
                    self.log.error("Incorrect CRC on received packet")
                    self.log.info("Expected: %s" % (hexdump(expected_crc)))
                    self.log.info("Received: %s" % (hexdump(crc32)))

                # Use scapy to decode the packet
                if _have_scapy:
                    p = Ether(payload)
                    self.log.debug("Received decoded packet:\n%s" % p.show2())
                else:
                    p = payload

                self._recv(p)
                self._pkt = bytearray()
Exemplo n.º 22
0
    def rx_data_to_ad9361(self, i_data, q_data, i_data2=None, q_data2=None,
                          binaryRepresentation=BinaryRepresentation.TWOS_COMPLEMENT):
        """Receive data to AD9361.

        This is a coroutine.

        Args:
            i_data (int): Data of the I0 channel.
            q_data (int): Data of the Q0 channel.
            i_data2 (int, optional): Data of the I1 channel.
            q_data2 (int, optional): Data of the Q1 channel.
            binaryRepresentation (BinaryRepresentation): The representation of the binary value.
                Default is :any:`TWOS_COMPLEMENT`. 
       """
        i_bin_val = BinaryValue(n_bits=12, bigEndian=False,
                                binaryRepresentation=binaryRepresentation)
        q_bin_val = BinaryValue(n_bits=12, bigEndian=False,
                                binaryRepresentation=binaryRepresentation)
        index = 0
        if i_data2 is None and q_data2 is None:
            while True:
                yield RisingEdge(self.dut.rx_clk_in_p)
                if self.rx_frame_asserted:
                    self.dut.rx_data_in_p <= i_bin_val[5:0]
                    self.dut.rx_data_in_n <= ~i_bin_val[5:0]
                    self.rx_frame_asserted = False
                    self.dut.rx_frame_in_p <= 0
                    self.dut.rx_frame_in_n <= 1
                else:
                    if index < len(i_data):
                        i_bin_val.set_value(i_data[index])
                        q_bin_val.set_value(q_data[index])
                        index += 1
                    else:
                        return
                    self.dut.rx_data_in_p <= i_bin_val[11:6]
                    self.dut.rx_data_in_n <= ~i_bin_val[11:6]
                    self.rx_frame_asserted = True
                    self.dut.rx_frame_in_p <= 1
                    self.dut.rx_frame_in_n <= 0
                yield RisingEdge(self.dut.rx_clk_in_n)
                if self.rx_frame_asserted:
                    self.dut.rx_data_in_p <= q_bin_val[11:6]
                    self.dut.rx_data_in_n <= ~q_bin_val[11:6]
                else:
                    self.dut.rx_data_in_p <= q_bin_val[5:0]
                    self.dut.rx_data_in_n <= ~q_bin_val[5:0]
        else:
            I_SEND_HIGH = True
            Q_SEND_HIGH = True
            channel = 1
            while True:
                yield RisingEdge(self.dut.rx_clk_in_p)
                if I_SEND_HIGH:
                    self.dut.rx_data_in_p <= i_bin_val[11:6]
                    self.dut.rx_data_in_n <= ~i_bin_val[11:6]
                    I_SEND_HIGH = False
                    if channel == 1:
                        self.dut.rx_frame_in_p <= 1
                        self.dut.rx_frame_in_n <= 0
                    elif channel == 2:
                        self.dut.rx_frame_in_p <= 0
                        self.dut.rx_frame_in_n <= 1
                else:
                    self.dut.rx_data_in_p <= i_bin_val[5:0]
                    self.dut.rx_data_in_n <= ~i_bin_val[5:0]
                    I_SEND_HIGH = True
                yield RisingEdge(self.dut.rx_clk_in_n)
                if Q_SEND_HIGH:
                    self.dut.rx_data_in_p <= q_bin_val[5:0]
                    self.dut.rx_data_in_n <= ~q_bin_val[5:0]
                    Q_SEND_HIGH = False
                else:
                    self.dut.rx_data_in_p <= q_bin_val[11:6]
                    self.dut.rx_data_in_n <= ~q_bin_val[11:6]
                    Q_SEND_HIGH = True
                    if index < len(i_data):
                        if channel == 1:
                            i_bin_val.set_value(i_data[index])
                            q_bin_val.set_value(q_data[index])
                            channel = 2
                        elif channel == 2:
                            i_bin_val.set_value(i_data2[index])
                            q_bin_val.set_value(q_data2[index])
                            channel = 1
                            index += 1
                    else:
                        return
Exemplo n.º 23
0
def init_test(dut):
    dut.rst <= 1
    cocotb.fork(Clock(dut.clk, 10, 'ns').start())
    yield RisingEdge(dut.clk)
    dut.rst <= 0
    yield RisingEdge(dut.clk)
Exemplo n.º 24
0
 def __init__(self, itf: BaseSynchronousInterface, *args, **kwargs) -> None:
     self.re = RisingEdge(itf.clock)
     self.ro = ReadOnly()
     super().__init__(itf, *args, **kwargs)
Exemplo n.º 25
0
def clock_one(dut):
    count = 0
    while count is not 50:
        yield RisingEdge(dut.clk)
        yield Timer(1000)
        count += 1
Exemplo n.º 26
0
 def wait_cycles(dut, n):
     for _ in range(n):
         yield RisingEdge(dut.clk)
Exemplo n.º 27
0
def clock_two(dut):
    count = 0
    while count != 50:
        yield RisingEdge(dut.clk)
        yield Timer(10000)
        count += 1
Exemplo n.º 28
0
def pkt_switch_test(dut):
    """ PKT_SWITCH Test """

    log = cocotb.logging.getLogger("cocotb.test") # logger instance
    cocotb.fork(clock_gen(dut.clk, period=100))   # start clock running

    # reset & init
    dut.rst_n <= 1
    dut.datain_data <= 0
    dut.datain_valid <= 0
    dut.ctrl_addr <= 0
    dut.ctrl_data <= 0
    dut.ctrl_wr <= 0

    yield Timer(1000)
    dut.rst_n <= 0
    yield Timer(1000)
    dut.rst_n <= 1

    # procedure of writing configuration registers
    @cocotb.coroutine
    def write_config(addr, data):
        for [a, d] in zip(addr, data):
            dut.ctrl_addr <= a
            dut.ctrl_data <= d
            dut.ctrl_wr <= 1
            yield RisingEdge(dut.clk)
            dut.ctrl_wr <= 0

    enable_transmit_both = lambda: write_config([0], [4])
    disable_filtering = lambda: write_config([0], [0])

    @cocotb.coroutine
    def enable_addr_filtering(addr, mask):
        yield write_config([0, 2, 3], [1, addr, mask])

    @cocotb.coroutine
    def enable_len_filtering(low_limit, up_limit):
        yield write_config([0, 4, 5], [2, low_limit, up_limit])

    driver = PacketIFDriver(dut, name="datain", clock=dut.clk)
    monitor0 = PacketIFMonitor(dut, name="dataout0", clock=dut.clk)
    monitor1 = PacketIFMonitor(dut, name="dataout1", clock=dut.clk)

    expected_data0 = [] # queue of expeced packet at interface 0
    expected_data1 = [] # queue of expeced packet at interface 1


    def scoreboarding(pkt, queue_expected):
        assert pkt.addr == queue_expected[0].addr
        assert pkt.len == queue_expected[0].len
        assert pkt.payload == queue_expected[0].payload
        queue_expected.pop()

    monitor0.add_callback(lambda _ : scoreboarding(_, expected_data0))
    monitor1.add_callback(lambda _ : scoreboarding(_, expected_data1))
    monitor0.add_callback(lambda _ : log.info("Receiving packet on interface 0 (packet not filtered)"))
    monitor1.add_callback(lambda _ : log.info("Receiving packet on interface 1 (packet filtered)"))

    # functional coverage - check received packet

    @CoverPoint(
      "top.packet_length",
      xf = lambda pkt, event, addr, mask, ll, ul: pkt.len,    # packet length
      bins = list(range(3,32))                                # may be 3 ... 31 bytes
    )
    @CoverPoint("top.event", vname="event", bins = ["DIS", "TB", "AF", "LF"])
    @CoverPoint(
      "top.filt_addr",
      xf = lambda pkt, event, addr, mask, ll, ul:         # filtering based on particular bits in header
        (addr & mask & 0x0F) if event == "AF" else None,  # check only if event is "address filtering"
      bins = list(range(16)),                             # check only 4 LSBs if all options tested
    )
    @CoverPoint(
      "top.filt_len_eq",
      xf = lambda pkt, event, addr, mask, ll, ul: ll == ul,  # filtering of a single packet length
      bins = [True, False]
    )
    @CoverPoint(
      "top.filt_len_ll",
      vname = "ll",                    # lower limit of packet length
      bins = list(range(3,32))         # 3 ... 31
    )
    @CoverPoint(
      "top.filt_len_ul",
      vname = "ul",                    # upper limit of packet length
      bins = list(range(3,32))         # 3 ... 31
    )
    @CoverCross(
      "top.filt_len_ll_x_packet_length",
      items = ["top.packet_length", "top.filt_len_ll"]
    )
    @CoverCross(
      "top.filt_len_ul_x_packet_length",
      items = ["top.packet_length", "top.filt_len_ul"]
    )
    def log_sequence(pkt, event, addr, mask, ll, ul):
        log.info("Processing packet:")
        log.info("  ADDRESS: %X", pkt.addr)
        log.info("  LENGTH: %d", pkt.len)
        log.info("  PAYLOAD: " + str(pkt.payload))
        if event is "DIS":
            log.info("Filtering disabled")
        elif event is "TB":
            log.info("Transmit on both interfaces")
        elif event is "AF":
            log.info("Address filtering, address: %02X, mask: %02X", addr, mask)
        elif event is "LF":
            log.info("Length filtering, lower limit: %d, upper limit: %d", ll, ul)

    # main loop
    for _ in range(1000): # is that enough repetitions to ensure coverage goal? Check out!

        event = np.random.choice(["DIS", "TB", "AF", "LF"])
        # DIS - disable filtering : expect all packets on interface 0
        # TB  - transmit bot : expect all packets on interface 0 and 1
        # AF  - address filtering : expect filtered packets on interface 1, others on 0
        # LF  - length filtering : expect filtered packets on interface 1, others on 0

        # randomize test data
        pkt = Packet();
        pkt.randomize()
        addr = np.random.randint(256)               # 0x00 .. 0xFF
        mask = np.random.randint(256)               # 0x00 .. 0xFF
        low_limit = np.random.randint(3,32)         # 3 ... 31
        up_limit = np.random.randint(low_limit,32)  # low_limit ... 31

        # expect the packet on the particular interface
        if event == "DIS":
            yield disable_filtering()
            expected_data0.append(pkt)
        elif event == "TB":
            yield enable_transmit_both()
            expected_data0.append(pkt)
            expected_data1.append(pkt)
        elif event == "AF":
            yield enable_addr_filtering(addr, mask)
            if ((pkt.addr & mask) == (addr & mask)):
                expected_data1.append(pkt)
            else:
                expected_data0.append(pkt)
        elif event == "LF":
            yield enable_len_filtering(low_limit, up_limit)
            if (low_limit <= pkt.len <= up_limit):
                expected_data1.append(pkt)
            else:
                expected_data0.append(pkt)

        # wait DUT
        yield driver.send(pkt)
        yield RisingEdge(dut.clk)
        yield RisingEdge(dut.clk)

        # LOG the action
        log_sequence(pkt, event, addr, mask, low_limit, up_limit)

    # print coverage report
    coverage_db.report_coverage(log.info, bins=False)
    # export
    coverage_db.export_to_xml(filename="coverage_pkt_switch.xml")
    coverage_db.export_to_yaml(filename="coverage_pkt_switch.yml")
Exemplo n.º 29
0
def wait_for_signals(self, entity, signals=[]):
    yield ReadOnly()
    while (any(entity.sig.value.integer != 1 for sign in signals)):
        yield [RisingEdge(entity.sig.value) for sign in signals]
        yield ReadOnly()
    yield NextTimeStep()
Exemplo n.º 30
0
 def flush_pipeline(self):
     for _ in range(self.pipeline_latency):
         yield RisingEdge(self.dut.pixel_clk)