| // Copyright lowRISC contributors. | 
 | // Licensed under the Apache License, Version 2.0, see LICENSE for details. | 
 | // SPDX-License-Identifier: Apache-2.0 | 
 |  | 
 | module top_earlgrey_verilator ( | 
 |   // Clock and Reset | 
 |   input clk_i, | 
 |   input rst_ni | 
 | ); | 
 |  | 
 |   logic cio_jtag_tck, cio_jtag_tms, cio_jtag_tdi, cio_jtag_tdo; | 
 |   logic cio_jtag_trst_n, cio_jtag_srst_n; | 
 |  | 
 |   logic [31:0]  cio_gpio_p2d, cio_gpio_d2p, cio_gpio_en_d2p; | 
 |   logic cio_uart_rx_p2d, cio_uart_tx_d2p, cio_uart_tx_en_d2p; | 
 |  | 
 |   logic cio_spi_device_sck_p2d, cio_spi_device_csb_p2d; | 
 |   logic cio_spi_device_sdi_p2d; | 
 |   logic cio_spi_device_sdo_d2p, cio_spi_device_sdo_en_d2p; | 
 |  | 
 |   logic cio_usbdev_sense_p2d; | 
 |   logic cio_usbdev_se0_d2p, cio_usbdev_se0_en_d2p; | 
 |   logic cio_usbdev_dp_pullup_d2p, cio_usbdev_dp_pullup_en_d2p; | 
 |   logic cio_usbdev_dn_pullup_d2p, cio_usbdev_dn_pullup_en_d2p; | 
 |   logic cio_usbdev_tx_mode_se_d2p, cio_usbdev_tx_mode_se_en_d2p; | 
 |   logic cio_usbdev_suspend_d2p, cio_usbdev_suspend_en_d2p; | 
 |   logic cio_usbdev_d_p2d, cio_usbdev_d_d2p, cio_usbdev_d_en_d2p; | 
 |   logic cio_usbdev_dp_p2d, cio_usbdev_dp_d2p, cio_usbdev_dp_en_d2p; | 
 |   logic cio_usbdev_dn_p2d, cio_usbdev_dn_d2p, cio_usbdev_dn_en_d2p; | 
 |  | 
 |   logic IO_JTCK, IO_JTMS, IO_JTRST_N, IO_JTDI, IO_JTDO; | 
 |  | 
 |   // TODO: instantiate padring and route these signals through that module | 
 |   logic [14:0] dio_in; | 
 |   logic [14:0] dio_out; | 
 |   logic [14:0] dio_oe; | 
 |  | 
 |   assign dio_in = {cio_spi_device_sck_p2d, | 
 |                    cio_spi_device_csb_p2d, | 
 |                    cio_spi_device_sdi_p2d, | 
 |                    1'b0, | 
 |                    cio_uart_rx_p2d, | 
 |                    1'b0, | 
 |                    cio_usbdev_sense_p2d, | 
 |                    1'b0, | 
 |                    1'b0, | 
 |                    1'b0, | 
 |                    1'b0, | 
 |                    1'b0, | 
 |                    cio_usbdev_d_p2d, | 
 |                    cio_usbdev_dp_p2d, | 
 |                    cio_usbdev_dn_p2d}; | 
 |  | 
 |   assign cio_usbdev_dn_d2p = dio_out[0]; | 
 |   assign cio_usbdev_dp_d2p = dio_out[1]; | 
 |   assign cio_usbdev_d_d2p  = dio_out[2]; | 
 |   assign cio_usbdev_suspend_d2p = dio_out[3]; | 
 |   assign cio_usbdev_tx_mode_se_d2p = dio_out[4]; | 
 |   assign cio_usbdev_dn_pullup_d2p = dio_out[5]; | 
 |   assign cio_usbdev_dp_pullup_d2p = dio_out[6]; | 
 |   assign cio_usbdev_se0_d2p = dio_out[7]; | 
 |   assign cio_uart_tx_d2p = dio_out[9]; | 
 |   assign cio_spi_device_sdo_d2p = dio_out[11]; | 
 |  | 
 |   assign cio_usbdev_dn_en_d2p = dio_oe[0]; | 
 |   assign cio_usbdev_dp_en_d2p = dio_oe[1]; | 
 |   assign cio_usbdev_d_en_d2p  = dio_oe[2]; | 
 |   assign cio_usbdev_suspend_en_d2p = dio_oe[3]; | 
 |   assign cio_usbdev_tx_mode_se_en_d2p = dio_oe[4]; | 
 |   assign cio_usbdev_dn_pullup_en_d2p = dio_oe[5]; | 
 |   assign cio_usbdev_dp_pullup_en_d2p = dio_oe[6]; | 
 |   assign cio_usbdev_se0_en_d2p = dio_oe[7]; | 
 |   assign cio_uart_tx_en_d2p = dio_oe[9]; | 
 |   assign cio_spi_device_sdo_en_d2p = dio_oe[11]; | 
 |  | 
 |   // dummy ast connections | 
 |   pwrmgr_pkg::pwr_ast_rsp_t ast_base_pwr; | 
 |   ast_wrapper_pkg::ast_rst_t ast_base_rst; | 
 |   ast_wrapper_pkg::ast_alert_req_t ast_base_alerts; | 
 |   ast_wrapper_pkg::ast_status_t ast_base_status; | 
 |  | 
 |   assign ast_base_pwr.slow_clk_val = pwrmgr_pkg::DiffValid; | 
 |   assign ast_base_pwr.core_clk_val = pwrmgr_pkg::DiffValid; | 
 |   assign ast_base_pwr.io_clk_val   = pwrmgr_pkg::DiffValid; | 
 |   assign ast_base_pwr.usb_clk_val  = pwrmgr_pkg::DiffValid; | 
 |   assign ast_base_pwr.main_pok     = 1'b1; | 
 |  | 
 |   assign ast_base_alerts.alerts_p  = '0; | 
 |   assign ast_base_alerts.alerts_n  = {ast_wrapper_pkg::NumAlerts{1'b1}}; | 
 |   assign ast_base_status.io_pok    = {ast_wrapper_pkg::NumIoRails{1'b1}}; | 
 |  | 
 |   // the rst_ni pin only goes to AST | 
 |   // the rest of the logic generates reset based on the 'pok' signal. | 
 |   // for verilator purposes, make these two the same. | 
 |   assign ast_base_rst.aon_pok      = rst_ni; | 
 |   // Top-level design | 
 |   top_earlgrey top_earlgrey ( | 
 |     .rst_ni                     (rst_ni), | 
 |     .clk_main_i                 (clk_i), | 
 |     .clk_io_i                   (clk_i), | 
 |     .clk_usb_i                  (clk_i), | 
 |     .clk_aon_i                  (clk_i), | 
 |     .rstmgr_ast_i                 ( ast_base_rst    ), | 
 |     .pwrmgr_pwr_ast_req_o         (                 ), | 
 |     .pwrmgr_pwr_ast_rsp_i         ( ast_base_pwr    ), | 
 |     .sensor_ctrl_ast_alert_req_i  ( ast_base_alerts ), | 
 |     .sensor_ctrl_ast_alert_rsp_o  (                 ), | 
 |     .sensor_ctrl_ast_status_i     ( ast_base_status ), | 
 |     .usbdev_usb_ref_val_o         (                 ), | 
 |     .usbdev_usb_ref_pulse_o       (                 ), | 
 |     .ast_tl_req_o                 (                 ), | 
 |     .ast_tl_rsp_i                 ( '0              ), | 
 |     .otp_ctrl_otp_ast_pwr_seq_o   (                 ), | 
 |     .otp_ctrl_otp_ast_pwr_seq_h_i ( '0              ), | 
 |     .flash_power_down_h_i         ( '0              ), | 
 |     .flash_power_ready_h_i        ( 1'b1            ), | 
 |  | 
 |     .jtag_tck_i                 (cio_jtag_tck), | 
 |     .jtag_tms_i                 (cio_jtag_tms), | 
 |     .jtag_trst_ni               (cio_jtag_trst_n), | 
 |     .jtag_tdi_i                 (cio_jtag_tdi), | 
 |     .jtag_tdo_o                 (cio_jtag_tdo), | 
 |  | 
 |     // Multiplexed I/O | 
 |     .mio_in_i                   (cio_gpio_p2d), | 
 |     .mio_out_o                  (cio_gpio_d2p), | 
 |     .mio_oe_o                   (cio_gpio_en_d2p), | 
 |  | 
 |     // Dedicated I/O | 
 |     .dio_in_i                   (dio_in), | 
 |     .dio_out_o                  (dio_out), | 
 |     .dio_oe_o                   (dio_oe), | 
 |  | 
 |     // Pad attributes | 
 |     .mio_attr_o                 ( ), | 
 |     .dio_attr_o                 ( ), | 
 |  | 
 |     // DFT signals | 
 |     .scan_rst_ni                (1'b1), | 
 |     .scanmode_i                 (1'b0) | 
 |   ); | 
 |  | 
 |   // GPIO DPI | 
 |   gpiodpi #(.N_GPIO(32)) u_gpiodpi ( | 
 |     .clk_i      (clk_i), | 
 |     .rst_ni     (rst_ni), | 
 |     .gpio_p2d   (cio_gpio_p2d), | 
 |     .gpio_d2p   (cio_gpio_d2p), | 
 |     .gpio_en_d2p(cio_gpio_en_d2p) | 
 |   ); | 
 |  | 
 |   // UART DPI | 
 |   // The baud rate set to match FPGA implementation; the frequency is | 
 |   // "artificial". | 
 |   // Both baud rate and frequency must match the settings used in the on-chip | 
 |   // software. | 
 |   uartdpi #( | 
 |     .BAUD('d7_200), | 
 |     .FREQ('d500_000) | 
 |   ) u_uart ( | 
 |     .clk_i  (clk_i), | 
 |     .rst_ni (rst_ni), | 
 |     .tx_o   (cio_uart_rx_p2d), | 
 |     .rx_i   (cio_uart_tx_d2p) | 
 |   ); | 
 |  | 
 | `ifdef DMIDirectTAP | 
 |   // OpenOCD direct DMI TAP | 
 |   bind rv_dm dmidpi u_dmidpi ( | 
 |     .clk_i, | 
 |     .rst_ni, | 
 |     .dmi_req_valid, | 
 |     .dmi_req_ready, | 
 |     .dmi_req_addr   (dmi_req.addr), | 
 |     .dmi_req_op     (dmi_req.op), | 
 |     .dmi_req_data   (dmi_req.data), | 
 |     .dmi_rsp_valid, | 
 |     .dmi_rsp_ready, | 
 |     .dmi_rsp_data   (dmi_rsp.data), | 
 |     .dmi_rsp_resp   (dmi_rsp.resp), | 
 |     .dmi_rst_n      (dmi_rst_n) | 
 |   ); | 
 | `else | 
 |   // JTAG DPI for OpenOCD | 
 |   jtagdpi u_jtagdpi ( | 
 |     .clk_i, | 
 |     .rst_ni, | 
 |  | 
 |     .jtag_tck    (cio_jtag_tck), | 
 |     .jtag_tms    (cio_jtag_tms), | 
 |     .jtag_tdi    (cio_jtag_tdi), | 
 |     .jtag_tdo    (cio_jtag_tdo), | 
 |     .jtag_trst_n (cio_jtag_trst_n), | 
 |     .jtag_srst_n (cio_jtag_srst_n) | 
 |   ); | 
 | `endif | 
 |  | 
 |   // SPI DPI | 
 |   spidpi u_spi ( | 
 |     .clk_i  (clk_i), | 
 |     .rst_ni (rst_ni), | 
 |     .spi_device_sck_o     (cio_spi_device_sck_p2d), | 
 |     .spi_device_csb_o     (cio_spi_device_csb_p2d), | 
 |     .spi_device_sdi_o     (cio_spi_device_sdi_p2d), | 
 |     .spi_device_sdo_i     (cio_spi_device_sdo_d2p), | 
 |     .spi_device_sdo_en_i  (cio_spi_device_sdo_en_d2p) | 
 |   ); | 
 |  | 
 |   // USB DPI | 
 |   usbdpi u_usbdpi ( | 
 |     .clk_i           (clk_i), | 
 |     .rst_ni          (rst_ni), | 
 |     .clk_48MHz_i     (clk_i), | 
 |     .sense_p2d       (cio_usbdev_sense_p2d), | 
 |     .pullupdp_d2p    (cio_usbdev_dp_pullup_d2p), | 
 |     .pullupdp_en_d2p (cio_usbdev_dp_pullup_en_d2p), | 
 |     .pullupdn_d2p    (cio_usbdev_dn_pullup_d2p), | 
 |     .pullupdn_en_d2p (cio_usbdev_dn_pullup_en_d2p), | 
 |     .dp_p2d          (cio_usbdev_dp_p2d), | 
 |     .dp_d2p          (cio_usbdev_dp_d2p), | 
 |     .dp_en_d2p       (cio_usbdev_dp_en_d2p), | 
 |     .dn_p2d          (cio_usbdev_dn_p2d), | 
 |     .dn_d2p          (cio_usbdev_dn_d2p), | 
 |     .dn_en_d2p       (cio_usbdev_dn_en_d2p), | 
 |     .d_p2d           (cio_usbdev_d_p2d), | 
 |     .d_d2p           (cio_usbdev_d_d2p), | 
 |     .d_en_d2p        (cio_usbdev_d_en_d2p), | 
 |     .se0_d2p         (cio_usbdev_se0_d2p), | 
 |     .se0_en_d2p      (cio_usbdev_se0_en_d2p), | 
 |     .txmode_d2p      (cio_usbdev_tx_mode_se_d2p), | 
 |     .txmode_en_d2p   (cio_usbdev_tx_mode_se_en_d2p) | 
 |   ); | 
 |  | 
 |   // Tie off unused signals. | 
 |   logic unused_cio_usbdev_suspend_d2p, unused_cio_usbdev_suspend_en_d2p; | 
 |   assign unused_cio_usbdev_suspend_d2p = cio_usbdev_suspend_d2p; | 
 |   assign unused_cio_usbdev_suspend_en_d2p = cio_usbdev_suspend_en_d2p; | 
 |  | 
 |   `define RV_CORE_IBEX      top_earlgrey.u_rv_core_ibex | 
 |   `define SIM_SRAM_IF       u_sim_sram.u_sim_sram_if | 
 |  | 
 |   // Detect SW test termination. | 
 |   sim_sram u_sim_sram ( | 
 |     .clk_i    (`RV_CORE_IBEX.clk_i), | 
 |     .rst_ni   (`RV_CORE_IBEX.rst_ni), | 
 |     .tl_in_i  (`RV_CORE_IBEX.tl_d_o_int), | 
 |     .tl_in_o  (), | 
 |     .tl_out_o (), | 
 |     .tl_out_i (`RV_CORE_IBEX.tl_d_i) | 
 |   ); | 
 |  | 
 |   // Connect the sim SRAM directly inside rv_core_ibex. | 
 |   assign `RV_CORE_IBEX.tl_d_i_int = u_sim_sram.tl_in_o; | 
 |   assign `RV_CORE_IBEX.tl_d_o     = u_sim_sram.tl_out_o; | 
 |  | 
 |   // Instantiate the SW test status interface & connect signals from sim_sram_if instance | 
 |   // instantiated inside sim_sram. Bind would have worked nicely here, but Verilator segfaults | 
 |   // when trace is enabled (#3951). | 
 |   sw_test_status_if u_sw_test_status_if ( | 
 |     .clk_i    (`SIM_SRAM_IF.clk_i), | 
 |     .wr_valid (`SIM_SRAM_IF.wr_valid), | 
 |     .addr     (`SIM_SRAM_IF.tl_h2d.a_address), | 
 |     .data     (`SIM_SRAM_IF.tl_h2d.a_data[15:0]) | 
 |   ); | 
 |  | 
 |   // Set the start address of the simulation SRAM. | 
 |   // Use offset 0 within the sim SRAM for SW test status indication. | 
 |   initial begin | 
 |     `SIM_SRAM_IF.start_addr = `VERILATOR_TEST_STATUS_ADDR; | 
 |     u_sw_test_status_if.sw_test_status_addr = `SIM_SRAM_IF.start_addr; | 
 |   end | 
 |  | 
 |   always @(posedge clk_i) begin | 
 |     if (u_sw_test_status_if.sw_test_done) begin | 
 |       $display("Verilator sim termination requested"); | 
 |       $display("Your simulation wrote to 0x%h", u_sw_test_status_if.sw_test_status_addr); | 
 |       dv_test_status_pkg::dv_test_status(u_sw_test_status_if.sw_test_passed); | 
 |       $finish; | 
 |     end | 
 |   end | 
 |  | 
 |   `undef RV_CORE_IBEX | 
 |   `undef SIM_SRAM_IF | 
 |  | 
 | endmodule |