| // Copyright lowRISC contributors. |
| // Licensed under the Apache License, Version 2.0, see LICENSE for details. |
| // SPDX-License-Identifier: Apache-2.0 |
| // |
| module tb; |
| // dep packages |
| import uvm_pkg::*; |
| import dv_utils_pkg::*; |
| import tl_agent_pkg::*; |
| import chip_env_pkg::*; |
| import top_pkg::*; |
| import chip_test_pkg::*; |
| |
| // macro includes |
| `include "uvm_macros.svh" |
| `include "dv_macros.svh" |
| `include "chip_hier_macros.svh" |
| |
| wire clk, rst_n; |
| wire usb_clk, usb_rst_n; |
| |
| wire [NUM_GPIOS-1:0] gpio_pins; |
| |
| wire jtag_tck; |
| wire jtag_tms; |
| wire jtag_trst_n; |
| wire jtag_tdi; |
| wire jtag_tdo; |
| |
| wire spi_device_sck; |
| wire spi_device_csb; |
| wire spi_device_miso_o; |
| wire spi_device_mosi_i; |
| |
| wire srst_n; |
| wire jtag_spi_n; |
| wire bootstrap; |
| wire [7:0] io_dps; |
| |
| wire usb_dp0, usb_dn0, usb_sense0, usb_pullup0; |
| |
| bit stub_cpu; |
| |
| // interfaces |
| clk_rst_if clk_rst_if(.clk(clk), .rst_n(rst_n)); |
| clk_rst_if usb_clk_rst_if(.clk(usb_clk), .rst_n(usb_rst_n)); |
| pins_if #(NUM_GPIOS) gpio_if(.pins(gpio_pins)); |
| pins_if #(1) srst_n_if(.pins(srst_n)); |
| pins_if #(1) jtag_spi_n_if(.pins(jtag_spi_n)); |
| pins_if #(1) bootstrap_if(.pins(bootstrap)); |
| spi_if spi_if(.rst_n(rst_n)); |
| tl_if cpu_d_tl_if(.clk(clk), .rst_n(rst_n)); |
| uart_if uart_if(); |
| jtag_if jtag_if(); |
| |
| // backdoors |
| bind `ROM_HIER mem_bkdr_if rom_mem_bkdr_if(); |
| bind `FLASH0_MEM_HIER mem_bkdr_if flash0_mem_bkdr_if(); |
| bind `FLASH1_MEM_HIER mem_bkdr_if flash1_mem_bkdr_if(); |
| |
| top_earlgrey_asic dut ( |
| // Clock and Reset |
| .IO_CLK (clk), |
| .IO_RST_N (rst_n), |
| .IO_CLK_USB_48MHZ (usb_clk), |
| |
| // JTAG / SPI interface |
| .IO_DPS0 (io_dps[0]), |
| .IO_DPS1 (io_dps[1]), |
| .IO_DPS2 (io_dps[2]), |
| .IO_DPS3 (io_dps[3]), |
| .IO_DPS4 (io_dps[4]), |
| .IO_DPS5 (io_dps[5]), |
| .IO_DPS6 (io_dps[6]), |
| .IO_DPS7 (io_dps[7]), |
| |
| // UART interface |
| .IO_URX (uart_if.uart_rx), |
| .IO_UTX (uart_if.uart_tx), |
| |
| // USB interface |
| .IO_USB_DP0 (usb_dp0), |
| .IO_USB_DN0 (usb_dn0), |
| .IO_USB_SENSE0 (usb_sense0), |
| .IO_USB_PULLUP0 (usb_pullup0), |
| |
| // GPIO x 16 interface |
| .IO_GP0 (gpio_pins[0 ]), |
| .IO_GP1 (gpio_pins[1 ]), |
| .IO_GP2 (gpio_pins[2 ]), |
| .IO_GP3 (gpio_pins[3 ]), |
| .IO_GP4 (gpio_pins[4 ]), |
| .IO_GP5 (gpio_pins[5 ]), |
| .IO_GP6 (gpio_pins[6 ]), |
| .IO_GP7 (gpio_pins[7 ]), |
| .IO_GP8 (gpio_pins[8 ]), |
| .IO_GP9 (gpio_pins[9 ]), |
| .IO_GP10 (gpio_pins[10]), |
| .IO_GP11 (gpio_pins[11]), |
| .IO_GP12 (gpio_pins[12]), |
| .IO_GP13 (gpio_pins[13]), |
| .IO_GP14 (gpio_pins[14]), |
| .IO_GP15 (gpio_pins[15]) |
| ); |
| |
| // connect sw_logger_if |
| parameter string SwTypes[] = '{"rom", "sw"}; |
| generate |
| for (genvar i = 0; i < 2; i++) begin: sw_logger_if_i |
| bit sw_log_valid; |
| bit [TL_AW-1:0] sw_log_addr; |
| |
| sw_logger_if sw_logger_if ( |
| .clk (`RAM_MAIN_HIER.clk_i), |
| .rst_n (`RAM_MAIN_HIER.rst_ni), |
| .valid (sw_log_valid), |
| .addr_data (`RAM_MAIN_HIER.wdata_i), |
| .sw_log_addr (sw_log_addr) |
| ); |
| // TODO: RAM only looks at addr[15:2] - need to find a better way to capture it. |
| assign sw_log_valid = `RAM_MAIN_HIER.req_i && `RAM_MAIN_HIER.write_i && |
| (`RAM_MAIN_HIER.addr_i == sw_log_addr[15:2]); |
| |
| initial begin |
| uvm_config_db#(virtual sw_logger_if)::set( |
| null, "*.env", $sformatf("sw_logger_vif[%0s]", SwTypes[i]), sw_logger_if); |
| end |
| end |
| endgenerate |
| |
| // connect signals |
| assign io_dps[0] = jtag_spi_n ? jtag_tck : spi_device_sck; |
| assign io_dps[1] = jtag_spi_n ? jtag_tdi : spi_device_mosi_i; |
| assign io_dps[3] = jtag_spi_n ? jtag_tms : spi_device_csb; |
| assign io_dps[4] = jtag_trst_n; |
| assign io_dps[5] = srst_n; |
| assign io_dps[6] = jtag_spi_n; |
| assign io_dps[7] = bootstrap; |
| assign spi_device_miso_o = jtag_spi_n ? 1'b0 : io_dps[2]; |
| assign jtag_tdo = jtag_spi_n ? io_dps[2] : 1'b0; |
| |
| assign jtag_tck = jtag_if.tck; |
| assign jtag_tms = jtag_if.tms; |
| assign jtag_trst_n = jtag_if.trst_n; |
| assign jtag_tdi = jtag_if.tdi; |
| assign jtag_if.tdo = jtag_tdo; |
| |
| assign spi_device_sck = spi_if.sck; |
| assign spi_device_csb = spi_if.csb; |
| assign spi_device_mosi_i = spi_if.mosi; |
| assign spi_if.miso = spi_device_miso_o; |
| |
| // TODO: USB-related signals, hookup an interface. |
| assign usb_rst_n = `USBDEV_HIER.rst_usb_48mhz_ni; |
| assign usb_dp0 = 1'b1; |
| assign usb_dn0 = 1'b0; |
| assign usb_sense0 = 1'b0; |
| |
| initial begin |
| // Set clk_rst_vifs |
| // drive clk and rst_n from clk_if |
| clk_rst_if.set_active(); |
| usb_clk_rst_if.set_active(.drive_clk_val(1'b1), .drive_rst_n_val(1'b0)); |
| uvm_config_db#(virtual clk_rst_if)::set(null, "*.env", "clk_rst_vif", clk_rst_if); |
| uvm_config_db#(virtual clk_rst_if)::set(null, "*.env", "usb_clk_rst_vif", usb_clk_rst_if); |
| |
| // IO Interfaces |
| uvm_config_db#(virtual pins_if #(NUM_GPIOS))::set(null, "*.env", "gpio_vif", gpio_if); |
| uvm_config_db#(virtual uart_if)::set(null, "*.env.m_uart_agent*", "vif", uart_if); |
| uvm_config_db#(virtual jtag_if)::set(null, "*.env.m_jtag_agent*", "vif", jtag_if); |
| uvm_config_db#(virtual spi_if)::set(null, "*.env.m_spi_agent*", "vif", spi_if); |
| uvm_config_db#(virtual tl_if)::set(null, "*.env.m_cpu_d_tl_agent*", "vif", cpu_d_tl_if); |
| |
| // Strap pins |
| uvm_config_db#(virtual pins_if #(1))::set( |
| null, "*.env", "srst_n_vif", srst_n_if); |
| uvm_config_db#(virtual pins_if #(1))::set( |
| null, "*.env", "jtag_spi_n_vif", jtag_spi_n_if); |
| uvm_config_db#(virtual pins_if #(1))::set( |
| null, "*.env", "bootstrap_vif", bootstrap_if); |
| |
| // Backdoors |
| uvm_config_db#(virtual mem_bkdr_if)::set( |
| null, "*.env", "mem_bkdr_vifs[Rom]", `ROM_HIER.rom_mem_bkdr_if); |
| uvm_config_db#(virtual mem_bkdr_if)::set( |
| null, "*.env", "mem_bkdr_vifs[FlashBank0]", `FLASH0_MEM_HIER.flash0_mem_bkdr_if); |
| uvm_config_db#(virtual mem_bkdr_if)::set( |
| null, "*.env", "mem_bkdr_vifs[FlashBank1]", `FLASH1_MEM_HIER.flash1_mem_bkdr_if); |
| |
| $timeformat(-12, 0, " ps", 12); |
| run_test(); |
| end |
| |
| // stub cpu environment |
| // if enabled, clock to cpu is forced to 0 |
| // cpu_d_tl_if force are applied to cpu d tl interface |
| initial begin |
| void'($value$plusargs("stub_cpu=%0b", stub_cpu)); |
| if (stub_cpu) begin |
| force `CPU_HIER.clk_i = 1'b0; |
| force `CPU_HIER.tl_d_o = cpu_d_tl_if.h2d; |
| end else begin |
| force cpu_d_tl_if.h2d = `CPU_HIER.tl_d_o; |
| end |
| end |
| assign cpu_d_tl_if.d2h = `CPU_HIER.tl_d_i; |
| |
| endmodule |