diff --git a/flows/makefile.simulate b/flows/makefile.simulate index 1c77a12c919935a08746808014b2966957fce736..195746d07c07ce4d622d6e8f879708ca39b121f4 100644 --- a/flows/makefile.simulate +++ b/flows/makefile.simulate @@ -157,11 +157,12 @@ flist_makefile_nanosoc: gen_defs @mkdir -p $(COCOTB_DIR) @(cd $(COCOTB_DIR); \ $(SOCLABS_SOCTOOLS_FLOW_DIR)/bin/filelist_compile.py -m -f $(DESIGN_VC) -o $(MAKEFILE_FILELIST);) - + +run_cocotb: DEFINES_VC += COCOTB_SIM run_cocotb: flist_makefile_nanosoc @mkdir -p $(SIM_DIR) @cd $(SIM_DIR); $(MAKE) -C $(SOCLABS_NANOSOC_TECH_DIR)/verif/cocotb clean SIM_BUILD=$(COCOTB_SCRATCH_DIR) - @cd $(SIM_DIR); $(MAKE) -C $(SOCLABS_NANOSOC_TECH_DIR)/verif/cocotb sim SIM=$(COCOTB_SIMULATOR) MODULE=$(TESTNAME) GUI=$(GUI) SIM_BUILD=$(COCOTB_SCRATCH_DIR) + @cd $(SIM_DIR); $(MAKE) -C $(SOCLABS_NANOSOC_TECH_DIR)/verif/cocotb sim SIM=$(COCOTB_SIMULATOR) TESTCASE=$(TESTNAME) GUI=$(GUI) SIM_BUILD=$(COCOTB_SCRATCH_DIR) ACCELERATOR=$(ACCELERATOR) sim_cocotb: GUI=1 sim_cocotb: run_cocotb diff --git a/verif/cocotb/makefile b/verif/cocotb/makefile index ff0f886ea12169e2d4326a84ee0237e83d51759c..e6d298b285bc5727baf126997d76a1e6ee41a095 100644 --- a/verif/cocotb/makefile +++ b/verif/cocotb/makefile @@ -30,6 +30,15 @@ else TOPLEVEL := nanosoc_tb +EXTRA_ARGS += +define+CORTEX_M0 +EXTRA_ARGS += +define+COCOTB_SIM + +ACCELERATOR ?= yes + +ifeq ($(ACCELERATOR),yes) + EXTRA_ARGS += +define+ACCELERATOR_SUBSYSTEM +endif + include $(SOCLABS_PROJECT_DIR)/simulate/sim/cocotb/makefile.flist include $(shell cocotb-config --makefiles)/Makefile.sim diff --git a/verif/cocotb/test_chip.py b/verif/cocotb/test_chip.py new file mode 100644 index 0000000000000000000000000000000000000000..766ee509f5467c20b93aae676c4927cdb569f1f3 --- /dev/null +++ b/verif/cocotb/test_chip.py @@ -0,0 +1,47 @@ +from random import randint, randrange, getrandbits, shuffle +from collections.abc import Iterable + +import logging +import cocotb +from cocotb.clock import Clock +from cocotb.regression import TestFactory +from cocotb.result import TestFailure +from cocotb.triggers import ClockCycles, Combine, Join, RisingEdge + +from cocotbext.axi import AxiBus, AxiMaster + +CLK_PERIOD = (10, "ns") +AXI_PREFIX = "S_AXI" + +async def setup_dut(dut): + cocotb.start_soon(Clock(dut.XTAL1, *CLK_PERIOD).start()) + dut.NRST.value = 0 + await ClockCycles(dut.XTAL1, 2) + dut.NRST.value = 1 + await ClockCycles(dut.XTAL1, 2) + +def binatodeci(binary): + return sum(val*(2**idx) for idx, val in enumerate(reversed(binary))) + +@cocotb.coroutine +async def reg_write(manager, register, data): + print("Writing address: "+str(register.address)) + await manager.write(register.address, data) + +@cocotb.coroutine +async def reg_read(manager, register, length = 1): + event = manager.init_read(register.address, length) + await event.wait() + return event.data.data + +@cocotb.coroutine +async def field_read(manager, register, field, length = 1): + reg_read_val = await reg_read(manager, register, length) + return getattr(register, field).decode_read_value(binatodeci(reg_read_val)) + + +@cocotb.test() +async def test_clocks(dut): + """Tests Clocks and Resets in Cocotb""" + await setup_dut(dut) + print("Setup Complete") \ No newline at end of file diff --git a/verif/cocotb/test_nanosoc_chip.py b/verif/cocotb/test_nanosoc_chip.py deleted file mode 100644 index 3f2211f7ee844d7658f3cf44e80a7e2b32e31e69..0000000000000000000000000000000000000000 --- a/verif/cocotb/test_nanosoc_chip.py +++ /dev/null @@ -1,135 +0,0 @@ -from random import randint, randrange, getrandbits, shuffle -from collections.abc import Iterable - -import logging -import cocotb -from cocotb.clock import Clock -from cocotb.regression import TestFactory -from cocotb.result import TestFailure -from cocotb.triggers import ClockCycles, Combine, Join, RisingEdge -# from cocotb_bus.drivers.amba import ( -# AXIBurst, AXI4Master, AXIProtocolError, AXIReadBurstLengthMismatch, -# AXIxRESP) -from systemrdltest.python.cmsdk_reg.lib import NormalCallbackSet -from systemrdltest.python.cmsdk_reg.reg_model import cmsdk_reg - -from cocotbext.axi import AxiBus, AxiMaster - -CLK_PERIOD = (10, "ns") -AXI_PREFIX = "S_AXI" - -async def setup_dut(dut): - cocotb.start_soon(Clock(dut.clk, *CLK_PERIOD).start()) - axi_bus = AxiBus.from_prefix(dut, AXI_PREFIX) - axi_driver = AxiMaster(axi_bus, dut.clk, dut.rstn, reset_active_level=False) - dut.rstn.value = 0 - await ClockCycles(dut.clk, 2) - dut.rstn.value = 1 - await ClockCycles(dut.clk, 2) - return axi_driver - -def binatodeci(binary): - return sum(val*(2**idx) for idx, val in enumerate(reversed(binary))) - -@cocotb.coroutine -async def reg_write(manager, register, data): - print("Writing address: "+str(register.address)) - await manager.write(register.address, data) - -@cocotb.coroutine -async def reg_read(manager, register, length = 1): - event = manager.init_read(register.address, length) - await event.wait() - return event.data.data - -@cocotb.coroutine -async def field_read(manager, register, field, length = 1): - reg_read_val = await reg_read(manager, register, length) - return getattr(register, field).decode_read_value(binatodeci(reg_read_val)) - -@cocotb.test() -async def test_read(dut): - """Test Software Readable CMSDK Registers can be read""" - - # Connect AXI4 driver into DUT AXI Signals - axim = AxiMaster(AxiBus.from_prefix(dut, AXI_PREFIX), dut.clk, dut.rstn, reset_active_level=False) - reg_address_map = cmsdk_reg.cmsdk_reg_cls(callbacks = NormalCallbackSet()) - - # Generate a Clock and Perform a Reset - await setup_dut(dut) - - # Select a readable register with known reset value - test_addr = reg_address_map.pid.PID_4 - expected_result = test_addr.ID.default - - #Read Register Field - read_result = await field_read(axim, test_addr, "ID") - - print(f"Address: {hex(test_addr.address)} | Read Value: {read_result}, Expected Value: {expected_result}") - assert read_result == expected_result - -@cocotb.test() -async def test_read(dut): - """Test 1 Software Readable CMSDK Register can be read""" - - # Connect AXI4 driver into DUT AXI Signals - - reg_address_map = cmsdk_reg.cmsdk_reg_cls(callbacks = NormalCallbackSet()) - - # Generate a Clock and Perform a Reset - axi_driver = await setup_dut(dut) - - # Select a readable register with known reset value - test_addr = reg_address_map.pid.PID_4 - expected_result = test_addr.ID.default - - #Read Register Field - read_result = await field_read(axi_driver, test_addr, "ID") - - log = logging.getLogger(f"cocotb.test") - log.info(f"Address: {hex(test_addr.address)} | Read Value: {read_result}, Expected Value: {expected_result}") - assert read_result == expected_result - -@cocotb.test() -async def test_readable_regs(dut): - """Test Software Readable CMSDK Registers can be read""" - - # Connect AXI4 driver into DUT AXI Signals - reg_address_map = cmsdk_reg.cmsdk_reg_cls(callbacks = NormalCallbackSet()) - - # Generate a Clock and Perform a Reset - axi_driver = await setup_dut(dut) - - # Setup Logger - log = logging.getLogger(f"cocotb.test") - - # Select a readable register with known reset values - sections = list(reg_address_map.get_sections()) - - # Get a list of readable registers - readable_reg_list = [] - for section in sections: - for reg in list(section.get_readable_registers()): - if isinstance(reg, Iterable): - for index in reg: - readable_reg_list.append(index) - else: - readable_reg_list.append(reg) - - # Randomly select registers in readable list and perform a read - shuffle(readable_reg_list) - for reg in readable_reg_list: - # Get a list of the fields in the register and randomise - readable_fields_list = list(reg.readable_fields) - shuffle(readable_fields_list) - - for field in readable_fields_list: - # Read each field - read_result = await field_read(axi_driver, reg, field.inst_name) - - # Get default (reset value) for each field - expected_result = field.default - - # Run an assertion against reset values - log.info(f"Field: {field.inst_name} @ Address: {hex(reg.address)} | Read Value: {read_result}, Expected Value: {expected_result}") - assert read_result == expected_result \ No newline at end of file diff --git a/verif/tb/verilog/nanosoc_tb.v b/verif/tb/verilog/nanosoc_tb.v index be19c15f457c2c4a6ed33158c31b6bbb8a5db811..c7be34f9465ae74577d78f395ff19684cab20324 100644 --- a/verif/tb/verilog/nanosoc_tb.v +++ b/verif/tb/verilog/nanosoc_tb.v @@ -123,10 +123,12 @@ SROM_Ax32 // -------------------------------------------------------------------------------- // Source for clock and reset // -------------------------------------------------------------------------------- + `ifndef COCOTB_SIM nanosoc_clkreset u_nanosoc_clkreset( .CLK (XTAL1), .NRST (NRST) ); + `endif // Pullup to suppress X-inputs pullup(P0[ 0]); @@ -228,7 +230,7 @@ reg baud_clk_del; wire FASTMODE = 1'b0; wire uart_clk = (FASTMODE) ? PCLK : baud_clk; //(baud_clk & !baud_clk_del); - +`ifndef COCOTB_SIM nanosoc_uart_capture #(.LOGFILENAME("logs/uart2.log")) u_nanosoc_uart_capture( .RESETn (NRST), @@ -238,6 +240,7 @@ reg baud_clk_del; .SIMULATIONEND (), // This signal set to 1 at the end of simulation. .AUXCTRL () ); +`endif // -------------------------------------------------------------------------------- // FTDI IO capture @@ -266,6 +269,7 @@ reg baud_clk_del; wire rxd8_valid; wire [7:0] rxd8_data ; +`ifndef COCOTB_SIM nanosoc_axi_stream_io_8_txd_from_file #( .TXDFILENAME(ADP_FILENAME) ) u_nanosoc_axi_stream_io_8_txd_from_file ( @@ -275,6 +279,7 @@ reg baud_clk_del; .txd8_valid (txd8_valid), .txd8_data (txd8_data) ); +`endif wire ft_miosio_o; wire ft_miosio_z; @@ -299,16 +304,17 @@ reg baud_clk_del; .txd_tdata8_o (rxd8_data) ); -nanosoc_axi_stream_io_8_rxd_to_file - #(.RXDFILENAME("logs/ft1248_out.log")) - u_nanosoc_axi_stream_io_8_rxd_to_file - ( - .aclk (XTAL1), - .aresetn (NRST), - .rxd8_ready (rxd8_ready), - .rxd8_valid (rxd8_valid), - .rxd8_data (rxd8_data) +`ifndef COCOTB_SIM + nanosoc_axi_stream_io_8_rxd_to_file#( + .RXDFILENAME("logs/ft1248_out.log") + ) u_nanosoc_axi_stream_io_8_rxd_to_file ( + .aclk (XTAL1), + .aresetn (NRST), + .rxd8_ready (rxd8_ready), + .rxd8_valid (rxd8_valid), + .rxd8_data (rxd8_data) ); +`endif nanosoc_track_tb_iostream u_nanosoc_track_tb_iostream @@ -341,6 +347,7 @@ nanosoc_ft1248x1_track .FTDI_IP2UART_o (ft_txd2uart) // Transmitted data to UART capture ); +`ifndef COCOTB_SIM nanosoc_uart_capture #(.LOGFILENAME("logs/ft1248_op.log")) u_nanosoc_uart_capture1( .RESETn (NRST), @@ -350,7 +357,9 @@ nanosoc_ft1248x1_track .SIMULATIONEND (), // This signal set to 1 at the end of simulation. .AUXCTRL () ); +`endif +`ifndef COCOTB_SIM nanosoc_uart_capture #(.LOGFILENAME("logs/ft1248_ip.log")) u_nanosoc_uart_capture2( .RESETn (NRST), @@ -360,7 +369,7 @@ nanosoc_ft1248x1_track .SIMULATIONEND (), // This signal set to 1 at the end of simulation. .AUXCTRL () ); - +`endif // -------------------------------------------------------------------------------- // Tracking CPU with Tarmac trace support @@ -542,6 +551,7 @@ nanosoc_ft1248x1_track `define DMAC_TRACK_PATH u_track_pl230_udma +`ifndef COCOTB_SIM nanosoc_dma_log_to_file #(.FILENAME("logs/dma230.log"),.NUM_CHNLS(2),.NUM_CHNL_BITS(1),.TIMESTAMP(1)) u_nanosoc_dma_log_to_file ( .hclk (`DMAC_TRACK_PATH.hclk), @@ -573,6 +583,7 @@ nanosoc_ft1248x1_track .dma_chnl (`DMAC_TRACK_PATH.u_pl230_ahb_ctrl.current_chnl), .dma_ctrl_state(`DMAC_TRACK_PATH.u_pl230_ahb_ctrl.ctrl_state) ); + `endif // -------------------------------------------------------------------------------- // Tracking Accelerator logging support @@ -580,6 +591,7 @@ nanosoc_ft1248x1_track `define ACC_PATH u_nanosoc_chip_pads.u_nanosoc_chip.u_system.u_ss_expansion.u_region_exp +`ifndef COCOTB_SIM nanosoc_accelerator_ss_logger #( .FILENAME("logs/acc_exp.log"), .TIMESTAMP(1) @@ -603,7 +615,7 @@ nanosoc_ft1248x1_track .exp_dlast_op_i (`ACC_PATH.EXP_DLAST[1] ), .exp_irq_o (`ACC_PATH.EXP_IRQ ) ); - +`endif // -------------------------------------------------------------------------------- // Debug tester connection - @@ -643,7 +655,6 @@ nanosoc_ft1248x1_track bufif1 (P0[31-16], debug_running, debug_test_en); bufif1 (P0[30-16], debug_err, debug_test_en); - cmsdk_debug_tester #(.ROM_MEMFILE((BE==1) ? "debugtester_be.hex" : "debugtester_le.hex")) u_cmsdk_debug_tester ( @@ -668,7 +679,6 @@ nanosoc_ft1248x1_track .TDI (TDI), .SWDIOTMS (SWDIOTMS) ); - `endif // -------------------------------------------------------------------------------- diff --git a/verif/tb/verilog/nanosoc_tb_qs.v b/verif/tb/verilog/nanosoc_tb_qs.v index 839544474715fb65f4068de6a8c1536a4ad784bf..d52dfde260f490a08894929ac3a9142627d845cd 100644 --- a/verif/tb/verilog/nanosoc_tb_qs.v +++ b/verif/tb/verilog/nanosoc_tb_qs.v @@ -123,10 +123,12 @@ SROM_Ax32 // -------------------------------------------------------------------------------- // Source for clock and reset // -------------------------------------------------------------------------------- + `ifndef COCOTB_SIM nanosoc_clkreset u_nanosoc_clkreset( .CLK (XTAL1), .NRST (NRST) ); + `endif // Pullup to suppress X-inputs pullup(P0[ 0]); @@ -228,7 +230,7 @@ reg baud_clk_del; wire FASTMODE = 1'b0; wire uart_clk = (FASTMODE) ? PCLK : baud_clk; //(baud_clk & !baud_clk_del); - +`ifndef COCOTB_SIM nanosoc_uart_capture #(.LOGFILENAME("logs/uart2.log")) u_nanosoc_uart_capture( .RESETn (NRST), @@ -238,67 +240,53 @@ reg baud_clk_del; .SIMULATIONEND (), // This signal set to 1 at the end of simulation. .AUXCTRL () ); +`endif // -------------------------------------------------------------------------------- // FTDI IO capture // -------------------------------------------------------------------------------- // UART connection cross over for UART test -// assign P1[0] = P1[3]; // UART 0 RXD = UART 1 TXD -// assign P1[2] = P1[1]; // UART 1 RXD = UART 0 TXD - -assign P1[4] = P1[5]; // loopback UART2 - -wire ft_clk_out = P1[1]; -wire ft_miso_in; -assign P1[0] = ft_miso_in; -wire ft_ssn_out = P1[3]; - -// -// AXI stream io testing -// - -wire txd8_ready; -wire txd8_valid; -wire [7:0] txd8_data ; - -wire rxd8_ready; -wire rxd8_valid; -wire [7:0] rxd8_data ; - -nanosoc_axi_stream_io_8_txd_from_file - #(.TXDFILENAME(ADP_FILENAME)) - u_nanosoc_axi_stream_io_8_txd_from_file - ( - .aclk (XTAL1), - .aresetn (NRST), - .txd8_ready (txd8_ready), - .txd8_valid (txd8_valid), - .txd8_data (txd8_data) - ); - -/* -axi_stream_io_8_buffer - u_axi_stream_io_8_buffer - ( - .aclk (XTAL1), - .aresetn (NRST), - .rxd8_ready (txd8_ready), - .rxd8_valid (txd8_valid), - .rxd8_data (txd8_data), - .txd8_ready (rxd8_ready), - .txd8_valid (rxd8_valid), - .txd8_data (rxd8_data) + // assign P1[0] = P1[3]; // UART 0 RXD = UART 1 TXD + // assign P1[2] = P1[1]; // UART 1 RXD = UART 0 TXD + + assign P1[4] = P1[5]; // loopback UART2 + + wire ft_clk_out = P1[1]; + wire ft_miso_in; + assign P1[0] = ft_miso_in; + wire ft_ssn_out = P1[3]; + + // + // AXI stream io testing + // + + wire txd8_ready; + wire txd8_valid; + wire [7:0] txd8_data ; + + wire rxd8_ready; + wire rxd8_valid; + wire [7:0] rxd8_data ; + +`ifndef COCOTB_SIM + nanosoc_axi_stream_io_8_txd_from_file #( + .TXDFILENAME(ADP_FILENAME) + ) u_nanosoc_axi_stream_io_8_txd_from_file ( + .aclk (XTAL1), + .aresetn (NRST), + .txd8_ready (txd8_ready), + .txd8_valid (txd8_valid), + .txd8_data (txd8_data) ); -*/ +`endif -wire ft_miosio_o; -wire ft_miosio_z; -wire ft_miosio_i = P1[2]; // & ft_miosio_z; -assign P1[2] = (ft_miosio_z) ? 1'bz : ft_miosio_o; + wire ft_miosio_o; + wire ft_miosio_z; + wire ft_miosio_i = P1[2]; // & ft_miosio_z; + assign P1[2] = (ft_miosio_z) ? 1'bz : ft_miosio_o; -nanosoc_ft1248x1_to_axi_streamio_v1_0 - u_nanosoc_ft1248x1_to_axi_streamio_v1_0 + nanosoc_ft1248x1_to_axi_streamio_v1_0 u_nanosoc_ft1248x1_to_axi_streamio_v1_0 ( .ft_clk_i (ft_clk_out), .ft_ssn_i (ft_ssn_out), @@ -316,16 +304,17 @@ nanosoc_ft1248x1_to_axi_streamio_v1_0 .txd_tdata8_o (rxd8_data) ); -nanosoc_axi_stream_io_8_rxd_to_file - #(.RXDFILENAME("logs/ft1248_out.log")) - u_nanosoc_axi_stream_io_8_rxd_to_file - ( - .aclk (XTAL1), - .aresetn (NRST), - .rxd8_ready (rxd8_ready), - .rxd8_valid (rxd8_valid), - .rxd8_data (rxd8_data) +`ifndef COCOTB_SIM + nanosoc_axi_stream_io_8_rxd_to_file#( + .RXDFILENAME("logs/ft1248_out.log") + ) u_nanosoc_axi_stream_io_8_rxd_to_file ( + .aclk (XTAL1), + .aresetn (NRST), + .rxd8_ready (rxd8_ready), + .rxd8_valid (rxd8_valid), + .rxd8_data (rxd8_data) ); +`endif nanosoc_track_tb_iostream u_nanosoc_track_tb_iostream @@ -358,6 +347,7 @@ nanosoc_ft1248x1_track .FTDI_IP2UART_o (ft_txd2uart) // Transmitted data to UART capture ); +`ifndef COCOTB_SIM nanosoc_uart_capture #(.LOGFILENAME("logs/ft1248_op.log")) u_nanosoc_uart_capture1( .RESETn (NRST), @@ -367,7 +357,9 @@ nanosoc_ft1248x1_track .SIMULATIONEND (), // This signal set to 1 at the end of simulation. .AUXCTRL () ); +`endif +`ifndef COCOTB_SIM nanosoc_uart_capture #(.LOGFILENAME("logs/ft1248_ip.log")) u_nanosoc_uart_capture2( .RESETn (NRST), @@ -377,7 +369,7 @@ nanosoc_ft1248x1_track .SIMULATIONEND (), // This signal set to 1 at the end of simulation. .AUXCTRL () ); - +`endif // -------------------------------------------------------------------------------- // Tracking CPU with Tarmac trace support @@ -522,6 +514,7 @@ nanosoc_ft1248x1_track `define ACC_PATH u_nanosoc_chip_pads.u_nanosoc_chip.u_system.u_ss_expansion.u_region_exp +`ifndef COCOTB_SIM nanosoc_accelerator_ss_logger #( .FILENAME("logs/acc_exp.log"), .TIMESTAMP(1) @@ -545,7 +538,7 @@ nanosoc_ft1248x1_track .exp_dlast_op_i (`ACC_PATH.EXP_DLAST[1] ), .exp_irq_o (`ACC_PATH.EXP_IRQ ) ); - +`endif // -------------------------------------------------------------------------------- // Debug tester connection - @@ -585,7 +578,6 @@ nanosoc_ft1248x1_track bufif1 (P0[31-16], debug_running, debug_test_en); bufif1 (P0[30-16], debug_err, debug_test_en); - cmsdk_debug_tester #(.ROM_MEMFILE((BE==1) ? "debugtester_be.hex" : "debugtester_le.hex")) u_cmsdk_debug_tester ( @@ -610,7 +602,6 @@ nanosoc_ft1248x1_track .TDI (TDI), .SWDIOTMS (SWDIOTMS) ); - `endif // --------------------------------------------------------------------------------