../src/lowrisc_systems_top_earlgrey_verilator_0.1/rtl/top_earlgrey_verilator.sv Cov: 100%
1: // Copyright lowRISC contributors.
2: // Licensed under the Apache License, Version 2.0, see LICENSE for details.
3: // SPDX-License-Identifier: Apache-2.0
4:
5: module top_earlgrey_verilator (
6: // Clock and Reset
7: input clk_i,
8: input rst_ni
9: );
10:
11: logic cio_jtag_tck, cio_jtag_tms, cio_jtag_tdi, cio_jtag_tdo;
12: logic cio_jtag_trst_n, cio_jtag_srst_n;
13:
14: logic [31:0] cio_gpio_p2d, cio_gpio_d2p, cio_gpio_en_d2p;
15: logic cio_uart_rx_p2d, cio_uart_tx_d2p, cio_uart_tx_en_d2p;
16:
17: logic cio_spi_device_sck_p2d, cio_spi_device_csb_p2d;
18: logic cio_spi_device_mosi_p2d;
19: logic cio_spi_device_miso_d2p, cio_spi_device_miso_en_d2p;
20:
21: logic cio_usbdev_sense_p2d;
22: logic cio_usbdev_se0_d2p, cio_usbdev_se0_en_d2p;
23: logic cio_usbdev_dp_pullup_d2p, cio_usbdev_dp_pullup_en_d2p;
24: logic cio_usbdev_dn_pullup_d2p, cio_usbdev_dn_pullup_en_d2p;
25: logic cio_usbdev_tx_mode_se_d2p, cio_usbdev_tx_mode_se_en_d2p;
26: logic cio_usbdev_suspend_d2p, cio_usbdev_suspend_en_d2p;
27: logic cio_usbdev_d_p2d, cio_usbdev_d_d2p, cio_usbdev_d_en_d2p;
28: logic cio_usbdev_dp_p2d, cio_usbdev_dp_d2p, cio_usbdev_dp_en_d2p;
29: logic cio_usbdev_dn_p2d, cio_usbdev_dn_d2p, cio_usbdev_dn_en_d2p;
30:
31: logic IO_JTCK, IO_JTMS, IO_JTRST_N, IO_JTDI, IO_JTDO;
32:
33: // TODO: instantiate padring and route these signals through that module
34: logic [14:0] dio_in;
35: logic [14:0] dio_out;
36: logic [14:0] dio_oe;
37:
38: assign dio_in = {cio_spi_device_sck_p2d,
39: cio_spi_device_csb_p2d,
40: cio_spi_device_mosi_p2d,
41: 1'b0,
42: cio_uart_rx_p2d,
43: 1'b0,
44: cio_usbdev_sense_p2d,
45: 1'b0,
46: 1'b0,
47: 1'b0,
48: 1'b0,
49: 1'b0,
50: cio_usbdev_d_p2d,
51: cio_usbdev_dp_p2d,
52: cio_usbdev_dn_p2d};
53:
54: assign cio_usbdev_dn_d2p = dio_out[0];
55: assign cio_usbdev_dp_d2p = dio_out[1];
56: assign cio_usbdev_d_d2p = dio_out[2];
57: assign cio_usbdev_suspend_d2p = dio_out[3];
58: assign cio_usbdev_tx_mode_se_d2p = dio_out[4];
59: assign cio_usbdev_dn_pullup_d2p = dio_out[5];
60: assign cio_usbdev_dp_pullup_d2p = dio_out[6];
61: assign cio_usbdev_se0_d2p = dio_out[7];
62: assign cio_uart_tx_d2p = dio_out[9];
63: assign cio_spi_device_miso_d2p = dio_out[11];
64:
65: assign cio_usbdev_dn_en_d2p = dio_oe[0];
66: assign cio_usbdev_dp_en_d2p = dio_oe[1];
67: assign cio_usbdev_d_en_d2p = dio_oe[2];
68: assign cio_usbdev_suspend_en_d2p = dio_oe[3];
69: assign cio_usbdev_tx_mode_se_en_d2p = dio_oe[4];
70: assign cio_usbdev_dn_pullup_en_d2p = dio_oe[5];
71: assign cio_usbdev_dp_pullup_en_d2p = dio_oe[6];
72: assign cio_usbdev_se0_en_d2p = dio_oe[7];
73: assign cio_uart_tx_en_d2p = dio_oe[9];
74: assign cio_spi_device_miso_en_d2p = dio_oe[11];
75:
76: // Top-level design
77: top_earlgrey top_earlgrey (
78: .clk_i (clk_i),
79: .rst_ni (rst_ni),
80: .clk_io_i (clk_i),
81: .clk_usb_i (clk_i),
82: .clk_aon_i (clk_i),
83:
84: .jtag_tck_i (cio_jtag_tck),
85: .jtag_tms_i (cio_jtag_tms),
86: .jtag_trst_ni (cio_jtag_trst_n),
87: .jtag_tdi_i (cio_jtag_tdi),
88: .jtag_tdo_o (cio_jtag_tdo),
89:
90: // Multiplexed I/O
91: .mio_in_i (cio_gpio_p2d),
92: .mio_out_o (cio_gpio_d2p),
93: .mio_oe_o (cio_gpio_en_d2p),
94:
95: // Dedicated I/O
96: .dio_in_i (dio_in),
97: .dio_out_o (dio_out),
98: .dio_oe_o (dio_oe),
99:
100: // Pad attributes
101: .mio_attr_o ( ),
102: .dio_attr_o ( ),
103:
104: .scanmode_i (1'b0)
105: );
106:
107: // GPIO DPI
108: gpiodpi #(.N_GPIO(32)) u_gpiodpi (
109: .clk_i (clk_i),
110: .rst_ni (rst_ni),
111: .gpio_p2d (cio_gpio_p2d),
112: .gpio_d2p (cio_gpio_d2p),
113: .gpio_en_d2p(cio_gpio_en_d2p)
114: );
115:
116: // UART DPI
117: // The baud rate set to match FPGA implementation; the frequency is
118: // "artificial".
119: // Both baud rate and frequency must match the settings used in the on-chip
120: // software.
121: uartdpi #(
122: .BAUD('d9_600),
123: .FREQ('d500_000)
124: ) u_uart (
125: .clk_i (clk_i),
126: .rst_ni (rst_ni),
127: .tx_o (cio_uart_rx_p2d),
128: .rx_i (cio_uart_tx_d2p)
129: );
130:
131: `ifdef DMIDirectTAP
132: // OpenOCD direct DMI TAP
133: bind rv_dm dmidpi u_dmidpi (
134: .clk_i,
135: .rst_ni,
136: .dmi_req_valid,
137: .dmi_req_ready,
138: .dmi_req_addr (dmi_req.addr),
139: .dmi_req_op (dmi_req.op),
140: .dmi_req_data (dmi_req.data),
141: .dmi_rsp_valid,
142: .dmi_rsp_ready,
143: .dmi_rsp_data (dmi_rsp.data),
144: .dmi_rsp_resp (dmi_rsp.resp),
145: .dmi_rst_n (dmi_rst_n)
146: );
147: `else
148: // JTAG DPI for OpenOCD
149: jtagdpi u_jtagdpi (
150: .clk_i,
151: .rst_ni,
152:
153: .jtag_tck (cio_jtag_tck),
154: .jtag_tms (cio_jtag_tms),
155: .jtag_tdi (cio_jtag_tdi),
156: .jtag_tdo (cio_jtag_tdo),
157: .jtag_trst_n (cio_jtag_trst_n),
158: .jtag_srst_n (cio_jtag_srst_n)
159: );
160: `endif
161:
162: // SPI DPI
163: spidpi u_spi (
164: .clk_i (clk_i),
165: .rst_ni (rst_ni),
166: .spi_device_sck_o (cio_spi_device_sck_p2d),
167: .spi_device_csb_o (cio_spi_device_csb_p2d),
168: .spi_device_mosi_o (cio_spi_device_mosi_p2d),
169: .spi_device_miso_i (cio_spi_device_miso_d2p),
170: .spi_device_miso_en_i (cio_spi_device_miso_en_d2p)
171: );
172:
173: // USB DPI
174: usbdpi u_usbdpi (
175: .clk_i (clk_i),
176: .rst_ni (rst_ni),
177: .clk_48MHz_i (clk_i),
178: .sense_p2d (cio_usbdev_sense_p2d),
179: .pullup_d2p (cio_usbdev_dp_pullup_d2p),
180: .pullup_en_d2p (cio_usbdev_dp_pullup_en_d2p),
181: .dp_p2d (cio_usbdev_dp_p2d),
182: .dp_d2p (cio_usbdev_dp_d2p),
183: .dp_en_d2p (cio_usbdev_dp_en_d2p),
184: .dn_p2d (cio_usbdev_dn_p2d),
185: .dn_d2p (cio_usbdev_dn_d2p),
186: .dn_en_d2p (cio_usbdev_dn_en_d2p)
187: );
188:
189: // Tie off unused signals.
190: logic unused_cio_usbdev_se0_d2p, unused_cio_usbdev_se0_en_d2p;
191: logic unused_cio_usbdev_dn_pullup_d2p, unused_cio_usbdev_dn_pullup_en_d2p;
192: logic unused_cio_usbdev_tx_mode_se_d2p, unused_cio_usbdev_tx_mode_se_en_d2p;
193: logic unused_cio_usbdev_suspend_d2p, unused_cio_usbdev_suspend_en_d2p;
194: logic unused_cio_usbdev_d_d2p, unused_cio_usbdev_d_en_d2p;
195: assign unused_cio_usbdev_se0_d2p = cio_usbdev_se0_d2p;
196: assign unused_cio_usbdev_se0_en_d2p = cio_usbdev_se0_en_d2p;
197: assign unused_cio_usbdev_dn_pullup_d2p = cio_usbdev_dn_pullup_d2p;
198: assign unused_cio_usbdev_dn_pullup_en_d2p = cio_usbdev_dn_pullup_en_d2p;
199: assign unused_cio_usbdev_tx_mode_se_d2p = cio_usbdev_tx_mode_se_d2p;
200: assign unused_cio_usbdev_tx_mode_se_en_d2p = cio_usbdev_tx_mode_se_en_d2p;
201: assign unused_cio_usbdev_suspend_d2p = cio_usbdev_suspend_d2p;
202: assign unused_cio_usbdev_suspend_en_d2p = cio_usbdev_suspend_en_d2p;
203: assign cio_usbdev_d_p2d = 1'b0;
204: assign unused_cio_usbdev_d_d2p = cio_usbdev_d_d2p;
205: assign unused_cio_usbdev_d_en_d2p = cio_usbdev_d_en_d2p;
206:
207: // monitor for termination
208: `ifndef END_MON_PATH
209: `define END_MON_PATH top_earlgrey.u_ram1p_ram_main
210: `endif
211:
212: logic valid;
213: logic [31:0] addr;
214: logic end_valid;
215:
216: // mem address in design is offset from base, re-create the full address here
217: assign addr = `VERILATOR_MEM_BASE + {`END_MON_PATH.addr_i, 2'h0};
218: assign valid = `END_MON_PATH.req_i & `END_MON_PATH.write_i & `END_MON_PATH.rst_ni;
219: assign end_valid = valid & (addr == `VERILATOR_END_SIM_ADDR);
220:
221: always_ff @(posedge clk_i) begin
222: if (end_valid) begin
223: $display("Verilator sim termination requested");
224: $display("Your simulation wrote to 0x%h", `VERILATOR_END_SIM_ADDR);
225: $finish;
226: end
227: end
228:
229: endmodule
230: