def basic_bringup(dut): cocotb.fork(Clock(dut.clk_i, CLOCK_PERIOD).start()) yield reset_dut(dut.rst_ni, RESET_TIME) yield Timer(10000)
import cocotb from cocotb.clock import Clock from cocotb.triggers import RisingEdge, ClockCycles from cocotb.result import TestFailure, TestSuccess from cocotb.regression import TestFactory DEBUG = 0 @cocotb.coroutine def test(dut, wclk, rclk, async): if not async and (wclk != rclk): raise TestSuccess("Test of the SYNC version with different clock domains is SKIPPED.") cocotb.fork(Clock(dut.wclk_i, wclk).start()) cocotb.fork(Clock(dut.rclk_i, rclk).start()) dut.async_i <= async yield reset(dut) yield test_signaling(dut) yield test_running(dut) factory = TestFactory(test) factory.add_option("wclk", [4,10]) factory.add_option("rclk", [4,10]) factory.add_option("async", [0,1]) factory.generate_tests() @cocotb.coroutine def reset(dut): dut.wrst_i <= 1 dut.wen_i <= 0 dut.data_i <= 0 dut.rrst_i <= 1
def create_clock(dut): cocotb.fork(Clock(dut.clk, 10, 'ns').start())
async def test_icez0mb1e_gpio_loopback(dut): dv = dv_test(dut) clk = Clock(dut.clk, 10, units="ns") # Create a 10us period clock on port clk cocotb.fork(clk.start()) # Start the clock dut.uart_txd = 0 dut.P1_in = 0x55 dut.P2_in = 0xAA # THIS WORKS. X IS CORRECTLY ASSIGNED to miso # dut._log.info("AAA before spi loop back") # val = dut.spi_mosi.value.binstr # dut._log.info("+++ mosi=" + val) # dut.spi_miso <= dut.spi_mosi.value # for i in range(20): # val = dut.spi_mosi.value.binstr # dut._log.info("AAA mosi=" + val) # dut.spi_miso <= dut.spi_mosi.value # await Edge(dut.spi_mosi) # dut._log.info("AAA after spi loop back") # THIS WORKS. X IS CORRECTLY ASSIGNED to miso dut._log.info("BBB Before assignng X to P2_in") # works dut.P2_in <= int(dut.P1_out.value) + 5 dut._log.info(dut.P2_in.value) dut.P2_in <= dut.P1_out.value dut._log.info(dut.P2_in.value) await FallingEdge(dut.clk) dut._log.info(dut.P2_in.value) dut._log.info("BBB1 After assignng X to P2_in") dut.P2_in <= dut.P1_out await FallingEdge(dut.clk) dut._log.info("BBB2 After assignng X to P2_in") dv.info("dut.P1_out.value =" + str(type(dut.P1_out.value))) dv.info("dut.P1_out =" + str(type(dut.P1_out))) dv.info("dut =" + str(type(dut))) for i in range(1000): await FallingEdge(dut.clk) ### dut.P2_in <= dut.P1_out if (i + 1) % 1000 == 0: dv.info(str(i + 1)) # assert val == 0, "Error count from Z80 for GPIO Loopback Test" dut._log.info("DUT OUTPUT") dut._log.info(dut.P1_out.value) dut._log.info("BEFORE ASSIGMENT") dut._log.info(dut.P2_in.value) ### dut.P2_in <= dut.P1_out.value dut.P2_in <= dut.P1_out dut._log.info("IMMEDIATELY AFTER ASSIGMENT") dut._log.info(dut.P2_in.value) await FallingEdge(dut.clk) dut._log.info("AFTER AWAIT ASSIGMENT") dut._log.info(dut.P2_in.value) dv.info("SPI SHOULD BE READING") ### ============================================================================================================= ### SPI TEST ### TEST MODE 0 spi_val = "10010111" dut.P2_in <= 0x70 for i in range(10): spi_val = await spi_periph(dut, dut.spi_sclk, dut.spi_cs, dut.spi_mosi, dut.spi_miso, "{:08b}".format(int(spi_val))) dv.info("0. spi_val = " + str(int(spi_val, 2)) + " expect = " + str(int(dut.P1_out.value.binstr, 2))) ### TEST MODE 1 dut.P2_in <= 0x71 for i in range(10): spi_val = await spi_periph(dut, dut.spi_sclk, dut.spi_cs, dut.spi_mosi, dut.spi_miso, "{:08b}".format(int(spi_val)), 1) dv.info("1. spi_val = " + str(int(spi_val, 2)) + " expect = " + str(int(dut.P1_out.value.binstr, 2))) ### TEST MODE 2 dut.P2_in <= 0x72 for i in range(10): spi_val = await spi_periph(dut, dut.spi_sclk, dut.spi_cs, dut.spi_mosi, dut.spi_miso, "{:08b}".format(int(spi_val)), 2) dv.info("2. spi_val = " + str(int(spi_val, 2)) + " expect = " + str(int(dut.P1_out.value.binstr, 2))) ### TEST MODE 3 dut.P2_in <= 0x73 for i in range(10): spi_val = await spi_periph(dut, dut.spi_sclk, dut.spi_cs, dut.spi_mosi, dut.spi_miso, "{:08b}".format(int(spi_val)), 3) dv.info("3. spi_val = " + str(int(spi_val, 2)) + " expect = " + str(int(dut.P1_out.value.binstr, 2))) dv.info("After SPI TEST") await ClockCycles(dut.clk, 1000)
def C_load_second_test(dut): """ Resets data and tries again """ log = SimLog("cocotb.%s" % dut._name) log.setLevel(logging.DEBUG) cocotb.fork(Clock(dut.clk_i, 1000).start()) filename = '../test_data/wpa2-psk-linksys.hccap' obj = wpa2slow.Handshake() obj.load(filename) ssid = obj.ssid mac1 = obj.mac1 mac2 = obj.mac2 nonce1 = obj.nonce1 nonce2 = obj.nonce2 eapol = obj.eapol eapol_size = obj.eapol_size keymic = obj.keymic dut.cs_i <= 1 yield reset(dut) yield RisingEdge(dut.clk_i) yield load_file(dut, filename) #This clock isn't necessary while pipelining yield RisingEdge(dut.clk_i) #yield wait_process(dut) ssid_test1 = dut.test_ssid_1 ssid_test2 = dut.test_ssid_2 ssid_test3 = dut.test_ssid_3 if ord(ssid[0]) != int(str(ssid_test1), 2): raise TestFailure("ssid_test1 differs from mock") elif ord(ssid[3]) != int(str(ssid_test2), 2): raise TestFailure("ssid_test2 differs from mock") elif ord(ssid[6]) != int(str(ssid_test3), 2): raise TestFailure("ssid_test3 differs from mock") elif ord(ssid[6]) == int( str(ssid_test1), 2): #Todo: remove false positive if 1st and 7th chars equal raise TestFailure("SSID comparisons failing.") else: log.info("SSID Ok!") mic_test1 = dut.test_keymic_1 mic_test2 = dut.test_keymic_2 mic_test3 = dut.test_keymic_3 if ord(keymic[0]) != int(str(mic_test1), 2): raise TestFailure("mic_test1 differs from mock") elif ord(keymic[14]) != int(str(mic_test2), 2): raise TestFailure("mic_test2 differs from mock") elif ord(keymic[15]) != int(str(mic_test3), 2): raise TestFailure("mic_test3 differs from mock") elif ord(keymic[5]) == int(str(mic_test1), 2): #Todo: remove false positive raise TestFailure("MIC comparisons failing.") else: log.info("MIC Ok!")
def create_clock(dut): cocotb.fork(Clock(dut.clk, CLK_PERIOD, 'ns').start())
def setup_dut(dut): cocotb.fork(Clock(dut.clock, CLOCK_PERIOD, units="ns").start())
def test_dut(dut): ''' The testbench: * binds the interfaces * Loads the Key * Loads the IV in the ICB * Sends the AAD data through the pipeline * Sends the PT data through the pipeline * Checks the CT and the MAC match the model ''' # Create the lists of transactions aad_tran = [] pt_tran = [] aad_model_tran = [] pt_model_tran = [] tb = gcm_gctr(dut) # Open config file with open('./tmp/' + str(cocotb.RANDOM_SEED) + '.json', 'r') as config_file: tb.config = dict(json.load(config_file)) # Generate configuration data tb.config_data() # Initialise GCM model dut_model = gcm_model.gcm(tb.data['key'], tb.data['iv']) # Create drivers pkt_drv = pkt_driver(dut.clk_i, dut.aes_gcm_ghash_pkt_val_i) aad_drv = aad_driver(dut.clk_i, dut.aes_gcm_ghash_aad_bval_i, dut.aes_gcm_ghash_aad_i) pt_drv = pt_driver(dut.clk_i, dut.aes_gcm_plain_text_bval_i, dut.aes_gcm_plain_text_i, dut.aes_gcm_cipher_ready_o) # Create delay function delay = wait_for(dut.clk_i, RisingEdge) # Get the AES mode dut._log.info('AES mode: ' + tb.config['aes_mode']) # Get AES key size dut._log.info('AES size: ' + tb.config['aes_size']) # Release the Reset cocotb.fork(tb.release_rst(RST_WINDOW)) # Start the Clock cocotb.fork(Clock(dut.clk_i, CLK_PERIOD, 'ns').start()) # Wait for the Reset falling edge event yield FallingEdge(dut.rst_i) # Wait few clocks yield ClockCycles(dut.clk_i, random.randint(10, 20)) # Create the sequencer seq = sequencer(pkt_drv, aad_drv, pt_drv, delay.n_clk, tb.data, str(tb.config['seed']), aad_tran, pt_tran) # Create monitors mon_aad = gcm_AAD_monitor("Get AAD", dut, dut_model.load_aad) mon_pt = gcm_PT_monitor("Get PT", dut, dut_model.load_plain_text) mon_ct = gcm_CT_monitor("Get CT", dut) mon_tag = gcm_TAG_monitor("Get TAG", dut, dut_model.get_tag) # Create scoreboard scoreboard = Scoreboard(dut) # Add scoreboard interfaces scoreboard.add_interface(mon_aad, aad_model_tran) scoreboard.add_interface(mon_pt, pt_model_tran) scoreboard.add_interface(mon_ct, dut_model.ct) scoreboard.add_interface(mon_tag, dut_model.tag) # Set AES key mode yield tb.aes_set_mode() # Load the KEY if (tb.config['key_pre_exp'] == True): yield tb.load_pre_exp_key(tb.data['key']) else: yield tb.load_key(tb.data['key']) # Load the ICB yield tb.load_iv(tb.data['iv']) # Start The ICB yield tb.start_icb() # Wait the AES to produce cipher data yield tb.cipher_is_ready() # Set the number of AAD transactions n_transaction = tb.data['aad_n_bytes'] >> 4 if tb.data['aad_n_bytes'] & 0xF: n_transaction += 1 dut._log.info('\n' + str(n_transaction) + " AAD transactions to read") # Set the number of PT transactions n_transaction = tb.data['pt_n_bytes'] >> 4 if tb.data['pt_n_bytes'] & 0xF: n_transaction += 1 dut._log.info(str(n_transaction) + " PT transactions to read\n") # Start the sequencer seq.start_sequencer() # Encrypt data yield tb.encrypt_data(tb.data['aad_n_bytes'], tb.data['pt_n_bytes'], aad_tran, pt_tran, aad_model_tran, pt_model_tran) # Wait for the test to finish while dut.aes_gcm_ghash_tag_val_o.value == 0: yield RisingEdge(dut.clk_i) last_cycles = ClockCycles(dut.clk_i, 20) yield last_cycles
def setup_function(dut, key, iv): cocotb.fork(Clock(dut.clk, CLK_PERIOD).start()) dut.rst = 0 dut.en = 0 dut.key = key dut.iv = iv
async def setup_dut(dut): cocotb.fork(Clock(dut.aclk, CLK_PERIOD, "ns").start()) dut.aresetn <= 0 await Timer(CLK_PERIOD * 2, "ns") dut.aresetn <= 1 await Timer(CLK_PERIOD * 2, "ns")
def __init__(self, dut): self.dut = dut self.log = SimLog("cocotb.tb") self.log.setLevel(logging.DEBUG) cocotb.fork(Clock(dut.clk, 6.4, units="ns").start()) # Ethernet cocotb.fork(Clock(dut.qsfp0_rx_clk_1, 6.4, units="ns").start()) self.qsfp0_1_source = XgmiiSource(dut.qsfp0_rxd_1, dut.qsfp0_rxc_1, dut.qsfp0_rx_clk_1, dut.qsfp0_rx_rst_1) cocotb.fork(Clock(dut.qsfp0_tx_clk_1, 6.4, units="ns").start()) self.qsfp0_1_sink = XgmiiSink(dut.qsfp0_txd_1, dut.qsfp0_txc_1, dut.qsfp0_tx_clk_1, dut.qsfp0_tx_rst_1) cocotb.fork(Clock(dut.qsfp0_rx_clk_2, 6.4, units="ns").start()) self.qsfp0_2_source = XgmiiSource(dut.qsfp0_rxd_2, dut.qsfp0_rxc_2, dut.qsfp0_rx_clk_2, dut.qsfp0_rx_rst_2) cocotb.fork(Clock(dut.qsfp0_tx_clk_2, 6.4, units="ns").start()) self.qsfp0_2_sink = XgmiiSink(dut.qsfp0_txd_2, dut.qsfp0_txc_2, dut.qsfp0_tx_clk_2, dut.qsfp0_tx_rst_2) cocotb.fork(Clock(dut.qsfp0_rx_clk_3, 6.4, units="ns").start()) self.qsfp0_3_source = XgmiiSource(dut.qsfp0_rxd_3, dut.qsfp0_rxc_3, dut.qsfp0_rx_clk_3, dut.qsfp0_rx_rst_3) cocotb.fork(Clock(dut.qsfp0_tx_clk_3, 6.4, units="ns").start()) self.qsfp0_3_sink = XgmiiSink(dut.qsfp0_txd_3, dut.qsfp0_txc_3, dut.qsfp0_tx_clk_3, dut.qsfp0_tx_rst_3) cocotb.fork(Clock(dut.qsfp0_rx_clk_4, 6.4, units="ns").start()) self.qsfp0_4_source = XgmiiSource(dut.qsfp0_rxd_4, dut.qsfp0_rxc_4, dut.qsfp0_rx_clk_4, dut.qsfp0_rx_rst_4) cocotb.fork(Clock(dut.qsfp0_tx_clk_4, 6.4, units="ns").start()) self.qsfp0_4_sink = XgmiiSink(dut.qsfp0_txd_4, dut.qsfp0_txc_4, dut.qsfp0_tx_clk_4, dut.qsfp0_tx_rst_4) cocotb.fork(Clock(dut.qsfp1_rx_clk_1, 6.4, units="ns").start()) self.qsfp1_1_source = XgmiiSource(dut.qsfp1_rxd_1, dut.qsfp1_rxc_1, dut.qsfp1_rx_clk_1, dut.qsfp1_rx_rst_1) cocotb.fork(Clock(dut.qsfp1_tx_clk_1, 6.4, units="ns").start()) self.qsfp1_1_sink = XgmiiSink(dut.qsfp1_txd_1, dut.qsfp1_txc_1, dut.qsfp1_tx_clk_1, dut.qsfp1_tx_rst_1) cocotb.fork(Clock(dut.qsfp1_rx_clk_2, 6.4, units="ns").start()) self.qsfp1_2_source = XgmiiSource(dut.qsfp1_rxd_2, dut.qsfp1_rxc_2, dut.qsfp1_rx_clk_2, dut.qsfp1_rx_rst_2) cocotb.fork(Clock(dut.qsfp1_tx_clk_2, 6.4, units="ns").start()) self.qsfp1_2_sink = XgmiiSink(dut.qsfp1_txd_2, dut.qsfp1_txc_2, dut.qsfp1_tx_clk_2, dut.qsfp1_tx_rst_2) cocotb.fork(Clock(dut.qsfp1_rx_clk_3, 6.4, units="ns").start()) self.qsfp1_3_source = XgmiiSource(dut.qsfp1_rxd_3, dut.qsfp1_rxc_3, dut.qsfp1_rx_clk_3, dut.qsfp1_rx_rst_3) cocotb.fork(Clock(dut.qsfp1_tx_clk_3, 6.4, units="ns").start()) self.qsfp1_3_sink = XgmiiSink(dut.qsfp1_txd_3, dut.qsfp1_txc_3, dut.qsfp1_tx_clk_3, dut.qsfp1_tx_rst_3) cocotb.fork(Clock(dut.qsfp1_rx_clk_4, 6.4, units="ns").start()) self.qsfp1_4_source = XgmiiSource(dut.qsfp1_rxd_4, dut.qsfp1_rxc_4, dut.qsfp1_rx_clk_4, dut.qsfp1_rx_rst_4) cocotb.fork(Clock(dut.qsfp1_tx_clk_4, 6.4, units="ns").start()) self.qsfp1_4_sink = XgmiiSink(dut.qsfp1_txd_4, dut.qsfp1_txc_4, dut.qsfp1_tx_clk_4, dut.qsfp1_tx_rst_4)
def __init__(self, dut): self.dut = dut self.log = SimLog("cocotb.tb") self.log.setLevel(logging.DEBUG) cocotb.start_soon(Clock(dut.clk, 2.56, units="ns").start()) # Ethernet cocotb.start_soon(Clock(dut.phy_gmii_clk, 8, units="ns").start()) self.gmii_source = GmiiSource(dut.phy_gmii_rxd, dut.phy_gmii_rx_er, dut.phy_gmii_rx_dv, dut.phy_gmii_clk, dut.phy_gmii_rst, dut.phy_gmii_clk_en) self.gmii_sink = GmiiSink(dut.phy_gmii_txd, dut.phy_gmii_tx_er, dut.phy_gmii_tx_en, dut.phy_gmii_clk, dut.phy_gmii_rst, dut.phy_gmii_clk_en) dut.phy_gmii_clk_en.setimmediatevalue(1) cocotb.start_soon(Clock(dut.qsfp1_rx_clk_1, 2.56, units="ns").start()) self.qsfp1_1_source = XgmiiSource(dut.qsfp1_rxd_1, dut.qsfp1_rxc_1, dut.qsfp1_rx_clk_1, dut.qsfp1_rx_rst_1) cocotb.start_soon(Clock(dut.qsfp1_tx_clk_1, 2.56, units="ns").start()) self.qsfp1_1_sink = XgmiiSink(dut.qsfp1_txd_1, dut.qsfp1_txc_1, dut.qsfp1_tx_clk_1, dut.qsfp1_tx_rst_1) cocotb.start_soon(Clock(dut.qsfp1_rx_clk_2, 2.56, units="ns").start()) self.qsfp1_2_source = XgmiiSource(dut.qsfp1_rxd_2, dut.qsfp1_rxc_2, dut.qsfp1_rx_clk_2, dut.qsfp1_rx_rst_2) cocotb.start_soon(Clock(dut.qsfp1_tx_clk_2, 2.56, units="ns").start()) self.qsfp1_2_sink = XgmiiSink(dut.qsfp1_txd_2, dut.qsfp1_txc_2, dut.qsfp1_tx_clk_2, dut.qsfp1_tx_rst_2) cocotb.start_soon(Clock(dut.qsfp1_rx_clk_3, 2.56, units="ns").start()) self.qsfp1_3_source = XgmiiSource(dut.qsfp1_rxd_3, dut.qsfp1_rxc_3, dut.qsfp1_rx_clk_3, dut.qsfp1_rx_rst_3) cocotb.start_soon(Clock(dut.qsfp1_tx_clk_3, 2.56, units="ns").start()) self.qsfp1_3_sink = XgmiiSink(dut.qsfp1_txd_3, dut.qsfp1_txc_3, dut.qsfp1_tx_clk_3, dut.qsfp1_tx_rst_3) cocotb.start_soon(Clock(dut.qsfp1_rx_clk_4, 2.56, units="ns").start()) self.qsfp1_4_source = XgmiiSource(dut.qsfp1_rxd_4, dut.qsfp1_rxc_4, dut.qsfp1_rx_clk_4, dut.qsfp1_rx_rst_4) cocotb.start_soon(Clock(dut.qsfp1_tx_clk_4, 2.56, units="ns").start()) self.qsfp1_4_sink = XgmiiSink(dut.qsfp1_txd_4, dut.qsfp1_txc_4, dut.qsfp1_tx_clk_4, dut.qsfp1_tx_rst_4) cocotb.start_soon(Clock(dut.qsfp2_rx_clk_1, 2.56, units="ns").start()) self.qsfp2_1_source = XgmiiSource(dut.qsfp2_rxd_1, dut.qsfp2_rxc_1, dut.qsfp2_rx_clk_1, dut.qsfp2_rx_rst_1) cocotb.start_soon(Clock(dut.qsfp2_tx_clk_1, 2.56, units="ns").start()) self.qsfp2_1_sink = XgmiiSink(dut.qsfp2_txd_1, dut.qsfp2_txc_1, dut.qsfp2_tx_clk_1, dut.qsfp2_tx_rst_1) cocotb.start_soon(Clock(dut.qsfp2_rx_clk_2, 2.56, units="ns").start()) self.qsfp2_2_source = XgmiiSource(dut.qsfp2_rxd_2, dut.qsfp2_rxc_2, dut.qsfp2_rx_clk_2, dut.qsfp2_rx_rst_2) cocotb.start_soon(Clock(dut.qsfp2_tx_clk_2, 2.56, units="ns").start()) self.qsfp2_2_sink = XgmiiSink(dut.qsfp2_txd_2, dut.qsfp2_txc_2, dut.qsfp2_tx_clk_2, dut.qsfp2_tx_rst_2) cocotb.start_soon(Clock(dut.qsfp2_rx_clk_3, 2.56, units="ns").start()) self.qsfp2_3_source = XgmiiSource(dut.qsfp2_rxd_3, dut.qsfp2_rxc_3, dut.qsfp2_rx_clk_3, dut.qsfp2_rx_rst_3) cocotb.start_soon(Clock(dut.qsfp2_tx_clk_3, 2.56, units="ns").start()) self.qsfp2_3_sink = XgmiiSink(dut.qsfp2_txd_3, dut.qsfp2_txc_3, dut.qsfp2_tx_clk_3, dut.qsfp2_tx_rst_3) cocotb.start_soon(Clock(dut.qsfp2_rx_clk_4, 2.56, units="ns").start()) self.qsfp2_4_source = XgmiiSource(dut.qsfp2_rxd_4, dut.qsfp2_rxc_4, dut.qsfp2_rx_clk_4, dut.qsfp2_rx_rst_4) cocotb.start_soon(Clock(dut.qsfp2_tx_clk_4, 2.56, units="ns").start()) self.qsfp2_4_sink = XgmiiSink(dut.qsfp2_txd_4, dut.qsfp2_txc_4, dut.qsfp2_tx_clk_4, dut.qsfp2_tx_rst_4) dut.btnu.setimmediatevalue(0) dut.btnl.setimmediatevalue(0) dut.btnd.setimmediatevalue(0) dut.btnr.setimmediatevalue(0) dut.btnc.setimmediatevalue(0) dut.sw.setimmediatevalue(0) dut.uart_rxd.setimmediatevalue(0) dut.uart_cts.setimmediatevalue(0)
async def main(dut): # Create a 10us period clock on port clk clock = Clock(dut.clk_i, 10, units="us") cocotb.fork(clock.start()) # Reset system await FallingEdge(dut.clk_i) dut.la_data_in_i <= 0 disable_la_write(dut) dut.ctl_pipeline_en_i <= 0 # dut.mic_pdm_data_i <= 0 dut.dfe_data_i <= 0 dut.dfe_valid_i <= 0 dut.aco_data_i <= 0 dut.aco_valid_i <= 0 dut.aco_last_i <= 0 dut.wrd_wake_i <= 0 dut.wrd_wake_valid_i <= 0 # reset await FallingEdge(dut.clk_i) dut.rst_n_i <= 1 dut.la_data_in_i <= 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF # test CTL await FallingEdge(dut.clk_i) assert dut.ctl_pipeline_en_o.value == 0 assert get_la_data_slice(dut, pipeline_en_slice) == 0 enable_la_write(dut, [pipeline_en_slice]) await FallingEdge(dut.clk_i) assert dut.ctl_pipeline_en_o.value == 1 assert get_la_data_slice(dut, pipeline_en_slice) == 0 check_other_slices_unchanged(dut, [pipeline_en_slice]) disable_la_write(dut) # test MIC -> DFE ''' # skip pdm for cocotb sim await FallingEdge(dut.clk_i) assert dut.mic_pdm_data_o.value == 0 assert get_la_data_slice(dut, mic_data_slice) == 0 enable_la_write(dut, [mic_data_slice]) await FallingEdge(dut.clk_i) assert dut.mic_pdm_data_o.value == 1 assert get_la_data_slice(dut, mic_data_slice) == 0 check_other_slices_unchanged(dut, [mic_data_slice]) disable_la_write(dut) ''' # test DFE -> ACO await FallingEdge(dut.clk_i) assert dut.dfe_data_o.value == 0 assert dut.dfe_valid_o.value == 0 assert get_la_data_slice(dut, dfe_data_slice) == 0 assert get_la_data_slice(dut, dfe_valid_slice) == 0 enable_la_write(dut, [dfe_data_slice, dfe_valid_slice]) dut.dfe_data_i <= 0xDE await FallingEdge(dut.clk_i) assert dut.dfe_data_o.value == 0xFF assert dut.dfe_valid_o.value == 1 assert get_la_data_slice(dut, dfe_data_slice) == 0xDE assert get_la_data_slice(dut, dfe_valid_slice) == 0 check_other_slices_unchanged(dut, [dfe_data_slice, dfe_valid_slice]) disable_la_write(dut) dut.dfe_data_i <= 0 await FallingEdge(dut.clk_i) # test ACO -> WRD await FallingEdge(dut.clk_i) assert dut.aco_data_o.value == 0 assert dut.aco_valid_o.value == 0 assert dut.aco_last_o.value == 0 assert get_la_data_slice(dut, aco_data_slice) == 0 assert get_la_data_slice(dut, aco_valid_slice) == 0 assert get_la_data_slice(dut, aco_last_slice) == 0 enable_la_write(dut, [aco_data_slice, aco_valid_slice, aco_last_slice]) dut.aco_data_i <= 0xDEADBEEFDEADBEEFDEADBEEFCC await FallingEdge(dut.clk_i) assert dut.aco_data_o.value == 0xFFFFFFFFFFFFFFFFFFFFFFFFFF assert dut.aco_valid_o.value == 1 assert dut.aco_last_o.value == 1 assert get_la_data_slice(dut, aco_data_slice) == 0xDEADBEEFDEADBEEFDEADBEEFCC assert get_la_data_slice(dut, aco_valid_slice) == 0 assert get_la_data_slice(dut, aco_last_slice) == 0 check_other_slices_unchanged( dut, [aco_data_slice, aco_valid_slice, aco_last_slice]) disable_la_write(dut) dut.aco_data_i <= 0 await FallingEdge(dut.clk_i) # test WRD -> Wake await FallingEdge(dut.clk_i) assert dut.wrd_wake_o.value == 0 assert dut.wrd_wake_valid_o.value == 0 assert get_la_data_slice(dut, wrd_wake_slice) == 0 assert get_la_data_slice(dut, wrd_wake_valid_slice) == 0 enable_la_write(dut, [wrd_wake_slice, wrd_wake_valid_slice]) await FallingEdge(dut.clk_i) assert dut.wrd_wake_o.value == 1 assert dut.wrd_wake_valid_o.value == 1 assert get_la_data_slice(dut, wrd_wake_slice) == 0 assert get_la_data_slice(dut, wrd_wake_valid_slice) == 0 check_other_slices_unchanged(dut, [wrd_wake_slice, wrd_wake_valid_slice]) disable_la_write(dut)
def test_tree(dut): """Testing APBI2C core""" log = cocotb.logging.getLogger("cocotb.test") cocotb.fork(Clock(dut.PCLK, 1000).start()) #instantiate the APB agent (monitor and driver) (see apb.py) apb = APBSlave(dut, name=None, clock=dut.PCLK) #instantiate the I2C monitor and driver (see i2c.py) i2c_monitor = I2CMonitor(dut, name="", clock=dut.PCLK) i2c_driver = I2CDriver(dut, name=None, clock=dut.PCLK) #write to config register via APB @cocotb.coroutine def config_write(addr, data): xaction = APBTransaction(addr, data, write=True) xaction.randomize() yield apb.send(xaction) #store observed I2C transactions received_i2c_xactions = [] #the catcher for observerd I2C transaction on the interfece @I2CCoverage def i2c_xaction_catcher(i2c_xaction): if LOG_XACTION_ENABLE: log.info("I2C Monitor: Transaction 0x%08X" % i2c_xaction.data) received_i2c_xactions.append(i2c_xaction) #callback to the monitor to call the catcher when I2C transaction observed i2c_monitor.add_callback(i2c_xaction_catcher) #the catcher for observerd APB transaction on the interfece @APBCoverage def apb_xaction_catcher(apb_xaction): if LOG_XACTION_ENABLE: try: log.info("APB Transaction %s 0x%08X -> 0x%08X" % ("Write" if apb_xaction.write else "Read ", int(apb_xaction.addr), int(apb_xaction.data))) except: log.info("APB Transaction %s 0x%08X -> 0x%08s" % ("Write" if apb_xaction.write else "Read ", int(apb_xaction.addr), int(apb_xaction.data))) #callback to the monitor to call the catcher when APB transaction observed apb.add_callback(apb_xaction_catcher) #define "I2C Operation" as a bunch of r/ws with defined number of data #and a specific clock divider #this is the main stuff to be tested - we want to know if controller #correctly processes transfers with different directions, amount of #data and SCK period class I2C_Operation(Randomized): def __init__(self, direction='write', repeat=1, divider=1): Randomized.__init__(self) self.direction = direction self.repeat = repeat self.divider = divider self.repeat_range = (1, 3) self.divider_range = (1, 3) #I2C_Operation objects may be fully randomized self.addRand("direction", ["write", "read"]) self.addRand("repeat_range", [(1, 3), (4, 7), (8, 11), (12, 15), (16, 23), (24, 31)]) self.addRand("divider_range", [(1, 3), (4, 7), (8, 11), (12, 15), (16, 23), (24, 31)]) #post_randomize to pick random values from already randomized ranges def post_randomize(self): self.repeat = random.randint(self.repeat_range[0], self.repeat_range[1]) self.divider = random.randint(self.divider_range[0], self.divider_range[1]) #list of completed operations for the summary operations_completed = [] #function sampling operations order coverage (see coverage.py) @OperationsOrderCoverage def sample_operations_order_coverage(prev_operation, operation): pass #function sampling operations coverage (see coverage.py) @OperationsCoverage def sample_operation(operation, ok): operations_completed.append((operation, ok)) if (len(operations_completed) > 1): sample_operations_order_coverage(operations_completed[-2][0], operations_completed[-1][0]) if ok: log.info( "Operation %s of %d words, divider %d - OK!" % (operation.direction, operation.repeat, operation.divider)) else: log.error( "Operation %s of %d words, divider %d - error!" % (operation.direction, operation.repeat, operation.divider)) #a test sequence - complete I2C Write Operation @cocotb.coroutine def segment_i2c_write_operation(operation): expected_out = [] yield config_write(8, 0x0001 | (operation.divider << 2)) #create xaction objects and fill FIFO up via APB with data to be send apb_xaction = APBTransaction(0, 0, write=True) for i in range(operation.repeat): i2c_xaction = I2CTransaction(0, write=False) i2c_xaction.randomize() apb_xaction.data = i2c_xaction.data apb_xaction.randomize() yield apb.send(apb_xaction) expected_out.append(i2c_xaction) #wait for FIFO empty - meaning all data sent out guard_int = 0 while not dut.INT_TX.value: guard_int = guard_int + 1 yield RisingEdge(dut.PCLK) if guard_int == 50000: raise TestFailure("Controller hang-up!") #a simple scoreboarding... #compare data written to APB with catched on I2C interface ok = True received_xactions = received_i2c_xactions[-operation.repeat:] if len(received_xactions) < operation.repeat: ok = False else: for i in range(operation.repeat): if (received_xactions[i] != expected_out[i]): ok = False break #call sampling at the and of the sequence sample_operation(operation, ok) #a test sequence - complete I2C Read Operation @cocotb.coroutine def segment_i2c_read_operation(operation): expected_in = [] yield config_write(8, 0x0002 | (operation.divider << 2)) #create I2C xaction objects and send on the interface for i in range(operation.repeat): i2c_xaction = I2CTransaction(0, write=True) i2c_xaction.randomize() expected_in.append(i2c_xaction) yield i2c_driver.send(i2c_xaction) #a simple scoreboarding... #compare data written on I2C interface with read from FIFO ok = True apb_xaction = APBTransaction(0x04, 0, write=False) for i in range(operation.repeat): try: apb_xaction.randomize() rdata = yield apb.send(xaction) if (rdata != expected_in[i].data): ok = False except: if LOG_XACTION_ENABLE: log.error("APB read data from FIFO is 'X'") ok = False #call sampling at the and of the sequence sample_operation(operation, ok) #a test sequence - APB registers operation (sort of UVM_REG :) ) @cocotb.coroutine def segment_apb_rw(repeat=1, addr=0xC): apb_xaction_wr = APBTransaction(addr, 0, write=True) apb_xaction_rd = APBTransaction(addr, 0, write=False) #just do some APB/RW for i in range(repeat): data = random.randint(0, 0xFFFFFFFF) apb_xaction_wr.randomize() apb_xaction_wr.data = data yield apb.send(apb_xaction_wr) apb_xaction_rd.randomize() rdata = yield apb.send(apb_xaction_rd) if LOG_XACTION_ENABLE: try: if rdata != data: log.error( "APB read data @ 0x%08X does not match written value" % addr) except: log.error("APB read data @ 0x%08X is 'X'" % addr) #reset the DUT dut.PRESETn <= 0 yield Timer(2000) dut.PRESETn <= 1 yield config_write(12, 0x0100) #if checkpoints used, store them in the map, (see checkpoint.py) if ENABLE_CHECKPOINTS: checkpoints = {} get_checkpoint_hier(dut) #the fist checkpoint is just after reset checkpoints['init'] = (checkpoint(), None) #list of already covered operations, used to constraint the randomization already_covered = [] #constraint for the operation randomization - do not use already #covered combinations def op_constraint(direction, divider_range, repeat_range): return not (direction, repeat_range, divider_range) in already_covered apb_cover_item = coverage_db["top.apb.writeXdelay"] top_cover_item = coverage_db["top"] #we define test end condition as reaching 99% coverage at the #top cover item cov_op = 0 while cov_op < 90: #restore randomly selected checkpoint if ENABLE_CHECKPOINTS: if CHECKPOINTS_TREE_STRUCTURE: chkp_to_restore = random.choice(list(checkpoints.keys())) else: chkp_to_restore = 'init' log.info("Restoring a simulation checkpoint: " + chkp_to_restore) current_chceckpoint = checkpoints[chkp_to_restore] restore(current_chceckpoint[0]) #create I2C operation object to be executed i2c_op = I2C_Operation() #if there is no tree structure, knowledge about already covered #cases cannot be used if ENABLE_CHECKPOINTS & CHECKPOINTS_TREE_STRUCTURE: try: i2c_op.randomize_with(op_constraint) except: i2c_op.randomize() else: i2c_op.randomize() already_covered.append( (i2c_op.direction, i2c_op.repeat_range, i2c_op.divider_range)) #call test sequence if i2c_op.direction == "read": yield segment_i2c_read_operation(i2c_op) else: yield segment_i2c_write_operation(i2c_op) if ENABLE_CHECKPOINTS: #if status is OK, add this simulation point to the checkpoints list if operations_completed[-1][1]: chkp_name = str(get_sim_time('ns')) log.info("Creating a simulation checkpoint: " + chkp_name) checkpoints[chkp_name] = (checkpoint(), i2c_op) #call APB test sequence as long as cover item apb.writeXdelay #coverage level is below 100% if apb_cover_item.coverage * 100 / apb_cover_item.size < 100: yield segment_apb_rw(repeat=random.randint(1, 5)) #update the coverage level cov_op_prev = cov_op cov_op = top_cover_item.coverage * 100.0 / top_cover_item.size log.info("Current overall coverage level = %f %%", cov_op) #print summary log.info("Opertions finished succesfully:") for elem in operations_completed: if elem[1]: log.info(" %s of %d words with divider %d" % (elem[0].direction, elem[0].repeat, elem[0].divider)) log.info("Opertions finished with error:") for elem in operations_completed: if not elem[1]: log.info(" %s of %d words with divider %d" % (elem[0].direction, elem[0].repeat, elem[0].divider)) log.info("Functional coverage details:") reportCoverage(log.info, bins=False)
async def test_fpga_core(dut): clock = Clock(dut.scan_clk, 10000, units="ps") cocotb.fork(clock.start()) # 2 * 2 fpga # built for primary fpga functional test because bitstream generator is pending complete # bitstream used in this testbench is hand-translated from VTR result # io info: # io_0: C, io_1: B, io_2: A, io_3: D # C = A | B, D = A & B tile_2_A_port = 0 tile_3_A_port = 0 tile_2_B_port = 2 tile_3_B_port = 2 # The Environmental Variable BITSTREAM_DIR is set in the vtr_wholeflow.sh # Loading Routing Configuration Bitstream import re f = open(os.getenv('BITSTREAM_ROUTE_PATH'), "r") routing = f.read() routing = re.split("\n", routing) routing = [int(i) for i in routing if len(i) > 0] f.close() conn_bitstream = int_list_to_bitstream(routing, 2) conn_scan_size = len(conn_bitstream) conn_bitstream_check = conn_bitstream.copy() conn_bitstream += conn_bitstream_check # Loading CLB Configuration Bitstream # The Environmental Variable BITSTREAM_DIR is set in the vtr_wholeflow.sh f = open(os.getenv('BITSTREAM_CLB_PATH'), "r") lut_bitstream = f.read() lut_bitstream = [int(i) for i in lut_bitstream] f.close() lut_scan_size = len(lut_bitstream) lut_bitstream_check = lut_bitstream.copy() lut_bitstream += lut_bitstream_check # print("lut bitstream:") # print(lut_bitstream) # print("conn bitstream:") # print(conn_bitstream) #first scan dut.clb_scan_en <= 1 for i in range(lut_scan_size): dut.clb_scan_in <= lut_bitstream.pop(-1) await RisingEdge(dut.scan_clk) dut.clb_scan_en <= 0 dut.conn_scan_en <= 1 for i in range(conn_scan_size): dut.conn_scan_in <= conn_bitstream.pop(-1) await RisingEdge(dut.scan_clk) dut.conn_scan_en <= 0 #repeated scan and check clb_scan_out = [] dut.clb_scan_en <= 1 for i in range(lut_scan_size): dut.clb_scan_in <= lut_bitstream.pop(-1) await RisingEdge(dut.scan_clk) clb_scan_out.append(dut.clb_scan_out.value) dut.clb_scan_en <= 0 if(lut_bitstream_check == clb_scan_out[::-1]): print('clb bitstream valid') else: print('clb bitstream invalid') conn_scan_out = [] dut.conn_scan_en <= 1 for i in range(conn_scan_size): dut.conn_scan_in <= conn_bitstream.pop(-1) await RisingEdge(dut.scan_clk) conn_scan_out.append(dut.conn_scan_out.value) dut.conn_scan_en <= 0 if(conn_bitstream_check == conn_scan_out[::-1]): print('conn bitstream valid') else: print('conn bitstream invalid') print("This is really the blink test.") print(conn_scan_size) await Timer(100, units='ps') clock = Clock(dut.clk, 10000, units="ps") cocotb.fork(clock.start()) dut.reset <= 1; dut.fpga_in[14] <= 1; await Timer(100, units='ns') dut.reset <= 0; await Timer(100, units='ns') dut.fpga_in[14] <= 0; await Timer(1000, units='ns')
async def test_fc_mem(dut): # Create a 10us period clock on port clk clock = Clock(dut.clk_i, 10, units="us") cocotb.fork(clock.start()) # Reset system await FallingEdge(dut.clk_i) dut.data_i <= 0 dut.valid_i <= 0 dut.last_i <= 0 dut.ready_i <= 0 dut.rst_n_i <= 0 dut.wr_en_i <= 0 dut.rd_en_i <= 0 dut.rd_wr_bank_i <= 0 dut.rd_wr_addr_i <= 0 dut.wr_data_i <= 0 await FallingEdge(dut.clk_i) dut.rst_n_i <= 1 dut.wr_en_i <= 0 dut.rd_en_i <= 0 dut.rd_wr_bank_i <= 0 dut.rd_wr_addr_i <= 0 dut.wr_data_i <= 0 await FallingEdge(dut.clk_i) # Sequential Write Weights for i in range(208 * 3): dut.wr_en_i <= 1 dut.rd_en_i <= 0 dut.rd_wr_bank_i <= i // 208 dut.rd_wr_addr_i <= i % 208 dut.wr_data_i <= i % 208 await FallingEdge(dut.clk_i) # Sequential Write Bias for i in range(3): dut.wr_en_i <= 1 dut.rd_en_i <= 0 dut.rd_wr_bank_i <= i + 3 dut.rd_wr_addr_i <= 0 dut.wr_data_i <= i await FallingEdge(dut.clk_i) # Sequential Read for i in range(208 * 3): dut.wr_en_i <= 0 dut.rd_en_i <= 1 dut.rd_wr_bank_i <= i // 208 dut.rd_wr_addr_i <= i % 208 dut.wr_data_i <= 0 await FallingEdge(dut.clk_i) await FallingEdge(dut.clk_i) # Check Cycling for i in range(208): dut.data_i <= i dut.valid_i <= 1 if i == 207: dut.last_i <= 1 else: dut.last_i <= 0 dut.ready_i <= 1 dut.wr_en_i <= 0 dut.rd_en_i <= 0 dut.rd_wr_bank_i <= 0 dut.rd_wr_addr_i <= 0 dut.wr_data_i <= 0 await FallingEdge(dut.clk_i) for i in range(50): dut.valid_i <= 0 dut.last_i <= 0 await FallingEdge(dut.clk_i)
def __init__(self, dut): self.dut = dut self.log = SimLog("cocotb.tb") self.log.setLevel(logging.DEBUG) # PCIe self.rc = RootComplex() self.rc.max_payload_size = 0x1 # 256 bytes self.rc.max_read_request_size = 0x2 # 512 bytes self.dev = UltraScalePlusPcieDevice( # configuration options pcie_generation=3, pcie_link_width=16, user_clk_frequency=250e6, alignment="dword", cq_cc_straddle=False, rq_rc_straddle=False, rc_4tlp_straddle=False, enable_pf1=False, enable_client_tag=True, enable_extended_tag=True, enable_parity=False, enable_rx_msg_interface=False, enable_sriov=False, enable_extended_configuration=False, enable_pf0_msi=True, enable_pf1_msi=False, # signals # Clock and Reset Interface user_clk=dut.clk_250mhz, user_reset=dut.rst_250mhz, # user_lnk_up # sys_clk # sys_clk_gt # sys_reset # phy_rdy_out # Requester reQuest Interface rq_bus=AxiStreamBus.from_prefix(dut, "m_axis_rq"), pcie_rq_seq_num0=dut.s_axis_rq_seq_num_0, pcie_rq_seq_num_vld0=dut.s_axis_rq_seq_num_valid_0, pcie_rq_seq_num1=dut.s_axis_rq_seq_num_1, pcie_rq_seq_num_vld1=dut.s_axis_rq_seq_num_valid_1, # pcie_rq_tag0 # pcie_rq_tag1 # pcie_rq_tag_av # pcie_rq_tag_vld0 # pcie_rq_tag_vld1 # Requester Completion Interface rc_bus=AxiStreamBus.from_prefix(dut, "s_axis_rc"), # Completer reQuest Interface cq_bus=AxiStreamBus.from_prefix(dut, "s_axis_cq"), # pcie_cq_np_req # pcie_cq_np_req_count # Completer Completion Interface cc_bus=AxiStreamBus.from_prefix(dut, "m_axis_cc"), # Transmit Flow Control Interface # pcie_tfc_nph_av=dut.pcie_tfc_nph_av, # pcie_tfc_npd_av=dut.pcie_tfc_npd_av, # Configuration Management Interface cfg_mgmt_addr=dut.cfg_mgmt_addr, cfg_mgmt_function_number=dut.cfg_mgmt_function_number, cfg_mgmt_write=dut.cfg_mgmt_write, cfg_mgmt_write_data=dut.cfg_mgmt_write_data, cfg_mgmt_byte_enable=dut.cfg_mgmt_byte_enable, cfg_mgmt_read=dut.cfg_mgmt_read, cfg_mgmt_read_data=dut.cfg_mgmt_read_data, cfg_mgmt_read_write_done=dut.cfg_mgmt_read_write_done, # cfg_mgmt_debug_access # Configuration Status Interface # cfg_phy_link_down # cfg_phy_link_status # cfg_negotiated_width # cfg_current_speed cfg_max_payload=dut.cfg_max_payload, cfg_max_read_req=dut.cfg_max_read_req, # cfg_function_status # cfg_vf_status # cfg_function_power_state # cfg_vf_power_state # cfg_link_power_state # cfg_err_cor_out # cfg_err_nonfatal_out # cfg_err_fatal_out # cfg_local_error_out # cfg_local_error_valid # cfg_rx_pm_state # cfg_tx_pm_state # cfg_ltssm_state # cfg_rcb_status # cfg_obff_enable # cfg_pl_status_change # cfg_tph_requester_enable # cfg_tph_st_mode # cfg_vf_tph_requester_enable # cfg_vf_tph_st_mode # Configuration Received Message Interface # cfg_msg_received # cfg_msg_received_data # cfg_msg_received_type # Configuration Transmit Message Interface # cfg_msg_transmit # cfg_msg_transmit_type # cfg_msg_transmit_data # cfg_msg_transmit_done # Configuration Flow Control Interface cfg_fc_ph=dut.cfg_fc_ph, cfg_fc_pd=dut.cfg_fc_pd, cfg_fc_nph=dut.cfg_fc_nph, cfg_fc_npd=dut.cfg_fc_npd, cfg_fc_cplh=dut.cfg_fc_cplh, cfg_fc_cpld=dut.cfg_fc_cpld, cfg_fc_sel=dut.cfg_fc_sel, # Configuration Control Interface # cfg_hot_reset_in # cfg_hot_reset_out # cfg_config_space_enable # cfg_dsn # cfg_bus_number # cfg_ds_port_number # cfg_ds_bus_number # cfg_ds_device_number # cfg_ds_function_number # cfg_power_state_change_ack # cfg_power_state_change_interrupt cfg_err_cor_in=dut.status_error_cor, cfg_err_uncor_in=dut.status_error_uncor, # cfg_flr_in_process # cfg_flr_done # cfg_vf_flr_in_process # cfg_vf_flr_func_num # cfg_vf_flr_done # cfg_pm_aspm_l1_entry_reject # cfg_pm_aspm_tx_l0s_entry_disable # cfg_req_pm_transition_l23_ready # cfg_link_training_enable # Configuration Interrupt Controller Interface # cfg_interrupt_int # cfg_interrupt_sent # cfg_interrupt_pending cfg_interrupt_msi_enable=dut.cfg_interrupt_msi_enable, cfg_interrupt_msi_mmenable=dut.cfg_interrupt_msi_mmenable, cfg_interrupt_msi_mask_update=dut.cfg_interrupt_msi_mask_update, cfg_interrupt_msi_data=dut.cfg_interrupt_msi_data, # cfg_interrupt_msi_select=dut.cfg_interrupt_msi_select, cfg_interrupt_msi_int=dut.cfg_interrupt_msi_int, cfg_interrupt_msi_pending_status=dut. cfg_interrupt_msi_pending_status, cfg_interrupt_msi_pending_status_data_enable=dut. cfg_interrupt_msi_pending_status_data_enable, # cfg_interrupt_msi_pending_status_function_num=dut.cfg_interrupt_msi_pending_status_function_num, cfg_interrupt_msi_sent=dut.cfg_interrupt_msi_sent, cfg_interrupt_msi_fail=dut.cfg_interrupt_msi_fail, # cfg_interrupt_msix_enable # cfg_interrupt_msix_mask # cfg_interrupt_msix_vf_enable # cfg_interrupt_msix_vf_mask # cfg_interrupt_msix_address # cfg_interrupt_msix_data # cfg_interrupt_msix_int # cfg_interrupt_msix_vec_pending # cfg_interrupt_msix_vec_pending_status cfg_interrupt_msi_attr=dut.cfg_interrupt_msi_attr, cfg_interrupt_msi_tph_present=dut.cfg_interrupt_msi_tph_present, cfg_interrupt_msi_tph_type=dut.cfg_interrupt_msi_tph_type, # cfg_interrupt_msi_tph_st_tag=dut.cfg_interrupt_msi_tph_st_tag, # cfg_interrupt_msi_function_number=dut.cfg_interrupt_msi_function_number, # Configuration Extend Interface # cfg_ext_read_received # cfg_ext_write_received # cfg_ext_register_number # cfg_ext_function_number # cfg_ext_write_data # cfg_ext_write_byte_enable # cfg_ext_read_data # cfg_ext_read_data_valid ) # self.dev.log.setLevel(logging.DEBUG) self.rc.make_port().connect(self.dev) self.driver = mqnic.Driver() self.dev.functions[0].msi_cap.msi_multiple_message_capable = 5 self.dev.functions[0].configure_bar( 0, 2**len(dut.core_inst.core_pcie_inst.axil_ctrl_araddr), ext=True, prefetch=True) if hasattr(dut.core_inst.core_pcie_inst, 'pcie_app_ctrl'): self.dev.functions[0].configure_bar( 2, 2**len(dut.core_inst.core_pcie_inst.axil_app_ctrl_araddr), ext=True, prefetch=True) # Ethernet cocotb.start_soon(Clock(dut.qsfp_rx_clk, 3.102, units="ns").start()) cocotb.start_soon(Clock(dut.qsfp_tx_clk, 3.102, units="ns").start()) self.qsfp_mac = EthMac( tx_clk=dut.qsfp_tx_clk, tx_rst=dut.qsfp_tx_rst, tx_bus=AxiStreamBus.from_prefix(dut, "qsfp_tx_axis"), tx_ptp_time=dut.qsfp_tx_ptp_time, tx_ptp_ts=dut.qsfp_tx_ptp_ts, tx_ptp_ts_tag=dut.qsfp_tx_ptp_ts_tag, tx_ptp_ts_valid=dut.qsfp_tx_ptp_ts_valid, rx_clk=dut.qsfp_rx_clk, rx_rst=dut.qsfp_rx_rst, rx_bus=AxiStreamBus.from_prefix(dut, "qsfp_rx_axis"), rx_ptp_time=dut.qsfp_rx_ptp_time, ifg=12, speed=100e9) dut.qspi_dq_i.setimmediatevalue(0) self.cms_ram = AxiLiteRam(AxiLiteBus.from_prefix(dut, "m_axil_cms"), dut.m_axil_cms_clk, dut.m_axil_cms_rst, size=256 * 1024) self.loopback_enable = False cocotb.start_soon(self._run_loopback())
def test_port_tm(dut): """Testing port_tm """ # start HW sim clock cocotb.fork(Clock(dut.axis_aclk, PERIOD).start()) # Reset the DUT dut._log.debug("Resetting DUT") dut.axis_resetn <= 0 yield ClockCycles(dut.axis_aclk, 10) dut.axis_resetn <= 1 dut._log.debug("Out of reset") print "FINISHED RESET..." dut.m_axis_tready <= 0 dst_port = 0b00000100 # build the list of pkts and metadata to insert pkts_meta_in = [] for i in range(10): # pkt_len = random.randint(50, 1000) # build a packet pkt = Ether(dst='aa:aa:aa:aa:aa:aa', src='bb:bb:bb:bb:bb:bb') pkt = pkt / ('\x11'*18 + '\x22'*32) # pkt = pkt / ('\x11'*18 + '\x22'*32 + '\x33'*32 + '\x44'*32 + '\x55'*16) # pkt = pkt / ('\x11'*(pkt_len - 14)) rank = random.randint(0, 100) # build the metadata meta = Metadata(pkt_len=len(pkt), src_port=0b00000001, dst_port=dst_port, rank=rank) tuser = BinaryValue(bits=len(meta)*8, bigEndian=False) tuser.set_buff(str(meta)) pkts_meta_in.append((rank, pkt, tuser)) ranks_in = [tup[0] for tup in pkts_meta_in] pkts_in = [tup[1] for tup in pkts_meta_in] meta_in = [tup[2] for tup in pkts_meta_in] # Attach an AXI4Stream Master to the input pkt interface pkt_master = AXI4StreamMaster(dut, 's_axis', dut.axis_aclk) # Attach ReqMaster to each input interface nf0_req_master = ReqMaster(dut, 'nf0_sel', dut.axis_aclk) nf1_req_master = ReqMaster(dut, 'nf1_sel', dut.axis_aclk) nf2_req_master = ReqMaster(dut, 'nf2_sel', dut.axis_aclk) nf3_req_master = ReqMaster(dut, 'nf3_sel', dut.axis_aclk) # Send pkts and metadata in the HW sim yield pkt_master.write_pkts(pkts_in, meta_in) # delay between writing pkts and reading them out yield ClockCycles(dut.axis_aclk, 10) # Attach and AXI4StreamSlave to the output pkt interface pkt_slave = AXI4StreamSlave(dut, 'm_axis', dut.axis_aclk) # Read output pkts pkt_slave_thread = cocotb.fork(pkt_slave.read_n_pkts(len(pkts_in))) # start submitting read requests delay = 20 #nf0_req_thread = cocotb.fork(nf0_req_master.write_reqs(requests, delay)) nf1_req_thread = cocotb.fork(nf1_req_master.write_reqs(len(ranks_in), delay)) #nf2_req_thread = cocotb.fork(nf2_req_master.write_reqs(requests, delay)) #nf3_req_thread = cocotb.fork(nf3_req_master.write_reqs(requests, delay)) # wait for all pkts yield pkt_slave_thread.join() sorted_pkts_meta = sorted(pkts_meta_in, key=lambda x: x[0]) expected_ranks = [tup[0] for tup in sorted_pkts_meta] expected_pkts = [tup[1] for tup in sorted_pkts_meta] expected_meta = [tup[2] for tup in sorted_pkts_meta] pkts_out = pkt_slave.pkts meta_out = pkt_slave.metadata actual_ranks = [Metadata(m.get_buff()).rank for m in meta_out] print 'input ranks = {}'.format(ranks_in) print 'expected output ranks = {}'.format(expected_ranks) print 'actual output ranks = {}'.format(actual_ranks) error = False for (exp_pkt, pkt, exp_meta, meta, i) in zip(expected_pkts, pkts_out, expected_meta, meta_out, range(len(expected_pkts))): if str(exp_pkt) != str(pkt): print 'ERROR: exp_pkt != pkt_out for pkt {}'.format(i) error = True if exp_meta.get_buff() != meta.get_buff(): print 'ERROR: exp_meta != meta_out for pkt {}'.format(i) exp_meta = Metadata(exp_meta.get_buff()) meta = Metadata(meta.get_buff()) print 'exp_meta = {}'.format(exp_meta.summary()) print 'meta = {}'.format(meta.summary()) error = True yield ClockCycles(dut.axis_aclk, 20) if error: print 'ERROR: Test Failed' raise(TestFailure)
async def train(dut): """ Train RL agent using Q-Learning """ #Length of an episode in timesteps EPISODE_LENGTH = 200 #Number of episodes over which to train NUM_EPISODES = 200 ALPHA = 0.005 GAMMA = 1.0 EPS_START = 1.0 EPS_DECAY = 0.9999 EPS_MIN = 0.1 #Size of Action space = 6 nA = 6 if 'EPISODE_LENGTH' in cocotb.plusargs: EPISODE_LENGTH = int(cocotb.plusargs['EPISODE_LENGTH']) if 'NUM_EPISODES' in cocotb.plusargs: NUM_EPISODES = int(cocotb.plusargs['NUM_EPISODES']) if 'POLICY_STABLE_LIMIT' in cocotb.plusargs: POLICY_STABLE_LIMIT = int(cocotb.plusargs['POLICY_STABLE_LIMIT']) else: POLICY_STABLE_LIMIT = NUM_EPISODES / 10 if 'ALPHA' in cocotb.plusargs: ALPHA = float(cocotb.plusargs['ALPHA']) if 'EPS_DECAY' in cocotb.plusargs: EPS_DECAY = float(cocotb.plusargs['EPS_DECAY']) if 'EPS_MIN' in cocotb.plusargs: EPS_MIN = float(cocotb.plusargs['EPS_MIN']) if 'EPS_START' in cocotb.plusargs: EPS_START = float(cocotb.plusargs['EPS_START']) if 'GAMMA' in cocotb.plusargs: GAMMA = float(cocotb.plusargs['GAMMA']) for k, v in cocotb.plusargs.items(): print("{} = {}".format(k, v)) async def q_learning(num_episodes, alpha, gamma=1.0, plot_every=10): """ Q-Learning - TD Control Params ====== num_episodes (int): number of episodes to run the algorithm alpha (float): learning rate gamma (float): discount factor plot_every (int): number of episodes to use when calculating average score """ Q = defaultdict( lambda: np.zeros(nA)) # initialize empty dictionary of arrays new_policy = {} old_policy = {} policy_stable_count = 0 # monitor performance tmp_scores = deque( maxlen=plot_every) # deque for keeping track of scores avg_scores = deque(maxlen=NUM_EPISODES ) # average scores over every plot_every episodes eps = EPS_START for i_episode in range(1, NUM_EPISODES + 1): # monitor progress if i_episode % 10 == 0: print("\rEpisode {}/{}".format(i_episode, num_episodes)) #sys.stdout.flush() policy_print = dict( (k, ACTION_NAME_MAP[np.argmax(v)]) for k, v in Q.items()) pp(policy_print) score = 0 # initialize score #state = env.reset() # start episode await initialize_inputs(dut) await reset(dut) await initialize_counters(dut) total_episode_reward = 0 state, reward = get_state_reward(dut) #dut._log.info("Reset state = {}".format(state)) #eps = 1.0 / i_episode # set value of epsilon eps = eps * EPS_DECAY eps = np.max([eps, EPS_MIN]) for _ in range(EPISODE_LENGTH): action = epsilon_greedy(Q, state, nA, eps) # epsilon-greedy action selection #next_state, reward, done, info = env.step(action) # take action A, observe R, S' s = Switcher(dut) s.do_action(action) #print("state:{} + action:{} ->".format(state,action),end="") await tick(dut) next_state, reward = get_state_reward(dut) #print("next_state:{}".format(next_state)) score += reward # add reward to agent's score Q[state][action] = update_Q_sarsamax(alpha, gamma, Q, \ state, action, reward, next_state) state = next_state tmp_scores.append(score) # append score if (i_episode % plot_every == 0): avg_scores.append(np.mean(tmp_scores)) new_policy = dict((k, np.argmax(v)) for k, v in Q.items()) policy_stable_count += 1 if new_policy == old_policy else 0 old_policy = new_policy.copy() if policy_stable_count > POLICY_STABLE_LIMIT: dut._log.info("----- Policy stable for {} episodes".format( policy_stable_count)) break # plot performance #plt.plot(np.linspace(0,num_episodes,len(avg_scores),endpoint=False), np.asarray(avg_scores)) #plt.xlabel('Episode Number') #plt.ylabel('Average Reward (Over Next %d Episodes)' % plot_every) #plt.show() # print best 100-episode performance print(('Best Average Reward over %d Episodes: ' % plot_every), np.max(avg_scores)) return Q """ Create a 2ps period clock on port clk This will be fastest clock possible with the Verilator default time resolution of 1 ps. Will result in the fastest runtime. Sample runtimes (with 1000 transactions, over 10000 cycles) 2 ps clock : 2.61 sec 2 ns clock : 17.14 sec """ clock = Clock(dut.clk, 2, units="ns") cocotb.fork(clock.start()) # Start the clock Q = await q_learning(NUM_EPISODES, ALPHA) print("Final Policy") policy_print = dict( (k, ACTION_NAME_MAP[np.argmax(v)]) for k, v in Q.items()) pp(policy_print) # determine the policy corresponding to the final action-value function estimate policy = dict((k, np.argmax(v)) for k, v in Q.items()) #print(policy) #print(Q) with open("policy.dump", "wb") as f: dill.dump((policy, Q), f) dut._log.info("End of Training::Finished dumping")
def CREATORTESTNAME_test(dut): ## ## first grab the testbench configuration ## config = test_config.get_config() ## ## process input arguments for this test ## input_args = config["input_args"] num_events_to_process = int(input_args["n_events"]) event_level_detail_in_sumary = bool(input_args["event_detail"]) #CREATORSOFTWAREBLOCK## #CREATORSOFTWAREBLOCK## start the software block instance #CREATORSOFTWAREBLOCK## #CREATORSOFTWAREBLOCKCREATORTESTNAME_block_instance = CREATORTESTNAME_block.CREATORCLASSNAMEBlock(dut.clock, "CREATORCLASSNAMEBlock") #CREATORSOFTWAREBLOCKfor i, io in enumerate(CREATORCLASSNAMEPorts.Inputs): #CREATORSOFTWAREBLOCK CREATORTESTNAME_block_instance.add_fifo( #CREATORSOFTWAREBLOCK dut.input_spybuffers[i].spybuffer, #CREATORSOFTWAREBLOCK dut.clock, #CREATORSOFTWAREBLOCK f"{CREATORTESTNAME_block_instance.name}_Input_{i}", #CREATORSOFTWAREBLOCK io, #CREATORSOFTWAREBLOCK direction="in", #CREATORSOFTWAREBLOCK ) #CREATORSOFTWAREBLOCKfor i, io in enumerate(CREATORCLASSNAMEPorts.Outputs): #CREATORSOFTWAREBLOCK CREATORTESTNAME_block_instance.add_fifo( #CREATORSOFTWAREBLOCK dut.output_spybuffers[i].spybuffer, #CREATORSOFTWAREBLOCK dut.clock, #CREATORSOFTWAREBLOCK f"{CREATORTESTNAME_block_instance.name}_Output_{i}", #CREATORSOFTWAREBLOCK io, #CREATORSOFTWAREBLOCK direction="out", #CREATORSOFTWAREBLOCK ) #CREATORSOFTWAREBLOCKCREATORTESTNAME_block_instance.start() ## ## mark the current board ## for i in range(20): dut._log.warning( "AUTOGEN WARNING User should explicitly check the DUT board identifier" ) board_id = 0 # autogen dut._log.info( f"Instantiated CREATORCLASSNAME block with BOARD_ID = {board_id}") for io in CREATORCLASSNAMEPorts.Outputs: if int(io.value) == board_id: this_tp = io break if not this_tp: raise ValueError( f"Unable to find assocated IO for CREATORCLASSNAME BOARD_ID={board_id}" ) dut._log.info(f"Setting test IO with base port_name = {this_tp.name}") ## ## setup the clock and start it ## sim_clock = Clock(dut.clock, int(input_args["clock_period"]), input_args["clock_time_unit"]) cocotb.fork(sim_clock.start()) ## ## initialize the DUT to known state ## initialize_dut(dut) ## ## reset ## dut._log.info("Resetting DUT") yield reset(dut) ## ## get testvectors ## ( input_testvector_files, output_testvector_files, ) = test_config.get_testvector_files_from_config(config) ### ### alternative method for getting testvectors: ### # testvector_dir = config["testvectors"]["testvector_dir"] # ( # input_testvector_files, # output_testvector_files, # ) = CREATORTESTNAME_utils.get_testvector_files(testvector_dir) ## ## initialize the CREATORCLASSNAME block wrapper ## CREATORTESTNAME_wrapper = wrapper.CREATORCLASSNAMEWrapper( clock=dut.clock, name= f"CREATORCLASSNAMEWrapper_{CREATORCLASSNAMEPorts.simplename(this_tp)}", ) for i, io in enumerate(CREATORCLASSNAMEPorts.Inputs): driver = FifoDriver( dut.input_spybuffers[io.value].spybuffer, dut.clock, "CREATORCLASSNAME", io, write_out=True, ) CREATORTESTNAME_wrapper.add_input_driver(driver, io) for i, io in enumerate(CREATORCLASSNAMEPorts.Outputs): active = True monitor = FifoMonitor( dut.output_spybuffers[i].spybuffer, dut.clock, "CREATORCLASSNAME", io, callbacks=[], write_out=True, ) CREATORTESTNAME_wrapper.add_output_monitor(monitor, io, active=active) CREATORTESTNAME_wrapper.sort_ports() ## ## send input events ## dut._log.info("Sending input events") send_finished_signal = CREATORTESTNAME_wrapper.send_input_events( input_testvector_files, n_to_send=num_events_to_process) if not send_finished_signal: raise cocotb.result.TestFailure( f"ERROR Event sending timed out! Number of expected inputs with events = {len(send_finished_signal)}" ) yield Combine(*send_finished_signal) ## ## if you want to put a timeout on the sending of events use ## "with_timeout" instead of just "Combine" ## # try: # yield with_timeout(Combine(*send_finished_signal), 20, "us") # except Exception as ex: # raise cocotb.result.TestFailure( # f"ERROR Timed out waiting for events to send: {ex}" # ) dut._log.info("Sending finished!") timer = Timer(20, "us") dut._log.info("Going to wait 20 microseconds") yield timer ## ## perform testvector comparison test ## all_tests_passed = True all_test_results = [] for oport in CREATORTESTNAME_wrapper.output_ports: ## ## extract the observed data for this output ## monitor, io, is_active = oport words = monitor.observed_words recvd_events = events.load_events(words, "little") cocotb.log.info( f"Output for {io.name} (output port num {io.value}) received {len(recvd_events)} events" ) ## ## extract the expected data for this output ## if config["run_config"]["expected_is_observed"]: # map the "expected" to be the same as the "observed" dut._log.warning( "WARNING Taking expected events to be the same as the observed events!" ) output_testvector_file = "expected_is_observed" expected_output_events = recvd_events else: output_testvector_file = output_testvector_files[io.value] expected_output_events = events.load_events_from_file( output_testvector_file, n_to_load=num_events_to_process) ## ## perform test by comparison with expected testvectors ## events_are_equal, test_results = tb_diff.events_are_equal( recvd_events, expected_output_events, verbose=False) result_summary = result_handler.result_summary_dict( f"{str('CREATORCLASSNAME').upper()}_Output_{io.value:02}", str(output_testvector_file), test_name= f"TEST_{str('CREATORCLASSNAME').upper()}_SRC{this_tp.value:02}_DEST{io.value:02}", test_results=test_results, ) all_test_results.append(result_summary) all_tests_passed = (all_tests_passed and result_summary["test_results"]["test_success"]) this_tp_name = ( f"{this_tp.name.split('_')[0]}{int(this_tp.name.split('_')[1]):02}" ) out_io_name = f"{io.name.split('_')[0]}{int(io.name.split('_')[1]):02}" output_json_name = f"test_results_summary_CREATORCLASSNAME_src{this_tp_name}_dest{out_io_name}.json" with open(output_json_name, "w", encoding="utf-8") as f: json.dump(result_summary, f, ensure_ascii=False, indent=4) result_handler.dump_test_results(all_test_results, event_detail=event_level_detail_in_sumary) cocotb_result = { True: cocotb.result.TestSuccess, False: cocotb.result.TestFailure }[all_tests_passed] raise cocotb_result
async def fir_filter_test(dut): """ Load test data from files and send them through the DUT. Compare input and output afterwards. """ EnablePlots = True timestamp_start = time.time() # -------------------------------------------------------------------------- # Constants # -------------------------------------------------------------------------- # Number of seconds to process n_sec = 0.001 # Derived constants num_samples = int(n_sec * fm_global.fs_rx_c) # -------------------------------------------------------------------------- # Load data from files # -------------------------------------------------------------------------- filename = "../../../../../../sim/matlab/verification_data/rx_fm_channel_data.txt" data_i = [] with open(filename) as fd: val_count = 0 for line in fd: data_i.append(float(line.strip('\n'))) val_count += 1 # Stop after required number of samples if val_count >= num_samples: break # Convert to fixed point and back to int data_i_fp = to_fixed_point(data_i, fm_global.fp_width_c, fm_global.fp_width_frac_c) data_i_int = fixed_to_int(data_i_fp) filename = "../../../../../../sim/matlab/verification_data/rx_pilot.txt" gold_data_o = [] with open(filename) as fd: val_count = 0 for line in fd: gold_data_o.append(float(line.strip('\n'))) val_count += 1 # Stop after required number of samples if val_count >= num_samples: break # Convert to fixed point gold_data_o_fp = to_fixed_point(gold_data_o, fm_global.fp_width_c, fm_global.fp_width_frac_c) # -------------------------------------------------------------------------- # Prepare environment # -------------------------------------------------------------------------- tb = FM_TB(dut, num_samples) # Generate clock clk_period_ns = round(1 / tb.CLOCK_FREQ_MHZ * 1e3) clk = Clock(dut.iClk, period=clk_period_ns, units='ns') clk_gen = cocotb.fork(clk.start()) # Generate FIR input strobe strobe_num_cycles_high = 1 strobe_num_cycles_low = tb.CLOCK_FREQ_MHZ * 1e6 // fm_global.fs_rx_c - strobe_num_cycles_high tb.fir_in_strobe.start( bit_toggler(repeat(strobe_num_cycles_high), repeat(strobe_num_cycles_low))) N_FIR = 73 # see filter_bp_pilot_coeffs_c in DUT (DspFir) assert strobe_num_cycles_low >= N_FIR, \ "The FIR filter takes N_FIR clock cycles to produce a result! Use a lower sampling frequency!!" print("strobe_num_cycles_high : %d" % strobe_num_cycles_high) print("strobe_num_cycles_low : %d" % strobe_num_cycles_low) # -------------------------------------------------------------------------- # Run test on DUT # -------------------------------------------------------------------------- # Reset the DUT before any tests begin await tb.assign_defaults() await tb.reset() # Fork the 'receiving part' fir_out_fork = cocotb.fork( tb.read_fir_result(fm_global.pilot_output_scale_c, num_samples)) # Send input data through filter dut._log.info("Sending input data through filter ...") for i, sample in enumerate(data_i_int): await RisingEdge(dut.iValDry) dut.iDdry <= int(sample) await RisingEdge(dut.iValDry) # Await forked routines to stop await fir_out_fork # Measure time timestamp_end = time.time() dut._log.info("Execution took {:.2f} seconds.".format(timestamp_end - timestamp_start)) num_received = len(tb.data_out) num_expected = len(gold_data_o_fp) # -------------------------------------------------------------------------- # Plots # -------------------------------------------------------------------------- if EnablePlots: dut._log.info("Plots ...") fig = plt.figure() plt.plot(np.arange(0, num_expected) / fm_global.fs_rx_c, from_fixed_point(gold_data_o_fp), "b", label="gold_data_o_fp") plt.plot(np.arange(0, num_received) / fm_global.fs_rx_c, tb.data_out, "r", label="data_out") plt.title("Pilot") plt.grid(True) plt.legend() fig.tight_layout() plt.xlim([0, num_samples / fm_global.fs_rx_c]) plt.show() # -------------------------------------------------------------------------- # Compare results # -------------------------------------------------------------------------- # Sanity check if num_received < num_expected: raise cocotb.result.TestError( "Did not capture enough output values: {} actual, {} expected.". format(num_received, num_expected)) # Skip first N samples skip_N = 10 dut._log.info(f"Skipping first N={skip_N} samples.") gold_data_o_fp = gold_data_o_fp[skip_N:] tb.data_out = tb.data_out[skip_N:] max_diff = 2**-5 for i, res in enumerate(tb.data_out): diff = gold_data_o_fp[i] - res if abs(from_fixed_point(diff)) > max_diff: msg = "FIR output [{}] is not matching the expected values: {}>{}.".format( i, abs(from_fixed_point(diff)), max_diff) raise cocotb.result.TestError(msg) # dut._log.info(msg) norm_res = np.linalg.norm( np.array(from_fixed_point(gold_data_o_fp[0:num_received])) - np.array(tb.data_out), 2) dut._log.info("2-Norm = {}".format(norm_res)) dut._log.info("Done.")
def setup_dut(dut): cocotb.fork(Clock(dut.clk, CLK_PERIOD_NS, units='ns').start())
def __init__(self, dut): self.dut = dut self.log = SimLog("cocotb.tb") self.log.setLevel(logging.DEBUG) cocotb.fork(Clock(dut.clk, 6.4, units="ns").start()) # Ethernet self.eth_r0_source = XgmiiSource(dut.eth_r0_rxd, dut.eth_r0_rxc, dut.clk, dut.rst) self.eth_r0_sink = XgmiiSink(dut.eth_r0_txd, dut.eth_r0_txc, dut.clk, dut.rst) self.eth_r1_source = XgmiiSource(dut.eth_r1_rxd, dut.eth_r1_rxc, dut.clk, dut.rst) self.eth_r1_sink = XgmiiSink(dut.eth_r1_txd, dut.eth_r1_txc, dut.clk, dut.rst) self.eth_r2_source = XgmiiSource(dut.eth_r2_rxd, dut.eth_r2_rxc, dut.clk, dut.rst) self.eth_r2_sink = XgmiiSink(dut.eth_r2_txd, dut.eth_r2_txc, dut.clk, dut.rst) self.eth_r3_source = XgmiiSource(dut.eth_r3_rxd, dut.eth_r3_rxc, dut.clk, dut.rst) self.eth_r3_sink = XgmiiSink(dut.eth_r3_txd, dut.eth_r3_txc, dut.clk, dut.rst) self.eth_r4_source = XgmiiSource(dut.eth_r4_rxd, dut.eth_r4_rxc, dut.clk, dut.rst) self.eth_r4_sink = XgmiiSink(dut.eth_r4_txd, dut.eth_r4_txc, dut.clk, dut.rst) self.eth_r5_source = XgmiiSource(dut.eth_r5_rxd, dut.eth_r5_rxc, dut.clk, dut.rst) self.eth_r5_sink = XgmiiSink(dut.eth_r5_txd, dut.eth_r5_txc, dut.clk, dut.rst) self.eth_r6_source = XgmiiSource(dut.eth_r6_rxd, dut.eth_r6_rxc, dut.clk, dut.rst) self.eth_r6_sink = XgmiiSink(dut.eth_r6_txd, dut.eth_r6_txc, dut.clk, dut.rst) self.eth_r7_source = XgmiiSource(dut.eth_r7_rxd, dut.eth_r7_rxc, dut.clk, dut.rst) self.eth_r7_sink = XgmiiSink(dut.eth_r7_txd, dut.eth_r7_txc, dut.clk, dut.rst) self.eth_r8_source = XgmiiSource(dut.eth_r8_rxd, dut.eth_r8_rxc, dut.clk, dut.rst) self.eth_r8_sink = XgmiiSink(dut.eth_r8_txd, dut.eth_r8_txc, dut.clk, dut.rst) self.eth_r9_source = XgmiiSource(dut.eth_r9_rxd, dut.eth_r9_rxc, dut.clk, dut.rst) self.eth_r9_sink = XgmiiSink(dut.eth_r9_txd, dut.eth_r9_txc, dut.clk, dut.rst) self.eth_r10_source = XgmiiSource(dut.eth_r10_rxd, dut.eth_r10_rxc, dut.clk, dut.rst) self.eth_r10_sink = XgmiiSink(dut.eth_r10_txd, dut.eth_r10_txc, dut.clk, dut.rst) self.eth_r11_source = XgmiiSource(dut.eth_r11_rxd, dut.eth_r11_rxc, dut.clk, dut.rst) self.eth_r11_sink = XgmiiSink(dut.eth_r11_txd, dut.eth_r11_txc, dut.clk, dut.rst) self.eth_l0_source = XgmiiSource(dut.eth_l0_rxd, dut.eth_l0_rxc, dut.clk, dut.rst) self.eth_l0_sink = XgmiiSink(dut.eth_l0_txd, dut.eth_l0_txc, dut.clk, dut.rst) self.eth_l1_source = XgmiiSource(dut.eth_l1_rxd, dut.eth_l1_rxc, dut.clk, dut.rst) self.eth_l1_sink = XgmiiSink(dut.eth_l1_txd, dut.eth_l1_txc, dut.clk, dut.rst) self.eth_l2_source = XgmiiSource(dut.eth_l2_rxd, dut.eth_l2_rxc, dut.clk, dut.rst) self.eth_l2_sink = XgmiiSink(dut.eth_l2_txd, dut.eth_l2_txc, dut.clk, dut.rst) self.eth_l3_source = XgmiiSource(dut.eth_l3_rxd, dut.eth_l3_rxc, dut.clk, dut.rst) self.eth_l3_sink = XgmiiSink(dut.eth_l3_txd, dut.eth_l3_txc, dut.clk, dut.rst) self.eth_l4_source = XgmiiSource(dut.eth_l4_rxd, dut.eth_l4_rxc, dut.clk, dut.rst) self.eth_l4_sink = XgmiiSink(dut.eth_l4_txd, dut.eth_l4_txc, dut.clk, dut.rst) self.eth_l5_source = XgmiiSource(dut.eth_l5_rxd, dut.eth_l5_rxc, dut.clk, dut.rst) self.eth_l5_sink = XgmiiSink(dut.eth_l5_txd, dut.eth_l5_txc, dut.clk, dut.rst) self.eth_l6_source = XgmiiSource(dut.eth_l6_rxd, dut.eth_l6_rxc, dut.clk, dut.rst) self.eth_l6_sink = XgmiiSink(dut.eth_l6_txd, dut.eth_l6_txc, dut.clk, dut.rst) self.eth_l7_source = XgmiiSource(dut.eth_l7_rxd, dut.eth_l7_rxc, dut.clk, dut.rst) self.eth_l7_sink = XgmiiSink(dut.eth_l7_txd, dut.eth_l7_txc, dut.clk, dut.rst) self.eth_l8_source = XgmiiSource(dut.eth_l8_rxd, dut.eth_l8_rxc, dut.clk, dut.rst) self.eth_l8_sink = XgmiiSink(dut.eth_l8_txd, dut.eth_l8_txc, dut.clk, dut.rst) self.eth_l9_source = XgmiiSource(dut.eth_l9_rxd, dut.eth_l9_rxc, dut.clk, dut.rst) self.eth_l9_sink = XgmiiSink(dut.eth_l9_txd, dut.eth_l9_txc, dut.clk, dut.rst) self.eth_l10_source = XgmiiSource(dut.eth_l10_rxd, dut.eth_l10_rxc, dut.clk, dut.rst) self.eth_l10_sink = XgmiiSink(dut.eth_l10_txd, dut.eth_l10_txc, dut.clk, dut.rst) self.eth_l11_source = XgmiiSource(dut.eth_l11_rxd, dut.eth_l11_rxc, dut.clk, dut.rst) self.eth_l11_sink = XgmiiSink(dut.eth_l11_txd, dut.eth_l11_txc, dut.clk, dut.rst) dut.sw.setimmediatevalue(0) dut.jp.setimmediatevalue(0) dut.uart_suspend.setimmediatevalue(0) dut.uart_dtr.setimmediatevalue(0) dut.uart_txd.setimmediatevalue(0) dut.uart_rts.setimmediatevalue(0) dut.amh_right_mdio_i.setimmediatevalue(0) dut.amh_left_mdio_i.setimmediatevalue(0)
def setup_function(dut, din): cocotb.fork(Clock(dut.clk, CLK_PERIOD).start()) dut.addr = din
def __init__(self, dut): self.dut = dut self.BAR0_APERTURE = int(os.getenv("PARAM_BAR0_APERTURE")) self.log = SimLog("cocotb.tb") self.log.setLevel(logging.DEBUG) # PCIe self.rc = RootComplex() self.rc.max_payload_size = 0x1 # 256 bytes self.rc.max_read_request_size = 0x2 # 512 bytes self.dev = UltraScalePcieDevice( # configuration options pcie_generation=3, pcie_link_width=8, user_clk_frequency=250e6, alignment="dword", straddle=False, enable_pf1=False, enable_client_tag=True, enable_extended_tag=True, enable_parity=False, enable_rx_msg_interface=False, enable_sriov=False, enable_extended_configuration=False, enable_pf0_msi=True, enable_pf1_msi=False, # signals # Clock and Reset Interface user_clk=dut.clk_250mhz, user_reset=dut.rst_250mhz, # user_lnk_up # sys_clk # sys_clk_gt # sys_reset # phy_rdy_out # Requester reQuest Interface rq_bus=AxiStreamBus.from_prefix(dut, "m_axis_rq"), pcie_rq_seq_num=dut.s_axis_rq_seq_num, pcie_rq_seq_num_vld=dut.s_axis_rq_seq_num_valid, # pcie_rq_tag # pcie_rq_tag_av # pcie_rq_tag_vld # Requester Completion Interface rc_bus=AxiStreamBus.from_prefix(dut, "s_axis_rc"), # Completer reQuest Interface cq_bus=AxiStreamBus.from_prefix(dut, "s_axis_cq"), # pcie_cq_np_req # pcie_cq_np_req_count # Completer Completion Interface cc_bus=AxiStreamBus.from_prefix(dut, "m_axis_cc"), # Transmit Flow Control Interface # pcie_tfc_nph_av=dut.pcie_tfc_nph_av, # pcie_tfc_npd_av=dut.pcie_tfc_npd_av, # Configuration Management Interface cfg_mgmt_addr=dut.cfg_mgmt_addr, cfg_mgmt_write=dut.cfg_mgmt_write, cfg_mgmt_write_data=dut.cfg_mgmt_write_data, cfg_mgmt_byte_enable=dut.cfg_mgmt_byte_enable, cfg_mgmt_read=dut.cfg_mgmt_read, cfg_mgmt_read_data=dut.cfg_mgmt_read_data, cfg_mgmt_read_write_done=dut.cfg_mgmt_read_write_done, # cfg_mgmt_debug_access # Configuration Status Interface # cfg_phy_link_down # cfg_phy_link_status # cfg_negotiated_width # cfg_current_speed cfg_max_payload=dut.cfg_max_payload, cfg_max_read_req=dut.cfg_max_read_req, # cfg_function_status # cfg_vf_status # cfg_function_power_state # cfg_vf_power_state # cfg_link_power_state # cfg_err_cor_out # cfg_err_nonfatal_out # cfg_err_fatal_out # cfg_local_error_out # cfg_local_error_valid # cfg_rx_pm_state # cfg_tx_pm_state # cfg_ltssm_state # cfg_rcb_status # cfg_obff_enable # cfg_pl_status_change # cfg_tph_requester_enable # cfg_tph_st_mode # cfg_vf_tph_requester_enable # cfg_vf_tph_st_mode # Configuration Received Message Interface # cfg_msg_received # cfg_msg_received_data # cfg_msg_received_type # Configuration Transmit Message Interface # cfg_msg_transmit # cfg_msg_transmit_type # cfg_msg_transmit_data # cfg_msg_transmit_done # Configuration Flow Control Interface cfg_fc_ph=dut.cfg_fc_ph, cfg_fc_pd=dut.cfg_fc_pd, cfg_fc_nph=dut.cfg_fc_nph, cfg_fc_npd=dut.cfg_fc_npd, cfg_fc_cplh=dut.cfg_fc_cplh, cfg_fc_cpld=dut.cfg_fc_cpld, cfg_fc_sel=dut.cfg_fc_sel, # Configuration Control Interface # cfg_hot_reset_in # cfg_hot_reset_out # cfg_config_space_enable # cfg_dsn # cfg_bus_number # cfg_ds_port_number # cfg_ds_bus_number # cfg_ds_device_number # cfg_ds_function_number # cfg_power_state_change_ack # cfg_power_state_change_interrupt cfg_err_cor_in=dut.status_error_cor, cfg_err_uncor_in=dut.status_error_uncor, # cfg_flr_in_process # cfg_flr_done # cfg_vf_flr_in_process # cfg_vf_flr_func_num # cfg_vf_flr_done # cfg_pm_aspm_l1_entry_reject # cfg_pm_aspm_tx_l0s_entry_disable # cfg_req_pm_transition_l23_ready # cfg_link_training_enable # Configuration Interrupt Controller Interface # cfg_interrupt_int # cfg_interrupt_sent # cfg_interrupt_pending cfg_interrupt_msi_enable=dut.cfg_interrupt_msi_enable, cfg_interrupt_msi_vf_enable=dut.cfg_interrupt_msi_vf_enable, cfg_interrupt_msi_mmenable=dut.cfg_interrupt_msi_mmenable, cfg_interrupt_msi_mask_update=dut.cfg_interrupt_msi_mask_update, cfg_interrupt_msi_data=dut.cfg_interrupt_msi_data, cfg_interrupt_msi_select=dut.cfg_interrupt_msi_select, cfg_interrupt_msi_int=dut.cfg_interrupt_msi_int, cfg_interrupt_msi_pending_status=dut. cfg_interrupt_msi_pending_status, cfg_interrupt_msi_pending_status_data_enable=dut. cfg_interrupt_msi_pending_status_data_enable, cfg_interrupt_msi_pending_status_function_num=dut. cfg_interrupt_msi_pending_status_function_num, cfg_interrupt_msi_sent=dut.cfg_interrupt_msi_sent, cfg_interrupt_msi_fail=dut.cfg_interrupt_msi_fail, # cfg_interrupt_msix_enable # cfg_interrupt_msix_mask # cfg_interrupt_msix_vf_enable # cfg_interrupt_msix_vf_mask # cfg_interrupt_msix_address # cfg_interrupt_msix_data # cfg_interrupt_msix_int # cfg_interrupt_msix_vec_pending # cfg_interrupt_msix_vec_pending_status cfg_interrupt_msi_attr=dut.cfg_interrupt_msi_attr, cfg_interrupt_msi_tph_present=dut.cfg_interrupt_msi_tph_present, cfg_interrupt_msi_tph_type=dut.cfg_interrupt_msi_tph_type, # cfg_interrupt_msi_tph_st_tag=dut.cfg_interrupt_msi_tph_st_tag, # cfg_interrupt_msi_function_number=dut.cfg_interrupt_msi_function_number, # Configuration Extend Interface # cfg_ext_read_received # cfg_ext_write_received # cfg_ext_register_number # cfg_ext_function_number # cfg_ext_write_data # cfg_ext_write_byte_enable # cfg_ext_read_data # cfg_ext_read_data_valid ) # self.dev.log.setLevel(logging.DEBUG) self.rc.make_port().connect(self.dev) self.driver = mqnic.Driver(self.rc) self.dev.functions[0].msi_multiple_message_capable = 5 self.dev.functions[0].configure_bar(0, 2**self.BAR0_APERTURE, ext=True, prefetch=True) # Ethernet cocotb.fork(Clock(dut.sfp_1_rx_clk, 6.4, units="ns").start()) self.sfp_1_source = XgmiiSource(dut.sfp_1_rxd, dut.sfp_1_rxc, dut.sfp_1_rx_clk, dut.sfp_1_rx_rst) cocotb.fork(Clock(dut.sfp_1_tx_clk, 6.4, units="ns").start()) self.sfp_1_sink = XgmiiSink(dut.sfp_1_txd, dut.sfp_1_txc, dut.sfp_1_tx_clk, dut.sfp_1_tx_rst) cocotb.fork(Clock(dut.sfp_2_rx_clk, 6.4, units="ns").start()) self.sfp_2_source = XgmiiSource(dut.sfp_2_rxd, dut.sfp_2_rxc, dut.sfp_2_rx_clk, dut.sfp_2_rx_rst) cocotb.fork(Clock(dut.sfp_2_tx_clk, 6.4, units="ns").start()) self.sfp_2_sink = XgmiiSink(dut.sfp_2_txd, dut.sfp_2_txc, dut.sfp_2_tx_clk, dut.sfp_2_tx_rst) dut.sfp_1_npres.setimmediatevalue(0) dut.sfp_2_npres.setimmediatevalue(0) dut.sfp_1_los.setimmediatevalue(0) dut.sfp_2_los.setimmediatevalue(0) dut.sma_in.setimmediatevalue(0) dut.sfp_i2c_scl_i.setimmediatevalue(1) dut.sfp_1_i2c_sda_i.setimmediatevalue(1) dut.sfp_2_i2c_sda_i.setimmediatevalue(1) dut.eeprom_i2c_scl_i.setimmediatevalue(1) dut.eeprom_i2c_sda_i.setimmediatevalue(1) dut.flash_dq_i.setimmediatevalue(0) self.loopback_enable = False cocotb.fork(self._run_loopback())
def run_test(dut, command_value=None, response_value=None): cocotb.fork(Clock(dut.clk, CLK_PERIOD).start()) command = command_value command_array = generate_command_array_from_value(command) response_test = response_value response_array = generate_response_array_from_value(response_test) ############################################### ''' IDLE State check current_state = 0 check spi_in_sdcmd_out = 0xFF ''' ############################################### dut.reset = 1 dut.spi_out_sdcmd_in = 0xFF dut.spi_busy = 0 ################# yield n_cycles_clock(dut, 10) ################# if (int(dut.current_state.value) != 0x0): raise TestFailure("Error IDLE state, cause wrong current state = %i" % int(dut.current_state.value)) if (int(dut.spi_in_sdcmd_out) != 0xFF): raise TestFailure("Error IDLE state, cause wrong spi input = %i" % int(dut.spi_in_sdcmd_out)) dut.w_cmd = 1 dut.reset = 0 dut.command = command yield n_cycles_clock(dut, 1) ################################################## ''' bucle SEND_CMD - WAIT_SPI SEND_CMD State check current_state = 1 check spi_in_sdcmd_out = command[i-1] check spi_in_0_i = command[i] WAIT_SPI check current_state = check spi_in_sdcmd_out = command[i] ''' ############################################### for i in range(0, 6): if (int(dut.current_state.value) != 0x1): raise TestFailure( "Error SEND_CMD state, cause wrong current state = %i" % int(dut.current_state.value)) ################# yield n_cycles_clock(dut, 1) ################# if (int(dut.spi_in_sdcmd_out) != command_array[i]): raise TestFailure( "Error SEND_CMD state, cause wrong command_i input = %i" % int(dut.spi_in_sdcmd_out)) dut.spi_busy = 1 ################ yield n_cycles_clock(dut, 1) ################# if (int(dut.current_state.value) != 0x4): raise TestFailure( "Error WAIT_SPI state, cause wrong current state = %i" % int(dut.current_state.value)) ################# yield n_cycles_clock(dut, 16) ################# dut.spi_busy = 0 ################ yield n_cycles_clock(dut, 1) ################# ################################################## ''' WAIT_RESP State check current_state check spi_in_sdcmd_out = FF ''' ############################################### ############### dut.spi_busy = 1 yield n_cycles_clock(dut, 1) ################### if (int(dut.current_state.value) != 0x2): raise TestFailure( "Error WAIT_RESP state, cause wrong current state = %i" % int(dut.current_state.value)) if (int(dut.spi_in_sdcmd_out) != 0xFF): raise TestFailure("Error WAIT_RESP state, cause wrong spi input = %i" % int(dut.spi_in_sdcmd_out)) if (int(dut.spi_out_0_o) != 0xFF): raise TestFailure( "Error WAIT_RESP state, cause wrong spi output = %i" % int(dut.spi_out_0_o)) #################### yield n_cycles_clock(dut, 1) ##################### if (int(dut.current_state.value) != 0x4): raise TestFailure( "Error WAIT_SPI state, cause wrong current state = %i" % int(dut.current_state.value)) dut.spi_out_sdcmd_in = int(response_array[0]) yield n_cycles_clock(dut, 16) dut.spi_busy = 0 #################### yield n_cycles_clock(dut, 1) if (int(dut.current_state.value) != 0x2): raise TestFailure( "Error WAIT_RESP state, cause wrong current state = %i" % int(dut.current_state.value)) ################################################## ''' bucle READ_RESP - WAIT_SPI READ_RESP State check current_state = WAIT_SPI check current_state = check spi_in_sdcmd_out = ''' ############################################### ########################### yield n_cycles_clock(dut, 1) limite = 1 if (response_array[0] == 0x48): limite = 5 ############################ for j in range(0, limite): print(j) dut.spi_out_sdcmd_in = int(response_array[j + 1]) ################### if (int(dut.current_state.value) != 0x3): raise TestFailure( "Error READ_RESP state, cause wrong current state = %i" % int(dut.current_state.value)) if (int(dut.spi_out_0_o) != int(response_array[j])): raise TestFailure( "Error READ_RESP state, cause wrong spi output = %i" % int(dut.spi_out_0_o)) #################### yield n_cycles_clock(dut, 1) ##################### if (int(dut.current_state.value) != 0x4): raise TestFailure( "Error WAIT_SPI state, cause wrong current state = %i" % int(dut.current_state.value)) #################### yield n_cycles_clock(dut, 1) if (int(dut.current_state.value) != 0x3): raise TestFailure( "Error last READ_RESP state, cause wrong current state = %i" % int(dut.current_state.value)) if (((int(dut.response.value) >> 32) & 0xFF) != response_array[0]): raise TestFailure( """Error RESPONSE,wrong value = {0}, expected value is {1}""". format(hex(int(dut.response.value)), hex(response_test))) yield n_cycles_clock(dut, 1) if (int(dut.current_state.value) != 0x0): raise TestFailure("Error IDLE state, cause wrong current state = %i" % int(dut.current_state.value))
def setup_dut(dut): cocotb.fork(Clock(dut.S_AXI_ACLK, CLK_PERIOD).start())
def setup_function(dut,key,enc_dec,text_input): cocotb.fork(Clock(dut.clk, CLK_PERIOD).start()) dut.key = key dut.enc_dec = enc_dec dut.text_input = text_input dut.rst = 1
def setup_dut(dut): cocotb.fork(Clock(dut.clk, CLK_PERIOD).start())
def setup_function(dut): cocotb.fork(Clock(dut.clk, CLK_PERIOD).start()) dut.rst = 0 dut.data_ready = 0