From 523fa3a5bba2462008c598b3bbe531586b540ed2 Mon Sep 17 00:00:00 2001 From: M0stafaRady <107422726+M0stafaRady@users.noreply.github.com> Date: Sat, 22 Oct 2022 21:14:25 +0200 Subject: [PATCH] cooctb- update gpio tests for caravan (#341) * update gpio tests for caravan * cocotb - Add gpio caravan tests --- verilog/dv/cocotb/caravel_tests.py | 1 + verilog/dv/cocotb/caravel_top.sv | 2 + verilog/dv/cocotb/interfaces/common.py | 1 + verilog/dv/cocotb/interfaces/cpu.py | 5 + verilog/dv/cocotb/tests.json | 77 ++- .../tests/gpio_caravan/gpio_all_i_caravan.c | 87 +++ .../gpio_caravan/gpio_all_i_pd_caravan.c | 58 ++ .../gpio_caravan/gpio_all_i_pu_caravan.c | 57 ++ .../tests/gpio_caravan/gpio_all_o_caravan.c | 81 +++ .../cocotb/tests/gpio_caravan/gpio_caravan.py | 500 ++++++++++++++++++ .../dv/cocotb/tests/gpio_caravan/gpio_user.py | 468 ++++++++++++++++ verilog/dv/cocotb/verify_cocotb.py | 9 +- 12 files changed, 1319 insertions(+), 27 deletions(-) create mode 100644 verilog/dv/cocotb/tests/gpio_caravan/gpio_all_i_caravan.c create mode 100644 verilog/dv/cocotb/tests/gpio_caravan/gpio_all_i_pd_caravan.c create mode 100644 verilog/dv/cocotb/tests/gpio_caravan/gpio_all_i_pu_caravan.c create mode 100644 verilog/dv/cocotb/tests/gpio_caravan/gpio_all_o_caravan.c create mode 100644 verilog/dv/cocotb/tests/gpio_caravan/gpio_caravan.py create mode 100644 verilog/dv/cocotb/tests/gpio_caravan/gpio_user.py diff --git a/verilog/dv/cocotb/caravel_tests.py b/verilog/dv/cocotb/caravel_tests.py index f1aabcc4..98169871 100644 --- a/verilog/dv/cocotb/caravel_tests.py +++ b/verilog/dv/cocotb/caravel_tests.py @@ -37,6 +37,7 @@ from tests.irq.IRQ_external import * from tests.irq.IRQ_timer import * from tests.irq.IRQ_uart import * from tests.gpio.gpio import * +from tests.gpio_caravan.gpio_caravan import * from tests.gpio.gpio_user import * from tests.mgmt_gpio.mgmt_gpio import * from tests.timer.timer import * diff --git a/verilog/dv/cocotb/caravel_top.sv b/verilog/dv/cocotb/caravel_top.sv index 1772ab64..30b73b60 100644 --- a/verilog/dv/cocotb/caravel_top.sv +++ b/verilog/dv/cocotb/caravel_top.sv @@ -371,4 +371,6 @@ reg [7:0] DM_INIT = `ifdef DM_INIT `DM_INIT `else 0 `endif; reg GL = `ifdef GL 1 `else 0 `endif; +reg CARAVAN = `ifdef CARAVAN 1 `else 0 `endif; + endmodule \ No newline at end of file diff --git a/verilog/dv/cocotb/interfaces/common.py b/verilog/dv/cocotb/interfaces/common.py index 76240f7e..b5d98414 100644 --- a/verilog/dv/cocotb/interfaces/common.py +++ b/verilog/dv/cocotb/interfaces/common.py @@ -74,6 +74,7 @@ def fill_macros(macros_hdl): Macros['MPRJ_IO_PADS_2'] = macros_hdl.MPRJ_IO_PADS_2.value.integer Macros['MPRJ_IO_PADS'] = macros_hdl.MPRJ_IO_PADS.value.integer Macros['GL'] = macros_hdl.GL.value.integer + Macros['CARAVAN'] = macros_hdl.CARAVAN.value.integer diff --git a/verilog/dv/cocotb/interfaces/cpu.py b/verilog/dv/cocotb/interfaces/cpu.py index b2bd6885..1f925370 100644 --- a/verilog/dv/cocotb/interfaces/cpu.py +++ b/verilog/dv/cocotb/interfaces/cpu.py @@ -193,6 +193,11 @@ class RiskV: def read_debug_reg2(self): return self.debug_hdl.debug_reg_2.value.integer + def read_debug_reg1_str(self): + return self.debug_hdl.debug_reg_1.value.binstr + def read_debug_reg2_str(self): + return self.debug_hdl.debug_reg_2.value.binstr + # writing debug registers using backdoor because in GL cpu can't be disabled for now because of different netlist names def write_debug_reg1_backdoor(self,data): self.debug_hdl.debug_reg_1.value = data diff --git a/verilog/dv/cocotb/tests.json b/verilog/dv/cocotb/tests.json index 411d1821..98150f1d 100644 --- a/verilog/dv/cocotb/tests.json +++ b/verilog/dv/cocotb/tests.json @@ -4,10 +4,16 @@ "_comment1" :"GL regressions run this test in gatelevel, GL_SDF regression run this test with SDF included" ,"gpio_all_i" :{"level":0, "SW":true, - "RTL":["r_rtl","r_caravan_rtl","setup","gpio_rtl","push","push_gl","nightly","weekly","tape_out"], - "GL":["r_gl","r_caravan_gl","push_gl","gpio_gl","nightly","weekly","tape_out"], + "RTL":["r_rtl","setup","gpio_rtl","push","push_gl","nightly","weekly","tape_out"], + "GL":["r_gl","push_gl","gpio_gl","nightly","weekly","tape_out"], "GL_SDF":["r_sdf","weekly","tape_out"], "description":"configure all gpios as mgmt input using automatic approach firmware and check them"} + ,"gpio_all_i_caravan" :{"level":0, + "SW":true, + "RTL":["r_caravan_rtl"], + "GL":["r_caravan_gl"], + "GL_SDF":[], + "description":"configure all gpios as mgmt input using automatic approach firmware and check them for caravan"} ,"hk_disable" :{"level":0, "SW":true, @@ -23,25 +29,33 @@ "description":"test uart reception"} ,"hk_regs_rst_spi" :{"level":0, "SW":false, - "RTL":["r_rtl","setup","push","push_gl","nightly","weekly","tape_out"], - "GL":["r_gl","push_gl","nightly","weekly","tape_out"], + "RTL":["r_rtl","r_caravan_rtl","setup","push","push_gl","nightly","weekly","tape_out"], + "GL":["r_gl","r_caravan_gl","push_gl","nightly","weekly","tape_out"], "GL_SDF":["r_sdf","weekly","tape_out"], "description":"check reset value of house keeping registers by reading them trough the spi housekeeping"} ,"gpio_all_i_user" :{"level":0, "SW":true, - "RTL":["r_rtl","setup","r_caravan_rtl","gpio_rtl","push","push_gl","nightly","weekly","tape_out"], - "GL":["r_gl","r_caravan_gl","push_gl","gpio_gl","nightly","weekly","tape_out"], + "RTL":["r_rtl","setup","gpio_rtl","push","push_gl","nightly","weekly","tape_out"], + "GL":["r_gl","push_gl","gpio_gl","nightly","weekly","tape_out"], "GL_SDF":["r_sdf","weekly","tape_out"], "description":"configure all gpios as user input using automatic approach firmware and check them"} ,"gpio_all_i_pu" :{"level":0, "SW":true, - "RTL":["r_rtl","setup","r_caravan_rtl","gpio_rtl","push","push_gl","nightly","weekly","tape_out"], - "GL":["r_gl","r_caravan_gl","push_gl","gpio_gl","nightly","weekly","tape_out"], + "RTL":["r_rtl","setup","gpio_rtl","push","push_gl","nightly","weekly","tape_out"], + "GL":["r_gl","push_gl","gpio_gl","nightly","weekly","tape_out"], "GL_SDF":["r_sdf","weekly","tape_out"], "description":"configure all gpios as mgmt input pull up using automatic approach firmware and check them"} + + ,"gpio_all_i_pu_caravan" :{"level":0, + "SW":true, + "RTL":["r_caravan_rtl"], + "GL":["r_caravan_gl"], + "GL_SDF":[], + "description":"configure all gpios as mgmt input pull up using automatic approach firmware and check them for caravan"} + ,"gpio_all_i_pu_user" :{"level":0, "SW":true, "RTL":["r_rtl","setup","gpio_rtl","push","push_gl","nightly","weekly","tape_out"], @@ -51,15 +65,21 @@ ,"gpio_all_i_pd" :{"level":0, "SW":true, - "RTL":["r_rtl","setup","r_caravan_rtl","gpio_rtl","push","push_gl","nightly","weekly","tape_out"], - "GL":["r_gl","r_caravan_gl","push_gl","gpio_gl","nightly","weekly","tape_out"], + "RTL":["r_rtl","setup","gpio_rtl","push","push_gl","nightly","weekly","tape_out"], + "GL":["r_gl","push_gl","gpio_gl","nightly","weekly","tape_out"], "GL_SDF":["r_sdf","weekly","tape_out"], "description":"configure all gpios as mgmt input pull down using automatic approach firmware and check them"} + ,"gpio_all_i_pd_caravan" :{"level":0, + "SW":true, + "RTL":["r_caravan_rtl"], + "GL":["r_caravan_gl"], + "GL_SDF":[], + "description":"configure all gpios as mgmt input pull down using automatic approach firmware and check them for caravan"} ,"gpio_all_i_pd_user" :{"level":0, "SW":true, "RTL":["r_rtl","setup","gpio_rtl","push","push_gl","nightly","weekly","tape_out"], - "GL":["r_gl","r_caravan_gl","push_gl","gpio_gl","nightly","weekly","tape_out"], + "GL":["r_gl","push_gl","gpio_gl","nightly","weekly","tape_out"], "GL_SDF":["r_sdf","weekly","tape_out"], "description":"configure all gpios as user input pull down using automatic approach firmware and check them"} @@ -72,11 +92,18 @@ ,"gpio_all_o" :{"level":0, "SW":true, - "RTL":["r_rtl","setup","r_caravan_rtl","gpio_rtl","push","push_gl","nightly","weekly","tape_out"], - "GL":["r_gl","r_caravan_gl","push_gl","gpio_gl","nightly","weekly","tape_out"], + "RTL":["r_rtl","setup","gpio_rtl","push","push_gl","nightly","weekly","tape_out"], + "GL":["r_gl","push_gl","gpio_gl","nightly","weekly","tape_out"], "GL_SDF":["r_sdf","weekly","tape_out"], "description":"configure all gpios as mgmt output using automatic approach firmware and check them"} + ,"gpio_all_o_caravan" :{"level":0, + "SW":true, + "RTL":["r_caravan_rtl"], + "GL":["r_caravan_gl"], + "GL_SDF":[], + "description":"configure all gpios as mgmt output using automatic approach firmware and check them for caravan"} + ,"gpio_all_o_user" :{"level":0, "SW":true, "RTL":["r_rtl","setup","gpio_rtl","push","push_gl","nightly","weekly","tape_out"], @@ -153,8 +180,8 @@ ,"timer0_oneshot" :{"level":0, "SW":true, - "RTL":["r_rtl","setup","nightly","weekly","tape_out"], - "GL":["r_gl","nightly","weekly","tape_out"], + "RTL":["r_rtl","r_caravan_rtl","setup","nightly","weekly","tape_out"], + "GL":["r_gl","r_caravan_gl","nightly","weekly","tape_out"], "GL_SDF":["r_sdf","weekly","tape_out"], "description":"check timer0 oneshot mode"} @@ -174,27 +201,27 @@ ,"uart_tx" :{"level":0, "SW":true, - "RTL":["r_rtl","setup","nightly","weekly","tape_out"], - "GL":["r_gl","nightly","weekly","tape_out"], + "RTL":["r_rtl","r_caravan_rtl","setup","nightly","weekly","tape_out"], + "GL":["r_gl","r_caravan_gl","nightly","weekly","tape_out"], "GL_SDF":["r_sdf","weekly","tape_out"], "description":"test uart transmit"} ,"debug" :{"level":0, "SW":true, - "RTL":["r_rtl","setup","nightly","weekly","tape_out"], - "GL":["r_gl","nightly","weekly","tape_out"], + "RTL":["r_rtl","r_caravan_rtl","setup","nightly","weekly","tape_out"], + "GL":["r_gl","r_caravan_gl","nightly","weekly","tape_out"], "GL_SDF":["r_sdf","weekly","tape_out"], "description":"use caravel in debug mode and check reading and writing from dff2 RAM"} ,"spi_master_rd" :{"level":0, "SW":true, - "RTL":["r_rtl","setup","nightly","weekly","tape_out"], - "GL":["r_gl","nightly","weekly","tape_out"], + "RTL":["r_rtl","r_caravan_rtl","setup","nightly","weekly","tape_out"], + "GL":["r_gl","r_caravan_gl","nightly","weekly","tape_out"], "GL_SDF":["r_sdf","weekly","tape_out"], "description":"using SPI master for reading from external memory"} ,"user_pass_thru_rd" :{"level":0, "SW":true, - "RTL":["r_rtl","setup","nightly","weekly","tape_out"], - "GL":["r_gl","nightly","weekly","tape_out"], + "RTL":["r_rtl","r_caravan_rtl","setup","nightly","weekly","tape_out"], + "GL":["r_gl","r_caravan_gl","nightly","weekly","tape_out"], "GL_SDF":["r_sdf","weekly","tape_out"], "description":"use the housekeeping spi in user pass thru mode to read from external mem"} @@ -214,8 +241,8 @@ ,"la" :{"level":0, "SW":true, - "RTL":["r_rtl","setup","nightly","weekly","tape_out"], - "GL":["r_gl","nightly","weekly","tape_out"], + "RTL":["r_rtl","r_caravan_rtl","setup","nightly","weekly","tape_out"], + "GL":["r_gl","r_caravan_gl","nightly","weekly","tape_out"], "GL_SDF":["r_sdf","weekly","tape_out"], "description":"check logic analyzer input and output enable"} diff --git a/verilog/dv/cocotb/tests/gpio_caravan/gpio_all_i_caravan.c b/verilog/dv/cocotb/tests/gpio_caravan/gpio_all_i_caravan.c new file mode 100644 index 00000000..4fa59722 --- /dev/null +++ b/verilog/dv/cocotb/tests/gpio_caravan/gpio_all_i_caravan.c @@ -0,0 +1,87 @@ +#include +#include +#include "../bitbang/bitbang_functions.c" + +void main(){ + unsigned int i, j, k; + reg_wb_enable =1; // for enable writing to reg_debug_1 and reg_debug_2 + reg_debug_1 = 0x0; + reg_debug_2 = 0x0; + reg_hkspi_disable = 1; + reg_mprj_io_37 = GPIO_MODE_MGMT_STD_INPUT_NOPULL; + reg_mprj_io_36 = GPIO_MODE_MGMT_STD_INPUT_NOPULL; + reg_mprj_io_35 = GPIO_MODE_MGMT_STD_INPUT_NOPULL; + reg_mprj_io_34 = GPIO_MODE_MGMT_STD_INPUT_NOPULL; + reg_mprj_io_33 = GPIO_MODE_MGMT_STD_INPUT_NOPULL; + reg_mprj_io_32 = GPIO_MODE_MGMT_STD_INPUT_NOPULL; + reg_mprj_io_31 = GPIO_MODE_MGMT_STD_INPUT_NOPULL; + reg_mprj_io_30 = GPIO_MODE_MGMT_STD_INPUT_NOPULL; + reg_mprj_io_29 = GPIO_MODE_MGMT_STD_INPUT_NOPULL; + reg_mprj_io_28 = GPIO_MODE_MGMT_STD_INPUT_NOPULL; + reg_mprj_io_27 = GPIO_MODE_MGMT_STD_INPUT_NOPULL; + reg_mprj_io_26 = GPIO_MODE_MGMT_STD_INPUT_NOPULL; + reg_mprj_io_25 = GPIO_MODE_MGMT_STD_INPUT_NOPULL; + reg_mprj_io_24 = GPIO_MODE_MGMT_STD_INPUT_NOPULL; + reg_mprj_io_23 = GPIO_MODE_MGMT_STD_INPUT_NOPULL; + reg_mprj_io_22 = GPIO_MODE_MGMT_STD_INPUT_NOPULL; + reg_mprj_io_21 = GPIO_MODE_MGMT_STD_INPUT_NOPULL; + reg_mprj_io_20 = GPIO_MODE_MGMT_STD_INPUT_NOPULL; + reg_mprj_io_19 = GPIO_MODE_MGMT_STD_INPUT_NOPULL; + reg_mprj_io_18 = GPIO_MODE_MGMT_STD_INPUT_NOPULL; + reg_mprj_io_17 = GPIO_MODE_MGMT_STD_INPUT_NOPULL; + reg_mprj_io_16 = GPIO_MODE_MGMT_STD_INPUT_NOPULL; + reg_mprj_io_15 = GPIO_MODE_MGMT_STD_INPUT_NOPULL; + reg_mprj_io_14 = GPIO_MODE_MGMT_STD_INPUT_NOPULL; + reg_mprj_io_13 = GPIO_MODE_MGMT_STD_INPUT_NOPULL; + reg_mprj_io_12 = GPIO_MODE_MGMT_STD_INPUT_NOPULL; + reg_mprj_io_11 = GPIO_MODE_MGMT_STD_INPUT_NOPULL; + reg_mprj_io_10 = GPIO_MODE_MGMT_STD_INPUT_NOPULL; + reg_mprj_io_9 = GPIO_MODE_MGMT_STD_INPUT_NOPULL; + reg_mprj_io_8 = GPIO_MODE_MGMT_STD_INPUT_NOPULL; + reg_mprj_io_7 = GPIO_MODE_MGMT_STD_INPUT_NOPULL; + reg_mprj_io_6 = GPIO_MODE_MGMT_STD_INPUT_NOPULL; + reg_mprj_io_5 = GPIO_MODE_MGMT_STD_INPUT_NOPULL; + reg_mprj_io_4 = GPIO_MODE_MGMT_STD_INPUT_NOPULL; + reg_mprj_io_3 = GPIO_MODE_MGMT_STD_INPUT_NOPULL; + reg_mprj_io_2 = GPIO_MODE_MGMT_STD_INPUT_NOPULL; + reg_mprj_io_1 = GPIO_MODE_MGMT_STD_INPUT_NOPULL; + reg_mprj_io_0 = GPIO_MODE_MGMT_STD_INPUT_NOPULL; + reg_mprj_io_0 = GPIO_MODE_MGMT_STD_INPUT_NOPULL; + + reg_mprj_xfer = 1; + while (reg_mprj_xfer == 1); + + reg_debug_1 = 0XAA; // configuration done wait environment to send 0xFFFFFFFF to reg_mprj_datal + while (reg_mprj_datal != 0xfe003fff); // gpios 14 to 25 has to be 0 + reg_debug_2 = reg_mprj_datal; + reg_debug_1 = 0XBB; // configuration done wait environment to send 0xAAAAAAAA to reg_mprj_datal + while (reg_mprj_datal != 0xaa002aaa); + reg_debug_2 = reg_mprj_datal; + reg_debug_1 = 0XCC; // configuration done wait environment to send 0x55555555 to reg_mprj_datal + while (reg_mprj_datal != 0x54001555); + reg_debug_2 = reg_mprj_datal; + reg_debug_1 = 0XDD; // configuration done wait environment to send 0x0 to reg_mprj_datal + while (reg_mprj_datal != 0x0); + reg_debug_2 = reg_mprj_datal; + reg_debug_1 = 0XD1; + while (reg_mprj_datah != 0x3F); + reg_debug_2 = reg_mprj_datah; + reg_debug_1 = 0XD2; + while (reg_mprj_datah != 0x0); + reg_debug_2 = reg_mprj_datah; + reg_debug_1 = 0XD3; + while (reg_mprj_datah != 0x15); + reg_debug_2 = reg_mprj_datah; + reg_debug_1 = 0XD4; + while (reg_mprj_datah != 0x2A); + reg_debug_2 = reg_mprj_datah; + reg_debug_1 = 0XD5; + reg_debug_1 = 0XD5; // for delay insertion for release + // trying to inject error by sending data to gpio by firmware where gpios configured as input + reg_mprj_datal = 0x5AE1FFB8; // random number + reg_mprj_datah = 0x1E; // random number + + reg_debug_2 = 0xFF; +} + + diff --git a/verilog/dv/cocotb/tests/gpio_caravan/gpio_all_i_pd_caravan.c b/verilog/dv/cocotb/tests/gpio_caravan/gpio_all_i_pd_caravan.c new file mode 100644 index 00000000..e7dccc76 --- /dev/null +++ b/verilog/dv/cocotb/tests/gpio_caravan/gpio_all_i_pd_caravan.c @@ -0,0 +1,58 @@ +#include +#include +#include "../bitbang/bitbang_functions.c" + +void main(){ + unsigned int i, j, k; + reg_wb_enable =1; // for enable writing to reg_debug_1 and reg_debug_2 + reg_debug_1 = 0x0; + reg_debug_2 = 0x0; + reg_hkspi_disable = 1; + reg_mprj_io_37 = GPIO_MODE_MGMT_STD_INPUT_PULLDOWN; + reg_mprj_io_36 = GPIO_MODE_MGMT_STD_INPUT_PULLDOWN; + reg_mprj_io_35 = GPIO_MODE_MGMT_STD_INPUT_PULLDOWN; + reg_mprj_io_34 = GPIO_MODE_MGMT_STD_INPUT_PULLDOWN; + reg_mprj_io_33 = GPIO_MODE_MGMT_STD_INPUT_PULLDOWN; + reg_mprj_io_32 = GPIO_MODE_MGMT_STD_INPUT_PULLDOWN; + reg_mprj_io_31 = GPIO_MODE_MGMT_STD_INPUT_PULLDOWN; + reg_mprj_io_30 = GPIO_MODE_MGMT_STD_INPUT_PULLDOWN; + reg_mprj_io_29 = GPIO_MODE_MGMT_STD_INPUT_PULLDOWN; + reg_mprj_io_28 = GPIO_MODE_MGMT_STD_INPUT_PULLDOWN; + reg_mprj_io_27 = GPIO_MODE_MGMT_STD_INPUT_PULLDOWN; + reg_mprj_io_26 = GPIO_MODE_MGMT_STD_INPUT_PULLDOWN; + reg_mprj_io_25 = GPIO_MODE_MGMT_STD_INPUT_PULLDOWN; + reg_mprj_io_24 = GPIO_MODE_MGMT_STD_INPUT_PULLDOWN; + reg_mprj_io_23 = GPIO_MODE_MGMT_STD_INPUT_PULLDOWN; + reg_mprj_io_22 = GPIO_MODE_MGMT_STD_INPUT_PULLDOWN; + reg_mprj_io_21 = GPIO_MODE_MGMT_STD_INPUT_PULLDOWN; + reg_mprj_io_20 = GPIO_MODE_MGMT_STD_INPUT_PULLDOWN; + reg_mprj_io_19 = GPIO_MODE_MGMT_STD_INPUT_PULLDOWN; + reg_mprj_io_18 = GPIO_MODE_MGMT_STD_INPUT_PULLDOWN; + reg_mprj_io_17 = GPIO_MODE_MGMT_STD_INPUT_PULLDOWN; + reg_mprj_io_16 = GPIO_MODE_MGMT_STD_INPUT_PULLDOWN; + reg_mprj_io_15 = GPIO_MODE_MGMT_STD_INPUT_PULLDOWN; + reg_mprj_io_14 = GPIO_MODE_MGMT_STD_INPUT_PULLDOWN; + reg_mprj_io_13 = GPIO_MODE_MGMT_STD_INPUT_PULLDOWN; + reg_mprj_io_12 = GPIO_MODE_MGMT_STD_INPUT_PULLDOWN; + reg_mprj_io_11 = GPIO_MODE_MGMT_STD_INPUT_PULLDOWN; + reg_mprj_io_10 = GPIO_MODE_MGMT_STD_INPUT_PULLDOWN; + reg_mprj_io_9 = GPIO_MODE_MGMT_STD_INPUT_PULLDOWN; + reg_mprj_io_8 = GPIO_MODE_MGMT_STD_INPUT_PULLDOWN; + reg_mprj_io_7 = GPIO_MODE_MGMT_STD_INPUT_PULLDOWN; + reg_mprj_io_6 = GPIO_MODE_MGMT_STD_INPUT_PULLDOWN; + reg_mprj_io_5 = GPIO_MODE_MGMT_STD_INPUT_PULLDOWN; + reg_mprj_io_4 = GPIO_MODE_MGMT_STD_INPUT_PULLDOWN; + reg_mprj_io_3 = GPIO_MODE_MGMT_STD_INPUT_PULLDOWN; + reg_mprj_io_2 = GPIO_MODE_MGMT_STD_INPUT_PULLDOWN; + reg_mprj_io_1 = GPIO_MODE_MGMT_STD_INPUT_PULLDOWN; + reg_mprj_io_0 = GPIO_MODE_MGMT_STD_INPUT_PULLDOWN; + reg_mprj_io_0 = GPIO_MODE_MGMT_STD_INPUT_PULLDOWN; + + reg_mprj_xfer = 1; + while (reg_mprj_xfer == 1); + + reg_debug_1 = 0XAA; // configuration done + + print("adding a very very long delay because cpu produces X's when code finish and this break the simulation"); + while (true); +} diff --git a/verilog/dv/cocotb/tests/gpio_caravan/gpio_all_i_pu_caravan.c b/verilog/dv/cocotb/tests/gpio_caravan/gpio_all_i_pu_caravan.c new file mode 100644 index 00000000..d7f71d6c --- /dev/null +++ b/verilog/dv/cocotb/tests/gpio_caravan/gpio_all_i_pu_caravan.c @@ -0,0 +1,57 @@ +#include +#include +#include "../bitbang/bitbang_functions.c" + +void main(){ + unsigned int i, j, k; + reg_wb_enable =1; // for enable writing to reg_debug_1 and reg_debug_2 + reg_debug_1 = 0x0; + reg_debug_2 = 0x0; + reg_hkspi_disable = 1; + reg_mprj_io_37 = GPIO_MODE_MGMT_STD_INPUT_PULLUP; + reg_mprj_io_36 = GPIO_MODE_MGMT_STD_INPUT_PULLUP; + reg_mprj_io_35 = GPIO_MODE_MGMT_STD_INPUT_PULLUP; + reg_mprj_io_34 = GPIO_MODE_MGMT_STD_INPUT_PULLUP; + reg_mprj_io_33 = GPIO_MODE_MGMT_STD_INPUT_PULLUP; + reg_mprj_io_32 = GPIO_MODE_MGMT_STD_INPUT_PULLUP; + reg_mprj_io_31 = GPIO_MODE_MGMT_STD_INPUT_PULLUP; + reg_mprj_io_30 = GPIO_MODE_MGMT_STD_INPUT_PULLUP; + reg_mprj_io_29 = GPIO_MODE_MGMT_STD_INPUT_PULLUP; + reg_mprj_io_28 = GPIO_MODE_MGMT_STD_INPUT_PULLUP; + reg_mprj_io_27 = GPIO_MODE_MGMT_STD_INPUT_PULLUP; + reg_mprj_io_26 = GPIO_MODE_MGMT_STD_INPUT_PULLUP; + reg_mprj_io_25 = GPIO_MODE_MGMT_STD_INPUT_PULLUP; + reg_mprj_io_24 = GPIO_MODE_MGMT_STD_INPUT_PULLUP; + reg_mprj_io_23 = GPIO_MODE_MGMT_STD_INPUT_PULLUP; + reg_mprj_io_22 = GPIO_MODE_MGMT_STD_INPUT_PULLUP; + reg_mprj_io_21 = GPIO_MODE_MGMT_STD_INPUT_PULLUP; + reg_mprj_io_20 = GPIO_MODE_MGMT_STD_INPUT_PULLUP; + reg_mprj_io_19 = GPIO_MODE_MGMT_STD_INPUT_PULLUP; + reg_mprj_io_18 = GPIO_MODE_MGMT_STD_INPUT_PULLUP; + reg_mprj_io_17 = GPIO_MODE_MGMT_STD_INPUT_PULLUP; + reg_mprj_io_16 = GPIO_MODE_MGMT_STD_INPUT_PULLUP; + reg_mprj_io_15 = GPIO_MODE_MGMT_STD_INPUT_PULLUP; + reg_mprj_io_14 = GPIO_MODE_MGMT_STD_INPUT_PULLUP; + reg_mprj_io_13 = GPIO_MODE_MGMT_STD_INPUT_PULLUP; + reg_mprj_io_12 = GPIO_MODE_MGMT_STD_INPUT_PULLUP; + reg_mprj_io_11 = GPIO_MODE_MGMT_STD_INPUT_PULLUP; + reg_mprj_io_10 = GPIO_MODE_MGMT_STD_INPUT_PULLUP; + reg_mprj_io_9 = GPIO_MODE_MGMT_STD_INPUT_PULLUP; + reg_mprj_io_8 = GPIO_MODE_MGMT_STD_INPUT_PULLUP; + reg_mprj_io_7 = GPIO_MODE_MGMT_STD_INPUT_PULLUP; + reg_mprj_io_6 = GPIO_MODE_MGMT_STD_INPUT_PULLUP; + reg_mprj_io_5 = GPIO_MODE_MGMT_STD_INPUT_PULLUP; + reg_mprj_io_4 = GPIO_MODE_MGMT_STD_INPUT_PULLUP; + reg_mprj_io_3 = GPIO_MODE_MGMT_STD_INPUT_PULLUP; + reg_mprj_io_2 = GPIO_MODE_MGMT_STD_INPUT_PULLUP; + reg_mprj_io_1 = GPIO_MODE_MGMT_STD_INPUT_PULLUP; + reg_mprj_io_0 = GPIO_MODE_MGMT_STD_INPUT_PULLUP; + reg_mprj_io_0 = GPIO_MODE_MGMT_STD_INPUT_PULLUP; + + reg_mprj_xfer = 1; + while (reg_mprj_xfer == 1); + + reg_debug_1 = 0XAA; // configuration done + print("adding a very very long delay because cpu produces X's when code finish and this break the simulation"); + while (true); +} diff --git a/verilog/dv/cocotb/tests/gpio_caravan/gpio_all_o_caravan.c b/verilog/dv/cocotb/tests/gpio_caravan/gpio_all_o_caravan.c new file mode 100644 index 00000000..8ea9111c --- /dev/null +++ b/verilog/dv/cocotb/tests/gpio_caravan/gpio_all_o_caravan.c @@ -0,0 +1,81 @@ +#include +#include +#include "../bitbang/bitbang_functions.c" + +void main(){ + unsigned int i, j, k; + reg_wb_enable =1; // for enable writing to reg_debug_1 and reg_debug_2 + reg_debug_1 = 0x0; + reg_debug_2 = 0x0; + reg_hkspi_disable = 1; + reg_mprj_io_37 = GPIO_MODE_MGMT_STD_OUTPUT; + reg_mprj_io_36 = GPIO_MODE_MGMT_STD_OUTPUT; + reg_mprj_io_35 = GPIO_MODE_MGMT_STD_OUTPUT; + reg_mprj_io_34 = GPIO_MODE_MGMT_STD_OUTPUT; + reg_mprj_io_33 = GPIO_MODE_MGMT_STD_OUTPUT; + reg_mprj_io_32 = GPIO_MODE_MGMT_STD_OUTPUT; + reg_mprj_io_31 = GPIO_MODE_MGMT_STD_OUTPUT; + reg_mprj_io_30 = GPIO_MODE_MGMT_STD_OUTPUT; + reg_mprj_io_29 = GPIO_MODE_MGMT_STD_OUTPUT; + reg_mprj_io_28 = GPIO_MODE_MGMT_STD_OUTPUT; + reg_mprj_io_27 = GPIO_MODE_MGMT_STD_OUTPUT; + reg_mprj_io_26 = GPIO_MODE_MGMT_STD_OUTPUT; + reg_mprj_io_25 = GPIO_MODE_MGMT_STD_OUTPUT; + reg_mprj_io_24 = GPIO_MODE_MGMT_STD_OUTPUT; + reg_mprj_io_23 = GPIO_MODE_MGMT_STD_OUTPUT; + reg_mprj_io_22 = GPIO_MODE_MGMT_STD_OUTPUT; + reg_mprj_io_21 = GPIO_MODE_MGMT_STD_OUTPUT; + reg_mprj_io_20 = GPIO_MODE_MGMT_STD_OUTPUT; + reg_mprj_io_19 = GPIO_MODE_MGMT_STD_OUTPUT; + reg_mprj_io_18 = GPIO_MODE_MGMT_STD_OUTPUT; + reg_mprj_io_17 = GPIO_MODE_MGMT_STD_OUTPUT; + reg_mprj_io_16 = GPIO_MODE_MGMT_STD_OUTPUT; + reg_mprj_io_15 = GPIO_MODE_MGMT_STD_OUTPUT; + reg_mprj_io_14 = GPIO_MODE_MGMT_STD_OUTPUT; + reg_mprj_io_13 = GPIO_MODE_MGMT_STD_OUTPUT; + reg_mprj_io_12 = GPIO_MODE_MGMT_STD_OUTPUT; + reg_mprj_io_11 = GPIO_MODE_MGMT_STD_OUTPUT; + reg_mprj_io_10 = GPIO_MODE_MGMT_STD_OUTPUT; + reg_mprj_io_9 = GPIO_MODE_MGMT_STD_OUTPUT; + reg_mprj_io_8 = GPIO_MODE_MGMT_STD_OUTPUT; + reg_mprj_io_7 = GPIO_MODE_MGMT_STD_OUTPUT; + reg_mprj_io_6 = GPIO_MODE_MGMT_STD_OUTPUT; + reg_mprj_io_5 = GPIO_MODE_MGMT_STD_OUTPUT; + reg_mprj_io_4 = GPIO_MODE_MGMT_STD_OUTPUT; + reg_mprj_io_3 = GPIO_MODE_MGMT_STD_OUTPUT; + reg_mprj_io_2 = GPIO_MODE_MGMT_STD_OUTPUT; + reg_mprj_io_1 = GPIO_MODE_MGMT_STD_OUTPUT; + reg_mprj_io_0 = GPIO_MODE_MGMT_STD_OUTPUT; + reg_mprj_io_0 = GPIO_MODE_MGMT_STD_OUTPUT; + + reg_mprj_xfer = 1; + while (reg_mprj_xfer == 1); + + reg_debug_1 = 0xAA; // finish configuration + reg_mprj_datal = 0x0; + reg_mprj_datah = 0x0; + i = 0x20; + for (j = 0; j < 5; j++) { + reg_mprj_datah = i; + reg_debug_2 = 37-j; + reg_mprj_datah = 0x00000000; + reg_debug_2 = 0; + i >>=1; + i |= 0x20; + } + i = 0x80000000; + for (j = 0; j < 32; j++) { + reg_mprj_datah = 0x3f; + reg_mprj_datal = i; + reg_debug_2 = 32-j; + reg_mprj_datah = 0x00; + reg_mprj_datal = 0x00000000; + reg_debug_2 = 0; + i >>=1; + i |= 0x80000000; + } + + + reg_debug_1 = 0XFF; // configuration done wait environment to send 0xFFA88C5A to reg_mprj_datal +} + diff --git a/verilog/dv/cocotb/tests/gpio_caravan/gpio_caravan.py b/verilog/dv/cocotb/tests/gpio_caravan/gpio_caravan.py new file mode 100644 index 00000000..554cd400 --- /dev/null +++ b/verilog/dv/cocotb/tests/gpio_caravan/gpio_caravan.py @@ -0,0 +1,500 @@ +import random +import cocotb +from cocotb.triggers import FallingEdge,RisingEdge,ClockCycles +import cocotb.log +from interfaces.cpu import RiskV +from interfaces.defsParser import Regs +from cocotb.result import TestSuccess +from tests.common_functions.test_functions import * +from tests.bitbang.bitbang_functions import * +from interfaces.caravel import GPIO_MODE +from interfaces.common import Macros +from cocotb.binary import BinaryValue + +reg = Regs() + +@cocotb.test() +@repot_test +async def gpio_all_o_caravan(dut): + caravelEnv,clock = await test_configure(dut,timeout_cycles=586652) + cpu = RiskV(dut) + cpu.cpu_force_reset() + cpu.cpu_release_reset() + + await wait_reg1(cpu,caravelEnv,0xAA) + await caravelEnv.release_csb() + cocotb.log.info("[TEST] finish configuring ") + i= 0x20 + for j in range(5): + await wait_reg2(cpu,caravelEnv,37-j) + cocotb.log.info(f'[Test] gpio out = {caravelEnv.monitor_gpio((37,0))} j = {j}') + expected_data = bin(i<<32)[2:].zfill(38)[:13] +"zzzzzzzzzzz" + bin(i<<32)[2:].zfill(38)[24:] + if caravelEnv.monitor_gpio((37,0)).binstr != expected_data: + cocotb.log.error(f'[TEST] Wrong gpio high bits output {caravelEnv.monitor_gpio((37,0))} instead of {expected_data}') + await wait_reg2(cpu,caravelEnv,0) + expected_data = bin(0)[2:].zfill(38)[:13] +"zzzzzzzzzzz" + bin(0)[2:].zfill(38)[24:] + if caravelEnv.monitor_gpio((37,0)).binstr != expected_data: + cocotb.log.error(f'[TEST] Wrong gpio output {caravelEnv.monitor_gpio((37,0))} instead of {expected_data}') + i = i >> 1 + i |= 0x20 + + i= 0x80000000 + for j in range(32): + await wait_reg2(cpu,caravelEnv,32-j) + cocotb.log.info(f'[Test] gpio out = {caravelEnv.monitor_gpio((37,0))} j = {j}') + if caravelEnv.monitor_gpio((37,32)).integer != 0x3f: + cocotb.log.error(f'[TEST] Wrong gpio high bits output {caravelEnv.monitor_gpio((37,32))} instead of {bin(0x3f)} ') + expected_data = bin(i)[2:].zfill(32)[:7] +"zzzzzzzzzzz" + bin(i)[2:].zfill(32)[18:] + if caravelEnv.monitor_gpio((31,0)).binstr != expected_data : + cocotb.log.error(f'[TEST] Wrong gpio low bits output {caravelEnv.monitor_gpio((31,0))} instead of {expected_data}') + await wait_reg2(cpu,caravelEnv,0) + expected_data = bin(0)[2:].zfill(38)[:13] +"zzzzzzzzzzz" + bin(0)[2:].zfill(38)[24:] + if caravelEnv.monitor_gpio((37,0)).binstr != expected_data: + cocotb.log.error(f'Wrong gpio output {caravelEnv.monitor_gpio((37,0))} instead of {expected_data}') + + i = i >> 1 + i |= 0x80000000 + + + await wait_reg1(cpu,caravelEnv,0XFF) + await ClockCycles(caravelEnv.clk, 10) + +@cocotb.test() +@repot_test +async def gpio_all_i_caravan(dut): + caravelEnv,clock = await test_configure(dut,timeout_cycles=56837) + cpu = RiskV(dut) + cpu.cpu_force_reset() + cpu.cpu_release_reset() + await wait_reg1(cpu,caravelEnv,0xAA) + cocotb.log.info(f"[TEST] configuration finished") + data_in = 0xFFFFFFFF + cocotb.log.info(f"[TEST] drive {hex(data_in)} to gpio[31:0]") + caravelEnv.drive_gpio_in((31,0),data_in) + await wait_reg1(cpu,caravelEnv,0xBB) + mask = 0xfe003fff + data_expected = data_in & mask + if cpu.read_debug_reg2() == data_expected: + cocotb.log.info(f"[TEST] data {bin(data_in)} sent successfully through gpio[31:0] and seen as {bin(data_expected)}") + else: + cocotb.log.error(f"[TEST] Error: reg_mprj_datal has recieved wrong data {bin(cpu.read_debug_reg2())} instead of {bin(data_expected)}") + data_in = 0xAAAAAAAA + cocotb.log.info(f"[TEST] drive {hex(data_in)} to gpio[31:0]") + caravelEnv.drive_gpio_in((31,0),data_in) + await wait_reg1(cpu,caravelEnv,0xCC) + data_expected = data_in & mask + if cpu.read_debug_reg2() == data_expected: + cocotb.log.info(f"[TEST] data {bin(data_in)} sent successfully through gpio[31:0] and seen as {bin(data_expected)}") + else: + cocotb.log.error(f"[TEST] Error: reg_mprj_datal has recieved wrong data {bin(cpu.read_debug_reg2())} instead of {bin(data_expected)}") + data_in = 0x55555555 + cocotb.log.info(f"[TEST] drive {hex(data_in)} to gpio[31:0]") + caravelEnv.drive_gpio_in((31,0),data_in) + await wait_reg1(cpu,caravelEnv,0xDD) + data_expected = data_in & mask + if cpu.read_debug_reg2() == data_expected: + cocotb.log.info(f"[TEST] data {bin(data_in)} sent successfully through gpio[31:0] and seen as {bin(data_expected)}") + else: + cocotb.log.error(f"[TEST] Error: reg_mprj_datal has recieved wrong data {bin(cpu.read_debug_reg2())} instead of {bin(data_expected)}") + data_in = 0x0 + cocotb.log.info(f"[TEST] drive {hex(data_in)} to gpio[31:0]") + caravelEnv.drive_gpio_in((31,0),data_in) + await wait_reg1(cpu,caravelEnv,0xD1) + data_expected = data_in & mask + if cpu.read_debug_reg2() == data_expected: + cocotb.log.info(f"[TEST] data {bin(data_in)} sent successfully through gpio[31:0] and seen as {bin(data_expected)}") + else: + cocotb.log.error(f"[TEST] Error: reg_mprj_datal has recieved wrong data {bin(cpu.read_debug_reg2())} instead of {bin(data_expected)}") + data_in = 0x3F + cocotb.log.info(f"[TEST] drive {hex(data_in)} to gpio[37:32]") + caravelEnv.drive_gpio_in((37,32),data_in) + await wait_reg1(cpu,caravelEnv,0xD2) + if cpu.read_debug_reg2() == data_in: + cocotb.log.info(f"[TEST] data {hex(data_in)} sent successfully through gpio[37:32]") + else: + cocotb.log.error(f"[TEST] Error: reg_mprj_datah has recieved wrong data {cpu.read_debug_reg2()} instead of {data_in}") + data_in = 0x0 + cocotb.log.info(f"[TEST] drive {hex(data_in)} to gpio[37:32]") + caravelEnv.drive_gpio_in((37,32),data_in) + await wait_reg1(cpu,caravelEnv,0xD3) + if cpu.read_debug_reg2() == data_in: + cocotb.log.info(f"[TEST] data {hex(data_in)} sent successfully through gpio[37:32]") + else: + cocotb.log.error(f"[TEST] Error: reg_mprj_datah has recieved wrong data {cpu.read_debug_reg2()} instead of {data_in}") + data_in = 0x15 + cocotb.log.info(f"[TEST] drive {hex(data_in)} to gpio[37:32]") + caravelEnv.drive_gpio_in((37,32),data_in) + await wait_reg1(cpu,caravelEnv,0xD4) + if cpu.read_debug_reg2() == data_in: + cocotb.log.info(f"[TEST] data {hex(data_in)} sent successfully through gpio[37:32]") + else: + cocotb.log.error(f"[TEST] Error: reg_mprj_datah has recieved wrong data {cpu.read_debug_reg2()} instead of {data_in}") + data_in = 0x2A + cocotb.log.info(f"[TEST] drive {hex(data_in)} to gpio[37:32]") + caravelEnv.drive_gpio_in((37,32),data_in) + await wait_reg1(cpu,caravelEnv,0XD5) + if cpu.read_debug_reg2() == data_in: + cocotb.log.info(f"[TEST] data {hex(data_in)} sent successfully through gpio[37:32]") + else: + cocotb.log.error(f"[TEST] Error: reg_mprj_datah has recieved wrong data {cpu.read_debug_reg2()} instead of {data_in}") + caravelEnv.release_gpio((37,0)) + await wait_reg2(cpu,caravelEnv,0XFF) + if caravelEnv.monitor_gpio((37,0)).binstr != "zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz": + cocotb.log.error(f"[TEST] ERROR: firmware can write to the gpios while they are configured as input_nopull gpio= {caravelEnv.monitor_gpio((37,0))}") + else: + cocotb.log.info(f"[TEST] [TEST] PASS: firmware cannot write to the gpios while they are configured as input_nopull gpio= {caravelEnv.monitor_gpio((37,0))}") + cocotb.log.info(f"[TEST] finish") + + +@cocotb.test() +@repot_test +async def gpio_all_i_pu_caravan(dut): + caravelEnv,clock = await test_configure(dut,timeout_cycles=58961,num_error=2000) + cpu = RiskV(dut) + cpu.cpu_force_reset() + cpu.cpu_release_reset() + uut = dut.uut + + await wait_reg1(cpu,caravelEnv,0xAA) + await caravelEnv.release_csb() + # monitor the output of padframe module it suppose to be all ones when no input is applied + await ClockCycles(caravelEnv.clk,100) + gpio = dut.uut.mprj_io.value.binstr[::-1] + for i in range(38): + if i in range(14,25,1): + if gpio[i] != "z": + cocotb.log.error(f"[TEST] gpio[{i}] is having wrong value {gpio[i]} instead of z while configured as input pullup and float and {i} gpio must be z in caravan") + continue + if gpio[i] != "1": + cocotb.log.error(f"[TEST] gpio[{i}] is having wrong value {gpio[i]} instead of 1 while configured as input pullup and float") + await ClockCycles(caravelEnv.clk,1000) + # drive gpios with zero + data_in = 0x0 + caravelEnv.drive_gpio_in((37,0),data_in) + await ClockCycles(caravelEnv.clk,1000) + gpio = dut.uut.mprj_io.value.binstr[::-1] + for i in range(38): + if gpio[i] != "0": + cocotb.log.error(f"[TEST] gpio[{i}] is having wrong value {gpio[i]} instead of 0 while configured as input pullup and drived with 0") + await ClockCycles(caravelEnv.clk,1000) + # drive gpios with ones + data_in = 0x3FFFFFFFFF + caravelEnv.drive_gpio_in((37,0),data_in) + await ClockCycles(caravelEnv.clk,1000) + gpio = dut.uut.mprj_io.value.binstr[::-1] + for i in range(38): + if gpio[i] != "1": + cocotb.log.error(f"[TEST] gpio[{i}] is having wrong value {gpio[i]} instead of 1 while configured as input pullup and drived with 1") + await ClockCycles(caravelEnv.clk,1000) + # drive odd half gpios with zeros and float other half + data_in = 0x0 + caravelEnv.drive_gpio_in((37,0),data_in) + for i in range(0,38,2): + caravelEnv.release_gpio(i) # release even gpios + await ClockCycles(caravelEnv.clk,1000) + gpio = dut.uut.mprj_io.value.binstr[::-1] + for i in range(38): + + if i%2 ==0: #even + if i in range(14,25,1): + if gpio[i] != "z": + cocotb.log.error(f"[TEST] gpio[{i}] is having wrong value {gpio[i]} instead of z while configured as input pullup and drived with odd half with 0 and {i} gpio must be z in caravan") + continue + if gpio[i]!="1": + cocotb.log.error(f"[TEST] gpio[{i}] is having wrong value {gpio[i]} instead of 1 while configured as input pullup and drived with odd half with 0") + else: + if gpio[i] != "0": + cocotb.log.error(f"[TEST] gpio[{i}] is having wrong value {gpio[i]} instead of 0 while configured as input pullup and drived with odd half with 0") + await ClockCycles(caravelEnv.clk,1000) + # drive even half gpios with zeros and float other half + caravelEnv.drive_gpio_in((37,0),data_in) + for i in range(1,38,2): + caravelEnv.release_gpio(i) # release odd gpios + await ClockCycles(caravelEnv.clk,1000) + gpio = dut.uut.mprj_io.value.binstr[::-1] + for i in range(38): + if i%2 ==0: #odd + if gpio[i] != "0": + cocotb.log.error(f"[TEST] gpio[{i}] is having wrong value {gpio[i]} instead of 0 while configured as input pullup and drived with even half with 0") + else: + if i in range(14,25,1): + if gpio[i] != "z": + cocotb.log.error(f"[TEST] gpio[{i}] is having wrong value {gpio[i]} instead of z while configured as input pullup and drived with even half with 0 and {i} gpio must be z in caravan") + continue + if gpio[i]!="1": + cocotb.log.error(f"[TEST] gpio[{i}] is having wrong value {gpio[i]} instead of 1 while configured as input pullup and drived with even half with 0") + await ClockCycles(caravelEnv.clk,1000) + # drive odd half gpios with ones and float other half + data_in = 0x3FFFFFFFFF + caravelEnv.drive_gpio_in((37,0),data_in) + for i in range(0,38,2): + caravelEnv.release_gpio(i) # release even gpios + await ClockCycles(caravelEnv.clk,1000) + gpio = dut.uut.mprj_io.value.binstr[::-1] + for i in range(38): + if i in range(14,25,1) and i%2==0: + if gpio[i] != "z": + cocotb.log.error(f"[TEST] gpio[{i}] is having wrong value {gpio[i]} instead of z while configured as input pullup and drived with odd half with 1 and {i} gpio must be z in caravan") + continue + if gpio[i]!="1": + cocotb.log.error(f"[TEST] gpio[{i}] is having wrong value {gpio[i]} instead of 1 while configured as input pullup and drived with odd half with 1") + + await ClockCycles(caravelEnv.clk,1000) + # drive even half gpios with zeros and float other half + caravelEnv.drive_gpio_in((37,0),data_in) + for i in range(1,38,2): + caravelEnv.release_gpio(i) # release odd gpios + await ClockCycles(caravelEnv.clk,1000) + gpio = dut.uut.mprj_io.value.binstr[::-1] + for i in range(38): + if i in range(14,25,1) and i%2==1: + if gpio[i] != "z": + cocotb.log.error(f"[TEST] gpio[{i}] is having wrong value {gpio[i]} instead of z while configured as input pullup and drived with even half with 1 and {i} gpio must be z in caravan") + continue + if gpio[i] != "1": + cocotb.log.error(f"[TEST] gpio[{i}] is having wrong value {gpio[i]} instead of 1 while configured as input pullup and drived with even half with 1") + + await ClockCycles(caravelEnv.clk,1000) + + # drive with zeros then release all gpio + data_in = 0x0 + caravelEnv.drive_gpio_in((37,0),data_in) + await ClockCycles(caravelEnv.clk,1000) + caravelEnv.release_gpio((37,0)) + await ClockCycles(caravelEnv.clk,1000) + gpio = dut.uut.mprj_io.value.binstr[::-1] + for i in range(38): + if i in range(14,25,1): + if gpio[i] != "z": + cocotb.log.error(f"[TEST] gpio[{i}] is having wrong value {gpio[i]} instead of z while configured as input pullup and all released and {i} gpio must be z in caravan") + continue + if gpio[i] != "1": + cocotb.log.error(f"[TEST] gpio[{i}] is having wrong value {gpio[i]} instead of 1 while configured as input pullup and all released") + await ClockCycles(caravelEnv.clk,1000) + + +@cocotb.test() +@repot_test +async def gpio_all_i_pd_caravan(dut): + caravelEnv,clock = await test_configure(dut,timeout_cycles=58961,num_error=2000) + cpu = RiskV(dut) + cpu.cpu_force_reset() + cpu.cpu_release_reset() + uut = dut.uut + + await wait_reg1(cpu,caravelEnv,0xAA) + await caravelEnv.release_csb() + # monitor the output of padframe module it suppose to be all ones when no input is applied + await ClockCycles(caravelEnv.clk,100) + gpio = dut.uut.mprj_io.value.binstr[::-1] + for i in range(38): + if i in range(14,25,1): + if gpio[i] != "z": + cocotb.log.error(f"[TEST] gpio[{i}] is having wrong value {gpio[i]} instead of z while configured as input pulldown and float and {i} gpio must be z in caravan") + continue + if gpio[i] != "0": + cocotb.log.error(f"[TEST] gpio[{i}] is having wrong value {gpio[i]} instead of 0 while configured as input pulldown and float") + await ClockCycles(caravelEnv.clk,1000) + # drive gpios with zero + data_in = 0x0 + caravelEnv.drive_gpio_in((37,0),data_in) + await ClockCycles(caravelEnv.clk,1000) + gpio = dut.uut.mprj_io.value.binstr[::-1] + for i in range(38): + if gpio[i] != "0": + cocotb.log.error(f"[TEST] gpio[{i}] is having wrong value {gpio[i]} instead of 0 while configured as input pulldown and drived with 0") + await ClockCycles(caravelEnv.clk,1000) + # drive gpios with ones + data_in = 0x3FFFFFFFFF + caravelEnv.drive_gpio_in((37,0),data_in) + await ClockCycles(caravelEnv.clk,1000) + gpio = dut.uut.mprj_io.value.binstr[::-1] + for i in range(38): + if gpio[i] != "1": + cocotb.log.error(f"[TEST] gpio[{i}] is having wrong value {gpio[i]} instead of 1 while configured as input pulldown and drived with 1") + await ClockCycles(caravelEnv.clk,1000) + # drive odd half gpios with zeros and float other half + data_in = 0x0 + caravelEnv.drive_gpio_in((37,0),data_in) + for i in range(0,38,2): + caravelEnv.release_gpio(i) # release even gpios + await ClockCycles(caravelEnv.clk,1000) + gpio = dut.uut.mprj_io.value.binstr[::-1] + for i in range(38): + if i in range(14,25,1) and i%2==0: + if gpio[i] != "z": + cocotb.log.error(f"[TEST] gpio[{i}] is having wrong value {gpio[i]} instead of z while configured as input pulldown and drived with odd half with 0 and {i} gpio must be z in caravan") + continue + if gpio[i]!="0": + cocotb.log.error(f"[TEST] gpio[{i}] is having wrong value {gpio[i]} instead of 0 while configured as input pulldown and drived with odd half with 0") + + await ClockCycles(caravelEnv.clk,1000) + # drive even half gpios with zeros and float other half + caravelEnv.drive_gpio_in((37,0),data_in) + for i in range(1,38,2): + caravelEnv.release_gpio(i) # release odd gpios + await ClockCycles(caravelEnv.clk,1000) + gpio = dut.uut.mprj_io.value.binstr[::-1] + for i in range(38): + if i in range(14,25,1) and i%2==1: + if gpio[i] != "z": + cocotb.log.error(f"[TEST] gpio[{i}] is having wrong value {gpio[i]} instead of z while configured as input pulldown and drived with even half with 0 and {i} gpio must be z in caravan") + continue + if gpio[i]!="0": + cocotb.log.error(f"[TEST] gpio[{i}] is having wrong value {gpio[i]} instead of 0 while configured as input pulldown and drived with even half with 0") + await ClockCycles(caravelEnv.clk,1000) + # drive odd half gpios with ones and float other half + data_in = 0x3FFFFFFFFF + caravelEnv.drive_gpio_in((37,0),data_in) + for i in range(0,38,2): + caravelEnv.release_gpio(i) # release even gpios + await ClockCycles(caravelEnv.clk,1000) + gpio = dut.uut.mprj_io.value.binstr[::-1] + for i in range(38): + if i%2 ==1: #odd + if gpio[i]!="1": + cocotb.log.error(f"[TEST] gpio[{i}] is having wrong value {gpio[i]} instead of 1 while configured as input pulldown and drived with odd half with 1") + else: + if i in range(14,25,1): + if gpio[i] != "z": + cocotb.log.error(f"[TEST] gpio[{i}] is having wrong value {gpio[i]} instead of z while configured as input pulldown and drived with odd half with 1 and {i} gpio must be z in caravan") + continue + if gpio[i] != "0": + cocotb.log.error(f"[TEST] gpio[{i}] is having wrong value {gpio[i]} instead of 0 while configured as input pulldown and drived with odd half with 1") + + await ClockCycles(caravelEnv.clk,1000) + # drive even half gpios with zeros and float other half + caravelEnv.drive_gpio_in((37,0),data_in) + for i in range(1,38,2): + caravelEnv.release_gpio(i) # release odd gpios + await ClockCycles(caravelEnv.clk,1000) + gpio = dut.uut.mprj_io.value.binstr[::-1] + for i in range(38): + if i%2 ==0: #even + if gpio[i]!="1": + cocotb.log.error(f"[TEST] gpio[{i}] is having wrong value {gpio[i]} instead of 1 while configured as input pulldown and drived with odd half with 1") + else: + if i in range(14,25,1): + if gpio[i] != "z": + cocotb.log.error(f"[TEST] gpio[{i}] is having wrong value {gpio[i]} instead of z while configured as input pulldown and drived with odd half with 1 and {i} gpio must be z in caravan") + continue + if gpio[i] != "0": + cocotb.log.error(f"[TEST] gpio[{i}] is having wrong value {gpio[i]} instead of 0 while configured as input pulldown and drived with odd half with 1") + + await ClockCycles(caravelEnv.clk,1000) + + # drive with ones then release all gpio + data_in = 0x3FFFFFFFFF + caravelEnv.drive_gpio_in((37,0),data_in) + await ClockCycles(caravelEnv.clk,1000) + caravelEnv.release_gpio((37,0)) + await ClockCycles(caravelEnv.clk,1000) + gpio = dut.uut.mprj_io.value.binstr[::-1] + for i in range(38): + if i in range(14,25,1): + if gpio[i] != "z": + cocotb.log.error(f"[TEST] gpio[{i}] is having wrong value {gpio[i]} instead of z while while configured as input pulldown and all released and {i} gpio must be z in caravan") + continue + if gpio[i] != "0": + cocotb.log.error(f"[TEST] gpio[{i}] is having wrong value {gpio[i]} instead of 0 while configured as input pulldown and all released") + await ClockCycles(caravelEnv.clk,1000) + +@cocotb.test() +@repot_test +async def gpio_all_bidir(dut): + caravelEnv,clock = await test_configure(dut,timeout_cycles=1144980) + cpu = RiskV(dut) + cpu.cpu_force_reset() + cpu.cpu_release_reset() + uut = dut.uut + await wait_reg1(cpu,caravelEnv,0x1A) + await caravelEnv.release_csb() + cocotb.log.info("[TEST] finish configuring ") + i= 0x20 + for j in range(5): + await wait_reg2(cpu,caravelEnv,37-j) + cocotb.log.info(f'[Test] gpio out = {caravelEnv.monitor_gpio((37,0))} j = {j}') + if caravelEnv.monitor_gpio((37,0)).integer != i << 32: + cocotb.log.error(f'[TEST] Wrong gpio high bits output {caravelEnv.monitor_gpio((37,0))} instead of {bin(i << 32)}') + await wait_reg2(cpu,caravelEnv,0) + if caravelEnv.monitor_gpio((37,0)).integer != 0: + cocotb.log.error(f'[TEST] Wrong gpio output {caravelEnv.monitor_gpio((37,0))} instead of {bin(0x00000)}') + i = i >> 1 + i |= 0x20 + + i= 0x80000000 + for j in range(32): + await wait_reg2(cpu,caravelEnv,32-j) + cocotb.log.info(f'[Test] gpio out = {caravelEnv.monitor_gpio((37,0))} j = {j}') + if caravelEnv.monitor_gpio((37,32)).integer != 0x3f: + cocotb.log.error(f'[TEST] Wrong gpio high bits output {caravelEnv.monitor_gpio((37,32))} instead of {bin(0x3f)} ') + if caravelEnv.monitor_gpio((31,0)).integer != i : + cocotb.log.error(f'[TEST] Wrong gpio low bits output {caravelEnv.monitor_gpio((31,0))} instead of {bin(i)}') + await wait_reg2(cpu,caravelEnv,0) + if caravelEnv.monitor_gpio((37,0)).integer != 0: + cocotb.log.error(f'Wrong gpio output {caravelEnv.monitor_gpio((37,0))} instead of {bin(0x00000)}') + + i = i >> 1 + i |= 0x80000000 + + await wait_reg1(cpu,caravelEnv,0x2A) + cocotb.log.info(f"[TEST] configuration finished") + data_in = 0x8F66FD7B + cocotb.log.info(f"[TEST] drive {hex(data_in)} to gpio[31:0]") + caravelEnv.drive_gpio_in((31,0),data_in) + await wait_reg1(cpu,caravelEnv,0xBB) + if cpu.read_debug_reg2() == data_in: + cocotb.log.info(f"[TEST] data {hex(data_in)} sent successfully through gpio[31:0]") + else: + cocotb.log.error(f"[TEST] Error: reg_mprj_datal has recieved wrong data {cpu.read_debug_reg2()} instead of {data_in}") + data_in = 0xFFA88C5A + cocotb.log.info(f"[TEST] drive {hex(data_in)} to gpio[31:0]") + caravelEnv.drive_gpio_in((31,0),data_in) + await wait_reg1(cpu,caravelEnv,0xCC) + if cpu.read_debug_reg2() == data_in: + cocotb.log.info(f"[TEST] data {hex(data_in)} sent successfully through gpio[31:0]") + else: + cocotb.log.error(f"[TEST] Error: reg_mprj_datal has recieved wrong data {cpu.read_debug_reg2()} instead of {data_in}") + data_in = 0xC9536346 + cocotb.log.info(f"[TEST] drive {hex(data_in)} to gpio[31:0]") + caravelEnv.drive_gpio_in((31,0),data_in) + await wait_reg1(cpu,caravelEnv,0xD1) + if cpu.read_debug_reg2() == data_in: + cocotb.log.info(f"[TEST] data {hex(data_in)} sent successfully through gpio[31:0]") + else: + cocotb.log.error(f"[TEST] Error: reg_mprj_datal has recieved wrong data {cpu.read_debug_reg2()} instead of {data_in}") + data_in = 0xC9536346 + data_in = 0x3F + cocotb.log.info(f"[TEST] drive {hex(data_in)} to gpio[37:32]") + caravelEnv.drive_gpio_in((37,32),data_in) + await wait_reg1(cpu,caravelEnv,0xD2) + if cpu.read_debug_reg2() == data_in: + cocotb.log.info(f"[TEST] data {hex(data_in)} sent successfully through gpio[31:0]") + else: + cocotb.log.error(f"[TEST] Error: reg_mprj_datal has recieved wrong data {cpu.read_debug_reg2()} instead of {data_in}") + data_in = 0xC9536346 + data_in = 0x0 + cocotb.log.info(f"[TEST] drive {hex(data_in)} to gpio[37:32]") + caravelEnv.drive_gpio_in((37,32),data_in) + await wait_reg1(cpu,caravelEnv,0xD3) + if cpu.read_debug_reg2() == data_in: + cocotb.log.info(f"[TEST] data {hex(data_in)} sent successfully through gpio[31:0]") + else: + cocotb.log.error(f"[TEST] Error: reg_mprj_datal has recieved wrong data {cpu.read_debug_reg2()} instead of {data_in}") + data_in = 0xC9536346 + data_in = 0x15 + cocotb.log.info(f"[TEST] drive {hex(data_in)} to gpio[37:32]") + caravelEnv.drive_gpio_in((37,32),data_in) + await wait_reg1(cpu,caravelEnv,0xD4) + if cpu.read_debug_reg2() == data_in: + cocotb.log.info(f"[TEST] data {hex(data_in)} sent successfully through gpio[31:0]") + else: + cocotb.log.error(f"[TEST] Error: reg_mprj_datal has recieved wrong data {cpu.read_debug_reg2()} instead of {data_in}") + data_in = 0xC9536346 + data_in = 0x2A + cocotb.log.info(f"[TEST] drive {hex(data_in)} to gpio[37:32]") + caravelEnv.drive_gpio_in((37,32),data_in) + await wait_reg2(cpu,caravelEnv,0xFF) + cocotb.log.info(f"[TEST] finish") + + await ClockCycles(caravelEnv.clk, 10) diff --git a/verilog/dv/cocotb/tests/gpio_caravan/gpio_user.py b/verilog/dv/cocotb/tests/gpio_caravan/gpio_user.py new file mode 100644 index 00000000..9b7ccee7 --- /dev/null +++ b/verilog/dv/cocotb/tests/gpio_caravan/gpio_user.py @@ -0,0 +1,468 @@ +import random +import cocotb +from cocotb.triggers import FallingEdge,RisingEdge,ClockCycles +import cocotb.log +from interfaces.cpu import RiskV +from interfaces.defsParser import Regs +from cocotb.result import TestSuccess +from tests.common_functions.test_functions import * +from tests.bitbang.bitbang_functions import * +from interfaces.caravel import GPIO_MODE +from cocotb.binary import BinaryValue + +reg = Regs() + +@cocotb.test() +@repot_test +async def gpio_all_o_user(dut): + caravelEnv,clock = await test_configure(dut,timeout_cycles=542674) + cpu = RiskV(dut) + cpu.cpu_force_reset() + cpu.cpu_release_reset() + + await wait_reg1(cpu,caravelEnv,0xAA) + await caravelEnv.release_csb() + cocotb.log.info("[TEST] finish configuring as user output") + i= 0x20 + for j in range(5): + await wait_reg2(cpu,caravelEnv,37-j) + cocotb.log.info(f'[Test] gpio out = {caravelEnv.monitor_gpio((37,0))} j = {j}') + if caravelEnv.monitor_gpio((37,0)).integer != i<<32: + cocotb.log.error(f'[TEST] Wrong gpio high bits output {caravelEnv.monitor_gpio((37,0))} instead of {bin(i<<32)}') + await wait_reg2(cpu,caravelEnv,0) + if caravelEnv.monitor_gpio((37,0)).integer != 0: + cocotb.log.error(f'[TEST] Wrong gpio output {caravelEnv.monitor_gpio((37,0))} instead of {bin(0x00000)}') + i = i >> 1 + i |= 0x20 + + i= 0x80000000 + for j in range(32): + await wait_reg2(cpu,caravelEnv,32-j) + cocotb.log.info(f'[Test] gpio out = {caravelEnv.monitor_gpio((37,0))} j = {j}') + if caravelEnv.monitor_gpio((37,32)).integer != 0x3f: + cocotb.log.error(f'[TEST] Wrong gpio high bits output {caravelEnv.monitor_gpio((37,32))} instead of {bin(0x3f)} ') + if caravelEnv.monitor_gpio((31,0)).integer != i : + cocotb.log.error(f'[TEST] Wrong gpio low bits output {caravelEnv.monitor_gpio((31,0))} instead of {bin(i)}') + await wait_reg2(cpu,caravelEnv,0) + if caravelEnv.monitor_gpio((37,0)).integer != 0: + cocotb.log.error(f'Wrong gpio output {caravelEnv.monitor_gpio((37,0))} instead of {bin(0x00000)}') + + i = i >> 1 + i |= 0x80000000 + + await wait_reg1(cpu,caravelEnv,0XBB) + data_in = 0x8F66FD7B + cocotb.log.info(f"[TEST] try send {hex(data_in)} to gpio[31:0]") + caravelEnv.drive_gpio_in((31,0),data_in) + reg2 =0 + await wait_reg1(cpu,caravelEnv,0XFF) + try: + reg2 =cpu.read_debug_reg2() + if reg2 == data_in: + cocotb.log.error(f"[TEST] Error: data {hex(data_in)} driven on gpio[31:0] is seen by firmware while gpios are configured as output") + else: + cocotb.log.info(f"[TEST] driven data {hex(data_in)} sent can't be sent to gpio[31:0] when it configure as output it can see {reg2}") + except Exception as e: + cocotb.log.info(f"[TEST] driven data {hex(data_in)} sent can't be sent to gpio[31:0] when it configure as output") + return + + + await ClockCycles(caravelEnv.clk, 10) + + +@cocotb.test() +@repot_test +async def gpio_all_i_user(dut): + caravelEnv,clock = await test_configure(dut,timeout_cycles=56694) + cpu = RiskV(dut) + cpu.cpu_force_reset() + cpu.cpu_release_reset() + await wait_reg1(cpu,caravelEnv,0xAA) + cocotb.log.info(f"[TEST] configuration finished") + data_in = 0xFFFFFFFF + cocotb.log.info(f"[TEST] drive {hex(data_in)} to gpio[31:0]") + caravelEnv.drive_gpio_in((31,0),data_in) + await wait_reg1(cpu,caravelEnv,0xBB) + if cpu.read_debug_reg2() == data_in: + cocotb.log.info(f"[TEST] data {hex(data_in)} sent successfully through gpio[31:0]") + else: + cocotb.log.error(f"[TEST] Error: reg_mprj_datal has recieved wrong data {cpu.read_debug_reg2()} instead of {data_in}") + data_in = 0xAAAAAAAA + cocotb.log.info(f"[TEST] drive {hex(data_in)} to gpio[31:0]") + caravelEnv.drive_gpio_in((31,0),data_in) + await wait_reg1(cpu,caravelEnv,0xCC) + if cpu.read_debug_reg2() == data_in: + cocotb.log.info(f"[TEST] data {hex(data_in)} sent successfully through gpio[31:0]") + else: + cocotb.log.error(f"[TEST] Error: reg_mprj_datal has recieved wrong data {cpu.read_debug_reg2()} instead of {data_in}") + data_in = 0x55555555 + cocotb.log.info(f"[TEST] drive {hex(data_in)} to gpio[31:0]") + caravelEnv.drive_gpio_in((31,0),data_in) + await wait_reg1(cpu,caravelEnv,0xDD) + if cpu.read_debug_reg2() == data_in: + cocotb.log.info(f"[TEST] data {hex(data_in)} sent successfully through gpio[31:0]") + else: + cocotb.log.error(f"[TEST] Error: reg_mprj_datal has recieved wrong data {cpu.read_debug_reg2()} instead of {data_in}") + data_in = 0x0 + cocotb.log.info(f"[TEST] drive {hex(data_in)} to gpio[31:0]") + caravelEnv.drive_gpio_in((31,0),data_in) + await wait_reg1(cpu,caravelEnv,0xD1) + if cpu.read_debug_reg2() == data_in: + cocotb.log.info(f"[TEST] data {hex(data_in)} sent successfully through gpio[31:0]") + else: + cocotb.log.error(f"[TEST] Error: reg_mprj_datal has recieved wrong data {cpu.read_debug_reg2()} instead of {data_in}") + data_in = 0x3F + cocotb.log.info(f"[TEST] drive {hex(data_in)} to gpio[37:32]") + caravelEnv.drive_gpio_in((37,32),data_in) + await wait_reg1(cpu,caravelEnv,0xD2) + if cpu.read_debug_reg2() == data_in: + cocotb.log.info(f"[TEST] data {hex(data_in)} sent successfully through gpio[37:32]") + else: + cocotb.log.error(f"[TEST] Error: reg_mprj_datah has recieved wrong data {cpu.read_debug_reg2()} instead of {data_in}") + data_in = 0x0 + cocotb.log.info(f"[TEST] drive {hex(data_in)} to gpio[37:32]") + caravelEnv.drive_gpio_in((37,32),data_in) + await wait_reg1(cpu,caravelEnv,0xD3) + if cpu.read_debug_reg2() == data_in: + cocotb.log.info(f"[TEST] data {hex(data_in)} sent successfully through gpio[37:32]") + else: + cocotb.log.error(f"[TEST] Error: reg_mprj_datah has recieved wrong data {cpu.read_debug_reg2()} instead of {data_in}") + data_in = 0x15 + cocotb.log.info(f"[TEST] drive {hex(data_in)} to gpio[37:32]") + caravelEnv.drive_gpio_in((37,32),data_in) + await wait_reg1(cpu,caravelEnv,0xD4) + if cpu.read_debug_reg2() == data_in: + cocotb.log.info(f"[TEST] data {hex(data_in)} sent successfully through gpio[37:32]") + else: + cocotb.log.error(f"[TEST] Error: reg_mprj_datah has recieved wrong data {cpu.read_debug_reg2()} instead of {data_in}") + data_in = 0x2A + cocotb.log.info(f"[TEST] drive {hex(data_in)} to gpio[37:32]") + caravelEnv.drive_gpio_in((37,32),data_in) + await wait_reg1(cpu,caravelEnv,0XD5) + if cpu.read_debug_reg2() == data_in: + cocotb.log.info(f"[TEST] data {hex(data_in)} sent successfully through gpio[37:32]") + else: + cocotb.log.error(f"[TEST] Error: reg_mprj_datah has recieved wrong data {cpu.read_debug_reg2()} instead of {data_in}") + caravelEnv.release_gpio((37,0)) + await wait_reg2(cpu,caravelEnv,0XFF) + if caravelEnv.monitor_gpio((37,0)).binstr != "zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz": + cocotb.log.error(f"[TEST] ERROR: firmware can write to the gpios while they are configured as input_nopull gpio= {caravelEnv.monitor_gpio((37,0))}") + else: + cocotb.log.info(f"[TEST] [TEST] PASS: firmware cannot write to the gpios while they are configured as input_nopull gpio= {caravelEnv.monitor_gpio((37,0))}") + cocotb.log.info(f"[TEST] finish") + + +@cocotb.test() +@repot_test +async def gpio_all_i_pu_user(dut): + caravelEnv,clock = await test_configure(dut,timeout_cycles=58961,num_error=2000) + cpu = RiskV(dut) + cpu.cpu_force_reset() + cpu.cpu_release_reset() + uut = dut.uut + + await wait_reg1(cpu,caravelEnv,0xAA) + await caravelEnv.release_csb() + # monitor the output of padframe module it suppose to be all ones when no input is applied + await ClockCycles(caravelEnv.clk,100) + gpio = dut.uut.padframe.mprj_io_in.value.binstr + for i in range(38): + if gpio[i] != "1": + cocotb.log.error(f"[TEST] gpio[{i}] is having wrong value {gpio[i]} instead of 1 while configured as input pullup and float") + await ClockCycles(caravelEnv.clk,1000) + # drive gpios with zero + data_in = 0x0 + caravelEnv.drive_gpio_in((37,0),data_in) + await ClockCycles(caravelEnv.clk,1000) + gpio = dut.uut.padframe.mprj_io_in.value.binstr + for i in range(38): + if gpio[i] != "0": + cocotb.log.error(f"[TEST] gpio[{i}] is having wrong value {gpio[i]} instead of 0 while configured as input pullup and drived with 0") + await ClockCycles(caravelEnv.clk,1000) + # drive gpios with ones + data_in = 0x3FFFFFFFFF + caravelEnv.drive_gpio_in((37,0),data_in) + await ClockCycles(caravelEnv.clk,1000) + gpio = dut.uut.padframe.mprj_io_in.value.binstr + for i in range(38): + if gpio[i] != "1": + cocotb.log.error(f"[TEST] gpio[{i}] is having wrong value {gpio[i]} instead of 1 while configured as input pullup and drived with 1") + await ClockCycles(caravelEnv.clk,1000) + # drive odd half gpios with zeros and float other half + data_in = 0x0 + caravelEnv.drive_gpio_in((37,0),data_in) + for i in range(0,38,2): + caravelEnv.release_gpio(i) # release even gpios + await ClockCycles(caravelEnv.clk,1000) + gpio = dut.uut.padframe.mprj_io_in.value.binstr + for i in range(38): + if i%2 ==1: #odd + if gpio[i]!="1": + cocotb.log.error(f"[TEST] gpio[{i}] is having wrong value {gpio[i]} instead of 1 while configured as input pullup and drived with odd half with 0") + else: + if gpio[i] != "0": + cocotb.log.error(f"[TEST] gpio[{i}] is having wrong value {gpio[i]} instead of 0 while configured as input pullup and drived with odd half with 0") + await ClockCycles(caravelEnv.clk,1000) + # drive even half gpios with zeros and float other half + caravelEnv.drive_gpio_in((37,0),data_in) + for i in range(1,38,2): + caravelEnv.release_gpio(i) # release odd gpios + await ClockCycles(caravelEnv.clk,1000) + gpio = dut.uut.padframe.mprj_io_in.value.binstr + for i in range(38): + if i%2 ==1: #odd + if gpio[i] != "0": + cocotb.log.error(f"[TEST] gpio[{i}] is having wrong value {gpio[i]} instead of 0 while configured as input pullup and drived with even half with 0") + else: + if gpio[i]!="1": + cocotb.log.error(f"[TEST] gpio[{i}] is having wrong value {gpio[i]} instead of 1 while configured as input pullup and drived with even half with 0") + await ClockCycles(caravelEnv.clk,1000) + # drive odd half gpios with ones and float other half + data_in = 0x3FFFFFFFFF + caravelEnv.drive_gpio_in((37,0),data_in) + for i in range(0,38,2): + caravelEnv.release_gpio(i) # release even gpios + await ClockCycles(caravelEnv.clk,1000) + gpio = dut.uut.padframe.mprj_io_in.value.binstr + for i in range(38): + if gpio[i]!="1": + cocotb.log.error(f"[TEST] gpio[{i}] is having wrong value {gpio[i]} instead of 1 while configured as input pullup and drived with odd half with 1") + + await ClockCycles(caravelEnv.clk,1000) + # drive even half gpios with zeros and float other half + caravelEnv.drive_gpio_in((37,0),data_in) + for i in range(1,38,2): + caravelEnv.release_gpio(i) # release odd gpios + await ClockCycles(caravelEnv.clk,1000) + gpio = dut.uut.padframe.mprj_io_in.value.binstr + for i in range(38): + if gpio[i] != "1": + cocotb.log.error(f"[TEST] gpio[{i}] is having wrong value {gpio[i]} instead of 1 while configured as input pullup and drived with even half with 1") + + await ClockCycles(caravelEnv.clk,1000) + + # drive with zeros then release all gpio + data_in = 0x0 + caravelEnv.drive_gpio_in((37,0),data_in) + await ClockCycles(caravelEnv.clk,1000) + caravelEnv.release_gpio((37,0)) + await ClockCycles(caravelEnv.clk,1000) + gpio = dut.uut.padframe.mprj_io_in.value.binstr + for i in range(38): + if gpio[i] != "1": + cocotb.log.error(f"[TEST] gpio[{i}] is having wrong value {gpio[i]} instead of 1 while configured as input pullup and all released") + await ClockCycles(caravelEnv.clk,1000) + + +@cocotb.test() +@repot_test +async def gpio_all_i_pd_user(dut): + caravelEnv,clock = await test_configure(dut,timeout_cycles=58961,num_error=2000) + cpu = RiskV(dut) + cpu.cpu_force_reset() + cpu.cpu_release_reset() + uut = dut.uut + + await wait_reg1(cpu,caravelEnv,0xAA) + await caravelEnv.release_csb() + # monitor the output of padframe module it suppose to be all ones when no input is applied + await ClockCycles(caravelEnv.clk,100) + gpio = dut.uut.padframe.mprj_io_in.value.binstr + for i in range(38): + if gpio[i] != "0": + cocotb.log.error(f"[TEST] gpio[{i}] is having wrong value {gpio[i]} instead of 0 while configured as input pulldown and float") + await ClockCycles(caravelEnv.clk,1000) + # drive gpios with zero + data_in = 0x0 + caravelEnv.drive_gpio_in((37,0),data_in) + await ClockCycles(caravelEnv.clk,1000) + gpio = dut.uut.padframe.mprj_io_in.value.binstr + for i in range(38): + if gpio[i] != "0": + cocotb.log.error(f"[TEST] gpio[{i}] is having wrong value {gpio[i]} instead of 0 while configured as input pulldown and drived with 0") + await ClockCycles(caravelEnv.clk,1000) + # drive gpios with ones + data_in = 0x3FFFFFFFFF + caravelEnv.drive_gpio_in((37,0),data_in) + await ClockCycles(caravelEnv.clk,1000) + gpio = dut.uut.padframe.mprj_io_in.value.binstr + for i in range(38): + if gpio[i] != "1": + cocotb.log.error(f"[TEST] gpio[{i}] is having wrong value {gpio[i]} instead of 1 while configured as input pulldown and drived with 1") + await ClockCycles(caravelEnv.clk,1000) + # drive odd half gpios with zeros and float other half + data_in = 0x0 + caravelEnv.drive_gpio_in((37,0),data_in) + for i in range(0,38,2): + caravelEnv.release_gpio(i) # release even gpios + await ClockCycles(caravelEnv.clk,1000) + gpio = dut.uut.padframe.mprj_io_in.value.binstr + for i in range(38): + if gpio[i]!="0": + cocotb.log.error(f"[TEST] gpio[{i}] is having wrong value {gpio[i]} instead of 0 while configured as input pulldown and drived with odd half with 0") + + await ClockCycles(caravelEnv.clk,1000) + # drive even half gpios with zeros and float other half + caravelEnv.drive_gpio_in((37,0),data_in) + for i in range(1,38,2): + caravelEnv.release_gpio(i) # release odd gpios + await ClockCycles(caravelEnv.clk,1000) + gpio = dut.uut.padframe.mprj_io_in.value.binstr + for i in range(38): + if gpio[i]!="0": + cocotb.log.error(f"[TEST] gpio[{i}] is having wrong value {gpio[i]} instead of 0 while configured as input pulldown and drived with even half with 0") + await ClockCycles(caravelEnv.clk,1000) + # drive odd half gpios with ones and float other half + data_in = 0x3FFFFFFFFF + caravelEnv.drive_gpio_in((37,0),data_in) + for i in range(0,38,2): + caravelEnv.release_gpio(i) # release even gpios + await ClockCycles(caravelEnv.clk,1000) + gpio = dut.uut.padframe.mprj_io_in.value.binstr + for i in range(38): + if i%2 ==0: #even + if gpio[i]!="1": + cocotb.log.error(f"[TEST] gpio[{i}] is having wrong value {gpio[i]} instead of 1 while configured as input pulldown and drived with odd half with 1") + else: + if gpio[i] != "0": + cocotb.log.error(f"[TEST] gpio[{i}] is having wrong value {gpio[i]} instead of 0 while configured as input pulldown and drived with odd half with 1") + + await ClockCycles(caravelEnv.clk,1000) + # drive even half gpios with zeros and float other half + caravelEnv.drive_gpio_in((37,0),data_in) + for i in range(1,38,2): + caravelEnv.release_gpio(i) # release odd gpios + await ClockCycles(caravelEnv.clk,1000) + gpio = dut.uut.padframe.mprj_io_in.value.binstr + for i in range(38): + if i%2 ==1: #odd + if gpio[i]!="1": + cocotb.log.error(f"[TEST] gpio[{i}] is having wrong value {gpio[i]} instead of 1 while configured as input pulldown and drived with odd half with 1") + else: + if gpio[i] != "0": + cocotb.log.error(f"[TEST] gpio[{i}] is having wrong value {gpio[i]} instead of 0 while configured as input pulldown and drived with odd half with 1") + + await ClockCycles(caravelEnv.clk,1000) + + # drive with ones then release all gpio + data_in = 0x3FFFFFFFFF + caravelEnv.drive_gpio_in((37,0),data_in) + await ClockCycles(caravelEnv.clk,1000) + caravelEnv.release_gpio((37,0)) + await ClockCycles(caravelEnv.clk,1000) + gpio = dut.uut.padframe.mprj_io_in.value.binstr + for i in range(38): + if gpio[i] != "0": + cocotb.log.error(f"[TEST] gpio[{i}] is having wrong value {gpio[i]} instead of 0 while configured as input pulldown and all released") + await ClockCycles(caravelEnv.clk,1000) + + + +@cocotb.test() +@repot_test +async def gpio_all_bidir_user(dut): + caravelEnv,clock = await test_configure(dut,timeout_cycles=290455) + cpu = RiskV(dut) + cpu.cpu_force_reset() + cpu.cpu_release_reset() + uut = dut.uut + await wait_reg1(cpu,caravelEnv,0x1A) + await caravelEnv.release_csb() + cocotb.log.info("[TEST] finish configuring ") + i= 0x20 + for j in range(5): + await wait_reg2(cpu,caravelEnv,37-j) + cocotb.log.info(f'[Test] gpio out = {caravelEnv.monitor_gpio((37,0))} j = {j}') + if caravelEnv.monitor_gpio((37,0)).integer != i << 32: + cocotb.log.error(f'[TEST] Wrong gpio high bits output {caravelEnv.monitor_gpio((37,0))} instead of {bin(i << 32)}') + await wait_reg2(cpu,caravelEnv,0) + if caravelEnv.monitor_gpio((37,0)).integer != 0: + cocotb.log.error(f'[TEST] Wrong gpio output {caravelEnv.monitor_gpio((37,0))} instead of {bin(0x00000)}') + i = i >> 1 + i |= 0x20 + + i= 0x80000000 + for j in range(32): + await wait_reg2(cpu,caravelEnv,32-j) + cocotb.log.info(f'[Test] gpio out = {caravelEnv.monitor_gpio((37,0))} j = {j}') + if caravelEnv.monitor_gpio((37,32)).integer != 0x3f: + cocotb.log.error(f'[TEST] Wrong gpio high bits output {caravelEnv.monitor_gpio((37,32))} instead of {bin(0x3f)} ') + if caravelEnv.monitor_gpio((31,0)).integer != i : + cocotb.log.error(f'[TEST] Wrong gpio low bits output {caravelEnv.monitor_gpio((31,0))} instead of {bin(i)}') + await wait_reg2(cpu,caravelEnv,0) + if caravelEnv.monitor_gpio((37,0)).integer != 0: + cocotb.log.error(f'Wrong gpio output {caravelEnv.monitor_gpio((37,0))} instead of {bin(0x00000)}') + + i = i >> 1 + i |= 0x80000000 + caravelEnv.release_gpio((37,0)) + await ClockCycles(caravelEnv.clk, 10) + caravelEnv.drive_gpio_in((31,0),0) + await ClockCycles(caravelEnv.clk, 10) + await wait_reg1(cpu,caravelEnv,0xAA) + cocotb.log.info(f"[TEST] configuration finished") + data_in = 0xFFFFFFFF + cocotb.log.info(f"[TEST] drive {hex(data_in)} to gpio[31:0]") + caravelEnv.drive_gpio_in((31,0),data_in) + await wait_reg1(cpu,caravelEnv,0xBB) + if cpu.read_debug_reg2() == data_in: + cocotb.log.info(f"[TEST] data {hex(data_in)} sent successfully through gpio[31:0]") + else: + cocotb.log.error(f"[TEST] Error: reg_mprj_datal has recieved wrong data {cpu.read_debug_reg2()} instead of {data_in}") + data_in = 0xAAAAAAAA + cocotb.log.info(f"[TEST] drive {hex(data_in)} to gpio[31:0]") + caravelEnv.drive_gpio_in((31,0),data_in) + await wait_reg1(cpu,caravelEnv,0xCC) + if cpu.read_debug_reg2() == data_in: + cocotb.log.info(f"[TEST] data {hex(data_in)} sent successfully through gpio[31:0]") + else: + cocotb.log.error(f"[TEST] Error: reg_mprj_datal has recieved wrong data {cpu.read_debug_reg2()} instead of {data_in}") + data_in = 0x55555555 + cocotb.log.info(f"[TEST] drive {hex(data_in)} to gpio[31:0]") + caravelEnv.drive_gpio_in((31,0),data_in) + await wait_reg1(cpu,caravelEnv,0xDD) + if cpu.read_debug_reg2() == data_in: + cocotb.log.info(f"[TEST] data {hex(data_in)} sent successfully through gpio[31:0]") + else: + cocotb.log.error(f"[TEST] Error: reg_mprj_datal has recieved wrong data {cpu.read_debug_reg2()} instead of {data_in}") + data_in = 0x0 + cocotb.log.info(f"[TEST] drive {hex(data_in)} to gpio[31:0]") + caravelEnv.drive_gpio_in((31,0),data_in) + await wait_reg1(cpu,caravelEnv,0xD1) + if cpu.read_debug_reg2() == data_in: + cocotb.log.info(f"[TEST] data {hex(data_in)} sent successfully through gpio[31:0]") + else: + cocotb.log.error(f"[TEST] Error: reg_mprj_datal has recieved wrong data {cpu.read_debug_reg2()} instead of {data_in}") + data_in = 0x3F + cocotb.log.info(f"[TEST] drive {hex(data_in)} to gpio[37:32]") + caravelEnv.drive_gpio_in((37,32),data_in) + await wait_reg1(cpu,caravelEnv,0xD2) + if cpu.read_debug_reg2() == data_in: + cocotb.log.info(f"[TEST] data {hex(data_in)} sent successfully through gpio[37:32]") + else: + cocotb.log.error(f"[TEST] Error: reg_mprj_datah has recieved wrong data {cpu.read_debug_reg2()} instead of {data_in}") + data_in = 0x0 + cocotb.log.info(f"[TEST] drive {hex(data_in)} to gpio[37:32]") + caravelEnv.drive_gpio_in((37,32),data_in) + await wait_reg1(cpu,caravelEnv,0xD3) + if cpu.read_debug_reg2() == data_in: + cocotb.log.info(f"[TEST] data {hex(data_in)} sent successfully through gpio[37:32]") + else: + cocotb.log.error(f"[TEST] Error: reg_mprj_datah has recieved wrong data {cpu.read_debug_reg2()} instead of {data_in}") + data_in = 0x15 + cocotb.log.info(f"[TEST] drive {hex(data_in)} to gpio[37:32]") + caravelEnv.drive_gpio_in((37,32),data_in) + await wait_reg1(cpu,caravelEnv,0xD4) + if cpu.read_debug_reg2() == data_in: + cocotb.log.info(f"[TEST] data {hex(data_in)} sent successfully through gpio[37:32]") + else: + cocotb.log.error(f"[TEST] Error: reg_mprj_datah has recieved wrong data {cpu.read_debug_reg2()} instead of {data_in}") + data_in = 0x2A + cocotb.log.info(f"[TEST] drive {hex(data_in)} to gpio[37:32]") + caravelEnv.drive_gpio_in((37,32),data_in) + await wait_reg1(cpu,caravelEnv,0XD5) + + await wait_reg2(cpu,caravelEnv,0XFF) + + cocotb.log.info(f"[TEST] finish") + await ClockCycles(caravelEnv.clk, 10) diff --git a/verilog/dv/cocotb/verify_cocotb.py b/verilog/dv/cocotb/verify_cocotb.py index 346fd7fb..78282605 100755 --- a/verilog/dv/cocotb/verify_cocotb.py +++ b/verilog/dv/cocotb/verify_cocotb.py @@ -134,6 +134,7 @@ class RunTest: # vcs function def runTest_vcs(self): print(f"Start running test: {self.sim_type}-{self.test_name}") + CARAVEL_PATH = os.getenv('CARAVEL_PATH') PDK_ROOT = os.getenv('PDK_ROOT') PDK = os.getenv('PDK') VERILOG_PATH = os.getenv('VERILOG_PATH') @@ -168,8 +169,12 @@ class RunTest: os.environ["TESTCASE"] = f"{self.test_name}" os.environ["MODULE"] = f"caravel_tests" os.environ["SIM"] = self.sim_type - - os.system(f"vlogan -full64 -sverilog +error+30 caravel_top.sv {dirs} {macros} +define+TESTNAME=\\\"{self.test_name}\\\" +define+FTESTNAME=\\\"{self.full_test_name}\\\" +define+TAG=\\\"{os.getenv('RUNTAG')}\\\" -l {self.sim_path}/analysis.log -o {self.sim_path} ") + # user_project = f"-v {CARAVEL_PATH}/rtl/__user_project_wrapper.v" + # if caravan: + # print ("Use caravan") + # macros = f'+define+CARAVAN {macros} ' + # user_project = f"-v {CARAVEL_PATH}/rtl/__user_analog_project_wrapper.v" + os.system(f"vlogan -full64 -sverilog +error+30 caravel_top.sv {dirs} {macros} +define+TESTNAME=\\\"{self.test_name}\\\" +define+FTESTNAME=\\\"{self.full_test_name}\\\" +define+TAG=\\\"{os.getenv('RUNTAG')}\\\" -l {self.sim_path}/analysis.log -o {self.sim_path} ") os.system(f"vcs +lint=TFIPC-L {coverage_command} +error+30 -R -diag=sdf:verbose +sdfverbose +neg_tchk -debug_access -full64 -l {self.sim_path}/test.log caravel_top -Mdir={self.sim_path}/csrc -o {self.sim_path}/simv +vpi -P pli.tab -load $(cocotb-config --lib-name-path vpi vcs)") self.passed = search_str(self.test_log.name,"Test passed with (0)criticals (0)errors") Path(f'{self.sim_path}/{self.passed}').touch()