diff --git a/DOC/source/arch/clb_arch.rst b/DOC/source/arch/clb_arch.rst
index 0119110..415fc26 100644
--- a/DOC/source/arch/clb_arch.rst
+++ b/DOC/source/arch/clb_arch.rst
@@ -14,7 +14,7 @@ Feedback connections between LEs are implemented by the global routing architect
.. _fig_clb_arch:
-.. figure:: ./figures/clb_arch.png
+.. figure:: ./figures/clb_arch.svg
:scale: 20%
:alt: Configurable Logic Block schematic
@@ -32,7 +32,7 @@ As shown in :numref:`fig_fle_arch`, each Logic Element (LE) consists of
.. _fig_fle_arch:
-.. figure:: ./figures/fle_arch.png
+.. figure:: ./figures/fle_arch.svg
:scale: 30%
:alt: Logic element schematic
diff --git a/DOC/source/arch/figures/clb_arch.png b/DOC/source/arch/figures/clb_arch.png
deleted file mode 100644
index 16ac726..0000000
Binary files a/DOC/source/arch/figures/clb_arch.png and /dev/null differ
diff --git a/DOC/source/arch/figures/clb_arch.svg b/DOC/source/arch/figures/clb_arch.svg
new file mode 100644
index 0000000..0795459
--- /dev/null
+++ b/DOC/source/arch/figures/clb_arch.svg
@@ -0,0 +1,662 @@
+
+
+
diff --git a/DOC/source/arch/figures/embedded_io_schematic.png b/DOC/source/arch/figures/embedded_io_schematic.png
deleted file mode 100644
index 261f452..0000000
Binary files a/DOC/source/arch/figures/embedded_io_schematic.png and /dev/null differ
diff --git a/DOC/source/arch/figures/embedded_io_schematic.svg b/DOC/source/arch/figures/embedded_io_schematic.svg
new file mode 100644
index 0000000..75482cb
--- /dev/null
+++ b/DOC/source/arch/figures/embedded_io_schematic.svg
@@ -0,0 +1,253 @@
+
+
+
diff --git a/DOC/source/arch/figures/fabric_scan_chain.png b/DOC/source/arch/figures/fabric_scan_chain.png
deleted file mode 100644
index b8fdae2..0000000
Binary files a/DOC/source/arch/figures/fabric_scan_chain.png and /dev/null differ
diff --git a/DOC/source/arch/figures/fabric_scan_chain.svg b/DOC/source/arch/figures/fabric_scan_chain.svg
new file mode 100644
index 0000000..0bf9cc5
--- /dev/null
+++ b/DOC/source/arch/figures/fabric_scan_chain.svg
@@ -0,0 +1,320 @@
+
+
+
diff --git a/DOC/source/arch/figures/fle_arch.png b/DOC/source/arch/figures/fle_arch.png
deleted file mode 100644
index 3f5eb94..0000000
Binary files a/DOC/source/arch/figures/fle_arch.png and /dev/null differ
diff --git a/DOC/source/arch/figures/fle_arch.svg b/DOC/source/arch/figures/fle_arch.svg
new file mode 100644
index 0000000..0384515
--- /dev/null
+++ b/DOC/source/arch/figures/fle_arch.svg
@@ -0,0 +1,293 @@
+
+
+
diff --git a/DOC/source/arch/figures/fpga_arch.png b/DOC/source/arch/figures/fpga_arch.png
deleted file mode 100644
index 696e536..0000000
Binary files a/DOC/source/arch/figures/fpga_arch.png and /dev/null differ
diff --git a/DOC/source/arch/figures/fpga_arch.svg b/DOC/source/arch/figures/fpga_arch.svg
new file mode 100644
index 0000000..59678b3
--- /dev/null
+++ b/DOC/source/arch/figures/fpga_arch.svg
@@ -0,0 +1,1089 @@
+
+
+
diff --git a/DOC/source/arch/figures/fpga_io_map_logic_analyzer_mode.png b/DOC/source/arch/figures/fpga_io_map_logic_analyzer_mode.png
deleted file mode 100644
index 6b9b770..0000000
Binary files a/DOC/source/arch/figures/fpga_io_map_logic_analyzer_mode.png and /dev/null differ
diff --git a/DOC/source/arch/figures/fpga_io_map_logic_analyzer_mode.svg b/DOC/source/arch/figures/fpga_io_map_logic_analyzer_mode.svg
new file mode 100644
index 0000000..71939ce
--- /dev/null
+++ b/DOC/source/arch/figures/fpga_io_map_logic_analyzer_mode.svg
@@ -0,0 +1,247 @@
+
+
+
diff --git a/DOC/source/arch/figures/fpga_io_map_wishbone_mode.png b/DOC/source/arch/figures/fpga_io_map_wishbone_mode.png
deleted file mode 100644
index 635f25d..0000000
Binary files a/DOC/source/arch/figures/fpga_io_map_wishbone_mode.png and /dev/null differ
diff --git a/DOC/source/arch/figures/fpga_io_map_wishbone_mode.svg b/DOC/source/arch/figures/fpga_io_map_wishbone_mode.svg
new file mode 100644
index 0000000..67f148a
--- /dev/null
+++ b/DOC/source/arch/figures/fpga_io_map_wishbone_mode.svg
@@ -0,0 +1,253 @@
+
+
+
diff --git a/DOC/source/arch/figures/fpga_io_switch.png b/DOC/source/arch/figures/fpga_io_switch.png
deleted file mode 100644
index b686af2..0000000
Binary files a/DOC/source/arch/figures/fpga_io_switch.png and /dev/null differ
diff --git a/DOC/source/arch/figures/fpga_io_switch.svg b/DOC/source/arch/figures/fpga_io_switch.svg
new file mode 100644
index 0000000..c47bc8a
--- /dev/null
+++ b/DOC/source/arch/figures/fpga_io_switch.svg
@@ -0,0 +1,408 @@
+
+
+
diff --git a/DOC/source/arch/fpga_arch.rst b/DOC/source/arch/fpga_arch.rst
index c2bf3b2..c59304e 100644
--- a/DOC/source/arch/fpga_arch.rst
+++ b/DOC/source/arch/fpga_arch.rst
@@ -14,7 +14,7 @@ I/O tiles are placed at the boundary of the FPGA to interface with GPIOs and RIS
.. _fig_fpga_arch:
-.. figure:: ./figures/fpga_arch.png
+.. figure:: ./figures/fpga_arch.svg
:scale: 25%
:alt: Tile-based FPGA architecture
@@ -72,7 +72,7 @@ When `Test_en` signal is active, users can
.. _fig_fabric_scan_chain:
-.. figure:: ./figures/fabric_scan_chain.png
+.. figure:: ./figures/fabric_scan_chain.svg
:scale: 25%
:alt: Built-in scan-chain across FPGA
diff --git a/DOC/source/arch/io_resource.rst b/DOC/source/arch/io_resource.rst
index 394f588..bf73f87 100644
--- a/DOC/source/arch/io_resource.rst
+++ b/DOC/source/arch/io_resource.rst
@@ -20,9 +20,11 @@ Among the 144 I/Os,
.. note:: The connectivity of the 115 internal I/Os can be switched through a GPIO of Caravel SoC. As a result, the FPGA can operate in different modes.
+.. warning:: The internal I/O pins will drive either Wishbone or the logic analyzer, following the same truth table as mode-switch bit in :numref:`fig_fpga_io_switch`.
+
.. _fig_fpga_io_switch:
-.. figure:: ./figures/fpga_io_switch.png
+.. figure:: ./figures/fpga_io_switch.svg
:scale: 20%
:alt: I/O arrangement of FPGA IP
@@ -43,7 +45,7 @@ When the Wishbone interface is enabled, the FPGA can operate as an accelerator f
.. _fig_fpga_io_map_wishbone_mode:
-.. figure:: ./figures/fpga_io_map_wishbone_mode.png
+.. figure:: ./figures/fpga_io_map_wishbone_mode.svg
:scale: 20%
:alt: I/O arrangement of FPGA IP when interfacing wishbone bus
@@ -66,7 +68,7 @@ When the logic analyzer interface is enabled, the FPGA can operate in debug mode
.. _fig_fpga_io_map_logic_analyzer_mode:
-.. figure:: ./figures/fpga_io_map_logic_analyzer_mode.png
+.. figure:: ./figures/fpga_io_map_logic_analyzer_mode.svg
:scale: 20%
:alt: I/O arrangement of FPGA IP when interfacing logic analyzer
@@ -98,7 +100,7 @@ The truth table of the I/O cell is consistent with the GPIO cell of Caravel SoC,
.. _fig_embedded_io_schematic:
-.. figure:: ./figures/embedded_io_schematic.png
+.. figure:: ./figures/embedded_io_schematic.svg
:scale: 30%
:alt: Schematic of embedded I/O cell used in FPGA
diff --git a/HDL/common/caravel_fpga_wrapper_hd.v b/HDL/common/caravel_fpga_wrapper_hd.v
index 2d9d6f3..3e1a9ed 100644
--- a/HDL/common/caravel_fpga_wrapper_hd.v
+++ b/HDL/common/caravel_fpga_wrapper_hd.v
@@ -68,6 +68,12 @@ module fpga_top (
// Switch between wishbone and logic analyzer
wire wb_la_switch;
+ wire wb_la_switch_b;
+
+ // Inverted switch signal to drive tri-state buffers
+ // Use drive strength 8 as we will have 33 output pins which is driven by
+ // the buffers
+ sky130_fd_sc_hd__inv_8 WB_LA_SWITCH_INV (.A(la_wb_switch), .Y(la_wb_switch_b));
// Wire-bond TOP side I/O of FPGA to LEFT-side of Caravel interface
assign gfpga_pad_EMBEDDED_IO_HD_SOC_IN[0] = io_in[24];
@@ -109,7 +115,8 @@ module fpga_top (
sky130_fd_sc_hd__mux2_1 FPGA2SOC_IN_135_MUX (.S(la_wb_switch), .A1(wb_rst_i), .A0(la_data_in[13]), .X(gfpga_pad_EMBEDDED_IO_HD_SOC_IN[135]));
assign la_data_out[13] = gfpga_pad_EMBEDDED_IO_HD_SOC_OUT[135];
assign gfpga_pad_EMBEDDED_IO_HD_SOC_IN[134] = la_data_in[14];
- assign wbs_ack_o = gfpga_pad_EMBEDDED_IO_HD_SOC_OUT[134];
+ sky130_fd_sc_hd__ebufn_4 FPGA2SOC_OUT_134_DEMUX_WB (.TE_B(la_wb_switch_b), .A(gfpga_pad_EMBEDDED_IO_HD_SOC_OUT[134]), .Z(wbs_ack_o));
+ sky130_fd_sc_hd__ebufn_4 FPGA2SOC_OUT_134_DEMUX_LA (.TE_B(la_wb_switch), .A(gfpga_pad_EMBEDDED_IO_HD_SOC_OUT[134]), .Z(la_data_out[14]));
sky130_fd_sc_hd__mux2_1 FPGA2SOC_IN_133_MUX (.S(la_wb_switch), .A1(wbs_cyc_i), .A0(la_data_in[15]), .X(gfpga_pad_EMBEDDED_IO_HD_SOC_IN[133]));
assign la_data_out[15] = gfpga_pad_EMBEDDED_IO_HD_SOC_OUT[133];
sky130_fd_sc_hd__mux2_1 FPGA2SOC_IN_132_MUX (.S(la_wb_switch), .A1(wbs_stb_i), .A0(la_data_in[16]), .X(gfpga_pad_EMBEDDED_IO_HD_SOC_IN[132]));
@@ -253,69 +260,101 @@ module fpga_top (
sky130_fd_sc_hd__mux2_1 FPGA2SOC_IN_63_MUX (.S(la_wb_switch), .A1(wbs_dat_i[31]), .A0(la_data_in[85]), .X(gfpga_pad_EMBEDDED_IO_HD_SOC_IN[63]));
assign la_data_out[85] = gfpga_pad_EMBEDDED_IO_HD_SOC_OUT[63];
assign gfpga_pad_EMBEDDED_IO_HD_SOC_IN[62] = la_data_in[86];
- assign wbs_dat_o[0] = gfpga_pad_EMBEDDED_IO_HD_SOC_OUT[62];
+ sky130_fd_sc_hd__ebufn_4 FPGA2SOC_OUT_62_DEMUX_WB (.TE_B(la_wb_switch_b), .A(gfpga_pad_EMBEDDED_IO_HD_SOC_OUT[62]), .Z(wbs_dat_o[0]));
+ sky130_fd_sc_hd__ebufn_4 FPGA2SOC_OUT_62_DEMUX_LA (.TE_B(la_wb_switch), .A(gfpga_pad_EMBEDDED_IO_HD_SOC_OUT[62]), .Z(la_data_out[86]));
assign gfpga_pad_EMBEDDED_IO_HD_SOC_IN[61] = la_data_in[87];
- assign wbs_dat_o[1] = gfpga_pad_EMBEDDED_IO_HD_SOC_OUT[61];
+ sky130_fd_sc_hd__ebufn_4 FPGA2SOC_OUT_61_DEMUX_WB (.TE_B(la_wb_switch_b), .A(gfpga_pad_EMBEDDED_IO_HD_SOC_OUT[61]), .Z(wbs_dat_o[1]));
+ sky130_fd_sc_hd__ebufn_4 FPGA2SOC_OUT_61_DEMUX_LA (.TE_B(la_wb_switch), .A(gfpga_pad_EMBEDDED_IO_HD_SOC_OUT[61]), .Z(la_data_out[87]));
assign gfpga_pad_EMBEDDED_IO_HD_SOC_IN[60] = la_data_in[88];
- assign wbs_dat_o[2] = gfpga_pad_EMBEDDED_IO_HD_SOC_OUT[60];
+ sky130_fd_sc_hd__ebufn_4 FPGA2SOC_OUT_60_DEMUX_WB (.TE_B(la_wb_switch_b), .A(gfpga_pad_EMBEDDED_IO_HD_SOC_OUT[60]), .Z(wbs_dat_o[2]));
+ sky130_fd_sc_hd__ebufn_4 FPGA2SOC_OUT_60_DEMUX_LA (.TE_B(la_wb_switch), .A(gfpga_pad_EMBEDDED_IO_HD_SOC_OUT[60]), .Z(la_data_out[88]));
assign gfpga_pad_EMBEDDED_IO_HD_SOC_IN[59] = la_data_in[89];
- assign wbs_dat_o[3] = gfpga_pad_EMBEDDED_IO_HD_SOC_OUT[59];
+ sky130_fd_sc_hd__ebufn_4 FPGA2SOC_OUT_59_DEMUX_WB (.TE_B(la_wb_switch_b), .A(gfpga_pad_EMBEDDED_IO_HD_SOC_OUT[59]), .Z(wbs_dat_o[3]));
+ sky130_fd_sc_hd__ebufn_4 FPGA2SOC_OUT_59_DEMUX_LA (.TE_B(la_wb_switch), .A(gfpga_pad_EMBEDDED_IO_HD_SOC_OUT[59]), .Z(la_data_out[89]));
assign gfpga_pad_EMBEDDED_IO_HD_SOC_IN[58] = la_data_in[90];
- assign wbs_dat_o[4] = gfpga_pad_EMBEDDED_IO_HD_SOC_OUT[58];
+ sky130_fd_sc_hd__ebufn_4 FPGA2SOC_OUT_58_DEMUX_WB (.TE_B(la_wb_switch_b), .A(gfpga_pad_EMBEDDED_IO_HD_SOC_OUT[58]), .Z(wbs_dat_o[4]));
+ sky130_fd_sc_hd__ebufn_4 FPGA2SOC_OUT_58_DEMUX_LA (.TE_B(la_wb_switch), .A(gfpga_pad_EMBEDDED_IO_HD_SOC_OUT[58]), .Z(la_data_out[90]));
assign gfpga_pad_EMBEDDED_IO_HD_SOC_IN[57] = la_data_in[91];
- assign wbs_dat_o[5] = gfpga_pad_EMBEDDED_IO_HD_SOC_OUT[57];
+ sky130_fd_sc_hd__ebufn_4 FPGA2SOC_OUT_57_DEMUX_WB (.TE_B(la_wb_switch_b), .A(gfpga_pad_EMBEDDED_IO_HD_SOC_OUT[57]), .Z(wbs_dat_o[5]));
+ sky130_fd_sc_hd__ebufn_4 FPGA2SOC_OUT_57_DEMUX_LA (.TE_B(la_wb_switch), .A(gfpga_pad_EMBEDDED_IO_HD_SOC_OUT[57]), .Z(la_data_out[91]));
assign gfpga_pad_EMBEDDED_IO_HD_SOC_IN[56] = la_data_in[92];
- assign wbs_dat_o[6] = gfpga_pad_EMBEDDED_IO_HD_SOC_OUT[56];
+ sky130_fd_sc_hd__ebufn_4 FPGA2SOC_OUT_56_DEMUX_WB (.TE_B(la_wb_switch_b), .A(gfpga_pad_EMBEDDED_IO_HD_SOC_OUT[56]), .Z(wbs_dat_o[6]));
+ sky130_fd_sc_hd__ebufn_4 FPGA2SOC_OUT_56_DEMUX_LA (.TE_B(la_wb_switch), .A(gfpga_pad_EMBEDDED_IO_HD_SOC_OUT[56]), .Z(la_data_out[92]));
assign gfpga_pad_EMBEDDED_IO_HD_SOC_IN[55] = la_data_in[93];
- assign wbs_dat_o[7] = gfpga_pad_EMBEDDED_IO_HD_SOC_OUT[55];
+ sky130_fd_sc_hd__ebufn_4 FPGA2SOC_OUT_55_DEMUX_WB (.TE_B(la_wb_switch_b), .A(gfpga_pad_EMBEDDED_IO_HD_SOC_OUT[55]), .Z(wbs_dat_o[7]));
+ sky130_fd_sc_hd__ebufn_4 FPGA2SOC_OUT_55_DEMUX_LA (.TE_B(la_wb_switch), .A(gfpga_pad_EMBEDDED_IO_HD_SOC_OUT[55]), .Z(la_data_out[93]));
assign gfpga_pad_EMBEDDED_IO_HD_SOC_IN[54] = la_data_in[94];
- assign wbs_dat_o[8] = gfpga_pad_EMBEDDED_IO_HD_SOC_OUT[54];
+ sky130_fd_sc_hd__ebufn_4 FPGA2SOC_OUT_54_DEMUX_WB (.TE_B(la_wb_switch_b), .A(gfpga_pad_EMBEDDED_IO_HD_SOC_OUT[54]), .Z(wbs_dat_o[8]));
+ sky130_fd_sc_hd__ebufn_4 FPGA2SOC_OUT_54_DEMUX_LA (.TE_B(la_wb_switch), .A(gfpga_pad_EMBEDDED_IO_HD_SOC_OUT[54]), .Z(la_data_out[94]));
assign gfpga_pad_EMBEDDED_IO_HD_SOC_IN[53] = la_data_in[95];
- assign wbs_dat_o[9] = gfpga_pad_EMBEDDED_IO_HD_SOC_OUT[53];
+ sky130_fd_sc_hd__ebufn_4 FPGA2SOC_OUT_53_DEMUX_WB (.TE_B(la_wb_switch_b), .A(gfpga_pad_EMBEDDED_IO_HD_SOC_OUT[53]), .Z(wbs_dat_o[9]));
+ sky130_fd_sc_hd__ebufn_4 FPGA2SOC_OUT_53_DEMUX_LA (.TE_B(la_wb_switch), .A(gfpga_pad_EMBEDDED_IO_HD_SOC_OUT[53]), .Z(la_data_out[95]));
assign gfpga_pad_EMBEDDED_IO_HD_SOC_IN[52] = la_data_in[96];
- assign wbs_dat_o[10] = gfpga_pad_EMBEDDED_IO_HD_SOC_OUT[52];
+ sky130_fd_sc_hd__ebufn_4 FPGA2SOC_OUT_52_DEMUX_WB (.TE_B(la_wb_switch_b), .A(gfpga_pad_EMBEDDED_IO_HD_SOC_OUT[52]), .Z(wbs_dat_o[10]));
+ sky130_fd_sc_hd__ebufn_4 FPGA2SOC_OUT_52_DEMUX_LA (.TE_B(la_wb_switch), .A(gfpga_pad_EMBEDDED_IO_HD_SOC_OUT[52]), .Z(la_data_out[96]));
assign gfpga_pad_EMBEDDED_IO_HD_SOC_IN[51] = la_data_in[97];
- assign wbs_dat_o[11] = gfpga_pad_EMBEDDED_IO_HD_SOC_OUT[51];
+ sky130_fd_sc_hd__ebufn_4 FPGA2SOC_OUT_51_DEMUX_WB (.TE_B(la_wb_switch_b), .A(gfpga_pad_EMBEDDED_IO_HD_SOC_OUT[51]), .Z(wbs_dat_o[11]));
+ sky130_fd_sc_hd__ebufn_4 FPGA2SOC_OUT_51_DEMUX_LA (.TE_B(la_wb_switch), .A(gfpga_pad_EMBEDDED_IO_HD_SOC_OUT[51]), .Z(la_data_out[97]));
assign gfpga_pad_EMBEDDED_IO_HD_SOC_IN[50] = la_data_in[98];
- assign wbs_dat_o[12] = gfpga_pad_EMBEDDED_IO_HD_SOC_OUT[50];
+ sky130_fd_sc_hd__ebufn_4 FPGA2SOC_OUT_50_DEMUX_WB (.TE_B(la_wb_switch_b), .A(gfpga_pad_EMBEDDED_IO_HD_SOC_OUT[50]), .Z(wbs_dat_o[12]));
+ sky130_fd_sc_hd__ebufn_4 FPGA2SOC_OUT_50_DEMUX_LA (.TE_B(la_wb_switch), .A(gfpga_pad_EMBEDDED_IO_HD_SOC_OUT[50]), .Z(la_data_out[98]));
assign gfpga_pad_EMBEDDED_IO_HD_SOC_IN[49] = la_data_in[99];
- assign wbs_dat_o[13] = gfpga_pad_EMBEDDED_IO_HD_SOC_OUT[49];
+ sky130_fd_sc_hd__ebufn_4 FPGA2SOC_OUT_49_DEMUX_WB (.TE_B(la_wb_switch_b), .A(gfpga_pad_EMBEDDED_IO_HD_SOC_OUT[49]), .Z(wbs_dat_o[13]));
+ sky130_fd_sc_hd__ebufn_4 FPGA2SOC_OUT_49_DEMUX_LA (.TE_B(la_wb_switch), .A(gfpga_pad_EMBEDDED_IO_HD_SOC_OUT[49]), .Z(la_data_out[99]));
assign gfpga_pad_EMBEDDED_IO_HD_SOC_IN[48] = la_data_in[100];
- assign wbs_dat_o[14] = gfpga_pad_EMBEDDED_IO_HD_SOC_OUT[48];
+ sky130_fd_sc_hd__ebufn_4 FPGA2SOC_OUT_48_DEMUX_WB (.TE_B(la_wb_switch_b), .A(gfpga_pad_EMBEDDED_IO_HD_SOC_OUT[48]), .Z(wbs_dat_o[14]));
+ sky130_fd_sc_hd__ebufn_4 FPGA2SOC_OUT_48_DEMUX_LA (.TE_B(la_wb_switch), .A(gfpga_pad_EMBEDDED_IO_HD_SOC_OUT[48]), .Z(la_data_out[100]));
assign gfpga_pad_EMBEDDED_IO_HD_SOC_IN[47] = la_data_in[101];
- assign wbs_dat_o[15] = gfpga_pad_EMBEDDED_IO_HD_SOC_OUT[47];
+ sky130_fd_sc_hd__ebufn_4 FPGA2SOC_OUT_47_DEMUX_WB (.TE_B(la_wb_switch_b), .A(gfpga_pad_EMBEDDED_IO_HD_SOC_OUT[47]), .Z(wbs_dat_o[15]));
+ sky130_fd_sc_hd__ebufn_4 FPGA2SOC_OUT_47_DEMUX_LA (.TE_B(la_wb_switch), .A(gfpga_pad_EMBEDDED_IO_HD_SOC_OUT[47]), .Z(la_data_out[101]));
assign gfpga_pad_EMBEDDED_IO_HD_SOC_IN[46] = la_data_in[102];
- assign wbs_dat_o[16] = gfpga_pad_EMBEDDED_IO_HD_SOC_OUT[46];
+ sky130_fd_sc_hd__ebufn_4 FPGA2SOC_OUT_46_DEMUX_WB (.TE_B(la_wb_switch_b), .A(gfpga_pad_EMBEDDED_IO_HD_SOC_OUT[46]), .Z(wbs_dat_o[16]));
+ sky130_fd_sc_hd__ebufn_4 FPGA2SOC_OUT_46_DEMUX_LA (.TE_B(la_wb_switch), .A(gfpga_pad_EMBEDDED_IO_HD_SOC_OUT[46]), .Z(la_data_out[102]));
assign gfpga_pad_EMBEDDED_IO_HD_SOC_IN[45] = la_data_in[103];
- assign wbs_dat_o[17] = gfpga_pad_EMBEDDED_IO_HD_SOC_OUT[45];
+ sky130_fd_sc_hd__ebufn_4 FPGA2SOC_OUT_45_DEMUX_WB (.TE_B(la_wb_switch_b), .A(gfpga_pad_EMBEDDED_IO_HD_SOC_OUT[45]), .Z(wbs_dat_o[17]));
+ sky130_fd_sc_hd__ebufn_4 FPGA2SOC_OUT_45_DEMUX_LA (.TE_B(la_wb_switch), .A(gfpga_pad_EMBEDDED_IO_HD_SOC_OUT[45]), .Z(la_data_out[103]));
assign gfpga_pad_EMBEDDED_IO_HD_SOC_IN[44] = la_data_in[104];
- assign wbs_dat_o[18] = gfpga_pad_EMBEDDED_IO_HD_SOC_OUT[44];
+ sky130_fd_sc_hd__ebufn_4 FPGA2SOC_OUT_44_DEMUX_WB (.TE_B(la_wb_switch_b), .A(gfpga_pad_EMBEDDED_IO_HD_SOC_OUT[44]), .Z(wbs_dat_o[18]));
+ sky130_fd_sc_hd__ebufn_4 FPGA2SOC_OUT_44_DEMUX_LA (.TE_B(la_wb_switch), .A(gfpga_pad_EMBEDDED_IO_HD_SOC_OUT[44]), .Z(la_data_out[104]));
assign gfpga_pad_EMBEDDED_IO_HD_SOC_IN[43] = la_data_in[105];
- assign wbs_dat_o[19] = gfpga_pad_EMBEDDED_IO_HD_SOC_OUT[43];
+ sky130_fd_sc_hd__ebufn_4 FPGA2SOC_OUT_43_DEMUX_WB (.TE_B(la_wb_switch_b), .A(gfpga_pad_EMBEDDED_IO_HD_SOC_OUT[43]), .Z(wbs_dat_o[19]));
+ sky130_fd_sc_hd__ebufn_4 FPGA2SOC_OUT_43_DEMUX_LA (.TE_B(la_wb_switch), .A(gfpga_pad_EMBEDDED_IO_HD_SOC_OUT[43]), .Z(la_data_out[105]));
assign gfpga_pad_EMBEDDED_IO_HD_SOC_IN[42] = la_data_in[106];
- assign wbs_dat_o[20] = gfpga_pad_EMBEDDED_IO_HD_SOC_OUT[42];
+ sky130_fd_sc_hd__ebufn_4 FPGA2SOC_OUT_42_DEMUX_WB (.TE_B(la_wb_switch_b), .A(gfpga_pad_EMBEDDED_IO_HD_SOC_OUT[42]), .Z(wbs_dat_o[20]));
+ sky130_fd_sc_hd__ebufn_4 FPGA2SOC_OUT_42_DEMUX_LA (.TE_B(la_wb_switch), .A(gfpga_pad_EMBEDDED_IO_HD_SOC_OUT[42]), .Z(la_data_out[106]));
assign gfpga_pad_EMBEDDED_IO_HD_SOC_IN[41] = la_data_in[107];
- assign wbs_dat_o[21] = gfpga_pad_EMBEDDED_IO_HD_SOC_OUT[41];
+ sky130_fd_sc_hd__ebufn_4 FPGA2SOC_OUT_41_DEMUX_WB (.TE_B(la_wb_switch_b), .A(gfpga_pad_EMBEDDED_IO_HD_SOC_OUT[41]), .Z(wbs_dat_o[21]));
+ sky130_fd_sc_hd__ebufn_4 FPGA2SOC_OUT_41_DEMUX_LA (.TE_B(la_wb_switch), .A(gfpga_pad_EMBEDDED_IO_HD_SOC_OUT[41]), .Z(la_data_out[107]));
assign gfpga_pad_EMBEDDED_IO_HD_SOC_IN[40] = la_data_in[108];
- assign wbs_dat_o[22] = gfpga_pad_EMBEDDED_IO_HD_SOC_OUT[40];
+ sky130_fd_sc_hd__ebufn_4 FPGA2SOC_OUT_40_DEMUX_WB (.TE_B(la_wb_switch_b), .A(gfpga_pad_EMBEDDED_IO_HD_SOC_OUT[40]), .Z(wbs_dat_o[22]));
+ sky130_fd_sc_hd__ebufn_4 FPGA2SOC_OUT_40_DEMUX_LA (.TE_B(la_wb_switch), .A(gfpga_pad_EMBEDDED_IO_HD_SOC_OUT[40]), .Z(la_data_out[108]));
assign gfpga_pad_EMBEDDED_IO_HD_SOC_IN[39] = la_data_in[109];
- assign wbs_dat_o[23] = gfpga_pad_EMBEDDED_IO_HD_SOC_OUT[39];
+ sky130_fd_sc_hd__ebufn_4 FPGA2SOC_OUT_39_DEMUX_WB (.TE_B(la_wb_switch_b), .A(gfpga_pad_EMBEDDED_IO_HD_SOC_OUT[39]), .Z(wbs_dat_o[23]));
+ sky130_fd_sc_hd__ebufn_4 FPGA2SOC_OUT_39_DEMUX_LA (.TE_B(la_wb_switch), .A(gfpga_pad_EMBEDDED_IO_HD_SOC_OUT[39]), .Z(la_data_out[109]));
assign gfpga_pad_EMBEDDED_IO_HD_SOC_IN[38] = la_data_in[110];
- assign wbs_dat_o[24] = gfpga_pad_EMBEDDED_IO_HD_SOC_OUT[38];
+ sky130_fd_sc_hd__ebufn_4 FPGA2SOC_OUT_38_DEMUX_WB (.TE_B(la_wb_switch_b), .A(gfpga_pad_EMBEDDED_IO_HD_SOC_OUT[38]), .Z(wbs_dat_o[24]));
+ sky130_fd_sc_hd__ebufn_4 FPGA2SOC_OUT_38_DEMUX_LA (.TE_B(la_wb_switch), .A(gfpga_pad_EMBEDDED_IO_HD_SOC_OUT[38]), .Z(la_data_out[110]));
assign gfpga_pad_EMBEDDED_IO_HD_SOC_IN[37] = la_data_in[111];
- assign wbs_dat_o[25] = gfpga_pad_EMBEDDED_IO_HD_SOC_OUT[37];
+ sky130_fd_sc_hd__ebufn_4 FPGA2SOC_OUT_37_DEMUX_WB (.TE_B(la_wb_switch_b), .A(gfpga_pad_EMBEDDED_IO_HD_SOC_OUT[37]), .Z(wbs_dat_o[25]));
+ sky130_fd_sc_hd__ebufn_4 FPGA2SOC_OUT_37_DEMUX_LA (.TE_B(la_wb_switch), .A(gfpga_pad_EMBEDDED_IO_HD_SOC_OUT[37]), .Z(la_data_out[111]));
assign gfpga_pad_EMBEDDED_IO_HD_SOC_IN[36] = la_data_in[112];
- assign wbs_dat_o[26] = gfpga_pad_EMBEDDED_IO_HD_SOC_OUT[36];
+ sky130_fd_sc_hd__ebufn_4 FPGA2SOC_OUT_36_DEMUX_WB (.TE_B(la_wb_switch_b), .A(gfpga_pad_EMBEDDED_IO_HD_SOC_OUT[36]), .Z(wbs_dat_o[26]));
+ sky130_fd_sc_hd__ebufn_4 FPGA2SOC_OUT_36_DEMUX_LA (.TE_B(la_wb_switch), .A(gfpga_pad_EMBEDDED_IO_HD_SOC_OUT[36]), .Z(la_data_out[112]));
assign gfpga_pad_EMBEDDED_IO_HD_SOC_IN[35] = la_data_in[113];
- assign wbs_dat_o[27] = gfpga_pad_EMBEDDED_IO_HD_SOC_OUT[35];
+ sky130_fd_sc_hd__ebufn_4 FPGA2SOC_OUT_35_DEMUX_WB (.TE_B(la_wb_switch_b), .A(gfpga_pad_EMBEDDED_IO_HD_SOC_OUT[35]), .Z(wbs_dat_o[27]));
+ sky130_fd_sc_hd__ebufn_4 FPGA2SOC_OUT_35_DEMUX_LA (.TE_B(la_wb_switch), .A(gfpga_pad_EMBEDDED_IO_HD_SOC_OUT[35]), .Z(la_data_out[113]));
assign gfpga_pad_EMBEDDED_IO_HD_SOC_IN[34] = la_data_in[114];
- assign wbs_dat_o[28] = gfpga_pad_EMBEDDED_IO_HD_SOC_OUT[34];
+ sky130_fd_sc_hd__ebufn_4 FPGA2SOC_OUT_34_DEMUX_WB (.TE_B(la_wb_switch_b), .A(gfpga_pad_EMBEDDED_IO_HD_SOC_OUT[34]), .Z(wbs_dat_o[28]));
+ sky130_fd_sc_hd__ebufn_4 FPGA2SOC_OUT_34_DEMUX_LA (.TE_B(la_wb_switch), .A(gfpga_pad_EMBEDDED_IO_HD_SOC_OUT[34]), .Z(la_data_out[114]));
assign gfpga_pad_EMBEDDED_IO_HD_SOC_IN[33] = la_data_in[115];
- assign wbs_dat_o[29] = gfpga_pad_EMBEDDED_IO_HD_SOC_OUT[33];
+ sky130_fd_sc_hd__ebufn_4 FPGA2SOC_OUT_33_DEMUX_WB (.TE_B(la_wb_switch_b), .A(gfpga_pad_EMBEDDED_IO_HD_SOC_OUT[33]), .Z(wbs_dat_o[29]));
+ sky130_fd_sc_hd__ebufn_4 FPGA2SOC_OUT_33_DEMUX_LA (.TE_B(la_wb_switch), .A(gfpga_pad_EMBEDDED_IO_HD_SOC_OUT[33]), .Z(la_data_out[115]));
assign gfpga_pad_EMBEDDED_IO_HD_SOC_IN[32] = la_data_in[116];
- assign wbs_dat_o[30] = gfpga_pad_EMBEDDED_IO_HD_SOC_OUT[32];
+ sky130_fd_sc_hd__ebufn_4 FPGA2SOC_OUT_32_DEMUX_WB (.TE_B(la_wb_switch_b), .A(gfpga_pad_EMBEDDED_IO_HD_SOC_OUT[32]), .Z(wbs_dat_o[30]));
+ sky130_fd_sc_hd__ebufn_4 FPGA2SOC_OUT_32_DEMUX_LA (.TE_B(la_wb_switch), .A(gfpga_pad_EMBEDDED_IO_HD_SOC_OUT[32]), .Z(la_data_out[116]));
assign gfpga_pad_EMBEDDED_IO_HD_SOC_IN[31] = la_data_in[117];
- assign wbs_dat_o[31] = gfpga_pad_EMBEDDED_IO_HD_SOC_OUT[31];
+ sky130_fd_sc_hd__ebufn_4 FPGA2SOC_OUT_31_DEMUX_WB (.TE_B(la_wb_switch_b), .A(gfpga_pad_EMBEDDED_IO_HD_SOC_OUT[31]), .Z(wbs_dat_o[31]));
+ sky130_fd_sc_hd__ebufn_4 FPGA2SOC_OUT_31_DEMUX_LA (.TE_B(la_wb_switch), .A(gfpga_pad_EMBEDDED_IO_HD_SOC_OUT[31]), .Z(la_data_out[117]));
assign gfpga_pad_EMBEDDED_IO_HD_SOC_IN[30] = la_data_in[118];
assign la_data_out[118] = gfpga_pad_EMBEDDED_IO_HD_SOC_OUT[30];
assign gfpga_pad_EMBEDDED_IO_HD_SOC_IN[29] = la_data_in[119];
diff --git a/HDL/common/caravel_fpga_wrapper_hd_template.v b/HDL/common/caravel_fpga_wrapper_hd_template.v
index ebbc70a..81d00f7 100644
--- a/HDL/common/caravel_fpga_wrapper_hd_template.v
+++ b/HDL/common/caravel_fpga_wrapper_hd_template.v
@@ -68,6 +68,12 @@ module fpga_top (
// Switch between wishbone and logic analyzer
wire wb_la_switch;
+ wire wb_la_switch_b;
+
+ // Inverted switch signal to drive tri-state buffers
+ // Use drive strength 8 as we will have 33 output pins which is driven by
+ // the buffers
+ sky130_fd_sc_hd__inv_8 WB_LA_SWITCH_INV (.A(la_wb_switch), .Y(la_wb_switch_b));
// Wire-bond TOP side I/O of FPGA to LEFT-side of Caravel interface
assign gfpga_pad_EMBEDDED_IO_HD_SOC_IN[0] = io_in[24];
diff --git a/HDL/common/digital_io_behavorial.v b/HDL/common/digital_io_behavorial.v
deleted file mode 100644
index 18c50bc..0000000
--- a/HDL/common/digital_io_behavorial.v
+++ /dev/null
@@ -1,46 +0,0 @@
-//-----------------------------------------------------
-// This file includes behavorial modeling
-// for digital I/O cells
-// These cells may not be directly used for physical design
-// Synthesis tools may be needed
-//-----------------------------------------------------
-`timescale 1ns/1ps
-
-//-----------------------------------------------------
-// Function : A minimum input pad
-//-----------------------------------------------------
-module GPIN (
- inout A, // External PAD signal
- output Y // Data input
-);
- assign Y = A;
-endmodule
-
-//-----------------------------------------------------
-// Function : A minimum output pad
-//-----------------------------------------------------
-module GPOUT (
- inout Y, // External PAD signal
- input A // Data output
-);
- assign Y = A;
-endmodule
-
-//-----------------------------------------------------
-// Function : A minimum embedded I/O
-// just an overlay to interface other components
-//-----------------------------------------------------
-module EMBEDDED_IO (
- input SOC_IN, // Input to drive the inpad signal
- output SOC_OUT, // Output the outpad signal
- output SOC_DIR, // Output the directionality
- output FPGA_IN, // Input data to FPGA
- input FPGA_OUT, // Output data from FPGA
- input FPGA_DIR // direction control
-);
-
- assign FPGA_IN = SOC_IN;
- assign SOC_OUT = FPGA_OUT;
- assign SOC_DIR = FPGA_DIR;
-endmodule
-
diff --git a/HDL/common/digital_io_hd.v b/HDL/common/digital_io_hd.v
index b1548df..b88390b 100644
--- a/HDL/common/digital_io_hd.v
+++ b/HDL/common/digital_io_hd.v
@@ -31,22 +31,26 @@ module EMBEDDED_IO_HD (
input IO_ISOL_N // Isolation enable signal
);
- sky130_fd_sc_hd__and2_0 ISOL_EN_GATE (.A(IO_ISOL_N),
- .B(FPGA_DIR),
+ wire SOC_DIR_N;
+
+ // Use drive-strength 4 for a high fan-out from SoC components
+ sky130_fd_sc_hd__or2b_4 ISOL_EN_GATE (.B_N(IO_ISOL_N),
+ .A(FPGA_DIR),
.X(SOC_DIR)
);
// Use drive-strength 4 for a high fan-out from global routing architecture
- sky130_fd_sc_hd__and2_4 IN_PROTECT_GATE (.A(SOC_DIR),
- .B(SOC_IN),
- .X(FPGA_IN)
- );
+ sky130_fd_sc_hd__inv_1 INV_SOC_DIR (.A(SOC_DIR), .Y(SOC_DIR_N));
+ sky130_fd_sc_hd__ebufn_4 IN_PROTECT_GATE (.TE_B(SOC_DIR_N),
+ .A(SOC_IN),
+ .Z(FPGA_IN)
+ );
// Use drive-strength 4 for a potential high fan-out from SoC components
- sky130_fd_sc_hd__and2b_4 OUT_PROTECT_GATE (.A_N(SOC_DIR),
- .B(FPGA_OUT),
- .X(SOC_OUT)
- );
+ sky130_fd_sc_hd__ebufn_4 OUT_PROTECT_GATE (.TE_B(SOC_DIR),
+ .A(FPGA_OUT),
+ .Z(SOC_OUT)
+ );
endmodule
diff --git a/HDL/common/wrapper_lines_generator.py b/HDL/common/wrapper_lines_generator.py
index 43f4955..c05d3ef 100644
--- a/HDL/common/wrapper_lines_generator.py
+++ b/HDL/common/wrapper_lines_generator.py
@@ -1,8 +1,9 @@
#####################################################################
-# Python script to adapt an OpenFPGA architecture file
+# Python script generate Verilog codes for the Caravel wrapper
+# which interface the FPGA fabric and other SoC components
# This script will
-# - Convert the ${SKYWATER_OPENFPGA_HOME} to the absolute path of current directory
-#
+# - generate the Verilog codes to connect FPGA inputs to Wishbone and Logic analyzer
+# - generate the Verilog codes to connect FPGA outputs to Wishbone and Logic analyzer
#####################################################################
import os
@@ -73,25 +74,58 @@ for ipin in range(0, num_gpio_pins):
# If this is an input pin of wishbone interface, whose postfix is '_i', we use MUX
# otherwise, this is an output pin, we just wire the input to logic analyzer
if ((wishbone_pins[ipin].endswith("_i")) or (re.search(r'_i\[\d+\]$', wishbone_pins[ipin], re.M | re.I))):
+ ##############################################################
+ # SOC INPUT will be directly driven by either
+ # - the Wishbone input
+ # or
+ # - the logic analyzer input
+ # through a multiplexer controlled by the signal 'la_wb_switch
curr_line = " " + "sky130_fd_sc_hd__mux2_1 FPGA2SOC_IN_" + str(135 - ipin) + "_MUX (.S(la_wb_switch), .A1(" + str(
wishbone_pins[ipin]) + "), .A0(" + str(logic_analyzer_pins[ipin][0]) + "), .X(gfpga_pad_EMBEDDED_IO_HD_SOC_IN[" + str(135 - ipin) + "]));"
netlist_lines.append(curr_line + "\n")
+ ##############################################################
+ # SOC OUTPUT will drive an output of logic analyzer
+ # since this I/O is going to interface a Wishbone input only
curr_line = " " + "assign " + \
str(logic_analyzer_pins[ipin][1]) + \
" = gfpga_pad_EMBEDDED_IO_HD_SOC_OUT[" + str(135 - ipin) + "];"
netlist_lines.append(curr_line + "\n")
elif ((wishbone_pins[ipin].endswith("_o")) or (re.search(r'_o\[\d+\]$', wishbone_pins[ipin], re.M | re.I))):
+ ##############################################################
+ # SOC INPUT will be directly driven by logic analyzer
+ # since this I/O is going to interface a Wishbone output only
curr_line = " " + "assign gfpga_pad_EMBEDDED_IO_HD_SOC_IN[" + str(
135 - ipin) + "] = " + str(logic_analyzer_pins[ipin][0]) + ";"
netlist_lines.append(curr_line + "\n")
- curr_line = " " + "assign " + \
- str(wishbone_pins[ipin]) + \
- " = gfpga_pad_EMBEDDED_IO_HD_SOC_OUT[" + str(135 - ipin) + "];"
+ ##############################################################
+ # SOC OUTPUT will drive the Wishbone output through a tri-state buffer
+ # As the buffer is enabled by logic '0', we use the inverted 'la_wb_switch'
+ curr_line = " " + "sky130_fd_sc_hd__ebufn_4 FPGA2SOC_OUT_" + str(135 - ipin) + "_DEMUX_WB (" + \
+ ".TE_B(la_wb_switch_b), " + \
+ ".A(" + "gfpga_pad_EMBEDDED_IO_HD_SOC_OUT[" + str(135 - ipin) + "]), " + \
+ ".Z(" + str(wishbone_pins[ipin]) + ")" + \
+ ");"
netlist_lines.append(curr_line + "\n")
+ ##############################################################
+ # SOC OUTPUT will also drive the Logic Analyzer output through a tri-state buffer
+ # As the buffer is enabled by logic '0', we use the 'la_wb_switch'
+ curr_line = " " + "sky130_fd_sc_hd__ebufn_4 FPGA2SOC_OUT_" + str(135 - ipin) + "_DEMUX_LA (" + \
+ ".TE_B(la_wb_switch), " + \
+ ".A(" + "gfpga_pad_EMBEDDED_IO_HD_SOC_OUT[" + str(135 - ipin) + "]), " + \
+ ".Z(" + str(logic_analyzer_pins[ipin][1]) + ")" + \
+ ");"
+ netlist_lines.append(curr_line + "\n")
+
elif ((ipin >= num_wishbone_pins) and (ipin < num_logic_analyzer_pins)):
+ ##############################################################
+ # SOC INPUT will be directly driven by logic analyzer
+ # since this I/O is going to interface logic analyzer input only
curr_line = " " + "assign gfpga_pad_EMBEDDED_IO_HD_SOC_IN[" + str(
135 - ipin) + "] = " + str(logic_analyzer_pins[ipin][0]) + ";"
netlist_lines.append(curr_line + "\n")
+ ##############################################################
+ # SOC OUTPUT will directly drive logic analyzer
+ # since this I/O is going to interface logic analyzer output only
curr_line = " " + "assign " + \
str(logic_analyzer_pins[ipin][1]) + \
" = gfpga_pad_EMBEDDED_IO_HD_SOC_OUT[" + str(135 - ipin) + "];"