|  | /*--------------------------------------------------------------*/ | 
|  | /* caravel, a project harness for the Google/SkyWater sky130	*/ | 
|  | /* fabrication process and open source PDK			*/ | 
|  | /*                                                          	*/ | 
|  | /* Copyright 2020 efabless, Inc.                            	*/ | 
|  | /* Written by Tim Edwards, December 2019                    	*/ | 
|  | /* and Mohamed Shalan, August 2020			    	*/ | 
|  | /* This file is open source hardware released under the     	*/ | 
|  | /* Apache 2.0 license.  See file LICENSE.                   	*/ | 
|  | /*                                                          	*/ | 
|  | /*--------------------------------------------------------------*/ | 
|  |  | 
|  | `timescale 1 ns / 1 ps | 
|  |  | 
|  | `define USE_POWER_PINS | 
|  | `define UNIT_DELAY #1 | 
|  |  | 
|  | `include "defines.v" | 
|  | `include "pads.v" | 
|  |  | 
|  | /* NOTE: Need to pass the PDK root directory to iverilog with option -I */ | 
|  |  | 
|  | `include "libs.ref/sky130_fd_io/verilog/sky130_fd_io.v" | 
|  | `include "libs.ref/sky130_fd_io/verilog/sky130_ef_io.v" | 
|  |  | 
|  | `include "libs.ref/sky130_fd_sc_hd/verilog/primitives.v" | 
|  | `include "libs.ref/sky130_fd_sc_hd/verilog/sky130_fd_sc_hd.v" | 
|  | `include "libs.ref/sky130_fd_sc_hvl/verilog/primitives.v" | 
|  | `include "libs.ref/sky130_fd_sc_hvl/verilog/sky130_fd_sc_hvl.v" | 
|  |  | 
|  | `include "mgmt_soc.v" | 
|  | `include "housekeeping_spi.v" | 
|  | `include "digital_pll.v" | 
|  | `include "caravel_clocking.v" | 
|  | `include "mgmt_core.v" | 
|  | `include "mgmt_protect.v" | 
|  | `include "mprj_io.v" | 
|  | `include "chip_io.v" | 
|  | `include "user_id_programming.v" | 
|  | `include "user_project_wrapper.v" | 
|  | `include "gpio_control_block.v" | 
|  | `include "clock_div.v" | 
|  | `include "simple_por.v" | 
|  | `include "storage_bridge_wb.v" | 
|  | `include "DFFRAM.v" | 
|  | `include "sram_1rw1r_32_256_8_sky130.v" | 
|  | `include "storage.v" | 
|  |  | 
|  | /*------------------------------*/ | 
|  | /* Include user project here	*/ | 
|  | /*------------------------------*/ | 
|  | `include "user_proj_example.v" | 
|  |  | 
|  | // `ifdef USE_OPENRAM | 
|  | //     `include "sram_1rw1r_32_256_8_sky130.v" | 
|  | // `endif | 
|  |  | 
|  | module caravel ( | 
|  | inout vddio,	// Common 3.3V padframe/ESD power | 
|  | inout vssio,	// Common padframe/ESD ground | 
|  | inout vdda,		// Management 3.3V power | 
|  | inout vssa,		// Common analog ground | 
|  | inout vccd,		// Management/Common 1.8V power | 
|  | inout vssd,		// Common digital ground | 
|  | inout vdda1,	// User area 1 3.3V power | 
|  | inout vdda2,	// User area 2 3.3V power | 
|  | inout vssa1,	// User area 1 analog ground | 
|  | inout vssa2,	// User area 2 analog ground | 
|  | inout vccd1,	// User area 1 1.8V power | 
|  | inout vccd2,	// User area 2 1.8V power | 
|  | inout vssd1,	// User area 1 digital ground | 
|  | inout vssd2,	// User area 2 digital ground | 
|  |  | 
|  | inout gpio,			// Used for external LDO control | 
|  | inout [`MPRJ_IO_PADS-1:0] mprj_io, | 
|  | output [`MPRJ_PWR_PADS-1:0] pwr_ctrl_out, | 
|  | input clock,	    	// CMOS core clock input, not a crystal | 
|  | input resetb, | 
|  |  | 
|  | // Note that only two pins are available on the flash so dual and | 
|  | // quad flash modes are not available. | 
|  |  | 
|  | output flash_csb, | 
|  | output flash_clk, | 
|  | output flash_io0, | 
|  | output flash_io1 | 
|  | ); | 
|  |  | 
|  | //------------------------------------------------------------ | 
|  | // This value is uniquely defined for each user project. | 
|  | //------------------------------------------------------------ | 
|  | parameter USER_PROJECT_ID = 32'h0; | 
|  |  | 
|  | // These pins are overlaid on mprj_io space.  They have the function | 
|  | // below when the management processor is in reset, or in the default | 
|  | // configuration.  They are assigned to uses in the user space by the | 
|  | // configuration program running off of the SPI flash.  Note that even | 
|  | // when the user has taken control of these pins, they can be restored | 
|  | // to the original use by setting the resetb pin low.  The SPI pins and | 
|  | // UART pins can be connected directly to an FTDI chip as long as the | 
|  | // FTDI chip sets these lines to high impedence (input function) at | 
|  | // all times except when holding the chip in reset. | 
|  |  | 
|  | // JTAG      = mprj_io[0]		(inout) | 
|  | // SDO 	 = mprj_io[1]		(output) | 
|  | // SDI 	 = mprj_io[2]		(input) | 
|  | // CSB 	 = mprj_io[3]		(input) | 
|  | // SCK	 = mprj_io[4]		(input) | 
|  | // ser_rx    = mprj_io[5]		(input) | 
|  | // ser_tx    = mprj_io[6]		(output) | 
|  | // irq 	 = mprj_io[7]		(input) | 
|  |  | 
|  | // These pins are reserved for any project that wants to incorporate | 
|  | // its own processor and flash controller.  While a user project can | 
|  | // technically use any available I/O pins for the purpose, these | 
|  | // four pins connect to a pass-through mode from the SPI slave (pins | 
|  | // 1-4 above) so that any SPI flash connected to these specific pins | 
|  | // can be accessed through the SPI slave even when the processor is in | 
|  | // reset. | 
|  |  | 
|  | // user_flash_csb = mprj_io[8] | 
|  | // user_flash_sck = mprj_io[9] | 
|  | // user_flash_io0 = mprj_io[10] | 
|  | // user_flash_io1 = mprj_io[11] | 
|  |  | 
|  | // One-bit GPIO dedicated to management SoC (outside of user control) | 
|  | wire gpio_out_core; | 
|  | wire gpio_in_core; | 
|  | wire gpio_mode0_core; | 
|  | wire gpio_mode1_core; | 
|  | wire gpio_outenb_core; | 
|  | wire gpio_inenb_core; | 
|  |  | 
|  | // User Project Control (pad-facing) | 
|  | wire mprj_io_loader_resetn; | 
|  | wire mprj_io_loader_clock; | 
|  | wire mprj_io_loader_data; | 
|  |  | 
|  | wire [`MPRJ_IO_PADS-1:0] mprj_io_hldh_n; | 
|  | wire [`MPRJ_IO_PADS-1:0] mprj_io_enh; | 
|  | wire [`MPRJ_IO_PADS-1:0] mprj_io_inp_dis; | 
|  | wire [`MPRJ_IO_PADS-1:0] mprj_io_oeb; | 
|  | wire [`MPRJ_IO_PADS-1:0] mprj_io_ib_mode_sel; | 
|  | wire [`MPRJ_IO_PADS-1:0] mprj_io_vtrip_sel; | 
|  | wire [`MPRJ_IO_PADS-1:0] mprj_io_slow_sel; | 
|  | wire [`MPRJ_IO_PADS-1:0] mprj_io_holdover; | 
|  | wire [`MPRJ_IO_PADS-1:0] mprj_io_analog_en; | 
|  | wire [`MPRJ_IO_PADS-1:0] mprj_io_analog_sel; | 
|  | wire [`MPRJ_IO_PADS-1:0] mprj_io_analog_pol; | 
|  | wire [`MPRJ_IO_PADS*3-1:0] mprj_io_dm; | 
|  | wire [`MPRJ_IO_PADS-1:0] mprj_io_in; | 
|  | wire [`MPRJ_IO_PADS-1:0] mprj_io_out; | 
|  |  | 
|  | // User Project Control (user-facing) | 
|  | wire [`MPRJ_IO_PADS-1:0] user_io_oeb; | 
|  | wire [`MPRJ_IO_PADS-1:0] user_io_in; | 
|  | wire [`MPRJ_IO_PADS-1:0] user_io_out; | 
|  |  | 
|  | /* Padframe control signals */ | 
|  | wire [`MPRJ_IO_PADS-1:0] gpio_serial_link; | 
|  | wire mgmt_serial_clock; | 
|  | wire mgmt_serial_resetn; | 
|  |  | 
|  | // User Project Control management I/O | 
|  | // There are two types of GPIO connections: | 
|  | // (1) Full Bidirectional: Management connects to in, out, and oeb | 
|  | //     Uses:  JTAG and SDO | 
|  | // (2) Selectable bidirectional:  Management connects to in and out, | 
|  | //	   which are tied together.  oeb is grounded (oeb from the | 
|  | //	   configuration is used) | 
|  |  | 
|  | // SDI 	 = mprj_io[2]		(input) | 
|  | // CSB 	 = mprj_io[3]		(input) | 
|  | // SCK	 = mprj_io[4]		(input) | 
|  | // ser_rx    = mprj_io[5]		(input) | 
|  | // ser_tx    = mprj_io[6]		(output) | 
|  | // irq 	 = mprj_io[7]		(input) | 
|  |  | 
|  | wire [`MPRJ_IO_PADS-1:0] mgmt_io_in; | 
|  | wire jtag_out, sdo_out; | 
|  | wire jtag_outenb, sdo_outenb; | 
|  |  | 
|  | wire [`MPRJ_IO_PADS-3:0] mgmt_io_nc1;	/* no-connects */ | 
|  | wire [`MPRJ_IO_PADS-3:0] mgmt_io_nc3;	/* no-connects */ | 
|  | wire [1:0] mgmt_io_nc2;			/* no-connects */ | 
|  |  | 
|  | // Power-on-reset signal.  The reset pad generates the sense-inverted | 
|  | // reset at 3.3V.  The 1.8V signal and the inverted 1.8V signal are | 
|  | // derived. | 
|  |  | 
|  | wire porb_h; | 
|  | wire porb_l; | 
|  |  | 
|  | wire rstb_h; | 
|  | wire rstb_l; | 
|  |  | 
|  | // To be considered:  Master hold signal on all user pads (?) | 
|  | // For now, set holdh_n to 1 (NOTE:  This is in the 3.3V domain) | 
|  | // and setting enh to porb_h. | 
|  | assign mprj_io_hldh_n = {`MPRJ_IO_PADS{vddio}}; | 
|  | assign mprj_io_enh = {`MPRJ_IO_PADS{porb_h}}; | 
|  |  | 
|  | chip_io padframe( | 
|  | // Package Pins | 
|  | .vddio(vddio), | 
|  | .vssio(vssio), | 
|  | .vdda(vdda), | 
|  | .vssa(vssa), | 
|  | .vccd(vccd), | 
|  | .vssd(vssd), | 
|  | .vdda1(vdda1), | 
|  | .vdda2(vdda2), | 
|  | .vssa1(vssa1), | 
|  | .vssa2(vssa2), | 
|  | .vccd1(vccd1), | 
|  | .vccd2(vccd2), | 
|  | .vssd1(vssd1), | 
|  | .vssd2(vssd2), | 
|  |  | 
|  | .gpio(gpio), | 
|  | .mprj_io(mprj_io), | 
|  | .clock(clock), | 
|  | .resetb(resetb), | 
|  | .flash_csb(flash_csb), | 
|  | .flash_clk(flash_clk), | 
|  | .flash_io0(flash_io0), | 
|  | .flash_io1(flash_io1), | 
|  | // SoC Core Interface | 
|  | .porb_h(porb_h), | 
|  | .resetb_core_h(rstb_h), | 
|  | .clock_core(clock_core), | 
|  | .gpio_out_core(gpio_out_core), | 
|  | .gpio_in_core(gpio_in_core), | 
|  | .gpio_mode0_core(gpio_mode0_core), | 
|  | .gpio_mode1_core(gpio_mode1_core), | 
|  | .gpio_outenb_core(gpio_outenb_core), | 
|  | .gpio_inenb_core(gpio_inenb_core), | 
|  | .flash_csb_core(flash_csb_core), | 
|  | .flash_clk_core(flash_clk_core), | 
|  | .flash_csb_oeb_core(flash_csb_oeb_core), | 
|  | .flash_clk_oeb_core(flash_clk_oeb_core), | 
|  | .flash_io0_oeb_core(flash_io0_oeb_core), | 
|  | .flash_io1_oeb_core(flash_io1_oeb_core), | 
|  | .flash_csb_ieb_core(flash_csb_ieb_core), | 
|  | .flash_clk_ieb_core(flash_clk_ieb_core), | 
|  | .flash_io0_ieb_core(flash_io0_ieb_core), | 
|  | .flash_io1_ieb_core(flash_io1_ieb_core), | 
|  | .flash_io0_do_core(flash_io0_do_core), | 
|  | .flash_io1_do_core(flash_io1_do_core), | 
|  | .flash_io0_di_core(flash_io0_di_core), | 
|  | .flash_io1_di_core(flash_io1_di_core), | 
|  | .por(~porb_l), | 
|  | .mprj_io_in(mprj_io_in), | 
|  | .mprj_io_out(mprj_io_out), | 
|  | .mprj_io_oeb(mprj_io_oeb), | 
|  | .mprj_io_hldh_n(mprj_io_hldh_n), | 
|  | .mprj_io_enh(mprj_io_enh), | 
|  | .mprj_io_inp_dis(mprj_io_inp_dis), | 
|  | .mprj_io_ib_mode_sel(mprj_io_ib_mode_sel), | 
|  | .mprj_io_vtrip_sel(mprj_io_vtrip_sel), | 
|  | .mprj_io_slow_sel(mprj_io_slow_sel), | 
|  | .mprj_io_holdover(mprj_io_holdover), | 
|  | .mprj_io_analog_en(mprj_io_analog_en), | 
|  | .mprj_io_analog_sel(mprj_io_analog_sel), | 
|  | .mprj_io_analog_pol(mprj_io_analog_pol), | 
|  | .mprj_io_dm(mprj_io_dm) | 
|  | ); | 
|  |  | 
|  | // SoC core | 
|  | wire caravel_clk; | 
|  | wire caravel_clk2; | 
|  | wire caravel_rstn; | 
|  |  | 
|  | wire [7:0] spi_ro_config_core; | 
|  |  | 
|  | // LA signals | 
|  | wire [127:0] la_output_core;   // From CPU to MPRJ | 
|  | wire [127:0] la_data_in_mprj;  // From CPU to MPRJ | 
|  | wire [127:0] la_data_out_mprj; // From CPU to MPRJ | 
|  | wire [127:0] la_output_mprj;   // From MPRJ to CPU | 
|  | wire [127:0] la_oen;           // LA output enable from CPU perspective (active-low) | 
|  |  | 
|  | // WB MI A (User Project) | 
|  | wire mprj_cyc_o_core; | 
|  | wire mprj_stb_o_core; | 
|  | wire mprj_we_o_core; | 
|  | wire [3:0] mprj_sel_o_core; | 
|  | wire [31:0] mprj_adr_o_core; | 
|  | wire [31:0] mprj_dat_o_core; | 
|  | wire mprj_ack_i_core; | 
|  | wire [31:0] mprj_dat_i_core; | 
|  |  | 
|  | // WB MI B (xbar) | 
|  | wire xbar_cyc_o_core; | 
|  | wire xbar_stb_o_core; | 
|  | wire xbar_we_o_core; | 
|  | wire [3:0] xbar_sel_o_core; | 
|  | wire [31:0] xbar_adr_o_core; | 
|  | wire [31:0] xbar_dat_o_core; | 
|  | wire xbar_ack_i_core; | 
|  | wire [31:0] xbar_dat_i_core; | 
|  |  | 
|  | // Mask revision | 
|  | wire [31:0] mask_rev; | 
|  |  | 
|  | wire 	    mprj_clock; | 
|  | wire 	    mprj_clock2; | 
|  | wire 	    mprj_resetn; | 
|  | wire 	    mprj_cyc_o_user; | 
|  | wire 	    mprj_stb_o_user; | 
|  | wire 	    mprj_we_o_user; | 
|  | wire [3:0]  mprj_sel_o_user; | 
|  | wire [31:0] mprj_adr_o_user; | 
|  | wire [31:0] mprj_dat_o_user; | 
|  | wire	    mprj_vcc_pwrgood; | 
|  | wire	    mprj2_vcc_pwrgood; | 
|  | wire	    mprj_vdd_pwrgood; | 
|  | wire	    mprj2_vdd_pwrgood; | 
|  |  | 
|  | // Storage area | 
|  | // Management R/W interface | 
|  | wire [`MGMT_BLOCKS-1:0] mgmt_ena; | 
|  | wire [`MGMT_BLOCKS-1:0] mgmt_wen; | 
|  | wire [(`MGMT_BLOCKS*4)-1:0] mgmt_wen_mask; | 
|  | wire [7:0] mgmt_addr; | 
|  | wire [31:0] mgmt_wdata; | 
|  | wire [(`MGMT_BLOCKS*32)-1:0] mgmt_rdata; | 
|  | // Management RO interface | 
|  | wire [`USER_BLOCKS-1:0] mgmt_user_ena; | 
|  | wire [7:0] mgmt_user_addr; | 
|  | wire [(`USER_BLOCKS*32)-1:0] mgmt_user_rdata; | 
|  | // User R/W interface | 
|  | wire [`USER_BLOCKS-1:0] user_ena; | 
|  | wire [`USER_BLOCKS-1:0] user_wen; | 
|  | wire [(`USER_BLOCKS*4)-1:0] user_wen_mask; | 
|  | wire [7:0] user_addr; | 
|  | wire [31:0] user_wdata; | 
|  | wire [(`USER_BLOCKS*32)-1:0] user_rdata; | 
|  | // User RO interface | 
|  | wire [`MGMT_BLOCKS-1:0] user_mgmt_ena; | 
|  | wire [7:0] user_mgmt_addr; | 
|  | wire [(`MGMT_BLOCKS*32)-1:0] user_mgmt_rdata; | 
|  |  | 
|  | mgmt_core soc ( | 
|  | `ifdef LVS | 
|  | .vdd(vccd), | 
|  | .vss(vssa), | 
|  | `endif | 
|  | // GPIO (1 pin) | 
|  | .gpio_out_pad(gpio_out_core), | 
|  | .gpio_in_pad(gpio_in_core), | 
|  | .gpio_mode0_pad(gpio_mode0_core), | 
|  | .gpio_mode1_pad(gpio_mode1_core), | 
|  | .gpio_outenb_pad(gpio_outenb_core), | 
|  | .gpio_inenb_pad(gpio_inenb_core), | 
|  | // Primary SPI flash controller | 
|  | .flash_csb(flash_csb_core), | 
|  | .flash_clk(flash_clk_core), | 
|  | .flash_csb_oeb(flash_csb_oeb_core), | 
|  | .flash_clk_oeb(flash_clk_oeb_core), | 
|  | .flash_io0_oeb(flash_io0_oeb_core), | 
|  | .flash_io1_oeb(flash_io1_oeb_core), | 
|  | .flash_csb_ieb(flash_csb_ieb_core), | 
|  | .flash_clk_ieb(flash_clk_ieb_core), | 
|  | .flash_io0_ieb(flash_io0_ieb_core), | 
|  | .flash_io1_ieb(flash_io1_ieb_core), | 
|  | .flash_io0_do(flash_io0_do_core), | 
|  | .flash_io1_do(flash_io1_do_core), | 
|  | .flash_io0_di(flash_io0_di_core), | 
|  | .flash_io1_di(flash_io1_di_core), | 
|  | // Master Reset | 
|  | .resetb(rstb_l), | 
|  | .porb(porb_l), | 
|  | // Clocks and reset | 
|  | .clock(clock_core), | 
|  | .core_clk(caravel_clk), | 
|  | .user_clk(caravel_clk2), | 
|  | .core_rstn(caravel_rstn), | 
|  | // Logic Analyzer | 
|  | .la_input(la_data_out_mprj), | 
|  | .la_output(la_output_core), | 
|  | .la_oen(la_oen), | 
|  | // User Project IO Control | 
|  | .mprj_vcc_pwrgood(mprj_vcc_pwrgood), | 
|  | .mprj2_vcc_pwrgood(mprj2_vcc_pwrgood), | 
|  | .mprj_vdd_pwrgood(mprj_vdd_pwrgood), | 
|  | .mprj2_vdd_pwrgood(mprj2_vdd_pwrgood), | 
|  | .mprj_io_loader_resetn(mprj_io_loader_resetn), | 
|  | .mprj_io_loader_clock(mprj_io_loader_clock), | 
|  | .mprj_io_loader_data(mprj_io_loader_data), | 
|  | .mgmt_in_data(mgmt_io_in), | 
|  | .mgmt_out_data({mgmt_io_in[(`MPRJ_IO_PADS-1):2], mgmt_io_nc2}), | 
|  | .pwr_ctrl_out(pwr_ctrl_out), | 
|  | .sdo_out(sdo_out), | 
|  | .sdo_outenb(sdo_outenb), | 
|  | .jtag_out(jtag_out), | 
|  | .jtag_outenb(jtag_outenb), | 
|  | // User Project Slave ports (WB MI A) | 
|  | .mprj_cyc_o(mprj_cyc_o_core), | 
|  | .mprj_stb_o(mprj_stb_o_core), | 
|  | .mprj_we_o(mprj_we_o_core), | 
|  | .mprj_sel_o(mprj_sel_o_core), | 
|  | .mprj_adr_o(mprj_adr_o_core), | 
|  | .mprj_dat_o(mprj_dat_o_core), | 
|  | .mprj_ack_i(mprj_ack_i_core), | 
|  | .mprj_dat_i(mprj_dat_i_core), | 
|  | // mask data | 
|  | .mask_rev(mask_rev), | 
|  | // MGMT area R/W interface for mgmt RAM | 
|  | .mgmt_ena(mgmt_ena), | 
|  | .mgmt_wen_mask(mgmt_wen_mask), | 
|  | .mgmt_wen(mgmt_wen), | 
|  | .mgmt_addr(mgmt_addr), | 
|  | .mgmt_wdata(mgmt_wdata), | 
|  | .mgmt_rdata(mgmt_rdata), | 
|  | // MGMT area RO interface for user RAM | 
|  | .user_ena(mgmt_user_ena), | 
|  | .user_addr(mgmt_user_addr), | 
|  | .user_rdata(mgmt_user_rdata) | 
|  | ); | 
|  |  | 
|  | /* Clock and reset to user space are passed through a tristate	*/ | 
|  | /* buffer like the above, but since they are intended to be	*/ | 
|  | /* always active, connect the enable to the logic-1 output from	*/ | 
|  | /* the vccd1 domain.						*/ | 
|  |  | 
|  | mgmt_protect mgmt_buffers ( | 
|  | .vccd(vccd), | 
|  | .vssd(vssd), | 
|  | .vccd1(vccd1), | 
|  | .vssd1(vssd1), | 
|  | .vdda1(vdda1), | 
|  | .vssa1(vssa1), | 
|  | .vdda2(vdda2), | 
|  | .vssa2(vssa2), | 
|  |  | 
|  | .caravel_clk(caravel_clk), | 
|  | .caravel_clk2(caravel_clk2), | 
|  | .caravel_rstn(caravel_rstn), | 
|  | .mprj_cyc_o_core(mprj_cyc_o_core), | 
|  | .mprj_stb_o_core(mprj_stb_o_core), | 
|  | .mprj_we_o_core(mprj_we_o_core), | 
|  | .mprj_sel_o_core(mprj_sel_o_core), | 
|  | .mprj_adr_o_core(mprj_adr_o_core), | 
|  | .mprj_dat_o_core(mprj_dat_o_core), | 
|  | .la_output_core(la_output_core), | 
|  | .la_oen(la_oen), | 
|  |  | 
|  | .user_clock(mprj_clock), | 
|  | .user_clock2(mprj_clock2), | 
|  | .user_resetn(mprj_resetn), | 
|  | .mprj_cyc_o_user(mprj_cyc_o_user), | 
|  | .mprj_stb_o_user(mprj_stb_o_user), | 
|  | .mprj_we_o_user(mprj_we_o_user), | 
|  | .mprj_sel_o_user(mprj_sel_o_user), | 
|  | .mprj_adr_o_user(mprj_adr_o_user), | 
|  | .mprj_dat_o_user(mprj_dat_o_user), | 
|  | .la_data_in_mprj(la_data_in_mprj), | 
|  | .user1_vcc_powergood(mprj_vcc_pwrgood), | 
|  | .user2_vcc_powergood(mprj2_vcc_pwrgood), | 
|  | .user1_vdd_powergood(mprj_vdd_pwrgood), | 
|  | .user2_vdd_powergood(mprj2_vdd_pwrgood) | 
|  | ); | 
|  |  | 
|  |  | 
|  | /*----------------------------------------------*/ | 
|  | /* Wrapper module around the user project 	*/ | 
|  | /*----------------------------------------------*/ | 
|  |  | 
|  | user_project_wrapper mprj ( | 
|  | .vdda1(vdda1),	// User area 1 3.3V power | 
|  | .vdda2(vdda2),	// User area 2 3.3V power | 
|  | .vssa1(vssa1),	// User area 1 analog ground | 
|  | .vssa2(vssa2),	// User area 2 analog ground | 
|  | .vccd1(vccd1),	// User area 1 1.8V power | 
|  | .vccd2(vccd2),	// User area 2 1.8V power | 
|  | .vssd1(vssd1),	// User area 1 digital ground | 
|  | .vssd2(vssd2),	// User area 2 digital ground | 
|  |  | 
|  | .wb_clk_i(mprj_clock), | 
|  | .wb_rst_i(!mprj_resetn), | 
|  | // MGMT SoC Wishbone Slave | 
|  | .wbs_cyc_i(mprj_cyc_o_user), | 
|  | .wbs_stb_i(mprj_stb_o_user), | 
|  | .wbs_we_i(mprj_we_o_user), | 
|  | .wbs_sel_i(mprj_sel_o_user), | 
|  | .wbs_adr_i(mprj_adr_o_user), | 
|  | .wbs_dat_i(mprj_dat_o_user), | 
|  | .wbs_ack_o(mprj_ack_i_core), | 
|  | .wbs_dat_o(mprj_dat_i_core), | 
|  | // Logic Analyzer | 
|  | .la_data_in(la_data_in_mprj), | 
|  | .la_data_out(la_data_out_mprj), | 
|  | .la_oen (la_oen), | 
|  | // IO Pads | 
|  | .io_in (user_io_in), | 
|  | .io_out(user_io_out), | 
|  | .io_oeb(user_io_oeb), | 
|  | // Independent clock | 
|  | .user_clock2(mprj_clock2) | 
|  | ); | 
|  |  | 
|  | /*--------------------------------------*/ | 
|  | /* End user project instantiation	*/ | 
|  | /*--------------------------------------*/ | 
|  |  | 
|  | wire [`MPRJ_IO_PADS-1:0] gpio_serial_link_shifted; | 
|  |  | 
|  | assign gpio_serial_link_shifted = {gpio_serial_link[`MPRJ_IO_PADS-2:0], mprj_io_loader_data}; | 
|  |  | 
|  | // Each control block sits next to an I/O pad in the user area. | 
|  | // It gets input through a serial chain from the previous control | 
|  | // block and passes it to the next control block.  Due to the nature | 
|  | // of the shift register, bits are presented in reverse, as the first | 
|  | // bit in ends up as the last bit of the last I/O pad control block. | 
|  |  | 
|  | // There are two types of block;  the first two are configured to be | 
|  | // full bidirectional under control of the management Soc (JTAG and | 
|  | // SDO).  The rest are configured to be default (input). | 
|  |  | 
|  | gpio_control_block #( | 
|  | .DM_INIT(3'b110),	// Mode = output, strong up/down | 
|  | .OENB_INIT(1'b1)	// Enable output signaling from wire | 
|  | ) gpio_control_bidir [1:0] ( | 
|  | `ifdef LVS | 
|  | inout vccd, | 
|  | inout vssd, | 
|  | inout vccd1, | 
|  | inout vssd1, | 
|  | `endif | 
|  |  | 
|  | // Management Soc-facing signals | 
|  |  | 
|  | .resetn(mprj_io_loader_resetn), | 
|  | .serial_clock(mprj_io_loader_clock), | 
|  |  | 
|  | .mgmt_gpio_in(mgmt_io_in[1:0]), | 
|  | .mgmt_gpio_out({sdo_out, jtag_out}), | 
|  | .mgmt_gpio_oeb({sdo_outenb, jtag_outenb}), | 
|  |  | 
|  | // Serial data chain for pad configuration | 
|  | .serial_data_in(gpio_serial_link_shifted[1:0]), | 
|  | .serial_data_out(gpio_serial_link[1:0]), | 
|  |  | 
|  | // User-facing signals | 
|  | .user_gpio_out(user_io_out[1:0]), | 
|  | .user_gpio_oeb(user_io_oeb[1:0]), | 
|  | .user_gpio_in(user_io_in[1:0]), | 
|  |  | 
|  | // Pad-facing signals (Pad GPIOv2) | 
|  | .pad_gpio_inenb(mprj_io_inp_dis[1:0]), | 
|  | .pad_gpio_ib_mode_sel(mprj_io_ib_mode_sel[1:0]), | 
|  | .pad_gpio_vtrip_sel(mprj_io_vtrip_sel[1:0]), | 
|  | .pad_gpio_slow_sel(mprj_io_slow_sel[1:0]), | 
|  | .pad_gpio_holdover(mprj_io_holdover[1:0]), | 
|  | .pad_gpio_ana_en(mprj_io_analog_en[1:0]), | 
|  | .pad_gpio_ana_sel(mprj_io_analog_sel[1:0]), | 
|  | .pad_gpio_ana_pol(mprj_io_analog_pol[1:0]), | 
|  | .pad_gpio_dm(mprj_io_dm[5:0]), | 
|  | .pad_gpio_outenb(mprj_io_oeb[1:0]), | 
|  | .pad_gpio_out(mprj_io_out[1:0]), | 
|  | .pad_gpio_in(mprj_io_in[1:0]) | 
|  | ); | 
|  |  | 
|  | gpio_control_block gpio_control_in [`MPRJ_IO_PADS-1:2] ( | 
|  | `ifdef LVS | 
|  | inout vccd, | 
|  | inout vssd, | 
|  | inout vccd1, | 
|  | inout vssd1, | 
|  | `endif | 
|  |  | 
|  | // Management Soc-facing signals | 
|  |  | 
|  | .resetn(mprj_io_loader_resetn), | 
|  | .serial_clock(mprj_io_loader_clock), | 
|  |  | 
|  | .mgmt_gpio_in(mgmt_io_in[(`MPRJ_IO_PADS-1):2]), | 
|  | .mgmt_gpio_out(mgmt_io_in[(`MPRJ_IO_PADS-1):2]), | 
|  | .mgmt_gpio_oeb(1'b1), | 
|  |  | 
|  | // Serial data chain for pad configuration | 
|  | .serial_data_in(gpio_serial_link_shifted[(`MPRJ_IO_PADS-1):2]), | 
|  | .serial_data_out(gpio_serial_link[(`MPRJ_IO_PADS-1):2]), | 
|  |  | 
|  | // User-facing signals | 
|  | .user_gpio_out(user_io_out[(`MPRJ_IO_PADS-1):2]), | 
|  | .user_gpio_oeb(user_io_oeb[(`MPRJ_IO_PADS-1):2]), | 
|  | .user_gpio_in(user_io_in[(`MPRJ_IO_PADS-1):2]), | 
|  |  | 
|  | // Pad-facing signals (Pad GPIOv2) | 
|  | .pad_gpio_inenb(mprj_io_inp_dis[(`MPRJ_IO_PADS-1):2]), | 
|  | .pad_gpio_ib_mode_sel(mprj_io_ib_mode_sel[(`MPRJ_IO_PADS-1):2]), | 
|  | .pad_gpio_vtrip_sel(mprj_io_vtrip_sel[(`MPRJ_IO_PADS-1):2]), | 
|  | .pad_gpio_slow_sel(mprj_io_slow_sel[(`MPRJ_IO_PADS-1):2]), | 
|  | .pad_gpio_holdover(mprj_io_holdover[(`MPRJ_IO_PADS-1):2]), | 
|  | .pad_gpio_ana_en(mprj_io_analog_en[(`MPRJ_IO_PADS-1):2]), | 
|  | .pad_gpio_ana_sel(mprj_io_analog_sel[(`MPRJ_IO_PADS-1):2]), | 
|  | .pad_gpio_ana_pol(mprj_io_analog_pol[(`MPRJ_IO_PADS-1):2]), | 
|  | .pad_gpio_dm(mprj_io_dm[(`MPRJ_IO_PADS*3-1):6]), | 
|  | .pad_gpio_outenb(mprj_io_oeb[(`MPRJ_IO_PADS-1):2]), | 
|  | .pad_gpio_out(mprj_io_out[(`MPRJ_IO_PADS-1):2]), | 
|  | .pad_gpio_in(mprj_io_in[(`MPRJ_IO_PADS-1):2]) | 
|  | ); | 
|  |  | 
|  | sky130_fd_sc_hvl__lsbufhv2lv porb_level ( | 
|  | .VPWR(vddio), | 
|  | .VPB(vddio), | 
|  | .LVPWR(vccd), | 
|  | .VNB(vssio), | 
|  | .VGND(vssio), | 
|  | .A(porb_h), | 
|  | .X(porb_l) | 
|  | ); | 
|  |  | 
|  | user_id_programming #( | 
|  | .USER_PROJECT_ID(USER_PROJECT_ID) | 
|  | ) user_id_value ( | 
|  | .vdd1v8(vccd), | 
|  | .vss(vssd), | 
|  | .mask_rev(mask_rev) | 
|  | ); | 
|  |  | 
|  | // Power-on-reset circuit | 
|  | simple_por por ( | 
|  | .vdd3v3(vddio), | 
|  | .vss(vssio), | 
|  | .porb_h(porb_h) | 
|  | ); | 
|  |  | 
|  | // XRES (chip input pin reset) reset level converter | 
|  | sky130_fd_sc_hvl__lsbufhv2lv rstb_level ( | 
|  | .VPWR(vddio), | 
|  | .VPB(vddio), | 
|  | .LVPWR(vccd), | 
|  | .VNB(vssio), | 
|  | .VGND(vssio), | 
|  | .A(rstb_h), | 
|  | .X(rstb_l) | 
|  | ); | 
|  |  | 
|  | // Storage area | 
|  | storage #( | 
|  | .MGMT_BLOCKS(`MGMT_BLOCKS), | 
|  | .USER_BLOCKS(`USER_BLOCKS) | 
|  | ) storage( | 
|  | .mgmt_clk(caravel_clk), | 
|  | .mgmt_ena(mgmt_ena), | 
|  | .mgmt_wen(mgmt_wen), | 
|  | .mgmt_wen_mask(mgmt_wen_mask), | 
|  | .mgmt_addr(mgmt_addr), | 
|  | .mgmt_wdata(mgmt_wdata), | 
|  | .mgmt_rdata(mgmt_rdata), | 
|  | // Management RO interface | 
|  | .mgmt_user_ena(mgmt_user_ena), | 
|  | .mgmt_user_addr(mgmt_user_addr), | 
|  | .mgmt_user_rdata(mgmt_user_rdata), | 
|  |  | 
|  | // User R/W interface | 
|  | .user_clk(caravel_clk2), | 
|  | .user_ena(user_ena), | 
|  | .user_wen(user_wen), | 
|  | .user_wen_mask(user_wen_mask), | 
|  | .user_addr(user_addr), | 
|  | .user_wdata(user_wdata), | 
|  | .user_rdata(user_rdata), | 
|  | // User RO interface | 
|  | .user_mgmt_ena(user_mgmt_ena), | 
|  | .user_mgmt_addr(user_mgmt_addr), | 
|  | .user_mgmt_rdata(user_mgmt_rdata) | 
|  | ); | 
|  |  | 
|  | endmodule |