pull the git change from https://github.com/dineshannayya/riscduino.git on 15th Feb 2022 with SRAM
diff --git a/verilog/rtl/clk_skew_adjust/src/clk_skew_adjust.gv b/verilog/rtl/clk_skew_adjust/src/clk_skew_adjust.gv
new file mode 100644
index 0000000..7fd1a62
--- /dev/null
+++ b/verilog/rtl/clk_skew_adjust/src/clk_skew_adjust.gv
@@ -0,0 +1,205 @@
+//////////////////////////////////////////////////////////////////////////////
+// SPDX-FileCopyrightText: 2021 , Dinesh Annayya
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+// SPDX-License-Identifier: Apache-2.0
+// SPDX-FileContributor: Created by Dinesh Annayya <dinesha@opencores.org>
+//
+//////////////////////////////////////////////////////////////////////
+//// ////
+//// clock skew adjust ////
+//// ////
+//// This file is part of the YIFive cores project ////
+//// https://github.com/dineshannayya/yifive_r0.git ////
+//// http://www.opencores.org/cores/yifive/ ////
+//// ////
+//// Description ////
+//// This block is useful for global clock skew adjustment ////
+//// logic implementation: ////
+//// clk_out = (sel=0) ? clk_in : ////
+//// (sel=1) ? clk_d1 : ////
+//// (sel=1) ? clk_d2 : ////
+//// ..... ////
+//// (sel=15)? clk_d15 :clk_in ////
+//// ////
+//// Note: each d* indicate clk buf delay ////
+//// ////
+//// ////
+//// To Do: ////
+//// nothing ////
+//// ////
+//// Author(s): ////
+//// - Dinesh Annayya, dinesha@opencores.org ////
+//// ////
+//// Revision : ////
+//// 0.0 - 29th Feb 2021, Dinesh A ////
+//// Initial version ////
+///
+//// ////
+//////////////////////////////////////////////////////////////////////
+//// ////
+//// Copyright (C) 2000 Authors and OPENCORES.ORG ////
+//// ////
+//// This source file may be used and distributed without ////
+//// restriction provided that this copyright statement is not ////
+//// removed from the file and that any derivative work contains ////
+//// the original copyright notice and the associated disclaimer. ////
+//// ////
+//// This source file is free software; you can redistribute it ////
+//// and/or modify it under the terms of the GNU Lesser General ////
+//// Public License as published by the Free Software Foundation; ////
+//// either version 2.1 of the License, or (at your option) any ////
+//// later version. ////
+//// ////
+//// This source is distributed in the hope that it will be ////
+//// useful, but WITHOUT ANY WARRANTY; without even the implied ////
+//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR ////
+//// PURPOSE. See the GNU Lesser General Public License for more ////
+//// details. ////
+//// ////
+//// You should have received a copy of the GNU Lesser General ////
+//// Public License along with this source; if not, download it ////
+//// from http://www.opencores.org/lgpl.shtml ////
+//// ////
+//////////////////////////////////////////////////////////////////////
+// Clock-in is east pad direction
+// clock out give in other three direction for better placement
+/////////////////////////////////////////////////////////////////////
+module clk_skew_adjust(
+`ifdef USE_POWER_PINS
+ vccd1,// User area 1 1.8V supply
+ vssd1,// User area 1 digital ground
+`endif
+clk_in, sel, clk_out);
+
+
+`ifdef USE_POWER_PINS
+ input vccd1;// User area 1 1.8V supply
+ input vssd1;// User area 1 digital ground
+`endif
+ input clk_in;
+ output clk_out;
+ input [3:0] sel;
+ wire in0;
+ wire in1;
+ wire in2;
+ wire in3;
+ wire in4;
+ wire in5;
+ wire in6;
+ wire in7;
+ wire in8;
+ wire in9;
+ wire in10;
+ wire in11;
+ wire in12;
+ wire in13;
+ wire in14;
+ wire in15;
+
+ wire clk_d1;
+ wire clk_d2;
+ wire clk_d3;
+ wire clk_d4;
+ wire clk_d5;
+ wire clk_d6;
+ wire clk_d7;
+ wire clk_d8;
+ wire clk_d9;
+ wire clk_d10;
+ wire clk_d11;
+ wire clk_d12;
+ wire clk_d13;
+ wire clk_d14;
+ wire clk_d15;
+
+ wire d00;
+ wire d01;
+ wire d02;
+ wire d03;
+ wire d04;
+ wire d05;
+ wire d06;
+ wire d07;
+ wire d10;
+ wire d11;
+ wire d12;
+ wire d13;
+ wire d20;
+ wire d21;
+ wire d30;
+
+
+ sky130_fd_sc_hd__clkdlybuf4s15_2 clkbuf_1 (.A(clk_in), .X(clk_d1));
+ sky130_fd_sc_hd__clkdlybuf4s15_2 clkbuf_2 (.A(clk_d1), .X(clk_d2));
+ sky130_fd_sc_hd__clkdlybuf4s15_2 clkbuf_3 (.A(clk_d2), .X(clk_d3));
+ sky130_fd_sc_hd__clkdlybuf4s15_2 clkbuf_4 (.A(clk_d3), .X(clk_d4));
+ sky130_fd_sc_hd__clkdlybuf4s15_2 clkbuf_5 (.A(clk_d4), .X(clk_d5));
+ sky130_fd_sc_hd__clkdlybuf4s15_2 clkbuf_6 (.A(clk_d5), .X(clk_d6));
+ sky130_fd_sc_hd__clkdlybuf4s15_2 clkbuf_7 (.A(clk_d6), .X(clk_d7));
+ sky130_fd_sc_hd__clkdlybuf4s15_2 clkbuf_8 (.A(clk_d7), .X(clk_d8));
+ sky130_fd_sc_hd__clkdlybuf4s15_2 clkbuf_9 (.A(clk_d8), .X(clk_d9));
+ sky130_fd_sc_hd__clkdlybuf4s15_2 clkbuf_10 (.A(clk_d9), .X(clk_d10));
+ sky130_fd_sc_hd__clkdlybuf4s15_2 clkbuf_11 (.A(clk_d10), .X(clk_d11));
+ sky130_fd_sc_hd__clkdlybuf4s15_2 clkbuf_12 (.A(clk_d11), .X(clk_d12));
+ sky130_fd_sc_hd__clkdlybuf4s15_2 clkbuf_13 (.A(clk_d12), .X(clk_d13));
+ sky130_fd_sc_hd__clkdlybuf4s15_2 clkbuf_14 (.A(clk_d13), .X(clk_d14));
+ sky130_fd_sc_hd__clkdlybuf4s15_2 clkbuf_15 (.A(clk_d14), .X(clk_d15));
+
+
+ // Tap point selection
+ assign in0 = clk_in;
+ assign in1 = clk_d1;
+ assign in2 = clk_d2;
+ assign in3 = clk_d3;
+ assign in4 = clk_d4;
+ assign in5 = clk_d5;
+ assign in6 = clk_d6;
+ assign in7 = clk_d7;
+ assign in8 = clk_d8;
+ assign in9 = clk_d9;
+ assign in10 = clk_d10;
+ assign in11 = clk_d11;
+ assign in12 = clk_d12;
+ assign in13 = clk_d13;
+ assign in14 = clk_d14;
+ assign in15 = clk_d15;
+
+
+ // first level mux - 8
+ sky130_fd_sc_hd__mux2_1 u_mux_level_00 ( .X (d00) , .A0 (in0), .A1(in1), .S(sel[0]));
+ sky130_fd_sc_hd__mux2_1 u_mux_level_01 ( .X (d01) , .A0 (in2), .A1(in3), .S(sel[0]));
+ sky130_fd_sc_hd__mux2_1 u_mux_level_02 ( .X (d02) , .A0 (in4), .A1(in5), .S(sel[0]));
+ sky130_fd_sc_hd__mux2_1 u_mux_level_03 ( .X (d03) , .A0 (in6), .A1(in7), .S(sel[0]));
+ sky130_fd_sc_hd__mux2_1 u_mux_level_04 ( .X (d04) , .A0 (in8), .A1(in9), .S(sel[0]));
+ sky130_fd_sc_hd__mux2_1 u_mux_level_05 ( .X (d05) , .A0 (in10), .A1(in11), .S(sel[0]));
+ sky130_fd_sc_hd__mux2_1 u_mux_level_06 ( .X (d06) , .A0 (in12), .A1(in13), .S(sel[0]));
+ sky130_fd_sc_hd__mux2_1 u_mux_level_07 ( .X (d07) , .A0 (in14), .A1(in15), .S(sel[0]));
+
+ // second level mux - 4
+ sky130_fd_sc_hd__mux2_1 u_mux_level_10 ( .X (d10) , .A0 (d00), .A1(d01), .S(sel[1]));
+ sky130_fd_sc_hd__mux2_1 u_mux_level_11 ( .X (d11) , .A0 (d02), .A1(d03), .S(sel[1]));
+ sky130_fd_sc_hd__mux2_1 u_mux_level_12 ( .X (d12) , .A0 (d04), .A1(d05), .S(sel[1]));
+ sky130_fd_sc_hd__mux2_1 u_mux_level_13 ( .X (d13) , .A0 (d06), .A1(d07), .S(sel[1]));
+
+ // third level mux - 2
+ sky130_fd_sc_hd__mux2_1 u_mux_level_20 ( .X (d20) , .A0 (d10), .A1(d11), .S(sel[2]));
+ sky130_fd_sc_hd__mux2_1 u_mux_level_21 ( .X (d21) , .A0 (d12), .A1(d13), .S(sel[2]));
+
+ // fourth level mux - 1
+ sky130_fd_sc_hd__mux2_4 u_mux_level_30 ( .X (d30) , .A0 (d20), .A1(d21), .S(sel[3]));
+
+
+ assign clk_out = d30;
+
+endmodule
diff --git a/verilog/rtl/clk_skew_adjust/src/clk_skew_adjust.v b/verilog/rtl/clk_skew_adjust/src/clk_skew_adjust.v
new file mode 100644
index 0000000..a961a50
--- /dev/null
+++ b/verilog/rtl/clk_skew_adjust/src/clk_skew_adjust.v
@@ -0,0 +1,2898 @@
+module clk_skew_adjust (clk_in,
+ clk_out,
+ vccd1,
+ vssd1,
+ sel);
+ input clk_in;
+ output clk_out;
+ input vccd1;
+ input vssd1;
+ input [3:0] sel;
+
+ sky130_fd_sc_hd__clkdlybuf4s15_2 clkbuf_1 (.A(clk_in),
+ .X(clk_d1),
+ .VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__clkdlybuf4s15_2 clkbuf_10 (.A(clk_d9),
+ .X(clk_d10),
+ .VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__clkdlybuf4s15_2 clkbuf_11 (.A(clk_d10),
+ .X(clk_d11),
+ .VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__clkdlybuf4s15_2 clkbuf_12 (.A(clk_d11),
+ .X(clk_d12),
+ .VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__clkdlybuf4s15_2 clkbuf_13 (.A(clk_d12),
+ .X(clk_d13),
+ .VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__clkdlybuf4s15_2 clkbuf_14 (.A(clk_d13),
+ .X(clk_d14),
+ .VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__clkdlybuf4s15_2 clkbuf_15 (.A(clk_d14),
+ .X(clk_d15),
+ .VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__clkdlybuf4s15_2 clkbuf_2 (.A(clk_d1),
+ .X(clk_d2),
+ .VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__clkdlybuf4s15_2 clkbuf_3 (.A(clk_d2),
+ .X(clk_d3),
+ .VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__clkdlybuf4s15_2 clkbuf_4 (.A(clk_d3),
+ .X(clk_d4),
+ .VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__clkdlybuf4s15_2 clkbuf_5 (.A(clk_d4),
+ .X(clk_d5),
+ .VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__clkdlybuf4s15_2 clkbuf_6 (.A(clk_d5),
+ .X(clk_d6),
+ .VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__clkdlybuf4s15_2 clkbuf_7 (.A(clk_d6),
+ .X(clk_d7),
+ .VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__clkdlybuf4s15_2 clkbuf_8 (.A(clk_d7),
+ .X(clk_d8),
+ .VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__clkdlybuf4s15_2 clkbuf_9 (.A(clk_d8),
+ .X(clk_d9),
+ .VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__mux2_1 u_mux_level_00 (.A0(clk_in),
+ .A1(clk_d1),
+ .S(sel[0]),
+ .X(d00),
+ .VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__mux2_1 u_mux_level_01 (.A0(clk_d2),
+ .A1(clk_d3),
+ .S(sel[0]),
+ .X(d01),
+ .VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__mux2_1 u_mux_level_02 (.A0(clk_d4),
+ .A1(clk_d5),
+ .S(sel[0]),
+ .X(d02),
+ .VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__mux2_1 u_mux_level_03 (.A0(clk_d6),
+ .A1(clk_d7),
+ .S(sel[0]),
+ .X(d03),
+ .VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__mux2_1 u_mux_level_04 (.A0(clk_d8),
+ .A1(clk_d9),
+ .S(sel[0]),
+ .X(d04),
+ .VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__mux2_1 u_mux_level_05 (.A0(clk_d10),
+ .A1(clk_d11),
+ .S(sel[0]),
+ .X(d05),
+ .VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__mux2_1 u_mux_level_06 (.A0(clk_d12),
+ .A1(clk_d13),
+ .S(sel[0]),
+ .X(d06),
+ .VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__mux2_1 u_mux_level_07 (.A0(clk_d14),
+ .A1(clk_d15),
+ .S(sel[0]),
+ .X(d07),
+ .VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__mux2_1 u_mux_level_10 (.A0(d00),
+ .A1(d01),
+ .S(sel[1]),
+ .X(d10),
+ .VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__mux2_1 u_mux_level_11 (.A0(d02),
+ .A1(d03),
+ .S(sel[1]),
+ .X(d11),
+ .VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__mux2_1 u_mux_level_12 (.A0(d04),
+ .A1(d05),
+ .S(sel[1]),
+ .X(d12),
+ .VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__mux2_1 u_mux_level_13 (.A0(d06),
+ .A1(d07),
+ .S(sel[1]),
+ .X(d13),
+ .VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__mux2_1 u_mux_level_20 (.A0(d10),
+ .A1(d11),
+ .S(sel[2]),
+ .X(d20),
+ .VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__mux2_1 u_mux_level_21 (.A0(d12),
+ .A1(d13),
+ .S(sel[2]),
+ .X(d21),
+ .VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__mux2_4 u_mux_level_30 (.A0(d20),
+ .A1(d21),
+ .S(sel[3]),
+ .X(clk_out),
+ .VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_3 PHY_0 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_3 PHY_1 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_3 PHY_2 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_3 PHY_3 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_3 PHY_4 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_3 PHY_5 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_3 PHY_6 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_3 PHY_7 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_3 PHY_8 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_3 PHY_9 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_3 PHY_10 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_3 PHY_11 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_3 PHY_12 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_3 PHY_13 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_3 PHY_14 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_3 PHY_15 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_3 PHY_16 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_3 PHY_17 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_3 PHY_18 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_3 PHY_19 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_3 PHY_20 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_3 PHY_21 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_3 PHY_22 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_3 PHY_23 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_3 PHY_24 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_3 PHY_25 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_3 PHY_26 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_3 PHY_27 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_3 PHY_28 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_3 PHY_29 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_3 PHY_30 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_3 PHY_31 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_3 PHY_32 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_3 PHY_33 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_3 PHY_34 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_3 PHY_35 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_3 PHY_36 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_3 PHY_37 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_3 PHY_38 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_3 PHY_39 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_3 PHY_40 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_3 PHY_41 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_3 PHY_42 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_3 PHY_43 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_3 PHY_44 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_3 PHY_45 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_3 PHY_46 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_3 PHY_47 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_3 PHY_48 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_3 PHY_49 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_3 PHY_50 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_3 PHY_51 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_3 PHY_52 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_3 PHY_53 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_3 PHY_54 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_3 PHY_55 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_3 PHY_56 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_3 PHY_57 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_3 PHY_58 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_3 PHY_59 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_3 PHY_60 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_3 PHY_61 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_3 PHY_62 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_3 PHY_63 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__tapvpwrvgnd_1 PHY_64 (.VGND(vssd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__tapvpwrvgnd_1 PHY_65 (.VGND(vssd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__tapvpwrvgnd_1 PHY_66 (.VGND(vssd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__tapvpwrvgnd_1 PHY_67 (.VGND(vssd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__tapvpwrvgnd_1 PHY_68 (.VGND(vssd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__tapvpwrvgnd_1 PHY_69 (.VGND(vssd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__tapvpwrvgnd_1 PHY_70 (.VGND(vssd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__tapvpwrvgnd_1 PHY_71 (.VGND(vssd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__tapvpwrvgnd_1 PHY_72 (.VGND(vssd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__tapvpwrvgnd_1 PHY_73 (.VGND(vssd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__tapvpwrvgnd_1 PHY_74 (.VGND(vssd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__tapvpwrvgnd_1 PHY_75 (.VGND(vssd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__tapvpwrvgnd_1 PHY_76 (.VGND(vssd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__tapvpwrvgnd_1 PHY_77 (.VGND(vssd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__tapvpwrvgnd_1 PHY_78 (.VGND(vssd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__tapvpwrvgnd_1 PHY_79 (.VGND(vssd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__tapvpwrvgnd_1 PHY_80 (.VGND(vssd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__tapvpwrvgnd_1 PHY_81 (.VGND(vssd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__tapvpwrvgnd_1 PHY_82 (.VGND(vssd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__tapvpwrvgnd_1 PHY_83 (.VGND(vssd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__tapvpwrvgnd_1 PHY_84 (.VGND(vssd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__tapvpwrvgnd_1 PHY_85 (.VGND(vssd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__tapvpwrvgnd_1 PHY_86 (.VGND(vssd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__tapvpwrvgnd_1 PHY_87 (.VGND(vssd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__tapvpwrvgnd_1 PHY_88 (.VGND(vssd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__tapvpwrvgnd_1 PHY_89 (.VGND(vssd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__tapvpwrvgnd_1 PHY_90 (.VGND(vssd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__tapvpwrvgnd_1 PHY_91 (.VGND(vssd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__tapvpwrvgnd_1 PHY_92 (.VGND(vssd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__tapvpwrvgnd_1 PHY_93 (.VGND(vssd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__tapvpwrvgnd_1 PHY_94 (.VGND(vssd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__tapvpwrvgnd_1 PHY_95 (.VGND(vssd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__tapvpwrvgnd_1 PHY_96 (.VGND(vssd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__tapvpwrvgnd_1 PHY_97 (.VGND(vssd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__tapvpwrvgnd_1 PHY_98 (.VGND(vssd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__tapvpwrvgnd_1 PHY_99 (.VGND(vssd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__tapvpwrvgnd_1 PHY_100 (.VGND(vssd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__tapvpwrvgnd_1 PHY_101 (.VGND(vssd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__tapvpwrvgnd_1 PHY_102 (.VGND(vssd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__tapvpwrvgnd_1 PHY_103 (.VGND(vssd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__tapvpwrvgnd_1 PHY_104 (.VGND(vssd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__tapvpwrvgnd_1 PHY_105 (.VGND(vssd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__tapvpwrvgnd_1 PHY_106 (.VGND(vssd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__tapvpwrvgnd_1 PHY_107 (.VGND(vssd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__tapvpwrvgnd_1 PHY_108 (.VGND(vssd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__tapvpwrvgnd_1 PHY_109 (.VGND(vssd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__tapvpwrvgnd_1 PHY_110 (.VGND(vssd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__tapvpwrvgnd_1 PHY_111 (.VGND(vssd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__tapvpwrvgnd_1 PHY_112 (.VGND(vssd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__tapvpwrvgnd_1 PHY_113 (.VGND(vssd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__tapvpwrvgnd_1 PHY_114 (.VGND(vssd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__tapvpwrvgnd_1 PHY_115 (.VGND(vssd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__tapvpwrvgnd_1 PHY_116 (.VGND(vssd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__tapvpwrvgnd_1 PHY_117 (.VGND(vssd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__tapvpwrvgnd_1 PHY_118 (.VGND(vssd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__tapvpwrvgnd_1 PHY_119 (.VGND(vssd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__tapvpwrvgnd_1 PHY_120 (.VGND(vssd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__tapvpwrvgnd_1 PHY_121 (.VGND(vssd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__tapvpwrvgnd_1 PHY_122 (.VGND(vssd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__tapvpwrvgnd_1 PHY_123 (.VGND(vssd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__tapvpwrvgnd_1 PHY_124 (.VGND(vssd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__tapvpwrvgnd_1 PHY_125 (.VGND(vssd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__tapvpwrvgnd_1 PHY_126 (.VGND(vssd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__tapvpwrvgnd_1 PHY_127 (.VGND(vssd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__tapvpwrvgnd_1 PHY_128 (.VGND(vssd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__tapvpwrvgnd_1 PHY_129 (.VGND(vssd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__tapvpwrvgnd_1 PHY_130 (.VGND(vssd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__tapvpwrvgnd_1 PHY_131 (.VGND(vssd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__tapvpwrvgnd_1 PHY_132 (.VGND(vssd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__tapvpwrvgnd_1 PHY_133 (.VGND(vssd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__tapvpwrvgnd_1 PHY_134 (.VGND(vssd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__tapvpwrvgnd_1 PHY_135 (.VGND(vssd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__tapvpwrvgnd_1 PHY_136 (.VGND(vssd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__tapvpwrvgnd_1 PHY_137 (.VGND(vssd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__tapvpwrvgnd_1 PHY_138 (.VGND(vssd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__tapvpwrvgnd_1 PHY_139 (.VGND(vssd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__tapvpwrvgnd_1 PHY_140 (.VGND(vssd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__tapvpwrvgnd_1 PHY_141 (.VGND(vssd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__tapvpwrvgnd_1 PHY_142 (.VGND(vssd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__tapvpwrvgnd_1 PHY_143 (.VGND(vssd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__tapvpwrvgnd_1 PHY_144 (.VGND(vssd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__tapvpwrvgnd_1 PHY_145 (.VGND(vssd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__tapvpwrvgnd_1 PHY_146 (.VGND(vssd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__tapvpwrvgnd_1 PHY_147 (.VGND(vssd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__tapvpwrvgnd_1 PHY_148 (.VGND(vssd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__tapvpwrvgnd_1 PHY_149 (.VGND(vssd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__tapvpwrvgnd_1 PHY_150 (.VGND(vssd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__tapvpwrvgnd_1 PHY_151 (.VGND(vssd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__tapvpwrvgnd_1 PHY_152 (.VGND(vssd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__tapvpwrvgnd_1 PHY_153 (.VGND(vssd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__tapvpwrvgnd_1 PHY_154 (.VGND(vssd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__tapvpwrvgnd_1 PHY_155 (.VGND(vssd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__tapvpwrvgnd_1 PHY_156 (.VGND(vssd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__tapvpwrvgnd_1 PHY_157 (.VGND(vssd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__tapvpwrvgnd_1 PHY_158 (.VGND(vssd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__tapvpwrvgnd_1 PHY_159 (.VGND(vssd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__tapvpwrvgnd_1 PHY_160 (.VGND(vssd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__tapvpwrvgnd_1 PHY_161 (.VGND(vssd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__tapvpwrvgnd_1 PHY_162 (.VGND(vssd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__tapvpwrvgnd_1 PHY_163 (.VGND(vssd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__tapvpwrvgnd_1 PHY_164 (.VGND(vssd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__tapvpwrvgnd_1 PHY_165 (.VGND(vssd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_0_3 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_0_15 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_4 FILLER_0_27 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_0_32 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_0_44 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_6 FILLER_0_56 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_0_63 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_0_75 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_6 FILLER_0_87 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_0_94 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_0_106 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_6 FILLER_0_118 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_0_125 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_0_137 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_6 FILLER_0_149 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_0_156 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_0_168 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_6 FILLER_0_180 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_3 FILLER_0_187 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_1_3 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_1_15 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_4 FILLER_1_27 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_1_32 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_1_44 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_1_56 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_1_68 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_1_80 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_1_93 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_1_105 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_1_117 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_1_129 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_1_141 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_1_154 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_1_166 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_1_178 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_2_3 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_2_15 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_2_27 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_2_39 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_8 FILLER_2_51 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__fill_2 FILLER_2_59 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_2_62 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_2_74 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_2_86 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_2_98 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_2_110 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_2_123 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_2_135 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_2_147 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_2_159 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_2_171 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_6 FILLER_2_184 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_3_3 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_3_15 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_4 FILLER_3_27 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_3_32 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_3_44 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_3_56 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_3_68 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_3_80 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_3_93 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_3_105 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_3_117 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_3_129 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_3_141 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_3_154 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_3_166 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_3_178 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_4_3 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_8 FILLER_4_15 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_3 FILLER_4_23 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_4_35 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_4_47 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__fill_2 FILLER_4_59 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_4_62 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_4_74 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_4_86 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_4_98 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_4_110 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_4_123 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_4_135 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_4_147 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_4_159 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_4_171 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_6 FILLER_4_184 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_5_3 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_5_15 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_4 FILLER_5_27 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_5_32 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_5_44 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_5_56 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_5_68 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_5_80 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_5_93 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_5_114 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_8 FILLER_5_126 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_3 FILLER_5_134 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_6 FILLER_5_146 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__fill_1 FILLER_5_152 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_5_154 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_5_166 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_5_178 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_6_3 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_6_15 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_6_27 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_6_39 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_8 FILLER_6_51 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__fill_2 FILLER_6_59 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_6_62 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_6_74 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_6_86 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_6_98 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_6_110 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_6_123 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_6_135 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_6_147 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_6_159 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_6_171 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_6 FILLER_6_184 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_7_3 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_7_15 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_4 FILLER_7_27 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_7_32 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_7_44 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_7_56 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_7_68 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_7_80 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_7_102 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_7_114 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_7_126 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_7_138 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_3 FILLER_7_150 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_7_154 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_7_166 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_7_178 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_8_3 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_8_15 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_8_27 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_8_39 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_8 FILLER_8_51 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__fill_2 FILLER_8_59 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_8_62 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_8_74 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_8_86 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_8_98 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_8_110 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_8_123 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_8_135 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_8_147 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_8_159 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_8_171 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_6 FILLER_8_184 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_9_3 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_9_15 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_4 FILLER_9_27 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_9_32 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_9_44 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_8 FILLER_9_56 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_3 FILLER_9_64 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_9_76 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_4 FILLER_9_88 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_9_93 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_9_105 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_9_117 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_9_129 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_9_141 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_9_154 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_8 FILLER_9_166 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_6 FILLER_9_183 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__fill_1 FILLER_9_189 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_10_3 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_10_15 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_10_27 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_10_39 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_8 FILLER_10_51 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__fill_2 FILLER_10_59 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_10_62 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_10_74 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_10_86 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_10_98 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_10_110 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_10_123 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_10_135 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_10_147 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_10_159 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_10_171 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_6 FILLER_10_184 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_11_3 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_3 FILLER_11_15 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_4 FILLER_11_27 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_11_32 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_11_44 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_11_56 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_11_68 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_11_80 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_11_93 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_11_105 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_11_117 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_11_129 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_11_141 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_11_154 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_8 FILLER_11_166 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_3 FILLER_11_174 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_4 FILLER_11_186 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_12_3 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_12_15 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_12_27 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_12_39 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_8 FILLER_12_51 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__fill_2 FILLER_12_59 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_12_62 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_12_74 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_12_86 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_8 FILLER_12_98 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_3 FILLER_12_106 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_4 FILLER_12_118 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_12_123 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_12_135 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_12_147 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_12_159 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_12_171 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_6 FILLER_12_184 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_13_3 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_13_15 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_4 FILLER_13_27 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_13_32 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_13_44 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_13_56 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_13_68 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_13_80 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_13_93 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_13_105 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_13_117 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_13_129 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_13_141 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_13_154 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_13_166 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_13_178 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_14_3 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_14_15 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_14_27 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_14_39 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_8 FILLER_14_51 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__fill_2 FILLER_14_59 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_14_62 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_14_74 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_14_86 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_14_98 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_14_110 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_14_123 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__fill_2 FILLER_14_135 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_14_146 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_6 FILLER_14_158 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__fill_1 FILLER_14_164 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_8 FILLER_14_174 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__fill_1 FILLER_14_182 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_6 FILLER_14_184 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_15_3 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_15_15 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_4 FILLER_15_27 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_15_32 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_15_44 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_15_56 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_15_68 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_15_80 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_15_93 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_15_105 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_15_117 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_15_129 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_15_141 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_15_154 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_15_166 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_15_178 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_16_3 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_16_15 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_16_27 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_16_39 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_8 FILLER_16_51 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__fill_2 FILLER_16_59 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_16_62 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_16_74 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_16_86 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_16_98 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_16_110 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_16_123 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_16_135 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_16_147 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_16_159 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_16_171 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_6 FILLER_16_184 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_17_3 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_17_15 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_4 FILLER_17_27 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_17_32 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_17_44 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_4 FILLER_17_56 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__fill_1 FILLER_17_60 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_17_73 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_6 FILLER_17_85 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__fill_1 FILLER_17_91 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_17_93 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_17_105 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_17_117 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_17_129 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_17_141 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_17_154 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_8 FILLER_17_166 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_3 FILLER_17_174 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_4 FILLER_17_186 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_18_3 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_18_15 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_4 FILLER_18_27 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_18_40 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_8 FILLER_18_52 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__fill_1 FILLER_18_60 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_18_62 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_18_74 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_18_86 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_18_98 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_18_110 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_18_123 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_18_135 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_18_147 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_18_159 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_18_171 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_6 FILLER_18_184 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_19_3 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_19_15 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_4 FILLER_19_27 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_19_32 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_19_44 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_19_56 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_19_68 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_19_80 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_19_93 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_19_105 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_19_117 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_19_129 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_19_141 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_19_154 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_19_166 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_19_178 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_20_3 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_20_15 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_20_27 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_20_39 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_8 FILLER_20_51 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__fill_2 FILLER_20_59 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_20_62 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_20_74 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_20_86 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_20_98 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_20_110 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_20_123 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_20_135 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_20_147 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_20_159 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_20_171 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_6 FILLER_20_184 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_21_12 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_6 FILLER_21_24 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__fill_1 FILLER_21_30 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_21_32 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_21_44 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_21_56 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_21_68 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_21_80 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_21_93 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_21_105 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_21_117 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_21_129 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_21_141 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_21_154 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_4 FILLER_21_166 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_8 FILLER_21_179 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_3 FILLER_21_187 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_22_3 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_22_15 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_22_27 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_22_39 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_8 FILLER_22_51 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__fill_2 FILLER_22_59 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_22_71 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_22_83 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_22_95 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_22_107 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_3 FILLER_22_119 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_22_132 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_22_144 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_22_156 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_22_168 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_3 FILLER_22_180 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_6 FILLER_22_184 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_23_3 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_23_15 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_4 FILLER_23_27 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_23_32 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_23_44 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_23_56 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_23_68 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_23_80 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_23_93 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_23_105 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_6 FILLER_23_117 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__fill_1 FILLER_23_123 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_23_133 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_8 FILLER_23_145 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_4 FILLER_23_154 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_23_167 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_8 FILLER_23_179 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_3 FILLER_23_187 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_24_3 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_24_15 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_24_27 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_24_39 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_8 FILLER_24_51 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__fill_2 FILLER_24_59 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_24_62 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_24_74 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_24_86 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_24_98 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_24_110 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_24_123 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_24_135 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_24_147 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_24_159 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_24_171 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_6 FILLER_24_184 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_25_12 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_6 FILLER_25_24 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__fill_1 FILLER_25_30 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_25_32 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_25_44 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_3 FILLER_25_56 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_25_68 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_25_80 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_25_93 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_25_105 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_25_117 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_25_129 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_25_141 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_25_154 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_8 FILLER_25_166 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_3 FILLER_25_174 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_4 FILLER_25_186 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_26_3 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_26_15 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_26_27 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_26_39 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_8 FILLER_26_51 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__fill_2 FILLER_26_59 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_26_62 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_26_74 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_26_86 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_26_98 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_26_110 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_26_123 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_26_135 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_26_147 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_8 FILLER_26_159 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_3 FILLER_26_167 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_4 FILLER_26_179 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_6 FILLER_26_184 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_27_3 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_27_15 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_4 FILLER_27_27 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_27_32 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_27_44 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_27_56 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_27_68 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_27_80 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_27_93 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_27_105 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_27_117 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_27_129 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_27_141 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_27_154 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_27_166 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_27_178 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_28_3 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_28_15 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_28_27 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_28_39 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_8 FILLER_28_51 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__fill_2 FILLER_28_59 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_28_62 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_28_74 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_28_86 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_28_98 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_28_110 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_28_123 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_28_135 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_28_147 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_28_159 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_28_171 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_6 FILLER_28_184 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_29_3 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_29_15 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_4 FILLER_29_27 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_29_32 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_29_44 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_29_56 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_8 FILLER_29_68 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_3 FILLER_29_76 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_4 FILLER_29_88 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_29_93 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_29_105 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_29_117 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_29_129 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_29_141 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_29_154 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_6 FILLER_29_166 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_8 FILLER_29_181 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__fill_1 FILLER_29_189 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_30_3 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_30_15 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_30_27 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_30_39 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_8 FILLER_30_51 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__fill_2 FILLER_30_59 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_30_62 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_30_74 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_30_86 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_8 FILLER_30_98 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__fill_2 FILLER_30_106 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_4 FILLER_30_117 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__fill_1 FILLER_30_121 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_30_123 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_4 FILLER_30_135 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__fill_1 FILLER_30_139 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_30_149 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_8 FILLER_30_161 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__fill_1 FILLER_30_169 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_4 FILLER_30_179 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_6 FILLER_30_184 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_31_3 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_31_15 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_4 FILLER_31_27 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_31_32 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_31_44 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_6 FILLER_31_56 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_31_63 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_31_75 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_6 FILLER_31_87 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_31_94 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_31_106 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_6 FILLER_31_118 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_31_125 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__fill_1 FILLER_31_137 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_8 FILLER_31_147 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_31_156 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_31_168 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_6 FILLER_31_180 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_3 FILLER_31_187 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+endmodule
diff --git a/verilog/rtl/clk_skew_adjust/synth/Makefile b/verilog/rtl/clk_skew_adjust/synth/Makefile
new file mode 100644
index 0000000..f6ae1df
--- /dev/null
+++ b/verilog/rtl/clk_skew_adjust/synth/Makefile
@@ -0,0 +1,49 @@
+# //////////////////////////////////////////////////////////////////////////////
+# // SPDX-FileCopyrightText: 2021, Dinesh Annayya
+# //
+# // Licensed under the Apache License, Version 2.0 (the "License");
+# // you may not use this file except in compliance with the License.
+# // You may obtain a copy of the License at
+# //
+# // http://www.apache.org/licenses/LICENSE-2.0
+# //
+# // Unless required by applicable law or agreed to in writing, software
+# // distributed under the License is distributed on an "AS IS" BASIS,
+# // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# // See the License for the specific language governing permissions and
+# // limitations under the License.
+# // SPDX-License-Identifier: Apache-2.0
+# // SPDX-FileContributor: Dinesh Annayya <dinesha@opencores.org>
+# // //////////////////////////////////////////////////////////////////////////
+#------------------------------------------------------------------------------
+# Makefile for Synthesis
+#------------------------------------------------------------------------------
+
+# Paths
+export ROOT_DIR := $(shell pwd)
+export REPORT_DIR := $(ROOT_DIR)/reports
+export NETLIST_DIR := $(ROOT_DIR)/netlist
+export TMP_DIR := $(ROOT_DIR)/tmp
+
+
+# Targets
+.PHONY: clean create synth
+
+default: clean create synth
+
+synth: clean create
+ yosys -g -c synth.tcl -l synth.log
+
+create:
+ mkdir -p ./tmp/synthesis;
+ mkdir -p ./reports;
+ mkdir -p ./netlist;
+ $(OPENLANE_ROOT)/scripts/libtrim.pl $(PDK_ROOT)/sky130A/libs.ref/sky130_fd_sc_hd/lib/sky130_fd_sc_hd__tt_025C_1v80.lib $(PDK_ROOT)/sky130A/libs.tech/openlane/sky130_fd_sc_hd/no_synth.cells > ./tmp/trimmed.lib
+
+
+
+clean:
+ $(RM) -R synth.log
+ $(RM) -R $(REPORT_DIR)
+ $(RM) -R $(NETLIST_DIR)
+ $(RM) -R $(TMP_DIR)
diff --git a/verilog/rtl/clk_skew_adjust/synth/synth.tcl b/verilog/rtl/clk_skew_adjust/synth/synth.tcl
new file mode 100755
index 0000000..b7adea6
--- /dev/null
+++ b/verilog/rtl/clk_skew_adjust/synth/synth.tcl
@@ -0,0 +1,385 @@
+# //////////////////////////////////////////////////////////////////////////////
+# // SPDX-FileCopyrightText: 2021, Dinesh Annayya
+# //
+# // Licensed under the Apache License, Version 2.0 (the "License");
+# // you may not use this file except in compliance with the License.
+# // You may obtain a copy of the License at
+# //
+# // http://www.apache.org/licenses/LICENSE-2.0
+# //
+# // Unless required by applicable law or agreed to in writing, software
+# // distributed under the License is distributed on an "AS IS" BASIS,
+# // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# // See the License for the specific language governing permissions and
+# // limitations under the License.
+# // SPDX-License-Identifier: Apache-2.0
+# // SPDX-FileContributor: Dinesh Annayya <dinesha@opencores.org>
+# // //////////////////////////////////////////////////////////////////////////
+# inputs expected as env vars
+#set opt $::env(SYNTH_OPT)
+########### config.tcl ##################
+# User config
+
+# User config
+set ::env(DESIGN_DIR) ../
+
+set ::env(PROJ_DIR) ../../../../
+
+# User config
+set ::env(DESIGN_NAME) clk_mux
+
+# Change if needed
+set ::env(VERILOG_FILES) [glob \
+ ../src/clk_mux.v ]
+
+
+set ::env(SYNTH_DEFINES) [list YOSYS ]
+
+
+set ::env(LIB_SYNTH) ./tmp/trimmed.lib
+
+
+# Fill this
+set ::env(CLOCK_PERIOD) "10"
+#set ::env(CLOCK_PORT) "mclk"
+set ::env(CLOCK_TREE_SYNTH) 0
+
+set ::env(RUN_SIMPLE_CTS) 0
+set ::env(SYNTH_BUFFERING) 0
+set ::env(SYNTH_SIZING) 0
+
+set ::env(SYNTH_DRIVING_CELL) "sky130_fd_sc_hd__inv_8"
+set ::env(SYNTH_CAP_LOAD) "17.65"
+set ::env(SYNTH_MAX_TRAN) "[expr {0.1*10.0}]"
+
+set ::env(SYNTH_MAX_FANOUT) 6
+set ::env(FP_CORE_UTIL) 50
+set ::env(PL_TARGET_DENSITY) [ expr ($::env(FP_CORE_UTIL)+5) / 100.0 ]
+set ::env(CELL_PAD) 4
+
+set ::env(SYNTH_NO_FLAT) "0"
+
+
+set ::env(SYNTH_STRATEGY) "AREA 0"
+set ::env(SYNTH_TIELO_PORT) "sky130_fd_sc_hd__conb_1 LO"
+set ::env(SYNTH_TIEHI_PORT) "sky130_fd_sc_hd__conb_1 HI"
+set ::env(SYNTH_MIN_BUF_PORT) "sky130_fd_sc_hd__buf_2 A X"
+
+
+#set ::env(CLOCK_NET) $::env(CLOCK_PORT)
+
+
+
+set ::env(yosys_tmp_file_tag) "./tmp/"
+set ::env(TMP_DIR) "./tmp/"
+set ::env(yosys_netlist_dir) "./netlist"
+set ::env(yosys_report_file_tag) "./reports/yosys"
+set ::env(yosys_result_file_tag) "./reports/yosys.synthesis"
+
+set ::env(SAVE_NETLIST) $::env(yosys_netlist_dir)/$::env(DESIGN_NAME).gv
+
+
+
+########### End of config.tcl
+set buffering $::env(SYNTH_BUFFERING)
+set sizing $::env(SYNTH_SIZING)
+
+yosys -import
+
+set vtop $::env(DESIGN_NAME)
+#set sdc_file $::env(SDC_FILE)
+set sclib $::env(LIB_SYNTH)
+
+if { [info exists ::env(SYNTH_DEFINES) ] } {
+ foreach define $::env(SYNTH_DEFINES) {
+ log "Defining $define"
+ verilog_defines -D$define
+ }
+}
+
+set vIdirsArgs ""
+if {[info exist ::env(VERILOG_INCLUDE_DIRS)]} {
+ foreach dir $::env(VERILOG_INCLUDE_DIRS) {
+ log "Adding include file -I$dir "
+ lappend vIdirsArgs "-I$dir"
+ }
+ set vIdirsArgs [join $vIdirsArgs]
+}
+
+
+
+if { [info exists ::env(EXTRA_LIBS) ] } {
+ foreach lib $::env(EXTRA_LIBS) {
+ read_liberty {*}$vIdirsArgs -lib -ignore_miss_dir -setattr blackbox $lib
+ }
+}
+
+
+
+# ns expected (in sdc as well)
+set clock_period [expr {$::env(CLOCK_PERIOD)*1000}]
+
+set driver $::env(SYNTH_DRIVING_CELL)
+set cload $::env(SYNTH_CAP_LOAD)
+# input pin cap of IN_3VX8
+set max_FO $::env(SYNTH_MAX_FANOUT)
+if {![info exist ::env(SYNTH_MAX_TRAN)]} {
+ set ::env(SYNTH_MAX_TRAN) [expr {0.1*$clock_period}]
+} else {
+ set ::env(SYNTH_MAX_TRAN) [expr {$::env(SYNTH_MAX_TRAN) * 1000}]
+}
+set max_Tran $::env(SYNTH_MAX_TRAN)
+
+
+# Mapping parameters
+set A_factor 0.00
+set B_factor 0.88
+set F_factor 0.00
+
+# Don't change these unless you know what you are doing
+set stat_ext ".stat.rpt"
+set chk_ext ".chk.rpt"
+set gl_ext ".gl.v"
+set constr_ext ".$clock_period.constr"
+set timing_ext ".timing.txt"
+set abc_ext ".abc"
+
+
+# get old sdc, add library specific stuff for abc scripts
+set sdc_file $::env(yosys_tmp_file_tag).sdc
+set outfile [open ${sdc_file} w]
+#puts $outfile $sdc_data
+puts $outfile "set_driving_cell ${driver}"
+puts $outfile "set_load ${cload}"
+close $outfile
+
+
+# ABC Scrips
+set abc_rs_K "resub,-K,"
+set abc_rs "resub"
+set abc_rsz "resub,-z"
+set abc_rw_K "rewrite,-K,"
+set abc_rw "rewrite"
+set abc_rwz "rewrite,-z"
+set abc_rf "refactor"
+set abc_rfz "refactor,-z"
+set abc_b "balance"
+
+set abc_resyn2 "${abc_b}; ${abc_rw}; ${abc_rf}; ${abc_b}; ${abc_rw}; ${abc_rwz}; ${abc_b}; ${abc_rfz}; ${abc_rwz}; ${abc_b}"
+set abc_share "strash; multi,-m; ${abc_resyn2}"
+set abc_resyn2a "${abc_b};${abc_rw};${abc_b};${abc_rw};${abc_rwz};${abc_b};${abc_rwz};${abc_b}"
+set abc_resyn3 "balance;resub;resub,-K,6;balance;resub,-z;resub,-z,-K,6;balance;resub,-z,-K,5;balance"
+set abc_resyn2rs "${abc_b};${abc_rs_K},6;${abc_rw};${abc_rs_K},6,-N,2;${abc_rf};${abc_rs_K},8;${abc_rw};${abc_rs_K},10;${abc_rwz};${abc_rs_K},10,-N,2;${abc_b},${abc_rs_K},12;${abc_rfz};${abc_rs_K},12,-N,2;${abc_rwz};${abc_b}"
+
+set abc_choice "fraig_store; ${abc_resyn2}; fraig_store; ${abc_resyn2}; fraig_store; fraig_restore"
+set abc_choice2 "fraig_store; balance; fraig_store; ${abc_resyn2}; fraig_store; ${abc_resyn2}; fraig_store; ${abc_resyn2}; fraig_store; fraig_restore"
+
+set abc_map_old_cnt "map,-p,-a,-B,0.2,-A,0.9,-M,0"
+set abc_map_old_dly "map,-p,-B,0.2,-A,0.9,-M,0"
+set abc_retime_area "retime,-D,{D},-M,5"
+set abc_retime_dly "retime,-D,{D},-M,6"
+set abc_map_new_area "amap,-m,-Q,0.1,-F,20,-A,20,-C,5000"
+
+set abc_area_recovery_1 "${abc_choice}; map;"
+set abc_area_recovery_2 "${abc_choice2}; map;"
+
+set map_old_cnt "map,-p,-a,-B,0.2,-A,0.9,-M,0"
+set map_old_dly "map,-p,-B,0.2,-A,0.9,-M,0"
+set abc_retime_area "retime,-D,{D},-M,5"
+set abc_retime_dly "retime,-D,{D},-M,6"
+set abc_map_new_area "amap,-m,-Q,0.1,-F,20,-A,20,-C,5000"
+
+if {$buffering==1} {
+ set abc_fine_tune "buffer,-N,${max_FO},-S,${max_Tran};upsize,{D};dnsize,{D}"
+} elseif {$sizing} {
+ set abc_fine_tune "upsize,{D};dnsize,{D}"
+} else {
+ set abc_fine_tune ""
+}
+
+
+set delay_scripts [list \
+ "+read_constr,${sdc_file};fx;mfs;strash;refactor;${abc_resyn2};${abc_retime_dly}; scleanup;${abc_map_old_dly};retime,-D,{D};${abc_fine_tune};stime,-p;print_stats -m" \
+ \
+ "+read_constr,${sdc_file};fx;mfs;strash;refactor;${abc_resyn2};${abc_retime_dly}; scleanup;${abc_choice2};${abc_map_old_dly};${abc_area_recovery_2}; retime,-D,{D};${abc_fine_tune};stime,-p;print_stats -m" \
+ \
+ "+read_constr,${sdc_file};fx;mfs;strash;refactor;${abc_resyn2};${abc_retime_dly}; scleanup;${abc_choice};${abc_map_old_dly};${abc_area_recovery_1}; retime,-D,{D};${abc_fine_tune};stime,-p;print_stats -m" \
+ \
+ "+read_constr,${sdc_file};fx;mfs;strash;refactor;${abc_resyn2};${abc_retime_area};scleanup;${abc_choice2};${abc_map_new_area};${abc_choice2};${abc_map_old_dly};retime,-D,{D};${abc_fine_tune};stime,-p;print_stats -m" \
+ ]
+
+set area_scripts [list \
+ "+read_constr,${sdc_file};fx;mfs;strash;refactor;${abc_resyn2};${abc_retime_area};scleanup;${abc_choice2};${abc_map_new_area};retime,-D,{D};${abc_fine_tune};stime,-p;print_stats -m" \
+ \
+ "+read_constr,${sdc_file};fx;mfs;strash;refactor;${abc_resyn2};${abc_retime_area};scleanup;${abc_choice2};${abc_map_new_area};${abc_choice2};${abc_map_new_area};retime,-D,{D};${abc_fine_tune};stime,-p;print_stats -m" \
+ \
+ "+read_constr,${sdc_file};fx;mfs;strash;refactor;${abc_choice2};${abc_retime_area};scleanup;${abc_choice2};${abc_map_new_area};${abc_choice2};${abc_map_new_area};retime,-D,{D};${abc_fine_tune};stime,-p;print_stats -m" \
+ ]
+
+set all_scripts [list {*}$delay_scripts {*}$area_scripts]
+
+set strategy_parts [split $::env(SYNTH_STRATEGY)]
+
+proc synth_strategy_format_err { } {
+ upvar area_scripts area_scripts
+ upvar delay_scripts delay_scripts
+ log -stderr "\[ERROR] Misformatted SYNTH_STRATEGY (\"$::env(SYNTH_STRATEGY)\")."
+ log -stderr "\[ERROR] Correct format is \"DELAY|AREA 0-[expr [llength $delay_scripts]-1]|0-[expr [llength $area_scripts]-1]\"."
+ exit 1
+}
+
+if { [llength $strategy_parts] != 2 } {
+ synth_strategy_format_err
+}
+
+set strategy_type [lindex $strategy_parts 0]
+set strategy_type_idx [lindex $strategy_parts 1]
+
+if { $strategy_type != "AREA" && $strategy_type != "DELAY" } {
+ log -stderr "\[ERROR] AREA|DELAY tokens not found. ($strategy_type)"
+ synth_strategy_format_err
+}
+
+if { $strategy_type == "DELAY" && $strategy_type_idx >= [llength $delay_scripts] } {
+ log -stderr "\[ERROR] strategy index ($strategy_type_idx) is too high."
+ synth_strategy_format_err
+}
+
+if { $strategy_type == "AREA" && $strategy_type_idx >= [llength $area_scripts] } {
+ log -stderr "\[ERROR] strategy index ($strategy_type_idx) is too high."
+ synth_strategy_format_err
+}
+
+if { $strategy_type == "DELAY" } {
+ set strategy $strategy_type_idx
+} else {
+ set strategy [expr {[llength $delay_scripts]+$strategy_type_idx}]
+}
+
+
+for { set i 0 } { $i < [llength $::env(VERILOG_FILES)] } { incr i } {
+ read_verilog -sv {*}$vIdirsArgs [lindex $::env(VERILOG_FILES) $i]
+}
+
+if { [info exists ::env(VERILOG_FILES_BLACKBOX)] } {
+ foreach verilog_file $::env(VERILOG_FILES_BLACKBOX) {
+ read_verilog -sv {*}$vIdirsArgs -lib $verilog_file
+ }
+}
+select -module $vtop
+show -format dot -prefix $::env(TMP_DIR)/synthesis/hierarchy
+select -clear
+
+hierarchy -check -top $vtop
+
+# Infer tri-state buffers.
+set tbuf_map false
+if { [info exists ::env(TRISTATE_BUFFER_MAP)] } {
+ if { [file exists $::env(TRISTATE_BUFFER_MAP)] } {
+ set tbuf_map true
+ tribuf
+ } else {
+ log "WARNING: TRISTATE_BUFFER_MAP is defined but could not be found: $::env(TRISTATE_BUFFER_MAP)"
+ }
+}
+
+if { $::env(SYNTH_NO_FLAT) } {
+ synth -top $vtop
+} else {
+ synth -top $vtop -flatten
+}
+
+share -aggressive
+opt
+opt_clean -purge
+
+tee -o "$::env(yosys_report_file_tag)_pre.stat" stat
+
+# Map tri-state buffers.
+if { $tbuf_map } {
+ log {mapping tbuf}
+ techmap -map $::env(TRISTATE_BUFFER_MAP)
+ simplemap
+}
+
+# handle technology mapping of 4-MUX, and tell Yosys to infer 4-muxes
+if { [info exists ::env(SYNTH_MUX4_MAP)] && [file exists $::env(SYNTH_MUX4_MAP)] } {
+ muxcover -mux4
+ techmap -map $::env(SYNTH_MUX4_MAP)
+ simplemap
+}
+
+# handle technology mapping of 2-MUX
+if { [info exists ::env(SYNTH_MUX_MAP)] && [file exists $::env(SYNTH_MUX_MAP)] } {
+ techmap -map $::env(SYNTH_MUX_MAP)
+ simplemap
+}
+
+# handle technology mapping of latches
+if { [info exists ::env(SYNTH_LATCH_MAP)] && [file exists $::env(SYNTH_LATCH_MAP)] } {
+ techmap -map $::env(SYNTH_LATCH_MAP)
+ simplemap
+}
+
+dfflibmap -liberty $sclib
+tee -o "$::env(yosys_report_file_tag)_dff.stat" stat
+
+if { [info exists ::env(SYNTH_EXPLORE)] && $::env(SYNTH_EXPLORE) } {
+ design -save myDesign
+
+ for { set index 0 } { $index < [llength $all_scripts] } { incr index } {
+ log "\[INFO\]: ABC: WireLoad : S_$index"
+ design -load myDesign
+
+ abc -D $clock_period \
+ -constr "$sdc_file" \
+ -liberty $sclib \
+ -script [lindex $all_scripts $index]
+
+ setundef -zero
+
+ hilomap -hicell {*}$::env(SYNTH_TIEHI_PORT) -locell {*}$::env(SYNTH_TIELO_PORT)
+
+ # get rid of the assignments that make verilog2def fail
+ splitnets
+ opt_clean -purge
+ insbuf -buf {*}$::env(SYNTH_MIN_BUF_PORT)
+
+ tee -o "$::env(yosys_report_file_tag)_$index$chk_ext" check
+ write_verilog -noattr -noexpr -nohex -nodec -defparam "$::env(yosys_result_file_tag)_$index.v"
+ design -reset
+ }
+} else {
+
+ log "\[INFO\]: ABC: WireLoad : S_$strategy"
+
+ abc -D $clock_period \
+ -constr "$sdc_file" \
+ -liberty $sclib \
+ -script [lindex $all_scripts $strategy] \
+ -showtmp;
+
+ setundef -zero
+
+ hilomap -hicell {*}$::env(SYNTH_TIEHI_PORT) -locell {*}$::env(SYNTH_TIELO_PORT)
+
+ # get rid of the assignments that make verilog2def fail
+ splitnets
+ opt_clean -purge
+ insbuf -buf {*}$::env(SYNTH_MIN_BUF_PORT)
+
+ tee -o "$::env(yosys_report_file_tag)_$strategy$chk_ext" check
+ write_verilog -noattr -noexpr -nohex -nodec -defparam "$::env(SAVE_NETLIST)"
+}
+
+if { $::env(SYNTH_NO_FLAT) } {
+ design -reset
+ file copy -force $::env(SAVE_NETLIST) $::env(yosys_tmp_file_tag)_unflat.v
+ read_verilog -sv $::env(SAVE_NETLIST)
+ synth -top $vtop -flatten
+ splitnets
+ opt_clean -purge
+ insbuf -buf {*}$::env(SYNTH_MIN_BUF_PORT)
+ write_verilog -noattr -noexpr -nohex -nodec -defparam "$::env(SAVE_NETLIST)"
+ tee -o "$::env(yosys_report_file_tag)_$strategy$chk_ext" check
+}
diff --git a/verilog/rtl/digital_core/filelist_rtl.f b/verilog/rtl/digital_core/filelist_rtl.f
new file mode 100755
index 0000000..3bb3d95
--- /dev/null
+++ b/verilog/rtl/digital_core/filelist_rtl.f
@@ -0,0 +1,75 @@
+//////////////////////////////////////////////////////////////////////////////
+// SPDX-FileCopyrightText: 2021, Dinesh Annayya
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+// SPDX-License-Identifier: Apache-2.0
+// SPDX-FileContributor: Dinesh Annayya <dinesha@opencores.org>
+// //////////////////////////////////////////////////////////////////////////
++incdir+../sdram_ctrl/src/defs
++incdir+../syntacore/scr1/src/includes
+
+../spi_master/src/spim_top.sv
+../spi_master/src/spim_regs.sv
+../spi_master/src/spim_clkgen.sv
+../spi_master/src/spim_ctrl.sv
+../spi_master/src/spim_rx.sv
+../spi_master/src/spim_tx.sv
+
+../sdram_ctrl/src/top/sdrc_top.v
+../sdram_ctrl/src/wb2sdrc/wb2sdrc.v
+../lib/async_fifo.sv
+../sdram_ctrl/src/core/sdrc_core.v
+../sdram_ctrl/src/core/sdrc_bank_ctl.v
+../sdram_ctrl/src/core/sdrc_bank_fsm.v
+../sdram_ctrl/src/core/sdrc_bs_convert.v
+../sdram_ctrl/src/core/sdrc_req_gen.v
+../sdram_ctrl/src/core/sdrc_xfr_ctl.v
+
+../lib/wb_crossbar.v
+../lib/registers.v
+../lib/clk_ctl.v
+./src/glbl_cfg.sv
+./src/digital_core.sv
+
+
+../syntacore/scr1/src/core/pipeline/scr1_pipe_hdu.sv
+../syntacore/scr1/src/core/pipeline/scr1_pipe_tdu.sv
+../syntacore/scr1/src/core/pipeline/scr1_ipic.sv
+../syntacore/scr1/src/core/pipeline/scr1_pipe_csr.sv
+../syntacore/scr1/src/core/pipeline/scr1_pipe_exu.sv
+../syntacore/scr1/src/core/pipeline/scr1_pipe_ialu.sv
+../syntacore/scr1/src/core/pipeline/scr1_pipe_idu.sv
+../syntacore/scr1/src/core/pipeline/scr1_pipe_ifu.sv
+../syntacore/scr1/src/core/pipeline/scr1_pipe_lsu.sv
+../syntacore/scr1/src/core/pipeline/scr1_pipe_mprf.sv
+../syntacore/scr1/src/core/pipeline/scr1_pipe_top.sv
+../syntacore/scr1/src/core/primitives/scr1_reset_cells.sv
+../syntacore/scr1/src/core/primitives/scr1_cg.sv
+../syntacore/scr1/src/core/scr1_clk_ctrl.sv
+../syntacore/scr1/src/core/scr1_tapc_shift_reg.sv
+../syntacore/scr1/src/core/scr1_tapc.sv
+../syntacore/scr1/src/core/scr1_tapc_synchronizer.sv
+../syntacore/scr1/src/core/scr1_core_top.sv
+../syntacore/scr1/src/core/scr1_dm.sv
+../syntacore/scr1/src/core/scr1_dmi.sv
+../syntacore/scr1/src/core/scr1_scu.sv
+
+../syntacore/scr1/src/top/scr1_dmem_router.sv
+../syntacore/scr1/src/top/scr1_dp_memory.sv
+../syntacore/scr1/src/top/scr1_tcm.sv
+../syntacore/scr1/src/top/scr1_timer.sv
+../syntacore/scr1/src/top/scr1_dmem_wb.sv
+../syntacore/scr1/src/top/scr1_imem_wb.sv
+../syntacore/scr1/src/top/scr1_top_wb.sv
+../lib/sync_fifo.sv
+
diff --git a/verilog/rtl/digital_core/run_modelsim b/verilog/rtl/digital_core/run_modelsim
new file mode 100755
index 0000000..2b56b12
--- /dev/null
+++ b/verilog/rtl/digital_core/run_modelsim
@@ -0,0 +1,21 @@
+# //////////////////////////////////////////////////////////////////////////////
+# // SPDX-FileCopyrightText: 2021, Dinesh Annayya
+# //
+# // Licensed under the Apache License, Version 2.0 (the "License");
+# // you may not use this file except in compliance with the License.
+# // You may obtain a copy of the License at
+# //
+# // http://www.apache.org/licenses/LICENSE-2.0
+# //
+# // Unless required by applicable law or agreed to in writing, software
+# // distributed under the License is distributed on an "AS IS" BASIS,
+# // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# // See the License for the specific language governing permissions and
+# // limitations under the License.
+# // SPDX-License-Identifier: Apache-2.0
+# // SPDX-FileContributor: Dinesh Annayya <dinesha@opencores.org>
+# // //////////////////////////////////////////////////////////////////////////
+
+vlib work
+vlog -f filelist_rtl.f
+vsim -c digital_core -suppress vsim-3999 -do "exit"
diff --git a/verilog/rtl/digital_core/src/digital_core.sv b/verilog/rtl/digital_core/src/digital_core.sv
new file mode 100644
index 0000000..2eb4b27
--- /dev/null
+++ b/verilog/rtl/digital_core/src/digital_core.sv
@@ -0,0 +1,805 @@
+//////////////////////////////////////////////////////////////////////////////
+// SPDX-FileCopyrightText: 2021 , Dinesh Annayya
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+// SPDX-License-Identifier: Apache-2.0
+// SPDX-FileContributor: Created by Dinesh Annayya <dinesha@opencores.org>
+//
+//////////////////////////////////////////////////////////////////////
+//// ////
+//// Digital core ////
+//// ////
+//// This file is part of the YIFive cores project ////
+//// https://github.com/dineshannayya/yifive_r0.git ////
+//// http://www.opencores.org/cores/yifive/ ////
+//// ////
+//// Description ////
+//// This is digital core and integrate all the main block ////
+//// here. Following block are integrated here ////
+//// 1. Risc V Core ////
+//// 2. SPI Master ////
+//// 3. Wishbone Cross Bar ////
+//// ////
+//// To Do: ////
+//// nothing ////
+//// ////
+//// Author(s): ////
+//// - Dinesh Annayya, dinesha@opencores.org ////
+//// ////
+//// Revision : ////
+//// 0.1 - 16th Feb 2021, Dinesh A ////
+//// Initial integration with Risc-V core + ////
+//// Wishbone Cross Bar + SPI Master ////
+//// 0.2 - 17th June 2021, Dinesh A ////
+//// 1. In risc core, wishbone and core domain is ////
+//// created ////
+//// 2. cpu and rtc clock are generated in glbl reg block ////
+//// 3. in wishbone interconnect:- Stagging flop are added ////
+//// at interface to break wishbone timing path ////
+//// 4. buswidth warning are fixed inside spi_master ////
+//// modified rtl files are ////
+//// verilog/rtl/digital_core/src/digital_core.sv ////
+//// verilog/rtl/digital_core/src/glbl_cfg.sv ////
+//// verilog/rtl/lib/wb_stagging.sv ////
+//// verilog/rtl/syntacore/scr1/src/top/scr1_dmem_wb.sv ////
+//// verilog/rtl/syntacore/scr1/src/top/scr1_imem_wb.sv ////
+//// verilog/rtl/syntacore/scr1/src/top/scr1_top_wb.sv ////
+//// verilog/rtl/user_project_wrapper.v ////
+//// verilog/rtl/wb_interconnect/src/wb_interconnect.sv ////
+//// verilog/rtl/spi_master/src/spim_clkgen.sv ////
+//// verilog/rtl/spi_master/src/spim_ctrl.sv ////
+//// 0.3 - 20th June 2021, Dinesh A ////
+//// 1. uart core is integrated ////
+//// 2. 3rd Slave ported added to wishbone interconnect ////
+//// 0.4 - 25th June 2021, Dinesh A ////
+//// Moved the pad logic inside sdram,spi,uart block to ////
+//// avoid logic at digital core level ////
+//// 0.5 - 25th June 2021, Dinesh A ////
+//// Since carvel gives only 16MB address space for user ////
+//// space, we have implemented indirect address select ////
+//// with 8 bit bank select given inside wb_host ////
+//// core Address = {Bank_Sel[7:0], Wb_Address[23:0] ////
+//// caravel user address space is ////
+//// 0x3000_0000 to 0x30FF_FFFF ////
+//// 0.6 - 27th June 2021, Dinesh A ////
+//// Digital core level tie are moved inside IP to avoid ////
+//// power hook up at core level ////
+//// u_risc_top - test_mode & test_rst_n ////
+//// u_intercon - s*_wbd_err_i ////
+//// unused wb_cti_i is removed from u_sdram_ctrl ////
+//// 0.7 - 28th June 2021, Dinesh A ////
+//// wb_interconnect master port are interchanged for ////
+//// better physical placement. ////
+//// m0 - External HOST ////
+//// m1 - RISC IMEM ////
+//// m2 - RISC DMEM ////
+//// 0.8 - 6th July 2021, Dinesh A ////
+//// For Better SDRAM Interface timing we have taping ////
+//// sdram_clock goint to io_out[29] directly from ////
+//// global register block, this help in better SDRAM ////
+//// interface timing control ////
+//// ////
+//////////////////////////////////////////////////////////////////////
+//// ////
+//// Copyright (C) 2000 Authors and OPENCORES.ORG ////
+//// ////
+//// This source file may be used and distributed without ////
+//// restriction provided that this copyright statement is not ////
+//// removed from the file and that any derivative work contains ////
+//// the original copyright notice and the associated disclaimer. ////
+//// ////
+//// This source file is free software; you can redistribute it ////
+//// and/or modify it under the terms of the GNU Lesser General ////
+//// Public License as published by the Free Software Foundation; ////
+//// either version 2.1 of the License, or (at your option) any ////
+//// later version. ////
+//// ////
+//// This source is distributed in the hope that it will be ////
+//// useful, but WITHOUT ANY WARRANTY; without even the implied ////
+//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR ////
+//// PURPOSE. See the GNU Lesser General Public License for more ////
+//// details. ////
+//// ////
+//// You should have received a copy of the GNU Lesser General ////
+//// Public License along with this source; if not, download it ////
+//// from http://www.opencores.org/lgpl.shtml ////
+//// ////
+//////////////////////////////////////////////////////////////////////
+
+
+module digital_core (
+`ifdef USE_POWER_PINS
+ inout vdda1, // User area 1 3.3V supply
+ inout vdda2, // User area 2 3.3V supply
+ inout vssa1, // User area 1 analog ground
+ inout vssa2, // User area 2 analog ground
+ inout vccd1, // User area 1 1.8V supply
+ inout vccd2, // User area 2 1.8v supply
+ inout vssd1, // User area 1 digital ground
+ inout vssd2, // User area 2 digital ground
+`endif
+ input wire wb_clk_i , // System clock
+ input wire user_clock2 , // user Clock
+ input wire wb_rst_i , // Regular Reset signal
+
+ input wire wbs_cyc_i , // strobe/request
+ input wire wbs_stb_i , // strobe/request
+ input wire [WB_WIDTH-1:0] wbs_adr_i , // address
+ input wire wbs_we_i , // write
+ input wire [WB_WIDTH-1:0] wbs_dat_i , // data output
+ input wire [3:0] wbs_sel_i , // byte enable
+ output wire [WB_WIDTH-1:0] wbs_dat_o , // data input
+ output wire wbs_ack_o , // acknowlegement
+
+ // Analog (direct connection to GPIO pad---use with caution)
+ // Note that analog I/O is not available on the 7 lowest-numbered
+ // GPIO pads, and so the analog_io indexing is offset from the
+ // GPIO indexing by 7 (also upper 2 GPIOs do not have analog_io).
+ inout [`MPRJ_IO_PADS-10:0] analog_io,
+
+ // Logic Analyzer Signals
+ input wire [127:0] la_data_in ,
+ output wire [127:0] la_data_out ,
+ input wire [127:0] la_oenb ,
+
+
+ // IOs
+ input wire [37:0] io_in ,
+ output wire [37:0] io_out ,
+ output wire [37:0] io_oeb ,
+
+ output wire [2:0] user_irq
+
+);
+
+//---------------------------------------------------
+// Local Parameter Declaration
+// --------------------------------------------------
+
+parameter SDR_DW = 8; // SDR Data Width
+parameter SDR_BW = 1; // SDR Byte Width
+parameter WB_WIDTH = 32; // WB ADDRESS/DARA WIDTH
+
+//---------------------------------------------------------------------
+// Wishbone Risc V Instruction Memory Interface
+//---------------------------------------------------------------------
+wire wbd_riscv_imem_stb_i; // strobe/request
+wire [WB_WIDTH-1:0] wbd_riscv_imem_adr_i; // address
+wire wbd_riscv_imem_we_i; // write
+wire [WB_WIDTH-1:0] wbd_riscv_imem_dat_i; // data output
+wire [3:0] wbd_riscv_imem_sel_i; // byte enable
+wire [WB_WIDTH-1:0] wbd_riscv_imem_dat_o; // data input
+wire wbd_riscv_imem_ack_o; // acknowlegement
+wire wbd_riscv_imem_err_o; // error
+
+//---------------------------------------------------------------------
+// RISC V Wishbone Data Memory Interface
+//---------------------------------------------------------------------
+wire wbd_riscv_dmem_stb_i; // strobe/request
+wire [WB_WIDTH-1:0] wbd_riscv_dmem_adr_i; // address
+wire wbd_riscv_dmem_we_i; // write
+wire [WB_WIDTH-1:0] wbd_riscv_dmem_dat_i; // data output
+wire [3:0] wbd_riscv_dmem_sel_i; // byte enable
+wire [WB_WIDTH-1:0] wbd_riscv_dmem_dat_o; // data input
+wire wbd_riscv_dmem_ack_o; // acknowlegement
+wire wbd_riscv_dmem_err_o; // error
+
+//---------------------------------------------------------------------
+// WB HOST Interface
+//---------------------------------------------------------------------
+wire wbd_int_cyc_i; // strobe/request
+wire wbd_int_stb_i; // strobe/request
+wire [WB_WIDTH-1:0] wbd_int_adr_i; // address
+wire wbd_int_we_i; // write
+wire [WB_WIDTH-1:0] wbd_int_dat_i; // data output
+wire [3:0] wbd_int_sel_i; // byte enable
+wire [WB_WIDTH-1:0] wbd_int_dat_o; // data input
+wire wbd_int_ack_o; // acknowlegement
+wire wbd_int_err_o; // error
+//---------------------------------------------------------------------
+// SPI Master Wishbone Interface
+//---------------------------------------------------------------------
+wire wbd_spim_stb_o; // strobe/request
+wire [WB_WIDTH-1:0] wbd_spim_adr_o; // address
+wire wbd_spim_we_o; // write
+wire [WB_WIDTH-1:0] wbd_spim_dat_o; // data output
+wire [3:0] wbd_spim_sel_o; // byte enable
+wire wbd_spim_cyc_o ;
+wire [WB_WIDTH-1:0] wbd_spim_dat_i; // data input
+wire wbd_spim_ack_i; // acknowlegement
+wire wbd_spim_err_i; // error
+
+//---------------------------------------------------------------------
+// SPI Master Wishbone Interface
+//---------------------------------------------------------------------
+wire wbd_sdram_stb_o ;
+wire [WB_WIDTH-1:0] wbd_sdram_adr_o ;
+wire wbd_sdram_we_o ; // 1 - Write, 0 - Read
+wire [WB_WIDTH-1:0] wbd_sdram_dat_o ;
+wire [WB_WIDTH/8-1:0] wbd_sdram_sel_o ; // Byte enable
+wire wbd_sdram_cyc_o ;
+wire [2:0] wbd_sdram_cti_o ;
+wire [WB_WIDTH-1:0] wbd_sdram_dat_i ;
+wire wbd_sdram_ack_i ;
+
+//---------------------------------------------------------------------
+// Global Register Wishbone Interface
+//---------------------------------------------------------------------
+wire wbd_glbl_stb_o; // strobe/request
+wire [7:0] wbd_glbl_adr_o; // address
+wire wbd_glbl_we_o; // write
+wire [WB_WIDTH-1:0] wbd_glbl_dat_o; // data output
+wire [3:0] wbd_glbl_sel_o; // byte enable
+wire wbd_glbl_cyc_o ;
+wire [WB_WIDTH-1:0] wbd_glbl_dat_i; // data input
+wire wbd_glbl_ack_i; // acknowlegement
+wire wbd_glbl_err_i; // error
+
+//---------------------------------------------------------------------
+// Global Register Wishbone Interface
+//---------------------------------------------------------------------
+wire wbd_uart_stb_o; // strobe/request
+wire [7:0] wbd_uart_adr_o; // address
+wire wbd_uart_we_o; // write
+wire [7:0] wbd_uart_dat_o; // data output
+wire wbd_uart_sel_o; // byte enable
+wire wbd_uart_cyc_o ;
+wire [7:0] wbd_uart_dat_i; // data input
+wire wbd_uart_ack_i; // acknowlegement
+wire wbd_uart_err_i; // error
+
+//----------------------------------------------------
+// CPU Configuration
+//----------------------------------------------------
+wire cpu_rst_n ;
+wire spi_rst_n ;
+wire sdram_rst_n ;
+wire sdram_clk ;
+wire cpu_clk ;
+wire rtc_clk ;
+wire wbd_clk_int ;
+wire wbd_int_rst_n ;
+
+wire [31:0] fuse_mhartid ;
+wire [15:0] irq_lines ;
+wire soft_irq ;
+
+wire [7:0] cfg_glb_ctrl ;
+wire [31:0] cfg_clk_ctrl1 ;
+wire [31:0] cfg_clk_ctrl2 ;
+wire [3:0] cfg_cska_wi ; // clock skew adjust for wishbone interconnect
+wire [3:0] cfg_cska_riscv; // clock skew adjust for riscv
+wire [3:0] cfg_cska_uart ; // clock skew adjust for uart
+wire [3:0] cfg_cska_spi ; // clock skew adjust for spi
+wire [3:0] cfg_cska_sdram; // clock skew adjust for sdram
+wire [3:0] cfg_cska_glbl ; // clock skew adjust for global reg
+wire [3:0] cfg_cska_wh ; // clock skew adjust for web host
+
+
+wire wbd_clk_wi ; // clock for wishbone interconnect
+wire wbd_clk_riscv ; // clock for riscv
+wire wbd_clk_uart ; // clock for uart
+wire wbd_clk_spi ; // clock for spi
+wire wbd_clk_sdram ; // clock for sdram
+wire wbd_clk_glbl ; // clock for global reg
+wire wbd_clk_wh ; // clock for global reg
+
+wire [3:0] cfg_cska_sd_co; // clock skew adjust for sdram clock out
+wire [3:0] cfg_cska_sd_ci; // clock skew adjust for sdram clock input
+wire [3:0] cfg_cska_sp_co; // clock skew adjust for SPI clock out
+
+wire io_out_29_ ; // Internally tapped SDRAM clock
+wire io_in_29_ ; // Clock Skewed Pad SDRAM clock
+wire io_in_30_ ; // SPI clock out
+
+//------------------------------------------------
+// Configuration Parameter
+//------------------------------------------------
+wire [1:0] cfg_sdr_width ; // 2'b00 - 32 Bit SDR, 2'b01 - 16 Bit SDR, 2'b1x - 8 Bit
+wire [1:0] cfg_colbits ; // 2'b00 - 8 Bit column address,
+wire sdr_init_done ; // Indicate SDRAM Initialisation Done
+wire [3:0] cfg_sdr_tras_d ; // Active to precharge delay
+wire [3:0] cfg_sdr_trp_d ; // Precharge to active delay
+wire [3:0] cfg_sdr_trcd_d ; // Active to R/W delay
+wire cfg_sdr_en ; // Enable SDRAM controller
+wire [1:0] cfg_req_depth ; // Maximum Request accepted by SDRAM controller
+wire [12:0] cfg_sdr_mode_reg ;
+wire [2:0] cfg_sdr_cas ; // SDRAM CAS Latency
+wire [3:0] cfg_sdr_trcar_d ; // Auto-refresh period
+wire [3:0] cfg_sdr_twr_d ; // Write recovery delay
+wire [11: 0] cfg_sdr_rfsh ;
+wire [2 : 0] cfg_sdr_rfmax ;
+
+
+
+
+
+/////////////////////////////////////////////////////////
+// Generating acive low wishbone reset
+// //////////////////////////////////////////////////////
+assign wbd_int_rst_n = cfg_glb_ctrl[0];
+assign cpu_rst_n = cfg_glb_ctrl[1];
+assign spi_rst_n = cfg_glb_ctrl[2];
+assign sdram_rst_n = cfg_glb_ctrl[3];
+
+assign cfg_cska_wi = cfg_clk_ctrl1[3:0];
+assign cfg_cska_riscv = cfg_clk_ctrl1[7:4];
+assign cfg_cska_uart = cfg_clk_ctrl1[11:8];
+assign cfg_cska_spi = cfg_clk_ctrl1[15:12];
+assign cfg_cska_sdram = cfg_clk_ctrl1[19:16];
+assign cfg_cska_glbl = cfg_clk_ctrl1[23:20];
+assign cfg_cska_wh = cfg_clk_ctrl1[27:24];
+
+assign cfg_cska_sd_co = cfg_clk_ctrl2[3:0]; // SDRAM clock out control
+assign cfg_cska_sd_ci = cfg_clk_ctrl2[7:4]; // SDRAM clock in control
+assign cfg_cska_sp_co = cfg_clk_ctrl2[11:8];// SPI clock out control
+
+
+wb_host u_wb_host(
+
+ // Master Port
+ .wbm_rst_i (wb_rst_i ),
+ .wbm_clk_i (wb_clk_i ),
+ .wbm_cyc_i (wbs_cyc_i ),
+ .wbm_stb_i (wbs_stb_i ),
+ .wbm_adr_i (wbs_adr_i ),
+ .wbm_we_i (wbs_we_i ),
+ .wbm_dat_i (wbs_dat_i ),
+ .wbm_sel_i (wbs_sel_i ),
+ .wbm_dat_o (wbs_dat_o ),
+ .wbm_ack_o (wbs_ack_o ),
+ .wbm_err_o ( ),
+
+ // Slave Port
+ .wbs_clk_out (wbd_clk_int ),
+ .wbs_clk_i (wbd_clk_wh ),
+ .wbs_cyc_o (wbd_int_cyc_i ),
+ .wbs_stb_o (wbd_int_stb_i ),
+ .wbs_adr_o (wbd_int_adr_i ),
+ .wbs_we_o (wbd_int_we_i ),
+ .wbs_dat_o (wbd_int_dat_i ),
+ .wbs_sel_o (wbd_int_sel_i ),
+ .wbs_dat_i (wbd_int_dat_o ),
+ .wbs_ack_i (wbd_int_ack_o ),
+ .wbs_err_i (wbd_int_err_o ),
+
+ .cfg_glb_ctrl (cfg_glb_ctrl ),
+ .cfg_clk_ctrl1 (cfg_clk_ctrl1 ),
+ .cfg_clk_ctrl2 (cfg_clk_ctrl2 ),
+
+ // Logic Analyzer Signals
+ .la_data_in (la_data_in ),
+ .la_data_out (la_data_out ),
+ .la_oenb (la_oenb )
+ );
+
+
+
+
+//------------------------------------------------------------------------------
+// RISC V Core instance
+//------------------------------------------------------------------------------
+scr1_top_wb u_riscv_top (
+ // Reset
+ .pwrup_rst_n (wbd_int_rst_n ),
+ .rst_n (wbd_int_rst_n ),
+ .cpu_rst_n (cpu_rst_n ),
+
+ // Clock
+ .core_clk (cpu_clk ),
+ .rtc_clk (rtc_clk ),
+
+ // Fuses
+ .fuse_mhartid (fuse_mhartid ),
+
+ // IRQ
+ .irq_lines (irq_lines ),
+ .soft_irq (soft_irq ), // TODO - Interrupts
+
+ // DFT
+ // .test_mode (1'b0 ), // Moved inside IP
+ // .test_rst_n (1'b1 ), // Moved inside IP
+
+
+ .wb_rst_n (wbd_int_rst_n ),
+ .wb_clk (wbd_clk_riscv ),
+ // Instruction memory interface
+ .wbd_imem_stb_o (wbd_riscv_imem_stb_i ),
+ .wbd_imem_adr_o (wbd_riscv_imem_adr_i ),
+ .wbd_imem_we_o (wbd_riscv_imem_we_i ),
+ .wbd_imem_dat_o (wbd_riscv_imem_dat_i ),
+ .wbd_imem_sel_o (wbd_riscv_imem_sel_i ),
+ .wbd_imem_dat_i (wbd_riscv_imem_dat_o ),
+ .wbd_imem_ack_i (wbd_riscv_imem_ack_o ),
+ .wbd_imem_err_i (wbd_riscv_imem_err_o ),
+
+ // Data memory interface
+ .wbd_dmem_stb_o (wbd_riscv_dmem_stb_i ),
+ .wbd_dmem_adr_o (wbd_riscv_dmem_adr_i ),
+ .wbd_dmem_we_o (wbd_riscv_dmem_we_i ),
+ .wbd_dmem_dat_o (wbd_riscv_dmem_dat_i ),
+ .wbd_dmem_sel_o (wbd_riscv_dmem_sel_i ),
+ .wbd_dmem_dat_i (wbd_riscv_dmem_dat_o ),
+ .wbd_dmem_ack_i (wbd_riscv_dmem_ack_o ),
+ .wbd_dmem_err_i (wbd_riscv_dmem_err_o )
+);
+
+/*********************************************************
+* SPI Master
+* This is an implementation of an SPI master that is controlled via an AXI bus.
+* It has FIFOs for transmitting and receiving data.
+* It supports both the normal SPI mode and QPI mode with 4 data lines.
+* *******************************************************/
+
+spim_top
+#(
+`ifndef SYNTHESIS
+ .WB_WIDTH (WB_WIDTH)
+`endif
+) u_spi_master
+(
+ .mclk (wbd_clk_spi ),
+ .rst_n (spi_rst_n ),
+
+ .wbd_stb_i (wbd_spim_stb_o ),
+ .wbd_adr_i (wbd_spim_adr_o ),
+ .wbd_we_i (wbd_spim_we_o ),
+ .wbd_dat_i (wbd_spim_dat_o ),
+ .wbd_sel_i (wbd_spim_sel_o ),
+ .wbd_dat_o (wbd_spim_dat_i ),
+ .wbd_ack_o (wbd_spim_ack_i ),
+ .wbd_err_o (wbd_spim_err_i ),
+
+ .spi_debug (spi_debug ),
+
+ // Pad Interface
+ .io_in (io_in[35:30] ),
+ .io_out ({io_out[35:31],io_in_30_} ),
+ .io_oeb (io_oeb[35:30] )
+
+);
+
+
+sdrc_top
+ `ifndef SYNTHESIS
+ #(.APP_AW(WB_WIDTH),
+ .APP_DW(WB_WIDTH),
+ .APP_BW(4),
+ .SDR_DW(8),
+ .SDR_BW(1))
+ `endif
+ u_sdram_ctrl (
+ .cfg_sdr_width (cfg_sdr_width ),
+ .cfg_colbits (cfg_colbits ),
+
+ // WB bus
+ .wb_rst_n (wbd_int_rst_n ),
+ .wb_clk_i (wbd_clk_sdram ),
+
+ .wb_stb_i (wbd_sdram_stb_o ),
+ .wb_addr_i (wbd_sdram_adr_o ),
+ .wb_we_i (wbd_sdram_we_o ),
+ .wb_dat_i (wbd_sdram_dat_o ),
+ .wb_sel_i (wbd_sdram_sel_o ),
+ .wb_cyc_i (wbd_sdram_cyc_o ),
+ .wb_ack_o (wbd_sdram_ack_i ),
+ .wb_dat_o (wbd_sdram_dat_i ),
+
+
+ /* Interface to SDRAMs */
+ .sdram_clk (sdram_clk ),
+ .sdram_resetn (sdram_rst_n ),
+
+ /** Pad Interface **/
+ .io_in ({io_in_29_,io_in[28:0]} ),
+ .io_oeb (io_oeb[29:0] ),
+ .io_out ({io_out_29_,io_out[28:0]} ),
+
+ /* Parameters */
+ .sdr_init_done (sdr_init_done ),
+ .cfg_req_depth (cfg_req_depth ), //how many req. buffer should hold
+ .cfg_sdr_en (cfg_sdr_en ),
+ .cfg_sdr_mode_reg (cfg_sdr_mode_reg ),
+ .cfg_sdr_tras_d (cfg_sdr_tras_d ),
+ .cfg_sdr_trp_d (cfg_sdr_trp_d ),
+ .cfg_sdr_trcd_d (cfg_sdr_trcd_d ),
+ .cfg_sdr_cas (cfg_sdr_cas ),
+ .cfg_sdr_trcar_d (cfg_sdr_trcar_d ),
+ .cfg_sdr_twr_d (cfg_sdr_twr_d ),
+ .cfg_sdr_rfsh (cfg_sdr_rfsh ),
+ .cfg_sdr_rfmax (cfg_sdr_rfmax )
+ );
+
+
+wb_interconnect u_intercon (
+ .clk_i (wbd_clk_wi ),
+ .rst_n (wbd_int_rst_n ),
+
+ // Master 0 Interface
+ .m0_wbd_dat_i (wbd_int_dat_i ),
+ .m0_wbd_adr_i (wbd_int_adr_i ),
+ .m0_wbd_sel_i (wbd_int_sel_i ),
+ .m0_wbd_we_i (wbd_int_we_i ),
+ .m0_wbd_cyc_i (wbd_int_cyc_i ),
+ .m0_wbd_stb_i (wbd_int_stb_i ),
+ .m0_wbd_dat_o (wbd_int_dat_o ),
+ .m0_wbd_ack_o (wbd_int_ack_o ),
+ .m0_wbd_err_o (wbd_int_err_o ),
+
+ // Master 0 Interface
+ .m1_wbd_dat_i (wbd_riscv_imem_dat_i ),
+ .m1_wbd_adr_i (wbd_riscv_imem_adr_i ),
+ .m1_wbd_sel_i (wbd_riscv_imem_sel_i ),
+ .m1_wbd_we_i (wbd_riscv_imem_we_i ),
+ .m1_wbd_cyc_i (wbd_riscv_imem_stb_i ),
+ .m1_wbd_stb_i (wbd_riscv_imem_stb_i ),
+ .m1_wbd_dat_o (wbd_riscv_imem_dat_o ),
+ .m1_wbd_ack_o (wbd_riscv_imem_ack_o ),
+ .m1_wbd_err_o (wbd_riscv_imem_err_o ),
+
+ // Master 1 Interface
+ .m2_wbd_dat_i (wbd_riscv_dmem_dat_i ),
+ .m2_wbd_adr_i (wbd_riscv_dmem_adr_i ),
+ .m2_wbd_sel_i (wbd_riscv_dmem_sel_i ),
+ .m2_wbd_we_i (wbd_riscv_dmem_we_i ),
+ .m2_wbd_cyc_i (wbd_riscv_dmem_stb_i ),
+ .m2_wbd_stb_i (wbd_riscv_dmem_stb_i ),
+ .m2_wbd_dat_o (wbd_riscv_dmem_dat_o ),
+ .m2_wbd_ack_o (wbd_riscv_dmem_ack_o ),
+ .m2_wbd_err_o (wbd_riscv_dmem_err_o ),
+
+
+ // Slave 0 Interface
+ // .s0_wbd_err_i (1'b0 ), - Moved inside IP
+ .s0_wbd_dat_i (wbd_spim_dat_i ),
+ .s0_wbd_ack_i (wbd_spim_ack_i ),
+ .s0_wbd_dat_o (wbd_spim_dat_o ),
+ .s0_wbd_adr_o (wbd_spim_adr_o ),
+ .s0_wbd_sel_o (wbd_spim_sel_o ),
+ .s0_wbd_we_o (wbd_spim_we_o ),
+ .s0_wbd_cyc_o (wbd_spim_cyc_o ),
+ .s0_wbd_stb_o (wbd_spim_stb_o ),
+
+ // Slave 1 Interface
+ // .s1_wbd_err_i (1'b0 ), - Moved inside IP
+ .s1_wbd_dat_i (wbd_sdram_dat_i ),
+ .s1_wbd_ack_i (wbd_sdram_ack_i ),
+ .s1_wbd_dat_o (wbd_sdram_dat_o ),
+ .s1_wbd_adr_o (wbd_sdram_adr_o ),
+ .s1_wbd_sel_o (wbd_sdram_sel_o ),
+ .s1_wbd_we_o (wbd_sdram_we_o ),
+ .s1_wbd_cyc_o (wbd_sdram_cyc_o ),
+ .s1_wbd_stb_o (wbd_sdram_stb_o ),
+
+ // Slave 2 Interface
+ // .s2_wbd_err_i (1'b0 ), - Moved inside IP
+ .s2_wbd_dat_i (wbd_glbl_dat_i ),
+ .s2_wbd_ack_i (wbd_glbl_ack_i ),
+ .s2_wbd_dat_o (wbd_glbl_dat_o ),
+ .s2_wbd_adr_o (wbd_glbl_adr_o ),
+ .s2_wbd_sel_o (wbd_glbl_sel_o ),
+ .s2_wbd_we_o (wbd_glbl_we_o ),
+ .s2_wbd_cyc_o (wbd_glbl_cyc_o ),
+ .s2_wbd_stb_o (wbd_glbl_stb_o ),
+
+ // Slave 3 Interface
+ // .s3_wbd_err_i (1'b0 ), - Moved inside IP
+ .s3_wbd_dat_i (wbd_uart_dat_i ),
+ .s3_wbd_ack_i (wbd_uart_ack_i ),
+ .s3_wbd_dat_o (wbd_uart_dat_o ),
+ .s3_wbd_adr_o (wbd_uart_adr_o ),
+ .s3_wbd_sel_o (wbd_uart_sel_o ),
+ .s3_wbd_we_o (wbd_uart_we_o ),
+ .s3_wbd_cyc_o (wbd_uart_cyc_o ),
+ .s3_wbd_stb_o (wbd_uart_stb_o )
+ );
+
+glbl_cfg u_glbl_cfg (
+
+ .mclk (wbd_clk_glbl ),
+ .reset_n (wbd_int_rst_n ),
+ .user_clock1 (wb_clk_i ),
+ .user_clock2 (user_clock2 ),
+ .device_idcode ( ),
+
+ // Reg Bus Interface Signal
+ .reg_cs (wbd_glbl_stb_o ),
+ .reg_wr (wbd_glbl_we_o ),
+ .reg_addr (wbd_glbl_adr_o ),
+ .reg_wdata (wbd_glbl_dat_o ),
+ .reg_be (wbd_glbl_sel_o ),
+
+ // Outputs
+ .reg_rdata (wbd_glbl_dat_i ),
+ .reg_ack (wbd_glbl_ack_i ),
+
+ // SDRAM Clock
+
+ .sdram_clk (sdram_clk ),
+ .cpu_clk (cpu_clk ),
+ .rtc_clk (rtc_clk ),
+
+ // Risc configuration
+ .fuse_mhartid (fuse_mhartid ),
+ .irq_lines (irq_lines ),
+ .soft_irq (soft_irq ),
+ .user_irq (user_irq ),
+
+ // SDRAM Config
+ .cfg_sdr_width (cfg_sdr_width ),
+ .cfg_colbits (cfg_colbits ),
+
+ /* Parameters */
+ .sdr_init_done (sdr_init_done ),
+ .cfg_req_depth (cfg_req_depth ), //how many req. buffer should hold
+ .cfg_sdr_en (cfg_sdr_en ),
+ .cfg_sdr_mode_reg (cfg_sdr_mode_reg ),
+ .cfg_sdr_tras_d (cfg_sdr_tras_d ),
+ .cfg_sdr_trp_d (cfg_sdr_trp_d ),
+ .cfg_sdr_trcd_d (cfg_sdr_trcd_d ),
+ .cfg_sdr_cas (cfg_sdr_cas ),
+ .cfg_sdr_trcar_d (cfg_sdr_trcar_d ),
+ .cfg_sdr_twr_d (cfg_sdr_twr_d ),
+ .cfg_sdr_rfsh (cfg_sdr_rfsh ),
+ .cfg_sdr_rfmax (cfg_sdr_rfmax )
+
+
+ );
+
+uart_core u_uart_core (
+ .arst_n (wbd_int_rst_n ), // async reset
+ .app_clk (wbd_clk_uart ),
+
+ // Reg Bus Interface Signal
+ .reg_cs (wbd_uart_stb_o ),
+ .reg_wr (wbd_uart_we_o ),
+ .reg_addr (wbd_uart_adr_o[5:2] ),
+ .reg_wdata (wbd_uart_dat_o[7:0] ),
+ .reg_be (wbd_uart_sel_o ),
+
+ // Outputs
+ .reg_rdata (wbd_uart_dat_i[7:0] ),
+ .reg_ack (wbd_uart_ack_i ),
+
+ // Pad interface
+ .io_in (io_in [37:36] ),
+ .io_oeb (io_oeb[37:36] ),
+ .io_out (io_out[37:36] )
+
+ );
+
+////////////////////////////////////////////////////////////////
+// Clock Skew adjust module
+// ///////////////////////////////////////////////////////////
+
+// Wishbone interconnect clock skew control
+clk_skew_adjust u_skew_wi
+ (
+`ifdef USE_POWER_PINS
+ .vccd1 (vccd1 ),// User area 1 1.8V supply
+ .vssd1 (vssd1 ),// User area 1 digital ground
+`endif
+ .clk_in (wbd_clk_int ),
+ .sel (cfg_cska_wi ),
+ .clk_out (wbd_clk_wi )
+ );
+
+// riscv clock skew control
+clk_skew_adjust u_skew_riscv
+ (
+`ifdef USE_POWER_PINS
+ .vccd1 (vccd1 ),// User area 1 1.8V supply
+ .vssd1 (vssd1 ),// User area 1 digital ground
+`endif
+ .clk_in (wbd_clk_int ),
+ .sel (cfg_cska_riscv ),
+ .clk_out (wbd_clk_riscv )
+ );
+
+// uart clock skew control
+clk_skew_adjust u_skew_uart
+ (
+`ifdef USE_POWER_PINS
+ .vccd1 (vccd1 ),// User area 1 1.8V supply
+ .vssd1 (vssd1 ),// User area 1 digital ground
+`endif
+ .clk_in (wbd_clk_int ),
+ .sel (cfg_cska_uart ),
+ .clk_out (wbd_clk_uart )
+ );
+
+// spi clock skew control
+clk_skew_adjust u_skew_spi
+ (
+`ifdef USE_POWER_PINS
+ .vccd1 (vccd1 ),// User area 1 1.8V supply
+ .vssd1 (vssd1 ),// User area 1 digital ground
+`endif
+ .clk_in (wbd_clk_int ),
+ .sel (cfg_cska_spi ),
+ .clk_out (wbd_clk_spi )
+ );
+
+// sdram clock skew control
+clk_skew_adjust u_skew_sdram
+ (
+`ifdef USE_POWER_PINS
+ .vccd1 (vccd1 ),// User area 1 1.8V supply
+ .vssd1 (vssd1 ),// User area 1 digital ground
+`endif
+ .clk_in (wbd_clk_int ),
+ .sel (cfg_cska_sdram ),
+ .clk_out (wbd_clk_sdram )
+ );
+
+// global clock skew control
+clk_skew_adjust u_skew_glbl
+ (
+`ifdef USE_POWER_PINS
+ .vccd1 (vccd1 ),// User area 1 1.8V supply
+ .vssd1 (vssd1 ),// User area 1 digital ground
+`endif
+ .clk_in (wbd_clk_int ),
+ .sel (cfg_cska_glbl ),
+ .clk_out (wbd_clk_glbl )
+ );
+
+// wb_host clock skew control
+clk_skew_adjust u_skew_wh
+ (
+`ifdef USE_POWER_PINS
+ .vccd1 (vccd1 ),// User area 1 1.8V supply
+ .vssd1 (vssd1 ),// User area 1 digital ground
+`endif
+ .clk_in (wbd_clk_int ),
+ .sel (cfg_cska_wh ),
+ .clk_out (wbd_clk_wh )
+ );
+
+// SDRAM clock out clock skew control
+clk_skew_adjust u_skew_sd_co
+ (
+`ifdef USE_POWER_PINS
+ .vccd1 (vccd1 ),// User area 1 1.8V supply
+ .vssd1 (vssd1 ),// User area 1 digital ground
+`endif
+ .clk_in (io_out_29_ ),
+ .sel (cfg_cska_sd_co ),
+ .clk_out (io_out[29] )
+ );
+
+// Clock Skey for PAD SDRAM clock
+clk_skew_adjust u_skew_sd_ci
+ (
+`ifdef USE_POWER_PINS
+ .vccd1 (vccd1 ),// User area 1 1.8V supply
+ .vssd1 (vssd1 ),// User area 1 digital ground
+`endif
+ .clk_in (sdram_clk ),
+ .sel (cfg_cska_sd_ci ),
+ .clk_out (io_in_29_ )
+ );
+
+// Clock Skey for SPI clock out
+clk_skew_adjust u_skew_sp_co
+ (
+`ifdef USE_POWER_PINS
+ .vccd1 (vccd1 ),// User area 1 1.8V supply
+ .vssd1 (vssd1 ),// User area 1 digital ground
+`endif
+ .clk_in (io_in_30_ ),
+ .sel (cfg_cska_sp_co ),
+ .clk_out (io_out[30] )
+ );
+
+endmodule : digital_core
diff --git a/verilog/rtl/digital_core/src/glbl_cfg.sv b/verilog/rtl/digital_core/src/glbl_cfg.sv
new file mode 100644
index 0000000..c852e19
--- /dev/null
+++ b/verilog/rtl/digital_core/src/glbl_cfg.sv
@@ -0,0 +1,1041 @@
+//////////////////////////////////////////////////////////////////////////////
+// SPDX-FileCopyrightText: 2021 , Dinesh Annayya
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+// SPDX-License-Identifier: Apache-2.0
+// SPDX-FileContributor: Created by Dinesh Annayya <dinesha@opencores.org>
+//
+//////////////////////////////////////////////////////////////////////
+//// ////
+//// Global confg register ////
+//// ////
+//// This file is part of the YIFive cores project ////
+//// https://github.com/dineshannayya/yifive_r0.git ////
+//// http://www.opencores.org/cores/yifive/ ////
+//// ////
+//// Description ////
+//// This block generate all the global config and status ////
+//// ////
+//// To Do: ////
+//// nothing ////
+//// ////
+//// Author(s): ////
+//// - Dinesh Annayya, dinesha@opencores.org ////
+//// ////
+//// Revision : ////
+//// 0.1 - 08 June 2021 Dinesh A ////
+//// Initial version ////
+//// ////
+//////////////////////////////////////////////////////////////////////
+//// ////
+//// Copyright (C) 2000 Authors and OPENCORES.ORG ////
+//// ////
+//// This source file may be used and distributed without ////
+//// restriction provided that this copyright statement is not ////
+//// removed from the file and that any derivative work contains ////
+//// the original copyright notice and the associated disclaimer. ////
+//// ////
+//// This source file is free software; you can redistribute it ////
+//// and/or modify it under the terms of the GNU Lesser General ////
+//// Public License as published by the Free Software Foundation; ////
+//// either version 2.1 of the License, or (at your option) any ////
+//// later version. ////
+//// ////
+//// This source is distributed in the hope that it will be ////
+//// useful, but WITHOUT ANY WARRANTY; without even the implied ////
+//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR ////
+//// PURPOSE. See the GNU Lesser General Public License for more ////
+//// details. ////
+//// ////
+//// You should have received a copy of the GNU Lesser General ////
+//// Public License along with this source; if not, download it ////
+//// from http://www.opencores.org/lgpl.shtml ////
+//// ////
+//////////////////////////////////////////////////////////////////////
+
+module glbl_cfg (
+
+ input logic mclk,
+ input logic reset_n,
+
+ // Reg Bus Interface Signal
+ input logic reg_cs,
+ input logic reg_wr,
+ input logic [7:0] reg_addr,
+ input logic [31:0] reg_wdata,
+ input logic [3:0] reg_be,
+
+ // Outputs
+ output logic [31:0] reg_rdata,
+ output logic reg_ack,
+
+ // Risc configuration
+ output logic [31:0] fuse_mhartid,
+ output logic [15:0] irq_lines,
+ output logic soft_irq,
+ output logic [2:0] user_irq,
+
+ // SDRAM Config
+ input logic sdr_init_done , // Indicate SDRAM Initialisation Done
+ output logic [1:0] cfg_sdr_width , // 2'b00 - 32 Bit SDR, 2'b01 - 16 Bit SDR, 2'b1x - 8 Bit
+ output logic [1:0] cfg_colbits , // 2'b00 - 8 Bit column address,
+ output logic [3:0] cfg_sdr_tras_d , // Active to precharge delay
+ output logic [3:0] cfg_sdr_trp_d , // Precharge to active delay
+ output logic [3:0] cfg_sdr_trcd_d , // Active to R/W delay
+ output logic cfg_sdr_en , // Enable SDRAM controller
+ output logic [1:0] cfg_req_depth , // Maximum Request accepted by SDRAM controller
+ output logic [12:0] cfg_sdr_mode_reg ,
+ output logic [2:0] cfg_sdr_cas , // SDRAM CAS Latency
+ output logic [3:0] cfg_sdr_trcar_d , // Auto-refresh period
+ output logic [3:0] cfg_sdr_twr_d , // Write recovery delay
+ output logic [11:0] cfg_sdr_rfsh ,
+ output logic [2:0] cfg_sdr_rfmax
+
+
+ );
+
+
+
+//-----------------------------------------------------------------------
+// Internal Wire Declarations
+//-----------------------------------------------------------------------
+
+logic sw_rd_en;
+logic sw_wr_en;
+logic [3:0] sw_addr ; // addressing 16 registers
+logic [3:0] wr_be ;
+logic [31:0] sw_reg_wdata;
+
+logic reg_cs_l ;
+logic reg_cs_2l ;
+
+
+logic [31:0] reg_0; // Software_Reg_0
+logic [31:0] reg_1; // Risc Fuse ID
+logic [31:0] reg_2; // Software-Reg_2
+logic [31:0] reg_3; // Interrup Control
+logic [31:0] reg_4; // SDRAM_CTRL1
+logic [31:0] reg_5; // SDRAM_CTRL2
+logic [31:0] reg_6; // Software-Reg_6
+logic [31:0] reg_7; // Software-Reg_7
+logic [31:0] reg_8; // Software-Reg_8
+logic [31:0] reg_9; // Software-Reg_9
+logic [31:0] reg_10; // Software-Reg_10
+logic [31:0] reg_11; // Software-Reg_11
+logic [31:0] reg_12; // Software-Reg_12
+logic [31:0] reg_13; // Software-Reg_13
+logic [31:0] reg_14; // Software-Reg_14
+logic [31:0] reg_15; // Software-Reg_15
+logic [31:0] reg_out;
+
+//-----------------------------------------------------------------------
+// Main code starts here
+//-----------------------------------------------------------------------
+
+//-----------------------------------------------------------------------
+// To avoid interface timing, all the content are registered
+//-----------------------------------------------------------------------
+always @ (posedge mclk or negedge reset_n)
+begin
+ if (reset_n == 1'b0)
+ begin
+ sw_addr <= '0;
+ sw_rd_en <= '0;
+ sw_wr_en <= '0;
+ sw_reg_wdata <= '0;
+ wr_be <= '0;
+ reg_cs_l <= '0;
+ reg_cs_2l <= '0;
+ end else begin
+ sw_addr <= reg_addr [5:2];
+ sw_rd_en <= reg_cs & !reg_wr;
+ sw_wr_en <= reg_cs & reg_wr;
+ sw_reg_wdata <= reg_wdata;
+ wr_be <= reg_be;
+ reg_cs_l <= reg_cs;
+ reg_cs_2l <= reg_cs_l;
+ end
+end
+
+
+//-----------------------------------------------------------------------
+// Read path mux
+//-----------------------------------------------------------------------
+
+always @ (posedge mclk or negedge reset_n)
+begin : preg_out_Seq
+ if (reset_n == 1'b0) begin
+ reg_rdata [31:0] <= 32'h0000_0000;
+ reg_ack <= 1'b0;
+ end else if (sw_rd_en && !reg_ack && !reg_cs_2l) begin
+ reg_rdata [31:0] <= reg_out [31:0];
+ reg_ack <= 1'b1;
+ end else if (sw_wr_en && !reg_ack && !reg_cs_2l) begin
+ reg_ack <= 1'b1;
+ end else begin
+ reg_ack <= 1'b0;
+ end
+end
+
+
+//-----------------------------------------------------------------------
+// register read enable and write enable decoding logic
+//-----------------------------------------------------------------------
+wire sw_wr_en_0 = sw_wr_en & (sw_addr == 4'h0);
+wire sw_rd_en_0 = sw_rd_en & (sw_addr == 4'h0);
+wire sw_wr_en_1 = sw_wr_en & (sw_addr == 4'h1);
+wire sw_rd_en_1 = sw_rd_en & (sw_addr == 4'h1);
+wire sw_wr_en_2 = sw_wr_en & (sw_addr == 4'h2);
+wire sw_rd_en_2 = sw_rd_en & (sw_addr == 4'h2);
+wire sw_wr_en_3 = sw_wr_en & (sw_addr == 4'h3);
+wire sw_rd_en_3 = sw_rd_en & (sw_addr == 4'h3);
+wire sw_wr_en_4 = sw_wr_en & (sw_addr == 4'h4);
+wire sw_rd_en_4 = sw_rd_en & (sw_addr == 4'h4);
+wire sw_wr_en_5 = sw_wr_en & (sw_addr == 4'h5);
+wire sw_rd_en_5 = sw_rd_en & (sw_addr == 4'h5);
+wire sw_wr_en_6 = sw_wr_en & (sw_addr == 4'h6);
+wire sw_rd_en_6 = sw_rd_en & (sw_addr == 4'h6);
+wire sw_wr_en_7 = sw_wr_en & (sw_addr == 4'h7);
+wire sw_rd_en_7 = sw_rd_en & (sw_addr == 4'h7);
+wire sw_wr_en_8 = sw_wr_en & (sw_addr == 4'h8);
+wire sw_rd_en_8 = sw_rd_en & (sw_addr == 4'h8);
+wire sw_wr_en_9 = sw_wr_en & (sw_addr == 4'h9);
+wire sw_rd_en_9 = sw_rd_en & (sw_addr == 4'h9);
+wire sw_wr_en_10 = sw_wr_en & (sw_addr == 4'hA);
+wire sw_rd_en_10 = sw_rd_en & (sw_addr == 4'hA);
+wire sw_wr_en_11 = sw_wr_en & (sw_addr == 4'hB);
+wire sw_rd_en_11 = sw_rd_en & (sw_addr == 4'hB);
+wire sw_wr_en_12 = sw_wr_en & (sw_addr == 4'hC);
+wire sw_rd_en_12 = sw_rd_en & (sw_addr == 4'hC);
+wire sw_wr_en_13 = sw_wr_en & (sw_addr == 4'hD);
+wire sw_rd_en_13 = sw_rd_en & (sw_addr == 4'hD);
+wire sw_wr_en_14 = sw_wr_en & (sw_addr == 4'hE);
+wire sw_rd_en_14 = sw_rd_en & (sw_addr == 4'hE);
+wire sw_wr_en_15 = sw_wr_en & (sw_addr == 4'hF);
+wire sw_rd_en_15 = sw_rd_en & (sw_addr == 4'hF);
+
+
+always @( *)
+begin : preg_sel_Com
+
+ reg_out [31:0] = 32'd0;
+
+ case (sw_addr [3:0])
+ 4'b0000 : reg_out [31:0] = reg_0 [31:0];
+ 4'b0001 : reg_out [31:0] = reg_1 [31:0];
+ 4'b0010 : reg_out [31:0] = reg_2 [31:0];
+ 4'b0011 : reg_out [31:0] = reg_3 [31:0];
+ 4'b0100 : reg_out [31:0] = reg_4 [31:0];
+ 4'b0101 : reg_out [31:0] = reg_5 [31:0];
+ 4'b0110 : reg_out [31:0] = reg_6 [31:0];
+ 4'b0111 : reg_out [31:0] = reg_7 [31:0];
+ 4'b1000 : reg_out [31:0] = reg_8 [31:0];
+ 4'b1001 : reg_out [31:0] = reg_9 [31:0];
+ 4'b1010 : reg_out [31:0] = reg_10 [31:0];
+ 4'b1011 : reg_out [31:0] = reg_11 [31:0];
+ 4'b1100 : reg_out [31:0] = reg_12 [31:0];
+ 4'b1101 : reg_out [31:0] = reg_13 [31:0];
+ 4'b1110 : reg_out [31:0] = reg_14 [31:0];
+ 4'b1111 : reg_out [31:0] = reg_15 [31:0];
+ endcase
+end
+
+
+
+//-----------------------------------------------------------------------
+// Individual register assignments
+//-----------------------------------------------------------------------
+//-----------------------------------------------------------------------
+// reg-0
+// -----------------------------------------------------------------
+
+
+
+generic_register #(8,8'hAA ) u_reg0_be0 (
+ .we ({8{sw_wr_en_0 &
+ wr_be[0] }} ),
+ .data_in (sw_reg_wdata[7:0] ),
+ .reset_n (reset_n ),
+ .clk (mclk ),
+
+ //List of Outs
+ .data_out (reg_0[7:0] )
+ );
+
+generic_register #(8,8'hBB ) u_reg0_be1 (
+ .we ({8{sw_wr_en_0 &
+ wr_be[1] }} ),
+ .data_in (sw_reg_wdata[15:8] ),
+ .reset_n (reset_n ),
+ .clk (mclk ),
+
+ //List of Outs
+ .data_out (reg_0[15:8] )
+ );
+generic_register #(8,8'hCC ) u_reg0_be2 (
+ .we ({8{sw_wr_en_0 &
+ wr_be[2] }} ),
+ .data_in (sw_reg_wdata[23:16] ),
+ .reset_n (reset_n ),
+ .clk (mclk ),
+
+ //List of Outs
+ .data_out (reg_0[23:16] )
+ );
+
+generic_register #(8,8'hDD ) u_reg0_be3 (
+ .we ({8{sw_wr_en_0 &
+ wr_be[3] }} ),
+ .data_in (sw_reg_wdata[31:24] ),
+ .reset_n (reset_n ),
+ .clk (mclk ),
+
+ //List of Outs
+ .data_out (reg_0[31:24] )
+ );
+
+
+
+//-----------------------------------------------------------------------
+// reg-1, reset value = 32'hA55A_A55A
+// -----------------------------------------------------------------
+
+assign fuse_mhartid = reg_1[31:0];
+generic_register #(.WD(8),.RESET_DEFAULT(8'h5A)) u_reg1_be0 (
+ .we ({8{sw_wr_en_1 &
+ wr_be[0] }} ),
+ .data_in (sw_reg_wdata[7:0] ),
+ .reset_n (reset_n ),
+ .clk (mclk ),
+
+ //List of Outs
+ .data_out (reg_1[7:0] )
+ );
+
+generic_register #(.WD(8),.RESET_DEFAULT(8'hA5) ) u_reg1_be1 (
+ .we ({8{sw_wr_en_1 &
+ wr_be[1] }} ),
+ .data_in (sw_reg_wdata[15:8] ),
+ .reset_n (reset_n ),
+ .clk (mclk ),
+
+ //List of Outs
+ .data_out (reg_1[15:8] )
+ );
+generic_register #(.WD(8),.RESET_DEFAULT(8'h5A) ) u_reg1_be2 (
+ .we ({8{sw_wr_en_1 &
+ wr_be[2] }} ),
+ .data_in (sw_reg_wdata[23:16] ),
+ .reset_n (reset_n ),
+ .clk (mclk ),
+
+ //List of Outs
+ .data_out (reg_1[23:16] )
+ );
+
+generic_register #(.WD(8),.RESET_DEFAULT(8'hA5) ) u_reg1_be3 (
+ .we ({8{sw_wr_en_1 &
+ wr_be[3] }} ),
+ .data_in (sw_reg_wdata[31:24] ),
+ .reset_n (reset_n ),
+ .clk (mclk ),
+
+ //List of Outs
+ .data_out (reg_1[31:24] )
+ );
+
+//-----------------------------------------------------------------------
+// reg-2, reset value = 32'hAABBCCDD
+//-----------------------------------------------------------------
+
+generic_register #(.WD(8),.RESET_DEFAULT(8'hDD) ) u_reg2_be0 (
+ .we ({8{sw_wr_en_2 &
+ wr_be[0] }} ),
+ .data_in (sw_reg_wdata[7:0] ),
+ .reset_n (reset_n ),
+ .clk (mclk ),
+
+ //List of Outs
+ .data_out (reg_2[7:0] )
+ );
+
+generic_register #(.WD(8),.RESET_DEFAULT(8'hCC) ) u_reg2_be1 (
+ .we ({8{sw_wr_en_2 &
+ wr_be[1] }} ),
+ .data_in (sw_reg_wdata[15:8] ),
+ .reset_n (reset_n ),
+ .clk (mclk ),
+
+ //List of Outs
+ .data_out (reg_2[15:8] )
+ );
+generic_register #(.WD(8),.RESET_DEFAULT(8'hBB) ) u_reg2_be2 (
+ .we ({8{sw_wr_en_2 &
+ wr_be[2] }} ),
+ .data_in (sw_reg_wdata[23:16] ),
+ .reset_n (reset_n ),
+ .clk (mclk ),
+
+ //List of Outs
+ .data_out (reg_2[23:16] )
+ );
+
+generic_register #(.WD(8),.RESET_DEFAULT(8'hAA) ) u_reg2_be3 (
+ .we ({8{sw_wr_en_2 &
+ wr_be[3] }} ),
+ .data_in (sw_reg_wdata[31:24] ),
+ .reset_n (reset_n ),
+ .clk (mclk ),
+
+ //List of Outs
+ .data_out (reg_2[31:24] )
+ );
+
+//-----------------------------------------------------------------------
+// reg-3
+//-----------------------------------------------------------------
+assign irq_lines = reg_3[15:0];
+assign soft_irq = reg_3[16];
+assign user_irq = reg_3[19:17];
+
+generic_register #(8,0 ) u_reg3_be0 (
+ .we ({8{sw_wr_en_3 &
+ wr_be[0] }} ),
+ .data_in (sw_reg_wdata[7:0] ),
+ .reset_n (reset_n ),
+ .clk (mclk ),
+
+ //List of Outs
+ .data_out (reg_3[7:0] )
+ );
+
+generic_register #(8,0 ) u_reg3_be1 (
+ .we ({8{sw_wr_en_3 &
+ wr_be[1] }} ),
+ .data_in (sw_reg_wdata[15:8] ),
+ .reset_n (reset_n ),
+ .clk (mclk ),
+
+ //List of Outs
+ .data_out (reg_3[15:8] )
+ );
+generic_register #(4,0 ) u_reg3_be2 (
+ .we ({4{sw_wr_en_3 &
+ wr_be[2] }} ),
+ .data_in (sw_reg_wdata[19:16] ),
+ .reset_n (reset_n ),
+ .clk (mclk ),
+
+ //List of Outs
+ .data_out (reg_3[19:16] )
+ );
+
+assign reg_3[31:20] = '0;
+
+
+//-----------------------------------------------------------------------
+// reg-4
+// recommended Default value:
+// 1'b1,3'h3,2'h3,4'h1,4'h7',4'h2,4'h2,4'h6,2'b01,2'b10 = 32'h2F17_2266
+//-----------------------------------------------------------------
+assign cfg_sdr_width = reg_4[1:0] ; // 2'b10 // 2'b00 - 32 Bit SDR, 2'b01 - 16 Bit SDR, 2'b1x - 8 Bit
+assign cfg_colbits = reg_4[3:2] ; // 2'b00 8 Bit column address, 2'b01 - 9 Bit column address,
+assign cfg_sdr_tras_d = reg_4[7:4] ; // 4'h4 // Active to precharge delay
+assign cfg_sdr_trp_d = reg_4[11:8]; // 4'h2 // Precharge to active delay
+assign cfg_sdr_trcd_d = reg_4[15:12]; // 4'h2 // Active to R/W delay
+assign cfg_sdr_trcar_d = reg_4[19:16]; // 4'h7 // Auto-refresh period
+assign cfg_sdr_twr_d = reg_4[23:20]; // 4'h1 // Write recovery delay
+assign cfg_req_depth = reg_4[25:24]; // 2'h3 // Maximum Request accepted by SDRAM controller
+assign cfg_sdr_cas = reg_4[28:26]; // 3'h3 // SDRAM CAS Latency
+assign cfg_sdr_en = reg_4[29] ; // 1'b1 // Enable SDRAM controller
+assign reg_4[30] = sdr_init_done ; // Indicate SDRAM Initialisation Done
+assign reg_4[31] = 1'b0;
+
+
+generic_register #(8,0 ) u_reg4_be0 (
+ .we ({8{sw_wr_en_4 &
+ wr_be[0] }} ),
+ .data_in (sw_reg_wdata[7:0] ),
+ .reset_n (reset_n ),
+ .clk (mclk ),
+
+ //List of Outs
+ .data_out (reg_4[7:0] )
+ );
+
+generic_register #(8,0 ) u_reg4_be1 (
+ .we ({8{sw_wr_en_4 &
+ wr_be[1] }} ),
+ .data_in (sw_reg_wdata[15:8] ),
+ .reset_n (reset_n ),
+ .clk (mclk ),
+
+ //List of Outs
+ .data_out (reg_4[15:8] )
+ );
+generic_register #(8,0 ) u_reg4_be2 (
+ .we ({8{sw_wr_en_4 &
+ wr_be[2] }} ),
+ .data_in (sw_reg_wdata[23:16] ),
+ .reset_n (reset_n ),
+ .clk (mclk ),
+
+ //List of Outs
+ .data_out (reg_4[23:16] )
+ );
+
+generic_register #(6,0 ) u_reg4_be3 (
+ .we ({6{sw_wr_en_4 &
+ wr_be[3] }} ),
+ .data_in (sw_reg_wdata[29:24] ),
+ .reset_n (reset_n ),
+ .clk (mclk ),
+
+ //List of Outs
+ .data_out (reg_4[29:24] )
+ );
+//-----------------------------------------------------------------------
+// reg-5, recomended default value {12'h100,13'h33,3'h6} = 32'h100_019E
+//-----------------------------------------------------------------
+assign cfg_sdr_rfmax = reg_5[2:0] ; // 3'h6
+assign cfg_sdr_mode_reg = reg_5[15:3] ; // 13'h033
+assign cfg_sdr_rfsh = reg_5[27:16]; // 12'h100
+
+generic_register #(8,0 ) u_reg5_be0 (
+ .we ({8{sw_wr_en_5 &
+ wr_be[0] }} ),
+ .data_in (sw_reg_wdata[7:0] ),
+ .reset_n (reset_n ),
+ .clk (mclk ),
+
+ //List of Outs
+ .data_out (reg_5[7:0] )
+ );
+
+generic_register #(8,0 ) u_reg5_be1 (
+ .we ({8{sw_wr_en_5 &
+ wr_be[1] }} ),
+ .data_in (sw_reg_wdata[15:8] ),
+ .reset_n (reset_n ),
+ .clk (mclk ),
+
+ //List of Outs
+ .data_out (reg_5[15:8] )
+ );
+generic_register #(8,0 ) u_reg5_be2 (
+ .we ({8{sw_wr_en_5 &
+ wr_be[2] }} ),
+ .data_in (sw_reg_wdata[23:16] ),
+ .reset_n (reset_n ),
+ .clk (mclk ),
+
+ //List of Outs
+ .data_out (reg_5[23:16] )
+ );
+
+generic_register #(8,0 ) u_reg5_be3 (
+ .we ({8{sw_wr_en_5 &
+ wr_be[3] }} ),
+ .data_in (sw_reg_wdata[31:24] ),
+ .reset_n (reset_n ),
+ .clk (mclk ),
+
+ //List of Outs
+ .data_out (reg_5[31:24] )
+ );
+
+
+//-----------------------------------------------------------------
+// reg- 6
+//-----------------------------------------------------------------
+
+generic_register #(8,0 ) u_reg6_be0 (
+ .we ({8{sw_wr_en_6 &
+ wr_be[0] }} ),
+ .data_in (sw_reg_wdata[7:0] ),
+ .reset_n (reset_n ),
+ .clk (mclk ),
+
+ //List of Outs
+ .data_out (reg_6[7:0] )
+ );
+
+generic_register #(8,0 ) u_reg6_be1 (
+ .we ({8{sw_wr_en_6 &
+ wr_be[1] }} ),
+ .data_in (sw_reg_wdata[15:8] ),
+ .reset_n (reset_n ),
+ .clk (mclk ),
+
+ //List of Outs
+ .data_out (reg_6[15:8] )
+ );
+generic_register #(8,0 ) u_reg6_be2 (
+ .we ({8{sw_wr_en_6 &
+ wr_be[2] }} ),
+ .data_in (sw_reg_wdata[23:16] ),
+ .reset_n (reset_n ),
+ .clk (mclk ),
+
+ //List of Outs
+ .data_out (reg_6[23:16] )
+ );
+
+generic_register #(8,0 ) u_reg6_be3 (
+ .we ({8{sw_wr_en_6 &
+ wr_be[3] }} ),
+ .data_in (sw_reg_wdata[31:24] ),
+ .reset_n (reset_n ),
+ .clk (mclk ),
+
+ //List of Outs
+ .data_out (reg_6[31:24] )
+ );
+
+
+//-----------------------------------------------------------------
+// reg- 7
+//-----------------------------------------------------------------
+
+generic_register #(8,0 ) u_reg7_be0 (
+ .we ({8{sw_wr_en_7 &
+ wr_be[0] }} ),
+ .data_in (sw_reg_wdata[7:0] ),
+ .reset_n (reset_n ),
+ .clk (mclk ),
+
+ //List of Outs
+ .data_out (reg_7[7:0] )
+ );
+
+generic_register #(8,0 ) u_reg7_be1 (
+ .we ({8{sw_wr_en_7 &
+ wr_be[1] }} ),
+ .data_in (sw_reg_wdata[15:8] ),
+ .reset_n (reset_n ),
+ .clk (mclk ),
+
+ //List of Outs
+ .data_out (reg_7[15:8] )
+ );
+generic_register #(8,0 ) u_reg7_be2 (
+ .we ({8{sw_wr_en_7 &
+ wr_be[2] }} ),
+ .data_in (sw_reg_wdata[23:16] ),
+ .reset_n (reset_n ),
+ .clk (mclk ),
+
+ //List of Outs
+ .data_out (reg_7[23:16] )
+ );
+
+generic_register #(8,0 ) u_reg7_be3 (
+ .we ({8{sw_wr_en_7 &
+ wr_be[3] }} ),
+ .data_in (sw_reg_wdata[31:24] ),
+ .reset_n (reset_n ),
+ .clk (mclk ),
+
+ //List of Outs
+ .data_out (reg_7[31:24] )
+ );
+
+
+//-----------------------------------------------------------------
+// reg- 8
+//-----------------------------------------------------------------
+
+generic_register #(8,0 ) u_reg8_be0 (
+ .we ({8{sw_wr_en_8 &
+ wr_be[0] }} ),
+ .data_in (sw_reg_wdata[7:0] ),
+ .reset_n (reset_n ),
+ .clk (mclk ),
+
+ //List of Outs
+ .data_out (reg_8[7:0] )
+ );
+
+generic_register #(8,0 ) u_reg8_be1 (
+ .we ({8{sw_wr_en_8 &
+ wr_be[1] }} ),
+ .data_in (sw_reg_wdata[15:8] ),
+ .reset_n (reset_n ),
+ .clk (mclk ),
+
+ //List of Outs
+ .data_out (reg_8[15:8] )
+ );
+generic_register #(8,0 ) u_reg8_be2 (
+ .we ({8{sw_wr_en_8 &
+ wr_be[2] }} ),
+ .data_in (sw_reg_wdata[23:16] ),
+ .reset_n (reset_n ),
+ .clk (mclk ),
+
+ //List of Outs
+ .data_out (reg_8[23:16] )
+ );
+
+generic_register #(8,0 ) u_reg8_be3 (
+ .we ({8{sw_wr_en_8 &
+ wr_be[3] }} ),
+ .data_in (sw_reg_wdata[31:24] ),
+ .reset_n (reset_n ),
+ .clk (mclk ),
+
+ //List of Outs
+ .data_out (reg_8[31:24] )
+ );
+
+
+//-----------------------------------------------------------------
+// reg- 9
+//-----------------------------------------------------------------
+
+generic_register #(8,0 ) u_reg9_be0 (
+ .we ({8{sw_wr_en_9 &
+ wr_be[0] }} ),
+ .data_in (sw_reg_wdata[7:0] ),
+ .reset_n (reset_n ),
+ .clk (mclk ),
+
+ //List of Outs
+ .data_out (reg_9[7:0] )
+ );
+
+generic_register #(8,0 ) u_reg9_be1 (
+ .we ({8{sw_wr_en_9 &
+ wr_be[1] }} ),
+ .data_in (sw_reg_wdata[15:8] ),
+ .reset_n (reset_n ),
+ .clk (mclk ),
+
+ //List of Outs
+ .data_out (reg_9[15:8] )
+ );
+generic_register #(8,0 ) u_reg9_be2 (
+ .we ({8{sw_wr_en_9 &
+ wr_be[2] }} ),
+ .data_in (sw_reg_wdata[23:16] ),
+ .reset_n (reset_n ),
+ .clk (mclk ),
+
+ //List of Outs
+ .data_out (reg_9[23:16] )
+ );
+
+generic_register #(8,0 ) u_reg9_be3 (
+ .we ({8{sw_wr_en_9 &
+ wr_be[3] }} ),
+ .data_in (sw_reg_wdata[31:24] ),
+ .reset_n (reset_n ),
+ .clk (mclk ),
+
+ //List of Outs
+ .data_out (reg_9[31:24] )
+ );
+
+
+//-----------------------------------------------------------------
+// reg- 10
+//-----------------------------------------------------------------
+
+generic_register #(8,0 ) u_reg10_be0 (
+ .we ({8{sw_wr_en_10 &
+ wr_be[0] }} ),
+ .data_in (sw_reg_wdata[7:0] ),
+ .reset_n (reset_n ),
+ .clk (mclk ),
+
+ //List of Outs
+ .data_out (reg_10[7:0] )
+ );
+
+generic_register #(8,0 ) u_reg10_be1 (
+ .we ({8{sw_wr_en_10 &
+ wr_be[1] }} ),
+ .data_in (sw_reg_wdata[15:8] ),
+ .reset_n (reset_n ),
+ .clk (mclk ),
+
+ //List of Outs
+ .data_out (reg_10[15:8] )
+ );
+generic_register #(8,0 ) u_reg10_be2 (
+ .we ({8{sw_wr_en_10 &
+ wr_be[2] }} ),
+ .data_in (sw_reg_wdata[23:16] ),
+ .reset_n (reset_n ),
+ .clk (mclk ),
+
+ //List of Outs
+ .data_out (reg_10[23:16] )
+ );
+
+generic_register #(8,0 ) u_reg10_be3 (
+ .we ({8{sw_wr_en_10 &
+ wr_be[3] }} ),
+ .data_in (sw_reg_wdata[31:24] ),
+ .reset_n (reset_n ),
+ .clk (mclk ),
+
+ //List of Outs
+ .data_out (reg_10[31:24] )
+ );
+
+
+//-----------------------------------------------------------------
+// reg- 11
+//-----------------------------------------------------------------
+
+generic_register #(8,0 ) u_reg11_be0 (
+ .we ({8{sw_wr_en_11 &
+ wr_be[0] }} ),
+ .data_in (sw_reg_wdata[7:0] ),
+ .reset_n (reset_n ),
+ .clk (mclk ),
+
+ //List of Outs
+ .data_out (reg_11[7:0] )
+ );
+
+generic_register #(8,0 ) u_reg11_be1 (
+ .we ({8{sw_wr_en_11 &
+ wr_be[1] }} ),
+ .data_in (sw_reg_wdata[15:8] ),
+ .reset_n (reset_n ),
+ .clk (mclk ),
+
+ //List of Outs
+ .data_out (reg_11[15:8] )
+ );
+generic_register #(8,0 ) u_reg11_be2 (
+ .we ({8{sw_wr_en_11 &
+ wr_be[2] }} ),
+ .data_in (sw_reg_wdata[23:16] ),
+ .reset_n (reset_n ),
+ .clk (mclk ),
+
+ //List of Outs
+ .data_out (reg_11[23:16] )
+ );
+
+generic_register #(8,0 ) u_reg11_be3 (
+ .we ({8{sw_wr_en_11 &
+ wr_be[3] }} ),
+ .data_in (sw_reg_wdata[31:24] ),
+ .reset_n (reset_n ),
+ .clk (mclk ),
+
+ //List of Outs
+ .data_out (reg_11[31:24] )
+ );
+
+
+//-----------------------------------------------------------------
+// reg- 12
+//-----------------------------------------------------------------
+
+generic_register #(8,0 ) u_reg12_be0 (
+ .we ({8{sw_wr_en_12 &
+ wr_be[0] }} ),
+ .data_in (sw_reg_wdata[7:0] ),
+ .reset_n (reset_n ),
+ .clk (mclk ),
+
+ //List of Outs
+ .data_out (reg_12[7:0] )
+ );
+
+generic_register #(8,0 ) u_reg12_be1 (
+ .we ({8{sw_wr_en_12 &
+ wr_be[1] }} ),
+ .data_in (sw_reg_wdata[15:8] ),
+ .reset_n (reset_n ),
+ .clk (mclk ),
+
+ //List of Outs
+ .data_out (reg_12[15:8] )
+ );
+generic_register #(8,0 ) u_reg12_be2 (
+ .we ({8{sw_wr_en_12 &
+ wr_be[2] }} ),
+ .data_in (sw_reg_wdata[23:16] ),
+ .reset_n (reset_n ),
+ .clk (mclk ),
+
+ //List of Outs
+ .data_out (reg_12[23:16] )
+ );
+
+generic_register #(8,0 ) u_reg12_be3 (
+ .we ({8{sw_wr_en_12 &
+ wr_be[3] }} ),
+ .data_in (sw_reg_wdata[31:24] ),
+ .reset_n (reset_n ),
+ .clk (mclk ),
+
+ //List of Outs
+ .data_out (reg_12[31:24] )
+ );
+
+
+//-----------------------------------------------------------------
+// reg- 13
+//-----------------------------------------------------------------
+
+generic_register #(8,0 ) u_reg13_be0 (
+ .we ({8{sw_wr_en_13 &
+ wr_be[0] }} ),
+ .data_in (sw_reg_wdata[7:0] ),
+ .reset_n (reset_n ),
+ .clk (mclk ),
+
+ //List of Outs
+ .data_out (reg_13[7:0] )
+ );
+
+generic_register #(8,0 ) u_reg13_be1 (
+ .we ({8{sw_wr_en_13 &
+ wr_be[1] }} ),
+ .data_in (sw_reg_wdata[15:8] ),
+ .reset_n (reset_n ),
+ .clk (mclk ),
+
+ //List of Outs
+ .data_out (reg_13[15:8] )
+ );
+generic_register #(8,0 ) u_reg13_be2 (
+ .we ({8{sw_wr_en_13 &
+ wr_be[2] }} ),
+ .data_in (sw_reg_wdata[23:16] ),
+ .reset_n (reset_n ),
+ .clk (mclk ),
+
+ //List of Outs
+ .data_out (reg_13[23:16] )
+ );
+
+generic_register #(8,0 ) u_reg13_be3 (
+ .we ({8{sw_wr_en_13 &
+ wr_be[3] }} ),
+ .data_in (sw_reg_wdata[31:24] ),
+ .reset_n (reset_n ),
+ .clk (mclk ),
+
+ //List of Outs
+ .data_out (reg_13[31:24] )
+ );
+
+
+//-----------------------------------------------------------------
+// reg- 14
+//-----------------------------------------------------------------
+
+generic_register #(8,0 ) u_reg14_be0 (
+ .we ({8{sw_wr_en_14 &
+ wr_be[0] }} ),
+ .data_in (sw_reg_wdata[7:0] ),
+ .reset_n (reset_n ),
+ .clk (mclk ),
+
+ //List of Outs
+ .data_out (reg_14[7:0] )
+ );
+
+generic_register #(8,0 ) u_reg14_be1 (
+ .we ({8{sw_wr_en_14 &
+ wr_be[1] }} ),
+ .data_in (sw_reg_wdata[15:8] ),
+ .reset_n (reset_n ),
+ .clk (mclk ),
+
+ //List of Outs
+ .data_out (reg_14[15:8] )
+ );
+generic_register #(8,0 ) u_reg14_be2 (
+ .we ({8{sw_wr_en_14 &
+ wr_be[2] }} ),
+ .data_in (sw_reg_wdata[23:16] ),
+ .reset_n (reset_n ),
+ .clk (mclk ),
+
+ //List of Outs
+ .data_out (reg_14[23:16] )
+ );
+
+generic_register #(8,0 ) u_reg14_be3 (
+ .we ({8{sw_wr_en_14 &
+ wr_be[3] }} ),
+ .data_in (sw_reg_wdata[31:24] ),
+ .reset_n (reset_n ),
+ .clk (mclk ),
+
+ //List of Outs
+ .data_out (reg_14[31:24] )
+ );
+
+
+//-----------------------------------------------------------------
+// reg- 15
+//-----------------------------------------------------------------
+
+generic_register #(8,0 ) u_reg15_be0 (
+ .we ({8{sw_wr_en_15 &
+ wr_be[0] }} ),
+ .data_in (sw_reg_wdata[7:0] ),
+ .reset_n (reset_n ),
+ .clk (mclk ),
+
+ //List of Outs
+ .data_out (reg_15[7:0] )
+ );
+
+generic_register #(8,0 ) u_reg15_be1 (
+ .we ({8{sw_wr_en_15 &
+ wr_be[1] }} ),
+ .data_in (sw_reg_wdata[15:8] ),
+ .reset_n (reset_n ),
+ .clk (mclk ),
+
+ //List of Outs
+ .data_out (reg_15[15:8] )
+ );
+generic_register #(8,0 ) u_reg15_be2 (
+ .we ({8{sw_wr_en_15 &
+ wr_be[2] }} ),
+ .data_in (sw_reg_wdata[23:16] ),
+ .reset_n (reset_n ),
+ .clk (mclk ),
+
+ //List of Outs
+ .data_out (reg_15[23:16] )
+ );
+
+generic_register #(8,0 ) u_reg15_be3 (
+ .we ({8{sw_wr_en_15 &
+ wr_be[3] }} ),
+ .data_in (sw_reg_wdata[31:24] ),
+ .reset_n (reset_n ),
+ .clk (mclk ),
+
+ //List of Outs
+ .data_out (reg_15[31:24] )
+ );
+
+
+
+
+
+endmodule
diff --git a/verilog/rtl/i2cm/src/core/i2cm_bit_ctrl.v b/verilog/rtl/i2cm/src/core/i2cm_bit_ctrl.v
new file mode 100755
index 0000000..35c2146
--- /dev/null
+++ b/verilog/rtl/i2cm/src/core/i2cm_bit_ctrl.v
@@ -0,0 +1,545 @@
+//////////////////////////////////////////////////////////////////////////////
+// SPDX-FileCopyrightText: 2021 , Dinesh Annayya
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+// SPDX-License-Identifier: Apache-2.0
+// SPDX-FileContributor: Created by Dinesh Annayya <dinesha@opencores.org>
+//
+
+//////////////////////////////////////////////////////////////////////
+//// ////
+//// OMS8051 I2C Master bit-controller Module ////
+//// WISHBONE rev.B2 compliant I2C Master bit-controller ////
+//// ////
+//// This file is part of the OMS 8051 cores project ////
+//// http://www.opencores.org/cores/oms8051mini/ ////
+//// ////
+//// Description ////
+//// OMS 8051 definitions. ////
+//// ////
+//// To Do: ////
+//// nothing ////
+//// ////
+//// Author(s): ////
+//// -Richard Herveille , richard@asics.ws, www.asics.ws ////
+//// -Dinesh Annayya, dinesha@opencores.org ////
+//// ////
+//// Revision : Jan 6, 2017 ////
+//// ////
+//////////////////////////////////////////////////////////////////////
+// v0.0 - Dinesh A, 6th Jan 2017
+// 1. Initail version picked from
+// http://www.opencores.org/projects/i2c/
+// v0.1 - Dinesh A, 19th Jan 2017
+// 1. Lint warning clean up
+//////////////////////////////////////////////////////////////////////
+//// ////
+//// Copyright (C) 2000 Authors and OPENCORES.ORG ////
+//// ////
+//// This source file may be used and distributed without ////
+//// restriction provided that this copyright statement is not ////
+//// removed from the file and that any derivative work contains ////
+//// the original copyright notice and the associated disclaimer. ////
+//// ////
+//// This source file is free software; you can redistribute it ////
+//// and/or modify it under the terms of the GNU Lesser General ////
+//// Public License as published by the Free Software Foundation; ////
+//// either version 2.1 of the License, or (at your option) any ////
+//// later version. ////
+//// ////
+//// This source is distributed in the hope that it will be ////
+//// useful, but WITHOUT ANY WARRANTY; without even the implied ////
+//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR ////
+//// PURPOSE. See the GNU Lesser General Public License for more ////
+//// details. ////
+//// ////
+//// You should have received a copy of the GNU Lesser General ////
+//// Public License along with this source; if not, download it ////
+//// from http://www.opencores.org/lgpl.shtml ////
+//// ////
+//////////////////////////////////////////////////////////////////////
+/////////////////////////////////////
+// Bit controller section
+/////////////////////////////////////
+//
+// Translate simple commands into SCL/SDA transitions
+// Each command has 5 states, A/B/C/D/idle
+//
+// start: SCL ~~~~~~~~~~\____
+// SDA ~~~~~~~~\______
+// x | A | B | C | D | i
+//
+// repstart SCL ____/~~~~\___
+// SDA __/~~~\______
+// x | A | B | C | D | i
+//
+// stop SCL ____/~~~~~~~~
+// SDA ==\____/~~~~~
+// x | A | B | C | D | i
+//
+//- write SCL ____/~~~~\____
+// SDA ==X=========X=
+// x | A | B | C | D | i
+//
+//- read SCL ____/~~~~\____
+// SDA XXXX=====XXXX
+// x | A | B | C | D | i
+//
+
+// Timing: Normal mode Fast mode
+///////////////////////////////////////////////////////////////////////
+// Fscl 100KHz 400KHz
+// Th_scl 4.0us 0.6us High period of SCL
+// Tl_scl 4.7us 1.3us Low period of SCL
+// Tsu:sta 4.7us 0.6us setup time for a repeated start condition
+// Tsu:sto 4.0us 0.6us setup time for a stop conditon
+// Tbuf 4.7us 1.3us Bus free time between a stop and start condition
+//
+
+
+`include "i2cm_defines.v"
+
+module i2cm_bit_ctrl (
+ input clk, // system clock
+ input sresetn, // synchronous active low reset
+ input aresetn, // asynchronous active low reset
+ input ena, // core enable signal
+
+ input [15:0] clk_cnt, // clock prescale value
+
+ input [ 3:0] cmd, // command (from byte controller)
+ output reg cmd_ack, // command complete acknowledge
+ output reg busy, // i2c bus busy
+ output reg al, // i2c bus arbitration lost
+
+ input din,
+ output reg dout,
+
+ input scl_i, // i2c clock line input
+ output scl_o, // i2c clock line output
+ output reg scl_oen, // i2c clock line output enable (active low)
+ input sda_i, // i2c data line input
+ output sda_o, // i2c data line output
+ output reg sda_oen // i2c data line output enable (active low)
+);
+
+
+ //
+ // variable declarations
+ //
+
+ reg [ 1:0] cSCL, cSDA; // capture SCL and SDA
+ reg [ 2:0] fSCL, fSDA; // SCL and SDA filter inputs
+ reg sSCL, sSDA; // filtered and synchronized SCL and SDA inputs
+ reg dSCL, dSDA; // delayed versions of sSCL and sSDA
+ reg dscl_oen; // delayed scl_oen
+ reg sda_chk; // check SDA output (Multi-master arbitration)
+ reg clk_en; // clock generation signals
+ reg slave_wait; // slave inserts wait states
+ reg [15:0] cnt; // clock divider counter (synthesis)
+ reg [13:0] filter_cnt; // clock divider for filter
+
+
+ // state machine variable
+ reg [17:0] c_state; // synopsys enum_state
+
+ //
+ // module body
+ //
+
+ // whenever the slave is not ready it can delay the cycle by pulling SCL low
+ // delay scl_oen
+ always @(posedge clk)
+ dscl_oen <= scl_oen;
+
+ // slave_wait is asserted when master wants to drive SCL high, but the slave pulls it low
+ // slave_wait remains asserted until the slave releases SCL
+ always @(posedge clk or negedge aresetn)
+ if (!aresetn) slave_wait <= 1'b0;
+ else slave_wait <= (scl_oen & ~dscl_oen & ~sSCL) | (slave_wait & ~sSCL);
+
+ // master drives SCL high, but another master pulls it low
+ // master start counting down its low cycle now (clock synchronization)
+ wire scl_sync = dSCL & ~sSCL & scl_oen;
+
+
+ // generate clk enable signal
+ always @(posedge clk or negedge aresetn)
+ if (~aresetn)
+ begin
+ cnt <= 16'h0;
+ clk_en <= 1'b1;
+ end
+ else if (!sresetn || ~|cnt || !ena || scl_sync)
+ begin
+ cnt <= clk_cnt;
+ clk_en <= 1'b1;
+ end
+ else if (slave_wait)
+ begin
+ cnt <= cnt;
+ clk_en <= 1'b0;
+ end
+ else
+ begin
+ cnt <= cnt - 16'h1;
+ clk_en <= 1'b0;
+ end
+
+
+ // generate bus status controller
+
+ // capture SDA and SCL
+ // reduce metastability risk
+ always @(posedge clk or negedge aresetn)
+ if (!aresetn)
+ begin
+ cSCL <= 2'b00;
+ cSDA <= 2'b00;
+ end
+ else if (!sresetn)
+ begin
+ cSCL <= 2'b00;
+ cSDA <= 2'b00;
+ end
+ else
+ begin
+ cSCL <= {cSCL[0],scl_i};
+ cSDA <= {cSDA[0],sda_i};
+ end
+
+
+ // filter SCL and SDA signals; (attempt to) remove glitches
+ always @(posedge clk or negedge aresetn)
+ if (!aresetn ) filter_cnt <= 14'h0;
+ else if (!sresetn || !ena ) filter_cnt <= 14'h0;
+ else if (~|filter_cnt) filter_cnt <= clk_cnt >> 2; //16x I2C bus frequency
+ else filter_cnt <= filter_cnt -1;
+
+
+ always @(posedge clk or negedge aresetn)
+ if (!aresetn)
+ begin
+ fSCL <= 3'b111;
+ fSDA <= 3'b111;
+ end
+ else if (!sresetn)
+ begin
+ fSCL <= 3'b111;
+ fSDA <= 3'b111;
+ end
+ else if (~|filter_cnt)
+ begin
+ fSCL <= {fSCL[1:0],cSCL[1]};
+ fSDA <= {fSDA[1:0],cSDA[1]};
+ end
+
+
+ // generate filtered SCL and SDA signals
+ always @(posedge clk or negedge aresetn)
+ if (~aresetn)
+ begin
+ sSCL <= 1'b1;
+ sSDA <= 1'b1;
+
+ dSCL <= 1'b1;
+ dSDA <= 1'b1;
+ end
+ else if (!sresetn)
+ begin
+ sSCL <= 1'b1;
+ sSDA <= 1'b1;
+
+ dSCL <= 1'b1;
+ dSDA <= 1'b1;
+ end
+ else
+ begin
+ sSCL <= &fSCL[2:1] | &fSCL[1:0] | (fSCL[2] & fSCL[0]);
+ sSDA <= &fSDA[2:1] | &fSDA[1:0] | (fSDA[2] & fSDA[0]);
+
+ dSCL <= sSCL;
+ dSDA <= sSDA;
+ end
+
+ // detect start condition => detect falling edge on SDA while SCL is high
+ // detect stop condition => detect rising edge on SDA while SCL is high
+ reg sta_condition;
+ reg sto_condition;
+ always @(posedge clk or negedge aresetn)
+ if (~aresetn)
+ begin
+ sta_condition <= 1'b0;
+ sto_condition <= 1'b0;
+ end
+ else if (!sresetn)
+ begin
+ sta_condition <= 1'b0;
+ sto_condition <= 1'b0;
+ end
+ else
+ begin
+ sta_condition <= ~sSDA & dSDA & sSCL;
+ sto_condition <= sSDA & ~dSDA & sSCL;
+ end
+
+
+ // generate i2c bus busy signal
+ always @(posedge clk or negedge aresetn)
+ if (!aresetn) busy <= 1'b0;
+ else if (!sresetn ) busy <= 1'b0;
+ else busy <= (sta_condition | busy) & ~sto_condition;
+
+
+ // generate arbitration lost signal
+ // aribitration lost when:
+ // 1) master drives SDA high, but the i2c bus is low
+ // 2) stop detected while not requested
+ reg cmd_stop;
+ always @(posedge clk or negedge aresetn)
+ if (~aresetn)
+ cmd_stop <= 1'b0;
+ else if (!sresetn)
+ cmd_stop <= 1'b0;
+ else if (clk_en)
+ cmd_stop <= cmd == `I2C_CMD_STOP;
+
+ always @(posedge clk or negedge aresetn)
+ if (~aresetn)
+ al <= 1'b0;
+ else if (!sresetn)
+ al <= 1'b0;
+ else
+ al <= (sda_chk & ~sSDA & sda_oen) | (|c_state & sto_condition & ~cmd_stop);
+
+
+ // generate dout signal (store SDA on rising edge of SCL)
+ always @(posedge clk)
+ if (sSCL & ~dSCL) dout <= sSDA;
+
+
+ // generate statemachine
+
+ // nxt_state decoder
+ parameter [17:0] idle = 18'b0_0000_0000_0000_0000;
+ parameter [17:0] start_a = 18'b0_0000_0000_0000_0001;
+ parameter [17:0] start_b = 18'b0_0000_0000_0000_0010;
+ parameter [17:0] start_c = 18'b0_0000_0000_0000_0100;
+ parameter [17:0] start_d = 18'b0_0000_0000_0000_1000;
+ parameter [17:0] start_e = 18'b0_0000_0000_0001_0000;
+ parameter [17:0] stop_a = 18'b0_0000_0000_0010_0000;
+ parameter [17:0] stop_b = 18'b0_0000_0000_0100_0000;
+ parameter [17:0] stop_c = 18'b0_0000_0000_1000_0000;
+ parameter [17:0] stop_d = 18'b0_0000_0001_0000_0000;
+ parameter [17:0] rd_a = 18'b0_0000_0010_0000_0000;
+ parameter [17:0] rd_b = 18'b0_0000_0100_0000_0000;
+ parameter [17:0] rd_c = 18'b0_0000_1000_0000_0000;
+ parameter [17:0] rd_d = 18'b0_0001_0000_0000_0000;
+ parameter [17:0] wr_a = 18'b0_0010_0000_0000_0000;
+ parameter [17:0] wr_b = 18'b0_0100_0000_0000_0000;
+ parameter [17:0] wr_c = 18'b0_1000_0000_0000_0000;
+ parameter [17:0] wr_d = 18'b1_0000_0000_0000_0000;
+
+ always @(posedge clk or negedge aresetn)
+ if (!aresetn)
+ begin
+ c_state <= idle;
+ cmd_ack <= 1'b0;
+ scl_oen <= 1'b1;
+ sda_oen <= 1'b1;
+ sda_chk <= 1'b0;
+ end
+ else if (!sresetn | al)
+ begin
+ c_state <= idle;
+ cmd_ack <= 1'b0;
+ scl_oen <= 1'b1;
+ sda_oen <= 1'b1;
+ sda_chk <= 1'b0;
+ end
+ else
+ begin
+ cmd_ack <= 1'b0; // default no command acknowledge + assert cmd_ack only 1clk cycle
+
+ if (clk_en)
+ case (c_state) // synopsys full_case parallel_case
+ // idle state
+ idle:
+ begin
+ case (cmd) // synopsys full_case parallel_case
+ `I2C_CMD_START: c_state <= start_a;
+ `I2C_CMD_STOP: c_state <= stop_a;
+ `I2C_CMD_WRITE: c_state <= wr_a;
+ `I2C_CMD_READ: c_state <= rd_a;
+ default: c_state <= idle;
+ endcase
+
+ scl_oen <= scl_oen; // keep SCL in same state
+ sda_oen <= sda_oen; // keep SDA in same state
+ sda_chk <= 1'b0; // don't check SDA output
+ end
+
+ // start
+ start_a:
+ begin
+ c_state <= start_b;
+ scl_oen <= scl_oen; // keep SCL in same state
+ sda_oen <= 1'b1; // set SDA high
+ sda_chk <= 1'b0; // don't check SDA output
+ end
+
+ start_b:
+ begin
+ c_state <= start_c;
+ scl_oen <= 1'b1; // set SCL high
+ sda_oen <= 1'b1; // keep SDA high
+ sda_chk <= 1'b0; // don't check SDA output
+ end
+
+ start_c:
+ begin
+ c_state <= start_d;
+ scl_oen <= 1'b1; // keep SCL high
+ sda_oen <= 1'b0; // set SDA low
+ sda_chk <= 1'b0; // don't check SDA output
+ end
+
+ start_d:
+ begin
+ c_state <= start_e;
+ scl_oen <= 1'b1; // keep SCL high
+ sda_oen <= 1'b0; // keep SDA low
+ sda_chk <= 1'b0; // don't check SDA output
+ end
+
+ start_e:
+ begin
+ c_state <= idle;
+ cmd_ack <= 1'b1;
+ scl_oen <= 1'b0; // set SCL low
+ sda_oen <= 1'b0; // keep SDA low
+ sda_chk <= 1'b0; // don't check SDA output
+ end
+
+ // stop
+ stop_a:
+ begin
+ c_state <= stop_b;
+ scl_oen <= 1'b0; // keep SCL low
+ sda_oen <= 1'b0; // set SDA low
+ sda_chk <= 1'b0; // don't check SDA output
+ end
+
+ stop_b:
+ begin
+ c_state <= stop_c;
+ scl_oen <= 1'b1; // set SCL high
+ sda_oen <= 1'b0; // keep SDA low
+ sda_chk <= 1'b0; // don't check SDA output
+ end
+
+ stop_c:
+ begin
+ c_state <= stop_d;
+ scl_oen <= 1'b1; // keep SCL high
+ sda_oen <= 1'b0; // keep SDA low
+ sda_chk <= 1'b0; // don't check SDA output
+ end
+
+ stop_d:
+ begin
+ c_state <= idle;
+ cmd_ack <= 1'b1;
+ scl_oen <= 1'b1; // keep SCL high
+ sda_oen <= 1'b1; // set SDA high
+ sda_chk <= 1'b0; // don't check SDA output
+ end
+
+ // read
+ rd_a:
+ begin
+ c_state <= rd_b;
+ scl_oen <= 1'b0; // keep SCL low
+ sda_oen <= 1'b1; // tri-state SDA
+ sda_chk <= 1'b0; // don't check SDA output
+ end
+
+ rd_b:
+ begin
+ c_state <= rd_c;
+ scl_oen <= 1'b1; // set SCL high
+ sda_oen <= 1'b1; // keep SDA tri-stated
+ sda_chk <= 1'b0; // don't check SDA output
+ end
+
+ rd_c:
+ begin
+ c_state <= rd_d;
+ scl_oen <= 1'b1; // keep SCL high
+ sda_oen <= 1'b1; // keep SDA tri-stated
+ sda_chk <= 1'b0; // don't check SDA output
+ end
+
+ rd_d:
+ begin
+ c_state <= idle;
+ cmd_ack <= 1'b1;
+ scl_oen <= 1'b0; // set SCL low
+ sda_oen <= 1'b1; // keep SDA tri-stated
+ sda_chk <= 1'b0; // don't check SDA output
+ end
+
+ // write
+ wr_a:
+ begin
+ c_state <= wr_b;
+ scl_oen <= 1'b0; // keep SCL low
+ sda_oen <= din; // set SDA
+ sda_chk <= 1'b0; // don't check SDA output (SCL low)
+ end
+
+ wr_b:
+ begin
+ c_state <= wr_c;
+ scl_oen <= 1'b1; // set SCL high
+ sda_oen <= din; // keep SDA
+ sda_chk <= 1'b0; // don't check SDA output yet
+ // allow some time for SDA and SCL to settle
+ end
+
+ wr_c:
+ begin
+ c_state <= wr_d;
+ scl_oen <= 1'b1; // keep SCL high
+ sda_oen <= din;
+ sda_chk <= 1'b1; // check SDA output
+ end
+
+ wr_d:
+ begin
+ c_state <= idle;
+ cmd_ack <= 1'b1;
+ scl_oen <= 1'b0; // set SCL low
+ sda_oen <= din;
+ sda_chk <= 1'b0; // don't check SDA output (SCL low)
+ end
+
+ endcase
+ end
+
+
+ // assign scl and sda output (always gnd)
+ assign scl_o = 1'b0;
+ assign sda_o = 1'b0;
+
+endmodule
diff --git a/verilog/rtl/i2cm/src/core/i2cm_byte_ctrl.v b/verilog/rtl/i2cm/src/core/i2cm_byte_ctrl.v
new file mode 100755
index 0000000..002b51e
--- /dev/null
+++ b/verilog/rtl/i2cm/src/core/i2cm_byte_ctrl.v
@@ -0,0 +1,343 @@
+//////////////////////////////////////////////////////////////////////////////
+// SPDX-FileCopyrightText: 2021 , Dinesh Annayya
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+// SPDX-License-Identifier: Apache-2.0
+// SPDX-FileContributor: Created by Dinesh Annayya <dinesha@opencores.org>
+//
+
+//////////////////////////////////////////////////////////////////////
+//// ////
+//// OMS8051 I2C Master byte-controller Module ////
+//// WISHBONE rev.B2 compliant I2C Master byte-controller ////
+//// ////
+//// This file is part of the OMS 8051 cores project ////
+//// http://www.opencores.org/cores/oms8051mini/ ////
+//// ////
+//// Description ////
+//// OMS 8051 definitions. ////
+//// ////
+//// To Do: ////
+//// nothing ////
+//// ////
+//// Author(s): ////
+//// -Richard Herveille , richard@asics.ws, www.asics.ws ////
+//// -Dinesh Annayya, dinesha@opencores.org ////
+//// ////
+//// Revision : Jan 6, 2017 ////
+//// ////
+//////////////////////////////////////////////////////////////////////
+//// v0.0 - Dinesh A, 6th Jan 2017
+//// 1. Initail version picked from
+//// http://www.opencores.org/projects/i2c/
+//// 2. renaming of reset signal to aresetn and sresetn
+//// v0.1 - Dinesh.A, 19th Jan 2017
+//// 1. Lint Error fixes
+//////////////////////////////////////////////////////////////////////
+//// ////
+//// Copyright (C) 2000 Authors and OPENCORES.ORG ////
+//// ////
+//// This source file may be used and distributed without ////
+//// restriction provided that this copyright statement is not ////
+//// removed from the file and that any derivative work contains ////
+//// the original copyright notice and the associated disclaimer. ////
+//// ////
+//// This source file is free software; you can redistribute it ////
+//// and/or modify it under the terms of the GNU Lesser General ////
+//// Public License as published by the Free Software Foundation; ////
+//// either version 2.1 of the License, or (at your option) any ////
+//// later version. ////
+//// ////
+//// This source is distributed in the hope that it will be ////
+//// useful, but WITHOUT ANY WARRANTY; without even the implied ////
+//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR ////
+//// PURPOSE. See the GNU Lesser General Public License for more ////
+//// details. ////
+//// ////
+//// You should have received a copy of the GNU Lesser General ////
+//// Public License along with this source; if not, download it ////
+//// from http://www.opencores.org/lgpl.shtml ////
+//// ////
+//////////////////////////////////////////////////////////////////////
+
+`include "i2cm_defines.v"
+
+module i2cm_byte_ctrl (
+ //
+ // inputs & outputs
+ //
+ input clk, // master clock
+ input sresetn, // synchronous active high reset
+ input aresetn, // asynchronous active low reset
+ input ena, // core enable signal
+
+ input [15:0] clk_cnt, // 4x SCL
+
+ // control inputs
+ input start,
+ input stop,
+ input read,
+ input write,
+ input ack_in,
+ input [7:0] din,
+
+ // status outputs
+ output reg cmd_ack,
+ output reg ack_out,
+ output i2c_busy,
+ output i2c_al,
+ output [7:0] dout,
+
+ // I2C signals
+ input scl_i,
+ output scl_o,
+ output scl_oen,
+ input sda_i,
+ output sda_o,
+ output sda_oen
+
+ );
+
+
+
+ //
+ // Variable declarations
+ //
+
+ // statemachine
+ parameter [4:0] ST_IDLE = 5'b0_0000;
+ parameter [4:0] ST_START = 5'b0_0001;
+ parameter [4:0] ST_READ = 5'b0_0010;
+ parameter [4:0] ST_WRITE = 5'b0_0100;
+ parameter [4:0] ST_ACK = 5'b0_1000;
+ parameter [4:0] ST_STOP = 5'b1_0000;
+
+ // signals for bit_controller
+ reg [3:0] core_cmd;
+ reg core_txd;
+ wire core_ack, core_rxd;
+
+ // signals for shift register
+ reg [7:0] sr; //8bit shift register
+ reg shift, ld;
+
+ // signals for state machine
+ wire go;
+ reg [2:0] dcnt;
+ wire cnt_done;
+
+ //
+ // Module body
+ //
+
+ // hookup bit_controller
+ i2cm_bit_ctrl u_bit_ctrl (
+ .clk ( clk ),
+ .sresetn ( sresetn ),
+ .aresetn ( aresetn ),
+ .ena ( ena ),
+ .clk_cnt ( clk_cnt ),
+ .cmd ( core_cmd ),
+ .cmd_ack ( core_ack ),
+ .busy ( i2c_busy ),
+ .al ( i2c_al ),
+ .din ( core_txd ),
+ .dout ( core_rxd ),
+ .scl_i ( scl_i ),
+ .scl_o ( scl_o ),
+ .scl_oen ( scl_oen ),
+ .sda_i ( sda_i ),
+ .sda_o ( sda_o ),
+ .sda_oen ( sda_oen )
+ );
+
+ // generate go-signal
+ assign go = (read | write | stop) & ~cmd_ack;
+
+ // assign dout output to shift-register
+ assign dout = sr;
+
+ // generate shift register
+ always @(posedge clk or negedge aresetn)
+ if (!aresetn)
+ sr <= 8'h0;
+ else if (!sresetn)
+ sr <= 8'h0;
+ else if (ld)
+ sr <= din;
+ else if (shift)
+ sr <= {sr[6:0], core_rxd};
+
+ // generate counter
+ always @(posedge clk or negedge aresetn)
+ if (!aresetn)
+ dcnt <= 3'h0;
+ else if (!sresetn)
+ dcnt <= 3'h0;
+ else if (ld)
+ dcnt <= 3'h7;
+ else if (shift)
+ dcnt <= dcnt - 3'h1;
+
+ assign cnt_done = ~(|dcnt);
+
+ //
+ // state machine
+ //
+ reg [4:0] c_state; // synopsys enum_state
+
+ always @(posedge clk or negedge aresetn)
+ if (!aresetn)
+ begin
+ core_cmd <= `I2C_CMD_NOP;
+ core_txd <= 1'b0;
+ shift <= 1'b0;
+ ld <= 1'b0;
+ cmd_ack <= 1'b0;
+ c_state <= ST_IDLE;
+ ack_out <= 1'b0;
+ end
+ else if (!sresetn | i2c_al)
+ begin
+ core_cmd <= `I2C_CMD_NOP;
+ core_txd <= 1'b0;
+ shift <= 1'b0;
+ ld <= 1'b0;
+ cmd_ack <= 1'b0;
+ c_state <= ST_IDLE;
+ ack_out <= 1'b0;
+ end
+ else
+ begin
+ // initially reset all signals
+ core_txd <= sr[7];
+ shift <= 1'b0;
+ ld <= 1'b0;
+ cmd_ack <= 1'b0;
+
+ case (c_state) // synopsys full_case parallel_case
+ ST_IDLE:
+ if (go)
+ begin
+ if (start)
+ begin
+ c_state <= ST_START;
+ core_cmd <= `I2C_CMD_START;
+ end
+ else if (read)
+ begin
+ c_state <= ST_READ;
+ core_cmd <= `I2C_CMD_READ;
+ end
+ else if (write)
+ begin
+ c_state <= ST_WRITE;
+ core_cmd <= `I2C_CMD_WRITE;
+ end
+ else // stop
+ begin
+ c_state <= ST_STOP;
+ core_cmd <= `I2C_CMD_STOP;
+ end
+
+ ld <= 1'b1;
+ end
+
+ ST_START:
+ if (core_ack)
+ begin
+ if (read)
+ begin
+ c_state <= ST_READ;
+ core_cmd <= `I2C_CMD_READ;
+ end
+ else
+ begin
+ c_state <= ST_WRITE;
+ core_cmd <= `I2C_CMD_WRITE;
+ end
+
+ ld <= 1'b1;
+ end
+
+ ST_WRITE:
+ if (core_ack)
+ if (cnt_done)
+ begin
+ c_state <= ST_ACK;
+ core_cmd <= `I2C_CMD_READ;
+ end
+ else
+ begin
+ c_state <= ST_WRITE; // stay in same state
+ core_cmd <= `I2C_CMD_WRITE; // write next bit
+ shift <= 1'b1;
+ end
+
+ ST_READ:
+ if (core_ack)
+ begin
+ if (cnt_done)
+ begin
+ c_state <= ST_ACK;
+ core_cmd <= `I2C_CMD_WRITE;
+ end
+ else
+ begin
+ c_state <= ST_READ; // stay in same state
+ core_cmd <= `I2C_CMD_READ; // read next bit
+ end
+
+ shift <= 1'b1;
+ core_txd <= ack_in;
+ end
+
+ ST_ACK:
+ if (core_ack)
+ begin
+ if (stop)
+ begin
+ c_state <= ST_STOP;
+ core_cmd <= `I2C_CMD_STOP;
+ end
+ else
+ begin
+ c_state <= ST_IDLE;
+ core_cmd <= `I2C_CMD_NOP;
+
+ // generate command acknowledge signal
+ cmd_ack <= 1'b1;
+ end
+
+ // assign ack_out output to bit_controller_rxd (contains last received bit)
+ ack_out <= core_rxd;
+
+ core_txd <= 1'b1;
+ end
+ else
+ core_txd <= ack_in;
+
+ ST_STOP:
+ if (core_ack)
+ begin
+ c_state <= ST_IDLE;
+ core_cmd <= `I2C_CMD_NOP;
+
+ // generate command acknowledge signal
+ cmd_ack <= 1'b1;
+ end
+ default: c_state <= ST_IDLE;
+
+ endcase
+ end
+endmodule
diff --git a/verilog/rtl/i2cm/src/core/i2cm_top.v b/verilog/rtl/i2cm/src/core/i2cm_top.v
new file mode 100755
index 0000000..3b32db9
--- /dev/null
+++ b/verilog/rtl/i2cm/src/core/i2cm_top.v
@@ -0,0 +1,280 @@
+//////////////////////////////////////////////////////////////////////////////
+// SPDX-FileCopyrightText: 2021 , Dinesh Annayya
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+// SPDX-License-Identifier: Apache-2.0
+// SPDX-FileContributor: Created by Dinesh Annayya <dinesha@opencores.org>
+//
+//////////////////////////////////////////////////////////////////////
+//// ////
+//// OMS8051 I2C Master Core Module ////
+//// WISHBONE revB.2 compliant I2C Master controller Top-level ////
+//// ////
+//// This file is part of the OMS 8051 cores project ////
+//// http://www.opencores.org/cores/oms8051mini/ ////
+//// ////
+//// Description ////
+//// OMS 8051 definitions. ////
+//// ////
+//// To Do: ////
+//// nothing ////
+//// ////
+//// Author(s): ////
+//// -Richard Herveille , richard@asics.ws, www.asics.ws ////
+//// -Dinesh Annayya, dinesha@opencores.org ////
+//// ////
+//// Revision : Jan 6, 2017 ////
+//// ////
+//////////////////////////////////////////////////////////////////////
+// v0.0 - Dinesh A, 6th Jan 2017
+// 1. Initail version picked from
+// http://www.opencores.org/projects/i2c/
+// 2. renaming of reset signal to aresetn and sresetn
+//
+//////////////////////////////////////////////////////////////////////
+//// ////
+//// Copyright (C) 2000 Authors and OPENCORES.ORG ////
+//// ////
+//// This source file may be used and distributed without ////
+//// restriction provided that this copyright statement is not ////
+//// removed from the file and that any derivative work contains ////
+//// the original copyright notice and the associated disclaimer. ////
+//// ////
+//// This source file is free software; you can redistribute it ////
+//// and/or modify it under the terms of the GNU Lesser General ////
+//// Public License as published by the Free Software Foundation; ////
+//// either version 2.1 of the License, or (at your option) any ////
+//// later version. ////
+//// ////
+//// This source is distributed in the hope that it will be ////
+//// useful, but WITHOUT ANY WARRANTY; without even the implied ////
+//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR ////
+//// PURPOSE. See the GNU Lesser General Public License for more ////
+//// details. ////
+//// ////
+//// You should have received a copy of the GNU Lesser General ////
+//// Public License along with this source; if not, download it ////
+//// from http://www.opencores.org/lgpl.shtml ////
+//// ////
+//////////////////////////////////////////////////////////////////////
+
+`include "i2cm_defines.v"
+
+module i2cm_top(
+ // wishbone signals
+ input wb_clk_i, // master clock input
+ input sresetn, // synchronous reset
+ input aresetn, // asynchronous reset
+ input [2:0] wb_adr_i, // lower address bits
+ input [7:0] wb_dat_i, // databus input
+ output reg [7:0] wb_dat_o, // databus output
+ input wb_we_i, // write enable input
+ input wb_stb_i, // stobe/core select signal
+ input wb_cyc_i, // valid bus cycle input
+ output reg wb_ack_o, // bus cycle acknowledge output
+ output reg wb_inta_o, // interrupt request signal output
+
+ // I2C signals
+ // i2c clock line
+ input scl_pad_i, // SCL-line input
+ output scl_pad_o, // SCL-line output (always 1'b0)
+ output scl_padoen_o, // SCL-line output enable (active low)
+
+ // i2c data line
+ input sda_pad_i, // SDA-line input
+ output sda_pad_o, // SDA-line output (always 1'b0)
+ output sda_padoen_o // SDA-line output enable (active low)
+
+ );
+
+
+ //
+ // variable declarations
+ //
+
+ // registers
+ reg [15:0] prer; // clock prescale register
+ reg [ 7:0] ctr; // control register
+ reg [ 7:0] txr; // transmit register
+ wire [ 7:0] rxr; // receive register
+ reg [ 7:0] cr; // command register
+ wire [ 7:0] sr; // status register
+
+ // done signal: command completed, clear command register
+ wire done;
+
+ // core enable signal
+ wire core_en;
+ wire ien;
+
+ // status register signals
+ wire irxack;
+ reg rxack; // received aknowledge from slave
+ reg tip; // transfer in progress
+ reg irq_flag; // interrupt pending flag
+ wire i2c_busy; // bus busy (start signal detected)
+ wire i2c_al; // i2c bus arbitration lost
+ reg al; // status register arbitration lost bit
+
+ //
+ // module body
+ //
+
+
+ // generate wishbone signals
+ wire wb_wacc = wb_we_i & wb_ack_o;
+
+ // generate acknowledge output signal
+ always @(posedge wb_clk_i)
+ wb_ack_o <= #1 wb_cyc_i & wb_stb_i & ~wb_ack_o; // because timing is always honored
+
+ // assign DAT_O
+ always @(posedge wb_clk_i)
+ begin
+ case (wb_adr_i) // synopsys parallel_case
+ 3'b000: wb_dat_o <= #1 prer[ 7:0];
+ 3'b001: wb_dat_o <= #1 prer[15:8];
+ 3'b010: wb_dat_o <= #1 ctr;
+ 3'b011: wb_dat_o <= #1 rxr; // write is transmit register (txr)
+ 3'b100: wb_dat_o <= #1 sr; // write is command register (cr)
+ 3'b101: wb_dat_o <= #1 txr;
+ 3'b110: wb_dat_o <= #1 cr;
+ 3'b111: wb_dat_o <= #1 0; // reserved
+ endcase
+ end
+
+ // generate registers
+ always @(posedge wb_clk_i or negedge aresetn)
+ if (!aresetn)
+ begin
+ prer <= #1 16'hffff;
+ ctr <= #1 8'h0;
+ txr <= #1 8'h0;
+ end
+ else if (!sresetn)
+ begin
+ prer <= #1 16'hffff;
+ ctr <= #1 8'h0;
+ txr <= #1 8'h0;
+ end
+ else
+ if (wb_wacc)
+ case (wb_adr_i) // synopsys parallel_case
+ 3'b000 : prer [ 7:0] <= #1 wb_dat_i;
+ 3'b001 : prer [15:8] <= #1 wb_dat_i;
+ 3'b010 : ctr <= #1 wb_dat_i;
+ 3'b011 : txr <= #1 wb_dat_i;
+ default: ;
+ endcase
+
+ // generate command register (special case)
+ always @(posedge wb_clk_i or negedge aresetn)
+ if (!aresetn)
+ cr <= #1 8'h0;
+ else if (!sresetn)
+ cr <= #1 8'h0;
+ else if (wb_wacc)
+ begin
+ if (core_en & (wb_adr_i == 3'b100) )
+ cr <= #1 wb_dat_i;
+ end
+ else
+ begin
+ if (done | i2c_al)
+ cr[7:4] <= #1 4'h0; // clear command bits when done
+ // or when aribitration lost
+ cr[2:1] <= #1 2'b0; // reserved bits
+ cr[0] <= #1 1'b0; // clear IRQ_ACK bit
+ end
+
+
+ // decode command register
+ wire sta = cr[7];
+ wire sto = cr[6];
+ wire rd = cr[5];
+ wire wr = cr[4];
+ wire ack = cr[3];
+ wire iack = cr[0];
+
+ // decode control register
+ assign core_en = ctr[7];
+ assign ien = ctr[6];
+
+ // hookup byte controller block
+ i2cm_byte_ctrl u_byte_ctrl (
+ .clk ( wb_clk_i ),
+ .sresetn ( sresetn ),
+ .aresetn ( aresetn ),
+ .ena ( core_en ),
+ .clk_cnt ( prer ),
+ .start ( sta ),
+ .stop ( sto ),
+ .read ( rd ),
+ .write ( wr ),
+ .ack_in ( ack ),
+ .din ( txr ),
+ .cmd_ack ( done ),
+ .ack_out ( irxack ),
+ .dout ( rxr ),
+ .i2c_busy ( i2c_busy ),
+ .i2c_al ( i2c_al ),
+ .scl_i ( scl_pad_i ),
+ .scl_o ( scl_pad_o ),
+ .scl_oen ( scl_padoen_o ),
+ .sda_i ( sda_pad_i ),
+ .sda_o ( sda_pad_o ),
+ .sda_oen ( sda_padoen_o )
+ );
+
+ // status register block + interrupt request signal
+ always @(posedge wb_clk_i or negedge aresetn)
+ if (!aresetn)
+ begin
+ al <= #1 1'b0;
+ rxack <= #1 1'b0;
+ tip <= #1 1'b0;
+ irq_flag <= #1 1'b0;
+ end
+ else if (!sresetn)
+ begin
+ al <= #1 1'b0;
+ rxack <= #1 1'b0;
+ tip <= #1 1'b0;
+ irq_flag <= #1 1'b0;
+ end
+ else
+ begin
+ al <= #1 i2c_al | (al & ~sta);
+ rxack <= #1 irxack;
+ tip <= #1 (rd | wr);
+ irq_flag <= #1 (done | i2c_al | irq_flag) & ~iack; // interrupt request flag is always generated
+ end
+
+ // generate interrupt request signals
+ always @(posedge wb_clk_i or negedge aresetn)
+ if (!aresetn)
+ wb_inta_o <= #1 1'b0;
+ else if (!sresetn)
+ wb_inta_o <= #1 1'b0;
+ else
+ wb_inta_o <= #1 irq_flag && ien; // interrupt signal is only generated when IEN (interrupt enable bit is set)
+
+ // assign status register bits
+ assign sr[7] = rxack;
+ assign sr[6] = i2c_busy;
+ assign sr[5] = al;
+ assign sr[4:2] = 3'h0; // reserved
+ assign sr[1] = tip;
+ assign sr[0] = irq_flag;
+
+endmodule
diff --git a/verilog/rtl/i2cm/src/includes/i2cm_defines.v b/verilog/rtl/i2cm/src/includes/i2cm_defines.v
new file mode 100755
index 0000000..ccfee25
--- /dev/null
+++ b/verilog/rtl/i2cm/src/includes/i2cm_defines.v
@@ -0,0 +1,25 @@
+//////////////////////////////////////////////////////////////////////////////
+// SPDX-FileCopyrightText: 2021 , Dinesh Annayya
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+// SPDX-License-Identifier: Apache-2.0
+// SPDX-FileContributor: Created by Dinesh Annayya <dinesha@opencores.org>
+//
+// I2C registers wishbone addresses
+
+// bitcontroller states
+`define I2C_CMD_NOP 4'b0000
+`define I2C_CMD_START 4'b0001
+`define I2C_CMD_STOP 4'b0010
+`define I2C_CMD_WRITE 4'b0100
+`define I2C_CMD_READ 4'b1000
diff --git a/verilog/rtl/lib/async_fifo.sv b/verilog/rtl/lib/async_fifo.sv
new file mode 100755
index 0000000..fd59cfa
--- /dev/null
+++ b/verilog/rtl/lib/async_fifo.sv
@@ -0,0 +1,341 @@
+//////////////////////////////////////////////////////////////////////////////
+// SPDX-FileCopyrightText: 2021 , Dinesh Annayya
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+// SPDX-License-Identifier: Apache-2.0
+// SPDX-FileContributor: Created by Dinesh Annayya <dinesha@opencores.org>
+//
+/*********************************************************************
+
+ ASYNC FIFO
+
+ This file is part of the sdram controller project
+ https://github.com/dineshannayya/yifive_r0.git
+ http://www.opencores.org/cores/sdr_ctrl/
+
+ Description: ASYNC FIFO
+
+ To Do:
+ nothing
+
+ Author(s): Dinesh Annayya, dinesha@opencores.org
+
+ Copyright (C) 2000 Authors and OPENCORES.ORG
+
+ This source file may be used and distributed without
+ restriction provided that this copyright statement is not
+ removed from the file and that any derivative work contains
+ the original copyright notice and the associated disclaimer.
+
+ This source file is free software; you can redistribute it
+ and/or modify it under the terms of the GNU Lesser General
+ Public License as published by the Free Software Foundation;
+ either version 2.1 of the License, or (at your option) any
+later version.
+
+ This source is distributed in the hope that it will be
+ useful, but WITHOUT ANY WARRANTY; without even the implied
+ warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ PURPOSE. See the GNU Lesser General Public License for more
+ details.
+
+ You should have received a copy of the GNU Lesser General
+ Public License along with this source; if not, download it
+ from http://www.opencores.org/lgpl.shtml
+
+*******************************************************************/
+
+//-------------------------------------------
+// async FIFO
+//-----------------------------------------------
+//`timescale 1ns/1ps
+
+module async_fifo (wr_clk,
+ wr_reset_n,
+ wr_en,
+ wr_data,
+ full, // sync'ed to wr_clk
+ afull, // sync'ed to wr_clk
+ rd_clk,
+ rd_reset_n,
+ rd_en,
+ empty, // sync'ed to rd_clk
+ aempty, // sync'ed to rd_clk
+ rd_data);
+
+ parameter W = 4'd8;
+ parameter DP = 3'd4;
+ parameter WR_FAST = 1'b1;
+ parameter RD_FAST = 1'b1;
+ parameter FULL_DP = DP;
+ parameter EMPTY_DP = 1'b0;
+
+ parameter AW = (DP == 2) ? 1 :
+ (DP == 4) ? 2 :
+ (DP == 8) ? 3 :
+ (DP == 16) ? 4 :
+ (DP == 32) ? 5 :
+ (DP == 64) ? 6 :
+ (DP == 128) ? 7 :
+ (DP == 256) ? 8 : 0;
+
+ output [W-1 : 0] rd_data;
+ input [W-1 : 0] wr_data;
+ input wr_clk, wr_reset_n, wr_en, rd_clk, rd_reset_n,
+ rd_en;
+ output full, empty;
+ output afull, aempty; // about full and about to empty
+
+
+ // synopsys translate_off
+
+ initial begin
+ if (AW == 0) begin
+ $display ("%m : ERROR!!! Fifo depth %d not in range 2 to 256", DP);
+ end // if (AW == 0)
+ end // initial begin
+
+ // synopsys translate_on
+
+ reg [W-1 : 0] mem[DP-1 : 0];
+
+ /*********************** write side ************************/
+ reg [AW:0] sync_rd_ptr_0, sync_rd_ptr_1;
+ wire [AW:0] sync_rd_ptr;
+ reg [AW:0] wr_ptr, grey_wr_ptr;
+ reg [AW:0] grey_rd_ptr;
+ reg full_q;
+ wire full_c;
+ wire afull_c;
+ wire [AW:0] wr_ptr_inc = wr_ptr + 1'b1;
+ wire [AW:0] wr_cnt = get_cnt(wr_ptr, sync_rd_ptr);
+
+ assign full_c = (wr_cnt == FULL_DP) ? 1'b1 : 1'b0;
+ assign afull_c = (wr_cnt == FULL_DP-1) ? 1'b1 : 1'b0;
+
+
+ always @(posedge wr_clk or negedge wr_reset_n) begin
+ if (!wr_reset_n) begin
+ wr_ptr <= 0;
+ grey_wr_ptr <= 0;
+ full_q <= 0;
+ end
+ else if (wr_en) begin
+ wr_ptr <= wr_ptr_inc;
+ grey_wr_ptr <= bin2grey(wr_ptr_inc);
+ if (wr_cnt == (FULL_DP-1)) begin
+ full_q <= 1'b1;
+ end
+ end
+ else begin
+ if (full_q && (wr_cnt<FULL_DP)) begin
+ full_q <= 1'b0;
+ end
+ end
+ end
+
+ assign full = (WR_FAST == 1) ? full_c : full_q;
+ assign afull = afull_c;
+
+ always @(posedge wr_clk) begin
+ if (wr_en) begin
+ mem[wr_ptr[AW-1:0]] <= wr_data;
+ end
+ end
+
+ wire [AW:0] grey_rd_ptr_dly ;
+ assign #1 grey_rd_ptr_dly = grey_rd_ptr;
+
+ // read pointer synchronizer
+ always @(posedge wr_clk or negedge wr_reset_n) begin
+ if (!wr_reset_n) begin
+ sync_rd_ptr_0 <= 0;
+ sync_rd_ptr_1 <= 0;
+ end
+ else begin
+ sync_rd_ptr_0 <= grey_rd_ptr_dly;
+ sync_rd_ptr_1 <= sync_rd_ptr_0;
+ end
+ end
+
+ assign sync_rd_ptr = grey2bin(sync_rd_ptr_1);
+
+ /************************ read side *****************************/
+ reg [AW:0] sync_wr_ptr_0, sync_wr_ptr_1;
+ wire [AW:0] sync_wr_ptr;
+ reg [AW:0] rd_ptr;
+ reg empty_q;
+ wire empty_c;
+ wire aempty_c;
+ wire [AW:0] rd_ptr_inc = rd_ptr + 1'b1;
+ wire [AW:0] sync_wr_ptr_dec = sync_wr_ptr - 1'b1;
+ wire [AW:0] rd_cnt = get_cnt(sync_wr_ptr, rd_ptr);
+
+ assign empty_c = (rd_cnt == 0) ? 1'b1 : 1'b0;
+ assign aempty_c = (rd_cnt == 1) ? 1'b1 : 1'b0;
+
+ always @(posedge rd_clk or negedge rd_reset_n) begin
+ if (!rd_reset_n) begin
+ rd_ptr <= 0;
+ grey_rd_ptr <= 0;
+ empty_q <= 1'b1;
+ end
+ else begin
+ if (rd_en) begin
+ rd_ptr <= rd_ptr_inc;
+ grey_rd_ptr <= bin2grey(rd_ptr_inc);
+ if (rd_cnt==(EMPTY_DP+1)) begin
+ empty_q <= 1'b1;
+ end
+ end
+ else begin
+ if (empty_q && (rd_cnt!=EMPTY_DP)) begin
+ empty_q <= 1'b0;
+ end
+ end
+ end
+ end
+
+ assign empty = (RD_FAST == 1) ? empty_c : empty_q;
+ assign aempty = aempty_c;
+
+ reg [W-1 : 0] rd_data_q;
+
+ wire [W-1 : 0] rd_data_c = mem[rd_ptr[AW-1:0]];
+ always @(posedge rd_clk) begin
+ rd_data_q <= rd_data_c;
+ end
+ assign rd_data = (RD_FAST == 1) ? rd_data_c : rd_data_q;
+
+ wire [AW:0] grey_wr_ptr_dly ;
+ assign #1 grey_wr_ptr_dly = grey_wr_ptr;
+
+ // write pointer synchronizer
+ always @(posedge rd_clk or negedge rd_reset_n) begin
+ if (!rd_reset_n) begin
+ sync_wr_ptr_0 <= 0;
+ sync_wr_ptr_1 <= 0;
+ end
+ else begin
+ sync_wr_ptr_0 <= grey_wr_ptr_dly;
+ sync_wr_ptr_1 <= sync_wr_ptr_0;
+ end
+ end
+ assign sync_wr_ptr = grey2bin(sync_wr_ptr_1);
+
+
+/************************ functions ******************************/
+function [AW:0] bin2grey;
+input [AW:0] bin;
+reg [8:0] bin_8;
+reg [8:0] grey_8;
+begin
+ bin_8 = bin;
+ grey_8[1:0] = do_grey(bin_8[2:0]);
+ grey_8[3:2] = do_grey(bin_8[4:2]);
+ grey_8[5:4] = do_grey(bin_8[6:4]);
+ grey_8[7:6] = do_grey(bin_8[8:6]);
+ grey_8[8] = bin_8[8];
+ bin2grey = grey_8;
+end
+endfunction
+
+function [AW:0] grey2bin;
+input [AW:0] grey;
+reg [8:0] grey_8;
+reg [8:0] bin_8;
+begin
+ grey_8 = grey;
+ bin_8[8] = grey_8[8];
+ bin_8[7:6] = do_bin({bin_8[8], grey_8[7:6]});
+ bin_8[5:4] = do_bin({bin_8[6], grey_8[5:4]});
+ bin_8[3:2] = do_bin({bin_8[4], grey_8[3:2]});
+ bin_8[1:0] = do_bin({bin_8[2], grey_8[1:0]});
+ grey2bin = bin_8;
+end
+endfunction
+
+
+function [1:0] do_grey;
+input [2:0] bin;
+begin
+ if (bin[2]) begin // do reverse grey
+ case (bin[1:0])
+ 2'b00: do_grey = 2'b10;
+ 2'b01: do_grey = 2'b11;
+ 2'b10: do_grey = 2'b01;
+ 2'b11: do_grey = 2'b00;
+ endcase
+ end
+ else begin
+ case (bin[1:0])
+ 2'b00: do_grey = 2'b00;
+ 2'b01: do_grey = 2'b01;
+ 2'b10: do_grey = 2'b11;
+ 2'b11: do_grey = 2'b10;
+ endcase
+ end
+end
+endfunction
+
+function [1:0] do_bin;
+input [2:0] grey;
+begin
+ if (grey[2]) begin // actually bin[2]
+ case (grey[1:0])
+ 2'b10: do_bin = 2'b00;
+ 2'b11: do_bin = 2'b01;
+ 2'b01: do_bin = 2'b10;
+ 2'b00: do_bin = 2'b11;
+ endcase
+ end
+ else begin
+ case (grey[1:0])
+ 2'b00: do_bin = 2'b00;
+ 2'b01: do_bin = 2'b01;
+ 2'b11: do_bin = 2'b10;
+ 2'b10: do_bin = 2'b11;
+ endcase
+ end
+end
+endfunction
+
+function [AW:0] get_cnt;
+input [AW:0] wr_ptr, rd_ptr;
+begin
+ if (wr_ptr >= rd_ptr) begin
+ get_cnt = (wr_ptr - rd_ptr);
+ end
+ else begin
+ get_cnt = DP*2 - (rd_ptr - wr_ptr);
+ end
+end
+endfunction
+
+// synopsys translate_off
+always @(posedge wr_clk) begin
+ if (wr_en && full) begin
+ $display($time, "%m Error! afifo overflow!");
+ $stop;
+ end
+end
+
+always @(posedge rd_clk) begin
+ if (rd_en && empty) begin
+ $display($time, "%m error! afifo underflow!");
+ $stop;
+ end
+end
+// synopsys translate_on
+
+endmodule
diff --git a/verilog/rtl/lib/async_fifo_th.sv b/verilog/rtl/lib/async_fifo_th.sv
new file mode 100755
index 0000000..05860f8
--- /dev/null
+++ b/verilog/rtl/lib/async_fifo_th.sv
@@ -0,0 +1,404 @@
+//////////////////////////////////////////////////////////////////////////////
+// SPDX-FileCopyrightText: 2021 , Dinesh Annayya
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+// SPDX-License-Identifier: Apache-2.0
+// SPDX-FileContributor: Created by Dinesh Annayya <dinesha@opencores.org>
+//
+//////////////////////////////////////////////////////////////////////
+//// ////
+//// OMS 8051 cores common library Module ////
+//// ////
+//// This file is part of the OMS 8051 cores project ////
+//// https://github.com/dineshannayya/yifive_r0.git ////
+//// http://www.opencores.org/cores/oms8051mini/ ////
+//// ////
+//// Description ////
+//// Async Fifo with threshold tracking/status ////
+//// ////
+//// To Do: ////
+//// nothing ////
+//// ////
+//// Author(s): ////
+//// - Dinesh Annayya, dinesha@opencores.org ////
+//// ////
+//// Revision : Nov 26, 2016 ////
+//// ////
+//////////////////////////////////////////////////////////////////////
+//// ////
+//// Copyright (C) 2000 Authors and OPENCORES.ORG ////
+//// ////
+//// This source file may be used and distributed without ////
+//// restriction provided that this copyright statement is not ////
+//// removed from the file and that any derivative work contains ////
+//// the original copyright notice and the associated disclaimer. ////
+//// ////
+//// This source file is free software; you can redistribute it ////
+//// and/or modify it under the terms of the GNU Lesser General ////
+//// Public License as published by the Free Software Foundation; ////
+//// either version 2.1 of the License, or (at your option) any ////
+//// later version. ////
+//// ////
+//// This source is distributed in the hope that it will be ////
+//// useful, but WITHOUT ANY WARRANTY; without even the implied ////
+//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR ////
+//// PURPOSE. See the GNU Lesser General Public License for more ////
+//// details. ////
+//// ////
+//// You should have received a copy of the GNU Lesser General ////
+//// Public License along with this source; if not, download it ////
+//// from http://www.opencores.org/lgpl.shtml ////
+//// ////
+//////////////////////////////////////////////////////////////////////
+
+//-------------------------------------------
+// async_fifo:: async FIFO
+// Following two ports are newly added
+// 1. At write clock domain:
+// wr_total_free_space --> Indicate total free transfer available
+// 2. At read clock domain:
+// rd_total_aval --> Indicate total no of transfer available
+//-----------------------------------------------
+
+module async_fifo_th (
+ wr_clk,
+ wr_reset_n,
+ wr_en,
+ wr_data,
+ full, // sync'ed to wr_clk
+ afull, // sync'ed to wr_clk
+ wr_total_free_space,
+ rd_clk,
+ rd_reset_n,
+ rd_en,
+ empty, // sync'ed to rd_clk
+ aempty, // sync'ed to rd_clk
+ rd_total_aval,
+ rd_data);
+
+ parameter W = 4'd8;
+ parameter DP = 3'd4;
+ parameter WR_FAST = 1'b1;
+ parameter RD_FAST = 1'b1;
+ parameter FULL_DP = DP;
+ parameter EMPTY_DP = 1'b0;
+
+ parameter AW = (DP == 2) ? 1 :
+ (DP == 4) ? 2 :
+ (DP == 8) ? 3 :
+ (DP == 16) ? 4 :
+ (DP == 32) ? 5 :
+ (DP == 64) ? 6 :
+ (DP == 128) ? 7 :
+ (DP == 256) ? 8 : 0;
+
+ output [W-1 : 0] rd_data;
+ input [W-1 : 0] wr_data;
+ input wr_clk, wr_reset_n, wr_en, rd_clk, rd_reset_n,
+ rd_en;
+ output full, empty;
+ output afull, aempty; // about full and about to empty
+ output [AW:0] wr_total_free_space; // Total Number of free space aval
+ // w.r.t write clk
+ // note: Without accounting byte enables
+ output [AW:0] rd_total_aval; // Total Number of words avaialble
+ // w.r.t rd clock,
+ // note: Without accounting byte enables
+ // synopsys translate_off
+
+ initial begin
+ if (AW == 0) begin
+ $display ("%m : ERROR!!! Fifo depth %d not in range 2 to 256", DP);
+ end // if (AW == 0)
+ end // initial begin
+
+ // synopsys translate_on
+ reg [W-1 : 0] mem[DP-1 : 0];
+
+ /*********************** write side ************************/
+ reg [AW:0] sync_rd_ptr_0, sync_rd_ptr_1;
+ wire [AW:0] sync_rd_ptr;
+ reg [AW:0] wr_ptr, grey_wr_ptr;
+ reg [AW:0] grey_rd_ptr;
+ reg full_q;
+ wire full_c;
+ wire afull_c;
+ wire [AW:0] wr_ptr_inc = wr_ptr + 1'b1;
+ wire [AW:0] wr_cnt = get_cnt(wr_ptr, sync_rd_ptr);
+
+ assign full_c = (wr_cnt == FULL_DP) ? 1'b1 : 1'b0;
+ assign afull_c = (wr_cnt == FULL_DP-1) ? 1'b1 : 1'b0;
+
+ //--------------------------
+ // Shows total number of words
+ // of free space available w.r.t write clock
+ //---------------------------
+ assign wr_total_free_space = FULL_DP - wr_cnt;
+
+ always @(posedge wr_clk or negedge wr_reset_n) begin
+ if (!wr_reset_n) begin
+ wr_ptr <= 0;
+ grey_wr_ptr <= 0;
+ full_q <= 0;
+ end
+ else if (wr_en) begin
+ wr_ptr <= wr_ptr_inc;
+ grey_wr_ptr <= bin2grey(wr_ptr_inc);
+ if (wr_cnt == (FULL_DP-1)) begin
+ full_q <= 1'b1;
+ end
+ end
+ else begin
+ if (full_q && (wr_cnt<FULL_DP)) begin
+ full_q <= 1'b0;
+ end
+ end
+ end
+
+ assign full = (WR_FAST == 1) ? full_c : full_q;
+ assign afull = afull_c;
+
+ always @(posedge wr_clk) begin
+ if (wr_en) begin
+ mem[wr_ptr[AW-1:0]] <= wr_data;
+ end
+ end
+
+ wire [AW:0] grey_rd_ptr_dly ;
+ assign #1 grey_rd_ptr_dly = grey_rd_ptr;
+
+ // read pointer synchronizer
+ always @(posedge wr_clk or negedge wr_reset_n) begin
+ if (!wr_reset_n) begin
+ sync_rd_ptr_0 <= 0;
+ sync_rd_ptr_1 <= 0;
+ end
+ else begin
+ sync_rd_ptr_0 <= grey_rd_ptr_dly;
+ sync_rd_ptr_1 <= sync_rd_ptr_0;
+ end
+ end
+
+ assign sync_rd_ptr = grey2bin(sync_rd_ptr_1);
+
+ /************************ read side *****************************/
+ reg [AW:0] sync_wr_ptr_0, sync_wr_ptr_1;
+ wire [AW:0] sync_wr_ptr;
+ reg [AW:0] rd_ptr;
+ reg empty_q;
+ wire empty_c;
+ wire aempty_c;
+ wire [AW:0] rd_ptr_inc = rd_ptr + 1'b1;
+ wire [AW:0] sync_wr_ptr_dec = sync_wr_ptr - 1'b1;
+ wire [AW:0] rd_cnt = get_cnt(sync_wr_ptr, rd_ptr);
+
+ assign empty_c = (rd_cnt == 0) ? 1'b1 : 1'b0;
+ assign aempty_c = (rd_cnt == 1) ? 1'b1 : 1'b0;
+ //--------------------------
+ // Shows total number of words
+ // space available w.r.t write clock
+ //---------------------------
+ assign rd_total_aval = rd_cnt;
+
+ always @(posedge rd_clk or negedge rd_reset_n) begin
+ if (!rd_reset_n) begin
+ rd_ptr <= 0;
+ grey_rd_ptr <= 0;
+ empty_q <= 1'b1;
+ end
+ else begin
+ if (rd_en) begin
+ rd_ptr <= rd_ptr_inc;
+ grey_rd_ptr <= bin2grey(rd_ptr_inc);
+ if (rd_cnt==(EMPTY_DP+1)) begin
+ empty_q <= 1'b1;
+ end
+ end
+ else begin
+ if (empty_q && (rd_cnt!=EMPTY_DP)) begin
+ empty_q <= 1'b0;
+ end
+ end
+ end
+ end
+
+ assign empty = (RD_FAST == 1) ? empty_c : empty_q;
+ assign aempty = aempty_c;
+
+ assign rd_data = mem[rd_ptr[AW-1:0]];
+
+ wire [AW:0] grey_wr_ptr_dly ;
+ assign #1 grey_wr_ptr_dly = grey_wr_ptr;
+
+ // write pointer synchronizer
+ always @(posedge rd_clk or negedge rd_reset_n) begin
+ if (!rd_reset_n) begin
+ sync_wr_ptr_0 <= 0;
+ sync_wr_ptr_1 <= 0;
+ end
+ else begin
+ sync_wr_ptr_0 <= grey_wr_ptr_dly;
+ sync_wr_ptr_1 <= sync_wr_ptr_0;
+ end
+ end
+ assign sync_wr_ptr = grey2bin(sync_wr_ptr_1);
+
+
+/************************ functions ******************************/
+function [AW:0] bin2grey;
+input [AW:0] bin;
+reg [8:0] bin_8;
+reg [8:0] grey_8;
+begin
+ bin_8 = bin;
+ grey_8[1:0] = do_grey(bin_8[2:0]);
+ grey_8[3:2] = do_grey(bin_8[4:2]);
+ grey_8[5:4] = do_grey(bin_8[6:4]);
+ grey_8[7:6] = do_grey(bin_8[8:6]);
+ grey_8[8] = bin_8[8];
+ bin2grey = grey_8;
+end
+endfunction
+
+function [AW:0] grey2bin;
+input [AW:0] grey;
+reg [8:0] grey_8;
+reg [8:0] bin_8;
+begin
+ grey_8 = grey;
+ bin_8[8] = grey_8[8];
+ bin_8[7:6] = do_bin({bin_8[8], grey_8[7:6]});
+ bin_8[5:4] = do_bin({bin_8[6], grey_8[5:4]});
+ bin_8[3:2] = do_bin({bin_8[4], grey_8[3:2]});
+ bin_8[1:0] = do_bin({bin_8[2], grey_8[1:0]});
+ grey2bin = bin_8;
+end
+endfunction
+
+
+function [1:0] do_grey;
+input [2:0] bin;
+begin
+ if (bin[2]) begin // do reverse grey
+ case (bin[1:0])
+ 2'b00: do_grey = 2'b10;
+ 2'b01: do_grey = 2'b11;
+ 2'b10: do_grey = 2'b01;
+ 2'b11: do_grey = 2'b00;
+ endcase
+ end
+ else begin
+ case (bin[1:0])
+ 2'b00: do_grey = 2'b00;
+ 2'b01: do_grey = 2'b01;
+ 2'b10: do_grey = 2'b11;
+ 2'b11: do_grey = 2'b10;
+ endcase
+ end
+end
+endfunction
+
+function [1:0] do_bin;
+input [2:0] grey;
+begin
+ if (grey[2]) begin // actually bin[2]
+ case (grey[1:0])
+ 2'b10: do_bin = 2'b00;
+ 2'b11: do_bin = 2'b01;
+ 2'b01: do_bin = 2'b10;
+ 2'b00: do_bin = 2'b11;
+ endcase
+ end
+ else begin
+ case (grey[1:0])
+ 2'b00: do_bin = 2'b00;
+ 2'b01: do_bin = 2'b01;
+ 2'b11: do_bin = 2'b10;
+ 2'b10: do_bin = 2'b11;
+ endcase
+ end
+end
+endfunction
+
+function [AW:0] get_cnt;
+input [AW:0] wr_ptr, rd_ptr;
+begin
+ if (wr_ptr >= rd_ptr) begin
+ get_cnt = (wr_ptr - rd_ptr);
+ end
+ else begin
+ get_cnt = DP*2 - (rd_ptr - wr_ptr);
+ end
+end
+endfunction
+
+// synopsys translate_off
+always @(posedge wr_clk) begin
+ if (wr_en && full) begin
+ $display($time, "%m Error! afifo overflow!");
+ $stop;
+ end
+end
+
+always @(posedge rd_clk) begin
+ if (rd_en && empty) begin
+ $display($time, "%m error! afifo underflow!");
+ $stop;
+ end
+end
+
+// gray code monitor
+reg [AW:0] last_gwr_ptr;
+always @(posedge wr_clk or negedge wr_reset_n) begin
+ if (!wr_reset_n) begin
+ last_gwr_ptr <= #1 0;
+ end
+ else if (last_gwr_ptr !== grey_wr_ptr) begin
+ check_ptr_chg(last_gwr_ptr, grey_wr_ptr);
+ last_gwr_ptr <= #1 grey_wr_ptr;
+ end
+end
+
+reg [AW:0] last_grd_ptr;
+always @(posedge rd_clk or negedge rd_reset_n) begin
+ if (!rd_reset_n) begin
+ last_grd_ptr <= #1 0;
+ end
+ else if (last_grd_ptr !== grey_rd_ptr) begin
+ check_ptr_chg(last_grd_ptr, grey_rd_ptr);
+ last_grd_ptr <= #1 grey_rd_ptr;
+ end
+end
+
+task check_ptr_chg;
+input [AW:0] last_ptr;
+input [AW:0] cur_ptr;
+integer i;
+integer ptr_diff;
+begin
+ ptr_diff = 0;
+ for (i=0; i<= AW; i=i+ 1'b1) begin
+ if (last_ptr[i] != cur_ptr[i]) begin
+ ptr_diff = ptr_diff + 1'b1;
+ end
+ end
+ if (ptr_diff !== 1) begin
+ $display($time, "%m, ERROR! async fifo ptr has changed more than noe bit, last=%h, cur=%h",
+ last_ptr, cur_ptr);
+ $stop;
+ end
+end
+endtask
+ // synopsys translate_on
+
+endmodule
diff --git a/verilog/rtl/lib/async_reg_bus.sv b/verilog/rtl/lib/async_reg_bus.sv
new file mode 100644
index 0000000..2c02701
--- /dev/null
+++ b/verilog/rtl/lib/async_reg_bus.sv
@@ -0,0 +1,305 @@
+
+
+//----------------------------------------------------------------------------------------------
+// This block translate the Reg Bus transaction from in_clk clock domain to out_clk clock domain.
+// This block also generate and terminate the transfer if 512 cycle transaction is not completed
+// Assumption
+// 1. in_reg_cs will be asserted untill ack is received
+// 2. reg_addr/reg_wdata/reg_be will be available during reg_cs
+// 3. Ever after out_reg_ack de-asserted reg_rdata holds the old data
+//----------------------------------------------------------------------------------------------
+
+module async_reg_bus (
+ // Initiator declartion
+ in_clk ,
+ in_reset_n ,
+ // Reg Bus Master
+ // outputs
+ in_reg_rdata ,
+ in_reg_ack ,
+ in_reg_timeout ,
+
+ // Inputs
+ in_reg_cs ,
+ in_reg_addr ,
+ in_reg_wdata ,
+ in_reg_wr ,
+ in_reg_be ,
+
+ // Target Declaration
+ out_clk ,
+ out_reset_n ,
+ // Reg Bus Slave
+ // output
+ out_reg_cs ,
+ out_reg_addr ,
+ out_reg_wdata ,
+ out_reg_wr ,
+ out_reg_be ,
+
+ // Inputs
+ out_reg_rdata ,
+ out_reg_ack
+ );
+parameter AW = 26 ; // Address width
+parameter DW = 32 ; // DATA WIDTH
+parameter BEW = 4 ; // Byte enable width
+
+//----------------------------------------
+// Reg Bus reg inout declration
+//----------------------------------------
+input in_clk ; // Initiator domain clock
+input in_reset_n ; // Initiator domain reset
+
+input in_reg_cs ; // Initiator Chip Select
+input [AW-1:0] in_reg_addr ; // Address bus
+input [DW-1:0] in_reg_wdata ; // Write data
+input in_reg_wr ; // Read/write indication, 1-> write
+input [BEW-1:0] in_reg_be ; // Byte valid for write
+
+output [DW-1:0] in_reg_rdata ; // Read Data
+output in_reg_ack ; // Reg Access done
+output in_reg_timeout ; // Access error indication pulse
+ // Genererated if no target ack
+ // received
+ // within 512 cycle
+
+//---------------------------------------------
+// Reg Bus target inout declration
+//---------------------------------------------
+
+input out_clk ; // Target domain clock
+input out_reset_n ; // Traget domain reset
+
+input [DW-1:0] out_reg_rdata ; // Read data
+input out_reg_ack ; // target finish
+
+output out_reg_cs ; // Target Start indication
+output [AW-1:0] out_reg_addr ; // Target address
+output [DW-1:0] out_reg_wdata ; // Target write data
+output out_reg_wr ; // Target Read/write ind, 1-> Write
+output [BEW-1:0] out_reg_be ; // Target Byte enable
+
+//-----------------------------------
+// Initiator Local Declaration
+// ----------------------------------
+parameter INI_IDLE = 2'b00;
+parameter INI_WAIT_ACK = 2'b01;
+parameter INI_WAIT_TAR_DONE = 2'b10;
+
+reg [1:0] in_state ; // reg state
+reg [8:0] in_timer ; // reg timout monitor timer
+reg in_flag ; // reg handshake flag
+reg in_reg_ack ; // reg reg access finish ind
+reg [DW-1:0] in_reg_rdata ; // reg reg access read data
+reg in_reg_timeout ; // reg time out error pulse
+
+//-----------------------------------
+// Target Local Declaration
+// ----------------------------------
+parameter TAR_IDLE = 2'b00;
+parameter TAR_WAIT_ACK = 2'b01;
+parameter TAR_WAIT_INI_DONE = 2'b10;
+
+reg [1:0] out_state ; // target state machine
+reg out_flag ; // target handshake flag
+reg out_reg_cs ; // Target Start indication
+
+reg [8:0] inititaor_timer ; // timeout counter
+//-----------------------------------------------
+// Double sync local declaration
+// ----------------------------------------------
+
+reg in_flag_s ; // Initiator handshake flag sync
+ // with target clk
+reg in_flag_ss ; // Initiator handshake flag sync
+ // with target clk
+
+reg out_flag_s ; // target handshake flag sync
+ // with initiator clk
+reg out_flag_ss ; // target handshake flag sync
+ // with initiator clck
+
+
+
+
+assign out_reg_addr = in_reg_addr;
+assign out_reg_wdata = in_reg_wdata;
+assign out_reg_wr = in_reg_wr;
+assign out_reg_be = in_reg_be;
+//------------------------------------------------------
+// Initiator Domain logic
+//------------------------------------------------------
+
+always @(negedge in_reset_n or posedge in_clk)
+begin
+ if(in_reset_n == 1'b0)
+ begin
+ in_state <= INI_IDLE;
+ in_timer <= 9'h0;
+ in_flag <= 1'b0;
+ in_reg_ack <= 1'b0;
+ in_reg_rdata <= {DW {1'b0}};
+ in_reg_timeout<= 1'b0;
+ end
+ else
+ begin
+ case(in_state)
+ INI_IDLE :
+ begin
+ in_reg_ack <= 1'b0;
+ in_reg_timeout <= 1'b0;
+ in_timer <= 'h0;
+ // Wait for Initiator Start Indication
+ // Once the reg start is detected
+ // Set the reg flag and move to WAIT
+ // for ack from Target
+ if(in_reg_cs) begin
+ in_flag <= 1'b1;
+ in_state <= INI_WAIT_ACK;
+ end
+ end
+ INI_WAIT_ACK :
+ begin
+ //--------------------------------------------
+ // 1. Wait for Out Flag == 1
+ // 2. If the Out Flag =1 is not
+ // detected witin 512 cycle, exit with error indication
+ // 3. If Target flag detected, then de-assert
+ // reg_flag = 0 and move the tar_wait_done state
+ // ---------------------------------------------
+ if(out_flag_ss == 1'b1) begin
+ in_flag <= 1'b0;
+ in_reg_rdata <= out_reg_rdata;
+ in_reg_ack <= 1'b1;
+ in_state <= INI_WAIT_TAR_DONE;
+ end
+ else begin
+ if(in_timer == 9'h1FF) begin
+ in_flag <= 1'b0;
+ in_reg_ack <= 1'b1;
+ in_reg_rdata <= 32'h0;
+ in_reg_timeout <= 1'b1;
+ in_state <= INI_IDLE;
+ end
+ else begin
+ in_timer <= in_timer + 1;
+ end
+ end
+ end
+ INI_WAIT_TAR_DONE :
+ begin
+ in_reg_ack <= 1'b0;
+ //--------------------------------------------
+ // 1. Wait for Target Flag == 0
+ // 2. If Target flag = 0 detected, then remove
+ // move the idle state
+ // ---------------------------------------------
+ if(out_flag_ss == 1'b0) begin
+ in_state <= INI_IDLE;
+ end
+ end
+ default:
+ begin
+ in_state <= INI_IDLE;
+ in_timer <= 9'h0;
+ in_flag <= 1'b0;
+ in_reg_rdata <= {DW {1'b0}};
+ in_reg_timeout <= 1'b0;
+ end
+ endcase
+ end
+end
+
+
+//------------------------------------------------------
+// target Domain logic
+//------------------------------------------------------
+always @(negedge out_reset_n or posedge out_clk)
+begin
+ if(out_reset_n == 1'b0)
+ begin
+ out_state <= TAR_IDLE;
+ out_flag <= 1'b0;
+ out_reg_cs <= 1'b0;
+ end
+ else
+ begin
+ case(out_state)
+ TAR_IDLE :
+ begin
+ // 1. Wait for Initiator flag assertion
+ // 2. Once the reg flag = 1 is detected
+ // Set the target_flag and initiate the
+ // target reg bus access
+ out_flag <= 1'b0;
+ if(in_flag_ss) begin
+ out_reg_cs <= 1'b1;
+ out_state <= TAR_WAIT_ACK;
+ end
+ end
+ TAR_WAIT_ACK :
+ begin
+ //--------------------------------------------
+ // 1. Wait for reg Flag == 0
+ // 2. If reg flag = 0 detected, then
+ // move the idle state
+ // ---------------------------------------------
+ if(out_reg_ack == 1'b1)
+ begin
+ out_reg_cs <= 1'b0;
+ out_flag <= 1'b1;
+ out_state <= TAR_WAIT_INI_DONE;
+ end
+ end
+ TAR_WAIT_INI_DONE :
+ begin
+ if(in_flag_ss == 1'b0) begin
+ out_flag <= 1'b0;
+ out_state <= TAR_IDLE;
+ end
+ end
+ default:
+ begin
+ out_state <= TAR_IDLE;
+ out_reg_cs <= 1'b0;
+ out_flag <= 1'b0;
+ end
+ endcase
+ end
+end
+
+//-------------------------------------------------------
+// Double Sync Logic
+// ------------------------------------------------------
+always @(negedge in_reset_n or posedge in_clk)
+begin
+ if(in_reset_n == 1'b0)
+ begin
+ out_flag_s <= 1'b0;
+ out_flag_ss <= 1'b0;
+ end
+ else
+ begin
+ out_flag_s <= out_flag;
+ out_flag_ss <= out_flag_s;
+ end
+end
+
+
+always @(negedge out_reset_n or posedge out_clk)
+begin
+ if(out_reset_n == 1'b0)
+ begin
+ in_flag_s <= 1'b0;
+ in_flag_ss <= 1'b0;
+ end
+ else
+ begin
+ in_flag_s <= in_flag;
+ in_flag_ss <= in_flag_s;
+ end
+end
+
+
+endmodule
diff --git a/verilog/rtl/lib/async_wb.sv b/verilog/rtl/lib/async_wb.sv
new file mode 100644
index 0000000..4e5d4a6
--- /dev/null
+++ b/verilog/rtl/lib/async_wb.sv
@@ -0,0 +1,234 @@
+//////////////////////////////////////////////////////////////////////////////
+// SPDX-FileCopyrightText: 2021 , Dinesh Annayya
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+// SPDX-License-Identifier: Apache-2.0
+// SPDX-FileContributor: Created by Dinesh Annayya <dinesha@opencores.org>
+//
+//////////////////////////////////////////////////////////////////////
+//// ////
+//// Async Wishbone Interface ////
+//// ////
+//// This file is part of the YIFive cores project ////
+//// http://www.opencores.org/cores/yifive/ ////
+//// ////
+//// Description ////
+//// This block does async Wishbone from one clock to other ////
+//// clock domain
+//// ////
+//// To Do: ////
+//// nothing ////
+//// ////
+//// Author(s): ////
+//// - Dinesh Annayya, dinesha@opencores.org ////
+//// ////
+//// Revision : ////
+//// 0.1 - 25th Feb 2021, Dinesh A ////
+//// initial version ////
+//// 0.2 - 28th Feb 2021, Dinesh A ////
+//// reduced the response FIFO path depth to 2 as ////
+//// return path used by only read logic and read is ////
+//// blocking request and expect only one location will ////
+//// be used ////
+//////////////////////////////////////////////////////////////////////
+//// ////
+//// Copyright (C) 2000 Authors and OPENCORES.ORG ////
+//// ////
+//// This source file may be used and distributed without ////
+//// restriction provided that this copyright statement is not ////
+//// removed from the file and that any derivative work contains ////
+//// the original copyright notice and the associated disclaimer. ////
+//// ////
+//// This source file is free software; you can redistribute it ////
+//// and/or modify it under the terms of the GNU Lesser General ////
+//// Public License as published by the Free Software Foundation; ////
+//// either version 2.1 of the License, or (at your option) any ////
+//// later version. ////
+//// ////
+//// This source is distributed in the hope that it will be ////
+//// useful, but WITHOUT ANY WARRANTY; without even the implied ////
+//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR ////
+//// PURPOSE. See the GNU Lesser General Public License for more ////
+//// details. ////
+//// ////
+//// You should have received a copy of the GNU Lesser General ////
+//// Public License along with this source; if not, download it ////
+//// from http://www.opencores.org/lgpl.shtml ////
+//// ////
+//////////////////////////////////////////////////////////////////////
+
+module async_wb
+ #(parameter AW = 32,
+ parameter BW = 4,
+ parameter DW = 32)
+ (
+
+ // Master Port
+ input logic wbm_rst_n , // Regular Reset signal
+ input logic wbm_clk_i , // System clock
+ input logic wbm_cyc_i , // strobe/request
+ input logic wbm_stb_i , // strobe/request
+ input logic [AW-1:0] wbm_adr_i , // address
+ input logic wbm_we_i , // write
+ input logic [DW-1:0] wbm_dat_i , // data output
+ input logic [BW-1:0] wbm_sel_i , // byte enable
+ output logic [DW-1:0] wbm_dat_o , // data input
+ output logic wbm_ack_o , // acknowlegement
+ output logic wbm_err_o , // error
+
+ // Slave Port
+ input logic wbs_rst_n , // Regular Reset signal
+ input logic wbs_clk_i , // System clock
+ output logic wbs_cyc_o , // strobe/request
+ output logic wbs_stb_o , // strobe/request
+ output logic [AW-1:0] wbs_adr_o , // address
+ output logic wbs_we_o , // write
+ output logic [DW-1:0] wbs_dat_o , // data output
+ output logic [BW-1:0] wbs_sel_o , // byte enable
+ input logic [DW-1:0] wbs_dat_i , // data input
+ input logic wbs_ack_i , // acknowlegement
+ input logic wbs_err_i // error
+
+ );
+
+
+
+parameter CFW = AW+DW+BW+1 ; // COMMAND FIFO WIDTH
+
+//-------------------------------------------------
+// Master Interface
+// -------------------------------------------------
+logic PendingRd ; // Pending Read Transaction
+logic m_cmd_wr_en ;
+logic [CFW-1:0] m_cmd_wr_data ;
+logic m_cmd_wr_full ;
+logic m_cmd_wr_afull ;
+
+logic m_resp_rd_empty ;
+logic m_resp_rd_aempty ;
+logic m_resp_rd_en ;
+logic [DW:0] m_resp_rd_data ;
+
+// Master Write Interface
+
+
+assign m_cmd_wr_en = (!PendingRd) && wbm_stb_i && !m_cmd_wr_full && !m_cmd_wr_afull;
+
+assign m_cmd_wr_data = {wbm_adr_i,wbm_we_i,wbm_dat_i,wbm_sel_i};
+
+always@(negedge wbm_rst_n or posedge wbm_clk_i)
+begin
+ if(wbm_rst_n == 0) begin
+ PendingRd <= 1'b0;
+ end else begin
+ if((!PendingRd) && wbm_stb_i && (!wbm_we_i) && m_cmd_wr_en) begin
+ PendingRd <= 1'b1;
+ end else if(PendingRd && wbm_stb_i && (!wbm_we_i) && wbm_ack_o) begin
+ PendingRd <= 1'b0;
+ end
+ end
+end
+
+
+// Master Read Interface
+// For Write is feed through, if there is space in fifo the ack
+// For Read, Wait for Response Path FIFO status
+assign wbm_ack_o = (wbm_stb_i && wbm_we_i) ? m_cmd_wr_en : // Write Logic
+ (wbm_stb_i && (!wbm_we_i)) ? !m_resp_rd_empty : 1'b0; // Read Logic
+
+assign m_resp_rd_en = !m_resp_rd_empty;
+assign wbm_dat_o = m_resp_rd_data[DW-1:0];
+assign wbm_err_o = m_resp_rd_data[DW];
+
+
+//------------------------------
+// Slave Interface
+//-------------------------------
+
+logic [CFW-1:0] s_cmd_rd_data ;
+logic s_cmd_rd_empty ;
+logic s_cmd_rd_aempty ;
+logic s_cmd_rd_en ;
+logic s_resp_wr_en ;
+logic [DW:0] s_resp_wr_data ;
+logic s_resp_wr_full ;
+logic s_resp_wr_afull ;
+logic wbs_ack_f ;
+
+
+always@(negedge wbs_rst_n or posedge wbs_clk_i)
+begin
+ if(wbs_rst_n == 0) begin
+ wbs_ack_f <= 1'b0;
+ end else begin
+ wbs_ack_f <= wbs_ack_i;
+ end
+end
+
+
+// Read Interface
+assign {wbs_adr_o,wbs_we_o,wbs_dat_o,wbs_sel_o} = (s_cmd_rd_empty) ? '0: s_cmd_rd_data;
+// All the downstream logic expect Stobe is getting de-asserted
+// atleast for 1 cycle after ack is generated
+assign wbs_stb_o = (wbs_ack_f) ? 1'b0 : (s_cmd_rd_empty) ? 1'b0: 1'b1;
+assign wbs_cyc_o = (wbs_ack_f) ? 1'b0 : (s_cmd_rd_empty) ? 1'b0: 1'b1;
+
+assign s_cmd_rd_en = wbs_ack_i;
+
+// Write Interface
+// response send only for read logic
+assign s_resp_wr_en = wbs_stb_o & (!wbs_we_o) & wbs_ack_i & !s_resp_wr_full;
+assign s_resp_wr_data = {wbs_err_i,wbs_dat_i};
+
+async_fifo #(.W(CFW), .DP(4), .WR_FAST(1), .RD_FAST(1)) u_cmd_if (
+ // Sync w.r.t WR clock
+ .wr_clk (wbm_clk_i ),
+ .wr_reset_n (wbm_rst_n ),
+ .wr_en (m_cmd_wr_en ),
+ .wr_data (m_cmd_wr_data ),
+ .full (m_cmd_wr_full ),
+ .afull (m_cmd_wr_afull ),
+
+ // Sync w.r.t RD Clock
+ .rd_clk (wbs_clk_i ),
+ .rd_reset_n (wbs_rst_n ),
+ .rd_en (s_cmd_rd_en ),
+ .empty (s_cmd_rd_empty ), // sync'ed to rd_clk
+ .aempty (s_cmd_rd_aempty ), // sync'ed to rd_clk
+ .rd_data (s_cmd_rd_data )
+ );
+
+
+// Response used only read path, read is blocking access, expect
+// only one location used in return path - reduced the depth to 2
+async_fifo #(.W(DW+1), .DP(2), .WR_FAST(1), .RD_FAST(1)) u_resp_if (
+ // Sync w.r.t WR clock
+ .wr_clk (wbs_clk_i ),
+ .wr_reset_n (wbs_rst_n ),
+ .wr_en (s_resp_wr_en ),
+ .wr_data (s_resp_wr_data ),
+ .full (s_resp_wr_full ),
+ .afull (s_resp_wr_afull ),
+
+ // Sync w.r.t RD Clock
+ .rd_clk (wbm_clk_i ),
+ .rd_reset_n (wbm_rst_n ),
+ .rd_en (m_resp_rd_en ),
+ .empty (m_resp_rd_empty ), // sync'ed to rd_clk
+ .aempty (m_resp_rd_aempty ), // sync'ed to rd_clk
+ .rd_data (m_resp_rd_data )
+ );
+
+
+
+endmodule
diff --git a/verilog/rtl/lib/clk_buf.v b/verilog/rtl/lib/clk_buf.v
new file mode 100644
index 0000000..dad8fc6
--- /dev/null
+++ b/verilog/rtl/lib/clk_buf.v
@@ -0,0 +1,85 @@
+//////////////////////////////////////////////////////////////////////////////
+// SPDX-FileCopyrightText: 2021 , Dinesh Annayya
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+// SPDX-License-Identifier: Apache-2.0
+// SPDX-FileContributor: Created by Dinesh Annayya <dinesha@opencores.org>
+//
+//////////////////////////////////////////////////////////////////////
+//// ////
+//// Clk Buf ////
+//// ////
+//// This file is part of the YIFive cores project ////
+//// https://github.com/dineshannayya/yifive_r0.git ////
+//// http://www.opencores.org/cores/yifive/ ////
+//// ////
+//// Description ////
+//// Adding clock buf for manual clock tree at SOC level ////
+//// To Do: ////
+//// nothing ////
+//// ////
+//// Author(s): ////
+//// - Dinesh Annayya, dinesha@opencores.org ////
+//// ////
+//// Revision : ////
+//////////////////////////////////////////////////////////////////////
+//// ////
+//// Copyright (C) 2000 Authors and OPENCORES.ORG ////
+//// ////
+//// This source file may be used and distributed without ////
+//// restriction provided that this copyright statement is not ////
+//// removed from the file and that any derivative work contains ////
+//// the original copyright notice and the associated disclaimer. ////
+//// ////
+//// This source file is free software; you can redistribute it ////
+//// and/or modify it under the terms of the GNU Lesser General ////
+//// Public License as published by the Free Software Foundation; ////
+//// either version 2.1 of the License, or (at your option) any ////
+//// later version. ////
+//// ////
+//// This source is distributed in the hope that it will be ////
+//// useful, but WITHOUT ANY WARRANTY; without even the implied ////
+//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR ////
+//// PURPOSE. See the GNU Lesser General Public License for more ////
+//// details. ////
+//// ////
+//// You should have received a copy of the GNU Lesser General ////
+//// Public License along with this source; if not, download it ////
+//// from http://www.opencores.org/lgpl.shtml ////
+//// ////
+//////////////////////////////////////////////////////////////////////
+
+
+module clk_buf (
+ // Outputs
+ clk_o,
+ // Inputs
+ clk_i
+ );
+
+//---------------------------------------------
+// All the input to this block are declared here
+// --------------------------------------------
+ input clk_i ;//
+
+//---------------------------------------------
+// All the output to this block are declared here
+// --------------------------------------------
+ output clk_o ; // clock out
+
+
+
+sky130_fd_sc_hd__clkbuf_16 u_buf (.A(clk_i),.X(clk_o));
+
+endmodule
+
diff --git a/verilog/rtl/lib/clk_ctl.v b/verilog/rtl/lib/clk_ctl.v
new file mode 100644
index 0000000..7e4478b
--- /dev/null
+++ b/verilog/rtl/lib/clk_ctl.v
@@ -0,0 +1,147 @@
+//////////////////////////////////////////////////////////////////////////////
+// SPDX-FileCopyrightText: 2021 , Dinesh Annayya
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+// SPDX-License-Identifier: Apache-2.0
+// SPDX-FileContributor: Created by Dinesh Annayya <dinesha@opencores.org>
+////////////////////////////////////////////////////////////////////////
+//// ////
+//// Tubo 8051 cores common library Module ////
+//// ////
+//// This file is part of the Turbo 8051 cores project ////
+//// https://github.com/dineshannayya/yifive_r0.git ////
+//// http://www.opencores.org/cores/turbo8051/ ////
+//// ////
+//// Description ////
+//// Turbo 8051 definitions. ////
+//// ////
+//// To Do: ////
+//// nothing ////
+//// ////
+//// Author(s): ////
+//// - Dinesh Annayya, dinesha@opencores.org ////
+//// ////
+//// Revision : ////
+//// 1.0 Mar 2, 2011,Dinesh.A ////
+//// Initial Version ////
+//// 1.1 Nov 15,2021,Dinesh A ////
+//// Bug fix in High and Low count width ////
+//// ////
+//////////////////////////////////////////////////////////////////////
+//// ////
+//// Copyright (C) 2000 Authors and OPENCORES.ORG ////
+//// ////
+//// This source file may be used and distributed without ////
+//// restriction provided that this copyright statement is not ////
+//// removed from the file and that any derivative work contains ////
+//// the original copyright notice and the associated disclaimer. ////
+//// ////
+//// This source file is free software; you can redistribute it ////
+//// and/or modify it under the terms of the GNU Lesser General ////
+//// Public License as published by the Free Software Foundation; ////
+//// either version 2.1 of the License, or (at your option) any ////
+//// later version. ////
+//// ////
+//// This source is distributed in the hope that it will be ////
+//// useful, but WITHOUT ANY WARRANTY; without even the implied ////
+//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR ////
+//// PURPOSE. See the GNU Lesser General Public License for more ////
+//// details. ////
+//// ////
+//// You should have received a copy of the GNU Lesser General ////
+//// Public License along with this source; if not, download it ////
+//// from http://www.opencores.org/lgpl.shtml ////
+//// ////
+//////////////////////////////////////////////////////////////////////
+
+// #################################################################
+// Module: clk_ctl
+//
+// Description: Generic clock control logic , clk-out = mclk/(2+clk_div_ratio)
+//
+//
+// #################################################################
+
+
+module clk_ctl (
+ // Outputs
+ clk_o,
+ // Inputs
+ mclk,
+ reset_n,
+ clk_div_ratio
+ );
+
+//---------------------------------
+// CLOCK Default Divider value.
+// This value will be change from outside
+//---------------------------------
+parameter WD = 'h1;
+
+//---------------------------------------------
+// All the input to this block are declared here
+// --------------------------------------------
+ input mclk ;//
+ input reset_n ;// primary reset signal
+ input [WD:0] clk_div_ratio ;// primary clock divide ratio
+ // output clock = selected clock / (div_ratio+1)
+
+//---------------------------------------------
+// All the output to this block are declared here
+// --------------------------------------------
+ output clk_o ; // clock out
+
+
+
+//------------------------------------
+// Clock Divide func is done here
+//------------------------------------
+reg [WD:0] high_count ; // high level counter
+reg [WD:0] low_count ; // low level counter
+reg mclk_div ; // divided clock
+
+
+assign clk_o = mclk_div;
+
+always @ (posedge mclk or negedge reset_n)
+begin // {
+ if(reset_n == 1'b0)
+ begin
+ high_count <= 'h0;
+ low_count <= 'h0;
+ mclk_div <= 'b0;
+ end
+ else
+ begin
+ if(high_count != 0)
+ begin // {
+ high_count <= high_count - 1;
+ mclk_div <= 1'b1;
+ end // }
+ else if(low_count != 0)
+ begin // {
+ low_count <= low_count - 1;
+ mclk_div <= 1'b0;
+ end // }
+ else
+ begin // {
+ high_count <= clk_div_ratio[WD:1] + clk_div_ratio[0];
+ low_count <= clk_div_ratio[WD:1] + 1;
+ mclk_div <= ~mclk_div;
+ end // }
+ end // }
+end // }
+
+
+endmodule
+
diff --git a/verilog/rtl/lib/clk_skew_adjust.gv b/verilog/rtl/lib/clk_skew_adjust.gv
new file mode 100644
index 0000000..fc811c0
--- /dev/null
+++ b/verilog/rtl/lib/clk_skew_adjust.gv
@@ -0,0 +1,205 @@
+//////////////////////////////////////////////////////////////////////////////
+// SPDX-FileCopyrightText: 2021 , Dinesh Annayya
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+// SPDX-License-Identifier: Apache-2.0
+// SPDX-FileContributor: Created by Dinesh Annayya <dinesha@opencores.org>
+//
+//////////////////////////////////////////////////////////////////////
+//// ////
+//// clock skew adjust ////
+//// ////
+//// This file is part of the YIFive cores project ////
+//// https://github.com/dineshannayya/yifive_r0.git ////
+//// http://www.opencores.org/cores/yifive/ ////
+//// ////
+//// Description ////
+//// This block is useful for global clock skew adjustment ////
+//// logic implementation: ////
+//// clk_out = (sel=0) ? clk_in : ////
+//// (sel=1) ? clk_d1 : ////
+//// (sel=1) ? clk_d2 : ////
+//// ..... ////
+//// (sel=15)? clk_d15 :clk_in ////
+//// ////
+//// Note: each d* indicate clk buf delay ////
+//// ////
+//// ////
+//// To Do: ////
+//// nothing ////
+//// ////
+//// Author(s): ////
+//// - Dinesh Annayya, dinesha@opencores.org ////
+//// ////
+//// Revision : ////
+//// 0.0 - 29th Feb 2021, Dinesh A ////
+//// Initial version ////
+///
+//// ////
+//////////////////////////////////////////////////////////////////////
+//// ////
+//// Copyright (C) 2000 Authors and OPENCORES.ORG ////
+//// ////
+//// This source file may be used and distributed without ////
+//// restriction provided that this copyright statement is not ////
+//// removed from the file and that any derivative work contains ////
+//// the original copyright notice and the associated disclaimer. ////
+//// ////
+//// This source file is free software; you can redistribute it ////
+//// and/or modify it under the terms of the GNU Lesser General ////
+//// Public License as published by the Free Software Foundation; ////
+//// either version 2.1 of the License, or (at your option) any ////
+//// later version. ////
+//// ////
+//// This source is distributed in the hope that it will be ////
+//// useful, but WITHOUT ANY WARRANTY; without even the implied ////
+//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR ////
+//// PURPOSE. See the GNU Lesser General Public License for more ////
+//// details. ////
+//// ////
+//// You should have received a copy of the GNU Lesser General ////
+//// Public License along with this source; if not, download it ////
+//// from http://www.opencores.org/lgpl.shtml ////
+//// ////
+//////////////////////////////////////////////////////////////////////
+// Clock-in is east pad direction
+// clock out give in other three direction for better placement
+/////////////////////////////////////////////////////////////////////
+module clk_skew_adjust(
+`ifdef USE_POWER_PINS
+ vccd1,// User area 1 1.8V supply
+ vssd1,// User area 1 digital ground
+`endif
+clk_in, sel, clk_out);
+
+
+`ifdef USE_POWER_PINS
+ input vccd1;// User area 1 1.8V supply
+ input vssd1;// User area 1 digital ground
+`endif
+ input clk_in;
+ output clk_out;
+ input [3:0] sel;
+ wire in0;
+ wire in1;
+ wire in2;
+ wire in3;
+ wire in4;
+ wire in5;
+ wire in6;
+ wire in7;
+ wire in8;
+ wire in9;
+ wire in10;
+ wire in11;
+ wire in12;
+ wire in13;
+ wire in14;
+ wire in15;
+
+ wire clk_d1;
+ wire clk_d2;
+ wire clk_d3;
+ wire clk_d4;
+ wire clk_d5;
+ wire clk_d6;
+ wire clk_d7;
+ wire clk_d8;
+ wire clk_d9;
+ wire clk_d10;
+ wire clk_d11;
+ wire clk_d12;
+ wire clk_d13;
+ wire clk_d14;
+ wire clk_d15;
+
+ wire d00;
+ wire d01;
+ wire d02;
+ wire d03;
+ wire d04;
+ wire d05;
+ wire d06;
+ wire d07;
+ wire d10;
+ wire d11;
+ wire d12;
+ wire d13;
+ wire d20;
+ wire d21;
+ wire d30;
+
+
+ ctech_delay_clkbuf clkbuf_1 (.A(clk_in), .X(clk_d1));
+ ctech_delay_clkbuf clkbuf_2 (.A(clk_d1), .X(clk_d2));
+ ctech_delay_clkbuf clkbuf_3 (.A(clk_d2), .X(clk_d3));
+ ctech_delay_clkbuf clkbuf_4 (.A(clk_d3), .X(clk_d4));
+ ctech_delay_clkbuf clkbuf_5 (.A(clk_d4), .X(clk_d5));
+ ctech_delay_clkbuf clkbuf_6 (.A(clk_d5), .X(clk_d6));
+ ctech_delay_clkbuf clkbuf_7 (.A(clk_d6), .X(clk_d7));
+ ctech_delay_clkbuf clkbuf_8 (.A(clk_d7), .X(clk_d8));
+ ctech_delay_clkbuf clkbuf_9 (.A(clk_d8), .X(clk_d9));
+ ctech_delay_clkbuf clkbuf_10 (.A(clk_d9), .X(clk_d10));
+ ctech_delay_clkbuf clkbuf_11 (.A(clk_d10), .X(clk_d11));
+ ctech_delay_clkbuf clkbuf_12 (.A(clk_d11), .X(clk_d12));
+ ctech_delay_clkbuf clkbuf_13 (.A(clk_d12), .X(clk_d13));
+ ctech_delay_clkbuf clkbuf_14 (.A(clk_d13), .X(clk_d14));
+ ctech_delay_clkbuf clkbuf_15 (.A(clk_d14), .X(clk_d15));
+
+
+ // Tap point selection
+ assign in0 = clk_in;
+ assign in1 = clk_d1;
+ assign in2 = clk_d2;
+ assign in3 = clk_d3;
+ assign in4 = clk_d4;
+ assign in5 = clk_d5;
+ assign in6 = clk_d6;
+ assign in7 = clk_d7;
+ assign in8 = clk_d8;
+ assign in9 = clk_d9;
+ assign in10 = clk_d10;
+ assign in11 = clk_d11;
+ assign in12 = clk_d12;
+ assign in13 = clk_d13;
+ assign in14 = clk_d14;
+ assign in15 = clk_d15;
+
+
+ // first level mux - 8
+ ctech_mux2x1_2 u_mux_level_00 ( .X (d00) , .A0 (in0), .A1(in1), .S(sel[0]));
+ ctech_mux2x1_2 u_mux_level_01 ( .X (d01) , .A0 (in2), .A1(in3), .S(sel[0]));
+ ctech_mux2x1_2 u_mux_level_02 ( .X (d02) , .A0 (in4), .A1(in5), .S(sel[0]));
+ ctech_mux2x1_2 u_mux_level_03 ( .X (d03) , .A0 (in6), .A1(in7), .S(sel[0]));
+ ctech_mux2x1_2 u_mux_level_04 ( .X (d04) , .A0 (in8), .A1(in9), .S(sel[0]));
+ ctech_mux2x1_2 u_mux_level_05 ( .X (d05) , .A0 (in10), .A1(in11), .S(sel[0]));
+ ctech_mux2x1_2 u_mux_level_06 ( .X (d06) , .A0 (in12), .A1(in13), .S(sel[0]));
+ ctech_mux2x1_2 u_mux_level_07 ( .X (d07) , .A0 (in14), .A1(in15), .S(sel[0]));
+
+ // second level mux - 4
+ ctech_mux2x1_2 u_mux_level_10 ( .X (d10) , .A0 (d00), .A1(d01), .S(sel[1]));
+ ctech_mux2x1_2 u_mux_level_11 ( .X (d11) , .A0 (d02), .A1(d03), .S(sel[1]));
+ ctech_mux2x1_2 u_mux_level_12 ( .X (d12) , .A0 (d04), .A1(d05), .S(sel[1]));
+ ctech_mux2x1_2 u_mux_level_13 ( .X (d13) , .A0 (d06), .A1(d07), .S(sel[1]));
+
+ // third level mux - 2
+ ctech_mux2x1_2 u_mux_level_20 ( .X (d20) , .A0 (d10), .A1(d11), .S(sel[2]));
+ ctech_mux2x1_2 u_mux_level_21 ( .X (d21) , .A0 (d12), .A1(d13), .S(sel[2]));
+
+ // fourth level mux - 1
+ ctech_mux2x1_4 u_mux_level_30 ( .X (d30) , .A0 (d20), .A1(d21), .S(sel[3]));
+
+
+ assign clk_out = d30;
+
+endmodule
diff --git a/verilog/rtl/lib/ctech_cells.sv b/verilog/rtl/lib/ctech_cells.sv
new file mode 100644
index 0000000..c9528de
--- /dev/null
+++ b/verilog/rtl/lib/ctech_cells.sv
@@ -0,0 +1,90 @@
+
+module ctech_mux2x1 (
+ input logic A0,
+ input logic A1,
+ input logic S ,
+ output logic X);
+
+`ifndef SYNTHESIS
+assign X = (S) ? A1 : A0;
+`else
+sky130_fd_sc_hd__mux2_8 u_mux (.A0 (A0), .A1 (A1), .S (S), .X (X));
+`endif
+
+endmodule
+
+module ctech_mux2x1_2 (
+ input logic A0,
+ input logic A1,
+ input logic S ,
+ output logic X);
+
+`ifndef SYNTHESIS
+assign X = (S) ? A1 : A0;
+`else
+sky130_fd_sc_hd__mux2_2 u_mux (.A0 (A0), .A1 (A1), .S (S), .X (X));
+`endif
+
+endmodule
+
+module ctech_mux2x1_4 (
+ input logic A0,
+ input logic A1,
+ input logic S ,
+ output logic X);
+
+`ifndef SYNTHESIS
+assign X = (S) ? A1 : A0;
+`else
+sky130_fd_sc_hd__mux2_4 u_mux (.A0 (A0), .A1 (A1), .S (S), .X (X));
+`endif
+
+endmodule
+
+module ctech_buf (
+ input logic A,
+ output logic X);
+
+`ifndef SYNTHESIS
+assign X = A;
+`else
+ sky130_fd_sc_hd__bufbuf_8 u_buf (.A(A),.X(X));
+`endif
+
+endmodule
+
+module ctech_clk_buf (
+ input logic A,
+ output logic X);
+
+`ifndef SYNTHESIS
+assign X = A;
+`else
+ sky130_fd_sc_hd__clkbuf_8 u_buf (.A(A),.X(X));
+`endif
+
+endmodule
+
+module ctech_delay_buf (
+ input logic A,
+ output logic X);
+
+`ifndef SYNTHESIS
+ assign X = A;
+`else
+ sky130_fd_sc_hd__dlygate4sd3_1 u_dly (.X(X),.A(A));
+`endif
+
+endmodule
+
+module ctech_delay_clkbuf (
+ input logic A,
+ output logic X);
+
+`ifndef SYNTHESIS
+ assign X = A;
+`else
+ sky130_fd_sc_hd__clkdlybuf4s15_2 u_dly (.X(X),.A(A));
+`endif
+
+endmodule
diff --git a/verilog/rtl/lib/double_sync_high.v b/verilog/rtl/lib/double_sync_high.v
new file mode 100755
index 0000000..d1d2ca6
--- /dev/null
+++ b/verilog/rtl/lib/double_sync_high.v
@@ -0,0 +1,106 @@
+//////////////////////////////////////////////////////////////////////////////
+// SPDX-FileCopyrightText: 2021 , Dinesh Annayya
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+// SPDX-License-Identifier: Apache-2.0
+// SPDX-FileContributor: Created by Dinesh Annayya <dinesha@opencores.org>
+//
+//////////////////////////////////////////////////////////////////////
+//// ////
+//// OMS 8051 cores common library Module ////
+//// ////
+//// This file is part of the OMS 8051 cores project ////
+//// http://www.opencores.org/cores/oms8051mini/ ////
+//// https://github.com/dineshannayya/yifive_r0.git ////
+//// ////
+//// Description ////
+//// OMS 8051 definitions. ////
+//// ////
+//// To Do: ////
+//// nothing ////
+//// ////
+//// Author(s): ////
+//// - Dinesh Annayya, dinesha@opencores.org ////
+//// ////
+//// Revision : Nov 26, 2016 ////
+//// ////
+//////////////////////////////////////////////////////////////////////
+//// ////
+//// Copyright (C) 2000 Authors and OPENCORES.ORG ////
+//// ////
+//// This source file may be used and distributed without ////
+//// restriction provided that this copyright statement is not ////
+//// removed from the file and that any derivative work contains ////
+//// the original copyright notice and the associated disclaimer. ////
+//// ////
+//// This source file is free software; you can redistribute it ////
+//// and/or modify it under the terms of the GNU Lesser General ////
+//// Public License as published by the Free Software Foundation; ////
+//// either version 2.1 of the License, or (at your option) any ////
+//// later version. ////
+//// ////
+//// This source is distributed in the hope that it will be ////
+//// useful, but WITHOUT ANY WARRANTY; without even the implied ////
+//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR ////
+//// PURPOSE. See the GNU Lesser General Public License for more ////
+//// details. ////
+//// ////
+//// You should have received a copy of the GNU Lesser General ////
+//// Public License along with this source; if not, download it ////
+//// from http://www.opencores.org/lgpl.shtml ////
+//// ////
+//////////////////////////////////////////////////////////////////////
+//----------------------------------------------------------------------------
+// Simple Double sync logic with Reset value = 0
+// This double signal should be used for signal transiting from low to high
+//----------------------------------------------------------------------------
+
+module double_sync_high (
+ in_data ,
+ out_clk ,
+ out_rst_n ,
+ out_data
+ );
+
+parameter WIDTH = 1;
+
+input [WIDTH-1:0] in_data ; // Input from Different clock domain
+input out_clk ; // Output clock
+input out_rst_n ; // Active low Reset
+output[WIDTH-1:0] out_data ; // Output Data
+
+
+reg [WIDTH-1:0] in_data_s ; // One Cycle sync
+reg [WIDTH-1:0] in_data_2s ; // two Cycle sync
+reg [WIDTH-1:0] in_data_3s ; // three Cycle sync
+
+assign out_data = in_data_3s;
+
+always @(negedge out_rst_n or posedge out_clk)
+begin
+ if(out_rst_n == 1'b0)
+ begin
+ in_data_s <= {WIDTH{1'b0}};
+ in_data_2s <= {WIDTH{1'b0}};
+ in_data_3s <= {WIDTH{1'b0}};
+ end
+ else
+ begin
+ in_data_s <= in_data;
+ in_data_2s <= in_data_s;
+ in_data_3s <= in_data_2s;
+ end
+end
+
+
+endmodule
diff --git a/verilog/rtl/lib/double_sync_low.v b/verilog/rtl/lib/double_sync_low.v
new file mode 100755
index 0000000..efd4269
--- /dev/null
+++ b/verilog/rtl/lib/double_sync_low.v
@@ -0,0 +1,106 @@
+//////////////////////////////////////////////////////////////////////////////
+// SPDX-FileCopyrightText: 2021 , Dinesh Annayya
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+// SPDX-License-Identifier: Apache-2.0
+// SPDX-FileContributor: Created by Dinesh Annayya <dinesha@opencores.org>
+//
+//////////////////////////////////////////////////////////////////////
+//// ////
+//// OMS 8051 cores common library Module ////
+//// ////
+//// This file is part of the OMS 8051 cores project ////
+//// http://www.opencores.org/cores/oms8051mini/ ////
+//// https://github.com/dineshannayya/yifive_r0.git ////
+//// ////
+//// Description ////
+//// OMS 8051 definitions. ////
+//// ////
+//// To Do: ////
+//// nothing ////
+//// ////
+//// Author(s): ////
+//// - Dinesh Annayya, dinesha@opencores.org ////
+//// ////
+//// Revision : Nov 26, 2016 ////
+//// ////
+//////////////////////////////////////////////////////////////////////
+//// ////
+//// Copyright (C) 2000 Authors and OPENCORES.ORG ////
+//// ////
+//// This source file may be used and distributed without ////
+//// restriction provided that this copyright statement is not ////
+//// removed from the file and that any derivative work contains ////
+//// the original copyright notice and the associated disclaimer. ////
+//// ////
+//// This source file is free software; you can redistribute it ////
+//// and/or modify it under the terms of the GNU Lesser General ////
+//// Public License as published by the Free Software Foundation; ////
+//// either version 2.1 of the License, or (at your option) any ////
+//// later version. ////
+//// ////
+//// This source is distributed in the hope that it will be ////
+//// useful, but WITHOUT ANY WARRANTY; without even the implied ////
+//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR ////
+//// PURPOSE. See the GNU Lesser General Public License for more ////
+//// details. ////
+//// ////
+//// You should have received a copy of the GNU Lesser General ////
+//// Public License along with this source; if not, download it ////
+//// from http://www.opencores.org/lgpl.shtml ////
+//// ////
+//////////////////////////////////////////////////////////////////////
+//----------------------------------------------------------------------------
+// Simple Double sync logic with Reset value = 1
+// This double signal should be used for signal transiting from low to high
+//----------------------------------------------------------------------------
+
+module double_sync_low (
+ in_data ,
+ out_clk ,
+ out_rst_n ,
+ out_data
+ );
+
+parameter WIDTH = 1;
+
+input [WIDTH-1:0] in_data ; // Input from Different clock domain
+input out_clk ; // Output clock
+input out_rst_n ; // Active low Reset
+output[WIDTH-1:0] out_data ; // Output Data
+
+
+reg [WIDTH-1:0] in_data_s ; // One Cycle sync
+reg [WIDTH-1:0] in_data_2s ; // two Cycle sync
+reg [WIDTH-1:0] in_data_3s ; // three Cycle sync
+
+assign out_data = in_data_3s;
+
+always @(negedge out_rst_n or posedge out_clk)
+begin
+ if(out_rst_n == 1'b0)
+ begin
+ in_data_s <= {WIDTH{1'b1}};
+ in_data_2s <= {WIDTH{1'b1}};
+ in_data_3s <= {WIDTH{1'b1}};
+ end
+ else
+ begin
+ in_data_s <= in_data;
+ in_data_2s <= in_data_s;
+ in_data_3s <= in_data_2s;
+ end
+end
+
+
+endmodule
diff --git a/verilog/rtl/lib/pulse_gen_type1.sv b/verilog/rtl/lib/pulse_gen_type1.sv
new file mode 100644
index 0000000..838fe03
--- /dev/null
+++ b/verilog/rtl/lib/pulse_gen_type1.sv
@@ -0,0 +1,37 @@
+
+//------------------------------------------------------------------------
+// This module is used to generate 1ms and 1sec pulse based on 1us trigger
+// pulse
+//------------------------------------------------------------------------
+
+module pulse_gen_type1(
+ output logic clk_pulse,
+
+ input logic clk,
+ input logic reset_n,
+ input logic trigger
+);
+
+parameter WD= 10; // This will count from 0 to 1023
+parameter MAX_CNT = 999;
+
+logic [WD-1:0] cnt;
+
+assign clk_pulse = (cnt == 0) && trigger;
+
+always @ (posedge clk or negedge reset_n)
+begin
+ if (reset_n == 1'b0) begin
+ cnt <= 'b0;
+ end else begin
+ if(trigger) begin
+ if(cnt >= MAX_CNT)
+ cnt <= 0;
+ else
+ cnt <= cnt +1;
+ end
+ end
+end
+
+endmodule
+
diff --git a/verilog/rtl/lib/pulse_gen_type2.sv b/verilog/rtl/lib/pulse_gen_type2.sv
new file mode 100644
index 0000000..9bc759e
--- /dev/null
+++ b/verilog/rtl/lib/pulse_gen_type2.sv
@@ -0,0 +1,36 @@
+
+//------------------------------------------------------------------------
+// This module is used to generate 1us based on config value
+//------------------------------------------------------------------------
+
+module pulse_gen_type2 #(parameter WD = 10)
+ (
+ output logic clk_pulse,
+
+ input logic clk,
+ input logic reset_n,
+ input logic [WD-1:0] cfg_max_cnt
+);
+
+
+logic [WD-1:0] cnt;
+
+
+always @ (posedge clk or negedge reset_n)
+begin
+ if (reset_n == 1'b0) begin
+ cnt <= 'b0;
+ clk_pulse <= 'b0;
+ end else begin
+ if(cnt == cfg_max_cnt) begin
+ cnt <= 0;
+ clk_pulse <= 1'b1;
+ end else begin
+ cnt <= cnt +1;
+ clk_pulse <= 1'b0;
+ end
+ end
+end
+
+endmodule
+
diff --git a/verilog/rtl/lib/registers.v b/verilog/rtl/lib/registers.v
new file mode 100755
index 0000000..e4a87a1
--- /dev/null
+++ b/verilog/rtl/lib/registers.v
@@ -0,0 +1,329 @@
+//////////////////////////////////////////////////////////////////////////////
+// SPDX-FileCopyrightText: 2021 , Dinesh Annayya
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+// SPDX-License-Identifier: Apache-2.0
+// SPDX-FileContributor: Created by Dinesh Annayya <dinesha@opencores.org>
+//
+//////////////////////////////////////////////////////////////////////
+//// ////
+//// Tubo 8051 cores common library Module ////
+//// ////
+//// This file is part of the Turbo 8051 cores project ////
+//// http://www.opencores.org/cores/turbo8051/ ////
+//// ////
+//// Description ////
+//// Turbo 8051 definitions. ////
+//// ////
+//// To Do: ////
+//// nothing ////
+//// ////
+//// Author(s): ////
+//// - Dinesh Annayya, dinesha@opencores.org ////
+//// ////
+//// Revision : Mar 2, 2011 ////
+//// ////
+//////////////////////////////////////////////////////////////////////
+//// ////
+//// Copyright (C) 2000 Authors and OPENCORES.ORG ////
+//// ////
+//// This source file may be used and distributed without ////
+//// restriction provided that this copyright statement is not ////
+//// removed from the file and that any derivative work contains ////
+//// the original copyright notice and the associated disclaimer. ////
+//// ////
+//// This source file is free software; you can redistribute it ////
+//// and/or modify it under the terms of the GNU Lesser General ////
+//// Public License as published by the Free Software Foundation; ////
+//// either version 2.1 of the License, or (at your option) any ////
+//// later version. ////
+//// ////
+//// This source is distributed in the hope that it will be ////
+//// useful, but WITHOUT ANY WARRANTY; without even the implied ////
+//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR ////
+//// PURPOSE. See the GNU Lesser General Public License for more ////
+//// details. ////
+//// ////
+//// You should have received a copy of the GNU Lesser General ////
+//// Public License along with this source; if not, download it ////
+//// from http://www.opencores.org/lgpl.shtml ////
+//// ////
+//////////////////////////////////////////////////////////////////////
+
+/*********************************************************************
+** module: bit register
+
+** description: infers a register, make it modular
+ ***********************************************************************/
+module bit_register (
+ //inputs
+ we,
+ clk,
+ reset_n,
+ data_in,
+
+ //outputs
+ data_out
+ );
+
+//---------------------------------
+// Reset Default value
+//---------------------------------
+parameter RESET_DEFAULT = 1'h0;
+
+ input we;
+ input clk;
+ input reset_n;
+ input data_in;
+ output data_out;
+
+ reg data_out;
+
+ //infer the register
+ always @(posedge clk or negedge reset_n)
+ begin
+ if (!reset_n)
+ data_out <= RESET_DEFAULT;
+ else if (we)
+ data_out <= data_in;
+ end // always @ (posedge clk or negedge reset_n)
+endmodule // register
+
+
+/*********************************************************************
+** module: req register.
+
+** description: This register is set by cpu writting 1 and reset by
+ harward req = 1
+
+ Note: When there is a clash between cpu and hardware, cpu is given higher
+ priority
+
+ ***********************************************************************/
+module req_register (
+ //inputs
+ clk,
+ reset_n,
+ cpu_we,
+ cpu_req,
+ hware_ack,
+
+ //outputs
+ data_out
+ );
+
+//---------------------------------
+// Reset Default value
+//---------------------------------
+parameter RESET_DEFAULT = 1'h0;
+
+ input clk ;
+ input reset_n ;
+ input cpu_we ; // cpu write enable
+ input cpu_req ; // CPU Request
+ input hware_ack; // Hardware Ack
+ output data_out ;
+
+ reg data_out;
+
+ //infer the register
+ always @(posedge clk or negedge reset_n)
+ begin
+ if (!reset_n)
+ data_out <= RESET_DEFAULT;
+ else if (cpu_we & cpu_req) // Set on CPU Request
+ data_out <= 1'b1;
+ else if (hware_ack) // Reset the flag on Hardware ack
+ data_out <= 1'b0;
+ end // always @ (posedge clk or negedge reset_n)
+endmodule // register
+
+
+/*********************************************************************
+** module: req register.
+
+** description: This register is cleared by cpu writting 1 and set by
+ harward req = 1
+
+ Note: When there is a clash between cpu and hardware,
+ hardware is given higher priority
+
+ ***********************************************************************/
+module stat_register (
+ //inputs
+ clk,
+ reset_n,
+ cpu_we,
+ cpu_ack,
+ hware_req,
+
+ //outputs
+ data_out
+ );
+
+//---------------------------------
+// Reset Default value
+//---------------------------------
+parameter RESET_DEFAULT = 1'h0;
+
+ input clk ;
+ input reset_n ;
+ input cpu_we ; // cpu write enable
+ input cpu_ack ; // CPU Ack
+ input hware_req; // Hardware Req
+ output data_out ;
+
+ reg data_out;
+
+ //infer the register
+ always @(posedge clk or negedge reset_n)
+ begin
+ if (!reset_n)
+ data_out <= RESET_DEFAULT;
+ else if (hware_req) // Set the flag on Hardware Req
+ data_out <= 1'b1;
+ else if (cpu_we & cpu_ack) // Clear on CPU Ack
+ data_out <= 1'b0;
+ end // always @ (posedge clk or negedge reset_n)
+endmodule // register
+
+
+
+
+
+/*********************************************************************
+ module: generic register
+***********************************************************************/
+module generic_register (
+ //List of Inputs
+ we,
+ data_in,
+ reset_n,
+ clk,
+
+ //List of Outs
+ data_out
+ );
+
+ parameter WD = 1;
+ parameter RESET_DEFAULT = 0;
+ input [WD-1:0] we;
+ input [WD-1:0] data_in;
+ input reset_n;
+ input clk;
+ output [WD-1:0] data_out;
+
+
+generate
+ genvar i;
+ for (i = 0; i < WD; i = i + 1) begin : gen_bit_reg
+ bit_register #(RESET_DEFAULT[i]) u_bit_reg (
+ .we (we[i]),
+ .clk (clk),
+ .reset_n (reset_n),
+ .data_in (data_in[i]),
+ .data_out (data_out[i])
+ );
+ end
+endgenerate
+
+
+endmodule
+
+
+/*********************************************************************
+ module: generic interrupt status
+***********************************************************************/
+module generic_intr_stat_reg (
+ //inputs
+ clk,
+ reset_n,
+ reg_we,
+ reg_din,
+ hware_req,
+
+ //outputs
+ data_out
+ );
+
+ parameter WD = 1;
+ parameter RESET_DEFAULT = 0;
+ input [WD-1:0] reg_we;
+ input [WD-1:0] reg_din;
+ input [WD-1:0] hware_req;
+ input reset_n;
+ input clk;
+ output [WD-1:0] data_out;
+
+
+generate
+ genvar i;
+ for (i = 0; i < WD; i = i + 1) begin : gen_bit_reg
+ stat_register #(RESET_DEFAULT[i]) u_bit_reg (
+ //inputs
+ . clk (clk ),
+ . reset_n (reset_n ),
+ . cpu_we (reg_we[i] ),
+ . cpu_ack (reg_din[i] ),
+ . hware_req (hware_req[i] ),
+
+ //outputs
+ . data_out (data_out[i] )
+ );
+
+ end
+endgenerate
+
+
+endmodule
+
+/*********************************************************************
+ module: generic 32b register
+***********************************************************************/
+module gen_32b_reg (
+ //List of Inputs
+ cs,
+ we,
+ data_in,
+ reset_n,
+ clk,
+
+ //List of Outs
+ data_out
+ );
+
+ parameter RESET_DEFAULT = 32'h0;
+ input [3:0] we;
+ input cs;
+ input [31:0] data_in;
+ input reset_n;
+ input clk;
+ output [31:0] data_out;
+
+
+ reg [31:0] data_out;
+
+always @ (posedge clk or negedge reset_n) begin
+ if (reset_n == 1'b0) begin
+ data_out <= RESET_DEFAULT ;
+ end
+ else begin
+ if(cs && we[0]) data_out[7:0] <= data_in[7:0];
+ if(cs && we[1]) data_out[15:8] <= data_in[15:8];
+ if(cs && we[2]) data_out[23:16] <= data_in[23:16];
+ if(cs && we[3]) data_out[31:24] <= data_in[31:24];
+ end
+end
+
+
+endmodule
diff --git a/verilog/rtl/lib/reset_sync.sv b/verilog/rtl/lib/reset_sync.sv
new file mode 100644
index 0000000..d96c719
--- /dev/null
+++ b/verilog/rtl/lib/reset_sync.sv
@@ -0,0 +1,101 @@
+//////////////////////////////////////////////////////////////////////////////
+// SPDX-FileCopyrightText: 2021 , Dinesh Annayya
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+// SPDX-License-Identifier: Apache-2.0
+// SPDX-FileContributor: Created by Dinesh Annayya <dinesha@opencores.org>
+//
+//////////////////////////////////////////////////////////////////////
+//// ////
+//// Active low reset synchronization ////
+//// ////
+//// This file is part of the yifive cores project ////
+//// https://github.com/dineshannayya/yifive_r0.git ////
+//// http://www.opencores.org/cores/yifive/ ////
+//// ////
+//// Description: ////
+//// Synchronize the active low reset to destination clock ////
+//// ////
+//// To Do: ////
+//// nothing ////
+//// ////
+//// Author(s): ////
+//// - Dinesh Annayya, dinesha@opencores.org ////
+//// ////
+//// Revision : ////
+//// v0: June 17, 2021, Dinesh A ////
+//// Initial version ////
+//// ////
+//////////////////////////////////////////////////////////////////////
+//// ////
+//// Copyright (C) 2000 Authors and OPENCORES.ORG ////
+//// ////
+//// This source file may be used and distributed without ////
+//// restriction provided that this copyright statement is not ////
+//// removed from the file and that any derivative work contains ////
+//// the original copyright notice and the associated disclaimer. ////
+//// ////
+//// This source file is free software; you can redistribute it ////
+//// and/or modify it under the terms of the GNU Lesser General ////
+//// Public License as published by the Free Software Foundation; ////
+//// either version 2.1 of the License, or (at your option) any ////
+//// later version. ////
+//// ////
+//// This source is distributed in the hope that it will be ////
+//// useful, but WITHOUT ANY WARRANTY; without even the implied ////
+//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR ////
+//// PURPOSE. See the GNU Lesser General Public License for more ////
+//// details. ////
+//// ////
+//// You should have received a copy of the GNU Lesser General ////
+//// Public License along with this source; if not, download it ////
+//// from http://www.opencores.org/lgpl.shtml ////
+//// ////
+//////////////////////////////////////////////////////////////////////
+
+module reset_sync (
+ scan_mode ,
+ dclk , // Destination clock domain
+ arst_n , // active low async reset
+ srst_n
+ );
+
+parameter WIDTH = 1;
+
+input scan_mode ; // test mode
+input dclk ; // Destination clock
+input arst_n ; // Async Reset
+output srst_n ; // Sync Reset w.r.t dclk
+
+
+reg in_data_s ; // One Cycle sync
+reg in_data_2s ; // two Cycle sync
+
+assign srst_n = (scan_mode) ? arst_n : in_data_2s;
+
+always @(negedge arst_n or posedge dclk)
+begin
+ if(arst_n == 1'b0)
+ begin
+ in_data_s <= 1'b0;
+ in_data_2s <= 1'b0;
+ end
+ else
+ begin
+ in_data_s <= 1'b1;
+ in_data_2s <= in_data_s;
+ end
+end
+
+
+endmodule
diff --git a/verilog/rtl/lib/ser_inf_32b.sv b/verilog/rtl/lib/ser_inf_32b.sv
new file mode 100644
index 0000000..8228852
--- /dev/null
+++ b/verilog/rtl/lib/ser_inf_32b.sv
@@ -0,0 +1,121 @@
+//////////////////////////////////////////////////////////////////////////////
+// SPDX-FileCopyrightText: 2021 , Dinesh Annayya
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+// SPDX-License-Identifier: Apache-2.0
+// SPDX-FileContributor: Created by Dinesh Annayya <dinesha@opencores.org>
+//
+//////////////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////////////
+//// ////
+//// ser_inf_32 ////
+//// ////
+//// This file is part of the mbist_ctrl cores project ////
+//// https://github.com/dineshannayya/mbist_ctrl.git ////
+//// ////
+//// Description ////
+//// This block manages the serial to Parallel conversion ////
+//// This block usefull for Bist SDI/SDO access ////
+//// Function: ////
+//// 1. When reg_wr=1, this block set shift=1 and shift ////
+//// reg_wdata serial through sdi for 32 cycles and ////
+//// asserts Reg Ack ////
+//// 2. When reg_rd=1, this block set shoft=1 and serial ////
+//// capture the sdo to reg_rdata for 32 cycles and ////
+//// asserts Reg Ack ////
+//// ////
+//// To Do: ////
+//// nothing ////
+//// ////
+//// Author(s): ////
+//// - Dinesh Annayya, dinesha@opencores.org ////
+//// ////
+//// Revision : ////
+//// 0.0 - 20th Oct 2021, Dinesh A ////
+//// Initial integration ////
+//// ////
+//////////////////////////////////////////////////////////////////////
+
+module ser_inf_32b
+ (
+
+ // Master Port
+ input logic rst_n , // Regular Reset signal
+ input logic clk , // System clock
+ input logic reg_wr , // Write Request
+ input logic reg_rd , // Read Request
+ input logic [31:0] reg_wdata , // data output
+ output logic [31:0] reg_rdata , // data input
+ output logic reg_ack , // acknowlegement
+
+ // Slave Port
+ output logic sdi , // Serial SDI
+ output logic shift , // Shift Signal
+ input logic sdo // Serial SDO
+
+ );
+
+
+ parameter IDLE = 1'b0;
+ parameter SHIFT_DATA = 1'b1;
+
+ logic state;
+ logic [5:0] bit_cnt;
+ logic [31:0] shift_data;
+
+
+always@(negedge rst_n or posedge clk)
+begin
+ if(rst_n == 0) begin
+ state <= IDLE;
+ reg_rdata <= 'h0;
+ reg_ack <= 1'b0;
+ sdi <= 1'b0;
+ bit_cnt <= 6'h0;
+ shift <= 'b0;
+ shift_data <= 32'h0;
+ end else begin
+ case(state)
+ IDLE: begin
+ reg_ack <= 1'b0;
+ bit_cnt <= 6'h0;
+ if(reg_wr) begin
+ shift <= 'b1;
+ shift_data <= reg_wdata;
+ state <= SHIFT_DATA;
+ end else if(reg_rd) begin
+ shift <= 'b1;
+ shift_data <= 'h0;
+ state <= SHIFT_DATA;
+ end
+ end
+ SHIFT_DATA: begin
+ shift_data <= {1'b0,shift_data[31:1]};
+ reg_rdata <= {sdo,reg_rdata[31:1]};
+ sdi <= shift_data[0];
+ if(bit_cnt < 31) begin
+ bit_cnt <= bit_cnt +1;
+ end else begin
+ reg_ack <= 1'b1;
+ shift <= 'b0;
+ state <= IDLE;
+ end
+ end
+ endcase
+ end
+end
+
+
+
+
+endmodule
diff --git a/verilog/rtl/lib/ser_shift.sv b/verilog/rtl/lib/ser_shift.sv
new file mode 100644
index 0000000..21ef9dc
--- /dev/null
+++ b/verilog/rtl/lib/ser_shift.sv
@@ -0,0 +1,76 @@
+//////////////////////////////////////////////////////////////////////////////
+// SPDX-FileCopyrightText: 2021 , Dinesh Annayya
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+// SPDX-License-Identifier: Apache-2.0
+// SPDX-FileContributor: Created by Dinesh Annayya <dinesha@opencores.org>
+//
+//////////////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////////////
+//// ////
+//// ser_shift ////
+//// ////
+//// This file is part of the mbist_ctrl cores project ////
+//// https://github.com/dineshannayya/riscdunio.git ////
+//// ////
+//// Description ////
+//// This block manages the parallel to serial conversion ////
+//// This block usefull for Bist SDI/SDO access ////
+//// asserts Reg Ack ////
+//// ////
+//// To Do: ////
+//// nothing ////
+//// ////
+//// Author(s): ////
+//// - Dinesh Annayya, dinesha@opencores.org ////
+//// ////
+//// Revision : ////
+//// 0.0 - 16th Dec 2021, Dinesh A ////
+//// Initial integration ////
+//// ////
+//////////////////////////////////////////////////////////////////////
+
+module ser_shift
+ #(parameter WD = 32)
+ (
+
+ // Master Port
+ input logic rst_n , // Regular Reset signal
+ input logic clk , // System clock
+ input logic load , // load request
+ input logic shift , // shift
+ input logic [WD-1:0] load_data , // load data
+ input logic sdi , // sdi
+ output logic sdo // sdo
+
+
+ );
+
+logic [WD-1:0] shift_reg;
+
+always@(negedge rst_n or posedge clk)
+begin
+ if(rst_n == 0) begin
+ shift_reg <= 'h0;
+ end else if(load) begin
+ shift_reg <= load_data;
+ end else if(shift) begin
+ shift_reg <= {sdi,shift_reg[WD-1:1]};
+ end
+end
+
+assign sdo = shift_reg[0];
+
+
+
+endmodule
diff --git a/verilog/rtl/lib/sync_fifo.sv b/verilog/rtl/lib/sync_fifo.sv
new file mode 100644
index 0000000..464a26c
--- /dev/null
+++ b/verilog/rtl/lib/sync_fifo.sv
@@ -0,0 +1,167 @@
+//////////////////////////////////////////////////////////////////////////////
+// SPDX-FileCopyrightText: 2021 , Dinesh Annayya
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+// SPDX-License-Identifier: Apache-2.0
+// SPDX-FileContributor: Created by Dinesh Annayya <dinesha@opencores.org>
+//
+/*********************************************************************
+
+ This file is part of the sdram controller project
+ http://www.opencores.org/cores/sdr_ctrl/
+ https://github.com/dineshannayya/yifive_r0.git
+
+ Description: SYNC FIFO
+ Parameters:
+ W : Width (integer)
+ D : Depth (integer, power of 2, 4 to 256)
+
+ To Do:
+ nothing
+
+ Author(s): Dinesh Annayya, dinesha@opencores.org
+
+ Copyright (C) 2000 Authors and OPENCORES.ORG
+
+ This source file may be used and distributed without
+ restriction provided that this copyright statement is not
+ removed from the file and that any derivative work contains
+ the original copyright notice and the associated disclaimer.
+
+ This source file is free software; you can redistribute it
+ and/or modify it under the terms of the GNU Lesser General
+ Public License as published by the Free Software Foundation;
+ either version 2.1 of the License, or (at your option) any
+later version.
+
+ This source is distributed in the hope that it will be
+ useful, but WITHOUT ANY WARRANTY; without even the implied
+ warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ PURPOSE. See the GNU Lesser General Public License for more
+ details.
+
+ You should have received a copy of the GNU Lesser General
+ Public License along with this source; if not, download it
+ from http://www.opencores.org/lgpl.shtml
+
+*******************************************************************/
+
+
+module sync_fifo (clk,
+ reset_n,
+ wr_en,
+ wr_data,
+ full,
+ empty,
+ rd_en,
+ rd_data);
+
+ parameter W = 8;
+ parameter D = 4;
+
+ parameter AW = (D == 2) ? 1 :
+ (D == 4) ? 2 :
+ (D == 8) ? 3 :
+ (D == 16) ? 4 :
+ (D == 32) ? 5 :
+ (D == 64) ? 6 :
+ (D == 128) ? 7 :
+ (D == 256) ? 8 : 0;
+
+ output [W-1 : 0] rd_data;
+ input [W-1 : 0] wr_data;
+ input clk, reset_n, wr_en, rd_en;
+ output full, empty;
+
+ // synopsys translate_off
+
+ initial begin
+ if (AW == 0) begin
+ $display ("%m : ERROR!!! Fifo depth %d not in range 4 to 256", D);
+ end // if (AW == 0)
+ end // initial begin
+
+ // synopsys translate_on
+
+
+ reg [W-1 : 0] mem[D-1 : 0];
+ reg [AW-1 : 0] rd_ptr, wr_ptr;
+ reg full, empty;
+
+ wire [W-1 : 0] rd_data;
+
+ always @ (posedge clk or negedge reset_n)
+ if (reset_n == 1'b0) begin
+ wr_ptr <= {AW{1'b0}} ;
+ end
+ else begin
+ if (wr_en & !full) begin
+ wr_ptr <= wr_ptr + 1'b1 ;
+ end
+ end
+
+ always @ (posedge clk or negedge reset_n)
+ if (reset_n == 1'b0) begin
+ rd_ptr <= {AW{1'b0}} ;
+ end
+ else begin
+ if (rd_en & !empty) begin
+ rd_ptr <= rd_ptr + 1'b1 ;
+ end
+ end
+
+
+ always @ (posedge clk or negedge reset_n)
+ if (reset_n == 1'b0) begin
+ empty <= 1'b1 ;
+ end
+ else begin
+ empty <= (((wr_ptr - rd_ptr) == {{(AW-1){1'b0}}, 1'b1}) & rd_en & ~wr_en) ? 1'b1 :
+ ((wr_ptr == rd_ptr) & ~rd_en & wr_en) ? 1'b0 : empty ;
+ end
+
+ always @ (posedge clk or negedge reset_n)
+ if (reset_n == 1'b0) begin
+ full <= 1'b0 ;
+ end
+ else begin
+ full <= (((wr_ptr - rd_ptr) == {{(AW-1){1'b1}}, 1'b0}) & ~rd_en & wr_en) ? 1'b1 :
+ (((wr_ptr - rd_ptr) == {AW{1'b1}}) & rd_en & ~wr_en) ? 1'b0 : full ;
+ end
+
+ always @ (posedge clk)
+ if (wr_en)
+ mem[wr_ptr] <= wr_data;
+
+assign rd_data = mem[rd_ptr];
+
+
+// synopsys translate_off
+ always @(posedge clk) begin
+ if (wr_en && full) begin
+ $display("%m : Error! sfifo overflow!");
+ end
+ end
+
+ always @(posedge clk) begin
+ if (rd_en && empty) begin
+ $display("%m : error! sfifo underflow!");
+ end
+ end
+
+// synopsys translate_on
+//---------------------------------------
+
+endmodule
+
+
diff --git a/verilog/rtl/lib/sync_fifo2.sv b/verilog/rtl/lib/sync_fifo2.sv
new file mode 100755
index 0000000..f71ad30
--- /dev/null
+++ b/verilog/rtl/lib/sync_fifo2.sv
@@ -0,0 +1,222 @@
+//////////////////////////////////////////////////////////////////////////////
+// SPDX-FileCopyrightText: 2021 , Dinesh Annayya
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+// SPDX-License-Identifier: Apache-2.0
+// SPDX-FileContributor: Created by Dinesh Annayya <dinesha@opencores.org>
+//
+/*********************************************************************
+
+ SYNC FIFO with empty,aempty,full,afull
+
+
+ Description: SYNC FIFO
+
+ To Do:
+ nothing
+
+ Author(s): Dinesh Annayya, dinesha@opencores.org
+
+ Copyright (C) 2000 Authors and OPENCORES.ORG
+
+ This source file may be used and distributed without
+ restriction provided that this copyright statement is not
+ removed from the file and that any derivative work contains
+ the original copyright notice and the associated disclaimer.
+
+ This source file is free software; you can redistribute it
+ and/or modify it under the terms of the GNU Lesser General
+ Public License as published by the Free Software Foundation;
+ either version 2.1 of the License, or (at your option) any
+later version.
+
+ This source is distributed in the hope that it will be
+ useful, but WITHOUT ANY WARRANTY; without even the implied
+ warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ PURPOSE. See the GNU Lesser General Public License for more
+ details.
+
+ You should have received a copy of the GNU Lesser General
+ Public License along with this source; if not, download it
+ from http://www.opencores.org/lgpl.shtml
+
+*******************************************************************/
+
+//-------------------------------------------
+// sync FIFO
+//-----------------------------------------------
+//`timescale 1ns/1ps
+
+module sync_fifo2 (clk,
+ reset_n,
+ wr_en,
+ wr_data,
+ full,
+ afull,
+ rd_en,
+ empty,
+ aempty,
+ rd_data);
+
+ parameter W = 4'd8;
+ parameter DP = 3'd4;
+ parameter WR_FAST = 1'b1;
+ parameter RD_FAST = 1'b1;
+ parameter FULL_DP = DP;
+ parameter EMPTY_DP = 1'b0;
+
+ parameter AW = (DP == 2) ? 1 :
+ (DP == 4) ? 2 :
+ (DP == 8) ? 3 :
+ (DP == 16) ? 4 :
+ (DP == 32) ? 5 :
+ (DP == 64) ? 6 :
+ (DP == 128) ? 7 :
+ (DP == 256) ? 8 : 0;
+
+ output [W-1 : 0] rd_data;
+ input [W-1 : 0] wr_data;
+ input clk, reset_n, wr_en, rd_en;
+ output full, empty;
+ output afull, aempty; // about full and about to empty
+
+
+ // synopsys translate_off
+
+ initial begin
+ if (AW == 0) begin
+ $display ("%m : ERROR!!! Fifo depth %d not in range 2 to 256", DP);
+ end // if (AW == 0)
+ end // initial begin
+
+ // synopsys translate_on
+
+ reg [W-1 : 0] mem[DP-1 : 0];
+
+ /*********************** write side ************************/
+ reg [AW:0] wr_ptr;
+ reg full_q;
+ wire full_c;
+ wire afull_c;
+ wire [AW:0]wr_ptr_inc = wr_ptr + 1'b1;
+ wire [AW:0]wr_cnt = get_cnt(wr_ptr, rd_ptr);
+
+ assign full_c = (wr_cnt == FULL_DP) ? 1'b1 : 1'b0;
+ assign afull_c = (wr_cnt == FULL_DP-1) ? 1'b1 : 1'b0;
+
+
+ always @(posedge clk or negedge reset_n) begin
+ if (!reset_n) begin
+ wr_ptr <= 0;
+ full_q <= 0;
+ end
+ else if (wr_en) begin
+ wr_ptr <= wr_ptr_inc;
+ if (wr_cnt == (FULL_DP-1)) begin
+ full_q <= 1'b1;
+ end
+ end
+ else begin
+ if (full_q && (wr_cnt<FULL_DP)) begin
+ full_q <= 1'b0;
+ end
+ end
+ end
+
+ assign full = (WR_FAST == 1) ? full_c : full_q;
+ assign afull = afull_c;
+
+ always @(posedge clk) begin
+ if (wr_en) begin
+ mem[wr_ptr[AW-1:0]] <= wr_data;
+ end
+ end
+
+
+
+ /************************ read side *****************************/
+ reg [AW:0] rd_ptr;
+ reg empty_q;
+ wire empty_c;
+ wire aempty_c;
+ wire [AW:0] rd_ptr_inc = rd_ptr + 1'b1;
+ wire [AW:0] rd_cnt = get_cnt(wr_ptr, rd_ptr);
+
+ assign empty_c = (rd_cnt == 0) ? 1'b1 : 1'b0;
+ assign aempty_c = (rd_cnt == 1) ? 1'b1 : 1'b0;
+
+ always @(posedge clk or negedge reset_n) begin
+ if (!reset_n) begin
+ rd_ptr <= 0;
+ empty_q <= 1'b1;
+ end
+ else begin
+ if (rd_en) begin
+ rd_ptr <= rd_ptr_inc;
+ if (rd_cnt==(EMPTY_DP+1)) begin
+ empty_q <= 1'b1;
+ end
+ end
+ else begin
+ if (empty_q && (rd_cnt!=EMPTY_DP)) begin
+ empty_q <= 1'b0;
+ end
+ end
+ end
+ end
+
+ assign empty = (RD_FAST == 1) ? empty_c : empty_q;
+ assign aempty = aempty_c;
+
+ reg [W-1 : 0] rd_data_q;
+
+ wire [W-1 : 0] rd_data_c = mem[rd_ptr[AW-1:0]];
+
+
+ always @(posedge clk) begin
+ rd_data_q <= rd_data_c;
+ end
+ assign rd_data = (RD_FAST == 1) ? rd_data_c : rd_data_q;
+
+
+
+
+function [AW:0] get_cnt;
+input [AW:0] wr_ptr, rd_ptr;
+begin
+ if (wr_ptr >= rd_ptr) begin
+ get_cnt = (wr_ptr - rd_ptr);
+ end
+ else begin
+ get_cnt = DP*2 - (rd_ptr - wr_ptr);
+ end
+end
+endfunction
+
+// synopsys translate_off
+always @(posedge clk) begin
+ if (wr_en && full) begin
+ $display($time, "%m Error! afifo overflow!");
+ $stop;
+ end
+end
+
+always @(posedge clk) begin
+ if (rd_en && empty) begin
+ $display($time, "%m error! afifo underflow!");
+ $stop;
+ end
+end
+// synopsys translate_on
+
+endmodule
diff --git a/verilog/rtl/lib/sync_wbb.sv b/verilog/rtl/lib/sync_wbb.sv
new file mode 100644
index 0000000..e2cc794
--- /dev/null
+++ b/verilog/rtl/lib/sync_wbb.sv
@@ -0,0 +1,336 @@
+//////////////////////////////////////////////////////////////////////////////
+// SPDX-FileCopyrightText: 2021 , Dinesh Annayya
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+// SPDX-License-Identifier: Apache-2.0
+// SPDX-FileContributor: Created by Dinesh Annayya <dinesha@opencores.org>
+//
+//////////////////////////////////////////////////////////////////////
+//// ////
+//// sync Wishbone Interface iBurst Enable and lack ////
+//// ////
+//// This file is part of the YIFive cores project ////
+//// http://www.opencores.org/cores/yifive/ ////
+//// ////
+//// Description ////
+//// This block does async Wishbone from one clock to other ////
+//// clock domain
+//// ////
+//// To Do: ////
+//// nothing ////
+//// ////
+//// Author(s): ////
+//// - Dinesh Annayya, dinesha@opencores.org ////
+//// ////
+//// Revision : ////
+//// 0.1 - 25th Feb 2021, Dinesh A ////
+//// initial version ////
+//// 0.2 - 28th Feb 2021, Dinesh A ////
+//// reduced the response FIFO path depth to 2 as ////
+//// return path used by only read logic and read is ////
+//// blocking request and expect only one location will ////
+//// be used ////
+//// 0.3 - 20 Jan 2022, Dinesh A ////
+//// added wishbone burst mode. Additional signal added ////
+//// A. *bl - 10 Bit word Burst count, 1 - 1 DW(32 bit)////
+//// B. *lack - Last Burst ack ////
+//////////////////////////////////////////////////////////////////////
+//// ////
+//// Copyright (C) 2000 Authors and OPENCORES.ORG ////
+//// ////
+//// This source file may be used and distributed without ////
+//// restriction provided that this copyright statement is not ////
+//// removed from the file and that any derivative work contains ////
+//// the original copyright notice and the associated disclaimer. ////
+//// ////
+//// This source file is free software; you can redistribute it ////
+//// and/or modify it under the terms of the GNU Lesser General ////
+//// Public License as published by the Free Software Foundation; ////
+//// either version 2.1 of the License, or (at your option) any ////
+//// later version. ////
+//// ////
+//// This source is distributed in the hope that it will be ////
+//// useful, but WITHOUT ANY WARRANTY; without even the implied ////
+//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR ////
+//// PURPOSE. See the GNU Lesser General Public License for more ////
+//// details. ////
+//// ////
+//// You should have received a copy of the GNU Lesser General ////
+//// Public License along with this source; if not, download it ////
+//// from http://www.opencores.org/lgpl.shtml ////
+//// ////
+//////////////////////////////////////////////////////////////////////
+
+module sync_wbb
+ #(parameter AW = 32,
+ parameter BW = 4,
+ parameter BL = 10,
+ parameter DW = 32)
+ (
+
+ // Master Port
+ input logic rst_n , // Regular Reset signal
+ input logic clk_i , // System clock
+ input logic wbm_cyc_i , // strobe/request
+ input logic wbm_stb_i , // strobe/request
+ input logic [AW-1:0] wbm_adr_i , // address
+ input logic wbm_we_i , // write
+ input logic [DW-1:0] wbm_dat_i , // data output
+ input logic [BW-1:0] wbm_sel_i , // byte enable
+ input logic [3:0] wbm_tid_i ,
+ input logic [BL-1:0] wbm_bl_i , // Burst Count
+ input logic wbm_bry_i , // Burst Ready
+ output logic [DW-1:0] wbm_dat_o , // data input
+ output logic wbm_ack_o , // acknowlegement
+ output logic wbm_lack_o , // Last Burst access
+ output logic wbm_err_o , // error
+
+ // Slave Port
+ output logic wbs_cyc_o , // strobe/request
+ output logic wbs_stb_o , // strobe/request
+ output logic [AW-1:0] wbs_adr_o , // address
+ output logic wbs_we_o , // write
+ output logic [DW-1:0] wbs_dat_o , // data output
+ output logic [BW-1:0] wbs_sel_o , // byte enable
+ output logic [3:0] wbs_tid_o ,
+ output logic [BL-1:0] wbs_bl_o , // Burst Count
+ output logic wbs_bry_o , // Busrt WData Avialble Or Ready To accept Rdata
+ input logic [DW-1:0] wbs_dat_i , // data input
+ input logic wbs_ack_i , // acknowlegement
+ input logic wbs_lack_i , // Last Ack
+ input logic wbs_err_i // error
+
+ );
+
+
+
+parameter CFW = AW+DW+BW+BL+4+1 ; // COMMAND FIFO WIDTH
+parameter RFW = DW+1+1 ; // RESPONSE FIFO WIDTH
+
+parameter IDLE = 2'b00;
+parameter WRITE_DATA = 2'b01;
+parameter READ_DATA = 2'b10;
+
+
+//-------------------------------------------------
+// Master Interface
+// -------------------------------------------------
+logic m_cmd_wr_en ;
+logic [CFW-1:0] m_cmd_wr_data ;
+logic m_cmd_wr_full ;
+logic m_cmd_wr_afull ;
+
+logic m_resp_rd_empty ;
+logic m_resp_rd_aempty ;
+logic m_resp_rd_en ;
+logic [RFW-1:0] m_resp_rd_data ;
+logic [BL-1:0] m_bl_cnt ;
+logic [1:0] m_state ;
+
+// Master Write Interface
+
+
+
+assign m_cmd_wr_data = {wbm_adr_i,wbm_we_i,wbm_dat_i,wbm_sel_i,wbm_tid_i,wbm_bl_i};
+
+assign wbm_dat_o = m_resp_rd_data[DW-1:0];
+assign wbm_err_o = 'b0;
+
+always@(negedge rst_n or posedge clk_i)
+begin
+ if(rst_n == 0) begin
+ m_cmd_wr_en <= 'b0;
+ m_resp_rd_en <= 'b0;
+ m_state <= 'h0;
+ m_bl_cnt <= 'h0;
+ wbm_ack_o <= 'b0;
+ wbm_lack_o <= 'b0;
+ end else begin
+ case(m_state)
+ IDLE: begin
+ // Read DATA
+ // Make sure that FIFO is not overflow and there is no previous
+ // pending write + fifo is about to full
+ if(wbm_stb_i && !wbm_we_i && wbm_bry_i && !m_cmd_wr_full && !(m_cmd_wr_afull && m_cmd_wr_en) && !wbm_lack_o) begin
+ m_bl_cnt <= wbm_bl_i;
+ m_cmd_wr_en <= 'b1;
+ m_state <= READ_DATA;
+ end else if(wbm_stb_i && wbm_we_i && wbm_bry_i && !m_cmd_wr_full && !(m_cmd_wr_afull && m_cmd_wr_en) && !wbm_lack_o) begin
+ wbm_ack_o <= 'b1;
+ m_cmd_wr_en <= 'b1;
+ m_bl_cnt <= wbm_bl_i-1;
+ if(wbm_bl_i == 'h1) begin
+ wbm_lack_o <= 'b1;
+ m_state <= IDLE;
+ end else begin
+ m_bl_cnt <= wbm_bl_i-1;
+ m_state <= WRITE_DATA;
+ end
+ end else begin
+ m_resp_rd_en <= 'b0;
+ m_cmd_wr_en <= 'b0;
+ wbm_ack_o <= 'b0;
+ wbm_lack_o <= 'b0;
+ end
+ end
+
+ // Write next Transaction
+ WRITE_DATA: begin
+ if(m_cmd_wr_full != 1 && !(m_cmd_wr_afull && m_cmd_wr_en) && wbm_bry_i) begin
+ wbm_ack_o <= 'b1;
+ m_cmd_wr_en <= 'b1;
+ if(m_bl_cnt == 1) begin
+ wbm_lack_o <= 'b1;
+ m_state <= IDLE;
+ end else begin
+ m_bl_cnt <= m_bl_cnt-1;
+ end
+ end else begin
+ m_cmd_wr_en <= 'b0;
+ wbm_ack_o <= 'b0;
+ wbm_lack_o <= 'b0;
+ end
+ end
+
+ // Read Transaction
+ READ_DATA: begin
+ // Check Back to Back Ack and last Location case
+ if(((wbm_ack_o == 0 && m_resp_rd_empty != 1) ||
+ (wbm_ack_o == 1 && m_resp_rd_aempty != 1)) && wbm_bry_i) begin
+ m_resp_rd_en <= 'b1;
+ wbm_ack_o <= 'b1;
+ if(m_bl_cnt == 1) begin
+ wbm_lack_o <= 'b1;
+ m_state <= IDLE;
+ end else begin
+ m_bl_cnt <= m_bl_cnt-1;
+ end
+ end else begin
+ m_resp_rd_en <= 'b0;
+ m_cmd_wr_en <= 'b0;
+ wbm_ack_o <= 'b0;
+ wbm_lack_o <= 'b0;
+ end
+ end
+ endcase
+ end
+end
+
+
+//------------------------------
+// Slave Interface
+//-------------------------------
+
+logic [CFW-1:0] s_cmd_rd_data ;
+logic [CFW-1:0] s_cmd_rd_data_l ;
+logic s_cmd_rd_empty ;
+logic s_cmd_rd_aempty ;
+logic s_cmd_rd_en ;
+logic s_resp_wr_en ;
+logic [RFW-1:0] s_resp_wr_data ;
+logic s_resp_wr_full ;
+logic s_resp_wr_afull ;
+logic wbs_ack_f ;
+logic wbs_stb_l ;
+logic wbs_burst ;
+
+wire wbs_stb_pedge = (wbs_stb_l == 1'b0) && wbs_stb_o;
+
+
+always@(negedge rst_n or posedge clk_i)
+begin
+ if(rst_n == 0) begin
+ wbs_ack_f <= 1'b0;
+ wbs_stb_l <= 1'b0;
+ wbs_burst <= 'h0;
+ s_cmd_rd_data_l <= 'h0;
+ end else begin
+ wbs_ack_f <= wbs_lack_i;
+ wbs_stb_l <= wbs_stb_o;
+ if(s_cmd_rd_en)
+ s_cmd_rd_data_l <= s_cmd_rd_data;
+ if(wbs_stb_pedge && wbs_bl_o > 'h1)
+ wbs_burst <= 1'b1;
+ else if(wbs_lack_i)
+ wbs_burst <= 1'b0;
+ end
+end
+
+
+// Read Interface
+
+
+assign {wbs_adr_o,wbs_we_o,wbs_dat_o,wbs_sel_o,wbs_tid_o,wbs_bl_o} = (s_cmd_rd_empty) ? s_cmd_rd_data_l: s_cmd_rd_data;
+// All the downstream logic expect Stobe is getting de-asserted
+// atleast for 1 cycle after ack is generated
+assign wbs_stb_o = (wbs_burst) ? 1'b1 : ((wbs_ack_f) ? 1'b0 : (s_cmd_rd_empty) ? 1'b0: 1'b1);
+assign wbs_cyc_o = (wbs_burst) ? 1'b1 : ((wbs_ack_f) ? 1'b0 : (s_cmd_rd_empty) ? 1'b0: 1'b1);
+
+// Generate bust ready only we have space inside response fifo
+// In Write Phase,
+// Generate burst ready, only when we have wdata & space in response fifo
+// In Read Phase
+// Generate burst ready, only when space in response fifo
+//
+assign wbs_bry_o = (wbs_we_o) ? ((s_cmd_rd_empty || (s_cmd_rd_en && s_cmd_rd_aempty)) ? 1'b0: 1'b1) :
+ (s_resp_wr_full || (s_resp_wr_en && s_resp_wr_afull)) ? 1'b0: 1'b1;
+
+// During Write phase, cmd fifo will have wdata, so dequeue for every ack
+// During Read Phase, cmd fifo will be written only one time, hold the bus
+// untill last ack received
+assign s_cmd_rd_en = (wbs_stb_o && wbs_we_o) ? wbs_ack_i: wbs_lack_i;
+
+// Write Interface
+// response send only for read logic
+assign s_resp_wr_en = wbs_stb_o & (!wbs_we_o) & wbs_ack_i ;
+assign s_resp_wr_data = {wbs_err_i,wbs_lack_i,wbs_dat_i};
+
+sync_fifo2 #(.W(CFW), .DP(4),.WR_FAST(1), .RD_FAST(1)) u_cmd_if (
+ // Sync w.r.t WR clock
+ .clk (clk_i ),
+ .reset_n (rst_n ),
+ .wr_en (m_cmd_wr_en ),
+ .wr_data (m_cmd_wr_data ),
+ .full (m_cmd_wr_full ),
+ .afull (m_cmd_wr_afull ),
+
+ // Sync w.r.t RD Clock
+ .rd_en (s_cmd_rd_en ),
+ .empty (s_cmd_rd_empty ), // sync'ed to rd_clk
+ .aempty (s_cmd_rd_aempty ), // sync'ed to rd_clk
+ .rd_data (s_cmd_rd_data )
+ );
+
+
+// Response used only for read path,
+// As cache access will be busrt of 512 location, To
+// support continous ack, depth is increase to 8 location
+sync_fifo2 #(.W(RFW), .DP(4), .WR_FAST(1), .RD_FAST(1)) u_resp_if (
+ // Sync w.r.t WR clock
+ .clk (clk_i ),
+ .reset_n (rst_n ),
+ .wr_en (s_resp_wr_en ),
+ .wr_data (s_resp_wr_data ),
+ .full (s_resp_wr_full ),
+ .afull (s_resp_wr_afull ),
+
+ // Sync w.r.t RD Clock
+ .rd_en (m_resp_rd_en ),
+ .empty (m_resp_rd_empty ), // sync'ed to rd_clk
+ .aempty (m_resp_rd_aempty ), // sync'ed to rd_clk
+ .rd_data (m_resp_rd_data )
+ );
+
+
+
+endmodule
diff --git a/verilog/rtl/lib/wb_interface.v b/verilog/rtl/lib/wb_interface.v
new file mode 100644
index 0000000..f25b147
--- /dev/null
+++ b/verilog/rtl/lib/wb_interface.v
@@ -0,0 +1,404 @@
+//////////////////////////////////////////////////////////////////////////////
+// SPDX-FileCopyrightText: 2021 , Dinesh Annayya
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+// SPDX-License-Identifier: Apache-2.0
+// SPDX-FileContributor: Created by Dinesh Annayya <dinesha@opencores.org>
+//
+//////////////////////////////////////////////////////////////////////
+//// ////
+//// yifive common library Module ////
+//// ////
+//// This file is part of the yifive cores project ////
+//// https://github.com/dineshannayya/yifive_r0.git ////
+//// http://www.opencores.org/cores/yifive/ ////
+//// ////
+//// Description: ////
+//// This module does the DMA to wishbone I/f ////
+//// ////
+//// To Do: ////
+//// nothing ////
+//// ////
+//// Author(s): ////
+//// - Dinesh Annayya, dinesha@opencores.org ////
+//// ////
+//// Revision : ////
+//// v0: Nov 26, 2016, Dinesh A ////
+//// This files copied from my open core ////
+//// turbo8051 project ////
+//// ////
+//////////////////////////////////////////////////////////////////////
+//// ////
+//// Copyright (C) 2000 Authors and OPENCORES.ORG ////
+//// ////
+//// This source file may be used and distributed without ////
+//// restriction provided that this copyright statement is not ////
+//// removed from the file and that any derivative work contains ////
+//// the original copyright notice and the associated disclaimer. ////
+//// ////
+//// This source file is free software; you can redistribute it ////
+//// and/or modify it under the terms of the GNU Lesser General ////
+//// Public License as published by the Free Software Foundation; ////
+//// either version 2.1 of the License, or (at your option) any ////
+//// later version. ////
+//// ////
+//// This source is distributed in the hope that it will be ////
+//// useful, but WITHOUT ANY WARRANTY; without even the implied ////
+//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR ////
+//// PURPOSE. See the GNU Lesser General Public License for more ////
+//// details. ////
+//// ////
+//// You should have received a copy of the GNU Lesser General ////
+//// Public License along with this source; if not, download it ////
+//// from http://www.opencores.org/lgpl.shtml ////
+//// ////
+//////////////////////////////////////////////////////////////////////
+
+module wb_interface (
+ rst ,
+ clk ,
+
+ dma_req_i ,
+ dma_write_i ,
+ dma_addr_i ,
+ dma_length_i ,
+ dma_ack_o ,
+ dma_done_o ,
+
+ dma_start_o ,
+ dma_wr_o ,
+ dma_rd_o ,
+ dma_last_o ,
+ dma_wdata_i ,
+ dma_rdata_o ,
+
+ // external memory
+ wbd_dat_i ,
+ wbd_dat_o ,
+ wbd_adr_o ,
+ wbd_be_o ,
+ wbd_we_o ,
+ wbd_ack_i ,
+ wbd_stb_o ,
+ wbd_cyc_o ,
+ wbd_err_i
+
+
+ );
+
+
+
+input rst ;
+input clk ;
+
+input dma_req_i ;
+input dma_write_i ;
+input [25:0] dma_addr_i ;
+input [7:0] dma_length_i ;
+output dma_ack_o ;
+output dma_done_o ; // indicates end of DMA transaction
+
+output dma_start_o ;
+output dma_wr_o ;
+output dma_rd_o ;
+output dma_last_o ;
+input [31:0] dma_wdata_i ;
+output [31:0] dma_rdata_o ;
+
+//--------------------------------
+// WB interface
+//--------------------------------
+input [31:0] wbd_dat_i ; // data input
+output [31:0] wbd_dat_o ; // data output
+output [23:0] wbd_adr_o ; // address
+output [3:0] wbd_be_o ; // byte enable
+output wbd_we_o ; // write
+input wbd_ack_i ; // acknowlegement
+output wbd_stb_o ; // strobe/request
+output wbd_cyc_o ; // wb cycle
+input wbd_err_i ; // we error
+
+//------------------------------------
+// Reg Declaration
+//--------------------------------
+reg [2:0] state ;
+reg [2:0] state_d ;
+reg [7:0] preq_len ; // pending request length in bytes
+reg wbd_we_o ; // westbone write req
+reg [23:0] wbd_adr_o ; // westnone address
+reg dma_ack_o ; // dma ack
+reg [7:0] twbtrans ; // total westbone transaction
+reg dma_wr_o ; // dma write request
+reg dma_rd_o ; // dma read request
+reg [31:0] temp_data ; // temp holding data
+reg [1:0] be_sof ; // Byte enable starting alignment
+reg [31:0] wbd_dat_o ; // westbone data out
+reg [3:0] wbd_be_o ; // west bone byte enable
+reg [31:0] dma_rdata_o ; // dma read data
+reg wbd_stb_o ;
+reg dma_start_o ; // dma first transfer
+reg dma_last_o ; // dma last transfer
+
+parameter WB_IDLE = 3'b000;
+parameter WB_REQ = 3'b001;
+parameter WB_WR_PHASE = 3'b010;
+parameter WB_RD_PHASE_SOF = 3'b011;
+parameter WB_RD_PHASE_CONT = 3'b100;
+
+assign dma_done_o = (state == WB_IDLE) && (state_d != WB_IDLE);
+
+always @(posedge rst or posedge clk)
+begin
+ if(rst) begin
+ state <= WB_IDLE;
+ state_d <= WB_IDLE;
+ wbd_we_o <= 0;
+ wbd_adr_o <= 0;
+ preq_len <= 0;
+ dma_ack_o <= 0;
+ twbtrans <= 0;
+ dma_wr_o <= 0;
+ dma_rd_o <= 0;
+ temp_data <= 0;
+ be_sof <= 0;
+ wbd_dat_o <= 0;
+ wbd_be_o <= 0;
+ dma_rdata_o <= 0;
+ wbd_stb_o <= 0;
+ dma_start_o <= 0;
+ dma_last_o <= 0;
+ end
+ else begin
+ state_d <= state;
+ case(state)
+ WB_IDLE :
+ begin
+ if(dma_req_i)
+ begin
+ dma_ack_o <= 1;
+ wbd_we_o <= dma_write_i;
+ wbd_adr_o <= dma_addr_i[25:2];
+ be_sof <= dma_addr_i[1] << 1 + dma_addr_i[0];
+ preq_len <= dma_length_i;
+ // total wb transfer
+ twbtrans <= dma_length_i[7:2] +
+ |(dma_length_i[1:0]) +
+ |(dma_addr_i[1:0]);
+ state <= WB_REQ;
+ end
+ dma_wr_o <= 0;
+ dma_rd_o <= 0;
+ wbd_stb_o <= 0;
+ dma_start_o <= 0;
+ end
+ WB_REQ :
+ begin
+ dma_ack_o <= 0;
+ wbd_stb_o <= 1;
+ if(wbd_we_o) begin
+ dma_wr_o <= 1;
+ dma_start_o <= 1;
+ temp_data <= dma_wdata_i;
+ if(be_sof == 0) begin
+ wbd_dat_o <= dma_wdata_i;
+ wbd_be_o <= 4'b1111;
+ preq_len <= preq_len - 4;
+ end
+ else if(be_sof == 1) begin
+ wbd_dat_o <= {dma_wdata_i[23:0],8'h0};
+ wbd_be_o <= 4'b1110;
+ preq_len <= preq_len - 3;
+ end
+ else if(be_sof == 2) begin
+ wbd_dat_o <= {dma_wdata_i[15:0],16'h0};
+ wbd_be_o <= 4'b1100;
+ preq_len <= preq_len - 2;
+ end
+ else begin
+ wbd_dat_o <= {dma_wdata_i[7:0],23'h0};
+ wbd_be_o <= 4'b1000;
+ preq_len <= preq_len - 1;
+ end
+ twbtrans <= twbtrans -1;
+ state <= WB_WR_PHASE;
+ if(twbtrans == 1)
+ dma_last_o <= 1;
+ end
+ else begin
+ state <= WB_RD_PHASE_SOF;
+ end
+ end
+ WB_WR_PHASE :
+ begin
+ dma_start_o <= 0;
+ if(wbd_ack_i) begin
+ if(twbtrans == 1)
+ dma_last_o <= 1;
+ else
+ dma_last_o <= 0;
+ if(twbtrans > 0) begin
+ temp_data <= dma_wdata_i;
+ twbtrans <= twbtrans -1;
+ if(be_sof == 0) begin
+ wbd_dat_o <= dma_wdata_i;
+ end
+ else if(be_sof == 1) begin
+ wbd_dat_o <= {dma_wdata_i[23:0],temp_data[31:24]};
+ end
+ else if(be_sof == 2) begin
+ wbd_dat_o <= {dma_wdata_i[15:0],temp_data[31:16]};
+ end
+ else begin
+ wbd_dat_o <= {dma_wdata_i[7:0],temp_data[31:8]};
+ end
+
+ if(twbtrans > 1) begin // If the Pending Transfer is more than 1
+ dma_wr_o <= 1;
+ wbd_be_o <= 4'b1111;
+ preq_len <= preq_len - 4;
+ end
+ else begin // for last write access
+ wbd_be_o <= preq_len[1:0] == 2'b00 ? 4'b1111:
+ preq_len[1:0] == 2'b01 ? 4'b0001:
+ preq_len[1:0] == 2'b10 ? 4'b0011: 4'b0111;
+
+ case({be_sof[1:0],preq_len[1:0]})
+ // Start alignment = 0
+ 4'b0001 : dma_wr_o <= 1;
+ 4'b0010 : dma_wr_o <= 1;
+ 4'b0011 : dma_wr_o <= 1;
+ 4'b0000 : dma_wr_o <= 1;
+ // Start alignment = 1
+ 4'b0101 : dma_wr_o <= 0;
+ 4'b0110 : dma_wr_o <= 1;
+ 4'b0111 : dma_wr_o <= 1;
+ 4'b0100 : dma_wr_o <= 1;
+ // Start alignment = 2
+ 4'b1001 : dma_wr_o <= 0;
+ 4'b1010 : dma_wr_o <= 0;
+ 4'b1011 : dma_wr_o <= 1;
+ 4'b1000 : dma_wr_o <= 1;
+ // Start alignment = 3
+ 4'b1101 : dma_wr_o <= 0;
+ 4'b1110 : dma_wr_o <= 0;
+ 4'b1111 : dma_wr_o <= 0;
+ 4'b1100 : dma_wr_o <= 1;
+ endcase
+ end
+ end
+ else begin
+ dma_wr_o <= 0;
+ wbd_stb_o <= 0;
+ state <= WB_IDLE;
+ end
+ end
+ else begin
+ dma_last_o <= 0;
+ dma_wr_o <= 0;
+ end
+ end
+ WB_RD_PHASE_SOF :
+ begin
+ if(wbd_ack_i) begin
+ twbtrans <= twbtrans -1;
+ if(twbtrans == 1) begin // If the Pending Transfer is 1
+ dma_rd_o <= 1;
+ dma_start_o<= 1;
+ if(be_sof == 0) begin
+ dma_rdata_o <= wbd_dat_i;
+ preq_len <= preq_len - 4;
+ end
+ else if(be_sof == 1) begin
+ dma_rdata_o <= {8'h0,wbd_dat_i[31:24]};
+ preq_len <= preq_len - 3;
+ end
+ else if(be_sof == 2) begin
+ dma_rdata_o <= {16'h0,wbd_dat_i[31:16]};
+ preq_len <= preq_len - 2;
+ end
+ else begin
+ dma_rdata_o <= {23'h0,wbd_dat_i[31:8]};
+ preq_len <= preq_len - 0;
+ end
+ dma_last_o <= 1;
+ state <= WB_IDLE;
+ end
+ else begin // pending transction is more than 1
+ if(be_sof == 0) begin
+ dma_rdata_o <= wbd_dat_i;
+ dma_rd_o <= 1;
+ dma_start_o <= 1;
+ preq_len <= preq_len - 4;
+ end
+ else if(be_sof == 1) begin
+ temp_data <= {8'h0,wbd_dat_i[31:24]};
+ dma_rd_o <= 0;
+ preq_len <= preq_len - 3;
+ end
+ else if(be_sof == 2) begin
+ temp_data <= {16'h0,wbd_dat_i[31:16]};
+ preq_len <= preq_len - 2;
+ end
+ else begin
+ temp_data <= {23'h0,wbd_dat_i[31:8]};
+ preq_len <= preq_len - 0;
+ end
+ state <= WB_RD_PHASE_CONT;
+ end
+ end
+ else begin
+ dma_rd_o <= 0;
+ end
+ end
+ WB_RD_PHASE_CONT:
+ begin
+ dma_start_o <= 0;
+ if(wbd_ack_i) begin
+ dma_rd_o <= 1;
+ twbtrans <= twbtrans -1;
+ if(be_sof == 0) begin
+ dma_rdata_o <= wbd_dat_i;
+ preq_len <= preq_len - 4;
+ end
+ else if(be_sof == 1) begin
+ dma_rdata_o <= {wbd_dat_i[7:0],temp_data[23:0]};
+ temp_data <= {8'h0,wbd_dat_i[31:8]};
+ preq_len <= preq_len - 3;
+ end
+ else if(be_sof == 2) begin
+ dma_rdata_o <= {wbd_dat_i[15:0],temp_data[15:0]};
+ temp_data <= {16'h0,wbd_dat_i[31:16]};
+ preq_len <= preq_len - 2;
+ end
+ else begin
+ dma_rdata_o <= {wbd_dat_i[23:0],temp_data[7:0]};
+ temp_data <= {24'h0,wbd_dat_i[31:23]};
+ preq_len <= preq_len - 1;
+ end
+ if(twbtrans == 1) begin // If the it's last transfer
+ dma_last_o <= 1;
+ state <= WB_IDLE;
+ end
+ end
+ else begin
+ dma_last_o <= 0;
+ dma_rd_o <= 0;
+ end
+ end
+ endcase
+ end
+end
+
+
+
+endmodule
diff --git a/verilog/rtl/lib/wb_stagging.sv b/verilog/rtl/lib/wb_stagging.sv
new file mode 100644
index 0000000..2661005
--- /dev/null
+++ b/verilog/rtl/lib/wb_stagging.sv
@@ -0,0 +1,192 @@
+//////////////////////////////////////////////////////////////////////////////
+// SPDX-FileCopyrightText: 2021 , Dinesh Annayya
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+// SPDX-License-Identifier: Apache-2.0
+// SPDX-FileContributor: Created by Dinesh Annayya <dinesha@opencores.org>
+//
+//----------------------------------------------------------------------
+// This logic create a holding register for Wishbone interface.
+// This is usefull to break timing issue at interconnect
+//
+// Limitation: Due to stagging FF, Continous Burst of Wishbone will have one
+// cycle break between each transaction
+//----------------------------------------------------------------------
+//////////////////////////////////////////////////////////////////////
+//// ////
+//// Wishbone Stagging FF ////
+//// ////
+//// This file is part of the YIFive cores project ////
+//// https://github.com/dineshannayya/yifive_r0.git ////
+//// http://www.opencores.org/cores/yifive/ ////
+//// ////
+//// Description ////
+//// This logic create a holding FF for Wishbone interface. ////
+//// This is usefull to break timing issue at interconnect ////
+//// ////
+//// Limitation: Due to stagging FF, Continous Burst of ////
+//// Wishbone will have one cycle break between each transaction ////
+//// ////
+//// To Do: ////
+//// nothing ////
+//// ////
+//// Author(s): ////
+//// - Dinesh Annayya, dinesha@opencores.org ////
+//// ////
+//// Revision : ////
+//// 0.1 - 12th June 2021, Dinesh A ////
+//// ////
+//////////////////////////////////////////////////////////////////////
+//// ////
+//// Copyright (C) 2000 Authors and OPENCORES.ORG ////
+//// ////
+//// This source file may be used and distributed without ////
+//// restriction provided that this copyright statement is not ////
+//// removed from the file and that any derivative work contains ////
+//// the original copyright notice and the associated disclaimer. ////
+//// ////
+//// This source file is free software; you can redistribute it ////
+//// and/or modify it under the terms of the GNU Lesser General ////
+//// Public License as published by the Free Software Foundation; ////
+//// either version 2.1 of the License, or (at your option) any ////
+//// later version. ////
+//// ////
+//// This source is distributed in the hope that it will be ////
+//// useful, but WITHOUT ANY WARRANTY; without even the implied ////
+//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR ////
+//// PURPOSE. See the GNU Lesser General Public License for more ////
+//// details. ////
+//// ////
+//// You should have received a copy of the GNU Lesser General ////
+//// Public License along with this source; if not, download it ////
+//// from http://www.opencores.org/lgpl.shtml ////
+//// ////
+//////////////////////////////////////////////////////////////////////
+
+
+module wb_stagging (
+ input logic clk_i,
+ input logic rst_n,
+ // WishBone Input master I/P
+ input logic [31:0] m_wbd_dat_i,
+ input logic [31:0] m_wbd_adr_i,
+ input logic [3:0] m_wbd_sel_i,
+ input logic [9:0] m_wbd_bl_i,
+ input logic m_wbd_bry_i,
+ input logic m_wbd_we_i,
+ input logic m_wbd_cyc_i,
+ input logic m_wbd_stb_i,
+ input logic [3:0] m_wbd_tid_i,
+ output logic [31:0] m_wbd_dat_o,
+ output logic m_wbd_ack_o,
+ output logic m_wbd_lack_o,
+ output logic m_wbd_err_o,
+
+ // Slave Interface
+ input logic [31:0] s_wbd_dat_i,
+ input logic s_wbd_ack_i,
+ input logic s_wbd_lack_i,
+ input logic s_wbd_err_i,
+ output logic [31:0] s_wbd_dat_o,
+ output logic [31:0] s_wbd_adr_o,
+ output logic [3:0] s_wbd_sel_o,
+ output logic [9:0] s_wbd_bl_o,
+ output logic s_wbd_bry_o,
+ output logic s_wbd_we_o,
+ output logic s_wbd_cyc_o,
+ output logic s_wbd_stb_o,
+ output logic [3:0] s_wbd_tid_o
+
+);
+
+logic [31:0] m_wbd_dat_i_ff ; // Flopped vesion of m_wbd_dat_i
+logic [31:0] m_wbd_adr_i_ff ; // Flopped vesion of m_wbd_adr_i
+logic [3:0] m_wbd_sel_i_ff ; // Flopped vesion of m_wbd_sel_i
+logic [9:0] m_wbd_bl_i_ff ; // Flopped vesion of m_wbd_bl_i
+logic m_wbd_bry_i_ff ; // Flopped vesion of m_wbd_bry_i
+logic m_wbd_we_i_ff ; // Flopped vesion of m_wbd_we_i
+logic m_wbd_cyc_i_ff ; // Flopped vesion of m_wbd_cyc_i
+logic m_wbd_stb_i_ff ; // Flopped vesion of m_wbd_stb_i
+logic [3:0] m_wbd_tid_i_ff ; // Flopped vesion of m_wbd_tid_i
+logic [31:0] s_wbd_dat_i_ff ; // Flopped vesion of s_wbd_dat_i
+logic s_wbd_ack_i_ff ; // Flopped vesion of s_wbd_ack_i
+logic s_wbd_lack_i_ff ; // Flopped vesion of s_wbd_ack_i
+logic s_wbd_err_i_ff ; // Flopped vesion of s_wbd_err_i
+
+
+assign s_wbd_dat_o = m_wbd_dat_i_ff;
+assign s_wbd_adr_o = m_wbd_adr_i_ff;
+assign s_wbd_sel_o = m_wbd_sel_i_ff;
+assign s_wbd_bl_o = m_wbd_bl_i_ff;
+assign s_wbd_bry_o = m_wbd_bry_i_ff;
+assign s_wbd_we_o = m_wbd_we_i_ff;
+assign s_wbd_cyc_o = m_wbd_cyc_i_ff;
+assign s_wbd_stb_o = m_wbd_stb_i_ff;
+assign s_wbd_tid_o = m_wbd_tid_i_ff;
+
+assign m_wbd_dat_o = s_wbd_dat_i_ff;
+assign m_wbd_ack_o = s_wbd_ack_i_ff;
+assign m_wbd_lack_o = s_wbd_lack_i_ff;
+assign m_wbd_err_o = s_wbd_err_i_ff;
+
+always @(negedge rst_n or posedge clk_i)
+begin
+ if(rst_n == 1'b0) begin
+ m_wbd_dat_i_ff <= 'h0;
+ m_wbd_adr_i_ff <= 'h0;
+ m_wbd_sel_i_ff <= 'h0;
+ m_wbd_bl_i_ff <= 'h0;
+ m_wbd_bry_i_ff <= 'b0;
+ m_wbd_we_i_ff <= 'h0;
+ m_wbd_cyc_i_ff <= 'h0;
+ m_wbd_stb_i_ff <= 'h0;
+ m_wbd_tid_i_ff <= 'h0;
+ s_wbd_dat_i_ff <= 'h0;
+ s_wbd_ack_i_ff <= 'h0;
+ s_wbd_lack_i_ff <= 'h0;
+ s_wbd_err_i_ff <= 'h0;
+ end else begin
+ s_wbd_dat_i_ff <= s_wbd_dat_i;
+ s_wbd_ack_i_ff <= s_wbd_ack_i;
+ s_wbd_lack_i_ff <= s_wbd_lack_i;
+ s_wbd_err_i_ff <= s_wbd_err_i;
+ if((m_wbd_stb_i && m_wbd_bry_i && s_wbd_ack_i == 0 && m_wbd_lack_o == 0) ||
+ (m_wbd_stb_i && m_wbd_bry_i && s_wbd_ack_i == 1 && s_wbd_lack_i == 0)) begin
+ m_wbd_dat_i_ff <= m_wbd_dat_i;
+ m_wbd_adr_i_ff <= m_wbd_adr_i;
+ m_wbd_sel_i_ff <= m_wbd_sel_i;
+ m_wbd_we_i_ff <= m_wbd_we_i;
+ m_wbd_cyc_i_ff <= m_wbd_cyc_i;
+ m_wbd_stb_i_ff <= m_wbd_stb_i;
+ m_wbd_tid_i_ff <= m_wbd_tid_i;
+ m_wbd_bl_i_ff <= m_wbd_bl_i;
+ m_wbd_bry_i_ff <= 'b1;
+ end else if ((m_wbd_stb_i && !m_wbd_bry_i && s_wbd_ack_i == 1 && s_wbd_lack_i == 0)) begin // De-Assert burst ready
+ m_wbd_bry_i_ff <= 'b0;
+ end else if (s_wbd_lack_i) begin
+ m_wbd_dat_i_ff <= 'h0;
+ m_wbd_adr_i_ff <= 'h0;
+ m_wbd_sel_i_ff <= 'h0;
+ m_wbd_we_i_ff <= 'h0;
+ m_wbd_cyc_i_ff <= 'h0;
+ m_wbd_stb_i_ff <= 'h0;
+ m_wbd_tid_i_ff <= 'h0;
+ m_wbd_bl_i_ff <= 'h0;
+ m_wbd_bry_i_ff <= 'b0;
+ end
+ end
+end
+
+
+endmodule
+
diff --git a/verilog/rtl/mbist/include/mbist_def.svh b/verilog/rtl/mbist/include/mbist_def.svh
new file mode 100644
index 0000000..10fb2ea
--- /dev/null
+++ b/verilog/rtl/mbist/include/mbist_def.svh
@@ -0,0 +1,66 @@
+///////////////////////////////////////////////////////////////////////
+// SPDX-FileCopyrightText: 2021 , Dinesh Annayya
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+// SPDX-License-Identifier: Apache-2.0
+// SPDX-FileContributor: Created by Dinesh Annayya <dinesha@opencores.org>
+//
+//////////////////////////////////////////////////////////////////////
+`ifndef BIST_DEFINE_SVH
+`define BIST_DEFINE_SVH
+
+// BIST ADDRESS CONTRL
+//
+//parameter BIST_ADDR_WD = 9 ;
+//parameter BIST_ADDR_START = 10'h000 ;
+//parameter BIST_ADDR_END = 10'h3FB ;
+
+// BIST DATA CONTRL
+//parameter BIST_DATA_WD = 32;
+parameter BIST_DATA_PAT_SIZE = 8;
+parameter BIST_DATA_PAT_TYPE1 = 64'h5555_5555_5555_5555;
+parameter BIST_DATA_PAT_TYPE2 = 64'h3333_3333_3333_3333;
+parameter BIST_DATA_PAT_TYPE3 = 64'h0F0F_0F0F_0F0F_0F0F;
+parameter BIST_DATA_PAT_TYPE4 = 64'h00FF_00FF_00FF_00FF;
+parameter BIST_DATA_PAT_TYPE5 = 64'h0000_FFFF_0000_FFFF;
+parameter BIST_DATA_PAT_TYPE6 = 64'h0000_0000_FFFF_FFFF;
+parameter BIST_DATA_PAT_TYPE7 = 64'hFFFF_FFFF_FFFF_FFFF;
+parameter BIST_DATA_PAT_TYPE8 = 64'h0000_0000_0000_0000;
+
+// BIST STIMULATION SELECT
+
+parameter BIST_STI_SIZE = 5;
+parameter BIST_STI_WD = 15;
+// Additional 3'b000 added at end of each stimulus to flush out the comparion
+// result + to handle error fix case
+parameter BIST_STIMULUS_TYPE1 = 15'b100100100100000;
+parameter BIST_STIMULUS_TYPE2 = 15'b100010101011000;
+parameter BIST_STIMULUS_TYPE3 = 15'b110011100010000;
+parameter BIST_STIMULUS_TYPE4 = 15'b000010101011000;
+parameter BIST_STIMULUS_TYPE5 = 15'b010011100010000;
+parameter BIST_STIMULUS_TYPE6 = 15'b000000000000000;
+parameter BIST_STIMULUS_TYPE7 = 15'b000000000000000;
+parameter BIST_STIMULUS_TYPE8 = 15'b000000000000000;
+
+
+// Operation
+parameter BIST_OP_SIZE = 4;
+
+// BIST ADDRESS REPAIR
+//parameter BIST_RAD_WD_I = BIST_ADDR_WD;
+//parameter BIST_RAD_WD_O = BIST_ADDR_WD;
+parameter BIST_ERR_LIMIT = 4;
+// Make Sure that this address in outside the valid address range
+//parameter BIST_REPAIR_ADDR_START = 10'h3FC ;
+
+`endif // BIST_DEFINE_SVH
diff --git a/verilog/rtl/mbist/run_iverilog b/verilog/rtl/mbist/run_iverilog
new file mode 100755
index 0000000..f5f5020
--- /dev/null
+++ b/verilog/rtl/mbist/run_iverilog
@@ -0,0 +1,17 @@
+iverilog -g2005-sv -DFUNCTIONAL -D UNIT_DELAY=#0.1 \
+src/top/mbist_top.sv \
+src/core/mbist_addr_gen.sv \
+src/core/mbist_fsm.sv \
+src/core/mbist_op_sel.sv \
+src/core/mbist_repair_addr.sv \
+src/core/mbist_data_cmp.sv \
+src/core/mbist_mux.sv \
+src/core/mbist_pat_sel.sv \
+src/core/mbist_sti_sel.sv \
+src/core/mbist_mem_wrapper.sv \
+-I include/ \
+../lib/ctech_cells.sv \
+../lib/reset_sync.sv \
+../clk_skew_adjust/src/clk_skew_adjust.gv \
+$PDK_ROOT/sky130A/libs.ref/sky130_fd_sc_hd/verilog/sky130_fd_sc_hd.v \
+$PDK_ROOT/sky130A/libs.ref/sky130_fd_sc_hd/verilog/primitives.v
diff --git a/verilog/rtl/mbist/run_verilator b/verilog/rtl/mbist/run_verilator
new file mode 100755
index 0000000..1dd5d6b
--- /dev/null
+++ b/verilog/rtl/mbist/run_verilator
@@ -0,0 +1,17 @@
+verilator -cc \
+src/top/mbist_top1.sv \
+src/core/mbist_addr_gen.sv \
+src/core/mbist_fsm.sv \
+src/core/mbist_op_sel.sv \
+src/core/mbist_repair_addr.sv \
+src/core/mbist_data_cmp.sv \
+src/core/mbist_mux.sv \
+src/core/mbist_pat_sel.sv \
+src/core/mbist_sti_sel.sv \
++incdir+include/ \
+../lib/ctech_cells.sv \
+../lib/reset_sync.sv \
+-v $PDK_ROOT/sky130A/libs.ref/sky130_fd_sc_hd/verilog/sky130_fd_sc_hd.v \
+-v $PDK_ROOT/sky130A/libs.ref/sky130_fd_sc_hd/verilog/primitives.v \
+--timescale 1ns/100ps \
+--bbox-unsup
diff --git a/verilog/rtl/mbist/src/core/mbist_addr_gen.sv b/verilog/rtl/mbist/src/core/mbist_addr_gen.sv
new file mode 100644
index 0000000..ffcf42c
--- /dev/null
+++ b/verilog/rtl/mbist/src/core/mbist_addr_gen.sv
@@ -0,0 +1,116 @@
+///////////////////////////////////////////////////////////////////////
+// SPDX-FileCopyrightText: 2021 , Dinesh Annayya
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+// SPDX-License-Identifier: Apache-2.0
+// SPDX-FileContributor: Created by Dinesh Annayya <dinesha@opencores.org>
+//
+//////////////////////////////////////////////////////////////////////
+//// ////
+//// MBIST Address Generator ////
+//// ////
+//// This file is part of the mbist_ctrl cores project ////
+//// https://github.com/dineshannayya/mbist_ctrl.git ////
+//// ////
+//// Description ////
+//// This block integrate mbist address gen ////
+//// ////
+//// To Do: ////
+//// nothing ////
+//// ////
+//// Author(s): ////
+//// - Dinesh Annayya, dinesha@opencores.org ////
+//// ////
+//// Revision : ////
+//// 0.0 - 11th Oct 2021, Dinesh A ////
+//// Initial integration ////
+//// ////
+//////////////////////////////////////////////////////////////////////
+
+`include "mbist_def.svh"
+
+module mbist_addr_gen
+ #( parameter BIST_ADDR_WD = 9,
+ parameter BIST_DATA_WD = 32,
+ parameter BIST_ADDR_START = 9'h000,
+ parameter BIST_ADDR_END = 9'h1F8,
+ parameter BIST_REPAIR_ADDR_START = 9'h1FC,
+ parameter BIST_RAD_WD_I = BIST_ADDR_WD,
+ parameter BIST_RAD_WD_O = BIST_ADDR_WD) (
+
+ output logic last_addr, // Last address access
+ output logic [BIST_ADDR_WD-1:0] bist_addr, // Bist Address
+ output logic sdo, // scan data output
+ input logic clk, // clock input
+ input logic rst_n, // asynchronous reset
+ input logic run, // stop or start state machine
+ input logic updown, // count up or down
+ input logic bist_shift, // shift scan input
+ input logic bist_load, // load scan input
+ input logic sdi // scan data input
+
+);
+
+
+logic [BIST_ADDR_WD-1:0] next_addr; // Next Address
+logic [BIST_ADDR_WD-1:0] start_addr; // Address Start Address
+logic [BIST_ADDR_WD-1:0] end_addr; // Address Stop Address
+
+
+assign last_addr = (((updown == 1'b1)&&(bist_addr == end_addr))||((updown == 1'b0)&&(bist_addr == start_addr)))?1'b1:1'b0;
+
+
+/******************************
+ Address register
+ Basic Assumption: Allways counter start with upcounting
+*********************************/
+
+
+always @(posedge clk or negedge rst_n) begin
+ if(!rst_n) bist_addr <= BIST_ADDR_START ;
+ else if(bist_load) bist_addr <= start_addr;
+ else bist_addr <= next_addr;
+end
+
+/* Input combinational block */
+
+always_comb begin
+ if(run) begin
+ if((bist_addr == end_addr)&&(updown == 1'b1))
+ next_addr = start_addr ;
+ else if((bist_addr == start_addr)&&(updown == 1'b0))
+ next_addr = end_addr ;
+ else next_addr = (updown)?bist_addr+1'b1:bist_addr-1'b1;
+ end
+ else next_addr = bist_addr;
+end
+
+
+/* Start register */
+
+always @(posedge clk or negedge rst_n) begin
+ if(!rst_n) start_addr <= BIST_ADDR_START ;
+ else if(bist_shift) start_addr <= {sdi, start_addr[BIST_ADDR_WD-1:1]};
+end
+
+/* Start register */
+always @(posedge clk or negedge rst_n) begin
+ if(!rst_n) end_addr <= BIST_ADDR_END ;
+ else if(bist_shift) end_addr <= {start_addr[0], end_addr[BIST_ADDR_WD-1:1]};
+end
+
+
+assign sdo = end_addr[0];
+
+endmodule
+
diff --git a/verilog/rtl/mbist/src/core/mbist_data_cmp.sv b/verilog/rtl/mbist/src/core/mbist_data_cmp.sv
new file mode 100644
index 0000000..45dd343
--- /dev/null
+++ b/verilog/rtl/mbist/src/core/mbist_data_cmp.sv
@@ -0,0 +1,116 @@
+///////////////////////////////////////////////////////////////////////
+// SPDX-FileCopyrightText: 2021 , Dinesh Annayya
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+// SPDX-License-Identifier: Apache-2.0
+// SPDX-FileContributor: Created by Dinesh Annayya <dinesha@opencores.org>
+//
+//////////////////////////////////////////////////////////////////////
+//// ////
+//// MBIST Data Comparator ////
+//// ////
+//// This file is part of the mbist_ctrl cores project ////
+//// https://github.com/dineshannayya/mbist_ctrl.git ////
+//// ////
+//// Description ////
+//// This block integrate mbist data comparator ////
+//// ////
+//// To Do: ////
+//// nothing ////
+//// ////
+//// Author(s): ////
+//// - Dinesh Annayya, dinesha@opencores.org ////
+//// ////
+//// Revision : ////
+//// 0.0 - 11th Oct 2021, Dinesh A ////
+//// Initial integration ////
+//// ////
+//////////////////////////////////////////////////////////////////////
+`include "mbist_def.svh"
+
+
+module mbist_data_cmp
+ #( parameter BIST_ADDR_WD = 9,
+ parameter BIST_DATA_WD = 32,
+ parameter BIST_ADDR_START = 9'h000,
+ parameter BIST_ADDR_END = 9'h1F8,
+ parameter BIST_REPAIR_ADDR_START = 9'h1FC,
+ parameter BIST_RAD_WD_I = BIST_ADDR_WD,
+ parameter BIST_RAD_WD_O = BIST_ADDR_WD) (
+
+ output logic error,
+ output logic error_correct,
+ output logic correct,
+ output logic [BIST_ADDR_WD-1:0] error_addr,
+ output logic [3:0] error_cnt,
+ input logic clk,
+ input logic rst_n,
+ input logic compare,
+ input logic addr_inc_phase,
+ input logic read_invert,
+ input logic [BIST_DATA_WD-1:0] comp_data,
+ input logic [BIST_DATA_WD-1:0] rxd_data,
+ input logic [BIST_ADDR_WD-1:0] addr
+
+ );
+
+logic mask_compare;
+logic [BIST_DATA_WD-1:0] exp_data;
+logic comp_status;
+
+assign exp_data = (read_invert) ? ~comp_data: comp_data;
+
+/* Comparison register */
+
+always @(posedge clk or negedge rst_n) begin
+ if(!rst_n) begin
+ comp_status <= 1'b0;
+ error_addr <= 'b0;
+ end else if(compare && !mask_compare) begin
+ comp_status <= |(exp_data ^ rxd_data);
+ error_addr <= addr;
+ end else begin
+ comp_status <= 1'b0;
+ end
+end
+
+// Due to cycle diference between compare and write opperation
+// There is chance two error reported for same address
+// To avoid this, once error is detected, comparision is masked
+// unit the next address phase
+always @(posedge clk or negedge rst_n) begin
+ if(!rst_n) begin
+ error_cnt <= 'b0;
+ correct <='b0;
+ mask_compare <= 'b0;
+ error <= '0;
+ end else if(mask_compare && addr_inc_phase) begin
+ mask_compare <= 1'b0;
+ end else if(comp_status && (error_cnt < BIST_ERR_LIMIT) ) begin
+ error_cnt <= error_cnt+1;
+ mask_compare <= 1'b1;
+ correct <='b1;
+ end else if(comp_status && (error_cnt == BIST_ERR_LIMIT) ) begin
+ error <= '1;
+ end
+end
+
+assign error_correct = (error_cnt < BIST_ERR_LIMIT) ? comp_status : 1'b0;
+
+endmodule
+
+
+
+
+
+
diff --git a/verilog/rtl/mbist/src/core/mbist_fsm.sv b/verilog/rtl/mbist/src/core/mbist_fsm.sv
new file mode 100644
index 0000000..7672ee7
--- /dev/null
+++ b/verilog/rtl/mbist/src/core/mbist_fsm.sv
@@ -0,0 +1,141 @@
+///////////////////////////////////////////////////////////////////////
+// SPDX-FileCopyrightText: 2021 , Dinesh Annayya
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+// SPDX-License-Identifier: Apache-2.0
+// SPDX-FileContributor: Created by Dinesh Annayya <dinesha@opencores.org>
+//
+//////////////////////////////////////////////////////////////////////
+//// ////
+//// MBIST Main control FSM ////
+//// ////
+//// This file is part of the mbist_ctrl cores project ////
+//// https://github.com/dineshannayya/mbist_ctrl.git ////
+//// ////
+//// Description ////
+//// MBIST Main control FSM to control Command, Address, Write ////
+//// and Read compare phase ////
+//// ////
+//// To Do: ////
+//// nothing ////
+//// ////
+//// Author(s): ////
+//// - Dinesh Annayya, dinesha@opencores.org ////
+//// ////
+//// Revision : ////
+//// 0.0 - 11th Oct 2021, Dinesh A ////
+//// Initial integration ////
+//// ////
+//////////////////////////////////////////////////////////////////////
+module mbist_fsm
+ #( parameter BIST_ADDR_WD = 9,
+ parameter BIST_DATA_WD = 32,
+ parameter BIST_ADDR_START = 9'h000,
+ parameter BIST_ADDR_END = 9'h1F8,
+ parameter BIST_REPAIR_ADDR_START = 9'h1FC,
+ parameter BIST_RAD_WD_I = BIST_ADDR_WD,
+ parameter BIST_RAD_WD_O = BIST_ADDR_WD) (
+
+ output logic cmd_phase, // Command Phase
+ output logic cmp_phase, // Compare Phase
+ output logic run_op, // Move to Next Operation
+ output logic run_addr, // Move to Next Address
+ output logic run_sti, // Move to Next Stimulus
+ output logic run_pat, // Move to next pattern
+ output logic bist_done, // Bist Test Done
+
+
+ input logic clk, // Clock
+ input logic rst_n, // Reset
+ input logic bist_run, // Bist Run
+ input logic bist_error, // Bist Error
+ input logic op_reverse, // Address Reverse in Next Cycle
+ input logic last_op, // Last Operation
+ input logic last_addr, // Last Address
+ input logic last_sti, // Last Stimulus
+ input logic last_pat // Last Pattern
+
+
+);
+
+parameter FSM_PHASE1 = 2'b00;
+parameter FSM_PHASE2 = 2'b01;
+parameter FSM_EXIT = 2'b10;
+
+logic [1:0] state;
+
+
+
+always @(posedge clk or negedge rst_n)
+begin
+ if(!rst_n) begin
+ cmd_phase <= 0;
+ cmp_phase <= 0;
+ run_op <= 0;
+ run_addr <= 0;
+ run_sti <= 0;
+ run_pat <= 0;
+ bist_done <= 0;
+ state <= FSM_PHASE1;
+ end else if(bist_run) begin
+ case(state)
+ FSM_PHASE1 :
+ begin
+ cmd_phase <= 1;
+ cmp_phase <= 0;
+ run_op <= 0;
+ run_addr <= 0;
+ run_sti <= 0;
+ run_pat <= 0;
+ state <= FSM_PHASE2;
+ end
+ FSM_PHASE2 :
+ begin
+ if((last_addr && last_op && last_sti && last_pat) || bist_error) begin
+ cmd_phase <= 0;
+ cmp_phase <= 0;
+ run_op <= 0;
+ run_addr <= 0;
+ run_sti <= 0;
+ run_pat <= 0;
+ state <= FSM_EXIT;
+ end else begin
+ cmd_phase <= 0;
+ cmp_phase <= 1;
+ run_op <= 1;
+ if(last_op && !(last_addr && op_reverse))
+ run_addr <= 1;
+ if(last_addr && last_op)
+ run_sti <= 1;
+ if(last_addr && last_op && last_sti)
+ run_pat <= 1;
+ state <= FSM_PHASE1;
+ end
+ end
+ FSM_EXIT: bist_done <= 1;
+ default: state <= FSM_PHASE1;
+ endcase
+ end else begin
+ cmd_phase <= 0;
+ cmp_phase <= 0;
+ run_op <= 0;
+ run_addr <= 0;
+ run_sti <= 0;
+ run_pat <= 0;
+ state <= FSM_PHASE1;
+ end
+end
+
+
+
+endmodule
diff --git a/verilog/rtl/mbist/src/core/mbist_mem_wrapper.sv b/verilog/rtl/mbist/src/core/mbist_mem_wrapper.sv
new file mode 100644
index 0000000..8f31671
--- /dev/null
+++ b/verilog/rtl/mbist/src/core/mbist_mem_wrapper.sv
@@ -0,0 +1,102 @@
+//////////////////////////////////////////////////////////////////////////////
+// SPDX-FileCopyrightText: 2021 , Dinesh Annayya
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+// SPDX-License-Identifier: Apache-2.0
+// SPDX-FileContributor: Created by Dinesh Annayya <dinesha@opencores.org>
+//
+//////////////////////////////////////////////////////////////////////
+//// ////
+//// Memory wrapper ////
+//// ////
+//// This file is part of the mbist_ctrl project ////
+//// https://github.com/dineshannayya/mbist_ctrl.git ////
+//// ////
+//// Description ////
+//// This block does wishbone to SRAM signal mapping ////
+//// ////
+//// To Do: ////
+//// nothing ////
+//// ////
+//// Author(s): ////
+//// - Dinesh Annayya, dinesha@opencores.org ////
+//// ////
+//// Revision : ////
+//// 0.1 - 18 Nov 2021, Dinesh A ////
+//// initial version ////
+//////////////////////////////////////////////////////////////////////
+//// ////
+//// Copyright (C) 2000 Authors and OPENCORES.ORG ////
+//// ////
+//// This source file may be used and distributed without ////
+//// restriction provided that this copyright statement is not ////
+//// removed from the file and that any derivative work contains ////
+//// the original copyright notice and the associated disclaimer. ////
+//// ////
+//// This source file is free software; you can redistribute it ////
+//// and/or modify it under the terms of the GNU Lesser General ////
+//// Public License as published by the Free Software Foundation; ////
+//// either version 2.1 of the License, or (at your option) any ////
+//// later version. ////
+//// ////
+//// This source is distributed in the hope that it will be ////
+//// useful, but WITHOUT ANY WARRANTY; without even the implied ////
+//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR ////
+//// PURPOSE. See the GNU Lesser General Public License for more ////
+//// details. ////
+//// ////
+//// You should have received a copy of the GNU Lesser General ////
+//// Public License along with this source; if not, download it ////
+//// from http://www.opencores.org/lgpl.shtml ////
+//// ////
+//////////////////////////////////////////////////////////////////////
+module mbist_mem_wrapper #(
+ parameter BIST_NO_SRAM=4,
+ parameter BIST_ADDR_WD=10,
+ parameter BIST_DATA_WD=32) (
+ input logic rst_n ,
+ // WB I/F
+ input logic [(BIST_NO_SRAM+1)/2-1:0] sram_id ,
+ input logic wb_clk_i , // System clock
+ input logic [(BIST_NO_SRAM+1)/2-1:0] mem_cs , // Chip Select
+ input logic mem_req , // strobe/request
+ input logic [BIST_ADDR_WD-1:0] mem_addr , // address
+ input logic mem_we , // write
+ input logic [BIST_DATA_WD-1:0] mem_wdata , // data output
+ input logic [BIST_DATA_WD/8-1:0] mem_wmask , // byte enable
+ output logic [BIST_DATA_WD-1:0] mem_rdata , // data input
+ // MEM PORT
+ output logic func_clk ,
+ output logic func_cen ,
+ output logic func_web ,
+ output logic [BIST_DATA_WD/8-1:0] func_mask ,
+ output logic [BIST_ADDR_WD-1:0] func_addr ,
+ input logic [BIST_DATA_WD-1:0] func_dout ,
+ output logic [BIST_DATA_WD-1:0] func_din
+
+);
+
+
+// Memory Write PORT
+assign func_clk = wb_clk_i;
+assign func_cen = (mem_cs == sram_id) ? !mem_req : 1'b1;
+assign func_web = (mem_cs == sram_id) ? !mem_we : 1'b1;
+assign func_mask = mem_wmask;
+assign func_addr = mem_addr;
+assign func_din = mem_wdata;
+assign mem_rdata = func_dout;
+
+
+
+
+endmodule
diff --git a/verilog/rtl/mbist/src/core/mbist_mux.sv b/verilog/rtl/mbist/src/core/mbist_mux.sv
new file mode 100755
index 0000000..0341b16
--- /dev/null
+++ b/verilog/rtl/mbist/src/core/mbist_mux.sv
@@ -0,0 +1,154 @@
+//////////////////////////////////////////////////////////////////////////////
+// SPDX-FileCopyrightText: 2021 , Dinesh Annayya
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+// SPDX-License-Identifier: Apache-2.0
+// SPDX-FileContributor: Created by Dinesh Annayya <dinesha@opencores.org>
+//
+//////////////////////////////////////////////////////////////////////
+//// ////
+//// MBIST and MEMORY Mux Control Selection ////
+//// ////
+//// This file is part of the mbist_ctrl cores project ////
+//// https://github.com/dineshannayya/mbist_ctrl.git ////
+//// ////
+//// Description ////
+//// This block integrate MBIST and Memory control selection ////
+//// ////
+//// To Do: ////
+//// nothing ////
+//// ////
+//// Author(s): ////
+//// - Dinesh Annayya, dinesha@opencores.org ////
+//// ////
+//// Revision : ////
+//// 0.0 - 11th Oct 2021, Dinesh A ////
+//// Initial integration
+//// ////
+//////////////////////////////////////////////////////////////////////
+
+`include "mbist_def.svh"
+module mbist_mux
+ #( parameter BIST_ADDR_WD = 9,
+ parameter BIST_DATA_WD = 32,
+ parameter BIST_ADDR_START = 9'h000,
+ parameter BIST_ADDR_END = 9'h1F8,
+ parameter BIST_REPAIR_ADDR_START = 9'h1FC,
+ parameter BIST_RAD_WD_I = BIST_ADDR_WD,
+ parameter BIST_RAD_WD_O = BIST_ADDR_WD) (
+
+ input logic scan_mode,
+
+ input logic rst_n,
+ // MBIST CTRL SIGNAL
+ input logic bist_en,
+ input logic [BIST_ADDR_WD-1:0] bist_addr,
+ input logic [BIST_DATA_WD-1:0] bist_wdata,
+ input logic bist_clk,
+ input logic bist_wr,
+ input logic bist_rd,
+ input logic bist_error,
+ input logic [BIST_ADDR_WD-1:0] bist_error_addr,
+ output logic bist_correct,
+ input logic bist_sdi,
+ input logic bist_load,
+ input logic bist_shift,
+ output logic bist_sdo,
+
+ input logic func_clk,
+ input logic func_cen,
+ input logic func_web,
+ input logic [BIST_DATA_WD/8-1:0] func_mask,
+ input logic [BIST_ADDR_WD-1:0] func_addr,
+ input logic [BIST_DATA_WD-1:0] func_din,
+ output logic [BIST_DATA_WD-1:0] func_dout,
+
+
+ // towards memory
+
+ output logic mem_clk,
+ output logic mem_cen,
+ output logic mem_web,
+ output logic [BIST_DATA_WD/8-1:0] mem_mask,
+ output logic [BIST_ADDR_WD-1:0] mem_addr,
+ output logic [BIST_DATA_WD-1:0] mem_din,
+ input logic [BIST_DATA_WD-1:0] mem_dout
+ );
+
+
+parameter BIST_MASK_WD = BIST_DATA_WD/8;
+
+wire [BIST_ADDR_WD-1:0] addr;
+
+
+
+assign addr = (bist_en) ? bist_addr : func_addr;
+
+assign mem_cen = (bist_en) ? !(bist_rd | bist_wr) : func_cen;
+assign mem_web = (bist_en) ? !bist_wr : func_web;
+assign mem_mask = (bist_en) ? {{BIST_MASK_WD}{1'b1}} : func_mask;
+
+//assign mem_clk_a = (bist_en) ? bist_clk : func_clk_a;
+//assign mem_clk_b = (bist_en) ? bist_clk : func_clk_b;
+
+ctech_mux2x1 u_mem_clk_sel (.A0 (func_clk),.A1 (bist_clk),.S (bist_en), .X (mem_clk));
+
+//ctech_clk_buf u_mem_clk (.A (mem_clk_cts), . X(mem_clk));
+
+assign mem_din = (bist_en) ? bist_wdata : func_din;
+
+
+
+// During scan, SRAM data is unknown, feed data in back to avoid unknow
+// propagation
+assign func_dout = (scan_mode) ? mem_din : mem_dout;
+
+mbist_repair_addr
+ #(.BIST_ADDR_WD (BIST_ADDR_WD),
+ .BIST_DATA_WD (BIST_DATA_WD),
+ .BIST_ADDR_START (BIST_ADDR_START),
+ .BIST_ADDR_END (BIST_ADDR_END),
+ .BIST_REPAIR_ADDR_START (BIST_REPAIR_ADDR_START),
+ .BIST_RAD_WD_I (BIST_RAD_WD_I),
+ .BIST_RAD_WD_O (BIST_RAD_WD_O))
+ u_repair(
+ .AddressOut (mem_addr ),
+ .Correct (bist_correct ),
+ .sdo (bist_sdo ),
+
+ .AddressIn (addr ),
+ .clk (mem_clk ),
+ .rst_n (rst_n ),
+ .Error (bist_error ),
+ .ErrorAddr (bist_error_addr ),
+ .bist_load (bist_load ),
+ .bist_shift (bist_shift ),
+ .sdi (bist_sdi )
+);
+
+
+
+
+
+endmodule
+
+
+
+
+
+
+
+
+
+
+
diff --git a/verilog/rtl/mbist/src/core/mbist_op_sel.sv b/verilog/rtl/mbist/src/core/mbist_op_sel.sv
new file mode 100644
index 0000000..a995b8e
--- /dev/null
+++ b/verilog/rtl/mbist/src/core/mbist_op_sel.sv
@@ -0,0 +1,132 @@
+///////////////////////////////////////////////////////////////////////
+// SPDX-FileCopyrightText: 2021 , Dinesh Annayya
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+// SPDX-License-Identifier: Apache-2.0
+// SPDX-FileContributor: Created by Dinesh Annayya <dinesha@opencores.org>
+//
+//////////////////////////////////////////////////////////////////////
+//// ////
+//// MBIST Operation Selection ////
+//// ////
+//// This file is part of the mbist_ctrl cores project ////
+//// https://github.com/dineshannayya/mbist_ctrl.git ////
+//// ////
+//// Description ////
+//// This block integrate Operation Selection ////
+//// ////
+//// To Do: ////
+//// nothing ////
+//// ////
+//// Author(s): ////
+//// - Dinesh Annayya, dinesha@opencores.org ////
+//// ////
+//// Revision : ////
+//// 0.0 - 11th Oct 2021, Dinesh A ////
+//// Initial integration ////
+//// ////
+//////////////////////////////////////////////////////////////////////
+
+
+`include "mbist_def.svh"
+// bist stimulus selection
+
+module mbist_op_sel
+ #( parameter BIST_ADDR_WD = 9,
+ parameter BIST_DATA_WD = 32,
+ parameter BIST_ADDR_START = 9'h000,
+ parameter BIST_ADDR_END = 9'h1F8,
+ parameter BIST_REPAIR_ADDR_START = 9'h1FC,
+ parameter BIST_RAD_WD_I = BIST_ADDR_WD,
+ parameter BIST_RAD_WD_O = BIST_ADDR_WD) (
+
+ output logic op_read , // Opertion Read
+ output logic op_write , // Operation Write
+ output logic op_invert , // Opertaion Data Invert
+ output logic op_updown , // Operation Address Up Down
+ output logic op_reverse , // Operation Reverse
+ output logic op_repeatflag , // Operation Repeat flag
+ output logic sdo , // Scan Data Out
+ output logic last_op , // last operation
+
+ input logic clk , // Clock
+ input logic rst_n , // Reset
+ input logic scan_shift , // Scan Shift
+ input logic sdi , // Scan data in
+ input logic re_init , // Re-init when there is error correction
+ input logic run , // Run
+ input logic [BIST_STI_WD-1:0] stimulus
+
+);
+
+
+logic [BIST_OP_SIZE-1:0] op_sel ;// Actual Operation
+logic [7:0] tmp_op ;// Warning : Assming Max opertion is 8
+logic [7:0] tmpinvert ;// read control
+logic [7:0] tmpread ;// write control
+logic [7:0] tmpwrite ;// invertor control
+integer index ;// output index */
+integer loop ;// bit count
+
+
+/* Operation Selection Selection */
+
+always @(posedge clk or negedge rst_n) begin
+ if(!rst_n) op_sel <= {1'b1,{(BIST_OP_SIZE-1){1'b0}}};
+ else if(scan_shift) op_sel <= {sdi, op_sel[BIST_OP_SIZE-1:1]};
+ else if(re_init) op_sel <= {1'b1,{(BIST_OP_SIZE-1){1'b0}}}; // need fix for pmbist moode
+ else if(run) op_sel <= {op_sel[0],op_sel[BIST_OP_SIZE-1:1]};
+end
+
+assign op_updown = stimulus[BIST_STI_WD-1];
+assign op_reverse = stimulus[BIST_STI_WD-2];
+assign op_repeatflag = stimulus[BIST_STI_WD-3];
+// Re-wind the operation, when the is error correct
+assign last_op = (re_init) ? 1'b0 : op_sel[0];
+
+
+
+always_comb
+begin
+ loop=0;
+ tmpinvert = 8'h0;
+ tmpread = 8'h0;
+ tmpwrite = 8'h0;
+ for(index = 0 ; index < BIST_OP_SIZE ; index = index+1)begin
+ tmpinvert[index] = stimulus[loop];
+ tmpread[index] = stimulus[loop+1];
+ tmpwrite[index] = stimulus[loop+2];
+ loop = loop + 3;
+ end
+end
+
+
+always_comb
+begin
+ tmp_op = 8'b00000000;
+ tmp_op[BIST_OP_SIZE-1:0] = op_sel;
+ case(tmp_op)
+ 8'b10000000: {op_read,op_write,op_invert} = {tmpread[7],tmpwrite[7],tmpinvert[7]};
+ 8'b01000000: {op_read,op_write,op_invert} = {tmpread[6],tmpwrite[6],tmpinvert[6]};
+ 8'b00100000: {op_read,op_write,op_invert} = {tmpread[5],tmpwrite[5],tmpinvert[5]};
+ 8'b00010000: {op_read,op_write,op_invert} = {tmpread[4],tmpwrite[4],tmpinvert[4]};
+ 8'b00001000: {op_read,op_write,op_invert} = {tmpread[3],tmpwrite[3],tmpinvert[3]};
+ 8'b00000100: {op_read,op_write,op_invert} = {tmpread[2],tmpwrite[2],tmpinvert[2]};
+ 8'b00000010: {op_read,op_write,op_invert} = {tmpread[1],tmpwrite[1],tmpinvert[1]};
+ 8'b00000001: {op_read,op_write,op_invert} = {tmpread[0],tmpwrite[0],tmpinvert[0]};
+ default: {op_read,op_write,op_invert} = {tmpread[0],tmpwrite[0],tmpinvert[0]};
+ endcase
+end
+
+
+endmodule
diff --git a/verilog/rtl/mbist/src/core/mbist_pat_sel.sv b/verilog/rtl/mbist/src/core/mbist_pat_sel.sv
new file mode 100644
index 0000000..47a5c98
--- /dev/null
+++ b/verilog/rtl/mbist/src/core/mbist_pat_sel.sv
@@ -0,0 +1,116 @@
+///////////////////////////////////////////////////////////////////////
+// SPDX-FileCopyrightText: 2021 , Dinesh Annayya
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+// SPDX-License-Identifier: Apache-2.0
+// SPDX-FileContributor: Created by Dinesh Annayya <dinesha@opencores.org>
+//
+//////////////////////////////////////////////////////////////////////
+//// ////
+//// MBIST Pattern Selection ////
+//// ////
+//// This file is part of the mbist_ctrl cores project ////
+//// https://github.com/dineshannayya/mbist_ctrl.git ////
+//// ////
+//// Description ////
+//// This block integrate mbist pattern selection ////
+//// ////
+//// To Do: ////
+//// nothing ////
+//// ////
+//// Author(s): ////
+//// - Dinesh Annayya, dinesha@opencores.org ////
+//// ////
+//// Revision : ////
+//// 0.0 - 11th Oct 2021, Dinesh A ////
+//// Initial integration ////
+//// ////
+//////////////////////////////////////////////////////////////////////
+`include "mbist_def.svh"
+//-----------------------------------
+// MBIST Data Pattern Selection Logic
+//-----------------------------------
+module mbist_pat_sel
+ #( parameter BIST_ADDR_WD = 9,
+ parameter BIST_DATA_WD = 32,
+ parameter BIST_ADDR_START = 9'h000,
+ parameter BIST_ADDR_END = 9'h1F8,
+ parameter BIST_REPAIR_ADDR_START = 9'h1FC,
+ parameter BIST_RAD_WD_I = BIST_ADDR_WD,
+ parameter BIST_RAD_WD_O = BIST_ADDR_WD) (
+
+ output logic pat_last, // Last pattern
+ output logic [BIST_DATA_WD-1:0] pat_data, // pattern data
+ output logic sdo, // scan data output
+ input logic clk, // clock
+ input logic rst_n, // reset
+ input logic run, // stop or start state machine
+ input logic scan_shift, // scan shift
+ input logic sdi // scan input
+
+);
+
+
+logic [BIST_DATA_PAT_SIZE-1:0] pat_sel ;/* Pattern Select */
+logic [63:0] pattern;
+
+integer index ;/* output index */
+
+
+
+// last pattern
+assign pat_last = pat_sel[0];
+
+
+/* Pattern Selection */
+
+always @(posedge clk or negedge rst_n) begin
+ if(!rst_n) pat_sel <= {1'b1,{(BIST_DATA_PAT_SIZE-1){1'b0}}};
+ else if(scan_shift) pat_sel <= {sdi, pat_sel[BIST_DATA_PAT_SIZE-1:1]};
+ else if(run) pat_sel <= {pat_sel[0],pat_sel[BIST_DATA_PAT_SIZE-1:1]};
+end
+
+
+/* Pattern Selection */
+logic [7:0] tmp_pat;
+always_comb
+begin
+ tmp_pat = 8'b00000000;
+ tmp_pat[7:8-BIST_DATA_PAT_SIZE] = pat_sel;
+ case(tmp_pat)
+ 8'b10000000: pattern = BIST_DATA_PAT_TYPE1;
+ 8'b01000000: pattern = BIST_DATA_PAT_TYPE2;
+ 8'b00100000: pattern = BIST_DATA_PAT_TYPE3;
+ 8'b00010000: pattern = BIST_DATA_PAT_TYPE4;
+ 8'b00001000: pattern = BIST_DATA_PAT_TYPE5;
+ 8'b00000100: pattern = BIST_DATA_PAT_TYPE6;
+ 8'b00000010: pattern = BIST_DATA_PAT_TYPE7;
+ 8'b00000001: pattern = BIST_DATA_PAT_TYPE8;
+ default: pattern = BIST_DATA_PAT_TYPE1;
+ endcase
+end
+
+/* Data distributor */
+
+always_comb
+begin
+ for(index = 0 ; index < BIST_DATA_WD ; index = index + 1) begin
+ pat_data[index] = pattern[index%64];
+ end
+end
+
+assign sdo = pat_sel[0];
+
+endmodule
+
+
diff --git a/verilog/rtl/mbist/src/core/mbist_repair_addr.sv b/verilog/rtl/mbist/src/core/mbist_repair_addr.sv
new file mode 100644
index 0000000..47871d6
--- /dev/null
+++ b/verilog/rtl/mbist/src/core/mbist_repair_addr.sv
@@ -0,0 +1,151 @@
+///////////////////////////////////////////////////////////////////////
+// SPDX-FileCopyrightText: 2021 , Dinesh Annayya
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+// SPDX-License-Identifier: Apache-2.0
+// SPDX-FileContributor: Created by Dinesh Annayya <dinesha@opencores.org>
+//
+//////////////////////////////////////////////////////////////////////
+//// ////
+//// MBIST Address Repair ////
+//// ////
+//// This file is part of the mbist_ctrl cores project ////
+//// https://github.com/dineshannayya/mbist_ctrl.git ////
+//// ////
+//// Description ////
+//// This block integrate mbist address repair ////
+//// ////
+//// To Do: ////
+//// nothing ////
+//// ////
+//// Author(s): ////
+//// - Dinesh Annayya, dinesha@opencores.org ////
+//// ////
+//// Revision : ////
+//// 0.0 - 11th Oct 2021, Dinesh A ////
+//// Initial integration ////
+//// ////
+//////////////////////////////////////////////////////////////////////
+
+
+// BIST address Repair Logic
+
+`include "mbist_def.svh"
+
+module mbist_repair_addr
+ #( parameter BIST_ADDR_WD = 9,
+ parameter BIST_DATA_WD = 32,
+ parameter BIST_ADDR_START = 9'h000,
+ parameter BIST_ADDR_END = 9'h1F8,
+ parameter BIST_REPAIR_ADDR_START = 9'h1FC,
+ parameter BIST_RAD_WD_I = BIST_ADDR_WD,
+ parameter BIST_RAD_WD_O = BIST_ADDR_WD) (
+
+ output logic [BIST_RAD_WD_O-1:0] AddressOut,
+ output logic Correct,
+ output logic sdo, // scan data output
+
+ input logic [BIST_RAD_WD_I-1:0] AddressIn,
+ input logic clk,
+ input logic rst_n,
+ input logic Error,
+ input logic [BIST_RAD_WD_I-1:0] ErrorAddr,
+ input logic bist_load,
+ input logic bist_shift, // shift scan input
+ input logic sdi // scan data input
+
+
+);
+
+logic [3:0] ErrorCnt; // Assumed Maximum Error correction is less than 16
+
+logic [BIST_RAD_WD_I-1:0] RepairMem [0:BIST_ERR_LIMIT-1];
+integer i;
+
+
+always@(posedge clk or negedge rst_n)
+begin
+ if(!rst_n) begin
+ ErrorCnt <= '0;
+ Correct <= '0;
+ // Initialize the Repair RAM for SCAN purpose
+ for(i =0; i < BIST_ERR_LIMIT; i = i+1) begin
+ RepairMem[i] = 'h0;
+ end
+ end else if(Error) begin
+ if(ErrorCnt <= BIST_ERR_LIMIT) begin
+ ErrorCnt <= ErrorCnt+1;
+ RepairMem[ErrorCnt] <= ErrorAddr;
+ Correct <= 1'b1;
+ end else begin
+ Correct <= 1'b0;
+ end
+ end
+end
+
+integer index;
+
+always_comb
+begin
+ AddressOut = AddressIn;
+ for(index=0; index < BIST_ERR_LIMIT; index=index+1) begin
+ if(ErrorCnt > index && AddressIn == RepairMem[index]) begin
+ AddressOut = BIST_REPAIR_ADDR_START+index;
+ $display("STATUS: MBIST ADDRESS REPAIR: %m => Old Addr: %x Nex Addr: %x",AddressIn,AddressOut);
+ end
+ end
+end
+
+/********************************************
+* Serial shifting the Repair address
+* *******************************************/
+integer j;
+logic [0:BIST_ERR_LIMIT-1] sdi_in;
+logic [0:BIST_ERR_LIMIT-1] sdo_out;
+// Daisy chain the Serial In/OUT
+always_comb begin
+ for(j =0; j < BIST_ERR_LIMIT; j=j+1) begin
+ sdi_in[j] =(j==0) ? sdi : sdo_out[j-1];
+ end
+end
+
+assign sdo = sdo_out[BIST_ERR_LIMIT-1];
+
+genvar no;
+generate
+for (no = 0; $unsigned(no) < BIST_ERR_LIMIT; no=no+1) begin : num
+
+ ser_shift
+ #(.WD(16)) u_shift(
+
+ // Master Port
+ .rst_n (rst_n ),
+ .clk (clk ),
+ .load (bist_load ),
+ .shift (bist_shift ),
+ .load_data (RepairMem[no] ),
+ .sdi (sdi_in[no] ),
+ .sdo (sdo_out[no] )
+
+
+ );
+end
+endgenerate
+
+endmodule
+
+
+
+
+
+
diff --git a/verilog/rtl/mbist/src/core/mbist_sti_sel.sv b/verilog/rtl/mbist/src/core/mbist_sti_sel.sv
new file mode 100644
index 0000000..459dc9f
--- /dev/null
+++ b/verilog/rtl/mbist/src/core/mbist_sti_sel.sv
@@ -0,0 +1,105 @@
+///////////////////////////////////////////////////////////////////////
+// SPDX-FileCopyrightText: 2021 , Dinesh Annayya
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+// SPDX-License-Identifier: Apache-2.0
+// SPDX-FileContributor: Created by Dinesh Annayya <dinesha@opencores.org>
+//
+//////////////////////////////////////////////////////////////////////
+//// ////
+//// MBIST Stimulus Selection ////
+//// ////
+//// This file is part of the mbist_ctrl cores project ////
+//// https://github.com/dineshannayya/mbist_ctrl.git ////
+//// ////
+//// Description ////
+//// This block integrate stimulus slectiion ////
+//// ////
+//// To Do: ////
+//// nothing ////
+//// ////
+//// Author(s): ////
+//// - Dinesh Annayya, dinesha@opencores.org ////
+//// ////
+//// Revision : ////
+//// 0.0 - 11th Oct 2021, Dinesh A ////
+//// Initial integration ////
+//// ////
+//////////////////////////////////////////////////////////////////////
+
+
+`include "mbist_def.svh"
+// bist stimulus selection
+
+module mbist_sti_sel
+ #( parameter BIST_ADDR_WD = 9,
+ parameter BIST_DATA_WD = 32,
+ parameter BIST_ADDR_START = 9'h000,
+ parameter BIST_ADDR_END = 9'h1F8,
+ parameter BIST_REPAIR_ADDR_START = 9'h1FC,
+ parameter BIST_RAD_WD_I = BIST_ADDR_WD,
+ parameter BIST_RAD_WD_O = BIST_ADDR_WD) (
+
+ output logic sdo , // Scan Data Out
+ output logic last_stimulus , // last stimulus
+ output logic [BIST_STI_WD-1:0] stimulus ,
+
+ input logic clk , // Clock
+ input logic rst_n , // Reset
+ input logic scan_shift , // Scan Shift
+ input logic sdi , // Scan data in
+ input logic run // Run
+
+);
+
+logic [BIST_STI_SIZE-1:0] sti_sel ; // Stimulation Selection
+logic [7:0] tmp_sti ; // Warning: Max Stimulus assmed is 8
+
+
+
+/* Pattern Selection */
+
+always @(posedge clk or negedge rst_n) begin
+ if(!rst_n) sti_sel <= {1'b1,{(BIST_STI_SIZE-1){1'b0}}};
+ else if(scan_shift) sti_sel <= {sdi, sti_sel[BIST_STI_SIZE-1:1]};
+ else if(run) sti_sel <= {sti_sel[0],sti_sel[BIST_STI_SIZE-1:1]};
+end
+
+
+/* Pattern Selection */
+always_comb
+begin
+ tmp_sti = 8'b00000000;
+ tmp_sti[7:8-BIST_STI_SIZE] = sti_sel;
+ case(tmp_sti)
+ 8'b10000000: stimulus = BIST_STIMULUS_TYPE1;
+ 8'b01000000: stimulus = BIST_STIMULUS_TYPE2;
+ 8'b00100000: stimulus = BIST_STIMULUS_TYPE3;
+ 8'b00010000: stimulus = BIST_STIMULUS_TYPE4;
+ 8'b00001000: stimulus = BIST_STIMULUS_TYPE5;
+ 8'b00000100: stimulus = BIST_STIMULUS_TYPE6;
+ 8'b00000010: stimulus = BIST_STIMULUS_TYPE7;
+ 8'b00000001: stimulus = BIST_STIMULUS_TYPE8;
+ default: stimulus = BIST_STIMULUS_TYPE1;
+ endcase
+end
+
+
+/* Assign output */
+
+assign sdo = sti_sel[0];
+assign last_stimulus = sti_sel[0];
+
+
+
+endmodule
diff --git a/verilog/rtl/mbist/src/top/mbist_top.sv b/verilog/rtl/mbist/src/top/mbist_top.sv
new file mode 100644
index 0000000..806ce13
--- /dev/null
+++ b/verilog/rtl/mbist/src/top/mbist_top.sv
@@ -0,0 +1,566 @@
+//////////////////////////////////////////////////////////////////////////////
+// SPDX-FileCopyrightText: 2021 , Dinesh Annayya
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+// SPDX-License-Identifier: Apache-2.0
+// SPDX-FileContributor: Created by Dinesh Annayya <dinesha@opencores.org>
+//
+//////////////////////////////////////////////////////////////////////
+//// ////
+//// MBIST TOP ////
+//// ////
+//// This file is part of the mbist_ctrl cores project ////
+//// https://github.com/dineshannayya/mbist_ctrl.git ////
+//// ////
+//// Description ////
+//// This block integrate mbist controller with row ////
+//// redendency feature ////
+//// ////
+//// To Do: ////
+//// nothing ////
+//// ////
+//// Author(s): ////
+//// - Dinesh Annayya, dinesha@opencores.org ////
+//// ////
+//// Revision : ////
+//// 0.0 - 11th Oct 2021, Dinesh A ////
+//// Initial integration ////
+//// 0.1 - 26th Oct 2021, Dinesh A ////
+//// Fixed Error Address are serial shifted through ////
+//// sdi/sdo ////
+//// 0.2 - 15 Dec 2021, Dinesh A ////
+//// Added support for common MBIST for 4 SRAM ////
+//// 0.3 - 29th Dec 2021, Dinesh A ////
+//// yosys synthesis issue for two dimension variable ////
+//// changed the variable defination from logic to wire ////
+//// ////
+//////////////////////////////////////////////////////////////////////
+
+`include "mbist_def.svh"
+module mbist_top
+ #(
+ parameter BIST_NO_SRAM = 4,
+ parameter BIST_ADDR_WD = 9,
+ parameter BIST_DATA_WD = 32,
+ parameter BIST_ADDR_START = 9'h000,
+ parameter BIST_ADDR_END = 9'h1FB,
+ parameter BIST_REPAIR_ADDR_START = 9'h1FC,
+ parameter BIST_RAD_WD_I = BIST_ADDR_WD,
+ parameter BIST_RAD_WD_O = BIST_ADDR_WD) (
+
+`ifdef USE_POWER_PINS
+ inout vccd1, // User area 1 1.8V supply
+ inout vssd1, // User area 1 digital ground
+`endif
+
+ // Clock Skew Adjust
+ input wire wbd_clk_int,
+ output wire wbd_clk_mbist,
+ input wire [3:0] cfg_cska_mbist, // clock skew adjust for web host
+
+ input logic rst_n,
+
+ // MBIST I/F
+ input wire bist_en,
+ input wire bist_run,
+ input wire bist_shift,
+ input wire bist_load,
+ input wire bist_sdi,
+
+ output wire [3:0] bist_error_cnt0,
+ output wire [3:0] bist_error_cnt1,
+ output wire [3:0] bist_error_cnt2,
+ output wire [3:0] bist_error_cnt3,
+ output wire [BIST_NO_SRAM-1:0] bist_correct ,
+ output wire [BIST_NO_SRAM-1:0] bist_error ,
+ output wire bist_done,
+ output wire bist_sdo,
+
+
+ // WB I/F
+ input wire wb_clk_i, // System clock
+ input wire wb_clk2_i, // System clock2 is no cts
+ input wire mem_req, // strobe/request
+ input wire [(BIST_NO_SRAM+1)/2-1:0] mem_cs,
+ input wire [BIST_ADDR_WD-1:0] mem_addr, // address
+ input wire mem_we , // write
+ input wire [BIST_DATA_WD-1:0] mem_wdata, // data output
+ input wire [BIST_DATA_WD/8-1:0] mem_wmask, // byte enable
+ output wire [BIST_DATA_WD-1:0] mem_rdata, // data input
+
+ // towards memory
+ // PORT-A
+ output wire [BIST_NO_SRAM-1:0] mem_clk_a,
+ output wire [BIST_ADDR_WD-1:0] mem_addr_a0,
+ output wire [BIST_ADDR_WD-1:0] mem_addr_a1,
+ output wire [BIST_ADDR_WD-1:0] mem_addr_a2,
+ output wire [BIST_ADDR_WD-1:0] mem_addr_a3,
+ output wire [BIST_NO_SRAM-1:0] mem_cen_a,
+ output wire [BIST_NO_SRAM-1:0] mem_web_a,
+ output wire [BIST_DATA_WD/8-1:0] mem_mask_a0,
+ output wire [BIST_DATA_WD/8-1:0] mem_mask_a1,
+ output wire [BIST_DATA_WD/8-1:0] mem_mask_a2,
+ output wire [BIST_DATA_WD/8-1:0] mem_mask_a3,
+ output wire [BIST_DATA_WD-1:0] mem_din_a0,
+ output wire [BIST_DATA_WD-1:0] mem_din_a1,
+ output wire [BIST_DATA_WD-1:0] mem_din_a2,
+ output wire [BIST_DATA_WD-1:0] mem_din_a3,
+
+ input wire [BIST_DATA_WD-1:0] mem_dout_a0,
+ input wire [BIST_DATA_WD-1:0] mem_dout_a1,
+ input wire [BIST_DATA_WD-1:0] mem_dout_a2,
+ input wire [BIST_DATA_WD-1:0] mem_dout_a3,
+
+
+ // PORT-B
+ output wire [BIST_NO_SRAM-1:0] mem_clk_b,
+ output wire [BIST_NO_SRAM-1:0] mem_cen_b,
+ output wire [BIST_ADDR_WD-1:0] mem_addr_b0,
+ output wire [BIST_ADDR_WD-1:0] mem_addr_b1,
+ output wire [BIST_ADDR_WD-1:0] mem_addr_b2,
+ output wire [BIST_ADDR_WD-1:0] mem_addr_b3
+
+
+
+
+);
+
+parameter NO_SRAM_WD = (BIST_NO_SRAM+1)/2;
+
+// FUNCTIONAL PORT
+wire func_clk[0:BIST_NO_SRAM-1];
+wire func_cen[0:BIST_NO_SRAM-1];
+wire func_web[0:BIST_NO_SRAM-1];
+wire [BIST_DATA_WD/8-1:0]func_mask[0:BIST_NO_SRAM-1];
+wire [BIST_ADDR_WD-1:0]func_addr[0:BIST_NO_SRAM-1];
+wire [BIST_DATA_WD-1:0]func_dout[0:BIST_NO_SRAM-1];
+wire [BIST_DATA_WD-1:0]func_din[0:BIST_NO_SRAM-1];
+
+//----------------------------------------------------
+// Local variable defination
+// ---------------------------------------------------
+//
+wire srst_n ; // sync reset w.r.t bist_clk
+wire cmd_phase ; // Command Phase
+wire cmp_phase ; // Compare Phase
+wire run_op ; // Run next Operation
+wire run_addr ; // Run Next Address
+wire run_sti ; // Run Next Stimulus
+wire run_pat ; // Run Next Pattern
+wire op_updown ; // Adress updown direction
+wire last_addr ; // last address indication
+wire last_sti ; // last stimulus
+wire last_op ; // last operation
+wire last_pat ; // last pattern
+wire [BIST_DATA_WD-1:0] pat_data ; // Selected Data Pattern
+wire [BIST_STI_WD-1:0] stimulus ; // current stimulus
+wire compare ; // compare data
+wire op_repeatflag;
+wire op_reverse;
+wire op_read ;
+wire op_write ;
+wire op_invert ;
+
+
+wire bist_error_correct[0:BIST_NO_SRAM-1] ;
+wire [BIST_ADDR_WD-1:0]bist_error_addr[0:BIST_NO_SRAM-1] ; // bist address
+
+wire [BIST_ADDR_WD-1:0]bist_addr ; // bist address
+wire [BIST_DATA_WD-1:0] bist_wdata ; // bist write data
+wire bist_wr ;
+wire bist_rd ;
+wire [BIST_DATA_WD-1:0] wb_dat[0:BIST_NO_SRAM-1]; // data input
+
+//--------------------------------------------------------
+// As yosys does not support two dimensional var,
+// converting it single dimension
+// -------------------------------------------------------
+wire [3:0] bist_error_cnt_i [0:BIST_NO_SRAM-1];
+
+assign bist_error_cnt0 = bist_error_cnt_i[0];
+assign bist_error_cnt1 = bist_error_cnt_i[1];
+assign bist_error_cnt2 = bist_error_cnt_i[2];
+assign bist_error_cnt3 = bist_error_cnt_i[3];
+
+
+// Towards MEMORY PORT - A
+wire [BIST_ADDR_WD-1:0] mem_addr_a_i[0:BIST_NO_SRAM-1];
+wire [BIST_DATA_WD/8-1:0] mem_mask_a_i[0:BIST_NO_SRAM-1];
+wire [BIST_DATA_WD-1:0] mem_dout_a_i[0:BIST_NO_SRAM-1];
+wire [BIST_DATA_WD-1:0] mem_din_a_i[0:BIST_NO_SRAM-1];
+
+assign mem_addr_a0 = mem_addr_a_i[0];
+assign mem_addr_a1 = mem_addr_a_i[1];
+assign mem_addr_a2 = mem_addr_a_i[2];
+assign mem_addr_a3 = mem_addr_a_i[3];
+
+assign mem_din_a0 = mem_din_a_i[0];
+assign mem_din_a1 = mem_din_a_i[1];
+assign mem_din_a2 = mem_din_a_i[2];
+assign mem_din_a3 = mem_din_a_i[3];
+
+assign mem_mask_a0= mem_mask_a_i[0];
+assign mem_mask_a1= mem_mask_a_i[1];
+assign mem_mask_a2= mem_mask_a_i[2];
+assign mem_mask_a3= mem_mask_a_i[3];
+
+// FROM MEMORY
+assign mem_dout_a_i[0] = mem_dout_a0;
+assign mem_dout_a_i[1] = mem_dout_a1;
+assign mem_dout_a_i[2] = mem_dout_a2;
+assign mem_dout_a_i[3] = mem_dout_a3;
+
+// Towards MEMORY PORT - A
+assign mem_clk_b = 'b0;
+assign mem_cen_b = 'b0;
+assign mem_addr_b0 = 'b0;
+assign mem_addr_b1 = 'b0;
+assign mem_addr_b2 = 'b0;
+assign mem_addr_b3 = 'b0;
+
+//---------------------------------------------------
+// Manage the SDI => SDO Diasy chain
+// --------------------------------------------------
+//---------------------------------
+// SDI => SDO diasy chain
+// bist_sdi => bist_addr_sdo => bist_sti_sdo => bist_op_sdo => bist_pat_sdo => bist_sdo
+// ---------------------------------
+wire bist_addr_sdo ;
+wire bist_sti_sdo ;
+wire bist_op_sdo ;
+wire bist_pat_sdo ;
+
+wire bist_ms_sdi[0:BIST_NO_SRAM-1];
+wire bist_ms_sdo[0:BIST_NO_SRAM-1];
+
+// Adjust the SDI => SDO Daisy chain
+assign bist_ms_sdi[0] = bist_pat_sdo;
+assign bist_ms_sdi[1] = bist_ms_sdo[0];
+assign bist_ms_sdi[2] = bist_ms_sdo[1];
+assign bist_ms_sdi[3] = bist_ms_sdo[2];
+assign bist_sdo = bist_ms_sdo[3];
+
+// Pick the correct read path
+assign mem_rdata = wb_dat[mem_cs];
+
+assign bist_wr = (cmd_phase && op_write);
+assign bist_rd = (cmd_phase && op_read);
+
+assign compare = (cmp_phase && op_read);
+assign bist_wdata = (op_invert) ? ~pat_data : pat_data;
+
+// Clock Tree branching to avoid clock latency towards SRAM path
+wire wb_clk_b1,wb_clk_b2;
+//ctech_clk_buf u_cts_wb_clk_b1 (.A (wb_clk_i), . X(wb_clk_b1));
+//ctech_clk_buf u_cts_wb_clk_b2 (.A (wb_clk_i), . X(wb_clk_b2));
+
+// wb_host clock skew control
+clk_skew_adjust u_skew_mbist
+ (
+`ifdef USE_POWER_PINS
+ .vccd1 (vccd1 ),// User area 1 1.8V supply
+ .vssd1 (vssd1 ),// User area 1 digital ground
+`endif
+ .clk_in (wbd_clk_int ),
+ .sel (cfg_cska_mbist ),
+ .clk_out (wbd_clk_mbist )
+ );
+
+reset_sync u_reset_sync (
+ .scan_mode (1'b0 ),
+ .dclk (wb_clk_i ), // Destination clock domain
+ .arst_n (rst_n ), // active low async reset
+ .srst_n (srst_n )
+ );
+
+
+integer i;
+reg bist_error_and;
+reg bist_error_correct_or;
+
+always_comb begin
+ bist_error_and =0;
+ bist_error_correct_or = 0;
+ for(i=0; i <BIST_NO_SRAM; i = i+1) begin
+ bist_error_and = bist_error_and & bist_error[i];
+ bist_error_correct_or = bist_error_correct_or | bist_error_correct[i];
+ end
+end
+
+
+// bist main control FSM
+
+mbist_fsm
+ #(
+ .BIST_ADDR_WD (BIST_ADDR_WD ),
+ .BIST_DATA_WD (BIST_DATA_WD ),
+ .BIST_ADDR_START (BIST_ADDR_START ),
+ .BIST_ADDR_END (BIST_ADDR_END ),
+ .BIST_REPAIR_ADDR_START (BIST_REPAIR_ADDR_START ),
+ .BIST_RAD_WD_I (BIST_RAD_WD_I ),
+ .BIST_RAD_WD_O (BIST_RAD_WD_O )
+ )
+ u_fsm (
+
+ .cmd_phase (cmd_phase ),
+ .cmp_phase (cmp_phase ),
+ .run_op (run_op ),
+ .run_addr (run_addr ),
+ .run_sti (run_sti ),
+ .run_pat (run_pat ),
+ .bist_done (bist_done ),
+
+
+ .clk (wb_clk_i ),
+ .rst_n (srst_n ),
+ .bist_run (bist_run ),
+ .last_op (last_op ),
+ .last_addr (last_addr ),
+ .last_sti (last_sti ),
+ .last_pat (last_pat ),
+ .op_reverse (op_reverse ),
+ .bist_error (bist_error_and )
+);
+
+
+// bist address generation
+mbist_addr_gen
+ #(
+ .BIST_ADDR_WD (BIST_ADDR_WD ),
+ .BIST_DATA_WD (BIST_DATA_WD ),
+ .BIST_ADDR_START (BIST_ADDR_START ),
+ .BIST_ADDR_END (BIST_ADDR_END ),
+ .BIST_REPAIR_ADDR_START (BIST_REPAIR_ADDR_START ),
+ .BIST_RAD_WD_I (BIST_RAD_WD_I ),
+ .BIST_RAD_WD_O (BIST_RAD_WD_O )
+ )
+ u_addr_gen(
+ .last_addr (last_addr ),
+ .bist_addr (bist_addr ),
+ .sdo (bist_addr_sdo ),
+
+ .clk (wb_clk_i ),
+ .rst_n (srst_n ),
+ .run (run_addr ),
+ .updown (op_updown ),
+ .bist_shift (bist_shift ),
+ .bist_load (bist_load ),
+ .sdi (bist_sdi )
+
+);
+
+
+// BIST current stimulus selection
+mbist_sti_sel
+ #(
+ .BIST_ADDR_WD (BIST_ADDR_WD ),
+ .BIST_DATA_WD (BIST_DATA_WD ),
+ .BIST_ADDR_START (BIST_ADDR_START ),
+ .BIST_ADDR_END (BIST_ADDR_END ),
+ .BIST_REPAIR_ADDR_START (BIST_REPAIR_ADDR_START ),
+ .BIST_RAD_WD_I (BIST_RAD_WD_I ),
+ .BIST_RAD_WD_O (BIST_RAD_WD_O )
+ )
+ u_sti_sel(
+
+ .sdo (bist_sti_sdo ),
+ .last_stimulus (last_sti ),
+ .stimulus (stimulus ),
+
+ .clk (wb_clk_i ),
+ .rst_n (srst_n ),
+ .scan_shift (bist_shift ),
+ .sdi (bist_addr_sdo ),
+ .run (run_sti )
+
+);
+
+
+// Bist Operation selection
+mbist_op_sel
+ #(
+ .BIST_ADDR_WD (BIST_ADDR_WD ),
+ .BIST_DATA_WD (BIST_DATA_WD ),
+ .BIST_ADDR_START (BIST_ADDR_START ),
+ .BIST_ADDR_END (BIST_ADDR_END ),
+ .BIST_REPAIR_ADDR_START (BIST_REPAIR_ADDR_START ),
+ .BIST_RAD_WD_I (BIST_RAD_WD_I ),
+ .BIST_RAD_WD_O (BIST_RAD_WD_O )
+ )
+ u_op_sel (
+
+ .op_read (op_read ),
+ .op_write (op_write ),
+ .op_invert (op_invert ),
+ .op_updown (op_updown ),
+ .op_reverse (op_reverse ),
+ .op_repeatflag (op_repeatflag ),
+ .sdo (bist_op_sdo ),
+ .last_op (last_op ),
+
+ .clk (wb_clk_i ),
+ .rst_n (srst_n ),
+ .scan_shift (bist_shift ),
+ .sdi (bist_sti_sdo ),
+ .re_init (bist_error_correct_or ),
+ .run (run_op ),
+ .stimulus (stimulus )
+
+ );
+
+
+
+mbist_pat_sel
+ #(
+ .BIST_ADDR_WD (BIST_ADDR_WD ),
+ .BIST_DATA_WD (BIST_DATA_WD ),
+ .BIST_ADDR_START (BIST_ADDR_START ),
+ .BIST_ADDR_END (BIST_ADDR_END ),
+ .BIST_REPAIR_ADDR_START (BIST_REPAIR_ADDR_START ),
+ .BIST_RAD_WD_I (BIST_RAD_WD_I ),
+ .BIST_RAD_WD_O (BIST_RAD_WD_O )
+ )
+ u_pat_sel (
+ .pat_last (last_pat ),
+ .pat_data (pat_data ),
+ .sdo (bist_pat_sdo ),
+ .clk (wb_clk_i ),
+ .rst_n (srst_n ),
+ .run (run_pat ),
+ .scan_shift (bist_shift ),
+ .sdi (bist_op_sdo )
+
+ );
+
+
+
+
+
+genvar sram_no;
+generate
+for (sram_no = 0; $unsigned(sram_no) < BIST_NO_SRAM; sram_no=sram_no+1) begin : mem_no
+
+
+mbist_data_cmp
+ #(
+ .BIST_ADDR_WD (BIST_ADDR_WD ),
+ .BIST_DATA_WD (BIST_DATA_WD ),
+ .BIST_ADDR_START (BIST_ADDR_START ),
+ .BIST_ADDR_END (BIST_ADDR_END ),
+ .BIST_REPAIR_ADDR_START (BIST_REPAIR_ADDR_START ),
+ .BIST_RAD_WD_I (BIST_RAD_WD_I ),
+ .BIST_RAD_WD_O (BIST_RAD_WD_O )
+ )
+
+
+ u_cmp (
+ .error (bist_error[sram_no] ),
+ .error_correct (bist_error_correct[sram_no] ),
+ .correct ( ), // same signal available at bist mux
+ .error_addr (bist_error_addr[sram_no] ),
+ .error_cnt (bist_error_cnt_i[sram_no] ),
+ .clk (wb_clk_i ),
+ .rst_n (srst_n ),
+ .addr_inc_phase (run_addr ),
+ .compare (compare ),
+ .read_invert (op_invert ),
+ .comp_data (pat_data ),
+ .rxd_data (func_dout[sram_no] ),
+ .addr (bist_addr )
+
+ );
+
+ // WB To Memory Signal Mapping
+ mbist_mem_wrapper #(
+ .BIST_NO_SRAM (BIST_NO_SRAM ),
+ .BIST_ADDR_WD (BIST_ADDR_WD ),
+ .BIST_DATA_WD (BIST_DATA_WD )
+ ) u_mem_wrapper_(
+ .rst_n (srst_n ),
+ // WB I/F
+ .sram_id (NO_SRAM_WD'(sram_no) ),
+ .wb_clk_i (wb_clk2_i ), // System clock
+ .mem_cs (mem_cs ), // Chip Select
+ .mem_req (mem_req ), // strobe/request
+ .mem_addr (mem_addr ), // address
+ .mem_we (mem_we ), // write
+ .mem_wdata (mem_wdata ), // data output
+ .mem_wmask (mem_wmask ), // byte enable
+ .mem_rdata (wb_dat[sram_no] ), // data input
+ // MEM A PORT
+ .func_clk (func_clk[sram_no] ),
+ .func_cen (func_cen[sram_no] ),
+ .func_web (func_web[sram_no] ),
+ .func_mask (func_mask[sram_no] ),
+ .func_addr (func_addr[sram_no] ),
+ .func_din (func_din[sram_no] ),
+ .func_dout (func_dout[sram_no] )
+ );
+
+
+mbist_mux
+ #(
+ .BIST_ADDR_WD (BIST_ADDR_WD ),
+ .BIST_DATA_WD (BIST_DATA_WD ),
+ .BIST_ADDR_START (BIST_ADDR_START ),
+ .BIST_ADDR_END (BIST_ADDR_END ),
+ .BIST_REPAIR_ADDR_START (BIST_REPAIR_ADDR_START ),
+ .BIST_RAD_WD_I (BIST_RAD_WD_I ),
+ .BIST_RAD_WD_O (BIST_RAD_WD_O )
+ )
+ u_mem_sel (
+
+ .scan_mode (1'b0 ),
+
+ .rst_n (srst_n ),
+ // MBIST CTRL SIGNAL
+ .bist_en (bist_en ),
+ .bist_addr (bist_addr ),
+ .bist_wdata (bist_wdata ),
+ .bist_clk (wb_clk2_i ),
+ .bist_wr (bist_wr ),
+ .bist_rd (bist_rd ),
+ .bist_error (bist_error_correct[sram_no]),
+ .bist_error_addr (bist_error_addr[sram_no] ),
+ .bist_correct (bist_correct[sram_no] ),
+ .bist_sdi (bist_ms_sdi[sram_no] ),
+ .bist_load (bist_load ),
+ .bist_shift (bist_shift ),
+ .bist_sdo (bist_ms_sdo[sram_no] ),
+
+ // FUNCTIONAL CTRL SIGNAL
+ .func_clk (func_clk[sram_no] ),
+ .func_cen (func_cen[sram_no] ),
+ .func_web (func_web[sram_no] ),
+ .func_mask (func_mask[sram_no] ),
+ .func_addr (func_addr[sram_no] ),
+ .func_din (func_din[sram_no] ),
+ .func_dout (func_dout[sram_no] ),
+
+
+ // towards memory
+ // Memory Out Port
+ .mem_clk (mem_clk_a[sram_no] ),
+ .mem_cen (mem_cen_a[sram_no] ),
+ .mem_web (mem_web_a[sram_no] ),
+ .mem_mask (mem_mask_a_i[sram_no] ),
+ .mem_addr (mem_addr_a_i[sram_no] ),
+ .mem_din (mem_din_a_i[sram_no] ),
+ .mem_dout (mem_dout_a_i[sram_no] )
+
+ );
+end
+endgenerate
+
+endmodule
+
diff --git a/verilog/rtl/mbist/src/top/mbist_top1.sv b/verilog/rtl/mbist/src/top/mbist_top1.sv
new file mode 100644
index 0000000..10fdbfd
--- /dev/null
+++ b/verilog/rtl/mbist/src/top/mbist_top1.sv
@@ -0,0 +1,469 @@
+//////////////////////////////////////////////////////////////////////////////
+// SPDX-FileCopyrightText: 2021 , Dinesh Annayya
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+// SPDX-License-Identifier: Apache-2.0
+// SPDX-FileContributor: Created by Dinesh Annayya <dinesha@opencores.org>
+//
+//////////////////////////////////////////////////////////////////////
+//// ////
+//// MBIST TOP ////
+//// ////
+//// This file is part of the mbist_ctrl cores project ////
+//// https://github.com/dineshannayya/mbist_ctrl.git ////
+//// ////
+//// Description ////
+//// This block integrate mbist controller with row ////
+//// redendency feature ////
+//// ////
+//// To Do: ////
+//// nothing ////
+//// ////
+//// Author(s): ////
+//// - Dinesh Annayya, dinesha@opencores.org ////
+//// ////
+//// Revision : ////
+//// 0.0 - 11th Oct 2021, Dinesh A ////
+//// Initial integration ////
+//// 0.1 - 26th Oct 2021, Dinesh A ////
+//// Fixed Error Address are serial shifted through ////
+//// sdi/sdo ////
+//// ////
+//////////////////////////////////////////////////////////////////////
+
+`include "mbist_def.svh"
+module mbist_top1
+ #(
+ parameter BIST_ADDR_WD = 9,
+ parameter BIST_DATA_WD = 32,
+ parameter BIST_ADDR_START = 9'h000,
+ parameter BIST_ADDR_END = 9'h1FB,
+ parameter BIST_REPAIR_ADDR_START = 9'h1FC,
+ parameter BIST_RAD_WD_I = BIST_ADDR_WD,
+ parameter BIST_RAD_WD_O = BIST_ADDR_WD) (
+
+`ifdef USE_POWER_PINS
+ inout vccd1, // User area 1 1.8V supply
+ inout vssd1, // User area 1 digital ground
+`endif
+
+ // Clock Skew Adjust
+ input logic wbd_clk_int,
+ output logic wbd_clk_mbist,
+ input logic [3:0] cfg_cska_mbist, // clock skew adjust for web host
+
+ input logic rst_n,
+
+ // MBIST I/F
+ input logic bist_en,
+ input logic bist_run,
+ input logic bist_shift,
+ input logic bist_load,
+ input logic bist_sdi,
+
+ output logic [3:0] bist_error_cnt,
+ output logic bist_correct,
+ output logic bist_error,
+ output logic bist_done,
+ output logic bist_sdo,
+
+
+ // WB I/F
+ input logic wb_clk_i, // System clock
+ input logic wb_cyc_i, // strobe/request
+ input logic wb_stb_i, // strobe/request
+ input logic [BIST_ADDR_WD-1:0] wb_adr_i, // address
+ input logic wb_we_i , // write
+ input logic [BIST_DATA_WD-1:0] wb_dat_i, // data output
+ input logic [BIST_DATA_WD/8-1:0] wb_sel_i, // byte enable
+ output logic [BIST_DATA_WD-1:0] wb_dat_o, // data input
+ output logic wb_ack_o, // acknowlegement
+ output logic wb_err_o, // error
+
+ // towards memory
+ // PORT-A
+ output logic mem_clk_a,
+ output logic [BIST_ADDR_WD-1:0]mem_addr_a,
+ output logic mem_cen_a,
+ output logic [BIST_DATA_WD-1:0]mem_din_b,
+ // PORT-B
+ output logic mem_clk_b,
+ output logic mem_cen_b,
+ output logic mem_web_b,
+ output logic [BIST_DATA_WD/8-1:0]mem_mask_b,
+ output logic [BIST_ADDR_WD-1:0]mem_addr_b,
+ input logic [BIST_DATA_WD-1:0]mem_dout_a
+
+
+
+
+);
+
+// FUNCTIONAL A PORT
+logic func_clk_a;
+logic func_cen_a;
+logic [BIST_ADDR_WD-1:0]func_addr_a;
+logic [BIST_DATA_WD-1:0]func_dout_a;
+
+// Functional B Port
+logic func_clk_b;
+logic func_cen_b;
+logic func_web_b;
+logic [BIST_DATA_WD/8-1:0]func_mask_b;
+logic [BIST_ADDR_WD-1:0]func_addr_b;
+logic [BIST_DATA_WD-1:0]func_din_b;
+//----------------------------------------------------
+// Local variable defination
+// ---------------------------------------------------
+//
+logic srst_n ; // sync reset w.r.t bist_clk
+logic cmd_phase ; // Command Phase
+logic cmp_phase ; // Compare Phase
+logic run_op ; // Run next Operation
+logic run_addr ; // Run Next Address
+logic run_sti ; // Run Next Stimulus
+logic run_pat ; // Run Next Pattern
+logic op_updown ; // Adress updown direction
+logic last_addr ; // last address indication
+logic last_sti ; // last stimulus
+logic last_op ; // last operation
+logic last_pat ; // last pattern
+logic [BIST_DATA_WD-1:0] pat_data ; // Selected Data Pattern
+logic [BIST_STI_WD-1:0] stimulus ; // current stimulus
+logic compare ; // compare data
+logic op_repeatflag;
+logic op_reverse;
+logic op_read ;
+logic op_write ;
+logic op_invert ;
+
+//---------------------------------
+// SDI => SDO diasy chain
+// bist_sdi => bist_addr_sdo => bist_sti_sdo => bist_op_sdo => bist_pat_sdo => bist_sdo
+// ---------------------------------
+logic bist_addr_sdo ;
+logic bist_sti_sdo ;
+logic bist_op_sdo ;
+logic bist_pat_sdo ;
+
+logic bist_error_correct ;
+logic [BIST_ADDR_WD-1:0]bist_error_addr ; // bist address
+
+logic [BIST_ADDR_WD-1:0]bist_addr ; // bist address
+logic [BIST_DATA_WD-1:0] bist_wdata ; // bist write data
+logic bist_wr ;
+logic bist_rd ;
+
+
+assign bist_wr = (cmd_phase && op_write);
+assign bist_rd = (cmd_phase && op_read);
+
+assign compare = (cmp_phase && op_read);
+assign bist_wdata = (op_invert) ? ~pat_data : pat_data;
+
+// Clock Tree branching to avoid clock latency towards SRAM path
+wire wb_clk_b1,wb_clk_b2;
+ctech_clk_buf u_cts_wb_clk_b1 (.A (wb_clk_i), . X(wb_clk_b1));
+ctech_clk_buf u_cts_wb_clk_b2 (.A (wb_clk_i), . X(wb_clk_b2));
+
+// wb_host clock skew control
+clk_skew_adjust u_skew_mbist
+ (
+`ifdef USE_POWER_PINS
+ .vccd1 (vccd1 ),// User area 1 1.8V supply
+ .vssd1 (vssd1 ),// User area 1 digital ground
+`endif
+ .clk_in (wbd_clk_int ),
+ .sel (cfg_cska_mbist ),
+ .clk_out (wbd_clk_mbist )
+ );
+
+reset_sync u_reset_sync (
+ .scan_mode (1'b0 ),
+ .dclk (wb_clk_b1 ), // Destination clock domain
+ .arst_n (rst_n ), // active low async reset
+ .srst_n (srst_n )
+ );
+
+
+
+// bist main control FSM
+
+mbist_fsm
+ #(
+ .BIST_ADDR_WD (BIST_ADDR_WD ),
+ .BIST_DATA_WD (BIST_DATA_WD ),
+ .BIST_ADDR_START (BIST_ADDR_START ),
+ .BIST_ADDR_END (BIST_ADDR_END ),
+ .BIST_REPAIR_ADDR_START (BIST_REPAIR_ADDR_START ),
+ .BIST_RAD_WD_I (BIST_RAD_WD_I ),
+ .BIST_RAD_WD_O (BIST_RAD_WD_O )
+ )
+ u_fsm (
+
+ .cmd_phase (cmd_phase ),
+ .cmp_phase (cmp_phase ),
+ .run_op (run_op ),
+ .run_addr (run_addr ),
+ .run_sti (run_sti ),
+ .run_pat (run_pat ),
+ .bist_done (bist_done ),
+
+
+ .clk (wb_clk_b1 ),
+ .rst_n (srst_n ),
+ .bist_run (bist_run ),
+ .last_op (last_op ),
+ .last_addr (last_addr ),
+ .last_sti (last_sti ),
+ .last_pat (last_pat ),
+ .op_reverse (op_reverse ),
+ .bist_error (bist_error )
+);
+
+
+// bist address generation
+mbist_addr_gen
+ #(
+ .BIST_ADDR_WD (BIST_ADDR_WD ),
+ .BIST_DATA_WD (BIST_DATA_WD ),
+ .BIST_ADDR_START (BIST_ADDR_START ),
+ .BIST_ADDR_END (BIST_ADDR_END ),
+ .BIST_REPAIR_ADDR_START (BIST_REPAIR_ADDR_START ),
+ .BIST_RAD_WD_I (BIST_RAD_WD_I ),
+ .BIST_RAD_WD_O (BIST_RAD_WD_O )
+ )
+ u_addr_gen(
+ .last_addr (last_addr ),
+ .bist_addr (bist_addr ),
+ .sdo (bist_addr_sdo ),
+
+ .clk (wb_clk_b1 ),
+ .rst_n (srst_n ),
+ .run (run_addr ),
+ .updown (op_updown ),
+ .scan_shift (bist_shift ),
+ .scan_load (bist_load ),
+ .sdi (bist_sdi )
+
+);
+
+
+// BIST current stimulus selection
+mbist_sti_sel
+ #(
+ .BIST_ADDR_WD (BIST_ADDR_WD ),
+ .BIST_DATA_WD (BIST_DATA_WD ),
+ .BIST_ADDR_START (BIST_ADDR_START ),
+ .BIST_ADDR_END (BIST_ADDR_END ),
+ .BIST_REPAIR_ADDR_START (BIST_REPAIR_ADDR_START ),
+ .BIST_RAD_WD_I (BIST_RAD_WD_I ),
+ .BIST_RAD_WD_O (BIST_RAD_WD_O )
+ )
+ u_sti_sel(
+
+ .sdo (bist_sti_sdo ),
+ .last_stimulus (last_sti ),
+ .stimulus (stimulus ),
+
+ .clk (wb_clk_b1 ),
+ .rst_n (srst_n ),
+ .scan_shift (bist_shift ),
+ .sdi (bist_addr_sdo ),
+ .run (run_sti )
+
+);
+
+
+// Bist Operation selection
+mbist_op_sel
+ #(
+ .BIST_ADDR_WD (BIST_ADDR_WD ),
+ .BIST_DATA_WD (BIST_DATA_WD ),
+ .BIST_ADDR_START (BIST_ADDR_START ),
+ .BIST_ADDR_END (BIST_ADDR_END ),
+ .BIST_REPAIR_ADDR_START (BIST_REPAIR_ADDR_START ),
+ .BIST_RAD_WD_I (BIST_RAD_WD_I ),
+ .BIST_RAD_WD_O (BIST_RAD_WD_O )
+ )
+ u_op_sel (
+
+ .op_read (op_read ),
+ .op_write (op_write ),
+ .op_invert (op_invert ),
+ .op_updown (op_updown ),
+ .op_reverse (op_reverse ),
+ .op_repeatflag (op_repeatflag ),
+ .sdo (bist_op_sdo ),
+ .last_op (last_op ),
+
+ .clk (wb_clk_b1 ),
+ .rst_n (srst_n ),
+ .scan_shift (bist_shift ),
+ .sdi (bist_sti_sdo ),
+ .re_init (bist_error_correct ),
+ .run (run_op ),
+ .stimulus (stimulus )
+
+ );
+
+
+
+mbist_pat_sel
+ #(
+ .BIST_ADDR_WD (BIST_ADDR_WD ),
+ .BIST_DATA_WD (BIST_DATA_WD ),
+ .BIST_ADDR_START (BIST_ADDR_START ),
+ .BIST_ADDR_END (BIST_ADDR_END ),
+ .BIST_REPAIR_ADDR_START (BIST_REPAIR_ADDR_START ),
+ .BIST_RAD_WD_I (BIST_RAD_WD_I ),
+ .BIST_RAD_WD_O (BIST_RAD_WD_O )
+ )
+ u_pat_sel (
+ .pat_last (last_pat ),
+ .pat_data (pat_data ),
+ .sdo (bist_pat_sdo ),
+ .clk (wb_clk_b1 ),
+ .rst_n (srst_n ),
+ .run (run_pat ),
+ .scan_shift (bist_shift ),
+ .sdi (bist_op_sdo )
+
+ );
+
+
+mbist_data_cmp
+ #(
+ .BIST_ADDR_WD (BIST_ADDR_WD ),
+ .BIST_DATA_WD (BIST_DATA_WD ),
+ .BIST_ADDR_START (BIST_ADDR_START ),
+ .BIST_ADDR_END (BIST_ADDR_END ),
+ .BIST_REPAIR_ADDR_START (BIST_REPAIR_ADDR_START ),
+ .BIST_RAD_WD_I (BIST_RAD_WD_I ),
+ .BIST_RAD_WD_O (BIST_RAD_WD_O )
+ )
+
+
+ u_cmp (
+ .error (bist_error ),
+ .error_correct (bist_error_correct ),
+ .correct ( ), // same signal available at bist mux
+ .error_addr (bist_error_addr ),
+ .error_cnt (bist_error_cnt ),
+ .clk (wb_clk_b1 ),
+ .rst_n (srst_n ),
+ .addr_inc_phase (run_addr ),
+ .compare (compare ),
+ .read_invert (op_invert ),
+ .comp_data (pat_data ),
+ .rxd_data (func_dout_a ),
+ .addr (bist_addr )
+
+ );
+
+
+mbist_mem_wrapper #(
+ .BIST_ADDR_WD (BIST_ADDR_WD ),
+ .BIST_DATA_WD (BIST_DATA_WD )
+ ) u_mem_wrapper(
+ .rst_n (srst_n ),
+ // WB I/F
+ .wb_clk_i (wb_clk_b2 ), // System clock
+ .wb_cyc_i (wb_cyc_i ), // strobe/request
+ .wb_stb_i (wb_stb_i ), // strobe/request
+ .wb_adr_i (wb_adr_i ), // address
+ .wb_we_i (wb_we_i ), // write
+ .wb_dat_i (wb_dat_i ), // data output
+ .wb_sel_i (wb_sel_i ), // byte enable
+ .wb_dat_o (wb_dat_o ), // data input
+ .wb_ack_o (wb_ack_o ), // acknowlegement
+ .wb_err_o (wb_err_o ), // error
+ // MEM A PORT
+ .func_clk_a (func_clk_a ),
+ .func_cen_a (func_cen_a ),
+ .func_addr_a (func_addr_a ),
+ .func_dout_a (func_dout_a ),
+
+ // Functional B Port
+ .func_clk_b (func_clk_b ),
+ .func_cen_b (func_cen_b ),
+ .func_web_b (func_web_b ),
+ .func_mask_b (func_mask_b ),
+ .func_addr_b (func_addr_b ),
+ .func_din_b (func_din_b )
+ );
+
+
+mbist_mux
+ #(
+ .BIST_ADDR_WD (BIST_ADDR_WD ),
+ .BIST_DATA_WD (BIST_DATA_WD ),
+ .BIST_ADDR_START (BIST_ADDR_START ),
+ .BIST_ADDR_END (BIST_ADDR_END ),
+ .BIST_REPAIR_ADDR_START (BIST_REPAIR_ADDR_START ),
+ .BIST_RAD_WD_I (BIST_RAD_WD_I ),
+ .BIST_RAD_WD_O (BIST_RAD_WD_O )
+ )
+ u_mem_sel (
+
+ .scan_mode (1'b0 ),
+
+ .rst_n (srst_n ),
+ // MBIST CTRL SIGNAL
+ .bist_en (bist_en ),
+ .bist_addr (bist_addr ),
+ .bist_wdata (bist_wdata ),
+ .bist_clk (wb_clk_b2 ),
+ .bist_wr (bist_wr ),
+ .bist_rd (bist_rd ),
+ .bist_error (bist_error_correct),
+ .bist_error_addr (bist_error_addr),
+ .bist_correct (bist_correct ),
+ .bist_sdi (bist_pat_sdo),
+ .bist_shift (bist_shift),
+ .bist_sdo (bist_sdo),
+
+ // FUNCTIONAL CTRL SIGNAL
+ .func_clk_a (func_clk_a ),
+ .func_cen_a (func_cen_a ),
+ .func_addr_a (func_addr_a ),
+ // Common for func and Mbist i/f
+ .func_dout_a (func_dout_a ),
+
+ .func_clk_b (func_clk_b ),
+ .func_cen_b (func_cen_b ),
+ .func_web_b (func_web_b ),
+ .func_mask_b (func_mask_b ),
+ .func_addr_b (func_addr_b ),
+ .func_din_b (func_din_b ),
+
+
+ // towards memory
+ // Memory Out Port
+ .mem_clk_a (mem_clk_a ),
+ .mem_cen_a (mem_cen_a ),
+ .mem_addr_a (mem_addr_a ),
+ .mem_dout_a (mem_dout_a ),
+
+ // Memory Input Port
+ .mem_clk_b (mem_clk_b ),
+ .mem_cen_b (mem_cen_b ),
+ .mem_web_b (mem_web_b ),
+ .mem_mask_b (mem_mask_b ),
+ .mem_addr_b (mem_addr_b ),
+ .mem_din_b (mem_din_b )
+ );
+
+
+endmodule
+
diff --git a/verilog/rtl/mbist/src/top/mbist_top2.sv b/verilog/rtl/mbist/src/top/mbist_top2.sv
new file mode 100644
index 0000000..89433df
--- /dev/null
+++ b/verilog/rtl/mbist/src/top/mbist_top2.sv
@@ -0,0 +1,479 @@
+//////////////////////////////////////////////////////////////////////////////
+// SPDX-FileCopyrightText: 2021 , Dinesh Annayya
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+// SPDX-License-Identifier: Apache-2.0
+// SPDX-FileContributor: Created by Dinesh Annayya <dinesha@opencores.org>
+//
+//////////////////////////////////////////////////////////////////////
+//// ////
+//// MBIST TOP ////
+//// ////
+//// This file is part of the mbist_ctrl cores project ////
+//// https://github.com/dineshannayya/mbist_ctrl.git ////
+//// ////
+//// Description ////
+//// This block integrate mbist controller with row ////
+//// redendency feature ////
+//// ////
+//// To Do: ////
+//// nothing ////
+//// ////
+//// Author(s): ////
+//// - Dinesh Annayya, dinesha@opencores.org ////
+//// ////
+//// Revision : ////
+//// 0.0 - 11th Oct 2021, Dinesh A ////
+//// Initial integration ////
+//// 0.1 - 26th Oct 2021, Dinesh A ////
+//// Fixed Error Address are serial shifted through ////
+//// sdi/sdo ////
+//// ////
+//////////////////////////////////////////////////////////////////////
+
+`include "mbist_def.svh"
+module mbist_top2
+ #( parameter SCW = 8, // SCAN CHAIN WIDTH
+ parameter BIST_ADDR_WD = 8,
+ parameter BIST_DATA_WD = 32,
+ parameter BIST_ADDR_START = 8'h00,
+ parameter BIST_ADDR_END = 8'hFB,
+ parameter BIST_REPAIR_ADDR_START = 8'hFC,
+ parameter BIST_RAD_WD_I = BIST_ADDR_WD,
+ parameter BIST_RAD_WD_O = BIST_ADDR_WD) (
+
+`ifdef USE_POWER_PINS
+ inout vccd1, // User area 1 1.8V supply
+ inout vssd1, // User area 1 digital ground
+`endif
+
+ // Scan I/F
+ input logic scan_en,
+ input logic scan_mode,
+ input logic [SCW-1:0] scan_si,
+ output logic [SCW-1:0] scan_so,
+ output logic scan_en_o,
+ output logic scan_mode_o,
+
+ // Clock Skew Adjust
+ input logic wbd_clk_int,
+ output logic wbd_clk_mbist,
+ input logic [3:0] cfg_cska_mbist, // clock skew adjust for web host
+
+ input logic rst_n,
+
+ // MBIST I/F
+ input logic bist_en,
+ input logic bist_run,
+ input logic bist_shift,
+ input logic bist_load,
+ input logic bist_sdi,
+
+ output logic [3:0] bist_error_cnt,
+ output logic bist_correct,
+ output logic bist_error,
+ output logic bist_done,
+ output logic bist_sdo,
+
+
+ // WB I/F
+ input logic wb_clk_i, // System clock
+ input logic wb_cyc_i, // strobe/request
+ input logic wb_stb_i, // strobe/request
+ input logic [BIST_ADDR_WD-1:0] wb_adr_i, // address
+ input logic wb_we_i , // write
+ input logic [BIST_DATA_WD-1:0] wb_dat_i, // data output
+ input logic [BIST_DATA_WD/8-1:0] wb_sel_i, // byte enable
+ output logic [BIST_DATA_WD-1:0] wb_dat_o, // data input
+ output logic wb_ack_o, // acknowlegement
+ output logic wb_err_o, // error
+
+ // towards memory
+ // PORT-A
+ output logic mem_clk_a,
+ output logic [BIST_ADDR_WD-1:0]mem_addr_a,
+ output logic mem_cen_a,
+ output logic [BIST_DATA_WD-1:0]mem_din_b,
+ // PORT-B
+ output logic mem_clk_b,
+ output logic mem_cen_b,
+ output logic mem_web_b,
+ output logic [BIST_DATA_WD/8-1:0]mem_mask_b,
+ output logic [BIST_ADDR_WD-1:0]mem_addr_b,
+ input logic [BIST_DATA_WD-1:0]mem_dout_a
+
+
+
+
+);
+
+// FUNCTIONAL A PORT
+logic func_clk_a;
+logic func_cen_a;
+logic [BIST_ADDR_WD-1:0]func_addr_a;
+logic [BIST_DATA_WD-1:0]func_dout_a;
+
+// Functional B Port
+logic func_clk_b;
+logic func_cen_b;
+logic func_web_b;
+logic [BIST_DATA_WD/8-1:0]func_mask_b;
+logic [BIST_ADDR_WD-1:0]func_addr_b;
+logic [BIST_DATA_WD-1:0]func_din_b;
+//----------------------------------------------------
+// Local variable defination
+// ---------------------------------------------------
+//
+logic srst_n ; // sync reset w.r.t bist_clk
+logic cmd_phase ; // Command Phase
+logic cmp_phase ; // Compare Phase
+logic run_op ; // Run next Operation
+logic run_addr ; // Run Next Address
+logic run_sti ; // Run Next Stimulus
+logic run_pat ; // Run Next Pattern
+logic op_updown ; // Adress updown direction
+logic last_addr ; // last address indication
+logic last_sti ; // last stimulus
+logic last_op ; // last operation
+logic last_pat ; // last pattern
+logic [BIST_DATA_WD-1:0] pat_data ; // Selected Data Pattern
+logic [BIST_STI_WD-1:0] stimulus ; // current stimulus
+logic compare ; // compare data
+logic op_repeatflag;
+logic op_reverse;
+logic op_read ;
+logic op_write ;
+logic op_invert ;
+
+//---------------------------------
+// SDI => SDO diasy chain
+// bist_sdi => bist_addr_sdo => bist_sti_sdo => bist_op_sdo => bist_pat_sdo => bist_sdo
+// ---------------------------------
+logic bist_addr_sdo ;
+logic bist_sti_sdo ;
+logic bist_op_sdo ;
+logic bist_pat_sdo ;
+
+logic bist_error_correct ;
+logic [BIST_ADDR_WD-1:0]bist_error_addr ; // bist address
+
+logic [BIST_ADDR_WD-1:0]bist_addr ; // bist address
+logic [BIST_DATA_WD-1:0] bist_wdata ; // bist write data
+logic bist_wr ;
+logic bist_rd ;
+
+assign scan_en_o = scan_en;
+assign scan_mode_o = scan_mode;
+
+assign bist_wr = (cmd_phase && op_write);
+assign bist_rd = (cmd_phase && op_read);
+
+assign compare = (cmp_phase && op_read);
+assign bist_wdata = (op_invert) ? ~pat_data : pat_data;
+
+// Clock Tree branching to avoid clock latency towards SRAM path
+wire wb_clk_b1,wb_clk_b2;
+ctech_clk_buf u_cts_wb_clk_b1 (.A (wb_clk_i), . X(wb_clk_b1));
+ctech_clk_buf u_cts_wb_clk_b2 (.A (wb_clk_i), . X(wb_clk_b2));
+
+// wb_host clock skew control
+clk_skew_adjust u_skew_mbist
+ (
+`ifdef USE_POWER_PINS
+ .vccd1 (vccd1 ),// User area 1 1.8V supply
+ .vssd1 (vssd1 ),// User area 1 digital ground
+`endif
+ .clk_in (wbd_clk_int ),
+ .sel (cfg_cska_mbist ),
+ .clk_out (wbd_clk_mbist )
+ );
+
+reset_sync u_reset_sync (
+ .scan_mode (scan_mode ),
+ .dclk (wb_clk_b1 ), // Destination clock domain
+ .arst_n (rst_n ), // active low async reset
+ .srst_n (srst_n )
+ );
+
+
+
+// bist main control FSM
+
+mbist_fsm
+ #(
+ .BIST_ADDR_WD (BIST_ADDR_WD ),
+ .BIST_DATA_WD (BIST_DATA_WD ),
+ .BIST_ADDR_START (BIST_ADDR_START ),
+ .BIST_ADDR_END (BIST_ADDR_END ),
+ .BIST_REPAIR_ADDR_START (BIST_REPAIR_ADDR_START ),
+ .BIST_RAD_WD_I (BIST_RAD_WD_I ),
+ .BIST_RAD_WD_O (BIST_RAD_WD_O )
+ )
+ u_fsm (
+
+ .cmd_phase (cmd_phase ),
+ .cmp_phase (cmp_phase ),
+ .run_op (run_op ),
+ .run_addr (run_addr ),
+ .run_sti (run_sti ),
+ .run_pat (run_pat ),
+ .bist_done (bist_done ),
+
+
+ .clk (wb_clk_b1 ),
+ .rst_n (srst_n ),
+ .bist_run (bist_run ),
+ .last_op (last_op ),
+ .last_addr (last_addr ),
+ .last_sti (last_sti ),
+ .last_pat (last_pat ),
+ .op_reverse (op_reverse ),
+ .bist_error (bist_error )
+);
+
+
+// bist address generation
+mbist_addr_gen
+ #(
+ .BIST_ADDR_WD (BIST_ADDR_WD ),
+ .BIST_DATA_WD (BIST_DATA_WD ),
+ .BIST_ADDR_START (BIST_ADDR_START ),
+ .BIST_ADDR_END (BIST_ADDR_END ),
+ .BIST_REPAIR_ADDR_START (BIST_REPAIR_ADDR_START ),
+ .BIST_RAD_WD_I (BIST_RAD_WD_I ),
+ .BIST_RAD_WD_O (BIST_RAD_WD_O )
+ )
+ u_addr_gen(
+ .last_addr (last_addr ),
+ .bist_addr (bist_addr ),
+ .sdo (bist_addr_sdo ),
+
+ .clk (wb_clk_b1 ),
+ .rst_n (srst_n ),
+ .run (run_addr ),
+ .updown (op_updown ),
+ .scan_shift (bist_shift ),
+ .scan_load (bist_load ),
+ .sdi (bist_sdi )
+
+);
+
+
+// BIST current stimulus selection
+mbist_sti_sel
+ #(
+ .BIST_ADDR_WD (BIST_ADDR_WD ),
+ .BIST_DATA_WD (BIST_DATA_WD ),
+ .BIST_ADDR_START (BIST_ADDR_START ),
+ .BIST_ADDR_END (BIST_ADDR_END ),
+ .BIST_REPAIR_ADDR_START (BIST_REPAIR_ADDR_START ),
+ .BIST_RAD_WD_I (BIST_RAD_WD_I ),
+ .BIST_RAD_WD_O (BIST_RAD_WD_O )
+ )
+ u_sti_sel(
+
+ .sdo (bist_sti_sdo ),
+ .last_stimulus (last_sti ),
+ .stimulus (stimulus ),
+
+ .clk (wb_clk_b1 ),
+ .rst_n (srst_n ),
+ .scan_shift (bist_shift ),
+ .sdi (bist_addr_sdo ),
+ .run (run_sti )
+
+);
+
+
+// Bist Operation selection
+mbist_op_sel
+ #(
+ .BIST_ADDR_WD (BIST_ADDR_WD ),
+ .BIST_DATA_WD (BIST_DATA_WD ),
+ .BIST_ADDR_START (BIST_ADDR_START ),
+ .BIST_ADDR_END (BIST_ADDR_END ),
+ .BIST_REPAIR_ADDR_START (BIST_REPAIR_ADDR_START ),
+ .BIST_RAD_WD_I (BIST_RAD_WD_I ),
+ .BIST_RAD_WD_O (BIST_RAD_WD_O )
+ )
+ u_op_sel (
+
+ .op_read (op_read ),
+ .op_write (op_write ),
+ .op_invert (op_invert ),
+ .op_updown (op_updown ),
+ .op_reverse (op_reverse ),
+ .op_repeatflag (op_repeatflag ),
+ .sdo (bist_op_sdo ),
+ .last_op (last_op ),
+
+ .clk (wb_clk_b1 ),
+ .rst_n (srst_n ),
+ .scan_shift (bist_shift ),
+ .sdi (bist_sti_sdo ),
+ .re_init (bist_error_correct ),
+ .run (run_op ),
+ .stimulus (stimulus )
+
+ );
+
+
+
+mbist_pat_sel
+ #(
+ .BIST_ADDR_WD (BIST_ADDR_WD ),
+ .BIST_DATA_WD (BIST_DATA_WD ),
+ .BIST_ADDR_START (BIST_ADDR_START ),
+ .BIST_ADDR_END (BIST_ADDR_END ),
+ .BIST_REPAIR_ADDR_START (BIST_REPAIR_ADDR_START ),
+ .BIST_RAD_WD_I (BIST_RAD_WD_I ),
+ .BIST_RAD_WD_O (BIST_RAD_WD_O )
+ )
+ u_pat_sel (
+ .pat_last (last_pat ),
+ .pat_data (pat_data ),
+ .sdo (bist_pat_sdo ),
+ .clk (wb_clk_b1 ),
+ .rst_n (srst_n ),
+ .run (run_pat ),
+ .scan_shift (bist_shift ),
+ .sdi (bist_op_sdo )
+
+ );
+
+
+mbist_data_cmp
+ #(
+ .BIST_ADDR_WD (BIST_ADDR_WD ),
+ .BIST_DATA_WD (BIST_DATA_WD ),
+ .BIST_ADDR_START (BIST_ADDR_START ),
+ .BIST_ADDR_END (BIST_ADDR_END ),
+ .BIST_REPAIR_ADDR_START (BIST_REPAIR_ADDR_START ),
+ .BIST_RAD_WD_I (BIST_RAD_WD_I ),
+ .BIST_RAD_WD_O (BIST_RAD_WD_O )
+ )
+
+
+ u_cmp (
+ .error (bist_error ),
+ .error_correct (bist_error_correct ),
+ .correct ( ), // same signal available at bist mux
+ .error_addr (bist_error_addr ),
+ .error_cnt (bist_error_cnt ),
+ .clk (wb_clk_b1 ),
+ .rst_n (srst_n ),
+ .addr_inc_phase (run_addr ),
+ .compare (compare ),
+ .read_invert (op_invert ),
+ .comp_data (pat_data ),
+ .rxd_data (func_dout_a ),
+ .addr (bist_addr )
+
+ );
+
+
+mbist_mem_wrapper #(
+ .BIST_ADDR_WD (BIST_ADDR_WD ),
+ .BIST_DATA_WD (BIST_DATA_WD )
+ ) u_mem_wrapper(
+ .rst_n (srst_n ),
+ // WB I/F
+ .wb_clk_i (wb_clk_b2 ), // System clock
+ .wb_cyc_i (wb_cyc_i ), // strobe/request
+ .wb_stb_i (wb_stb_i ), // strobe/request
+ .wb_adr_i (wb_adr_i ), // address
+ .wb_we_i (wb_we_i ), // write
+ .wb_dat_i (wb_dat_i ), // data output
+ .wb_sel_i (wb_sel_i ), // byte enable
+ .wb_dat_o (wb_dat_o ), // data input
+ .wb_ack_o (wb_ack_o ), // acknowlegement
+ .wb_err_o (wb_err_o ), // error
+ // MEM A PORT
+ .func_clk_a (func_clk_a ),
+ .func_cen_a (func_cen_a ),
+ .func_addr_a (func_addr_a ),
+ .func_dout_a (func_dout_a ),
+
+ // Functional B Port
+ .func_clk_b (func_clk_b ),
+ .func_cen_b (func_cen_b ),
+ .func_web_b (func_web_b ),
+ .func_mask_b (func_mask_b ),
+ .func_addr_b (func_addr_b ),
+ .func_din_b (func_din_b )
+ );
+
+
+mbist_mux
+ #(
+ .BIST_ADDR_WD (BIST_ADDR_WD ),
+ .BIST_DATA_WD (BIST_DATA_WD ),
+ .BIST_ADDR_START (BIST_ADDR_START ),
+ .BIST_ADDR_END (BIST_ADDR_END ),
+ .BIST_REPAIR_ADDR_START (BIST_REPAIR_ADDR_START ),
+ .BIST_RAD_WD_I (BIST_RAD_WD_I ),
+ .BIST_RAD_WD_O (BIST_RAD_WD_O )
+ )
+ u_mem_sel (
+
+ .scan_mode (scan_mode ),
+
+ .rst_n (srst_n ),
+ // MBIST CTRL SIGNAL
+ .bist_en (bist_en ),
+ .bist_addr (bist_addr ),
+ .bist_wdata (bist_wdata ),
+ .bist_clk (wb_clk_b2 ),
+ .bist_wr (bist_wr ),
+ .bist_rd (bist_rd ),
+ .bist_error (bist_error_correct),
+ .bist_error_addr (bist_error_addr),
+ .bist_correct (bist_correct ),
+ .bist_sdi (bist_pat_sdo),
+ .bist_shift (bist_shift),
+ .bist_sdo (bist_sdo),
+
+ // FUNCTIONAL CTRL SIGNAL
+ .func_clk_a (func_clk_a ),
+ .func_cen_a (func_cen_a ),
+ .func_addr_a (func_addr_a ),
+ // Common for func and Mbist i/f
+ .func_dout_a (func_dout_a ),
+
+ .func_clk_b (func_clk_b ),
+ .func_cen_b (func_cen_b ),
+ .func_web_b (func_web_b ),
+ .func_mask_b (func_mask_b ),
+ .func_addr_b (func_addr_b ),
+ .func_din_b (func_din_b ),
+
+
+ // towards memory
+ // Memory Out Port
+ .mem_clk_a (mem_clk_a ),
+ .mem_cen_a (mem_cen_a ),
+ .mem_addr_a (mem_addr_a ),
+ .mem_dout_a (mem_dout_a ),
+
+ // Memory Input Port
+ .mem_clk_b (mem_clk_b ),
+ .mem_cen_b (mem_cen_b ),
+ .mem_web_b (mem_web_b ),
+ .mem_mask_b (mem_mask_b ),
+ .mem_addr_b (mem_addr_b ),
+ .mem_din_b (mem_din_b )
+ );
+
+
+endmodule
+
diff --git a/verilog/rtl/mbist_wrapper/src/mbist_wb.sv b/verilog/rtl/mbist_wrapper/src/mbist_wb.sv
new file mode 100644
index 0000000..ef989dd
--- /dev/null
+++ b/verilog/rtl/mbist_wrapper/src/mbist_wb.sv
@@ -0,0 +1,179 @@
+//////////////////////////////////////////////////////////////////////////////
+// SPDX-FileCopyrightText: 2021 , Dinesh Annayya
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+// SPDX-License-Identifier: Apache-2.0
+// SPDX-FileContributor: Created by Dinesh Annayya <dinesha@opencores.org>
+//
+//////////////////////////////////////////////////////////////////////
+//
+// MBIST wishbone Burst access to SRAM Write and Read access
+// Note: BUSRT crossing the SRAM boundary is not supported due to sram
+// 2 cycle pipe line delay
+//////////////////////////////////////////////////////////////////////
+
+module mbist_wb
+ #(
+ parameter BIST_NO_SRAM = 4,
+ parameter BIST_ADDR_WD = 9,
+ parameter BIST_DATA_WD = 32) (
+
+`ifdef USE_POWER_PINS
+ inout vccd1, // User area 1 1.8V supply
+ inout vssd1, // User area 1 digital ground
+`endif
+
+
+ input logic rst_n,
+
+
+ // WB I/F
+ input logic wb_clk_i, // System clock
+ input logic wb_stb_i, // strobe/request
+ input logic [BIST_ADDR_WD-1:0] wb_adr_i, // address
+ input logic [(BIST_NO_SRAM+1)/2-1:0] wb_cs_i, // address
+ input logic wb_we_i , // write
+ input logic [BIST_DATA_WD-1:0] wb_dat_i, // data output
+ input logic [BIST_DATA_WD/8-1:0] wb_sel_i, // byte enable
+ input logic [9:0] wb_bl_i, // Burst Length
+ input logic wb_bry_i, // Burst Ready
+ output logic [BIST_DATA_WD-1:0] wb_dat_o, // data input
+ output logic wb_ack_o, // acknowlegement
+ output logic wb_lack_o, // acknowlegement
+ output logic wb_err_o, // error
+
+ output logic mem_req,
+ output logic [(BIST_NO_SRAM+1)/2-1:0] mem_cs,
+ output logic [BIST_ADDR_WD-1:0] mem_addr,
+ output logic [31:0] mem_wdata,
+ output logic mem_we,
+ output logic [3:0] mem_wmask,
+ input logic [31:0] mem_rdata
+
+
+
+
+);
+
+parameter IDLE = 2'b00;
+parameter WRITE_ACTION = 2'b01;
+parameter READ_ACTION1 = 2'b10;
+parameter READ_ACTION2 = 2'b11;
+
+
+logic [9:0] mem_bl_cnt ;
+logic wb_ack_l ;
+logic [BIST_ADDR_WD-1:0] mem_next_addr;
+logic [1:0] state;
+logic mem_hval; // Mem Hold Data valid
+logic [31:0] mem_hdata; // Mem Hold Data
+
+
+assign mem_wdata = wb_dat_i;
+
+always @(negedge rst_n, posedge wb_clk_i) begin
+ if (~rst_n) begin
+ mem_bl_cnt <= 'h0;
+ mem_addr <= 'h0;
+ mem_next_addr <= 'h0;
+ wb_ack_l <= 'b0;
+ wb_dat_o <= 'h0;
+ mem_req <= 'b0;
+ mem_cs <= 'b0;
+ mem_wmask <= 'h0;
+ mem_we <= 'h0;
+ mem_hval <= 'b0;
+ mem_hdata <= 'h0;
+ state <= IDLE;
+ end else begin
+ case(state)
+ IDLE: begin
+ mem_bl_cnt <= 'h1;
+ wb_ack_o <= 'b0;
+ wb_lack_o <= 'b0;
+ if(wb_stb_i && wb_bry_i && ~wb_we_i && !wb_lack_o) begin
+ mem_cs <= wb_cs_i;
+ mem_addr <= wb_adr_i;
+ mem_req <= 'b1;
+ mem_we <= 'b0;
+ state <= READ_ACTION1;
+ end else if(wb_stb_i && wb_bry_i && wb_we_i && !wb_lack_o) begin
+ mem_cs <= wb_cs_i;
+ mem_next_addr<= wb_adr_i;
+ mem_we <= 'b1;
+ mem_wmask <= wb_sel_i;
+ state <= WRITE_ACTION;
+ end else begin
+ mem_req <= 1'b0;
+ end
+ end
+
+ WRITE_ACTION: begin
+ if (wb_stb_i && wb_bry_i ) begin
+ wb_ack_o <= 'b1;
+ mem_req <= 1'b1;
+ mem_addr <= mem_next_addr;
+ if((wb_stb_i && wb_bry_i ) && (wb_bl_i == mem_bl_cnt)) begin
+ wb_lack_o <= 'b1;
+ state <= IDLE;
+ end else begin
+ mem_bl_cnt <= mem_bl_cnt+1;
+ mem_next_addr<= mem_next_addr+1;
+ end
+ end else begin
+ wb_ack_o <= 'b0;
+ mem_req <= 1'b0;
+ end
+ end
+ READ_ACTION1: begin
+ mem_addr <= mem_addr +1;
+ mem_hval <= 1'b0;
+ wb_ack_l <= 'b1;
+ mem_bl_cnt <= 'h1;
+ state <= READ_ACTION2;
+ end
+
+ // Wait for Ack from application layer
+ READ_ACTION2: begin
+ // If the not the last ack, update memory pointer
+ // accordingly
+ wb_ack_l <= wb_ack_o;
+ if (wb_stb_i && wb_bry_i ) begin
+ wb_ack_o <= 1'b1;
+ mem_bl_cnt <= mem_bl_cnt+1;
+ mem_addr <= mem_addr +1;
+ if(wb_ack_l || wb_ack_o ) begin // If back to back ack
+ wb_dat_o <= mem_rdata;
+ mem_hval <= 1'b0;
+ end else begin // Pick from previous holding data
+ mem_hval <= 1'b1;
+ wb_dat_o <= mem_hdata;
+ mem_hdata <= mem_rdata;
+ end
+ if((wb_stb_i && wb_bry_i ) && (wb_bl_i == mem_bl_cnt)) begin
+ wb_lack_o <= 1'b1;
+ state <= IDLE;
+ end
+ end else begin
+ wb_ack_o <= 1'b0;
+ if(!mem_hval) begin
+ mem_hdata <= mem_rdata;
+ mem_hval <= 1'b1;
+ end
+ end
+ end
+ endcase
+ end
+end
+
+endmodule
diff --git a/verilog/rtl/mbist_wrapper/src/mbist_wrapper.sv b/verilog/rtl/mbist_wrapper/src/mbist_wrapper.sv
new file mode 100644
index 0000000..07c5ce3
--- /dev/null
+++ b/verilog/rtl/mbist_wrapper/src/mbist_wrapper.sv
@@ -0,0 +1,369 @@
+//////////////////////////////////////////////////////////////////////////////
+// SPDX-FileCopyrightText: 2021 , Dinesh Annayya
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+// SPDX-License-Identifier: Apache-2.0
+// SPDX-FileContributor: Created by Dinesh Annayya <dinesha@opencores.org>
+//
+//////////////////////////////////////////////////////////////////////
+//// ////
+//// MBIST TOP ////
+//// ////
+//// This file is part of the mbist_ctrl cores project ////
+//// https://github.com/dineshannayya/mbist_ctrl.git ////
+//// ////
+//// Description ////
+//// This block integrate mbist controller with row ////
+//// redendency feature ////
+//// ////
+//// To Do: ////
+//// nothing ////
+//// ////
+//// Author(s): ////
+//// - Dinesh Annayya, dinesha@opencores.org ////
+//// ////
+//// Revision : ////
+//// 0.0 - 11th Oct 2021, Dinesh A ////
+//// Initial integration ////
+//// 0.1 - 26th Oct 2021, Dinesh A ////
+//// Fixed Error Address are serial shifted through ////
+//// sdi/sdo ////
+//// 0.2 - 15 Dec 2021, Dinesh A ////
+//// Added support for common MBIST for 4 SRAM ////
+//// 0.3 - 29th Dec 2021, Dinesh A ////
+//// yosys synthesis issue for two dimension variable ////
+//// changed the variable defination from logic to wire ////
+//// ////
+//////////////////////////////////////////////////////////////////////
+
+`include "mbist_def.svh"
+module mbist_wrapper
+ #(
+ parameter BIST_NO_SRAM = 4,
+ parameter BIST_ADDR_WD = 9,
+ parameter BIST_DATA_WD = 32,
+ parameter BIST_ADDR_START = 9'h000,
+ parameter BIST_ADDR_END = 9'h1FB,
+ parameter BIST_REPAIR_ADDR_START = 9'h1FC,
+ parameter BIST_RAD_WD_I = BIST_ADDR_WD,
+ parameter BIST_RAD_WD_O = BIST_ADDR_WD) (
+
+`ifdef USE_POWER_PINS
+ inout vccd1, // User area 1 1.8V supply
+ inout vssd1, // User area 1 digital ground
+`endif
+
+ // Clock Skew Adjust
+ input wire wbd_clk_int,
+ output wire wbd_clk_mbist,
+ input wire [3:0] cfg_cska_mbist, // clock skew adjust for web host
+
+ input logic rst_n,
+
+ // MBIST I/F
+ input wire bist_en,
+ input wire bist_run,
+ input wire bist_shift,
+ input wire bist_load,
+ input wire bist_sdi,
+
+ output wire [3:0] bist_error_cnt0,
+ output wire [3:0] bist_error_cnt1,
+ output wire [3:0] bist_error_cnt2,
+ output wire [3:0] bist_error_cnt3,
+ output wire [BIST_NO_SRAM-1:0] bist_correct ,
+ output wire [BIST_NO_SRAM-1:0] bist_error ,
+ output wire bist_done,
+ output wire bist_sdo,
+
+
+ // WB I/F
+ input wire wb_clk_i, // System clock
+ input wire wb_clk2_i, // System clock2 is no cts
+ input wire wb_stb_i, // strobe/request
+ input wire [(BIST_NO_SRAM+1)/2-1:0] wb_cs_i,
+ input wire [BIST_ADDR_WD-1:0] wb_adr_i, // address
+ input wire wb_we_i , // write
+ input wire [BIST_DATA_WD-1:0] wb_dat_i, // data output
+ input wire [BIST_DATA_WD/8-1:0] wb_sel_i, // byte enable
+ input wire [9:0] wb_bl_i, // burst
+ input wire wb_bry_i, // burst ready
+ output wire [BIST_DATA_WD-1:0] wb_dat_o, // data input
+ output wire wb_ack_o, // acknowlegement
+ output wire wb_lack_o, // acknowlegement
+ output wire wb_err_o, // error
+
+
+ // towards memory
+ // PORT-A
+ output wire [BIST_NO_SRAM-1:0] mem_clk_a,
+ output wire [BIST_ADDR_WD-1:0] mem_addr_a0,
+ output wire [BIST_ADDR_WD-1:0] mem_addr_a1,
+ output wire [BIST_ADDR_WD-1:0] mem_addr_a2,
+ output wire [BIST_ADDR_WD-1:0] mem_addr_a3,
+ output wire [BIST_NO_SRAM-1:0] mem_cen_a,
+ output wire [BIST_NO_SRAM-1:0] mem_web_a,
+ output wire [BIST_DATA_WD/8-1:0] mem_mask_a0,
+ output wire [BIST_DATA_WD/8-1:0] mem_mask_a1,
+ output wire [BIST_DATA_WD/8-1:0] mem_mask_a2,
+ output wire [BIST_DATA_WD/8-1:0] mem_mask_a3,
+ output wire [BIST_DATA_WD-1:0] mem_din_a0,
+ output wire [BIST_DATA_WD-1:0] mem_din_a1,
+ output wire [BIST_DATA_WD-1:0] mem_din_a2,
+ output wire [BIST_DATA_WD-1:0] mem_din_a3,
+
+ input wire [BIST_DATA_WD-1:0] mem_dout_a0,
+ input wire [BIST_DATA_WD-1:0] mem_dout_a1,
+ input wire [BIST_DATA_WD-1:0] mem_dout_a2,
+ input wire [BIST_DATA_WD-1:0] mem_dout_a3,
+
+
+ // PORT-B
+ output wire [BIST_NO_SRAM-1:0] mem_clk_b,
+ output wire [BIST_NO_SRAM-1:0] mem_cen_b,
+ output wire [BIST_ADDR_WD-1:0] mem_addr_b0,
+ output wire [BIST_ADDR_WD-1:0] mem_addr_b1,
+ output wire [BIST_ADDR_WD-1:0] mem_addr_b2,
+ output wire [BIST_ADDR_WD-1:0] mem_addr_b3
+
+
+
+);
+
+parameter NO_SRAM_WD = (BIST_NO_SRAM+1)/2;
+parameter BIST1_ADDR_WD = 11; // 512x32 SRAM
+
+logic mem_req; // strobe/request
+logic [(BIST_NO_SRAM+1)/2-1:0] mem_cs;
+logic [BIST_ADDR_WD-1:0] mem_addr; // address
+logic mem_we ; // write
+logic [BIST_DATA_WD-1:0] mem_wdata; // data output
+logic [BIST_DATA_WD/8-1:0] mem_wmask; // byte enable
+logic [BIST_DATA_WD-1:0] mem_rdata; // data input
+
+
+mbist_wb #(
+ .BIST_NO_SRAM (4 ),
+ .BIST_ADDR_WD (BIST1_ADDR_WD-2 ),
+ .BIST_DATA_WD (BIST_DATA_WD )
+ )
+ u_wb (
+
+`ifdef USE_POWER_PINS
+ .vccd1 (vccd1 ),// User area 1 1.8V supply
+ .vssd1 (vssd1 ),// User area 1 digital ground
+`endif
+
+ .rst_n (rst_n ),
+ // WB I/F
+ .wb_clk_i (wb_clk_i ),
+ .wb_stb_i (wb_stb_i ),
+ .wb_cs_i (wb_cs_i ),
+ .wb_adr_i (wb_adr_i ),
+ .wb_we_i (wb_we_i ),
+ .wb_dat_i (wb_dat_i ),
+ .wb_sel_i (wb_sel_i ),
+ .wb_bl_i (wb_bl_i ),
+ .wb_bry_i (wb_bry_i ),
+ .wb_dat_o (wb_dat_o ),
+ .wb_ack_o (wb_ack_o ),
+ .wb_lack_o (wb_lack_o ),
+ .wb_err_o ( ),
+
+ .mem_req (mem_req ),
+ .mem_cs (mem_cs ),
+ .mem_addr (mem_addr ),
+ .mem_we (mem_we ),
+ .mem_wdata (mem_wdata ),
+ .mem_wmask (mem_wmask ),
+ .mem_rdata (mem_rdata )
+
+
+
+
+);
+
+
+mbist_top #(
+ `ifndef SYNTHESIS
+ .BIST_NO_SRAM (4 ),
+ .BIST_ADDR_WD (BIST1_ADDR_WD-2 ),
+ .BIST_DATA_WD (BIST_DATA_WD ),
+ .BIST_ADDR_START (9'h000 ),
+ .BIST_ADDR_END (9'h1FB ),
+ .BIST_REPAIR_ADDR_START (9'h1FC ),
+ .BIST_RAD_WD_I (BIST1_ADDR_WD-2 ),
+ .BIST_RAD_WD_O (BIST1_ADDR_WD-2 )
+ `endif
+ )
+ u_mbist (
+
+`ifdef USE_POWER_PINS
+ .vccd1 (vccd1 ),// User area 1 1.8V supply
+ .vssd1 (vssd1 ),// User area 1 digital ground
+`endif
+
+ // Clock Skew adjust
+ .wbd_clk_int (wbd_clk_int ),
+ .cfg_cska_mbist (cfg_cska_mbist ),
+ .wbd_clk_mbist (wbd_clk_mbist ),
+
+ // WB I/F
+ .wb_clk2_i (wb_clk2_i ),
+ .wb_clk_i (wb_clk_i ),
+ .mem_req (mem_req ),
+ .mem_cs (mem_cs ),
+ .mem_addr (mem_addr ),
+ .mem_we (mem_we ),
+ .mem_wdata (mem_wdata ),
+ .mem_wmask (mem_wmask ),
+ .mem_rdata (mem_rdata ),
+
+ .rst_n (rst_n ),
+
+
+ .bist_en (bist_en ),
+ .bist_run (bist_run ),
+ .bist_shift (bist_shift ),
+ .bist_load (bist_load ),
+ .bist_sdi (bist_sdi ),
+
+ .bist_error_cnt3 (bist_error_cnt3 ),
+ .bist_error_cnt2 (bist_error_cnt2 ),
+ .bist_error_cnt1 (bist_error_cnt1 ),
+ .bist_error_cnt0 (bist_error_cnt0 ),
+ .bist_correct (bist_correct ),
+ .bist_error (bist_error ),
+ .bist_done (bist_done ),
+ .bist_sdo (bist_sdo ),
+
+ // towards memory
+ // PORT-A
+ .mem_clk_a (mem_clk_a ),
+ .mem_addr_a0 (mem_addr_a0 ),
+ .mem_addr_a1 (mem_addr_a1 ),
+ .mem_addr_a2 (mem_addr_a2 ),
+ .mem_addr_a3 (mem_addr_a3 ),
+ .mem_cen_a (mem_cen_a ),
+ .mem_web_a (mem_web_a ),
+ .mem_mask_a0 (mem_mask_a0 ),
+ .mem_mask_a1 (mem_mask_a1 ),
+ .mem_mask_a2 (mem_mask_a2 ),
+ .mem_mask_a3 (mem_mask_a3 ),
+ .mem_din_a0 (mem_din_a0 ),
+ .mem_din_a1 (mem_din_a1 ),
+ .mem_din_a2 (mem_din_a2 ),
+ .mem_din_a3 (mem_din_a3 ),
+ .mem_dout_a0 (mem_dout_a0 ),
+ .mem_dout_a1 (mem_dout_a1 ),
+ .mem_dout_a2 (mem_dout_a2 ),
+ .mem_dout_a3 (mem_dout_a3 ),
+ // PORT-B
+ .mem_clk_b (mem_clk_b ),
+ .mem_cen_b (mem_cen_b ),
+ .mem_addr_b0 (mem_addr_b0 ),
+ .mem_addr_b1 (mem_addr_b1 ),
+ .mem_addr_b2 (mem_addr_b2 ),
+ .mem_addr_b3 (mem_addr_b3 )
+
+
+);
+
+
+/**
+sky130_sram_2kbyte_1rw1r_32x512_8 u_sram0_2kb(
+`ifdef USE_POWER_PINS
+ .vccd1 (vccd1),// User area 1 1.8V supply
+ .vssd1 (vssd1),// User area 1 digital ground
+`endif
+// Port 0: RW
+ .clk0 (mem_clk_a[0]),
+ .csb0 (mem_cen_a[0]),
+ .web0 (mem_web_a[0]),
+ .wmask0 (mem0_mask_a),
+ .addr0 (mem0_addr_a),
+ .din0 (mem0_din_a),
+ .dout0 (mem0_dout_a),
+// Port 1: R
+ .clk1 (mem_clk_b[0]),
+ .csb1 (mem_cen_b[0]),
+ .addr1 (mem0_addr_b),
+ .dout1 ()
+ );
+
+sky130_sram_2kbyte_1rw1r_32x512_8 u_sram1_2kb(
+`ifdef USE_POWER_PINS
+ .vccd1 (vccd1),// User area 1 1.8V supply
+ .vssd1 (vssd1),// User area 1 digital ground
+`endif
+// Port 0: RW
+ .clk0 (mem_clk_a[1]),
+ .csb0 (mem_cen_a[1]),
+ .web0 (mem_web_a[1]),
+ .wmask0 (mem1_mask_a),
+ .addr0 (mem1_addr_a),
+ .din0 (mem1_din_a),
+ .dout0 (mem1_dout_a),
+// Port 1: R
+ .clk1 (mem_clk_b[1]),
+ .csb1 (mem_cen_b[1]),
+ .addr1 (mem1_addr_b),
+ .dout1 ()
+ );
+
+sky130_sram_2kbyte_1rw1r_32x512_8 u_sram2_2kb(
+`ifdef USE_POWER_PINS
+ .vccd1 (vccd1),// User area 1 1.8V supply
+ .vssd1 (vssd1),// User area 1 digital ground
+`endif
+// Port 0: RW
+ .clk0 (mem_clk_a[2]),
+ .csb0 (mem_cen_a[2]),
+ .web0 (mem_web_a[2]),
+ .wmask0 (mem2_mask_a),
+ .addr0 (mem2_addr_a),
+ .din0 (mem2_din_a),
+ .dout0 (mem2_dout_a),
+// Port 1: R
+ .clk1 (mem_clk_b[2]),
+ .csb1 (mem_cen_b[2]),
+ .addr1 (mem2_addr_b),
+ .dout1 ()
+ );
+
+
+sky130_sram_2kbyte_1rw1r_32x512_8 u_sram3_2kb(
+`ifdef USE_POWER_PINS
+ .vccd1 (vccd1),// User area 1 1.8V supply
+ .vssd1 (vssd1),// User area 1 digital ground
+`endif
+// Port 0: RW
+ .clk0 (mem_clk_a[3]),
+ .csb0 (mem_cen_a[3]),
+ .web0 (mem_web_a[3]),
+ .wmask0 (mem3_mask_a),
+ .addr0 (mem3_addr_a),
+ .din0 (mem3_din_a),
+ .dout0 (mem3_dout_a),
+// Port 1: R
+ .clk1 (mem_clk_b[3]),
+ .csb1 (mem_cen_b[3]),
+ .addr1 (mem3_addr_b),
+ .dout1 ()
+ );
+
+
+***/
+
+endmodule
+
diff --git a/verilog/rtl/pinmux/src/gpio_control.sv b/verilog/rtl/pinmux/src/gpio_control.sv
new file mode 100644
index 0000000..4c917dc
--- /dev/null
+++ b/verilog/rtl/pinmux/src/gpio_control.sv
@@ -0,0 +1,44 @@
+
+// GPIO Interrupt Generation
+module gpio_intr (
+ input logic mclk ,// System clk
+ input logic h_reset_n ,// system reset
+ input logic [31:0] gpio_prev_indata ,// previously captured GPIO I/P pins data
+ input logic [31:0] cfg_gpio_data_in ,// GPIO I/P pins data captured into this
+ input logic [31:0] cfg_gpio_out_data ,// GPIO statuc O/P data from config reg
+ input logic [31:0] cfg_gpio_dir_sel ,// decides on GPIO pin is I/P or O/P at pad level
+ input logic [31:0] cfg_gpio_posedge_int_sel ,// select posedge interrupt
+ input logic [31:0] cfg_gpio_negedge_int_sel ,// select negedge interrupt
+
+
+ output logic [31:0] pad_gpio_out ,// GPIO O/P to the gpio cfg reg
+ output logic [31:0] gpio_int_event // to the cfg interrupt status reg
+
+);
+
+
+integer i;
+//-----------------------------------------------------------------------
+// Logic for interrupt detection
+//-----------------------------------------------------------------------
+
+reg [31:0] local_gpio_int_event; // to the cfg interrupt status reg
+always @(cfg_gpio_data_in or cfg_gpio_negedge_int_sel or cfg_gpio_posedge_int_sel
+ or gpio_prev_indata)
+begin
+ for (i=0; i<32; i=i+1)
+ begin
+ // looking for rising edge int
+ local_gpio_int_event[i] = ((cfg_gpio_posedge_int_sel[i] & ~gpio_prev_indata[i]
+ & cfg_gpio_data_in[i]) |
+ (cfg_gpio_negedge_int_sel[i] & gpio_prev_indata[i] &
+ ~cfg_gpio_data_in[i]));
+ // looking for falling edge int
+ end
+end
+
+assign gpio_int_event = local_gpio_int_event[31:0]; // goes as O/P to the cfg reg
+
+assign pad_gpio_out = cfg_gpio_out_data[31:0] ;// O/P on the GPIO bus
+
+endmodule
diff --git a/verilog/rtl/pinmux/src/gpio_intr.sv b/verilog/rtl/pinmux/src/gpio_intr.sv
new file mode 100644
index 0000000..331918d
--- /dev/null
+++ b/verilog/rtl/pinmux/src/gpio_intr.sv
@@ -0,0 +1,43 @@
+
+// GPIO Interrupt Generation
+module gpio_intr (
+ input logic mclk ,// System clk
+ input logic h_reset_n ,// system reset
+ input logic [31:0] gpio_prev_indata ,// previously captured GPIO I/P pins data
+ input logic [31:0] cfg_gpio_data_in ,// GPIO I/P pins data captured into this
+ input logic [31:0] cfg_gpio_out_data ,// GPIO statuc O/P data from config reg
+ input logic [31:0] cfg_gpio_dir_sel ,// decides on GPIO pin is I/P or O/P at pad level
+ input logic [31:0] cfg_gpio_posedge_int_sel ,// select posedge interrupt
+ input logic [31:0] cfg_gpio_negedge_int_sel ,// select negedge interrupt
+
+
+ output logic [31:0] pad_gpio_out ,// GPIO O/P to the gpio cfg reg
+ output logic [31:0] gpio_int_event // to the cfg interrupt status reg
+
+);
+
+
+integer i;
+//-----------------------------------------------------------------------
+// Logic for interrupt detection
+//-----------------------------------------------------------------------
+
+reg [31:0] local_gpio_int_event; // to the cfg interrupt status reg
+always_comb
+begin
+ for (i=0; i<32; i=i+1)
+ begin
+ // looking for rising edge int
+ local_gpio_int_event[i] = ((cfg_gpio_posedge_int_sel[i] & ~gpio_prev_indata[i]
+ & cfg_gpio_data_in[i]) |
+ (cfg_gpio_negedge_int_sel[i] & gpio_prev_indata[i] &
+ ~cfg_gpio_data_in[i]));
+ // looking for falling edge int
+ end
+end
+
+assign gpio_int_event = local_gpio_int_event[31:0]; // goes as O/P to the cfg reg
+
+assign pad_gpio_out = cfg_gpio_out_data[31:0] ;// O/P on the GPIO bus
+
+endmodule
diff --git a/verilog/rtl/pinmux/src/pinmux.sv b/verilog/rtl/pinmux/src/pinmux.sv
new file mode 100755
index 0000000..46a69a4
--- /dev/null
+++ b/verilog/rtl/pinmux/src/pinmux.sv
@@ -0,0 +1,801 @@
+//////////////////////////////////////////////////////////////////////////////
+// SPDX-FileCopyrightText: 2021 , Dinesh Annayya
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+// SPDX-License-Identifier: Apache-2.0
+// SPDX-FileContributor: Created by Dinesh Annayya <dinesha@opencores.org>
+//
+//////////////////////////////////////////////////////////////////////
+//// ////
+//// Pinmux ////
+//// ////
+//// This file is part of the riscduino cores project ////
+//// https://github.com/dineshannayya/riscduino.git ////
+//// ////
+//// Description ////
+//// PinMux Manages all the pin multiplexing ////
+//// ////
+//// To Do: ////
+//// nothing ////
+//// ////
+//// Author(s): ////
+//// - Dinesh Annayya, dinesha@opencores.org ////
+//// ////
+//// Revision : ////
+//// 0.1 - 16th Feb 2021, Dinesh A ////
+//// initial version ////
+//////////////////////////////////////////////////////////////////////
+
+module pinmux (
+ `ifdef USE_POWER_PINS
+ input logic vccd1,// User area 1 1.8V supply
+ input logic vssd1,// User area 1 digital ground
+ `endif
+ // clock skew adjust
+ input logic [3:0] cfg_cska_pinmux,
+ input logic wbd_clk_int,
+ output logic wbd_clk_pinmux,
+ // System Signals
+ // Inputs
+ input logic mclk,
+ input logic h_reset_n,
+
+ // Reg Bus Interface Signal
+ input logic reg_cs,
+ input logic reg_wr,
+ input logic [7:0] reg_addr,
+ input logic [31:0] reg_wdata,
+ input logic [3:0] reg_be,
+
+ // Outputs
+ output logic [31:0] reg_rdata,
+ output logic reg_ack,
+
+ // Risc configuration
+ output logic [31:0] fuse_mhartid,
+ output logic [15:0] irq_lines,
+ output logic soft_irq,
+ output logic [2:0] user_irq,
+ input logic usb_intr,
+ input logic i2cm_intr,
+
+ // Digital IO
+ output logic [37:0] digital_io_out,
+ output logic [37:0] digital_io_oen,
+ input logic [37:0] digital_io_in,
+
+ // SFLASH I/F
+ input logic sflash_sck,
+ input logic [3:0] sflash_ss,
+ input logic [3:0] sflash_oen,
+ input logic [3:0] sflash_do,
+ output logic [3:0] sflash_di,
+
+ // SSRAM I/F - Temp Masked
+ //input logic ssram_sck,
+ //input logic ssram_ss,
+ //input logic [3:0] ssram_oen,
+ //input logic [3:0] ssram_do,
+ //output logic [3:0] ssram_di,
+
+ // USB I/F
+ input logic usb_dp_o,
+ input logic usb_dn_o,
+ input logic usb_oen,
+ output logic usb_dp_i,
+ output logic usb_dn_i,
+
+ // UART I/F
+ input logic uart_txd,
+ output logic uart_rxd,
+
+ // I2CM I/F
+ input logic i2cm_clk_o,
+ output logic i2cm_clk_i,
+ input logic i2cm_clk_oen,
+ input logic i2cm_data_oen,
+ input logic i2cm_data_o,
+ output logic i2cm_data_i,
+
+ // SPI MASTER
+ input logic spim_sck,
+ input logic spim_ss,
+ input logic spim_miso,
+ output logic spim_mosi,
+
+ // UART MASTER I/F
+ output logic uartm_rxd ,
+ input logic uartm_txd ,
+
+ output logic pulse1m_mclk,
+ output logic [31:0] pinmux_debug,
+
+ // BIST I/F
+ output logic bist_en,
+ output logic bist_run,
+ output logic bist_load,
+
+ output logic bist_sdi,
+ output logic bist_shift,
+ input logic bist_sdo,
+
+ input logic bist_done,
+ input logic [3:0] bist_error,
+ input logic [3:0] bist_correct,
+ input logic [3:0] bist_error_cnt0,
+ input logic [3:0] bist_error_cnt1,
+ input logic [3:0] bist_error_cnt2,
+ input logic [3:0] bist_error_cnt3
+ );
+
+
+
+
+/* clock pulse */
+//********************************************************
+logic pulse1u_mclk ;// 1 UsSecond Pulse for waveform Generator
+logic pulse1s_mclk ;// 1Second Pulse for waveform Generator
+logic [9:0] cfg_pulse_1us ;// 1us pulse generation config
+
+//---------------------------------------------------
+// 6 PWM variabled
+//---------------------------------------------------
+
+logic [5:0] pwm_wfm ;
+logic [5:0] cfg_pwm_enb ;
+logic [15:0] cfg_pwm0_high ;
+logic [15:0] cfg_pwm0_low ;
+logic [15:0] cfg_pwm1_high ;
+logic [15:0] cfg_pwm1_low ;
+logic [15:0] cfg_pwm2_high ;
+logic [15:0] cfg_pwm2_low ;
+logic [15:0] cfg_pwm3_high ;
+logic [15:0] cfg_pwm3_low ;
+logic [15:0] cfg_pwm4_high ;
+logic [15:0] cfg_pwm4_low ;
+logic [15:0] cfg_pwm5_high ;
+logic [15:0] cfg_pwm5_low ;
+
+
+wire [31:0] gpio_prev_indata ;// previously captured GPIO I/P pins data
+wire [31:0] cfg_gpio_out_data ;// GPIO statuc O/P data from config reg
+wire [31:0] cfg_gpio_dir_sel ;// decides on GPIO pin is I/P or O/P at pad level, 0 -> Input, 1 -> Output
+wire [31:0] cfg_gpio_out_type ;// GPIO Type, Unused
+wire [31:0] cfg_multi_func_sel ;// GPIO Multi function type
+wire [31:0] cfg_gpio_posedge_int_sel ;// select posedge interrupt
+wire [31:0] cfg_gpio_negedge_int_sel ;// select negedge interrupt
+wire [31:00] cfg_gpio_data_in ;
+
+
+reg [7:0] port_a_in; // PORT A Data In
+reg [7:0] port_b_in; // PORT B Data In
+reg [7:0] port_c_in; // PORT C Data In
+reg [7:0] port_d_in; // PORT D Data In
+
+wire [7:0] port_a_out; // PORT A Data Out
+wire [7:0] port_b_out; // PORT B Data Out
+wire [7:0] port_c_out; // PORT C Data Out
+wire [7:0] port_d_out; // PORT D Data Out
+wire [31:0] pad_gpio_in; // GPIO data input from PAD
+wire [31:0] pad_gpio_out; // GPIO Data out towards PAD
+wire [31:0] gpio_int_event; // GPIO Interrupt indication
+reg [1:0] ext_intr_in; // External PAD level interrupt
+
+// GPIO to PORT Mapping
+assign pad_gpio_in[7:0] = port_a_in;
+assign pad_gpio_in[15:8] = port_b_in;
+assign pad_gpio_in[23:16] = port_c_in;
+assign pad_gpio_in[31:24] = port_d_in;
+
+assign port_a_out = pad_gpio_out[7:0];
+assign port_b_out = pad_gpio_out[15:8];
+assign port_c_out = pad_gpio_out[23:16];
+assign port_d_out = pad_gpio_out[31:24];
+
+assign pinmux_debug = '0; // Todo: Need to fix
+
+// SSRAM I/F - Temp masked
+//input logic ssram_sck,
+//input logic ssram_ss,
+//input logic [3:0] ssram_oen,
+//input logic [3:0] ssram_do,
+//output logic [3:0] ssram_di,
+
+// pinmux clock skew control
+clk_skew_adjust u_skew_pinmux
+ (
+`ifdef USE_POWER_PINS
+ .vccd1 (vccd1 ),// User area 1 1.8V supply
+ .vssd1 (vssd1 ),// User area 1 digital ground
+`endif
+ .clk_in (wbd_clk_int ),
+ .sel (cfg_cska_pinmux ),
+ .clk_out (wbd_clk_pinmux )
+ );
+
+gpio_intr u_gpio_intr (
+ // System Signals
+ // Inputs
+ .mclk (mclk ),
+ .h_reset_n (h_reset_n ),
+
+ // GPIO cfg input pins
+ .gpio_prev_indata (gpio_prev_indata ),
+ .cfg_gpio_data_in (cfg_gpio_data_in ),
+ .cfg_gpio_dir_sel (cfg_gpio_dir_sel ),
+ .cfg_gpio_out_data (cfg_gpio_out_data ),
+ .cfg_gpio_posedge_int_sel(cfg_gpio_posedge_int_sel),
+ .cfg_gpio_negedge_int_sel(cfg_gpio_negedge_int_sel),
+
+
+ // GPIO output pins
+ .pad_gpio_out (pad_gpio_out ),
+ .gpio_int_event (gpio_int_event )
+ );
+
+
+// 1us pulse
+pulse_gen_type2 #(.WD(10)) u_pulse_1us (
+
+ .clk_pulse (pulse1u_mclk),
+ .clk (mclk ),
+ .reset_n (h_reset_n ),
+ .cfg_max_cnt (cfg_pulse_1us)
+
+ );
+
+// 1millisecond pulse
+pulse_gen_type1 u_pulse_1ms (
+
+ .clk_pulse (pulse1m_mclk),
+ .clk (mclk ),
+ .reset_n (h_reset_n ),
+ .trigger (pulse1u_mclk)
+
+ );
+
+// 1 second pulse
+pulse_gen_type2 u_pulse_1s (
+
+ .clk_pulse (pulse1s_mclk),
+ .clk (mclk ),
+ .reset_n (h_reset_n ),
+ .cfg_max_cnt (cfg_pulse_1us)
+
+ );
+
+pinmux_reg u_pinmux_reg(
+ // System Signals
+ // Inputs
+ .mclk (mclk ),
+ .h_reset_n (h_reset_n ),
+
+
+ // Reg read/write Interface Inputs
+ .reg_cs (reg_cs ),
+ .reg_wr (reg_wr ),
+ .reg_addr (reg_addr ),
+ .reg_wdata (reg_wdata ),
+ .reg_be (reg_be ),
+
+ .reg_rdata (reg_rdata ),
+ .reg_ack (reg_ack ),
+
+ .ext_intr_in (ext_intr_in ),
+
+ .fuse_mhartid (fuse_mhartid ),
+ .irq_lines (irq_lines ),
+ .soft_irq (soft_irq ),
+ .user_irq (user_irq ),
+ .usb_intr (usb_intr ),
+ .i2cm_intr (i2cm_intr ),
+
+ .cfg_pulse_1us (cfg_pulse_1us ),
+
+
+ .cfg_pwm0_high (cfg_pwm0_high ),
+ .cfg_pwm0_low (cfg_pwm0_low ),
+ .cfg_pwm1_high (cfg_pwm1_high ),
+ .cfg_pwm1_low (cfg_pwm1_low ),
+ .cfg_pwm2_high (cfg_pwm2_high ),
+ .cfg_pwm2_low (cfg_pwm2_low ),
+ .cfg_pwm3_high (cfg_pwm3_high ),
+ .cfg_pwm3_low (cfg_pwm3_low ),
+ .cfg_pwm4_high (cfg_pwm4_high ),
+ .cfg_pwm4_low (cfg_pwm4_low ),
+ .cfg_pwm5_high (cfg_pwm5_high ),
+ .cfg_pwm5_low (cfg_pwm5_low ),
+
+ // GPIO input pins
+ .gpio_in_data (pad_gpio_in ),
+ .gpio_int_event (gpio_int_event ),
+
+ // GPIO config pins
+ .cfg_gpio_out_data (cfg_gpio_out_data ),
+ .cfg_gpio_dir_sel (cfg_gpio_dir_sel ),
+ .cfg_gpio_out_type (cfg_gpio_out_type ),
+ .cfg_gpio_posedge_int_sel (cfg_gpio_posedge_int_sel),
+ .cfg_gpio_negedge_int_sel (cfg_gpio_negedge_int_sel),
+ .cfg_multi_func_sel (cfg_multi_func_sel ),
+ .cfg_gpio_data_in (cfg_gpio_data_in ),
+
+
+ // Outputs
+ .gpio_prev_indata (gpio_prev_indata ) ,
+
+ // BIST I/F
+ .bist_en (bist_en ),
+ .bist_run (bist_run ),
+ .bist_load (bist_load ),
+
+ .bist_sdi (bist_sdi ),
+ .bist_shift (bist_shift ),
+ .bist_sdo (bist_sdo ),
+
+ .bist_done (bist_done ),
+ .bist_error (bist_error ),
+ .bist_correct (bist_correct ),
+ .bist_error_cnt0 (bist_error_cnt0 ),
+ .bist_error_cnt1 (bist_error_cnt1 ),
+ .bist_error_cnt2 (bist_error_cnt2 ),
+ .bist_error_cnt3 (bist_error_cnt3 )
+
+ );
+
+
+// 6 PWM Waveform Generator
+pwm u_pwm_0 (
+ .waveform (pwm_wfm[0] ),
+ .h_reset_n (h_reset_n ),
+ .mclk (mclk ),
+ .pulse1m_mclk (pulse1m_mclk ),
+ .cfg_pwm_enb (cfg_pwm_enb[0] ),
+ .cfg_pwm_high (cfg_pwm0_high ),
+ .cfg_pwm_low (cfg_pwm0_low )
+ );
+
+pwm u_pwm_1 (
+ .waveform (pwm_wfm[1] ),
+ .h_reset_n (h_reset_n ),
+ .mclk (mclk ),
+ .pulse1m_mclk (pulse1m_mclk ),
+ .cfg_pwm_enb (cfg_pwm_enb[1] ),
+ .cfg_pwm_high (cfg_pwm1_high ),
+ .cfg_pwm_low (cfg_pwm1_low )
+ );
+
+pwm u_pwm_2 (
+ .waveform (pwm_wfm[2] ),
+ .h_reset_n (h_reset_n ),
+ .mclk (mclk ),
+ .pulse1m_mclk (pulse1m_mclk ),
+ .cfg_pwm_enb (cfg_pwm_enb[2] ),
+ .cfg_pwm_high (cfg_pwm2_high ),
+ .cfg_pwm_low (cfg_pwm2_low )
+ );
+
+pwm u_pwm_3 (
+ .waveform (pwm_wfm[3] ),
+ .h_reset_n (h_reset_n ),
+ .mclk (mclk ),
+ .pulse1m_mclk (pulse1m_mclk ),
+ .cfg_pwm_enb (cfg_pwm_enb[3] ),
+ .cfg_pwm_high (cfg_pwm3_high ),
+ .cfg_pwm_low (cfg_pwm3_low )
+ );
+pwm u_pwm_4 (
+ .waveform (pwm_wfm[4] ),
+ .h_reset_n (h_reset_n ),
+ .mclk (mclk ),
+ .pulse1m_mclk (pulse1m_mclk ),
+ .cfg_pwm_enb (cfg_pwm_enb[4] ),
+ .cfg_pwm_high (cfg_pwm4_high ),
+ .cfg_pwm_low (cfg_pwm4_low )
+ );
+pwm u_pwm_5 (
+ .waveform (pwm_wfm[5] ),
+ .h_reset_n (h_reset_n ),
+ .mclk (mclk ),
+ .pulse1m_mclk (pulse1m_mclk ),
+ .cfg_pwm_enb (cfg_pwm_enb[5] ),
+ .cfg_pwm_high (cfg_pwm5_high ),
+ .cfg_pwm_low (cfg_pwm5_low )
+ );
+
+/************************************************
+* Pin Mapping ATMGE CONFIG
+* ATMEGA328 caravel Pin Mapping
+* Pin-1 PC6/RESET* digital_io[0]
+* Pin-2 PD0/RXD digital_io[1]
+* Pin-3 PD1/TXD digital_io[2]
+* Pin-4 PD2/INT0 digital_io[3]
+* Pin-5 PD3/INT1/OC2B(PWM0) digital_io[4]
+* Pin-6 PD4 digital_io[5]
+* Pin-7 VCC -
+* Pin-8 GND -
+* Pin-9 PB6/XTAL1/TOSC1 digital_io[6]
+* Pin-10 PB7/XTAL2/TOSC2 digital_io[7]
+* Pin-11 PD5/OC0B(PWM1)/T1 digital_io[8]
+* Pin-12 PD6/OC0A(PWM2)/AIN0 digital_io[9] /analog_io[2]
+* Pin-13 PD7/A1N1 digital_io[10]/analog_io[3]
+* Pin-14 PB0/CLKO/ICP1 digital_io[11]
+* Pin-15 PB1/OC1A(PWM3) digital_io[12]
+* Pin-16 PB2/SS/OC1B(PWM4) digital_io[13]
+* Pin-17 PB3/MOSI/OC2A(PWM5) digital_io[14]
+* Pin-18 PB4/MISO digital_io[15]
+* Pin-19 PB5/SCK digital_io[16]
+* Pin-20 AVCC -
+* Pin-21 AREF analog_io[10]
+* Pin-22 GND -
+* Pin-23 PC0/ADC0 digital_io[18]/analog_io[11]
+* Pin-24 PC1/ADC1 digital_io[19]/analog_io[12]
+* Pin-25 PC2/ADC2 digital_io[20]/analog_io[13]
+* Pin-26 PC3/ADC3 digital_io[21]/analog_io[14]
+* Pin-27 PC4/ADC4/SDA digital_io[22]/analog_io[15]
+* Pin-28 PC5/ADC5/SCL digital_io[23]/analog_io[16]
+*
+* Additional Pad used for Externam ROM/RAM
+* sflash_sck digital_io[24]
+* sflash_ss[3] digital_io[25]
+* sflash_ss[2] digital_io[26]
+* sflash_ss[1] digital_io[27]
+* sflash_ss[0] digital_io[28]
+* sflash_io0 digital_io[29]
+* sflash_io1 digital_io[30]
+* sflash_io2 digital_io[31]
+* sflash_io3 digital_io[32]
+* reserved digital_io[33]
+* uartm_rxd digital_io[34]
+* uartm_txd digital_io[35]
+* usb_dp digital_io[36]
+* usb_dn digital_io[37]
+****************************************************************
+* Pin-1 RESET is not supported as there is no suppport for fuse config
+**************/
+
+assign cfg_pwm_enb = cfg_multi_func_sel[5:0];
+wire [1:0] cfg_int_enb = cfg_multi_func_sel[7:6];
+wire cfg_uart_enb = cfg_multi_func_sel[8];
+wire cfg_i2cm_enb = cfg_multi_func_sel[9];
+wire cfg_spim_enb = cfg_multi_func_sel[10];
+
+wire [7:0] cfg_port_a_dir_sel = cfg_gpio_dir_sel[7:0];
+wire [7:0] cfg_port_b_dir_sel = cfg_gpio_dir_sel[15:8];
+wire [7:0] cfg_port_c_dir_sel = cfg_gpio_dir_sel[23:16];
+wire [7:0] cfg_port_d_dir_sel = cfg_gpio_dir_sel[31:24];
+
+
+// datain selection
+always_comb begin
+ port_a_in = 'h0;
+ port_b_in = 'h0;
+ port_c_in = 'h0;
+ port_d_in = 'h0;
+ uart_rxd = 'h0;
+ ext_intr_in= 'h0;
+ spim_mosi = 'h0;
+ i2cm_data_i= 'h0;
+ i2cm_clk_i = 'h0;
+
+ //Pin-1 PC6/RESET* digital_io[0]
+ port_c_in[6] = digital_io_in[0];
+
+ //Pin-2 PD0/RXD digital_io[1]
+ port_d_in[0] = digital_io_in[1];
+ if(cfg_uart_enb) uart_rxd = digital_io_in[1];
+
+ //Pin-3 PD1/TXD digital_io[2]
+ port_d_in[1] = digital_io_in[2];
+
+
+ //Pin-4 PD2/INT0 digital_io[3]
+ port_d_in[2] = digital_io_in[3];
+ if(cfg_int_enb[0]) ext_intr_in[0] = digital_io_in[3];
+
+ //Pin-5 PD3/INT1/OC2B(PWM0) digital_io[4]
+ port_d_in[3] = digital_io_in[4];
+ if(cfg_int_enb[1]) ext_intr_in[1] = digital_io_in[4];
+
+ //Pin-6 PD4 digital_io[5]
+ port_d_in[4] = digital_io_in[5];
+
+ //Pin-9 PB6/XTAL1/TOSC1 digital_io[6]
+ port_b_in[6] = digital_io_in[6];
+
+ // Pin-10 PB7/XTAL2/TOSC2 digital_io[7]
+ port_b_in[7] = digital_io_in[7];
+
+ //Pin-11 PD5/OC0B(PWM1)/T1 digital_io[8]
+ port_d_in[5] = digital_io_in[8];
+
+ //Pin-12 PD6/OC0A(PWM2)/AIN0 digital_io[9] /analog_io[2]
+ port_d_in[6] = digital_io_in[9];
+
+ //Pin-13 PD7/A1N1 digital_io[10]/analog_io[3]
+ port_d_in[7] = digital_io_in[10];
+
+ //Pin-14 PB0/CLKO/ICP1 digital_io[11]
+ port_b_in[0] = digital_io_in[11];
+
+ //Pin-15 PB1/OC1A(PWM3) digital_io[12]
+ port_b_in[1] = digital_io_in[12];
+
+ //Pin-16 PB2/SS/OC1B(PWM4) digital_io[13]
+ port_b_in[2] = digital_io_in[13];
+
+ //Pin-17 PB3/MOSI/OC2A(PWM5) digital_io[14]
+ port_b_in[3] = digital_io_in[14];
+ if(cfg_spim_enb) spim_mosi = digital_io_in[14];
+
+ //Pin-18 PB4/MISO digital_io[15]
+ port_b_in[4] = digital_io_in[15];
+
+ //Pin-19 PB5/SCK digital_io[16]
+ port_b_in[5]= digital_io_in[16];
+
+ //Pin-23 PC0/ADC0 digital_io[18]/analog_io[11]
+ port_c_in[0] = digital_io_in[18];
+
+ //Pin-24 PC1/ADC1 digital_io[19]/analog_io[12]
+ port_c_in[1] = digital_io_in[19];
+
+ //Pin-25 PC2/ADC2 digital_io[20]/analog_io[13]
+ port_c_in[2] = digital_io_in[20];
+
+ //Pin-26 PC3/ADC3 digital_io[21]/analog_io[14]
+ port_c_in[3] = digital_io_in[21];
+
+ //Pin-27 PC4/ADC4/SDA digital_io[22]/analog_io[15]
+ port_c_in[4] = digital_io_in[22];
+ if(cfg_i2cm_enb) i2cm_data_i = digital_io_in[22];
+
+ //Pin-28 PC5/ADC5/SCL digital_io[23]/analog_io[16]
+ port_c_in[5] = digital_io_in[23];
+ if(cfg_i2cm_enb) i2cm_clk_i = digital_io_in[23];
+
+ sflash_di[0] = digital_io_in[29];
+ sflash_di[1] = digital_io_in[30];
+ sflash_di[2] = digital_io_in[31];
+ sflash_di[3] = digital_io_in[32];
+
+ // UAR MASTER I/F
+ uartm_rxd = digital_io_in[34];
+
+ usb_dp_i = digital_io_in[36];
+ usb_dn_i = digital_io_in[37];
+end
+
+// dataout selection
+always_comb begin
+ digital_io_out = 'h0;
+ //Pin-1 PC6/RESET* digital_io[0]
+ if(cfg_port_c_dir_sel[6]) digital_io_out[0] = port_c_out[6];
+
+ //Pin-2 PD0/RXD digital_io[1]
+ if(cfg_port_d_dir_sel[0]) digital_io_out[1] = port_d_out[0];
+
+ //Pin-3 PD1/TXD digital_io[2]
+ if (cfg_uart_enb) digital_io_out[2] = uart_txd;
+ else if(cfg_port_d_dir_sel[1]) digital_io_out[2] = port_d_out[1];
+
+
+ //Pin-4 PD2/INT0 digital_io[3]
+ if(cfg_port_d_dir_sel[2]) digital_io_out[3] = port_d_out[2];
+
+ //Pin-5 PD3/INT1/OC2B(PWM0) digital_io[4]
+ if(cfg_pwm_enb[0]) digital_io_out[4] = pwm_wfm[0];
+ if(cfg_port_d_dir_sel[3]) digital_io_out[4] = port_d_out[3];
+
+ //Pin-6 PD4 digital_io[5]
+ if(cfg_port_d_dir_sel[4]) digital_io_out[5] = port_d_out[4];
+
+ //Pin-9 PB6/XTAL1/TOSC1 digital_io[6]
+ if(cfg_port_b_dir_sel[6]) digital_io_out[6] = port_b_out[6];
+
+
+ // Pin-10 PB7/XTAL2/TOSC2 digital_io[7]
+ if(cfg_port_b_dir_sel[7]) digital_io_out[7] = port_b_out[7];
+
+ //Pin-11 PD5/OC0B(PWM1)/T1 digital_io[8]
+ if(cfg_pwm_enb[1]) digital_io_out[8] = pwm_wfm[1];
+ else if(cfg_port_d_dir_sel[5]) digital_io_out[8] = port_d_out[5];
+
+ //Pin-12 PD6/OC0A(PWM2)/AIN0 digital_io[9] /analog_io[2]
+ if(cfg_pwm_enb[2]) digital_io_out[9] = pwm_wfm[2];
+ else if(cfg_port_d_dir_sel[6]) digital_io_out[9] = port_d_out[6];
+
+
+ //Pin-13 PD7/A1N1 digital_io[10]/analog_io[3]
+ if(cfg_port_d_dir_sel[7]) digital_io_out[10] = port_d_out[7];
+
+ //Pin-14 PB0/CLKO/ICP1 digital_io[11]
+ if(cfg_port_b_dir_sel[0]) digital_io_out[11] = port_b_out[0];
+
+ //Pin-15 PB1/OC1A(PWM3) digital_io[12]
+ if(cfg_pwm_enb[3]) digital_io_out[12] = pwm_wfm[3];
+ else if(cfg_port_b_dir_sel[1]) digital_io_out[12] = port_b_out[1];
+
+ //Pin-16 PB2/SS/OC1B(PWM4) digital_io[13]
+ if(cfg_pwm_enb[4]) digital_io_out[13] = pwm_wfm[4];
+ else if(cfg_spim_enb) digital_io_out[13] = spim_ss;
+ else if(cfg_port_b_dir_sel[2]) digital_io_out[13] = port_b_out[2];
+
+ //Pin-17 PB3/MOSI/OC2A(PWM5) digital_io[14]
+ if(cfg_pwm_enb[5]) digital_io_out[14] = pwm_wfm[5];
+ else if(cfg_port_b_dir_sel[3]) digital_io_out[14] = port_b_out[3];
+
+ //Pin-18 PB4/MISO digital_io[15]
+ if(cfg_spim_enb) digital_io_out[15] = spim_miso;
+ else if(cfg_port_b_dir_sel[4]) digital_io_out[15] = port_b_out[4];
+
+ //Pin-19 PB5/SCK digital_io[16]
+ if(cfg_spim_enb) digital_io_out[16] = spim_sck;
+ else if(cfg_port_b_dir_sel[5]) digital_io_out[16] = port_b_out[5];
+
+ //Pin-23 PC0/ADC0 digital_io[18]/analog_io[11]
+ if(cfg_port_c_dir_sel[0]) digital_io_out[18] = port_c_out[0];
+
+ //Pin-24 PC1/ADC1 digital_io[19]/analog_io[12]
+ if(cfg_port_c_dir_sel[1]) digital_io_out[19] = port_c_out[1];
+
+ //Pin-25 PC2/ADC2 digital_io[20]/analog_io[13]
+ if(cfg_port_c_dir_sel[2]) digital_io_out[20] = port_c_out[2];
+
+ //Pin-26 PC3/ADC3 digital_io[21]/analog_io[14]
+ if(cfg_port_c_dir_sel[3]) digital_io_out[21] = port_c_out[3];
+
+ //Pin-27 PC4/ADC4/SDA digital_io[22]/analog_io[15]
+ if(cfg_i2cm_enb) digital_io_out[22] = i2cm_data_o;
+ else if(cfg_port_c_dir_sel[4]) digital_io_out[22] = port_c_out[4];
+
+ //Pin-28 PC5/ADC5/SCL digital_io[23]/analog_io[16]
+ if(cfg_i2cm_enb) digital_io_out[23] = i2cm_clk_o;
+ else if(cfg_port_c_dir_sel[5]) digital_io_out[23] = port_c_out[5];
+
+ // Serial Flash
+ digital_io_out[24] = sflash_sck ;
+ digital_io_out[25] = sflash_ss[3] ;
+ digital_io_out[26] = sflash_ss[2] ;
+ digital_io_out[27] = sflash_ss[1] ;
+ digital_io_out[28] = sflash_ss[0] ;
+ digital_io_out[29] = sflash_do[0] ;
+ digital_io_out[30] = sflash_do[1] ;
+ digital_io_out[31] = sflash_do[2] ;
+ digital_io_out[32] = sflash_do[3] ;
+
+ // Reserved
+ digital_io_out[33] = 1'b0;
+
+ // UART MASTER I/f
+ digital_io_out[34] = 1'b0 ; // RXD
+ digital_io_out[35] = uartm_txd ; // TXD
+
+ // USB 1.1
+ digital_io_out[36] = usb_dp_o ;
+ digital_io_out[37] = usb_dn_o ;
+end
+
+// dataoen selection
+always_comb begin
+ digital_io_oen = 38'h3F_FFFF_FFFF;
+ //Pin-1 PC6/RESET* digital_io[0]
+ if(cfg_port_c_dir_sel[6]) digital_io_oen[0] = 1'b0;
+
+ //Pin-2 PD0/RXD digital_io[1]
+ if (cfg_uart_enb) digital_io_oen[1] = 1'b1;
+ else if(cfg_port_d_dir_sel[0]) digital_io_oen[1] = 1'b0;
+
+ //Pin-3 PD1/TXD digital_io[2]
+ if (cfg_uart_enb) digital_io_oen[2] = 1'b0;
+ else if(cfg_port_d_dir_sel[1]) digital_io_oen[2] = 1'b0;
+
+ //Pin-4 PD2/INT0 digital_io[3]
+ if(cfg_int_enb[0]) digital_io_oen[3] = 1'b1;
+ else if(cfg_port_d_dir_sel[2]) digital_io_oen[3] = 1'b0;
+
+ //Pin-5 PD3/INT1/OC2B(PWM0) digital_io[4]
+ if(cfg_pwm_enb[0]) digital_io_oen[4] = 1'b0;
+ else if(cfg_int_enb[1]) digital_io_oen[4] = 1'b1;
+ else if(cfg_port_d_dir_sel[3]) digital_io_oen[4] = 1'b0;
+
+ //Pin-6 PD4 digital_io[5]
+ if(cfg_port_d_dir_sel[4]) digital_io_oen[5] = 1'b0;
+
+ //Pin-9 PB6/XTAL1/TOSC1 digital_io[6]
+ if(cfg_port_b_dir_sel[6]) digital_io_oen[6] = 1'b0;
+
+ // Pin-10 PB7/XTAL2/TOSC2 digital_io[7]
+ if(cfg_port_b_dir_sel[7]) digital_io_oen[7] = 1'b0;
+
+ //Pin-11 PD5/OC0B(PWM1)/T1 digital_io[8]
+ if(cfg_pwm_enb[1]) digital_io_oen[8] = 1'b0;
+ else if(cfg_port_d_dir_sel[5]) digital_io_oen[8] = 1'b0;
+
+ //Pin-12 PD6/OC0A(PWM2)/AIN0 digital_io[9] /analog_io[2]
+ if(cfg_pwm_enb[2]) digital_io_oen[9] = 1'b0;
+ else if(cfg_port_d_dir_sel[6]) digital_io_oen[9] = 1'b0;
+
+ //Pin-13 PD7/A1N1 digital_io[10]/analog_io[3]
+ if(cfg_port_d_dir_sel[7]) digital_io_oen[10] = 1'b0;
+
+ //Pin-14 PB0/CLKO/ICP1 digital_io[11]
+ if(cfg_port_b_dir_sel[0]) digital_io_oen[11] = 1'b0;
+
+ //Pin-15 PB1/OC1A(PWM3) digital_io[12]
+ if(cfg_pwm_enb[3]) digital_io_oen[12] = 1'b0;
+ else if(cfg_port_b_dir_sel[1]) digital_io_oen[12] = 1'b0;
+
+ //Pin-16 PB2/SS/OC1B(PWM4) digital_io[13]
+ if(cfg_pwm_enb[4]) digital_io_oen[13] = 1'b0;
+ else if(cfg_spim_enb) digital_io_oen[13] = 1'b0;
+ else if(cfg_port_b_dir_sel[2]) digital_io_oen[13] = 1'b0;
+
+ //Pin-17 PB3/MOSI/OC2A(PWM5) digital_io[14]
+ if(cfg_spim_enb) digital_io_oen[14] = 1'b1;
+ else if(cfg_pwm_enb[5]) digital_io_oen[14] = 1'b0;
+ else if(cfg_port_b_dir_sel[3]) digital_io_oen[14] = 1'b0;
+
+ //Pin-18 PB4/MISO digital_io[15]
+ if(cfg_spim_enb) digital_io_oen[15] = 1'b0;
+ else if(cfg_port_b_dir_sel[4]) digital_io_oen[15] = 1'b0;
+
+ //Pin-19 PB5/SCK digital_io[16]
+ if(cfg_spim_enb) digital_io_oen[16] = 1'b0;
+ else if(cfg_port_b_dir_sel[5]) digital_io_oen[16] = 1'b0;
+
+ //Pin-23 PC0/ADC0 digital_io[18]/analog_io[11]
+ if(cfg_port_c_dir_sel[0]) digital_io_oen[18] = 1'b0;
+
+ //Pin-24 PC1/ADC1 digital_io[19]/analog_io[12]
+ if(cfg_port_c_dir_sel[1]) digital_io_oen[19] = 1'b0;
+
+ //Pin-25 PC2/ADC2 digital_io[20]/analog_io[13]
+ if(cfg_port_c_dir_sel[2]) digital_io_oen[20] = 1'b0;
+
+ //Pin-26 PC3/ADC3 digital_io[21]/analog_io[14]
+ if(cfg_port_c_dir_sel[3]) digital_io_oen[21] = 1'b0;
+
+ //Pin-27 PC4/ADC4/SDA digital_io[22]/analog_io[15]
+ if(cfg_i2cm_enb) digital_io_oen[22] = i2cm_data_oen;
+ else if(cfg_port_c_dir_sel[4]) digital_io_oen[22] = 1'b0;
+
+ //Pin-28 PC5/ADC5/SCL digital_io[23]/analog_io[16]
+ if(cfg_i2cm_enb) digital_io_oen[23] = i2cm_clk_oen;
+ else if(cfg_port_c_dir_sel[5]) digital_io_oen[23] = 1'b0;
+
+ // Serial Flash
+ digital_io_oen[24] = 1'b0 ;
+ digital_io_oen[25] = 1'b0 ;
+ digital_io_oen[26] = 1'b0 ;
+ digital_io_oen[27] = 1'b0 ;
+ digital_io_oen[28] = 1'b0 ;
+ digital_io_oen[29] = sflash_oen[0];
+ digital_io_oen[30] = sflash_oen[1];
+ digital_io_oen[31] = sflash_oen[2];
+ digital_io_oen[32] = sflash_oen[3];
+
+ // Reserved
+ digital_io_oen[33] = 1'b0 ;
+ // UART MASTER
+ digital_io_oen[34] = 1'b1; // RXD
+ digital_io_oen[35] = 1'b0; // TXD
+
+ // USB 1.1
+ digital_io_oen[36] = usb_oen;
+ digital_io_oen[37] = usb_oen;
+end
+
+
+endmodule
+
+
diff --git a/verilog/rtl/pinmux/src/pinmux_reg.sv b/verilog/rtl/pinmux/src/pinmux_reg.sv
new file mode 100644
index 0000000..211bd40
--- /dev/null
+++ b/verilog/rtl/pinmux/src/pinmux_reg.sv
@@ -0,0 +1,913 @@
+//////////////////////////////////////////////////////////////////////////////
+// SPDX-FileCopyrightText: 2021 , Dinesh Annayya
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+// SPDX-License-Identifier: Apache-2.0
+// SPDX-FileContributor: Created by Dinesh Annayya <dinesha@opencores.org>
+//
+//////////////////////////////////////////////////////////////////////
+//// ////
+//// Pinmux Register ////
+//// ////
+//// This file is part of the riscduino cores project ////
+//// https://github.com/dineshannayya/riscduino.git ////
+//// ////
+//// Description ////
+//// Hold all the Global and PinMux Register ////
+//// ////
+//// To Do: ////
+//// nothing ////
+//// ////
+//// Author(s): ////
+//// - Dinesh Annayya, dinesha@opencores.org ////
+//// ////
+//// Revision : ////
+//// 0.1 - 16th Feb 2021, Dinesh A ////
+//// initial version ////
+//////////////////////////////////////////////////////////////////////
+//
+module pinmux_reg (
+ // System Signals
+ // Inputs
+ input logic mclk,
+ input logic h_reset_n,
+
+ // Reg Bus Interface Signal
+ input logic reg_cs,
+ input logic reg_wr,
+ input logic [7:0] reg_addr,
+ input logic [31:0] reg_wdata,
+ input logic [3:0] reg_be,
+
+ // Outputs
+ output logic [31:0] reg_rdata,
+ output logic reg_ack,
+
+ input logic [1:0] ext_intr_in,
+
+ // Risc configuration
+ output logic [31:0] fuse_mhartid,
+ output logic [15:0] irq_lines,
+ output logic soft_irq,
+ output logic [2:0] user_irq,
+ input logic usb_intr,
+ input logic i2cm_intr,
+
+ output logic [9:0] cfg_pulse_1us,
+
+ //---------------------------------------------------
+ // 6 PWM Configuration
+ //---------------------------------------------------
+
+ output logic [15:0] cfg_pwm0_high ,
+ output logic [15:0] cfg_pwm0_low ,
+ output logic [15:0] cfg_pwm1_high ,
+ output logic [15:0] cfg_pwm1_low ,
+ output logic [15:0] cfg_pwm2_high ,
+ output logic [15:0] cfg_pwm2_low ,
+ output logic [15:0] cfg_pwm3_high ,
+ output logic [15:0] cfg_pwm3_low ,
+ output logic [15:0] cfg_pwm4_high ,
+ output logic [15:0] cfg_pwm4_low ,
+ output logic [15:0] cfg_pwm5_high ,
+ output logic [15:0] cfg_pwm5_low ,
+
+ // GPIO input pins
+ input logic [31:0] gpio_in_data ,// GPIO I/P pins
+ input logic [31:0] gpio_int_event ,// from gpio control blk
+
+
+
+ // GPIO config pins
+ output logic [31:0] cfg_gpio_out_data ,// to the GPIO control block
+ output logic [31:0] cfg_gpio_data_in ,// GPIO I/P pins data captured into this
+ output logic [31:0] cfg_gpio_dir_sel ,// decides on GPIO pin is I/P or O/P at pad level
+ output logic [31:0] cfg_gpio_out_type ,// O/P is static , '1' : waveform
+ output logic [31:0] cfg_gpio_posedge_int_sel ,// select posedge interrupt
+ output logic [31:0] cfg_gpio_negedge_int_sel ,// select negedge interrupt
+ output logic [31:0] cfg_multi_func_sel ,// multifunction pins
+
+ // Outputs
+ output logic [31:0] gpio_prev_indata, // prv data from GPIO I/P pins
+
+ // BIST I/F
+ output logic bist_en,
+ output logic bist_run,
+ output logic bist_load,
+
+ output logic bist_sdi,
+ output logic bist_shift,
+ input logic bist_sdo,
+
+ input logic bist_done,
+ input logic [3:0] bist_error,
+ input logic [3:0] bist_correct,
+ input logic [3:0] bist_error_cnt0,
+ input logic [3:0] bist_error_cnt1,
+ input logic [3:0] bist_error_cnt2,
+ input logic [3:0] bist_error_cnt3
+
+ );
+
+
+
+//-----------------------------------------------------------------------
+// Internal Wire Declarations
+//-----------------------------------------------------------------------
+
+logic sw_rd_en ;
+logic sw_wr_en;
+logic [4:0] sw_addr; // addressing 16 registers
+logic [31:0] sw_reg_wdata;
+logic [3:0] wr_be ;
+
+logic [31:0] reg_out;
+logic [31:0] reg_0; // Chip ID
+logic [31:0] reg_1; // Risc Fuse Id
+logic [31:0] reg_2; // GPIO Read Data
+logic [31:0] reg_3; // GPIO Output Data
+logic [31:0] reg_4; // GPIO Dir Sel
+logic [31:0] reg_5; // GPIO Type
+logic [31:0] reg_6; // Interrupt
+logic [31:0] reg_7; //
+logic [31:0] reg_8; //
+logic [31:0] reg_9; // GPIO Interrupt Status
+logic [31:0] reg_10; // GPIO Interrupt Status
+logic [31:0] reg_11; // GPIO Interrupt Mask
+logic [31:0] reg_12; // GPIO Posedge Interrupt Select
+logic [31:0] reg_13; // GPIO Negedge Interrupt Select
+logic [31:0] reg_14; // Software-Reg_14
+logic [31:0] reg_15; // Software-Reg_15
+logic [31:0] reg_16; // PWN-0 Config
+logic [31:0] reg_17; // PWN-1 Config
+logic [31:0] reg_18; // PWN-2 Config
+logic [31:0] reg_19; // PWN-3 Config
+logic [31:0] reg_20; // PWN-4 Config
+logic [31:0] reg_21; // PWN-5 Config
+logic [31:0] reg_22; // Software-Reg1
+logic [31:0] reg_23; // Software-Reg2
+logic [31:0] reg_24; // Software-Reg3
+logic [31:0] reg_25; // Software-Reg4
+logic [31:0] reg_26; // Software-Reg5
+logic [31:0] reg_27; // Software-Reg6
+
+
+logic cs_int;
+logic gpio_intr;
+
+
+assign sw_addr = reg_addr [6:2];
+assign sw_rd_en = reg_cs & !reg_wr;
+assign sw_wr_en = reg_cs & reg_wr;
+assign wr_be = reg_be;
+assign sw_reg_wdata = reg_wdata;
+
+
+//-----------------------------------
+// Edge detection for Logic Bist
+// ----------------------------------
+
+logic wb_req;
+logic wb_req_d;
+logic wb_req_pedge;
+
+always_ff @(negedge h_reset_n or posedge mclk) begin
+ if ( h_reset_n == 1'b0 ) begin
+ wb_req <= '0;
+ wb_req_d <= '0;
+ end else begin
+ wb_req <= reg_cs && (reg_ack == 0) ;
+ wb_req_d <= wb_req;
+ end
+end
+
+// Detect pos edge of request
+assign wb_req_pedge = (wb_req_d ==0) && (wb_req==1'b1);
+
+
+//-----------------------------------------------------------------
+// Reg 4/5 are BIST Serial I/F register and it takes minimum 32
+// cycle to respond ACK back
+// ----------------------------------------------------------------
+wire ser_acc = sw_wr_en_30 | sw_rd_en_31;
+wire non_ser_acc = reg_cs ? !ser_acc : 1'b0;
+wire serial_ack;
+
+always @ (posedge mclk or negedge h_reset_n)
+begin : preg_out_Seq
+ if (h_reset_n == 1'b0) begin
+ reg_rdata <= 'h0;
+ reg_ack <= 1'b0;
+ end else if (ser_acc && serial_ack) begin
+ reg_rdata <= serail_dout ;
+ reg_ack <= 1'b1;
+ end else if (non_ser_acc && !reg_ack) begin
+ reg_rdata <= reg_out ;
+ reg_ack <= 1'b1;
+ end else begin
+ reg_ack <= 1'b0;
+ end
+end
+
+
+
+//-----------------------------------------------------------------------
+// register read enable and write enable decoding logic
+//-----------------------------------------------------------------------
+wire sw_wr_en_0 = sw_wr_en & (sw_addr == 5'h0);
+wire sw_wr_en_1 = sw_wr_en & (sw_addr == 5'h1);
+wire sw_wr_en_2 = sw_wr_en & (sw_addr == 5'h2);
+wire sw_wr_en_3 = sw_wr_en & (sw_addr == 5'h3);
+wire sw_wr_en_4 = sw_wr_en & (sw_addr == 5'h4);
+wire sw_wr_en_5 = sw_wr_en & (sw_addr == 5'h5);
+wire sw_wr_en_6 = sw_wr_en & (sw_addr == 5'h6);
+wire sw_wr_en_7 = sw_wr_en & (sw_addr == 5'h7);
+wire sw_wr_en_8 = sw_wr_en & (sw_addr == 5'h8);
+wire sw_wr_en_9 = sw_wr_en & (sw_addr == 5'h9);
+wire sw_wr_en_10 = sw_wr_en & (sw_addr == 5'hA);
+wire sw_wr_en_11 = sw_wr_en & (sw_addr == 5'hB);
+wire sw_wr_en_12 = sw_wr_en & (sw_addr == 5'hC);
+wire sw_wr_en_13 = sw_wr_en & (sw_addr == 5'hD);
+wire sw_wr_en_14 = sw_wr_en & (sw_addr == 5'hE);
+wire sw_wr_en_15 = sw_wr_en & (sw_addr == 5'hF);
+wire sw_wr_en_16 = sw_wr_en & (sw_addr == 5'h10);
+wire sw_wr_en_17 = sw_wr_en & (sw_addr == 5'h11);
+wire sw_wr_en_18 = sw_wr_en & (sw_addr == 5'h12);
+wire sw_wr_en_19 = sw_wr_en & (sw_addr == 5'h13);
+wire sw_wr_en_20 = sw_wr_en & (sw_addr == 5'h14);
+wire sw_wr_en_21 = sw_wr_en & (sw_addr == 5'h15);
+
+wire sw_wr_en_22 = sw_wr_en & (sw_addr == 5'h16);
+wire sw_wr_en_23 = sw_wr_en & (sw_addr == 5'h17);
+wire sw_wr_en_24 = sw_wr_en & (sw_addr == 5'h18);
+wire sw_wr_en_25 = sw_wr_en & (sw_addr == 5'h19);
+wire sw_wr_en_26 = sw_wr_en & (sw_addr == 5'h1A);
+wire sw_wr_en_27 = sw_wr_en & (sw_addr == 5'h1B);
+wire sw_wr_en_28 = sw_wr_en & (sw_addr == 5'h1C);
+wire sw_wr_en_29 = sw_wr_en & (sw_addr == 5'h1D);
+wire sw_wr_en_30 = sw_wr_en & (sw_addr == 5'h1E);
+wire sw_wr_en_31 = sw_wr_en & (sw_addr == 5'h1F);
+
+wire sw_rd_en_28 = sw_rd_en & (sw_addr == 5'h1C);
+wire sw_rd_en_29 = sw_rd_en & (sw_addr == 5'h1D);
+wire sw_rd_en_30 = sw_rd_en & (sw_addr == 5'h1E);
+wire sw_rd_en_31 = sw_rd_en & (sw_addr == 5'h1F);
+
+
+//-----------------------------------------------------------------------
+// Individual register assignments
+//-----------------------------------------------------------------------
+
+// Chip ID
+wire [15:0] manu_id = 16'h8949; // Asci value of YI
+wire [7:0] chip_id = 8'h02;
+wire [7:0] chip_rev = 8'h01;
+
+assign reg_0 = {manu_id,chip_id,chip_rev};
+
+
+//-----------------------------------------------------------------------
+// reg-1, reset value = 32'hA55A_A55A
+// -----------------------------------------------------------------
+
+gen_32b_reg #(32'hA55A_A55A) u_reg_1 (
+ //List of Inputs
+ .reset_n (h_reset_n ),
+ .clk (mclk ),
+ .cs (sw_wr_en_1 ),
+ .we (wr_be ),
+ .data_in (sw_reg_wdata ),
+
+ //List of Outs
+ .data_out (reg_1 )
+ );
+
+assign fuse_mhartid = reg_1;
+
+//-----------------------------------------------------------------------
+// Logic for gpio_data_in
+//-----------------------------------------------------------------------
+logic [31:0] gpio_in_data_s;
+logic [31:0] gpio_in_data_ss;
+// Double Sync the gpio pin data for edge detection
+always @ (posedge mclk or negedge h_reset_n)
+begin
+ if (h_reset_n == 1'b0) begin
+ reg_2 <= 'h0 ;
+ gpio_in_data_s <= 32'd0;
+ gpio_in_data_ss <= 32'd0;
+ end
+ else begin
+ gpio_in_data_s <= gpio_in_data;
+ gpio_in_data_ss <= gpio_in_data_s;
+ reg_2 <= gpio_in_data_ss;
+ end
+end
+
+
+assign cfg_gpio_data_in = reg_2[31:0]; // to be used for edge interrupt detect
+assign gpio_prev_indata = gpio_in_data_ss;
+
+//-----------------------------------------------------------------------
+// Logic for cfg_gpio_out_data
+//-----------------------------------------------------------------------
+assign cfg_gpio_out_data = reg_3[31:0]; // data to the GPIO control blk
+
+gen_32b_reg #(32'h0) u_reg_3 (
+ //List of Inputs
+ .reset_n (h_reset_n ),
+ .clk (mclk ),
+ .cs (sw_wr_en_3 ),
+ .we (wr_be ),
+ .data_in (sw_reg_wdata ),
+
+ //List of Outs
+ .data_out (reg_3 )
+ );
+//-----------------------------------------------------------------------
+// Logic for cfg_gpio_dir_sel
+//-----------------------------------------------------------------------
+assign cfg_gpio_dir_sel = reg_4[31:0]; // data to the GPIO O/P pins
+
+gen_32b_reg #(32'h0) u_reg_4 (
+ //List of Inputs
+ .reset_n (h_reset_n ),
+ .clk (mclk ),
+ .cs (sw_wr_en_4 ),
+ .we (wr_be ),
+ .data_in (sw_reg_wdata ),
+
+ //List of Outs
+ .data_out (reg_4 )
+ );
+//-----------------------------------------------------------------------
+// Logic for cfg_gpio_out_type
+//-----------------------------------------------------------------------
+assign cfg_gpio_out_type = reg_5[31:0]; // to be used for read
+
+gen_32b_reg #(32'h0) u_reg_5 (
+ //List of Inputs
+ .reset_n (h_reset_n ),
+ .clk (mclk ),
+ .cs (sw_wr_en_5 ),
+ .we (wr_be ),
+ .data_in (sw_reg_wdata ),
+
+ //List of Outs
+ .data_out (reg_5 )
+ );
+
+
+//-----------------------------------------------------------------------
+// reg-6
+//-----------------------------------------------------------------
+assign irq_lines = reg_6[15:0];
+assign soft_irq = reg_6[16];
+assign user_irq = reg_6[19:17];
+
+
+generic_register #(8,0 ) u_reg6_be0 (
+ .we ({8{sw_wr_en_6 &
+ wr_be[0] }} ),
+ .data_in (sw_reg_wdata[7:0] ),
+ .reset_n (h_reset_n ),
+ .clk (mclk ),
+
+ //List of Outs
+ .data_out (reg_6[7:0] )
+ );
+
+generic_register #(3,0 ) u_reg6_be1_1 (
+ .we ({3{sw_wr_en_6 &
+ wr_be[1] }} ),
+ .data_in (sw_reg_wdata[10:8] ),
+ .reset_n (h_reset_n ),
+ .clk (mclk ),
+
+ //List of Outs
+ .data_out (reg_6[10:8] )
+ );
+
+
+assign reg_6[15:11] = {gpio_intr, ext_intr_in[1:0], usb_intr, i2cm_intr};
+
+
+generic_register #(4,0 ) u_reg6_be2 (
+ .we ({4{sw_wr_en_6 &
+ wr_be[2] }} ),
+ .data_in (sw_reg_wdata[19:16]),
+ .reset_n (h_reset_n ),
+ .clk (mclk ),
+
+ //List of Outs
+ .data_out (reg_6[19:16] )
+ );
+
+assign reg_6[31:20] = '0;
+
+// Register-7
+gen_32b_reg #(32'h0) u_reg_7 (
+ //List of Inputs
+ .reset_n (h_reset_n ),
+ .clk (mclk ),
+ .cs (sw_wr_en_7 ),
+ .we (wr_be ),
+ .data_in (sw_reg_wdata ),
+
+ //List of Outs
+ .data_out (reg_7 )
+ );
+
+assign cfg_pulse_1us = reg_7[9:0];
+
+//-----------------------------------------------------------------------
+// Logic for cfg_int_status
+// Always update int_status, even if no register write is occuring.
+// Interrupt posting is higher priority than int clear by host
+//-----------------------------------------------------------------------
+wire [31:0] cfg_gpio_int_status = reg_9[31:0]; // to be used for read
+
+//--------------------------------------------------------
+// Interrupt Status Generation
+// Note: Reg_9 --> Interrupt Status Register, Writting '1' will clear the
+// corresponding interrupt status bit. Writting '0' has no
+// effect
+// Reg_10 --> Writting one to this register will set the interrupt in
+// interrupt status register (reg_9), Writting '0' does not has any
+// effect.
+/// Always update int_status, even if no register write is occuring.
+// Interrupt posting is higher priority than int clear by host
+//--------------------------------------------------------
+wire [31:0] gpio_int_status = reg_9;
+always @(posedge mclk or negedge h_reset_n)
+begin
+ if(~h_reset_n)
+ begin
+ reg_9[31:0] <= 32'h0;
+ end
+ else
+ begin
+ if(sw_wr_en_9 && wr_be[0])
+ begin
+ reg_9[7:0] <= ((~sw_reg_wdata[7:0] & gpio_int_status[7:0]) | gpio_int_event[7:0]);
+ end
+ else if(sw_wr_en_10 && wr_be[0])
+ begin
+ reg_9[7:0] <= ((sw_reg_wdata[7:0] | gpio_int_status[7:0]) | gpio_int_event[7:0]);
+ end
+ else
+ begin
+ reg_9[7:0] <= (gpio_int_status[7:0] | gpio_int_event[7:0]);
+ end
+
+ if(sw_wr_en_9 && wr_be[1])
+ begin
+ reg_9[15:8] <= ((~sw_reg_wdata[15:8] & gpio_int_status[15:8]) | gpio_int_event[15:8]);
+ end
+ else if(sw_wr_en_10 && wr_be[1])
+ begin
+ reg_9[15:8] <= ((sw_reg_wdata[15:8] | gpio_int_status[15:8]) | gpio_int_event[15:8]);
+ end
+ else
+ begin
+ reg_9[15:8] <= (gpio_int_status[15:8] | gpio_int_event[15:8]);
+ end
+
+ if(sw_wr_en_9 && wr_be[2])
+ begin
+ reg_9[23:16] <= ((~sw_reg_wdata[23:16] & gpio_int_status[23:16]) | gpio_int_event[23:16]);
+ end
+ else if(sw_wr_en_10 && wr_be[2])
+ begin
+ reg_9[23:16] <= ((sw_reg_wdata[23:16] | gpio_int_status[23:16]) | gpio_int_event[23:16]);
+ end
+ else
+ begin
+ reg_9[23:16] <= (gpio_int_status[23:16] | gpio_int_event[23:16]);
+ end
+
+ if(sw_wr_en_9 && wr_be[3])
+ begin
+ reg_9[31:24] <= ((~sw_reg_wdata[31:24] & gpio_int_status[31:24]) | gpio_int_event[31:24]);
+ end
+ else if(sw_wr_en_10 && wr_be[3])
+ begin
+ reg_9[31:24] <= ((sw_reg_wdata[31:24] | gpio_int_status[31:24]) | gpio_int_event[31:24]);
+ end
+ else
+ begin
+ reg_9[31:24] <= (gpio_int_status[31:24] | gpio_int_event[31:24]);
+ end
+ end
+end
+//-------------------------------------------------
+// Returns same value as interrupt status register
+//------------------------------------------------
+
+assign reg_10 = reg_9;
+//-----------------------------------------------------------------------
+// Logic for cfg_gpio_int_mask : GPIO interrupt mask
+//-----------------------------------------------------------------------
+wire [31:0] cfg_gpio_int_mask = reg_11[31:0]; // to be used for read
+
+assign gpio_intr = ( | (reg_9 & reg_11) ); // interrupt pin to the RISC
+
+
+// Register-11
+gen_32b_reg #(32'h0) u_reg_11 (
+ //List of Inputs
+ .reset_n (h_reset_n ),
+ .clk (mclk ),
+ .cs (sw_wr_en_11 ),
+ .we (wr_be ),
+ .data_in (sw_reg_wdata ),
+
+ //List of Outs
+ .data_out (reg_11 )
+ );
+//-----------------------------------------------------------------------
+// Logic for cfg_gpio_posedge_int_sel : Enable posedge GPIO interrupt
+//-----------------------------------------------------------------------
+assign cfg_gpio_posedge_int_sel = reg_12[31:0]; // to be used for read
+gen_32b_reg #(32'h0) u_reg_12 (
+ //List of Inputs
+ .reset_n (h_reset_n ),
+ .clk (mclk ),
+ .cs (sw_wr_en_12 ),
+ .we (wr_be ),
+ .data_in (sw_reg_wdata ),
+
+ //List of Outs
+ .data_out (reg_12 )
+ );
+//-----------------------------------------------------------------------
+// Logic for cfg_gpio_negedge_int_sel : Enable negedge GPIO interrupt
+//-----------------------------------------------------------------------
+assign cfg_gpio_negedge_int_sel = reg_13[31:0]; // to be used for read
+gen_32b_reg #(32'h0) u_reg_13 (
+ //List of Inputs
+ .reset_n (h_reset_n ),
+ .clk (mclk ),
+ .cs (sw_wr_en_13 ),
+ .we (wr_be ),
+ .data_in (sw_reg_wdata ),
+
+ //List of Outs
+ .data_out (reg_13 )
+ );
+
+//-----------------------------------------------------------------------
+// Logic for cfg_multi_func_sel :Enable GPIO to act as multi function pins
+//-----------------------------------------------------------------------
+assign cfg_multi_func_sel = reg_14[31:0]; // to be used for read
+
+
+gen_32b_reg #(32'h0) u_reg_14 (
+ //List of Inputs
+ .reset_n (h_reset_n ),
+ .clk (mclk ),
+ .cs (sw_wr_en_14 ),
+ .we (wr_be ),
+ .data_in (sw_reg_wdata ),
+
+ //List of Outs
+ .data_out (reg_14 )
+ );
+
+// Reg-15
+gen_32b_reg #(32'h0) u_reg_15 (
+ //List of Inputs
+ .reset_n (h_reset_n ),
+ .clk (mclk ),
+ .cs (sw_wr_en_15 ),
+ .we (wr_be ),
+ .data_in (sw_reg_wdata ),
+
+ //List of Outs
+ .data_out (reg_15 )
+ );
+//-----------------------------------------------------------------------
+// Logic for PWM-0 Config
+//-----------------------------------------------------------------------
+assign cfg_pwm0_low = reg_16[15:0]; // low period of w/f
+assign cfg_pwm0_high = reg_16[31:16]; // high period of w/f
+
+gen_32b_reg #(32'h0) u_reg_16 (
+ //List of Inputs
+ .reset_n (h_reset_n ),
+ .clk (mclk ),
+ .cs (sw_wr_en_16 ),
+ .we (wr_be ),
+ .data_in (sw_reg_wdata ),
+
+ //List of Outs
+ .data_out (reg_16 )
+ );
+
+
+//-----------------------------------------------------------------------
+// Logic for PWM-1 Config
+//-----------------------------------------------------------------------
+assign cfg_pwm1_low = reg_17[15:0]; // low period of w/f
+assign cfg_pwm1_high = reg_17[31:16]; // high period of w/f
+gen_32b_reg #(32'h0) u_reg_17 (
+ //List of Inputs
+ .reset_n (h_reset_n ),
+ .clk (mclk ),
+ .cs (sw_wr_en_17 ),
+ .we (wr_be ),
+ .data_in (sw_reg_wdata ),
+
+ //List of Outs
+ .data_out (reg_17 )
+ );
+
+//-----------------------------------------------------------------------
+// Logic for PWM-2 Config
+//-----------------------------------------------------------------------
+assign cfg_pwm2_low = reg_18[15:0]; // low period of w/f
+assign cfg_pwm2_high = reg_18[31:16]; // high period of w/f
+gen_32b_reg #(32'h0) u_reg_18 (
+ //List of Inputs
+ .reset_n (h_reset_n ),
+ .clk (mclk ),
+ .cs (sw_wr_en_18 ),
+ .we (wr_be ),
+ .data_in (sw_reg_wdata ),
+
+ //List of Outs
+ .data_out (reg_18 )
+ );
+
+//-----------------------------------------------------------------------
+// Logic for PWM-3 Config
+//-----------------------------------------------------------------------
+assign cfg_pwm3_low = reg_19[15:0]; // low period of w/f
+assign cfg_pwm3_high = reg_19[31:16]; // high period of w/f
+gen_32b_reg #(32'h0) u_reg_19 (
+ //List of Inputs
+ .reset_n (h_reset_n ),
+ .clk (mclk ),
+ .cs (sw_wr_en_19 ),
+ .we (wr_be ),
+ .data_in (sw_reg_wdata ),
+
+ //List of Outs
+ .data_out (reg_19 )
+ );
+
+//-----------------------------------------------------------------------
+// Logic for PWM-4 Config
+//-----------------------------------------------------------------------
+assign cfg_pwm4_low = reg_20[15:0]; // low period of w/f
+assign cfg_pwm4_high = reg_20[31:16]; // high period of w/f
+
+gen_32b_reg #(32'h0) u_reg_20 (
+ //List of Inputs
+ .reset_n (h_reset_n ),
+ .clk (mclk ),
+ .cs (sw_wr_en_20 ),
+ .we (wr_be ),
+ .data_in (sw_reg_wdata ),
+
+ //List of Outs
+ .data_out (reg_20 )
+ );
+
+//-----------------------------------------------------------------------
+// Logic for PWM-5 Config
+//-----------------------------------------------------------------------
+assign cfg_pwm5_low = reg_21[15:0]; // low period of w/f
+assign cfg_pwm5_high = reg_21[31:16]; // high period of w/f
+
+gen_32b_reg #(32'h0) u_reg_21 (
+ //List of Inputs
+ .reset_n (h_reset_n ),
+ .clk (mclk ),
+ .cs (sw_wr_en_21 ),
+ .we (wr_be ),
+ .data_in (sw_reg_wdata ),
+
+ //List of Outs
+ .data_out (reg_21 )
+ );
+
+
+//-----------------------------------------
+// Software Reg-1 : ASCI Representation of RISC = 32'h8273_8343
+// ----------------------------------------
+gen_32b_reg #(32'h8273_8343) u_reg_22 (
+ //List of Inputs
+ .reset_n (h_reset_n ),
+ .clk (mclk ),
+ .cs (sw_wr_en_22 ),
+ .we (wr_be ),
+ .data_in (sw_reg_wdata ),
+
+ //List of Outs
+ .data_out (reg_22 )
+ );
+
+//-----------------------------------------
+// Software Reg-2, Release date: <DAY><MONTH><YEAR>
+// ----------------------------------------
+gen_32b_reg #(32'h1402_2022) u_reg_23 (
+ //List of Inputs
+ .reset_n (h_reset_n ),
+ .clk (mclk ),
+ .cs (sw_wr_en_23 ),
+ .we (wr_be ),
+ .data_in (sw_reg_wdata ),
+
+ //List of Outs
+ .data_out (reg_23 )
+ );
+
+//-----------------------------------------
+// Software Reg-3: Poject Revison 3.3 = 0003400
+// ----------------------------------------
+gen_32b_reg #(32'h0003_4000) u_reg_24 (
+ //List of Inputs
+ .reset_n (h_reset_n ),
+ .clk (mclk ),
+ .cs (sw_wr_en_24 ),
+ .we (wr_be ),
+ .data_in (sw_reg_wdata ),
+
+ //List of Outs
+ .data_out (reg_24 )
+ );
+
+//-----------------------------------------
+// Software Reg-4
+// ----------------------------------------
+gen_32b_reg #(32'h0) u_reg_25 (
+ //List of Inputs
+ .reset_n (h_reset_n ),
+ .clk (mclk ),
+ .cs (sw_wr_en_25 ),
+ .we (wr_be ),
+ .data_in (sw_reg_wdata ),
+
+ //List of Outs
+ .data_out (reg_25 )
+ );
+
+//-----------------------------------------
+// Software Reg-5
+// ----------------------------------------
+gen_32b_reg #(32'h0) u_reg_26 (
+ //List of Inputs
+ .reset_n (h_reset_n ),
+ .clk (mclk ),
+ .cs (sw_wr_en_26 ),
+ .we (wr_be ),
+ .data_in (sw_reg_wdata ),
+
+ //List of Outs
+ .data_out (reg_26 )
+ );
+
+//-----------------------------------------
+// Software Reg-6
+// ----------------------------------------
+gen_32b_reg #(32'h0) u_reg_27 (
+ //List of Inputs
+ .reset_n (h_reset_n ),
+ .clk (mclk ),
+ .cs (sw_wr_en_27 ),
+ .we (wr_be ),
+ .data_in (sw_reg_wdata ),
+
+ //List of Outs
+ .data_out (reg_27 )
+ );
+
+
+//-----------------------------------------------------------------------
+// reg-28
+// -----------------------------------------------------------------
+logic [31:0] cfg_bist_ctrl_1;
+
+gen_32b_reg #(32'h0) u_reg_28 (
+ //List of Inputs
+ .reset_n (h_reset_n ),
+ .clk (mclk ),
+ .cs (sw_wr_en_28 ),
+ .we (wr_be ),
+ .data_in (sw_reg_wdata ),
+
+ //List of Outs
+ .data_out (cfg_bist_ctrl_1[31:0] )
+ );
+
+
+
+assign bist_en = cfg_bist_ctrl_1[0];
+assign bist_run = cfg_bist_ctrl_1[1];
+assign bist_load = cfg_bist_ctrl_1[2];
+
+
+//-----------------------------------------------------------------------
+// reg-29
+//-----------------------------------------------------------------
+logic [31:0] cfg_bist_status_1;
+
+assign cfg_bist_status_1 = { bist_error_cnt3, 1'b0, bist_correct[3], bist_error[3], bist_done,
+ bist_error_cnt2, 1'b0, bist_correct[2], bist_error[2], bist_done,
+ bist_error_cnt1, 1'b0, bist_correct[1], bist_error[1], bist_done,
+ bist_error_cnt0, 1'b0, bist_correct[0], bist_error[0], bist_done
+ };
+
+//-----------------------------------------------------------------------
+// reg-30 => Write to Serail I/F
+// reg-31 => READ from Serail I/F
+//-----------------------------------------------------------------
+logic bist_sdi_int;
+logic bist_shift_int;
+logic bist_sdo_int;
+logic [31:0] serail_dout;
+
+assign bist_sdo_int = bist_sdo;
+assign bist_shift = bist_shift_int;
+assign bist_sdi = bist_sdi_int ;
+
+ser_inf_32b u_ser_intf
+ (
+
+ // Master Port
+ .rst_n (h_reset_n), // Regular Reset signal
+ .clk (mclk), // System clock
+ .reg_wr (sw_wr_en_30 & wb_req_pedge), // Write Request
+ .reg_rd (sw_rd_en_31 & wb_req_pedge), // Read Request
+ .reg_wdata (sw_reg_wdata) , // data output
+ .reg_rdata (serail_dout), // data input
+ .reg_ack (serial_ack), // acknowlegement
+
+ // Slave Port
+ .sdi (bist_sdi_int), // Serial SDI
+ .shift (bist_shift_int), // Shift Signal
+ .sdo (bist_sdo_int) // Serial SDO
+
+ );
+
+
+
+
+//-----------------------------------------------------------------------
+// Register Read Path Multiplexer instantiation
+//-----------------------------------------------------------------------
+
+always_comb
+begin
+ reg_out [31:0] = 32'h0;
+
+ case (sw_addr [4:0])
+ 5'b00000 : reg_out [31:0] = reg_0 [31:0];
+ 5'b00001 : reg_out [31:0] = reg_1 [31:0];
+ 5'b00010 : reg_out [31:0] = reg_2 [31:0];
+ 5'b00011 : reg_out [31:0] = reg_3 [31:0];
+ 5'b00100 : reg_out [31:0] = reg_4 [31:0];
+ 5'b00101 : reg_out [31:0] = reg_5 [31:0];
+ 5'b00110 : reg_out [31:0] = reg_6 [31:0];
+ 5'b00111 : reg_out [31:0] = reg_7 [31:0];
+ 5'b01000 : reg_out [31:0] = reg_8 [31:0];
+ 5'b01001 : reg_out [31:0] = reg_9 [31:0];
+ 5'b01010 : reg_out [31:0] = reg_10 [31:0];
+ 5'b01011 : reg_out [31:0] = reg_11 [31:0];
+ 5'b01100 : reg_out [31:0] = reg_12 [31:0];
+ 5'b01101 : reg_out [31:0] = reg_13 [31:0];
+ 5'b01110 : reg_out [31:0] = reg_14 [31:0];
+ 5'b01111 : reg_out [31:0] = reg_15 [31:0];
+ 5'b10000 : reg_out [31:0] = reg_16 [31:0];
+ 5'b10001 : reg_out [31:0] = reg_17 [31:0];
+ 5'b10010 : reg_out [31:0] = reg_18 [31:0];
+ 5'b10011 : reg_out [31:0] = reg_19 [31:0];
+ 5'b10100 : reg_out [31:0] = reg_20 [31:0];
+ 5'b10101 : reg_out [31:0] = reg_21 [31:0];
+ 5'b10110 : reg_out [31:0] = reg_22 [31:0];
+ 5'b10111 : reg_out [31:0] = reg_23 [31:0];
+ 5'b11000 : reg_out [31:0] = reg_24 [31:0];
+ 5'b11001 : reg_out [31:0] = reg_25 [31:0];
+ 5'b11010 : reg_out [31:0] = reg_26 [31:0];
+ 5'b11011 : reg_out [31:0] = reg_27 [31:0];
+ 5'b11100 : reg_out [31:0] = cfg_bist_ctrl_1 [31:0];
+ 5'b11101 : reg_out [31:0] = cfg_bist_status_1 [31:0];
+ 5'b11110 : reg_out [31:0] = serail_dout [31:0]; // Previous Shift Data
+ 5'b11111 : reg_out [31:0] = serail_dout [31:0]; // Latest Shift Data
+ default : reg_out [31:0] = 32'h0;
+ endcase
+end
+
+
+endmodule
diff --git a/verilog/rtl/pinmux/src/pwm.sv b/verilog/rtl/pinmux/src/pwm.sv
new file mode 100644
index 0000000..7a30772
--- /dev/null
+++ b/verilog/rtl/pinmux/src/pwm.sv
@@ -0,0 +1,44 @@
+
+//-------------------------------------------------------------------
+// PWM waveform period: 1000/((cfg_pwm_high+1) + (cfg_pwm_low+1))
+// For 1 Second with Duty cycle 50 = 1000/((499+1) + (499+1))
+// For 1 Second with 1ms On and 999ms Off = 1000/((0+1) + (998+1))
+// Timing Run's with 1 Milisecond pulse
+//-------------------------------------------------------------------
+
+module pwm(
+ output logic waveform,
+
+ input logic h_reset_n,
+ input logic mclk,
+ input logic pulse1m_mclk,
+ input logic cfg_pwm_enb,
+ input logic [15:0] cfg_pwm_high,
+ input logic [15:0] cfg_pwm_low
+);
+
+logic [15:0] pwm_cnt ; // PWM on/off counter
+
+
+always @(posedge mclk or negedge h_reset_n)
+begin
+ if ( ~h_reset_n )
+ begin
+ pwm_cnt <= 16'h0;
+ waveform <= 1'b0;
+ end
+ else if ( pulse1m_mclk && cfg_pwm_enb)
+ begin
+ if ( pwm_cnt == 16'h0 && waveform == 1'b0) begin
+ pwm_cnt <= cfg_pwm_high;
+ waveform <= ~waveform;
+ end else if ( pwm_cnt == 16'h0 && waveform == 1'b1) begin
+ pwm_cnt <= cfg_pwm_low;
+ waveform <= ~waveform;
+ end else begin
+ pwm_cnt <= pwm_cnt - 1;
+ end
+ end
+end
+
+endmodule
diff --git a/verilog/rtl/sar_adc/ACMP.sv b/verilog/rtl/sar_adc/ACMP.sv
new file mode 100644
index 0000000..7f58f42
--- /dev/null
+++ b/verilog/rtl/sar_adc/ACMP.sv
@@ -0,0 +1,103 @@
+module ACMP(
+`ifdef USE_POWER_PINS
+ input wire vccd2,
+ input wire vssd2,
+`endif
+ input wire clk,
+ input wire INP,
+ input wire INN,
+ input wire VDD,
+ input wire VSS,
+ output wire Q
+);
+
+`ifdef ACMP_FUNCTIONAL
+
+ assign Q = INP > INN ;
+`else
+
+ wire clkb;
+ wire net1,
+ net2,
+ net3,
+ net4,
+ net5,
+ net6,
+ net7;
+
+ sky130_fd_sc_hd__inv_1 x15 (
+ `ifdef USE_POWER_PINS
+ .VPWR(VPWR),
+ .VGND(VGND),
+ .VPB(VPWR),
+ .VNB(VGND),
+ `endif
+ .A(clk), .Y(clkb));
+ sky130_fd_sc_hd__a221oi_1 x7 (
+ `ifdef USE_POWER_PINS
+ .VPWR(VPWR),
+ .VGND(VGND),
+ .VPB(VPWR),
+ .VNB(VGND),
+ `endif
+ .A1(INP), .A2(INP), .B1(clkb), .B2(VDD), .C1(net2), .Y(net1));
+ sky130_fd_sc_hd__a221oi_1 x8 (
+ `ifdef USE_POWER_PINS
+ .VPWR(VPWR),
+ .VGND(VGND),
+ .VPB(VPWR),
+ .VNB(VGND),
+ `endif
+ .A1(INN), .A2(INN), .B1(clkb), .B2(VDD), .C1(net1), .Y(net2));
+ sky130_fd_sc_hd__inv_1 x2 (
+ `ifdef USE_POWER_PINS
+ .VPWR(VPWR),
+ .VGND(VGND),
+ .VPB(VPWR),
+ .VNB(VGND),
+ `endif
+ .A(net3), .Y(net6));
+ sky130_fd_sc_hd__inv_1 x3 (
+ `ifdef USE_POWER_PINS
+ .VPWR(VPWR),
+ .VGND(VGND),
+ .VPB(VPWR),
+ .VNB(VGND),
+ `endif
+ .A(net4), .Y(net5));
+ sky130_fd_sc_hd__o221ai_1 x6 (
+ `ifdef USE_POWER_PINS
+ .VPWR(VPWR),
+ .VGND(VGND),
+ .VPB(VPWR),
+ .VNB(VGND),
+ `endif
+ .A1(INP), .A2(INP), .B1(clk), .B2(VSS), .C1(net4), .Y(net3));
+ sky130_fd_sc_hd__o221ai_1 x9 (
+ `ifdef USE_POWER_PINS
+ .VPWR(VPWR),
+ .VGND(VGND),
+ .VPB(VPWR),
+ .VNB(VGND),
+ `endif
+ .A1(INN), .A2(INN), .B1(clk), .B2(VSS), .C1(net3), .Y(net4));
+ sky130_fd_sc_hd__nor3_1 x10 (
+ `ifdef USE_POWER_PINS
+ .VPWR(VPWR),
+ .VGND(VGND),
+ .VPB(VPWR),
+ .VNB(VGND),
+ `endif
+ .A(net5), .B(net1), .C(net7), .Y(Q));
+ sky130_fd_sc_hd__nor3_1 x11 (
+ `ifdef USE_POWER_PINS
+ .VPWR(VPWR),
+ .VGND(VGND),
+ .VPB(VPWR),
+ .VNB(VGND),
+ `endif
+ .A(Q), .B(net6), .C(net2), .Y(net7));
+
+`endif
+
+endmodule
\ No newline at end of file
diff --git a/verilog/rtl/sar_adc/ACMP_HVL.v b/verilog/rtl/sar_adc/ACMP_HVL.v
new file mode 100644
index 0000000..543cd6e
--- /dev/null
+++ b/verilog/rtl/sar_adc/ACMP_HVL.v
@@ -0,0 +1,112 @@
+/*
+ An analog comparator using HVL cells
+*/
+
+module ACMP_HVL(
+`ifdef USE_POWER_PINS
+ input wire vccd2,
+ input wire vssd2,
+`endif
+ input wire clk,
+ input wire INP,
+ input wire INN,
+ output wire Q
+);
+ wire clkb;
+ wire Q1b, Q1;
+ wire Q2b, Q2;
+ wire Qb;
+
+ sky130_fd_sc_hvl__inv_1 x0 (
+ .Y(clkb),
+ .A(clk)
+ );
+
+ sky130_fd_sc_hvl__nor3_1 x5(
+ .Y(Q),
+ .A(Q1b),
+ .B(Q2b),
+ .C(Qb)
+ );
+
+ sky130_fd_sc_hvl__nor3_1 x6(
+ .Y(Qb),
+ .A(Q1),
+ .B(Q2),
+ .C(Q)
+ );
+
+ latch_nand3 x1 (
+ .CLK(clk),
+ .VP(INP),
+ .VN(INN),
+ .Q(Q1),
+ .Qb(Q1b)
+ );
+
+ latch_nor3 x2 (
+ .CLK(clkb),
+ .VP(INP),
+ .VN(INN),
+ .Q(Q2),
+ .Qb(Q2b)
+ );
+
+endmodule
+
+module latch_nor3 (
+ input wire CLK,
+ input wire VP,
+ input wire VN,
+ output wire Q,
+ output wire Qb
+);
+
+ sky130_fd_sc_hvl__nor3_1 x1(
+ .Y(Qb),
+ .A(CLK),
+ .B(VP),
+ .C(Q)
+ );
+ sky130_fd_sc_hvl__nor3_1 x2(
+ .Y(Q),
+ .A(CLK),
+ .B(VN),
+ .C(Qb)
+ );
+
+endmodule
+
+module latch_nand3 (
+ input wire CLK,
+ input wire VP,
+ input wire VN,
+ output wire Q,
+ output wire Qb
+);
+ wire Q0, Q0b;
+
+ sky130_fd_sc_hvl__nand3_1 x1(
+ .Y(Q0b),
+ .A(CLK),
+ .B(VP),
+ .C(Q0)
+ );
+ sky130_fd_sc_hvl__nand3_1 x2(
+ .Y(Q0),
+ .A(CLK),
+ .B(VN),
+ .C(Q0b)
+ );
+
+ sky130_fd_sc_hvl__inv_4 x3 (
+ .Y(Qb),
+ .A(Q0)
+ );
+
+ sky130_fd_sc_hvl__inv_4 x4 (
+ .Y(Q),
+ .A(Q0b)
+ );
+
+endmodule
\ No newline at end of file
diff --git a/verilog/rtl/sar_adc/DAC_8BIT.v b/verilog/rtl/sar_adc/DAC_8BIT.v
new file mode 100644
index 0000000..8030e18
--- /dev/null
+++ b/verilog/rtl/sar_adc/DAC_8BIT.v
@@ -0,0 +1,24 @@
+module DAC_8BIT (
+`ifdef USE_POWER_PINS
+ input wire vdd, // User area 1 1.8V supply
+ input wire gnd, // User area 1 digital ground
+`endif
+ input wire d0,
+ input wire d1,
+ input wire d2,
+ input wire d3,
+ input wire d4,
+ input wire d5,
+ input wire d6,
+ input wire d7,
+
+ input wire inp1,
+ input wire inp2,
+
+ output wire out_v
+);
+
+// Dummy behavirol model to verify the DAC connection with the user_project_wrapper
+assign out_v = d0 | d1 | d2 | d3 | d4 | d5 | d6 | d7 ;
+
+endmodule
\ No newline at end of file
diff --git a/verilog/rtl/sar_adc/SAR.sv b/verilog/rtl/sar_adc/SAR.sv
new file mode 100644
index 0000000..9931483
--- /dev/null
+++ b/verilog/rtl/sar_adc/SAR.sv
@@ -0,0 +1,65 @@
+// file: SAR.v
+// A parametrized Successive Approximation Register (SAR)
+// The module is so compact; it is only 110 cells for
+// 8-bit SAR using SKY130 HD library
+//
+// author: Mohamed Shalan (mshalan@aucegypt.edu)
+
+`timescale 1ns/1ns
+
+module SAR #(parameter SIZE = 8) (
+ input wire clk, // The clock
+ input wire reset_n, // Active low reset
+ input wire start, // Conversion start
+ input wire cmp, // Analog comparator output
+ output wire [SIZE-1:0] out, // The output sample
+ output wire [SIZE-1:0] outn, // Inverted output for active low DAC
+ output wire done, // Conversion is done
+ output wire clkn // Inverted clock to be used by the clocked analog comparator
+);
+
+ reg [SIZE-1:0] result;
+ reg [SIZE-1:0] shift;
+
+ // FSM to handle the SAR operation
+ reg [1:0] state, nstate;
+ localparam IDLE=0, CONV=1, DONE=2;
+
+ always @*
+ case (state)
+ IDLE: if(start) nstate = CONV;
+ else nstate = IDLE;
+ CONV: if(shift == 1'b1) nstate = DONE;
+ else nstate = CONV;
+ DONE: nstate = IDLE;
+ default: nstate = IDLE;
+ endcase
+
+ always @(posedge clk or negedge reset_n)
+ if(!reset_n)
+ state <= IDLE;
+ else
+ state <= nstate;
+
+ // Shift Register
+ always @(posedge clk)
+ if(state == IDLE)
+ shift <= 1'b1 << (SIZE-1);
+ else if(state == CONV)
+ shift<= shift >> 1;
+
+ // The SAR
+ wire [SIZE-1:0] current = (cmp == 1'b0) ? ~shift : {SIZE{1'b1}} ;
+ wire [SIZE-1:0] next = shift >> 1;
+ always @(posedge clk)
+ if(state == IDLE)
+ result <= 1'b1 << (SIZE-1);
+ else if(state == CONV)
+ result <= (result | next) & current;
+
+ assign out = result;
+ assign outn = ~result;
+ assign clkn = ~clk;
+ assign done = (state==DONE);
+
+endmodule
diff --git a/verilog/rtl/sar_adc/adc_reg.sv b/verilog/rtl/sar_adc/adc_reg.sv
new file mode 100644
index 0000000..24dcf0f
--- /dev/null
+++ b/verilog/rtl/sar_adc/adc_reg.sv
@@ -0,0 +1,262 @@
+//////////////////////////////////////////////////////////////////////////////
+// SPDX-FileCopyrightText: 2021 , Dinesh Annayya
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+// SPDX-License-Identifier: Apache-2.0
+// SPDX-FileContributor: Created by Dinesh Annayya <dinesha@opencores.org>
+//
+//////////////////////////////////////////////////////////////////////
+//// ////
+//// ADC register ////
+//// ////
+//// This file is part of the YIFive cores project ////
+//// https://github.com/dineshannayya/riscduino.git ////
+//// ////
+//// Description ////
+//// This block generate all the ADC config and status ////
+//// ////
+//// To Do: ////
+//// nothing ////
+//// ////
+//// Author(s): ////
+//// - Dinesh Annayya, dinesha@opencores.org ////
+//// ////
+//// Revision : ////
+//// 0.1 - 26 Sept 2021 Dinesh A ////
+//// Initial version ////
+//// ////
+//////////////////////////////////////////////////////////////////////
+//// ////
+//// Copyright (C) 2000 Authors and OPENCORES.ORG ////
+//// ////
+//// This source file may be used and distributed without ////
+//// restriction provided that this copyright statement is not ////
+//// removed from the file and that any derivative work contains ////
+//// the original copyright notice and the associated disclaimer. ////
+//// ////
+//// This source file is free software; you can redistribute it ////
+//// and/or modify it under the terms of the GNU Lesser General ////
+//// Public License as published by the Free Software Foundation; ////
+//// either version 2.1 of the License, or (at your option) any ////
+//// later version. ////
+//// ////
+//// This source is distributed in the hope that it will be ////
+//// useful, but WITHOUT ANY WARRANTY; without even the implied ////
+//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR ////
+//// PURPOSE. See the GNU Lesser General Public License for more ////
+//// details. ////
+//// ////
+//// You should have received a copy of the GNU Lesser General ////
+//// Public License along with this source; if not, download it ////
+//// from http://www.opencores.org/lgpl.shtml ////
+//// ////
+//////////////////////////////////////////////////////////////////////
+
+module adc_reg (
+
+ input logic mclk,
+ input logic reset_n,
+
+ // Reg Bus Interface Signal
+ input logic reg_cs,
+ input logic reg_wr,
+ input logic [7:0] reg_addr,
+ input logic [31:0] reg_wdata,
+ input logic [3:0] reg_be,
+
+ // Outputs
+ output logic [31:0] reg_rdata,
+ output logic reg_ack,
+
+ input logic pulse1m_mclk,
+ // ADC I/F
+ output logic start_conv,
+ output logic [2:0] adc_ch_no,
+ input logic conv_done,
+ input logic [7:0] adc_result
+
+
+ );
+
+
+
+//-----------------------------------------------------------------------
+// Internal Wire Declarations
+//-----------------------------------------------------------------------
+
+logic sw_rd_en;
+logic sw_wr_en;
+logic [3:0] sw_addr ; // addressing 16 registers
+logic [3:0] wr_be ;
+logic [31:0] sw_reg_wdata;
+
+logic reg_cs_l ;
+logic reg_cs_2l ;
+
+
+logic [31:0] reg_0; // ADC Config
+logic [31:0] reg_1; // ADC Ch-1 Result
+logic [31:0] reg_2; // ADC Ch-2 Result
+logic [31:0] reg_3; // ADC Ch-3 Result
+logic [31:0] reg_4; // ADC Ch-4 Result
+logic [31:0] reg_5; // ADC Ch-5 Result
+logic [31:0] reg_6; // ADC Ch-6 Result
+logic [31:0] reg_7; // Software-Reg_7
+logic [31:0] reg_out;
+
+//-----------------------------------------------------------------------
+// Main code starts here
+//-----------------------------------------------------------------------
+
+//-----------------------------------------------------------------------
+// To avoid interface timing, all the content are registered
+//-----------------------------------------------------------------------
+always @ (posedge mclk or negedge reset_n)
+begin
+ if (reset_n == 1'b0)
+ begin
+ sw_addr <= '0;
+ sw_rd_en <= '0;
+ sw_wr_en <= '0;
+ sw_reg_wdata <= '0;
+ wr_be <= '0;
+ reg_cs_l <= '0;
+ reg_cs_2l <= '0;
+ end else begin
+ sw_addr <= reg_addr [5:2];
+ sw_rd_en <= reg_cs & !reg_wr;
+ sw_wr_en <= reg_cs & reg_wr;
+ sw_reg_wdata <= reg_wdata;
+ wr_be <= reg_be;
+ reg_cs_l <= reg_cs;
+ reg_cs_2l <= reg_cs_l;
+ end
+end
+
+
+//-----------------------------------------------------------------------
+// Read path mux
+//-----------------------------------------------------------------------
+
+always @ (posedge mclk or negedge reset_n)
+begin : preg_out_Seq
+ if (reset_n == 1'b0) begin
+ reg_rdata [31:0] <= 32'h0000_0000;
+ reg_ack <= 1'b0;
+ end else if (sw_rd_en && !reg_ack && !reg_cs_2l) begin
+ reg_rdata [31:0] <= reg_out [31:0];
+ reg_ack <= 1'b1;
+ end else if (sw_wr_en && !reg_ack && !reg_cs_2l) begin
+ reg_ack <= 1'b1;
+ end else begin
+ reg_ack <= 1'b0;
+ end
+end
+
+
+//-----------------------------------------------------------------------
+// register read enable and write enable decoding logic
+//-----------------------------------------------------------------------
+wire sw_wr_en_0 = sw_wr_en & (sw_addr == 4'h0);
+wire sw_rd_en_0 = sw_rd_en & (sw_addr == 4'h0);
+wire sw_wr_en_1 = sw_wr_en & (sw_addr == 4'h1);
+wire sw_rd_en_1 = sw_rd_en & (sw_addr == 4'h1);
+wire sw_wr_en_2 = sw_wr_en & (sw_addr == 4'h2);
+wire sw_rd_en_2 = sw_rd_en & (sw_addr == 4'h2);
+wire sw_wr_en_3 = sw_wr_en & (sw_addr == 4'h3);
+wire sw_rd_en_3 = sw_rd_en & (sw_addr == 4'h3);
+wire sw_wr_en_4 = sw_wr_en & (sw_addr == 4'h4);
+wire sw_rd_en_4 = sw_rd_en & (sw_addr == 4'h4);
+wire sw_wr_en_5 = sw_wr_en & (sw_addr == 4'h5);
+wire sw_rd_en_5 = sw_rd_en & (sw_addr == 4'h5);
+wire sw_wr_en_6 = sw_wr_en & (sw_addr == 4'h6);
+wire sw_rd_en_6 = sw_rd_en & (sw_addr == 4'h6);
+wire sw_wr_en_7 = sw_wr_en & (sw_addr == 4'h7);
+wire sw_rd_en_7 = sw_rd_en & (sw_addr == 4'h7);
+
+always @( *)
+begin : preg_sel_Com
+
+ reg_out [31:0] = 32'd0;
+
+ case (sw_addr [3:0])
+ 4'b0000 : reg_out [31:0] = reg_0 [31:0];
+ 4'b0001 : reg_out [31:0] = {24'h0,reg_1 [7:0]};
+ 4'b0010 : reg_out [31:0] = {24'h0,reg_2 [7:0]};
+ 4'b0011 : reg_out [31:0] = {24'h0,reg_3 [7:0]};
+ 4'b0100 : reg_out [31:0] = {24'h0,reg_4 [7:0]};
+ 4'b0101 : reg_out [31:0] = {24'h0,reg_5 [7:0]};
+ 4'b0110 : reg_out [31:0] = {24'h0,reg_6 [7:0]};
+ default : reg_out [31:0] = 'h0;
+ endcase
+end
+
+
+
+//-----------------------------------------------------------------------
+// Individual register assignments
+//-----------------------------------------------------------------------
+logic [5:0] cfg_adc_enb = reg_0[5:0];
+
+gen_32b_reg #(32'h0) u_reg_0 (
+ //List of Inputs
+ .reset_n (reset_n ),
+ .clk (mclk ),
+ .cs (sw_wr_en_0 ),
+ .we (wr_be ),
+ .data_in (sw_reg_wdata ),
+
+ //List of Outs
+ .data_out (reg_0 )
+ );
+
+
+always @(posedge mclk or negedge reset_n)
+begin
+ if(~reset_n) begin
+ reg_1[7:0] <= 8'h0;
+ reg_2[7:0] <= 8'h0;
+ reg_3[7:0] <= 8'h0;
+ reg_4[7:0] <= 8'h0;
+ reg_5[7:0] <= 8'h0;
+ reg_6[7:0] <= 8'h0;
+ start_conv <= '0;
+ adc_ch_no <= '0;
+ end else begin
+ if(cfg_adc_enb[0] && pulse1m_mclk) begin
+ if(start_conv && conv_done) begin
+ start_conv <= 0;
+ case(adc_ch_no)
+ 3'b000: reg_1[7:0] <= adc_result;
+ 3'b001: reg_2[7:0] <= adc_result;
+ 3'b010: reg_3[7:0] <= adc_result;
+ 3'b011: reg_4[7:0] <= adc_result;
+ 3'b100: reg_5[7:0] <= adc_result;
+ 3'b101: reg_6[7:0] <= adc_result;
+ endcase
+ end
+ end else begin
+ start_conv <= 1;
+ if(adc_ch_no == 5) begin
+ adc_ch_no <= 0;
+ end else begin
+ adc_ch_no <= adc_ch_no+1;
+ end
+ end
+ end
+end
+
+
+
+
+endmodule
diff --git a/verilog/rtl/sar_adc/sar_adc.sv b/verilog/rtl/sar_adc/sar_adc.sv
new file mode 100644
index 0000000..45b7dbd
--- /dev/null
+++ b/verilog/rtl/sar_adc/sar_adc.sv
@@ -0,0 +1,170 @@
+module sar_adc(
+`ifdef USE_POWER_PINS
+ input logic vccd1 ,// User area 1 1.8V supply
+ input logic vssd1 ,// User area 1 digital ground
+ input logic vccd2 ,// User area 2 1.8V supply (analog)
+ input logic vssd2 ,// User area 2 ground (analog)
+`endif
+
+
+ input logic clk ,// The clock (digital)
+ input logic reset_n ,// Active low reset (digital)
+
+ // Reg Bus Interface Signal
+ input logic reg_cs ,
+ input logic reg_wr ,
+ input logic [7:0] reg_addr ,
+ input logic [31:0] reg_wdata ,
+ input logic [3:0] reg_be ,
+
+ // Outputs
+ output logic [31:0] reg_rdata ,
+ output logic reg_ack ,
+
+ input logic pulse1m_mclk ,
+ output logic [7:0] sar2dac ,// SAR O/P towards DAC
+
+ input logic analog_dac_out, // DAC analog o/p for compare
+
+ // ACMP (HD) Ports
+ input logic [5:0] analog_din // (Analog)
+
+);
+
+ logic clkn;
+ logic [5:0] sar_cmp; // SAR compare signal
+ logic sar_cmp_int;
+ logic [2:0] adc_ch_no;
+ logic start_conv ;// Conversion start (digital)
+ logic conv_done ;// Conversion is done (digital)
+ logic [7:0] adc_result ;// SAR o/p (digital)
+
+always_comb
+begin
+ sar_cmp_int = 0;
+ case(adc_ch_no)
+ 3'b000 : sar_cmp_int = sar_cmp[0];
+ 3'b001 : sar_cmp_int = sar_cmp[1];
+ 3'b010 : sar_cmp_int = sar_cmp[2];
+ 3'b011 : sar_cmp_int = sar_cmp[3];
+ 3'b100 : sar_cmp_int = sar_cmp[4];
+ 3'b101 : sar_cmp_int = sar_cmp[5];
+ endcase
+
+
+end
+
+adc_reg u_adc_reg (
+ .mclk (mclk),
+ .reset_n (reset_n),
+
+ // Reg Bus Interface Signal
+ .reg_cs (reg_cs),
+ .reg_wr (reg_wr),
+ .reg_addr (reg_addr),
+ .reg_wdata (reg_wdata),
+ .reg_be (reg_be),
+
+ // Outputs
+ .reg_rdata (reg_rdata),
+ .reg_ack (reg_ack),
+
+ .pulse1m_mclk (pulse1m_mclk),
+ // ADC I/F
+ .start_conv (start_conv),
+ .adc_ch_no (adc_ch_no),
+ .conv_done (conv_done),
+ .adc_result (adc_result)
+
+ );
+
+
+ ACMP COMP_0 (
+ `ifdef USE_POWER_PINS
+ .vccd2 (vccd2 ),
+ .vssd2 (vssd2 ),
+ .VDD (vccd2 ),
+ .VSS (vssd2 ),
+ `endif
+ .clk (clk ),
+ .INP (analog_din[0] ),
+ .INN (analog_dac_out ),
+ .Q (sar_cmp[0] )
+ );
+
+ ACMP COMP_1 (
+ `ifdef USE_POWER_PINS
+ .vccd2 (vccd2 ),
+ .vssd2 (vssd2 ),
+ .VDD (vccd2 ),
+ .VSS (vssd2 ),
+ `endif
+ .clk (clk ),
+ .INP (analog_din[1] ),
+ .INN (analog_dac_out ),
+ .Q (sar_cmp[1] )
+ );
+
+ ACMP COMP_2 (
+ `ifdef USE_POWER_PINS
+ .vccd2 (vccd2 ),
+ .vssd2 (vssd2 ),
+ .VDD (vccd2 ),
+ .VSS (vssd2 ),
+ `endif
+ .clk (clk ),
+ .INP (analog_din[2] ),
+ .INN (analog_dac_out ),
+ .Q (sar_cmp[2] )
+ );
+
+ ACMP COMP_3 (
+ `ifdef USE_POWER_PINS
+ .vccd2 (vccd2 ),
+ .vssd2 (vssd2 ),
+ .VDD (vccd2 ),
+ .VSS (vssd2 ),
+ `endif
+ .clk (clk ),
+ .INP (analog_din[3] ),
+ .INN (analog_dac_out ),
+ .Q (sar_cmp[3] )
+ );
+ ACMP COMP_4 (
+ `ifdef USE_POWER_PINS
+ .vccd2 (vccd2 ),
+ .vssd2 (vssd2 ),
+ .VDD (vccd2 ),
+ .VSS (vssd2 ),
+ `endif
+ .clk (clk ),
+ .INP (analog_din[4] ),
+ .INN (analog_dac_out ),
+ .Q (sar_cmp[4] )
+ );
+ ACMP COMP_5 (
+ `ifdef USE_POWER_PINS
+ .vccd2 (vccd2 ),
+ .vssd2 (vssd2 ),
+ .VDD (vccd2 ),
+ .VSS (vssd2 ),
+ `endif
+ .clk (clk ),
+ .INP (analog_din[5] ),
+ .INN (analog_dac_out ),
+ .Q (sar_cmp[5] )
+ );
+
+ SAR CTRL (
+ .clk (clk ),
+ .reset_n (reset_n ),
+ .start (start_conv ),
+ .cmp (sar_cmp_int ),
+ .out (adc_result ),
+ .done (conv_done ),
+ .outn (sar2dac ),
+ .clkn (clkn )
+ );
+
+
+endmodule
diff --git a/verilog/rtl/sram_macros/sky130_sram_2kbyte_1rw1r_32x512_8.v b/verilog/rtl/sram_macros/sky130_sram_2kbyte_1rw1r_32x512_8.v
new file mode 100644
index 0000000..289a770
--- /dev/null
+++ b/verilog/rtl/sram_macros/sky130_sram_2kbyte_1rw1r_32x512_8.v
@@ -0,0 +1,114 @@
+// OpenRAM SRAM model
+// Words: 512
+// Word size: 32
+// Write size: 8
+
+module sky130_sram_2kbyte_1rw1r_32x512_8(
+`ifdef USE_POWER_PINS
+ vccd1,
+ vssd1,
+`endif
+// Port 0: RW
+ clk0,csb0,web0,wmask0,addr0,din0,dout0,
+// Port 1: R
+ clk1,csb1,addr1,dout1
+ );
+
+ parameter NUM_WMASKS = 4 ;
+ parameter DATA_WIDTH = 32 ;
+ parameter ADDR_WIDTH = 9 ;
+ parameter RAM_DEPTH = 1 << ADDR_WIDTH;
+ // FIXME: This delay is arbitrary.
+ parameter DELAY = 3 ;
+ parameter VERBOSE = 0 ; //Set to 0 to only display warnings
+ parameter T_HOLD = 1 ; //Delay to hold dout value after posedge. Value is arbitrary
+
+`ifdef USE_POWER_PINS
+ inout vccd1;
+ inout vssd1;
+`endif
+ input clk0; // clock
+ input csb0; // active low chip select
+ input web0; // active low write control
+ input [NUM_WMASKS-1:0] wmask0; // write mask
+ input [ADDR_WIDTH-1:0] addr0;
+ input [DATA_WIDTH-1:0] din0;
+ output [DATA_WIDTH-1:0] dout0;
+ input clk1; // clock
+ input csb1; // active low chip select
+ input [ADDR_WIDTH-1:0] addr1;
+ output [DATA_WIDTH-1:0] dout1;
+
+ reg csb0_reg;
+ reg web0_reg;
+ reg [NUM_WMASKS-1:0] wmask0_reg;
+ reg [ADDR_WIDTH-1:0] addr0_reg;
+ reg [DATA_WIDTH-1:0] din0_reg;
+ reg [DATA_WIDTH-1:0] dout0;
+
+ // All inputs are registers
+ always @(posedge clk0)
+ begin
+ csb0_reg = csb0;
+ web0_reg = web0;
+ wmask0_reg = wmask0;
+ addr0_reg = addr0;
+ din0_reg = din0;
+ #(T_HOLD) dout0 = 32'bx;
+ if ( !csb0_reg && web0_reg && VERBOSE )
+ $display($time," Reading %m addr0=%b dout0=%b",addr0_reg,mem[addr0_reg]);
+ if ( !csb0_reg && !web0_reg && VERBOSE )
+ $display($time," Writing %m addr0=%b din0=%b wmask0=%b",addr0_reg,din0_reg,wmask0_reg);
+ end
+
+ reg csb1_reg;
+ reg [ADDR_WIDTH-1:0] addr1_reg;
+ reg [DATA_WIDTH-1:0] dout1;
+
+ // All inputs are registers
+ always @(posedge clk1)
+ begin
+ csb1_reg = csb1;
+ addr1_reg = addr1;
+ if (!csb0 && !web0 && !csb1 && (addr0 == addr1))
+ $display($time," WARNING: Writing and reading addr0=%b and addr1=%b simultaneously!",addr0,addr1);
+ #(T_HOLD) dout1 = 32'bx;
+ if ( !csb1_reg && VERBOSE )
+ $display($time," Reading %m addr1=%b dout1=%b",addr1_reg,mem[addr1_reg]);
+ end
+
+reg [DATA_WIDTH-1:0] mem [0:RAM_DEPTH-1];
+
+ // Memory Write Block Port 0
+ // Write Operation : When web0 = 0, csb0 = 0
+ always @ (negedge clk0)
+ begin : MEM_WRITE0
+ if ( !csb0_reg && !web0_reg ) begin
+ if (wmask0_reg[0])
+ mem[addr0_reg][7:0] = din0_reg[7:0];
+ if (wmask0_reg[1])
+ mem[addr0_reg][15:8] = din0_reg[15:8];
+ if (wmask0_reg[2])
+ mem[addr0_reg][23:16] = din0_reg[23:16];
+ if (wmask0_reg[3])
+ mem[addr0_reg][31:24] = din0_reg[31:24];
+ end
+ end
+
+ // Memory Read Block Port 0
+ // Read Operation : When web0 = 1, csb0 = 0
+ always @ (negedge clk0)
+ begin : MEM_READ0
+ if (!csb0_reg && web0_reg)
+ dout0 <= #(DELAY) mem[addr0_reg];
+ end
+
+ // Memory Read Block Port 1
+ // Read Operation : When web1 = 1, csb1 = 0
+ always @ (negedge clk1)
+ begin : MEM_READ1
+ if (!csb1_reg)
+ dout1 <= #(DELAY) mem[addr1_reg];
+ end
+
+endmodule
diff --git a/verilog/rtl/sspim/src/filelist_spi.f b/verilog/rtl/sspim/src/filelist_spi.f
new file mode 100755
index 0000000..23a2ad5
--- /dev/null
+++ b/verilog/rtl/sspim/src/filelist_spi.f
@@ -0,0 +1,5 @@
+sspim_top.sv
+sspim_ctl.sv
+sspim_if.sv
+sspim_cfg.sv
+-v ../../lib/registers.v
diff --git a/verilog/rtl/sspim/src/sspim_cfg.sv b/verilog/rtl/sspim/src/sspim_cfg.sv
new file mode 100755
index 0000000..cd39e1f
--- /dev/null
+++ b/verilog/rtl/sspim/src/sspim_cfg.sv
@@ -0,0 +1,298 @@
+//////////////////////////////////////////////////////////////////////
+//// ////
+//// Single SPI Master Interface Module ////
+//// ////
+//// This file is part of the riscduino cores project ////
+//// https://github.com/dineshannayya/riscduino.git ////
+//// ////
+//// Description ////
+//// Subbport Single Bit SPI Master ////
+//// ////
+//// To Do: ////
+//// nothing ////
+//// ////
+//// Author(s): ////
+//// - Dinesh Annayya, dinesha@opencores.org ////
+//// ////
+//// Revision : ////
+//// V.0 - 06 Oct 2021 ////
+//// Initial SpI Module picked from ////
+//// http://www.opencores.org/cores/turbo8051/ ////
+//// ////
+//// ////
+//////////////////////////////////////////////////////////////////////
+//// ////
+//// Copyright (C) 2000 Authors and OPENCORES.ORG ////
+//// ////
+//// This source file may be used and distributed without ////
+//// restriction provided that this copyright statement is not ////
+//// removed from the file and that any derivative work contains ////
+//// the original copyright notice and the associated disclaimer. ////
+//// ////
+//// This source file is free software; you can redistribute it ////
+//// and/or modify it under the terms of the GNU Lesser General ////
+//// Public License as published by the Free Software Foundation; ////
+//// either version 2.1 of the License, or (at your option) any ////
+//// later version. ////
+//// ////
+//// This source is distributed in the hope that it will be ////
+//// useful, but WITHOUT ANY WARRANTY; without even the implied ////
+//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR ////
+//// PURPOSE. See the GNU Lesser General Public License for more ////
+//// details. ////
+//// ////
+//// You should have received a copy of the GNU Lesser General ////
+//// Public License along with this source; if not, download it ////
+//// from http://www.opencores.org/lgpl.shtml ////
+//// ////
+//////////////////////////////////////////////////////////////////////
+
+
+
+module sspim_cfg (
+ input logic mclk ,
+ input logic reset_n ,
+
+ output logic [1:0] cfg_tgt_sel ,
+
+ output logic cfg_op_req , // SPI operation request
+ output logic [1:0] cfg_op_type , // SPI operation type
+ output logic [1:0] cfg_transfer_size , // SPI transfer size
+ output logic [5:0] cfg_sck_period , // sck clock period
+ output logic [4:0] cfg_sck_cs_period , // cs setup/hold period
+ output logic [7:0] cfg_cs_byte , // cs bit information
+ output logic [31:0] cfg_datain , // data for transfer
+ input logic [31:0] cfg_dataout , // data for received
+ input logic hware_op_done , // operation done
+
+ //---------------------------------
+ // Reg Bus Interface Signal
+ //---------------------------------
+ input logic reg_cs ,
+ input logic reg_wr ,
+ input logic [7:0] reg_addr ,
+ input logic [31:0] reg_wdata ,
+ input logic [3:0] reg_be ,
+
+ // Outputs
+ output logic [31:0] reg_rdata ,
+ output logic reg_ack
+
+
+ );
+
+
+
+//-----------------------------------------------------------------------
+// Internal Wire Declarations
+//-----------------------------------------------------------------------
+logic sw_rd_en ;
+logic sw_wr_en;
+logic [1:0] sw_addr; // addressing 16 registers
+logic [31:0] sw_reg_wdata;
+logic [3:0] wr_be ;
+logic reg_cs_l;
+logic reg_cs_2l;
+
+logic [31:0] reg_0; // Software_Reg_0
+logic [31:0] reg_1; // Software-Reg_1
+logic [31:0] reg_2; // Software-Reg_2
+logic [31:0] reg_out;
+
+//-----------------------------------------------------------------------
+// Main code starts here
+//-----------------------------------------------------------------------
+
+//-----------------------------------------------------------------------
+// To avoid interface timing, all the content are registered
+//-----------------------------------------------------------------------
+always @ (posedge mclk or negedge reset_n)
+begin
+ if (reset_n == 1'b0)
+ begin
+ sw_addr <= '0;
+ sw_rd_en <= '0;
+ sw_wr_en <= '0;
+ sw_reg_wdata <= '0;
+ wr_be <= '0;
+ reg_cs_l <= '0;
+ reg_cs_2l <= '0;
+ end else begin
+ sw_addr <= reg_addr [3:2];
+ sw_rd_en <= reg_cs & !reg_wr;
+ sw_wr_en <= reg_cs & reg_wr;
+ sw_reg_wdata <= reg_wdata;
+ wr_be <= reg_be;
+ reg_cs_l <= reg_cs;
+ reg_cs_2l <= reg_cs_l;
+ end
+end
+
+//-----------------------------------------------------------------------
+// Read path mux
+//-----------------------------------------------------------------------
+
+always @ (posedge mclk or negedge reset_n)
+begin : preg_out_Seq
+ if (reset_n == 1'b0) begin
+ reg_rdata [31:0] <= 32'h0000_0000;
+ reg_ack <= 1'b0;
+ end else if (sw_rd_en && !reg_ack && !reg_cs_2l) begin
+ reg_rdata [31:0] <= reg_out [31:0];
+ reg_ack <= 1'b1;
+ end else if (sw_wr_en && !reg_ack && !reg_cs_2l) begin
+ reg_ack <= 1'b1;
+ end else begin
+ reg_ack <= 1'b0;
+ end
+end
+//-----------------------------------------------------------------------
+// register read enable and write enable decoding logic
+//-----------------------------------------------------------------------
+wire sw_wr_en_0 = sw_wr_en & (sw_addr == 2'h0);
+wire sw_rd_en_0 = sw_rd_en & (sw_addr == 2'h0);
+wire sw_wr_en_1 = sw_wr_en & (sw_addr == 2'h1);
+wire sw_rd_en_1 = sw_rd_en & (sw_addr == 2'h1);
+wire sw_wr_en_2 = sw_wr_en & (sw_addr == 2'h2);
+wire sw_rd_en_2 = sw_rd_en & (sw_addr == 2'h2);
+wire sw_wr_en_3 = sw_wr_en & (sw_addr == 2'h3);
+wire sw_rd_en_3 = sw_rd_en & (sw_addr == 2'h3);
+
+
+always @( *)
+begin : preg_sel_Com
+
+ reg_out [31:0] = 32'd0;
+
+ case (sw_addr [3:0])
+ 4'b0000 : reg_out [31:0] = reg_0 [31:0];
+ 4'b0001 : reg_out [31:0] = reg_1 [31:0];
+ 4'b0010 : reg_out [31:0] = reg_2 [31:0];
+ default : reg_out [31:0] = 32'h0;
+ endcase
+end
+
+
+
+//-----------------------------------------------------------------------
+// Individual register assignments
+//-----------------------------------------------------------------------
+// Logic for Register 0 : SPI Control Register
+//-----------------------------------------------------------------------
+assign cfg_op_req = reg_0[31]; // cpu request
+assign cfg_tgt_sel = reg_0[24:23]; // target chip select
+assign cfg_op_type = reg_0[22:21]; // SPI operation type
+assign cfg_transfer_size = reg_0[20:19]; // SPI transfer size
+assign cfg_sck_period = reg_0[18:13]; // sck clock period
+assign cfg_sck_cs_period = reg_0[12:8]; // cs setup/hold period
+assign cfg_cs_byte = reg_0[7:0]; // cs bit information
+
+generic_register #(8,0 ) u_spi_ctrl_be0 (
+ .we ({8{sw_wr_en_0 &
+ wr_be[0] }} ),
+ .data_in (sw_reg_wdata[7:0] ),
+ .reset_n (reset_n ),
+ .clk (mclk ),
+
+ //List of Outs
+ .data_out (reg_0[7:0] )
+ );
+
+generic_register #(8,0 ) u_spi_ctrl_be1 (
+ .we ({8{sw_wr_en_0 &
+ wr_be[1] }} ),
+ .data_in (sw_reg_wdata[15:8] ),
+ .reset_n (reset_n ),
+ .clk (mclk ),
+
+ //List of Outs
+ .data_out (reg_0[15:8] )
+ );
+
+generic_register #(8,0 ) u_spi_ctrl_be2 (
+ .we ({8{sw_wr_en_0 &
+ wr_be[2] }} ),
+ .data_in (sw_reg_wdata[23:16] ),
+ .reset_n (reset_n ),
+ .clk (mclk ),
+
+ //List of Outs
+ .data_out (reg_0[23:16] )
+ );
+
+assign reg_0[30:24] = 7'h0;
+
+req_register #(0 ) u_spi_ctrl_req (
+ .cpu_we ({sw_wr_en_0 &
+ wr_be[3] } ),
+ .cpu_req (sw_reg_wdata[31] ),
+ .hware_ack (hware_op_done ),
+ .reset_n (reset_n ),
+ .clk (mclk ),
+
+ //List of Outs
+ .data_out (reg_0[31] )
+ );
+
+
+
+
+//-----------------------------------------------------------------------
+// Logic for Register 1 : SPI Data In Register
+//-----------------------------------------------------------------------
+assign cfg_datain = reg_1[31:0];
+
+generic_register #(8,0 ) u_spi_din_be0 (
+ .we ({8{sw_wr_en_1 &
+ wr_be[0] }} ),
+ .data_in (sw_reg_wdata[7:0] ),
+ .reset_n (reset_n ),
+ .clk (mclk ),
+
+ //List of Outs
+ .data_out (reg_1[7:0] )
+ );
+
+generic_register #(8,0 ) u_spi_din_be1 (
+ .we ({8{sw_wr_en_1 &
+ wr_be[1] }} ),
+ .data_in (sw_reg_wdata[15:8] ),
+ .reset_n (reset_n ),
+ .clk (mclk ),
+
+ //List of Outs
+ .data_out (reg_1[15:8] )
+ );
+
+generic_register #(8,0 ) u_spi_din_be2 (
+ .we ({8{sw_wr_en_1 &
+ wr_be[2] }} ),
+ .data_in (sw_reg_wdata[23:16] ),
+ .reset_n (reset_n ),
+ .clk (mclk ),
+
+ //List of Outs
+ .data_out (reg_1[23:16] )
+ );
+
+
+generic_register #(8,0 ) u_spi_din_be3 (
+ .we ({8{sw_wr_en_1 &
+ wr_be[3] }} ),
+ .data_in (sw_reg_wdata[31:24] ),
+ .reset_n (reset_n ),
+ .clk (mclk ),
+
+ //List of Outs
+ .data_out (reg_1[31:24] )
+ );
+
+
+//-----------------------------------------------------------------------
+// Logic for Register 2 : SPI Data output Register
+//-----------------------------------------------------------------------
+assign reg_2 = cfg_dataout;
+
+
+
+endmodule
diff --git a/verilog/rtl/sspim/src/sspim_ctl.sv b/verilog/rtl/sspim/src/sspim_ctl.sv
new file mode 100755
index 0000000..f65c0c2
--- /dev/null
+++ b/verilog/rtl/sspim/src/sspim_ctl.sv
@@ -0,0 +1,286 @@
+//////////////////////////////////////////////////////////////////////
+//// ////
+//// Single SPI Master Interface Module ////
+//// ////
+//// This file is part of the riscduino cores project ////
+//// https://github.com/dineshannayya/riscduino.git ////
+//// ////
+//// Description ////
+//// SPI Control module ////
+//// ////
+//// To Do: ////
+//// nothing ////
+//// ////
+//// Author(s): ////
+//// - Dinesh Annayya, dinesha@opencores.org ////
+//// ////
+//// Revision : ////
+//// V.0 - 06 Oct 2021 ////
+//// Initial SpI Module picked from ////
+//// http://www.opencores.org/cores/turbo8051/ ////
+//// ////
+//////////////////////////////////////////////////////////////////////
+//// ////
+//// Copyright (C) 2000 Authors and OPENCORES.ORG ////
+//// ////
+//// This source file may be used and distributed without ////
+//// restriction provided that this copyright statement is not ////
+//// removed from the file and that any derivative work contains ////
+//// the original copyright notice and the associated disclaimer. ////
+//// ////
+//// This source file is free software; you can redistribute it ////
+//// and/or modify it under the terms of the GNU Lesser General ////
+//// Public License as published by the Free Software Foundation; ////
+//// either version 2.1 of the License, or (at your option) any ////
+//// later version. ////
+//// ////
+//// This source is distributed in the hope that it will be ////
+//// useful, but WITHOUT ANY WARRANTY; without even the implied ////
+//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR ////
+//// PURPOSE. See the GNU Lesser General Public License for more ////
+//// details. ////
+//// ////
+//// You should have received a copy of the GNU Lesser General ////
+//// Public License along with this source; if not, download it ////
+//// from http://www.opencores.org/lgpl.shtml ////
+//// ////
+//////////////////////////////////////////////////////////////////////
+
+
+
+module sspim_ctl
+ (
+ input logic clk,
+ input logic reset_n,
+ input logic cfg_op_req,
+ input logic [1:0] cfg_op_type,
+ input logic [1:0] cfg_transfer_size,
+
+ input logic [5:0] cfg_sck_period,
+ input logic [4:0] cfg_sck_cs_period, // cs setup & hold period
+ input logic [7:0] cfg_cs_byte,
+ input logic [31:0] cfg_datain,
+ output logic [31:0] cfg_dataout,
+
+ output logic [7:0] byte_out, // Byte out for Serial Shifting out
+ input logic [7:0] byte_in, // Serial Received Byte
+ output logic sck_int,
+ output logic cs_int_n,
+ output logic sck_pe,
+ output logic sck_ne,
+ output logic shift_out,
+ output logic shift_in,
+ output logic load_byte,
+ output logic op_done
+
+ );
+
+ //*************************************************************************
+
+
+ logic [5:0] clk_cnt;
+ logic [5:0] sck_cnt;
+
+ logic [3:0] spiif_cs;
+ logic shift_enb;
+ logic clr_sck_cnt ;
+ logic sck_out_en;
+
+ logic [5:0] sck_half_period;
+ logic [2:0] byte_cnt;
+
+
+ `define SPI_IDLE 4'b0000
+ `define SPI_CS_SU 4'b0001
+ `define SPI_WRITE 4'b0010
+ `define SPI_READ 4'b0011
+ `define SPI_CS_HLD 4'b0100
+ `define SPI_WAIT 4'b0101
+
+
+ assign sck_half_period = {1'b0, cfg_sck_period[5:1]};
+ // The first transition on the sck_toggle happens one SCK period
+ // after op_en or boot_en is asserted
+ always @(posedge clk or negedge reset_n) begin
+ if(!reset_n) begin
+ sck_ne <= 1'b0;
+ clk_cnt <= 6'h1;
+ sck_pe <= 1'b0;
+ sck_int <= 1'b0;
+ end // if (!reset_n)
+ else
+ begin
+ if(cfg_op_req)
+ begin
+ if(clk_cnt == sck_half_period)
+ begin
+ sck_ne <= 1'b1;
+ sck_pe <= 1'b0;
+ if(sck_out_en) sck_int <= 0;
+ clk_cnt <= clk_cnt + 1'b1;
+ end // if (clk_cnt == sck_half_period)
+ else
+ begin
+ if(clk_cnt == cfg_sck_period)
+ begin
+ sck_ne <= 1'b0;
+ sck_pe <= 1'b1;
+ if(sck_out_en) sck_int <= 1;
+ clk_cnt <= 6'h1;
+ end // if (clk_cnt == cfg_sck_period)
+ else
+ begin
+ clk_cnt <= clk_cnt + 1'b1;
+ sck_pe <= 1'b0;
+ sck_ne <= 1'b0;
+ end // else: !if(clk_cnt == cfg_sck_period)
+ end // else: !if(clk_cnt == sck_half_period)
+ end // if (op_en)
+ else
+ begin
+ clk_cnt <= 6'h1;
+ sck_pe <= 1'b0;
+ sck_ne <= 1'b0;
+ end // else: !if(op_en)
+ end // else: !if(!reset_n)
+ end // always @ (posedge clk or negedge reset_n)
+
+
+wire [1:0] cs_data = (byte_cnt == 2'b00) ? cfg_cs_byte[7:6] :
+ (byte_cnt == 2'b01) ? cfg_cs_byte[5:4] :
+ (byte_cnt == 2'b10) ? cfg_cs_byte[3:2] : cfg_cs_byte[1:0] ;
+
+assign byte_out = (byte_cnt == 2'b00) ? cfg_datain[31:24] :
+ (byte_cnt == 2'b01) ? cfg_datain[23:16] :
+ (byte_cnt == 2'b10) ? cfg_datain[15:8] : cfg_datain[7:0] ;
+
+assign shift_out = shift_enb && sck_ne;
+
+always @(posedge clk or negedge reset_n) begin
+ if(!reset_n) begin
+ spiif_cs <= `SPI_IDLE;
+ sck_cnt <= 6'h0;
+ shift_in <= 1'b0;
+ clr_sck_cnt <= 1'b1;
+ byte_cnt <= 2'b00;
+ cs_int_n <= 1'b1;
+ sck_out_en <= 1'b0;
+ shift_enb <= 1'b0;
+ cfg_dataout <= 32'h0;
+ load_byte <= 1'b0;
+ end
+ else begin
+ if(sck_ne)
+ sck_cnt <= clr_sck_cnt ? 6'h0 : sck_cnt + 1 ;
+
+ case(spiif_cs)
+ `SPI_IDLE :
+ begin
+ op_done <= 0;
+ clr_sck_cnt <= 1'b1;
+ sck_out_en <= 1'b0;
+ shift_enb <= 1'b0;
+ if(cfg_op_req)
+ begin
+ cfg_dataout <= 32'h0;
+ spiif_cs <= `SPI_CS_SU;
+ end
+ else begin
+ spiif_cs <= `SPI_IDLE;
+ end
+ end
+
+ `SPI_CS_SU :
+ begin
+ if(sck_ne) begin
+ cs_int_n <= cs_data[1];
+ if(sck_cnt == cfg_sck_cs_period) begin
+ clr_sck_cnt <= 1'b1;
+ if(cfg_op_type == 0) begin // Write Mode
+ load_byte <= 1'b1;
+ spiif_cs <= `SPI_WRITE;
+ shift_enb <= 1'b0;
+ end else begin
+ shift_in <= 1;
+ spiif_cs <= `SPI_READ;
+ end
+ end
+ else begin
+ clr_sck_cnt <= 1'b0;
+ end
+ end
+ end
+
+ `SPI_WRITE :
+ begin
+ load_byte <= 1'b0;
+ if(sck_ne) begin
+ if(sck_cnt == 3'h7 )begin
+ clr_sck_cnt <= 1'b1;
+ spiif_cs <= `SPI_CS_HLD;
+ shift_enb <= 1'b0;
+ sck_out_en <= 1'b0; // Disable clock output
+ end
+ else begin
+ shift_enb <= 1'b1;
+ sck_out_en <= 1'b1;
+ clr_sck_cnt <= 1'b0;
+ end
+ end else begin
+ shift_enb <= 1'b1;
+ end
+ end
+
+ `SPI_READ :
+ begin
+ if(sck_ne) begin
+ if( sck_cnt == 3'h7 ) begin
+ clr_sck_cnt <= 1'b1;
+ shift_in <= 0;
+ spiif_cs <= `SPI_CS_HLD;
+ sck_out_en <= 1'b0; // Disable clock output
+ end
+ else begin
+ sck_out_en <= 1'b1; // Disable clock output
+ clr_sck_cnt <= 1'b0;
+ end
+ end
+ end
+
+ `SPI_CS_HLD : begin
+ if(sck_ne) begin
+ cs_int_n <= cs_data[0];
+ if(sck_cnt == cfg_sck_cs_period) begin
+ if(cfg_op_type == 1) begin // Read Mode
+ cfg_dataout <= (byte_cnt[1:0] == 2'b00) ? { byte_in, cfg_dataout[23:0] } :
+ (byte_cnt[1:0] == 2'b01) ? { cfg_dataout[31:24] ,
+ byte_in, cfg_dataout[15:0] } :
+ (byte_cnt[1:0] == 2'b10) ? { cfg_dataout[31:16] ,
+ byte_in, cfg_dataout[7:0] } :
+ { cfg_dataout[31:8] ,
+ byte_in } ;
+ end
+ clr_sck_cnt <= 1'b1;
+ if(byte_cnt == cfg_transfer_size) begin
+ spiif_cs <= `SPI_WAIT;
+ byte_cnt <= 0;
+ op_done <= 1;
+ end else begin
+ byte_cnt <= byte_cnt +1;
+ spiif_cs <= `SPI_CS_SU;
+ end
+ end
+ else begin
+ clr_sck_cnt <= 1'b0;
+ end
+ end
+ end // case: `SPI_CS_HLD
+ `SPI_WAIT : begin
+ if(!cfg_op_req) // Wait for Request de-assertion
+ spiif_cs <= `SPI_IDLE;
+ end
+ endcase // casex(spiif_cs)
+ end
+end // always @(sck_ne
+
+endmodule
diff --git a/verilog/rtl/sspim/src/sspim_if.sv b/verilog/rtl/sspim/src/sspim_if.sv
new file mode 100755
index 0000000..42b18f2
--- /dev/null
+++ b/verilog/rtl/sspim/src/sspim_if.sv
@@ -0,0 +1,122 @@
+//////////////////////////////////////////////////////////////////////
+//// ////
+//// Single SPI Master Interface Module ////
+//// ////
+//// This file is part of the riscduino cores project ////
+//// https://github.com/dineshannayya/riscduino.git ////
+//// ////
+//// Description ////
+//// ////
+//// To Do: ////
+//// nothing ////
+//// ////
+//// Author(s): ////
+//// - Dinesh Annayya, dinesha@opencores.org ////
+//// ////
+//// Revision : ////
+//// V.0 - 06 Oct 2021 ////
+//// Initial SpI Module picked from ////
+//// http://www.opencores.org/cores/turbo8051/ ////
+//// ////
+//////////////////////////////////////////////////////////////////////
+//// ////
+//// Copyright (C) 2000 Authors and OPENCORES.ORG ////
+//// ////
+//// This source file may be used and distributed without ////
+//// restriction provided that this copyright statement is not ////
+//// removed from the file and that any derivative work contains ////
+//// the original copyright notice and the associated disclaimer. ////
+//// ////
+//// This source file is free software; you can redistribute it ////
+//// and/or modify it under the terms of the GNU Lesser General ////
+//// Public License as published by the Free Software Foundation; ////
+//// either version 2.1 of the License, or (at your option) any ////
+//// later version. ////
+//// ////
+//// This source is distributed in the hope that it will be ////
+//// useful, but WITHOUT ANY WARRANTY; without even the implied ////
+//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR ////
+//// PURPOSE. See the GNU Lesser General Public License for more ////
+//// details. ////
+//// ////
+//// You should have received a copy of the GNU Lesser General ////
+//// Public License along with this source; if not, download it ////
+//// from http://www.opencores.org/lgpl.shtml ////
+//// ////
+//////////////////////////////////////////////////////////////////////
+
+module sspim_if
+ (
+ input logic clk,
+ input logic reset_n,
+ input logic sck_pe,
+ input logic sck_int,
+ input logic cs_int_n,
+
+ input logic load_byte,
+ input logic [1:0] cfg_tgt_sel,
+
+ input logic [7:0] byte_out,
+ input logic shift_out,
+ input logic shift_in,
+
+ output logic [7:0] byte_in,
+ output logic sck,
+ output logic so,
+ output logic [3:0] cs_n,
+ input logic si
+ );
+
+
+
+ logic [7:0] so_reg;
+ logic [7:0] si_reg;
+
+
+ //Output Shift Register
+
+ always @(posedge clk or negedge reset_n) begin
+ if(!reset_n) begin
+ so_reg <= 8'h00;
+ so <= 1'b0;
+ end
+ else begin
+ if(load_byte) begin
+ so_reg <= byte_out;
+ if(shift_out) begin
+ // Handling backto back case :
+ // Last Transfer bit + New Trasfer Load
+ so <= so_reg[7];
+ end
+ end // if (load_byte)
+ else begin
+ if(shift_out) begin
+ so <= so_reg[7];
+ so_reg <= {so_reg[6:0],1'b0};
+ end // if (shift_out)
+ end // else: !if(load_byte)
+ end // else: !if(!reset_n)
+ end // always @ (posedge clk or negedge reset_n)
+
+
+// Input shift register
+ always @(posedge clk or negedge reset_n) begin
+ if(!reset_n) begin
+ si_reg <= 8'h0;
+ end
+ else begin
+ if(sck_pe & shift_in) begin
+ si_reg[7:0] <= {si_reg[6:0],si};
+ end // if (sck_pe & shift_in)
+ end // else: !if(!reset_n)
+ end // always @ (posedge clk or negedge reset_n)
+
+
+ assign byte_in[7:0] = si_reg[7:0];
+ assign cs_n[0] = (cfg_tgt_sel[1:0] == 2'b00) ? cs_int_n : 1'b1;
+ assign cs_n[1] = (cfg_tgt_sel[1:0] == 2'b01) ? cs_int_n : 1'b1;
+ assign cs_n[2] = (cfg_tgt_sel[1:0] == 2'b10) ? cs_int_n : 1'b1;
+ assign cs_n[3] = (cfg_tgt_sel[1:0] == 2'b11) ? cs_int_n : 1'b1;
+ assign sck = sck_int;
+
+endmodule
diff --git a/verilog/rtl/sspim/src/sspim_top.sv b/verilog/rtl/sspim/src/sspim_top.sv
new file mode 100755
index 0000000..0c740d6
--- /dev/null
+++ b/verilog/rtl/sspim/src/sspim_top.sv
@@ -0,0 +1,208 @@
+
+//////////////////////////////////////////////////////////////////////////////
+// SPDX-FileCopyrightText: 2021 , Dinesh Annayya
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+// SPDX-License-Identifier: Apache-2.0
+// SPDX-FileContributor: Created by Dinesh Annayya <dinesha@opencores.org>
+//
+//////////////////////////////////////////////////////////////////////
+//// ////
+//// SPI Master Top Module ////
+//// ////
+//// This file is part of the riscduino cores project ////
+//// https://github.com/dineshannayya/riscduino.git ////
+//// This block integrate the SPI Master related module ////
+//// - sspim_if ////
+//// - sspim_ctl ////
+//// - sspim_cfg ////
+//// ////
+//// ////
+//// To Do: ////
+//// nothing ////
+//// ////
+//// Author(s): ////
+//// - Dinesh Annayya, dinesha@opencores.org ////
+//// ////
+//// Revision : ////
+//// 0.1 - 03 Oct 2021, Dinesh A ////
+//// Initial SpI Module picked from ////
+//// http://www.opencores.org/cores/turbo8051/ ////
+//// ////
+//////////////////////////////////////////////////////////////////////
+//// ////
+//// Copyright (C) 2000 Authors and OPENCORES.ORG ////
+//// ////
+//// This source file may be used and distributed without ////
+//// restriction provided that this copyright statement is not ////
+//// removed from the file and that any derivative work contains ////
+//// the original copyright notice and the associated disclaimer. ////
+//// ////
+//// This source file is free software; you can redistribute it ////
+//// and/or modify it under the terms of the GNU Lesser General ////
+//// Public License as published by the Free Software Foundation; ////
+//// either version 2.1 of the License, or (at your option) any ////
+//// later version. ////
+//// ////
+//// This source is distributed in the hope that it will be ////
+//// useful, but WITHOUT ANY WARRANTY; without even the implied ////
+//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR ////
+//// PURPOSE. See the GNU Lesser General Public License for more ////
+//// details. ////
+//// ////
+//// You should have received a copy of the GNU Lesser General ////
+//// Public License along with this source; if not, download it ////
+//// from http://www.opencores.org/lgpl.shtml ////
+//// ////
+//////////////////////////////////////////////////////////////////////
+
+
+module sspim_top (
+ input logic clk ,
+ input logic reset_n ,
+
+
+ //---------------------------------
+ // Reg Bus Interface Signal
+ //---------------------------------
+ input logic reg_cs ,
+ input logic reg_wr ,
+ input logic [7:0] reg_addr ,
+ input logic [31:0] reg_wdata ,
+ input logic [3:0] reg_be ,
+
+ // Outputs
+ output logic [31:0] reg_rdata ,
+ output logic reg_ack ,
+
+ //-------------------------------------------
+ // Line Interface
+ //-------------------------------------------
+
+ output logic sck , // clock out
+ output logic so , // serial data out
+ input logic si , // serial data in
+ output logic ssn // cs_n
+
+ );
+
+
+//------------------------------------
+// Local declration
+//------------------------------------
+
+logic [7:0] byte_in ;
+logic [7:0] byte_out ;
+
+
+logic [1:0] cfg_tgt_sel ;
+
+logic cfg_op_req ; // SPI operation request
+logic [1:0] cfg_op_type ; // SPI operation type
+logic [1:0] cfg_transfer_size ; // SPI transfer size
+logic [5:0] cfg_sck_period ; // sck clock period
+logic [4:0] cfg_sck_cs_period ; // cs setup/hold period
+logic [7:0] cfg_cs_byte ; // cs bit information
+logic [31:0] cfg_datain ; // data for transfer
+logic [31:0] cfg_dataout ; // data for received
+logic hware_op_done ; // operation done
+logic [3:0] cs_n ; // cs_n
+
+assign ssn = cs_n[0]; // Only 1 chip select supported in riscdunio
+
+sspim_if u_spi_if
+ (
+ . clk (clk ),
+ . reset_n (reset_n ),
+
+ // towards ctrl i/f
+ . sck_pe (sck_pe ),
+ . sck_int (sck_int ),
+ . cs_int_n (cs_int_n ),
+ . byte_in (byte_in ),
+ . load_byte (load_byte ),
+ . byte_out (byte_out ),
+ . shift_out (shift_out ),
+ . shift_in (shift_in ),
+
+ . cfg_tgt_sel (cfg_tgt_sel ),
+
+ . sck (sck ),
+ . so (so ),
+ . si (si ),
+ . cs_n (cs_n )
+ );
+
+
+sspim_ctl u_spi_ctrl
+ (
+ . clk (clk ),
+ . reset_n (reset_n ),
+
+ . cfg_op_req (cfg_op_req ),
+ . cfg_op_type (cfg_op_type ),
+ . cfg_transfer_size (cfg_transfer_size ),
+ . cfg_sck_period (cfg_sck_period ),
+ . cfg_sck_cs_period (cfg_sck_cs_period ),
+ . cfg_cs_byte (cfg_cs_byte ),
+ . cfg_datain (cfg_datain ),
+ . cfg_dataout (cfg_dataout ),
+ . op_done (hware_op_done ),
+
+ . sck_int (sck_int ),
+ . cs_int_n (cs_int_n ),
+ . sck_pe (sck_pe ),
+ . sck_ne (sck_ne ),
+ . shift_out (shift_out ),
+ . shift_in (shift_in ),
+ . load_byte (load_byte ),
+ . byte_out (byte_out ),
+ . byte_in (byte_in )
+
+ );
+
+
+
+
+sspim_cfg u_cfg (
+
+ . mclk (clk ),
+ . reset_n (reset_n ),
+
+ // Reg Bus Interface Signal
+ . reg_cs (reg_cs ),
+ . reg_wr (reg_wr ),
+ . reg_addr (reg_addr ),
+ . reg_wdata (reg_wdata ),
+ . reg_be (reg_be ),
+
+ // Outputs
+ . reg_rdata (reg_rdata ),
+ . reg_ack (reg_ack ),
+
+
+ // configuration signal
+ . cfg_tgt_sel (cfg_tgt_sel ),
+ . cfg_op_req (cfg_op_req ), // SPI operation request
+ . cfg_op_type (cfg_op_type ), // SPI operation type
+ . cfg_transfer_size (cfg_transfer_size ), // SPI transfer size
+ . cfg_sck_period (cfg_sck_period ), // sck clock period
+ . cfg_sck_cs_period (cfg_sck_cs_period ), // cs setup/hold period
+ . cfg_cs_byte (cfg_cs_byte ), // cs bit information
+ . cfg_datain (cfg_datain ), // data for transfer
+ . cfg_dataout (cfg_dataout ), // data for received
+ . hware_op_done (hware_op_done ) // operation done
+
+ );
+
+endmodule
diff --git a/verilog/rtl/uart/src/uart_cfg.sv b/verilog/rtl/uart/src/uart_cfg.sv
new file mode 100644
index 0000000..ca4dea6
--- /dev/null
+++ b/verilog/rtl/uart/src/uart_cfg.sv
@@ -0,0 +1,405 @@
+//////////////////////////////////////////////////////////////////////////////
+// SPDX-FileCopyrightText: 2021 , Dinesh Annayya
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+// SPDX-License-Identifier: Apache-2.0
+// SPDX-FileContributor: Created by Dinesh Annayya <dinesha@opencores.org>
+//
+//////////////////////////////////////////////////////////////////////
+//// ////
+//// UART Configuration ////
+//// ////
+//// This file is part of the YIFive cores project ////
+//// https://github.com/dineshannayya/yifive_r0.git ////
+//// http://www.opencores.org/cores/yifive/ ////
+//// ////
+//// Description ////
+//// ////
+//// To Do: ////
+//// nothing ////
+//// ////
+//// Author(s): ////
+//// - Dinesh Annayya, dinesha@opencores.org ////
+//// ////
+//// Revision : ////
+//// 0.1 - 20th June 2021, Dinesh A ////
+//// 1. initial version picked from ////
+//// http://www.opencores.org/cores/oms8051mini ////
+//// 0.2 - 20th June 2021, Dinesh A ////
+//// tx and rx buffer status added into reg7 and reg8 ////
+//// ////
+//////////////////////////////////////////////////////////////////////
+//// ////
+//// Copyright (C) 2000 Authors and OPENCORES.ORG ////
+//// ////
+//// This source file may be used and distributed without ////
+//// restriction provided that this copyright statement is not ////
+//// removed from the file and that any derivative work contains ////
+//// the original copyright notice and the associated disclaimer. ////
+//// ////
+//// This source file is free software; you can redistribute it ////
+//// and/or modify it under the terms of the GNU Lesser General ////
+//// Public License as published by the Free Software Foundation; ////
+//// either version 2.1 of the License, or (at your option) any ////
+//// later version. ////
+//// ////
+//// This source is distributed in the hope that it will be ////
+//// useful, but WITHOUT ANY WARRANTY; without even the implied ////
+//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR ////
+//// PURPOSE. See the GNU Lesser General Public License for more ////
+//// details. ////
+//// ////
+//// You should have received a copy of the GNU Lesser General ////
+//// Public License along with this source; if not, download it ////
+//// from http://www.opencores.org/lgpl.shtml ////
+//// ////
+//////////////////////////////////////////////////////////////////////
+
+module uart_cfg (
+
+ mclk,
+ reset_n,
+
+ // Reg Bus Interface Signal
+ reg_cs,
+ reg_wr,
+ reg_addr,
+ reg_wdata,
+ reg_be,
+
+ // Outputs
+ reg_rdata,
+ reg_ack,
+
+ // Uart Tx fifo interface
+ tx_fifo_full,
+ tx_fifo_fspace,
+ tx_fifo_wr_en,
+ tx_fifo_data,
+
+ // Uart Rx fifo interface
+ rx_fifo_empty,
+ rx_fifo_dval ,
+ rx_fifo_rd_en,
+ rx_fifo_data ,
+
+ // configuration
+ cfg_tx_enable,
+ cfg_rx_enable,
+ cfg_stop_bit ,
+ cfg_pri_mod ,
+ cfg_baud_16x ,
+
+ frm_error_o,
+ par_error_o,
+ rx_fifo_full_err_o
+
+ );
+
+
+
+input mclk;
+input reset_n;
+
+//--------------------------------
+// Uart Tx fifo interface
+//--------------------------------
+input tx_fifo_full;
+input [4:0] tx_fifo_fspace ; // Total Tx fifo Free Space
+output tx_fifo_wr_en;
+output [7:0] tx_fifo_data;
+
+//--------------------------------
+// Uart Rx fifo interface
+//--------------------------------
+input rx_fifo_empty;
+input [4:0] rx_fifo_dval ; // Total Rx fifo Data Available
+output rx_fifo_rd_en;
+input [7:0] rx_fifo_data;
+
+//----------------------------------
+// configuration
+//----------------------------------
+output cfg_tx_enable ; // Tx Enable
+output cfg_rx_enable ; // Rx Enable
+output cfg_stop_bit ; // 0 -> 1 Stop, 1 -> 2 Stop
+output [1:0] cfg_pri_mod ; // priority mode, 0 -> nop, 1 -> Even, 2 -> Odd
+output [11:0] cfg_baud_16x ; // 16x Baud clock config
+
+input frm_error_o ; // framing error
+input par_error_o ; // par error
+input rx_fifo_full_err_o ; // rx fifo full error
+
+//---------------------------------
+// Reg Bus Interface Signal
+//---------------------------------
+input reg_cs ;
+input reg_wr ;
+input [3:0] reg_addr ;
+input [7:0] reg_wdata ;
+input reg_be ;
+
+// Outputs
+output [7:0] reg_rdata ;
+output reg_ack ;
+
+
+
+//-----------------------------------------------------------------------
+// Internal Wire Declarations
+//-----------------------------------------------------------------------
+
+wire sw_rd_en;
+wire sw_wr_en;
+wire [3:0] sw_addr ; // addressing 16 registers
+wire wr_be ;
+
+reg [7:0] reg_rdata ;
+reg reg_ack ;
+
+wire [7:0] reg_0; // Software_Reg_0
+wire [7:0] reg_1; // Software-Reg_1
+wire [7:0] reg_2; // Software-Reg_2
+wire [7:0] reg_3; // Software-Reg_3
+wire [7:0] reg_4; // Software-Reg_4
+wire [7:0] reg_5; // Software-Reg_5
+wire [7:0] reg_6; // Software-Reg_6
+wire [7:0] reg_7; // Software-Reg_7
+wire [7:0] reg_8; // Software-Reg_8
+wire [7:0] reg_9; // Software-Reg_9
+wire [7:0] reg_10; // Software-Reg_10
+wire [7:0] reg_11; // Software-Reg_11
+wire [7:0] reg_12; // Software-Reg_12
+wire [7:0] reg_13; // Software-Reg_13
+wire [7:0] reg_14; // Software-Reg_14
+wire [7:0] reg_15; // Software-Reg_15
+reg [7:0] reg_out;
+
+//-----------------------------------------------------------------------
+// Main code starts here
+//-----------------------------------------------------------------------
+
+//-----------------------------------------------------------------------
+// Internal Logic Starts here
+//-----------------------------------------------------------------------
+ assign sw_addr = reg_addr [3:0];
+ assign sw_rd_en = reg_cs & !reg_wr;
+ assign sw_wr_en = reg_cs & reg_wr;
+ assign wr_be = reg_be;
+
+
+//-----------------------------------------------------------------------
+// Read path mux
+//-----------------------------------------------------------------------
+
+always @ (posedge mclk or negedge reset_n)
+begin : preg_out_Seq
+ if (reset_n == 1'b0)
+ begin
+ reg_rdata [7:0] <= 8'h00;
+ reg_ack <= 1'b0;
+ end
+ else if (sw_rd_en && !reg_ack)
+ begin
+ reg_rdata [7:0] <= reg_out [7:0];
+ reg_ack <= 1'b1;
+ end
+ else if (sw_wr_en && !reg_ack)
+ reg_ack <= 1'b1;
+ else
+ begin
+ reg_ack <= 1'b0;
+ end
+end
+
+
+//-----------------------------------------------------------------------
+// register read enable and write enable decoding logic
+//-----------------------------------------------------------------------
+wire sw_wr_en_0 = sw_wr_en & (sw_addr == 4'h0);
+wire sw_rd_en_0 = sw_rd_en & (sw_addr == 4'h0);
+wire sw_wr_en_1 = sw_wr_en & (sw_addr == 4'h1);
+wire sw_rd_en_1 = sw_rd_en & (sw_addr == 4'h1);
+wire sw_wr_en_2 = sw_wr_en & (sw_addr == 4'h2);
+wire sw_rd_en_2 = sw_rd_en & (sw_addr == 4'h2);
+wire sw_wr_en_3 = sw_wr_en & (sw_addr == 4'h3);
+wire sw_rd_en_3 = sw_rd_en & (sw_addr == 4'h3);
+wire sw_wr_en_4 = sw_wr_en & (sw_addr == 4'h4);
+wire sw_rd_en_4 = sw_rd_en & (sw_addr == 4'h4);
+wire sw_wr_en_5 = sw_wr_en & (sw_addr == 4'h5);
+wire sw_rd_en_5 = sw_rd_en & (sw_addr == 4'h5);
+wire sw_wr_en_6 = sw_wr_en & (sw_addr == 4'h6);
+wire sw_rd_en_6 = sw_rd_en & (sw_addr == 4'h6);
+wire sw_wr_en_7 = sw_wr_en & (sw_addr == 4'h7);
+wire sw_rd_en_7 = sw_rd_en & (sw_addr == 4'h7);
+wire sw_wr_en_8 = sw_wr_en & (sw_addr == 4'h8);
+wire sw_rd_en_8 = sw_rd_en & (sw_addr == 4'h8);
+wire sw_wr_en_9 = sw_wr_en & (sw_addr == 4'h9);
+wire sw_rd_en_9 = sw_rd_en & (sw_addr == 4'h9);
+wire sw_wr_en_10 = sw_wr_en & (sw_addr == 4'hA);
+wire sw_rd_en_10 = sw_rd_en & (sw_addr == 4'hA);
+wire sw_wr_en_11 = sw_wr_en & (sw_addr == 4'hB);
+wire sw_rd_en_11 = sw_rd_en & (sw_addr == 4'hB);
+wire sw_wr_en_12 = sw_wr_en & (sw_addr == 4'hC);
+wire sw_rd_en_12 = sw_rd_en & (sw_addr == 4'hC);
+wire sw_wr_en_13 = sw_wr_en & (sw_addr == 4'hD);
+wire sw_rd_en_13 = sw_rd_en & (sw_addr == 4'hD);
+wire sw_wr_en_14 = sw_wr_en & (sw_addr == 4'hE);
+wire sw_rd_en_14 = sw_rd_en & (sw_addr == 4'hE);
+wire sw_wr_en_15 = sw_wr_en & (sw_addr == 4'hF);
+wire sw_rd_en_15 = sw_rd_en & (sw_addr == 4'hF);
+
+
+always @( *)
+begin : preg_sel_Com
+
+ reg_out [7:0] = 8'd0;
+
+ case (sw_addr [3:0])
+ 4'b0000 : reg_out [7:0] = reg_0 [7:0];
+ 4'b0001 : reg_out [7:0] = reg_1 [7:0];
+ 4'b0010 : reg_out [7:0] = reg_2 [7:0];
+ 4'b0011 : reg_out [7:0] = reg_3 [7:0];
+ 4'b0100 : reg_out [7:0] = reg_4 [7:0];
+ 4'b0101 : reg_out [7:0] = reg_5 [7:0];
+ 4'b0110 : reg_out [7:0] = reg_6 [7:0];
+ 4'b0111 : reg_out [7:0] = reg_7 [7:0];
+ 4'b1000 : reg_out [7:0] = reg_8 [7:0];
+ 4'b1001 : reg_out [7:0] = reg_9 [7:0];
+ 4'b1010 : reg_out [7:0] = reg_10 [7:0];
+ 4'b1011 : reg_out [7:0] = reg_11 [7:0];
+ 4'b1100 : reg_out [7:0] = reg_12 [7:0];
+ 4'b1101 : reg_out [7:0] = reg_13 [7:0];
+ 4'b1110 : reg_out [7:0] = reg_14 [7:0];
+ 4'b1111 : reg_out [7:0] = reg_15 [7:0];
+ endcase
+end
+
+
+
+//-----------------------------------------------------------------------
+// Individual register assignments
+//-----------------------------------------------------------------------
+// Logic for Register 0 : uart Control Register
+//-----------------------------------------------------------------------
+wire [1:0] cfg_pri_mod = reg_0[4:3]; // priority mode, 0 -> nop, 1 -> Even, 2 -> Odd
+wire cfg_stop_bit = reg_0[2]; // 0 -> 1 Stop, 1 -> 2 Stop
+wire cfg_rx_enable = reg_0[1]; // Rx Enable
+wire cfg_tx_enable = reg_0[0]; // Tx Enable
+
+generic_register #(5,0 ) u_uart_ctrl_be0 (
+ .we ({5{sw_wr_en_0 &
+ wr_be }} ),
+ .data_in (reg_wdata[4:0] ),
+ .reset_n (reset_n ),
+ .clk (mclk ),
+
+ //List of Outs
+ .data_out (reg_0[4:0] )
+ );
+
+
+assign reg_0[7:5] = 3'h0;
+
+//-----------------------------------------------------------------------
+// Logic for Register 1 : uart interrupt status
+//-----------------------------------------------------------------------
+stat_register u_intr_bit0 (
+ //inputs
+ . clk (mclk ),
+ . reset_n (reset_n ),
+ . cpu_we (sw_wr_en_1 &
+ wr_be ),
+ . cpu_ack (reg_wdata[0] ),
+ . hware_req (frm_error_o ),
+
+ //outputs
+ . data_out (reg_1[0] )
+ );
+
+stat_register u_intr_bit1 (
+ //inputs
+ . clk (mclk ),
+ . reset_n (reset_n ),
+ . cpu_we (sw_wr_en_1 &
+ wr_be ),
+ . cpu_ack (reg_wdata[1] ),
+ . hware_req (par_error_o ),
+
+ //outputs
+ . data_out (reg_1[1] )
+ );
+
+stat_register u_intr_bit2 (
+ //inputs
+ . clk (mclk ),
+ . reset_n (reset_n ),
+ . cpu_we (sw_wr_en_1 &
+ wr_be ),
+ . cpu_ack (reg_wdata[2] ),
+ . hware_req (rx_fifo_full_err_o ),
+
+ //outputs
+ . data_out (reg_1[2] )
+ );
+
+assign reg_1[7:3] = 5'h0;
+
+
+//-----------------------------------------------------------------------
+// Logic for Register 2 : Baud Rate Control
+//-----------------------------------------------------------------------
+wire [11:0] cfg_baud_16x = {reg_3[3:0],reg_2[7:0]};
+
+generic_register #(8,0 ) u_uart_ctrl_reg2 (
+ .we ({8{sw_wr_en_2 &
+ wr_be }} ),
+ .data_in (reg_wdata[7:0] ),
+ .reset_n (reset_n ),
+ .clk (mclk ),
+
+ //List of Outs
+ .data_out (reg_2[7:0] )
+ );
+
+generic_register #(4,0 ) u_uart_ctrl_reg3 (
+ .we ({4{sw_wr_en_3 &
+ wr_be }} ),
+ .data_in (reg_wdata[3:0] ),
+ .reset_n (reset_n ),
+ .clk (mclk ),
+
+ //List of Outs
+ .data_out (reg_3[3:0] )
+ );
+
+assign reg_3[7:4] = 4'h0;
+
+
+// reg-4 status
+//
+assign reg_4[7:0] = {6'h0,rx_fifo_empty,tx_fifo_full};
+
+// reg_5 is tx_fifo wr
+assign tx_fifo_wr_en = sw_wr_en_5 & reg_ack & !tx_fifo_full;
+assign tx_fifo_data = reg_wdata[7:0];
+
+// reg_6 is rx_fifo read
+// rx_fifo read data
+assign reg_6[7:0] = {rx_fifo_data};
+assign rx_fifo_rd_en = sw_rd_en_6 & reg_ack & !rx_fifo_empty;
+
+assign reg_7[7:0] = {3'h0,tx_fifo_fspace}; // tx fifo free space
+assign reg_8[7:0] = {3'h0,rx_fifo_dval}; // rx fifo data available
+
+endmodule
diff --git a/verilog/rtl/uart/src/uart_core.sv b/verilog/rtl/uart/src/uart_core.sv
new file mode 100644
index 0000000..948cd35
--- /dev/null
+++ b/verilog/rtl/uart/src/uart_core.sv
@@ -0,0 +1,334 @@
+//////////////////////////////////////////////////////////////////////////////
+// SPDX-FileCopyrightText: 2021 , Dinesh Annayya
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+// SPDX-License-Identifier: Apache-2.0
+// SPDX-FileContributor: Created by Dinesh Annayya <dinesha@opencores.org>
+//
+//////////////////////////////////////////////////////////////////////
+//// ////
+//// UART CORE with TX/RX 16 Byte Buffer ////
+//// ////
+//// This file is part of the YIFive cores project ////
+//// https://github.com/dineshannayya/yifive_r0.git ////
+//// http://www.opencores.org/cores/yifive/ ////
+//// ////
+//// Description ////
+//// ////
+//// To Do: ////
+//// nothing ////
+//// ////
+//// Author(s): ////
+//// - Dinesh Annayya, dinesha@opencores.org ////
+//// ////
+//// Revision : ////
+//// 0.1 - 20th June 2021, Dinesh A ////
+//// 1. initial version picked from ////
+//// http://www.opencores.org/cores/oms8051mini ////
+//// 0.2 - 25th June 2021, Dinesh A ////
+//// Pad logic moved inside core to avoid combo logic at ////
+//// soc digital core level ////
+//// ////
+//////////////////////////////////////////////////////////////////////
+//// ////
+//// Copyright (C) 2000 Authors and OPENCORES.ORG ////
+//// ////
+//// This source file may be used and distributed without ////
+//// restriction provided that this copyright statement is not ////
+//// removed from the file and that any derivative work contains ////
+//// the original copyright notice and the associated disclaimer. ////
+//// ////
+//// This source file is free software; you can redistribute it ////
+//// and/or modify it under the terms of the GNU Lesser General ////
+//// Public License as published by the Free Software Foundation; ////
+//// either version 2.1 of the License, or (at your option) any ////
+//// later version. ////
+//// ////
+//// This source is distributed in the hope that it will be ////
+//// useful, but WITHOUT ANY WARRANTY; without even the implied ////
+//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR ////
+//// PURPOSE. See the GNU Lesser General Public License for more ////
+//// details. ////
+//// ////
+//// You should have received a copy of the GNU Lesser General ////
+//// Public License along with this source; if not, download it ////
+//// from http://www.opencores.org/lgpl.shtml ////
+//// ////
+//////////////////////////////////////////////////////////////////////
+
+module uart_core
+
+ (
+
+ input logic arst_n , // async reset
+ input logic app_clk ,
+
+ // Reg Bus Interface Signal
+ input logic reg_cs,
+ input logic reg_wr,
+ input logic [3:0] reg_addr,
+ input logic [7:0] reg_wdata,
+ input logic reg_be,
+
+ // Outputs
+ output logic [7:0] reg_rdata,
+ output logic reg_ack,
+
+ // Pad Control
+ input logic rxd,
+ output logic txd
+
+ );
+
+
+
+
+parameter W = 8'd8;
+parameter DP = 8'd16;
+parameter AW = (DP == 2) ? 1 :
+ (DP == 4) ? 2 :
+ (DP == 8) ? 3 :
+ (DP == 16) ? 4 :
+ (DP == 32) ? 5 :
+ (DP == 64) ? 6 :
+ (DP == 128) ? 7 :
+ (DP == 256) ? 8 : 0;
+
+
+
+// Wire Declaration
+wire app_reset_n ;
+wire line_reset_n ;
+
+wire [W-1: 0] tx_fifo_rd_data;
+wire [W-1: 0] rx_fifo_wr_data;
+wire [W-1: 0] app_rxfifo_data;
+wire [W-1: 0] app_txfifo_data;
+wire [1 : 0] error_ind;
+
+// Wire
+wire cfg_tx_enable ; // Tx Enable
+wire cfg_rx_enable ; // Rx Enable
+wire cfg_stop_bit ; // 0 -> 1 Stop, 1 -> 2 Stop
+wire [1:0] cfg_pri_mod ; // priority mode, 0 -> nop, 1 -> Even, 2 -> Odd
+
+wire frm_error_o ; // framing error
+wire par_error_o ; // par error
+wire rx_fifo_full_err_o ; // rx fifo full error
+
+wire [11:0] cfg_baud_16x ; // 16x Baud clock generation
+wire rx_fifo_wr_full ;
+wire tx_fifo_rd_empty ;
+wire tx_fifo_rd ;
+wire app_rxfifo_empty ;
+wire app_rxfifo_rd_en ;
+wire app_tx_fifo_full ;
+wire rx_fifo_wr ;
+wire tx_fifo_wr_en ;
+wire [AW:0] tx_fifo_fspace ; // Total Tx fifo Free Space
+wire [AW:0] rx_fifo_dval ; // Total Rx fifo Data Available
+wire si_ss ;
+
+
+
+uart_cfg u_cfg (
+
+ . mclk (app_clk),
+ . reset_n (app_reset_n),
+
+ // Reg Bus Interface Signal
+ . reg_cs (reg_cs),
+ . reg_wr (reg_wr),
+ . reg_addr (reg_addr),
+ . reg_wdata (reg_wdata),
+ . reg_be (reg_be),
+
+ // Outputs
+ . reg_rdata (reg_rdata),
+ . reg_ack (reg_ack),
+
+
+ // configuration
+ . cfg_tx_enable (cfg_tx_enable),
+ . cfg_rx_enable (cfg_rx_enable),
+ . cfg_stop_bit (cfg_stop_bit),
+ . cfg_pri_mod (cfg_pri_mod),
+
+ . cfg_baud_16x (cfg_baud_16x),
+
+ . tx_fifo_full (app_tx_fifo_full),
+ .tx_fifo_fspace (tx_fifo_fspace ),
+ . tx_fifo_wr_en (tx_fifo_wr_en),
+ . tx_fifo_data (app_txfifo_data),
+
+ . rx_fifo_empty (app_rxfifo_empty),
+ .rx_fifo_dval (rx_fifo_dval ),
+ . rx_fifo_rd_en (app_rxfifo_rd_en),
+ . rx_fifo_data (app_rxfifo_data) ,
+
+ . frm_error_o (frm_error_o),
+ . par_error_o (par_error_o),
+ . rx_fifo_full_err_o (rx_fifo_full_err_o)
+
+ );
+
+
+//##############################################################
+// 16x Baud clock generation
+// Example: to generate 19200 Baud clock from 50Mhz Link clock
+// 50 * 1000 * 1000 / (2 + cfg_baud_16x) = 19200 * 16
+// cfg_baud_16x = 0xA0 (160)
+//###############################################################
+
+wire line_clk_16x_in;
+
+// OpenSource CTS tool does not work with buffer as source point
+// changed buf to max with select tied=0
+//ctech_clk_buf u_lineclk_buf (.A(line_clk_16x_in), .X(line_clk_16x));
+ctech_mux2x1 u_lineclk_buf (.A0(line_clk_16x_in), .A1(1'b0), .S(1'b0), .X(line_clk_16x));
+
+clk_ctl #(11) u_clk_ctl (
+ // Outputs
+ .clk_o (line_clk_16x_in),
+
+ // Inputs
+ .mclk (app_clk),
+ .reset_n (app_reset_n),
+ .clk_div_ratio (cfg_baud_16x)
+ );
+
+//###################################
+// Application Reset Synchronization
+//###################################
+reset_sync u_app_rst (
+ .scan_mode (1'b0 ),
+ .dclk (app_clk ), // Destination clock domain
+ .arst_n (arst_n ), // active low async reset
+ .srst_n (app_reset_n )
+ );
+
+//###################################
+// Line Reset Synchronization
+//###################################
+reset_sync u_line_rst (
+ .scan_mode (1'b0 ),
+ .dclk (line_clk_16x ), // Destination clock domain
+ .arst_n (arst_n ), // active low async reset
+ .srst_n (line_reset_n )
+ );
+
+
+uart_txfsm u_txfsm (
+ .reset_n ( line_reset_n ),
+ .baud_clk_16x ( line_clk_16x ),
+
+ .cfg_tx_enable ( cfg_tx_enable ),
+ .cfg_stop_bit ( cfg_stop_bit ),
+ .cfg_pri_mod ( cfg_pri_mod ),
+
+ // FIFO control signal
+ .fifo_empty ( tx_fifo_rd_empty ),
+ .fifo_rd ( tx_fifo_rd ),
+ .fifo_data ( tx_fifo_rd_data ),
+
+ // Line Interface
+ .so ( txd )
+ );
+
+
+uart_rxfsm u_rxfsm (
+ .reset_n ( line_reset_n ),
+ .baud_clk_16x ( line_clk_16x ) ,
+
+ .cfg_rx_enable ( cfg_rx_enable ),
+ .cfg_stop_bit ( cfg_stop_bit ),
+ .cfg_pri_mod ( cfg_pri_mod ),
+
+ .error_ind ( error_ind ),
+
+ // FIFO control signal
+ .fifo_aval ( !rx_fifo_wr_full ),
+ .fifo_wr ( rx_fifo_wr ),
+ .fifo_data ( rx_fifo_wr_data ),
+
+ // Line Interface
+ .si (si_ss )
+ );
+
+async_fifo_th #(W,DP,0,0) u_rxfifo (
+ .wr_clk (line_clk_16x ),
+ .wr_reset_n (line_reset_n ),
+ .wr_en (rx_fifo_wr ),
+ .wr_data (rx_fifo_wr_data ),
+ .full (rx_fifo_wr_full ), // sync'ed to wr_clk
+ .wr_total_free_space( ),
+
+ .rd_clk (app_clk ),
+ .rd_reset_n (app_reset_n ),
+ .rd_en (app_rxfifo_rd_en ),
+ .empty (app_rxfifo_empty ), // sync'ed to rd_clk
+ .rd_total_aval (rx_fifo_dval ),
+ .rd_data (app_rxfifo_data )
+ );
+
+async_fifo_th #(W,DP,0,0) u_txfifo (
+ .wr_clk (app_clk ),
+ .wr_reset_n (app_reset_n ),
+ .wr_en (tx_fifo_wr_en ),
+ .wr_data (app_txfifo_data ),
+ .full (app_tx_fifo_full ), // sync'ed to wr_clk
+ .wr_total_free_space(tx_fifo_fspace ),
+
+ .rd_clk (line_clk_16x ),
+ .rd_reset_n (line_reset_n ),
+ .rd_en (tx_fifo_rd ),
+ .empty (tx_fifo_rd_empty ), // sync'ed to rd_clk
+ .rd_total_aval ( ),
+ .rd_data (tx_fifo_rd_data )
+ );
+
+
+double_sync_low u_si_sync (
+ .in_data (rxd ),
+ .out_clk (line_clk_16x ),
+ .out_rst_n (line_reset_n ),
+ .out_data (si_ss )
+ );
+
+wire frm_error = (error_ind == 2'b01);
+wire par_error = (error_ind == 2'b10);
+wire rx_fifo_full_err = (error_ind == 2'b11);
+
+double_sync_low u_frm_err (
+ .in_data ( frm_error ),
+ .out_clk ( app_clk ),
+ .out_rst_n ( app_reset_n ),
+ .out_data ( frm_error_o )
+ );
+
+double_sync_low u_par_err (
+ .in_data ( par_error ),
+ .out_clk ( app_clk ),
+ .out_rst_n ( app_reset_n ),
+ .out_data ( par_error_o )
+ );
+
+double_sync_low u_rxfifo_err (
+ .in_data ( rx_fifo_full_err ),
+ .out_clk ( app_clk ),
+ .out_rst_n ( app_reset_n ),
+ .out_data ( rx_fifo_full_err_o )
+ );
+
+
+endmodule
diff --git a/verilog/rtl/uart/src/uart_rxfsm.sv b/verilog/rtl/uart/src/uart_rxfsm.sv
new file mode 100644
index 0000000..58916e6
--- /dev/null
+++ b/verilog/rtl/uart/src/uart_rxfsm.sv
@@ -0,0 +1,221 @@
+//////////////////////////////////////////////////////////////////////////////
+// SPDX-FileCopyrightText: 2021 , Dinesh Annayya
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+// SPDX-License-Identifier: Apache-2.0
+// SPDX-FileContributor: Created by Dinesh Annayya <dinesha@opencores.org>
+//
+//////////////////////////////////////////////////////////////////////
+//// ////
+//// UART RX FSM ////
+//// ////
+//// This file is part of the YIFive cores project ////
+//// https://github.com/dineshannayya/yifive_r0.git ////
+//// http://www.opencores.org/cores/yifive/ ////
+//// ////
+//// Description ////
+//// ////
+//// To Do: ////
+//// nothing ////
+//// ////
+//// Author(s): ////
+//// - Dinesh Annayya, dinesha@opencores.org ////
+//// ////
+//// Revision : ////
+//// 0.1 - 20th June 2021, Dinesh A ////
+//// 1. initial version picked from ////
+//// http://www.opencores.org/cores/oms8051mini ////
+//// ////
+//////////////////////////////////////////////////////////////////////
+//// ////
+//// Copyright (C) 2000 Authors and OPENCORES.ORG ////
+//// ////
+//// This source file may be used and distributed without ////
+//// restriction provided that this copyright statement is not ////
+//// removed from the file and that any derivative work contains ////
+//// the original copyright notice and the associated disclaimer. ////
+//// ////
+//// This source file is free software; you can redistribute it ////
+//// and/or modify it under the terms of the GNU Lesser General ////
+//// Public License as published by the Free Software Foundation; ////
+//// either version 2.1 of the License, or (at your option) any ////
+//// later version. ////
+//// ////
+//// This source is distributed in the hope that it will be ////
+//// useful, but WITHOUT ANY WARRANTY; without even the implied ////
+//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR ////
+//// PURPOSE. See the GNU Lesser General Public License for more ////
+//// details. ////
+//// ////
+//// You should have received a copy of the GNU Lesser General ////
+//// Public License along with this source; if not, download it ////
+//// from http://www.opencores.org/lgpl.shtml ////
+//// ////
+//////////////////////////////////////////////////////////////////////
+
+module uart_rxfsm (
+ reset_n ,
+ baud_clk_16x ,
+
+ cfg_rx_enable ,
+ cfg_stop_bit ,
+ cfg_pri_mod ,
+
+ error_ind ,
+
+ // FIFO control signal
+ fifo_aval ,
+ fifo_wr ,
+ fifo_data ,
+
+ // Line Interface
+ si
+ );
+
+
+input reset_n ; // active low reset signal
+input baud_clk_16x ; // baud clock-16x
+
+input cfg_rx_enable ; // transmit interface enable
+input cfg_stop_bit ; // stop bit
+ // 0 --> 1 stop, 1 --> 2 Stop
+input [1:0] cfg_pri_mod ;// Priority Mode
+ // 2'b00 --> None
+ // 2'b10 --> Even priority
+ // 2'b11 --> Odd priority
+
+output [1:0] error_ind ; // 2'b00 --> Normal
+ // 2'b01 --> framing error
+ // 2'b10 --> parity error
+ // 2'b11 --> fifo full
+//--------------------------------------
+// FIFO control signal
+//--------------------------------------
+input fifo_aval ; // fifo empty
+output fifo_wr ; // fifo write, assumed no back to back write
+output [7:0] fifo_data ; // fifo write data
+
+// Line Interface
+input si ; // rxd pin
+
+
+
+reg [7:0] fifo_data ; // fifo write data
+reg fifo_wr ; // fifo write
+reg [1:0] error_ind ;
+reg [2:0] cnt ;
+reg [3:0] offset ; // free-running counter from 0 - 15
+reg [3:0] rxpos ; // stable rx position
+reg [2:0] rxstate ;
+
+parameter idle_st = 3'b000;
+parameter xfr_start = 3'b001;
+parameter xfr_data_st = 3'b010;
+parameter xfr_pri_st = 3'b011;
+parameter xfr_stop_st1 = 3'b100;
+parameter xfr_stop_st2 = 3'b101;
+
+
+always @(negedge reset_n or posedge baud_clk_16x) begin
+ if(reset_n == 0) begin
+ rxstate <= 3'b0;
+ offset <= 4'b0;
+ rxpos <= 4'b0;
+ cnt <= 3'b0;
+ error_ind <= 2'b0;
+ fifo_wr <= 1'b0;
+ fifo_data <= 8'h0;
+ end
+ else begin
+ offset <= offset + 1;
+ case(rxstate)
+ idle_st : begin
+ if(!si) begin // Start indication
+ if(fifo_aval && cfg_rx_enable) begin
+ rxstate <= xfr_start;
+ cnt <= 0;
+ rxpos <= offset + 8; // Assign center rxoffset
+ error_ind <= 2'b00;
+ end
+ else begin
+ error_ind <= 2'b11; // fifo full error indication
+ end
+ end else begin
+ error_ind <= 2'b00; // Reset Error
+ end
+ end
+ xfr_start : begin
+ // Make Sure that minimum 8 cycle low is detected
+ if(cnt < 7 && si) begin // Start indication
+ rxstate <= idle_st;
+ end
+ else if(cnt == 7 && !si) begin // Start indication
+ rxstate <= xfr_data_st;
+ cnt <= 0;
+ end else begin
+ cnt <= cnt +1;
+ end
+ end
+ xfr_data_st : begin
+ if(rxpos == offset) begin
+ fifo_data[cnt] <= si;
+ cnt <= cnt+1;
+ if(cnt == 7) begin
+ fifo_wr <= 1;
+ if(cfg_pri_mod == 2'b00) // No Priority
+ rxstate <= xfr_stop_st1;
+ else rxstate <= xfr_pri_st;
+ end
+ end
+ end
+ xfr_pri_st : begin
+ fifo_wr <= 0;
+ if(rxpos == offset) begin
+ if(cfg_pri_mod == 2'b10) // even priority
+ if( si != ^fifo_data) error_ind <= 2'b10;
+ else // Odd Priority
+ if( si != ~(^fifo_data)) error_ind <= 2'b10;
+ rxstate <= xfr_stop_st1;
+ end
+ end
+ xfr_stop_st1 : begin
+ fifo_wr <= 0;
+ if(rxpos == offset) begin
+ if(si) begin
+ if(cfg_stop_bit) // Two Stop bit
+ rxstate <= xfr_stop_st2;
+ else
+ rxstate <= idle_st;
+ end else begin // Framing error
+ error_ind <= 2'b01;
+ rxstate <= idle_st;
+ end
+ end
+ end
+ xfr_stop_st2 : begin
+ if(rxpos == offset) begin
+ if(si) begin
+ rxstate <= idle_st;
+ end else begin // Framing error
+ error_ind <= 2'b01;
+ rxstate <= idle_st;
+ end
+ end
+ end
+ default: rxstate <= idle_st;
+ endcase
+ end
+end
+
+
+endmodule
diff --git a/verilog/rtl/uart/src/uart_txfsm.sv b/verilog/rtl/uart/src/uart_txfsm.sv
new file mode 100644
index 0000000..ad6507e
--- /dev/null
+++ b/verilog/rtl/uart/src/uart_txfsm.sv
@@ -0,0 +1,190 @@
+//////////////////////////////////////////////////////////////////////////////
+// SPDX-FileCopyrightText: 2021 , Dinesh Annayya
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+// SPDX-License-Identifier: Apache-2.0
+// SPDX-FileContributor: Created by Dinesh Annayya <dinesha@opencores.org>
+//
+//////////////////////////////////////////////////////////////////////
+//// ////
+//// UART TX FSM ////
+//// ////
+//// This file is part of the YIFive cores project ////
+//// https://github.com/dineshannayya/yifive_r0.git ////
+//// http://www.opencores.org/cores/yifive/ ////
+//// ////
+//// Description ////
+//// ////
+//// To Do: ////
+//// nothing ////
+//// ////
+//// Author(s): ////
+//// - Dinesh Annayya, dinesha@opencores.org ////
+//// ////
+//// Revision : ////
+//// 0.1 - 20th June 2021, Dinesh A ////
+//// 1. initial version picked from ////
+//// http://www.opencores.org/cores/oms8051mini ////
+//// ////
+//////////////////////////////////////////////////////////////////////
+//// ////
+//// Copyright (C) 2000 Authors and OPENCORES.ORG ////
+//// ////
+//// This source file may be used and distributed without ////
+//// restriction provided that this copyright statement is not ////
+//// removed from the file and that any derivative work contains ////
+//// the original copyright notice and the associated disclaimer. ////
+//// ////
+//// This source file is free software; you can redistribute it ////
+//// and/or modify it under the terms of the GNU Lesser General ////
+//// Public License as published by the Free Software Foundation; ////
+//// either version 2.1 of the License, or (at your option) any ////
+//// later version. ////
+//// ////
+//// This source is distributed in the hope that it will be ////
+//// useful, but WITHOUT ANY WARRANTY; without even the implied ////
+//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR ////
+//// PURPOSE. See the GNU Lesser General Public License for more ////
+//// details. ////
+//// ////
+//// You should have received a copy of the GNU Lesser General ////
+//// Public License along with this source; if not, download it ////
+//// from http://www.opencores.org/lgpl.shtml ////
+//// ////
+//////////////////////////////////////////////////////////////////////
+
+
+module uart_txfsm (
+ reset_n ,
+ baud_clk_16x ,
+
+ cfg_tx_enable ,
+ cfg_stop_bit ,
+ cfg_pri_mod ,
+
+ // FIFO control signal
+ fifo_empty ,
+ fifo_rd ,
+ fifo_data ,
+
+ // Line Interface
+ so
+ );
+
+
+input reset_n ; // active low reset signal
+input baud_clk_16x ; // baud clock-16x
+
+input cfg_tx_enable ; // transmit interface enable
+input cfg_stop_bit ; // stop bit
+ // 0 --> 1 stop, 1 --> 2 Stop
+input [1:0] cfg_pri_mod ;// Priority Mode
+ // 2'b00 --> None
+ // 2'b10 --> Even priority
+ // 2'b11 --> Odd priority
+
+//--------------------------------------
+// FIFO control signal
+//--------------------------------------
+input fifo_empty ; // fifo empty
+output fifo_rd ; // fifo read, assumed no back to back read
+input [7:0] fifo_data ; // fifo read data
+
+// Line Interface
+output so ; // txd pin
+
+
+reg [2:0] txstate ; // tx state
+reg so ; // txd pin
+reg [7:0] txdata ; // local txdata
+reg fifo_rd ; // Fifo read enable
+reg [2:0] cnt ; // local data cont
+reg [3:0] divcnt ; // clock div count
+
+parameter idle_st = 3'b000;
+parameter xfr_data_st = 3'b001;
+parameter xfr_pri_st = 3'b010;
+parameter xfr_stop_st1 = 3'b011;
+parameter xfr_stop_st2 = 3'b100;
+
+
+always @(negedge reset_n or posedge baud_clk_16x)
+begin
+ if(reset_n == 1'b0) begin
+ txstate <= idle_st;
+ so <= 1'b1;
+ cnt <= 3'b0;
+ txdata <= 8'h0;
+ fifo_rd <= 1'b0;
+ divcnt <= 4'b0;
+ end
+ else begin
+ divcnt <= divcnt+1;
+ if(divcnt == 4'b0000) begin // Do at once in 16 clock
+ case(txstate)
+ idle_st : begin
+ if(!fifo_empty && cfg_tx_enable) begin
+ so <= 1'b0 ; // Start bit
+ cnt <= 3'b0;
+ fifo_rd <= 1'b1;
+ txdata <= fifo_data;
+ txstate <= xfr_data_st;
+ end
+ end
+
+ xfr_data_st : begin
+ fifo_rd <= 1'b0;
+ so <= txdata[cnt];
+ cnt <= cnt+1;
+ if(cnt == 7) begin
+ if(cfg_pri_mod == 2'b00) begin // No Priority
+ txstate <= xfr_stop_st1;
+ end
+ else begin
+ txstate <= xfr_pri_st;
+ end
+ end
+ end
+
+ xfr_pri_st : begin
+ if(cfg_pri_mod == 2'b10) // even priority
+ so <= ^txdata;
+ else begin // Odd Priority
+ so <= ~(^txdata);
+ end
+ txstate <= xfr_stop_st1;
+ end
+
+ xfr_stop_st1 : begin // First Stop Bit
+ so <= 1;
+ if(cfg_stop_bit == 0) // 1 Stop Bit
+ txstate <= idle_st;
+ else // 2 Stop Bit
+ txstate <= xfr_stop_st2;
+ end
+
+ xfr_stop_st2 : begin // Second Stop Bit
+ so <= 1;
+ txstate <= idle_st;
+ end
+ default: txstate <= idle_st;
+ endcase
+ end
+ else begin
+ fifo_rd <= 1'b0;
+ end
+ end
+end
+
+
+endmodule
diff --git a/verilog/rtl/uart2wb/src/run_verilog b/verilog/rtl/uart2wb/src/run_verilog
new file mode 100644
index 0000000..c689827
--- /dev/null
+++ b/verilog/rtl/uart2wb/src/run_verilog
@@ -0,0 +1 @@
+iverilog uart2wb.sv uart2_core.sv uart_msg_handler.v ../../uart/src/uart_rxfsm.sv ../../uart/src/uart_txfsm.sv ../../lib/double_sync_low.v ../../lib/clk_ctl.v ../../lib/reset_sync.sv
diff --git a/verilog/rtl/uart2wb/src/uart2_core.sv b/verilog/rtl/uart2wb/src/uart2_core.sv
new file mode 100755
index 0000000..78daa1a
--- /dev/null
+++ b/verilog/rtl/uart2wb/src/uart2_core.sv
@@ -0,0 +1,192 @@
+//////////////////////////////////////////////////////////////////////////////
+// SPDX-FileCopyrightText: 2021 , Dinesh Annayya
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+// SPDX-License-Identifier: Apache-2.0
+// SPDX-FileContributor: Created by Dinesh Annayya <dinesha@opencores.org>
+//
+//////////////////////////////////////////////////////////////////////
+//// ////
+//// Tubo 8051 cores UART Interface Module ////
+//// ////
+//// This file is part of the Turbo 8051 cores project ////
+//// http://www.opencores.org/cores/turbo8051/ ////
+//// ////
+//// Description ////
+//// Turbo 8051 definitions. ////
+//// ////
+//// To Do: ////
+//// nothing ////
+//// ////
+//// Author(s): ////
+//// - Dinesh Annayya, dinesha@opencores.org ////
+//// ////
+//////////////////////////////////////////////////////////////////////
+//// ////
+//// Copyright (C) 2000 Authors and OPENCORES.ORG ////
+//// ////
+//// This source file may be used and distributed without ////
+//// restriction provided that this copyright statement is not ////
+//// removed from the file and that any derivative work contains ////
+//// the original copyright notice and the associated disclaimer. ////
+//// ////
+//// This source file is free software; you can redistribute it ////
+//// and/or modify it under the terms of the GNU Lesser General ////
+//// Public License as published by the Free Software Foundation; ////
+//// either version 2.1 of the License, or (at your option) any ////
+//// later version. ////
+//// ////
+//// This source is distributed in the hope that it will be ////
+//// useful, but WITHOUT ANY WARRANTY; without even the implied ////
+//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR ////
+//// PURPOSE. See the GNU Lesser General Public License for more ////
+//// details. ////
+//// ////
+//// You should have received a copy of the GNU Lesser General ////
+//// Public License along with this source; if not, download it ////
+//// from http://www.opencores.org/lgpl.shtml ////
+//// ////
+//////////////////////////////////////////////////////////////////////
+module uart2_core (
+ input wire arst_n , // Async reset
+ input wire app_clk , // Application clock
+
+
+ // configuration control
+ input wire cfg_tx_enable , // Enable Transmit Path
+ input wire cfg_rx_enable , // Enable Received Path
+ input wire cfg_stop_bit , // 0 -> 1 Start , 1 -> 2 Stop Bits
+ input wire [1:0] cfg_pri_mod , // priority mode, 0 -> nop, 1 -> Even, 2 -> Odd
+ input wire [11:0]cfg_baud_16x , // 16x baud rate control
+
+ // TX PATH Information
+ input wire tx_data_avail , // Indicate valid TXD Data
+ output wire tx_rd , // Indicate TXD Data Been Read
+ input wire [7:0]tx_data , // Indicate TXD Data Been
+
+
+ // RXD Information
+ input wire rx_ready , // Indicate Ready to accept the Read Data
+ output wire rx_wr , // Valid RXD Data
+ output wire [7:0]rx_data , // RXD Data
+
+ // Status information
+ output wire frm_error , // framing error
+ output wire par_error , // par error
+
+ output wire baud_clk_16x , // 16x Baud clock
+ output wire line_reset_n , // Reset sync to 16x Baud clock
+
+ // Line Interface
+ input wire rxd , // uart rxd
+ output wire txd // uart txd
+
+ );
+
+
+
+//---------------------------------
+// Global Dec
+// ---------------------------------
+
+// Wire Declaration
+
+wire [1 : 0] error_ind ;
+wire si_ss ;
+
+// OpenSource CTS tool does not work with buffer as source point
+// changed buf to max with select tied=0
+//ctech_clk_buf u_lineclk_buf (.A(line_clk_16x_in), .X(line_clk_16x));
+wire line_clk_16x;
+ctech_mux2x1 u_uart_clk (.A0(line_clk_16x), .A1(1'b0), .S(1'b0), .X(baud_clk_16x));
+
+// 16x Baud clock generation
+// Example: to generate 19200 Baud clock from 50Mhz Link clock
+// 50 * 1000 * 1000 / (2 + cfg_baud_16x) = 19200 * 16
+// cfg_baud_16x = 0xA0 (160)
+
+clk_ctl #(11) u_clk_ctl (
+ // Outputs
+ .clk_o (line_clk_16x),
+
+ // Inputs
+ .mclk (app_clk),
+ .reset_n (arst_n),
+ .clk_div_ratio (cfg_baud_16x)
+ );
+
+
+//###################################
+// Line Reset Synchronization
+//###################################
+reset_sync u_line_rst (
+ .scan_mode (1'b0 ),
+ .dclk (baud_clk_16x ), // Destination clock domain
+ .arst_n (arst_n ), // active low async reset
+ .srst_n (line_reset_n )
+ );
+
+
+
+uart_txfsm u_txfsm (
+ . reset_n ( line_reset_n ),
+ . baud_clk_16x ( baud_clk_16x ),
+
+ . cfg_tx_enable ( cfg_tx_enable ),
+ . cfg_stop_bit ( cfg_stop_bit ),
+ . cfg_pri_mod ( cfg_pri_mod ),
+
+ // FIFO control signal
+ . fifo_empty ( !tx_data_avail ),
+ . fifo_rd ( tx_rd ),
+ . fifo_data ( tx_data ),
+
+ // Line Interface
+ . so ( txd )
+ );
+
+
+uart_rxfsm u_rxfsm (
+ . reset_n ( line_reset_n ),
+ . baud_clk_16x ( baud_clk_16x ) ,
+
+ . cfg_rx_enable ( cfg_rx_enable ),
+ . cfg_stop_bit ( cfg_stop_bit ),
+ . cfg_pri_mod ( cfg_pri_mod ),
+
+ . error_ind ( error_ind ),
+
+ // FIFO control signal
+ . fifo_aval ( rx_ready ),
+ . fifo_wr ( rx_wr ),
+ . fifo_data ( rx_data ),
+
+ // Line Interface
+ . si (si_ss )
+ );
+
+// Double Sync RXD
+double_sync_low u_rxd_sync (
+ .in_data (rxd ),
+ .out_clk (baud_clk_16x ),
+ .out_rst_n (line_reset_n ),
+ .out_data (si_ss )
+ );
+
+
+assign frm_error = (error_ind == 2'b01);
+assign par_error = (error_ind == 2'b10);
+
+
+
+endmodule
diff --git a/verilog/rtl/uart2wb/src/uart2wb.sv b/verilog/rtl/uart2wb/src/uart2wb.sv
new file mode 100755
index 0000000..0bf50b3
--- /dev/null
+++ b/verilog/rtl/uart2wb/src/uart2wb.sv
@@ -0,0 +1,229 @@
+//////////////////////////////////////////////////////////////////////////////
+// SPDX-FileCopyrightText: 2021 , Dinesh Annayya
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+// SPDX-License-Identifier: Apache-2.0
+// SPDX-FileContributor: Created by Dinesh Annayya <dinesha@opencores.org>
+//
+//////////////////////////////////////////////////////////////////////
+//// ////
+//// UART2WB Top Module ////
+//// ////
+//// Description ////
+//// 1. uart_core ////
+//// 2. uart_msg_handler ////
+//// ////
+//// To Do: ////
+//// nothing ////
+//// ////
+//// Author(s): ////
+//// - Dinesh Annayya, dinesha@opencores.org ////
+//// ////
+//////////////////////////////////////////////////////////////////////
+//// ////
+//// Copyright (C) 2000 Authors and OPENCORES.ORG ////
+//// ////
+//// This source file may be used and distributed without ////
+//// restriction provided that this copyright statement is not ////
+//// removed from the file and that any derivative work contains ////
+//// the original copyright notice and the associated disclaimer. ////
+//// ////
+//// This source file is free software; you can redistribute it ////
+//// and/or modify it under the terms of the GNU Lesser General ////
+//// Public License as published by the Free Software Foundation; ////
+//// either version 2.1 of the License, or (at your option) any ////
+//// later version. ////
+//// ////
+//// This source is distributed in the hope that it will be ////
+//// useful, but WITHOUT ANY WARRANTY; without even the implied ////
+//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR ////
+//// PURPOSE. See the GNU Lesser General Public License for more ////
+//// details. ////
+//// ////
+//// You should have received a copy of the GNU Lesser General ////
+//// Public License along with this source; if not, download it ////
+//// from http://www.opencores.org/lgpl.shtml ////
+//// ////
+//////////////////////////////////////////////////////////////////////
+
+module uart2wb (
+ input wire arst_n , // sync reset
+ input wire app_clk , // sys clock
+
+ // configuration control
+ input wire cfg_tx_enable , // Enable Transmit Path
+ input wire cfg_rx_enable , // Enable Received Path
+ input wire cfg_stop_bit , // 0 -> 1 Start , 1 -> 2 Stop Bits
+ input wire [1:0] cfg_pri_mod , // priority mode, 0 -> nop, 1 -> Even, 2 -> Odd
+ input wire [11:0] cfg_baud_16x , // 16x Baud clock generation
+
+ // Master Port
+ output wire wbm_cyc_o , // strobe/request
+ output wire wbm_stb_o , // strobe/request
+ output wire [31:0] wbm_adr_o , // address
+ output wire wbm_we_o , // write
+ output wire [31:0] wbm_dat_o , // data output
+ output wire [3:0] wbm_sel_o , // byte enable
+ input wire [31:0] wbm_dat_i , // data input
+ input wire wbm_ack_i , // acknowlegement
+ input wire wbm_err_i , // error
+
+ // Status information
+ output wire frm_error , // framing error
+ output wire par_error , // par error
+
+ output wire baud_clk_16x , // 16x Baud clock
+
+ // Line Interface
+ input wire rxd , // uart rxd
+ output wire txd // uart txd
+
+ );
+
+
+
+
+
+
+//-------------------------------------
+//---------------------------------------
+// Control Unit interface
+// --------------------------------------
+
+wire [31:0] reg_addr ; // Register Address
+wire [31:0] reg_wdata ; // Register Wdata
+wire reg_req ; // Register Request
+wire reg_wr ; // 1 -> write; 0 -> read
+wire reg_ack ; // Register Ack
+wire [31:0] reg_rdata ;
+//--------------------------------------
+// TXD Path
+// -------------------------------------
+wire tx_data_avail ; // Indicate valid TXD Data
+wire [7:0] tx_data ; // TXD Data to be transmited
+wire tx_rd ; // Indicate TXD Data Been Read
+
+
+//--------------------------------------
+// RXD Path
+// -------------------------------------
+wire rx_ready ; // Indicate Ready to accept the Read Data
+wire [7:0] rx_data ; // RXD Data
+wire rx_wr ; // Valid RXD Data
+
+wire line_reset_n ;
+
+assign wbm_cyc_o = wbm_stb_o;
+
+
+// Async App clock to Uart clock handling
+
+async_reg_bus #(.AW(32), .DW(32),.BEW(4))
+ u_async_reg_bus (
+ // Initiator declartion
+ .in_clk (baud_clk_16x),
+ .in_reset_n (line_reset_n),
+ // Reg Bus Master
+ // outputs
+ .in_reg_rdata (reg_rdata),
+ .in_reg_ack (reg_ack),
+ .in_reg_timeout (),
+
+ // Inputs
+ .in_reg_cs (reg_req),
+ .in_reg_addr (reg_addr),
+ .in_reg_wdata (reg_wdata),
+ .in_reg_wr (reg_wr),
+ .in_reg_be (4'hF), // No byte enable based support
+
+ // Target Declaration
+ .out_clk (app_clk),
+ .out_reset_n (arst_n),
+ // Reg Bus Slave
+ // output
+ .out_reg_cs (wbm_stb_o),
+ .out_reg_addr (wbm_adr_o),
+ .out_reg_wdata (wbm_dat_o),
+ .out_reg_wr (wbm_we_o),
+ .out_reg_be (wbm_sel_o),
+
+ // Inputs
+ .out_reg_rdata (wbm_dat_i),
+ .out_reg_ack (wbm_ack_i)
+ );
+
+
+uart2_core u_core (
+ .arst_n (arst_n) ,
+ .app_clk (app_clk) ,
+
+ // configuration control
+ .cfg_tx_enable (cfg_tx_enable) ,
+ .cfg_rx_enable (cfg_rx_enable) ,
+ .cfg_stop_bit (cfg_stop_bit) ,
+ .cfg_pri_mod (cfg_pri_mod) ,
+ .cfg_baud_16x (cfg_baud_16x) ,
+
+ // TXD Information
+ .tx_data_avail (tx_data_avail) ,
+ .tx_rd (tx_rd) ,
+ .tx_data (tx_data) ,
+
+
+ // RXD Information
+ .rx_ready (rx_ready) ,
+ .rx_wr (rx_wr) ,
+ .rx_data (rx_data) ,
+
+ // Status information
+ .frm_error (frm_error) ,
+ .par_error (par_error) ,
+
+ .baud_clk_16x (baud_clk_16x) ,
+ .line_reset_n (line_reset_n),
+
+ // Line Interface
+ .rxd (rxd) ,
+ .txd (txd)
+
+ );
+
+
+
+uart_msg_handler u_msg (
+ .reset_n (arst_n ) ,
+ .sys_clk (baud_clk_16x ) ,
+
+
+ // UART-TX Information
+ .tx_data_avail (tx_data_avail) ,
+ .tx_rd (tx_rd) ,
+ .tx_data (tx_data) ,
+
+
+ // UART-RX Information
+ .rx_ready (rx_ready) ,
+ .rx_wr (rx_wr) ,
+ .rx_data (rx_data) ,
+
+ // Towards Control Unit
+ .reg_addr (reg_addr),
+ .reg_wr (reg_wr),
+ .reg_wdata (reg_wdata),
+ .reg_req (reg_req),
+ .reg_ack (reg_ack),
+ .reg_rdata (reg_rdata)
+
+ );
+
+endmodule
diff --git a/verilog/rtl/uart2wb/src/uart_msg_handler.v b/verilog/rtl/uart2wb/src/uart_msg_handler.v
new file mode 100755
index 0000000..471ff88
--- /dev/null
+++ b/verilog/rtl/uart2wb/src/uart_msg_handler.v
@@ -0,0 +1,376 @@
+//////////////////////////////////////////////////////////////////////
+//// ////
+//// UART Message Handler Module ////
+//// ////
+//// This file is part of the uart2spi cores project ////
+//// http://www.opencores.org/cores/uart2spi/ ////
+//// ////
+//// Description ////
+//// Uart Message Handler definitions. ////
+//// ////
+//// To Do: ////
+//// nothing ////
+//// ////
+//// Author(s): ////
+//// - Dinesh Annayya, dinesha@opencores.org ////
+//// ////
+//////////////////////////////////////////////////////////////////////
+//// ////
+//// Copyright (C) 2000 Authors and OPENCORES.ORG ////
+//// ////
+//// This source file may be used and distributed without ////
+//// restriction provided that this copyright statement is not ////
+//// removed from the file and that any derivative work contains ////
+//// the original copyright notice and the associated disclaimer. ////
+//// ////
+//// This source file is free software; you can redistribute it ////
+//// and/or modify it under the terms of the GNU Lesser General ////
+//// Public License as published by the Free Software Foundation; ////
+//// either version 2.1 of the License, or (at your option) any ////
+//// later version. ////
+//// ////
+//// This source is distributed in the hope that it will be ////
+//// useful, but WITHOUT ANY WARRANTY; without even the implied ////
+//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR ////
+//// PURPOSE. See the GNU Lesser General Public License for more ////
+//// details. ////
+//// ////
+//// You should have received a copy of the GNU Lesser General ////
+//// Public License along with this source; if not, download it ////
+//// from http://www.opencores.org/lgpl.shtml ////
+//// ////
+//////////////////////////////////////////////////////////////////////
+
+module uart_msg_handler (
+ reset_n ,
+ sys_clk ,
+
+
+ // UART-TX Information
+ tx_data_avail,
+ tx_rd,
+ tx_data,
+
+
+ // UART-RX Information
+ rx_ready,
+ rx_wr,
+ rx_data,
+
+ // Towards Register Interface
+ reg_addr,
+ reg_wr,
+ reg_wdata,
+ reg_req,
+ reg_ack,
+ reg_rdata
+
+ );
+
+
+// Define the Message Hanlde States
+`define IDLE 4'h0
+`define IDLE_TX_MSG1 4'h1
+`define IDLE_TX_MSG2 4'h2
+`define RX_CMD_PHASE 4'h3
+`define ADR_PHASE 4'h4
+`define WR_DATA_PHASE 4'h5
+`define SEND_WR_REQ 4'h6
+`define SEND_RD_REQ 4'h7
+`define SEND_RD_DATA 4'h8
+`define TX_MSG 4'h9
+
+`define BREAK_CHAR 8'h0A
+
+//---------------------------------
+// Global Dec
+// ---------------------------------
+
+input reset_n ; // line reset
+input sys_clk ; // line clock
+
+
+//--------------------------------------
+// UART TXD Path
+// -------------------------------------
+output tx_data_avail ; // Indicate valid TXD Data available
+output [7:0] tx_data ; // TXD Data to be transmited
+input tx_rd ; // Indicate TXD Data Been Read
+
+
+//--------------------------------------
+// UART RXD Path
+// -------------------------------------
+output rx_ready ; // Indicate Ready to accept the Read Data
+input [7:0] rx_data ; // RXD Data
+input rx_wr ; // Valid RXD Data
+
+//---------------------------------------
+// Control Unit interface
+// --------------------------------------
+
+output [31:0] reg_addr ; // Operend-1
+output [31:0] reg_wdata ; // Operend-2
+output reg_req ; // Register Request
+output reg_wr ; // 1 -> write; 0 -> read
+input reg_ack ; // Register Ack
+input [31:0] reg_rdata ;
+
+// Local Wire/Register Decleration
+//
+//
+reg tx_data_avail ;
+reg [7:0] tx_data ;
+reg [16*8-1:0] TxMsgBuf ; // 16 Byte Tx Message Buffer
+reg [4:0] TxMsgSize ;
+reg [4:0] RxMsgCnt ; // Count the Receive Message Count
+reg [3:0] State ;
+reg [3:0] NextState ;
+reg [15:0] cmd ; // command
+reg [31:0] reg_addr ; // reg_addr
+reg [31:0] reg_wdata ; // reg_addr
+reg reg_wr ; // 1 -> Reg Write request, 0 -> Read Requestion
+reg reg_req ; // 1 -> Register request
+
+
+wire rx_ready = 1;
+/****************************************************************
+* UART Message Hanlding Steps
+*
+* 1. On Reset Or Unknown command, Send the Default Message
+* Select Option:
+* wr <addr> <data>
+* rd <addr>
+* 2. Wait for User command <wr/rd>
+* 3. On <wr> command move to write address phase;
+* phase
+* A. After write address phase move to write data phase
+* B. After write data phase, once user press \r command ; send register req
+* and write request and address + data
+* C. On receiving register ack response; send <success> message back and move
+* to state-2
+* 3. On <rd> command move to read address phase;
+* A. After read address phase , once user press '\r' command; send
+* register req , read request
+* C. On receiving register ack response; send <response + read_data> message and move
+* to state-2
+* *****************************************************************/
+
+always @(negedge reset_n or posedge sys_clk)
+begin
+ if(reset_n == 1'b0) begin
+ tx_data_avail <= 0;
+ reg_req <= 0;
+ reg_addr <= 0;
+ reg_wr <= 1'b0; // Read request
+ reg_wdata <= 0;
+ State <= `IDLE;
+ NextState <= `IDLE;
+ end else begin
+ case(State)
+ // Send Default Message
+ `IDLE: begin
+ TxMsgBuf <= "Command Format:\n"; // Align to 16 character format by appending space character
+ TxMsgSize <= 16;
+ tx_data_avail <= 0;
+ State <= `TX_MSG;
+ NextState <= `IDLE_TX_MSG1;
+ end
+
+ // Send Default Message (Contd..)
+ `IDLE_TX_MSG1: begin
+ TxMsgBuf <= "wm <ad> <data>\n "; // Align to 16 character format by appending space character
+ TxMsgSize <= 15;
+ tx_data_avail <= 0;
+ State <= `TX_MSG;
+ NextState <= `IDLE_TX_MSG2;
+ end
+
+ // Send Default Message (Contd..)
+ `IDLE_TX_MSG2: begin
+ TxMsgBuf <= "rm <ad>\n>> "; // Align to 16 character format by appending space character
+ TxMsgSize <= 10;
+ tx_data_avail <= 0;
+ RxMsgCnt <= 0;
+ State <= `TX_MSG;
+ NextState <= `RX_CMD_PHASE;
+ end
+
+ // Wait for Response
+ `RX_CMD_PHASE: begin
+ if(rx_wr == 1) begin
+ //if(RxMsgCnt == 0 && rx_data == " ") begin // Ignore the same
+ if(RxMsgCnt == 0 && rx_data == 8'h20) begin // Ignore the same
+ //end else if(RxMsgCnt > 0 && rx_data == " ") begin // Check the command
+ end else if(RxMsgCnt > 0 && rx_data == 8'h20) begin // Check the command
+ reg_addr <= 0;
+ RxMsgCnt <= 0;
+ //if(cmd == "wm") begin
+ if(cmd == 16'h776D) begin
+ State <= `ADR_PHASE;
+ //end else if(cmd == "rm") begin
+ end else if(cmd == 16'h726D) begin
+
+ State <= `ADR_PHASE;
+ end else begin // Unknow command
+ State <= `IDLE;
+ end
+ //end else if(rx_data == "\n") begin // Error State
+ end else if(rx_data == `BREAK_CHAR) begin // Error State
+ State <= `IDLE;
+ end
+ else begin
+ cmd <= (cmd << 8) | rx_data ;
+ RxMsgCnt <= RxMsgCnt+1;
+ end
+ end
+ end
+ // Write Address Phase
+ `ADR_PHASE: begin
+ if(rx_wr == 1) begin
+ //if(RxMsgCnt == 0 && rx_data == " ") begin // Ignore the Space character
+ if(RxMsgCnt == 0 && rx_data == 8'h20) begin // Ignore the Space character
+ end else if(RxMsgCnt > 0 && (rx_data == 8'h20 || rx_data == `BREAK_CHAR)) begin // Move to write data phase
+ //if(RxMsgCnt > 0 && "wm" && rx_data == " ") begin // Move to write data phase
+ if(cmd == 16'h776D && rx_data == 8'h20) begin // Move to write data phase
+ reg_wdata <= 0;
+ State <= `WR_DATA_PHASE;
+ // end else if(RxMsgCnt > 0 && "rm" && rx_data == "\n") begin // Move to read data phase
+ end else if(cmd == 16'h726D && rx_data == `BREAK_CHAR) begin // Move to read data phase
+ reg_wr <= 1'b0; // Read request
+ reg_req <= 1'b1; // Reg Request
+ State <= `SEND_RD_REQ;
+ end else begin // Unknow command
+ State <= `IDLE;
+ end
+ //end else if(rx_data == "\n") begin // Error State
+ end else if(rx_data == `BREAK_CHAR) begin // Error State
+ State <= `IDLE;
+ end else begin
+ reg_addr <= (reg_addr << 4) | char2hex(rx_data);
+ RxMsgCnt <= RxMsgCnt+1;
+ end
+ end
+ end
+ // Write Data Phase
+ `WR_DATA_PHASE: begin
+ if(rx_wr == 1) begin
+ //if(rx_data == " ") begin // Ignore the Space character
+ if(rx_data == 8'h20) begin // Ignore the Space character
+ //end else if(rx_data == "\n") begin // Error State
+ end else if(rx_data == `BREAK_CHAR) begin // Error State
+ State <= `SEND_WR_REQ;
+ reg_wr <= 1'b1; // Write request
+ reg_req <= 1'b1;
+ end else begin // A to F
+ reg_wdata <= (reg_wdata << 4) | char2hex(rx_data);
+ end
+ end
+ end
+ `SEND_WR_REQ: begin
+ if(reg_ack) begin
+ reg_req <= 1'b0;
+ TxMsgBuf <= "cmd success\n>> "; // Align to 16 character format by appending space character
+ TxMsgSize <= 14;
+ tx_data_avail <= 0;
+ State <= `TX_MSG;
+ NextState <= `RX_CMD_PHASE;
+ end
+ end
+
+ `SEND_RD_REQ: begin
+ if(reg_ack) begin
+ reg_req <= 1'b0;
+ TxMsgBuf <= "Response: "; // Align to 16 character format by appending space character
+ TxMsgSize <= 10;
+ tx_data_avail <= 0;
+ State <= `TX_MSG;
+ NextState <= `SEND_RD_DATA;
+ end
+ end
+ `SEND_RD_DATA: begin // Wait for Operation Completion
+ TxMsgBuf[16*8-1:15*8] <= hex2char(reg_rdata[31:28]);
+ TxMsgBuf[15*8-1:14*8] <= hex2char(reg_rdata[27:24]);
+ TxMsgBuf[14*8-1:13*8] <= hex2char(reg_rdata[23:20]);
+ TxMsgBuf[13*8-1:12*8] <= hex2char(reg_rdata[19:16]);
+ TxMsgBuf[12*8-1:11*8] <= hex2char(reg_rdata[15:12]);
+ TxMsgBuf[11*8-1:10*8] <= hex2char(reg_rdata[11:8]);
+ TxMsgBuf[10*8-1:9*8] <= hex2char(reg_rdata[7:4]);
+ TxMsgBuf[9*8-1:8*8] <= hex2char(reg_rdata[3:0]);
+ TxMsgBuf[8*8-1:7*8] <= "\n";
+ TxMsgSize <= 9;
+ tx_data_avail <= 0;
+ State <= `TX_MSG;
+ NextState <= `RX_CMD_PHASE;
+ end
+
+ // Send Default Message (Contd..)
+ `TX_MSG: begin
+ tx_data_avail <= 1;
+ tx_data <= TxMsgBuf[16*8-1:15*8];
+ if(TxMsgSize == 0) begin
+ tx_data_avail <= 0;
+ State <= NextState;
+ end else if(tx_rd) begin
+ TxMsgBuf <= TxMsgBuf << 8;
+ TxMsgSize <= TxMsgSize -1;
+ end
+ end
+ endcase
+ end
+end
+
+
+// Character to hex number
+function [3:0] char2hex;
+input [7:0] data_in;
+case (data_in)
+ 8'h30: char2hex = 4'h0; // character '0'
+ 8'h31: char2hex = 4'h1; // character '1'
+ 8'h32: char2hex = 4'h2; // character '2'
+ 8'h33: char2hex = 4'h3; // character '3'
+ 8'h34: char2hex = 4'h4; // character '4'
+ 8'h35: char2hex = 4'h5; // character '5'
+ 8'h36: char2hex = 4'h6; // character '6'
+ 8'h37: char2hex = 4'h7; // character '7'
+ 8'h38: char2hex = 4'h8; // character '8'
+ 8'h39: char2hex = 4'h9; // character '9'
+ 8'h41: char2hex = 4'hA; // character 'A'
+ 8'h42: char2hex = 4'hB; // character 'B'
+ 8'h43: char2hex = 4'hC; // character 'C'
+ 8'h44: char2hex = 4'hD; // character 'D'
+ 8'h45: char2hex = 4'hE; // character 'E'
+ 8'h46: char2hex = 4'hF; // character 'F'
+ 8'h61: char2hex = 4'hA; // character 'a'
+ 8'h62: char2hex = 4'hB; // character 'b'
+ 8'h63: char2hex = 4'hC; // character 'c'
+ 8'h64: char2hex = 4'hD; // character 'd'
+ 8'h65: char2hex = 4'hE; // character 'e'
+ 8'h66: char2hex = 4'hF; // character 'f'
+ default : char2hex = 4'hF;
+ endcase
+endfunction
+
+// Hex to Asci Character
+function [7:0] hex2char;
+input [3:0] data_in;
+case (data_in)
+ 4'h0: hex2char = 8'h30; // character '0'
+ 4'h1: hex2char = 8'h31; // character '1'
+ 4'h2: hex2char = 8'h32; // character '2'
+ 4'h3: hex2char = 8'h33; // character '3'
+ 4'h4: hex2char = 8'h34; // character '4'
+ 4'h5: hex2char = 8'h35; // character '5'
+ 4'h6: hex2char = 8'h36; // character '6'
+ 4'h7: hex2char = 8'h37; // character '7'
+ 4'h8: hex2char = 8'h38; // character '8'
+ 4'h9: hex2char = 8'h39; // character '9'
+ 4'hA: hex2char = 8'h41; // character 'A'
+ 4'hB: hex2char = 8'h42; // character 'B'
+ 4'hC: hex2char = 8'h43; // character 'C'
+ 4'hD: hex2char = 8'h44; // character 'D'
+ 4'hE: hex2char = 8'h45; // character 'E'
+ 4'hF: hex2char = 8'h46; // character 'F'
+ endcase
+endfunction
+endmodule
diff --git a/verilog/rtl/uart_i2c/src/uart_i2c_top.sv b/verilog/rtl/uart_i2c/src/uart_i2c_top.sv
new file mode 100644
index 0000000..c0b68c5
--- /dev/null
+++ b/verilog/rtl/uart_i2c/src/uart_i2c_top.sv
@@ -0,0 +1,179 @@
+
+//////////////////////////////////////////////////////////////////////////////
+// SPDX-FileCopyrightText: 2021 , Dinesh Annayya
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+// SPDX-License-Identifier: Apache-2.0
+// SPDX-FileContributor: Created by Dinesh Annayya <dinesha@opencores.org>
+//
+//////////////////////////////////////////////////////////////////////
+//// ////
+//// UART CORE with TX/RX 16 Byte Buffer ////
+//// I2C Master ////
+//// ////
+//// This file is part of the YIFive cores project ////
+//// https://github.com/dineshannayya/yifive_r0.git ////
+//// ////
+//// Description: This module integarte Uart and I2C Master ////
+//// Both these block share common two pins, effectly only ////
+//// one block active at time. This is due to top-level pin ////
+//// restriction. ////
+//// ////
+//// To Do: ////
+//// nothing ////
+//// ////
+//// Author(s): ////
+//// - Dinesh Annayya, dinesha@opencores.org ////
+//// ////
+//// Revision : ////
+//// ////
+//////////////////////////////////////////////////////////////////////
+//// ////
+//// Copyright (C) 2000 Authors and OPENCORES.ORG ////
+//// ////
+//// This source file may be used and distributed without ////
+//// restriction provided that this copyright statement is not ////
+//// removed from the file and that any derivative work contains ////
+//// the original copyright notice and the associated disclaimer. ////
+//// ////
+//// This source file is free software; you can redistribute it ////
+//// and/or modify it under the terms of the GNU Lesser General ////
+//// Public License as published by the Free Software Foundation; ////
+//// either version 2.1 of the License, or (at your option) any ////
+//// later version. ////
+//// ////
+//// This source is distributed in the hope that it will be ////
+//// useful, but WITHOUT ANY WARRANTY; without even the implied ////
+//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR ////
+//// PURPOSE. See the GNU Lesser General Public License for more ////
+//// details. ////
+//// ////
+//// You should have received a copy of the GNU Lesser General ////
+//// Public License along with this source; if not, download it ////
+//// from http://www.opencores.org/lgpl.shtml ////
+//// ////
+//////////////////////////////////////////////////////////////////////
+
+module uart_i2c_top
+
+ (
+
+ input logic uart_rstn , // async reset
+ input logic i2c_rstn , // async reset
+ input logic app_clk ,
+ input logic uart_i2c_sel, // Uart Or I2C Interface Select
+
+ // Reg Bus Interface Signal
+ input logic reg_cs,
+ input logic reg_wr,
+ input logic [3:0] reg_addr,
+ input logic [7:0] reg_wdata,
+ input logic reg_be,
+
+ // Outputs
+ output logic [7:0] reg_rdata,
+ output logic reg_ack,
+
+ // Pad Control
+ input logic [1:0] io_in,
+ output logic [1:0] io_out,
+ output logic [1:0] io_oeb
+
+ );
+
+/////////////////////////////////////////////////////////
+// uart interface
+///////////////////////////////////////////////////////
+
+logic uart_rxd ;
+logic uart_txd ;
+/////////////////////////////////////////////////////////
+// i2c interface
+///////////////////////////////////////////////////////
+logic scl_pad_i ; // SCL-line input
+logic scl_pad_o ; // SCL-line output (always 1'b0)
+logic scl_pad_oen_o ; // SCL-line output enable (active low)
+
+logic sda_pad_i ; // SDA-line input
+logic sda_pad_o ; // SDA-line output (always 1'b0)
+logic sda_padoen_o ; // SDA-line output enable (active low)
+
+
+
+assign io_oeb[0] = (uart_i2c_sel == 0) ? 1'b1 : scl_pad_oen_o ; // Uart RX
+assign uart_rxd = (uart_i2c_sel == 0) ? io_in[0]: 1'b0;
+assign scl_pad_i = (uart_i2c_sel == 1) ? io_in[0]: 1'b0;
+assign io_out[0] = (uart_i2c_sel == 0) ? 1'b0 : scl_pad_o ;
+
+assign io_oeb[1] = (uart_i2c_sel == 0) ? 1'b0 : sda_padoen_o ; // Uart TX & I2C Clock
+assign io_out[1] = (uart_i2c_sel == 0) ? uart_txd: sda_pad_o ;
+assign sda_pad_i = (uart_i2c_sel == 1) ? io_in[1] : 1'b0;
+
+logic [7:0] reg_uart_rdata;
+logic [7:0] reg_i2c_rdata;
+logic reg_uart_ack;
+logic reg_i2c_ack;
+
+
+assign reg_rdata = (uart_i2c_sel == 0) ? reg_uart_rdata : reg_i2c_rdata;
+assign reg_ack = (uart_i2c_sel == 0) ? reg_uart_ack : reg_i2c_ack;
+
+uart_core u_uart_core (
+
+ .arst_n (uart_rstn ), // async reset
+ .app_clk (app_clk ),
+
+ // Reg Bus Interface Signal
+ .reg_cs (reg_cs ),
+ .reg_wr (reg_wr ),
+ .reg_addr (reg_addr[3:0] ),
+ .reg_wdata (reg_wdata[7:0] ),
+ .reg_be (reg_be ),
+
+ // Outputs
+ .reg_rdata (reg_uart_rdata[7:0]),
+ .reg_ack (reg_uart_ack ),
+
+ // Pad Control
+ .rxd (uart_rxd ),
+ .txd (uart_txd )
+ );
+
+i2cm_top u_i2cm (
+ // wishbone signals
+ .wb_clk_i (app_clk ), // master clock input
+ .sresetn (1'b1 ), // synchronous reset
+ .aresetn (i2c_rstn ), // asynchronous reset
+ .wb_adr_i (reg_addr[2:0] ), // lower address bits
+ .wb_dat_i (reg_wdata ), // databus input
+ .wb_dat_o (reg_i2c_rdata ), // databus output
+ .wb_we_i (reg_wr ), // write enable input
+ .wb_stb_i (reg_cs ), // stobe/core select signal
+ .wb_cyc_i (reg_cs ), // valid bus cycle input
+ .wb_ack_o (reg_i2c_ack ), // bus cycle acknowledge output
+ .wb_inta_o ( ), // interrupt request signal output
+
+ // I2C signals
+ // i2c clock line
+ .scl_pad_i (scl_pad_i ), // SCL-line input
+ .scl_pad_o (scl_pad_o ), // SCL-line output (always 1'b0)
+ .scl_padoen_o (scl_pad_oen_o ), // SCL-line output enable (active low)
+
+ // i2c data line
+ .sda_pad_i (sda_pad_i ), // SDA-line input
+ .sda_pad_o (sda_pad_o ), // SDA-line output (always 1'b0)
+ .sda_padoen_o (sda_padoen_o ) // SDA-line output enable (active low)
+
+ );
+
+endmodule
diff --git a/verilog/rtl/uart_i2c_usb/src/uart_i2c_usb.sv b/verilog/rtl/uart_i2c_usb/src/uart_i2c_usb.sv
new file mode 100644
index 0000000..f1e7af6
--- /dev/null
+++ b/verilog/rtl/uart_i2c_usb/src/uart_i2c_usb.sv
@@ -0,0 +1,218 @@
+
+//////////////////////////////////////////////////////////////////////////////
+// SPDX-FileCopyrightText: 2021 , Dinesh Annayya
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+// SPDX-License-Identifier: Apache-2.0
+// SPDX-FileContributor: Created by Dinesh Annayya <dinesha@opencores.org>
+//
+//////////////////////////////////////////////////////////////////////
+//// ////
+//// integrated UART/I2C Master & USB1.1 Host ////
+//// ////
+//// ////
+//// This file is part of the YIFive cores project ////
+//// https://github.com/dineshannayya/yifive_r0.git ////
+//// ////
+//// Description: This module integarte Uart and I2C Master ////
+//// and USB 1.1 Host. Both these block share common two pins, ////
+//// effectly only one block active at time. This is due to ////
+//// top-level pin restriction. ////
+//// ////
+//// Pin Maping UART I2C USB ////
+//// IO[1] - TXD SDA DP ////
+//// IO[0] - RXD SCL DN ////
+//// ////
+//// To Do: ////
+//// nothing ////
+//// ////
+//// Author(s): ////
+//// - Dinesh Annayya, dinesha@opencores.org ////
+//// ////
+//// Revision : ////
+//// ////
+//////////////////////////////////////////////////////////////////////
+//// ////
+//// Copyright (C) 2000 Authors and OPENCORES.ORG ////
+//// ////
+//// This source file may be used and distributed without ////
+//// restriction provided that this copyright statement is not ////
+//// removed from the file and that any derivative work contains ////
+//// the original copyright notice and the associated disclaimer. ////
+//// ////
+//// This source file is free software; you can redistribute it ////
+//// and/or modify it under the terms of the GNU Lesser General ////
+//// Public License as published by the Free Software Foundation; ////
+//// either version 2.1 of the License, or (at your option) any ////
+//// later version. ////
+//// ////
+//// This source is distributed in the hope that it will be ////
+//// useful, but WITHOUT ANY WARRANTY; without even the implied ////
+//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR ////
+//// PURPOSE. See the GNU Lesser General Public License for more ////
+//// details. ////
+//// ////
+//// You should have received a copy of the GNU Lesser General ////
+//// Public License along with this source; if not, download it ////
+//// from http://www.opencores.org/lgpl.shtml ////
+//// ////
+//////////////////////////////////////////////////////////////////////
+
+module uart_i2c_usb_top
+
+ (
+
+ input logic uart_rstn , // async reset
+ input logic i2c_rstn , // async reset
+ input logic usb_rstn , // async reset
+ input logic app_clk ,
+ input logic usb_clk , // 48Mhz usb clock
+
+ // Reg Bus Interface Signal
+ input logic reg_cs,
+ input logic reg_wr,
+ input logic [7:0] reg_addr,
+ input logic [31:0] reg_wdata,
+ input logic reg_be,
+
+ // Outputs
+ output logic [31:0] reg_rdata,
+ output logic reg_ack,
+ /////////////////////////////////////////////////////////
+ // i2c interface
+ ///////////////////////////////////////////////////////
+ input logic scl_pad_i , // SCL-line input
+ output logic scl_pad_o , // SCL-line output (always 1'b0)
+ output logic scl_pad_oen_o , // SCL-line output enable (active low)
+
+ input logic sda_pad_i , // SDA-line input
+ output logic sda_pad_o , // SDA-line output (always 1'b0)
+ output logic sda_padoen_o , // SDA-line output enable (active low)
+
+ // UART I/F
+ input logic uart_rxd ,
+ output logic uart_txd ,
+
+ input logic usb_in_dp ,
+ input logic usb_in_dn ,
+
+ output logic usb_out_dp ,
+ output logic usb_out_dn ,
+ output logic usb_out_tx_oen
+
+ );
+
+
+`define SEL_UART 2'b00
+`define SEL_I2C 2'b01
+`define SEL_USB 2'b10
+
+
+
+//----------------------------------------
+// Register Response Path Mux
+// --------------------------------------
+logic [7:0] reg_uart_rdata;
+logic [7:0] reg_i2c_rdata;
+logic [31:0] reg_usb_rdata;
+logic reg_uart_ack;
+logic reg_i2c_ack;
+logic reg_usb_ack;
+
+
+assign reg_rdata = (reg_addr[7:6] == `SEL_UART) ? {24'h0,reg_uart_rdata} :
+ (reg_addr[7:6] == `SEL_I2C) ? {24'h0,reg_i2c_rdata} : reg_usb_rdata;
+assign reg_ack = (reg_addr[7:6] == `SEL_UART) ? reg_uart_ack :
+ (reg_addr[7:6] == `SEL_I2C) ? reg_i2c_ack : reg_usb_ack;
+
+uart_core u_uart_core (
+
+ .arst_n (uart_rstn ), // async reset
+ .app_clk (app_clk ),
+
+ // Reg Bus Interface Signal
+ .reg_cs (reg_cs ),
+ .reg_wr (reg_wr ),
+ .reg_addr (reg_addr[5:2] ),
+ .reg_wdata (reg_wdata[7:0] ),
+ .reg_be (reg_be ),
+
+ // Outputs
+ .reg_rdata (reg_uart_rdata[7:0]),
+ .reg_ack (reg_uart_ack ),
+
+ // Pad Control
+ .rxd (uart_rxd ),
+ .txd (uart_txd )
+ );
+
+i2cm_top u_i2cm (
+ // wishbone signals
+ .wb_clk_i (app_clk ), // master clock input
+ .sresetn (i2c_rstn ), // synchronous reset
+ .aresetn (1'b1 ), // asynchronous reset
+ .wb_adr_i (reg_addr[4:2] ), // lower address bits
+ .wb_dat_i (reg_wdata[7:0] ), // databus input
+ .wb_dat_o (reg_i2c_rdata ), // databus output
+ .wb_we_i (reg_wr ), // write enable input
+ .wb_stb_i (reg_cs ), // stobe/core select signal
+ .wb_cyc_i (reg_cs ), // valid bus cycle input
+ .wb_ack_o (reg_i2c_ack ), // bus cycle acknowledge output
+ .wb_inta_o ( ), // interrupt request signal output
+
+ // I2C signals
+ // i2c clock line
+ .scl_pad_i (scl_pad_i ), // SCL-line input
+ .scl_pad_o (scl_pad_o ), // SCL-line output (always 1'b0)
+ .scl_padoen_o (scl_pad_oen_o ), // SCL-line output enable (active low)
+
+ // i2c data line
+ .sda_pad_i (sda_pad_i ), // SDA-line input
+ .sda_pad_o (sda_pad_o ), // SDA-line output (always 1'b0)
+ .sda_padoen_o (sda_padoen_o ) // SDA-line output enable (active low)
+
+ );
+
+
+usb1_host u_usb_host (
+ .usb_clk_i (usb_clk ),
+ .usb_rstn_i (usb_rstn ),
+
+ // USB D+/D-
+ .in_dp (usb_in_dp ),
+ .in_dn (usb_in_dn ),
+
+ .out_dp (usb_out_dp ),
+ .out_dn (usb_out_dn ),
+ .out_tx_oen (usb_out_tx_oen),
+
+ // Master Port
+ .wbm_rst_n (usb_rstn ), // Regular Reset signal
+ .wbm_clk_i (app_clk ), // System clock
+ .wbm_stb_i (reg_cs ), // strobe/request
+ .wbm_adr_i (reg_addr[5:0]), // address
+ .wbm_we_i (reg_wr ), // write
+ .wbm_dat_i (reg_wdata ), // data output
+ .wbm_sel_i (reg_be ), // byte enable
+ .wbm_dat_o (reg_usb_rdata ), // data input
+ .wbm_ack_o (reg_usb_ack ), // acknowlegement
+ .wbm_err_o ( ), // error
+
+ // Outputs
+ .usb_intr_o ( )
+
+
+ );
+
+
+endmodule
diff --git a/verilog/rtl/uart_i2c_usb_spi/src/uart_i2c_usb_spi.sv b/verilog/rtl/uart_i2c_usb_spi/src/uart_i2c_usb_spi.sv
new file mode 100644
index 0000000..d3378e0
--- /dev/null
+++ b/verilog/rtl/uart_i2c_usb_spi/src/uart_i2c_usb_spi.sv
@@ -0,0 +1,281 @@
+
+//////////////////////////////////////////////////////////////////////////////
+// SPDX-FileCopyrightText: 2021 , Dinesh Annayya
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+// SPDX-License-Identifier: Apache-2.0
+// SPDX-FileContributor: Created by Dinesh Annayya <dinesha@opencores.org>
+//
+//////////////////////////////////////////////////////////////////////
+//// ////
+//// integrated UART,I2C Master, SPU Master & USB1.1 Host ////
+//// ////
+//// ////
+//// This file is part of the riscduino cores project ////
+//// https://github.com/dineshannayya/riscduino.git ////
+//// ////
+//// Description: This module integarte Uart , I2C Master ////
+//// SPI Master and USB 1.1 Host. ////
+//// ////
+//// ////
+//// To Do: ////
+//// nothing ////
+//// ////
+//// Author(s): ////
+//// - Dinesh Annayya, dinesha@opencores.org ////
+//// ////
+//// Revision : ////
+//// ////
+//////////////////////////////////////////////////////////////////////
+//// ////
+//// Copyright (C) 2000 Authors and OPENCORES.ORG ////
+//// ////
+//// This source file may be used and distributed without ////
+//// restriction provided that this copyright statement is not ////
+//// removed from the file and that any derivative work contains ////
+//// the original copyright notice and the associated disclaimer. ////
+//// ////
+//// This source file is free software; you can redistribute it ////
+//// and/or modify it under the terms of the GNU Lesser General ////
+//// Public License as published by the Free Software Foundation; ////
+//// either version 2.1 of the License, or (at your option) any ////
+//// later version. ////
+//// ////
+//// This source is distributed in the hope that it will be ////
+//// useful, but WITHOUT ANY WARRANTY; without even the implied ////
+//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR ////
+//// PURPOSE. See the GNU Lesser General Public License for more ////
+//// details. ////
+//// ////
+//// You should have received a copy of the GNU Lesser General ////
+//// Public License along with this source; if not, download it ////
+//// from http://www.opencores.org/lgpl.shtml ////
+//// ////
+//////////////////////////////////////////////////////////////////////
+
+module uart_i2c_usb_spi_top
+
+ (
+`ifdef USE_POWER_PINS
+ input logic vccd1,// User area 1 1.8V supply
+ input logic vssd1,// User area 1 digital ground
+`endif
+ // clock skew adjust
+ input logic [3:0] cfg_cska_uart,
+ input logic wbd_clk_int,
+ output logic wbd_clk_uart,
+
+ input logic uart_rstn , // async reset
+ input logic i2c_rstn , // async reset
+ input logic usb_rstn , // async reset
+ input logic spi_rstn , // async reset
+ input logic app_clk ,
+ input logic usb_clk , // 48Mhz usb clock
+
+ // Reg Bus Interface Signal
+ input logic reg_cs,
+ input logic reg_wr,
+ input logic [7:0] reg_addr,
+ input logic [31:0] reg_wdata,
+ input logic [3:0] reg_be,
+
+ // Outputs
+ output logic [31:0] reg_rdata,
+ output logic reg_ack,
+ /////////////////////////////////////////////////////////
+ // i2c interface
+ ///////////////////////////////////////////////////////
+ input logic scl_pad_i , // SCL-line input
+ output logic scl_pad_o , // SCL-line output (always 1'b0)
+ output logic scl_pad_oen_o , // SCL-line output enable (active low)
+
+ input logic sda_pad_i , // SDA-line input
+ output logic sda_pad_o , // SDA-line output (always 1'b0)
+ output logic sda_padoen_o , // SDA-line output enable (active low)
+
+ output logic i2cm_intr_o ,
+
+ // UART I/F
+ input logic uart_rxd ,
+ output logic uart_txd ,
+
+ // USB 1.1 HOST I/F
+ input logic usb_in_dp ,
+ input logic usb_in_dn ,
+
+ output logic usb_out_dp ,
+ output logic usb_out_dn ,
+ output logic usb_out_tx_oen ,
+
+ output logic usb_intr_o ,
+
+ // SPIM I/F
+ output logic sspim_sck, // clock out
+ output logic sspim_so, // serial data out
+ input logic sspim_si, // serial data in
+ output logic sspim_ssn // cs_n
+
+ );
+
+// uart clock skew control
+clk_skew_adjust u_skew_uart
+ (
+`ifdef USE_POWER_PINS
+ .vccd1 (vccd1 ),// User area 1 1.8V supply
+ .vssd1 (vssd1 ),// User area 1 digital ground
+`endif
+ .clk_in (wbd_clk_int ),
+ .sel (cfg_cska_uart ),
+ .clk_out (wbd_clk_uart )
+ );
+
+`define SEL_UART 2'b00
+`define SEL_I2C 2'b01
+`define SEL_USB 2'b10
+`define SEL_SPI 2'b11
+
+
+
+//----------------------------------------
+// Register Response Path Mux
+// --------------------------------------
+logic [7:0] reg_uart_rdata;
+logic [7:0] reg_i2c_rdata;
+logic [31:0] reg_usb_rdata;
+logic [31:0] reg_spim_rdata;
+logic reg_uart_ack;
+logic reg_i2c_ack;
+logic reg_usb_ack;
+logic reg_spim_ack;
+
+
+assign reg_rdata = (reg_addr[7:6] == `SEL_UART) ? {24'h0,reg_uart_rdata} :
+ (reg_addr[7:6] == `SEL_I2C) ? {24'h0,reg_i2c_rdata} :
+ (reg_addr[7:6] == `SEL_USB) ? reg_usb_rdata : reg_spim_rdata;
+assign reg_ack = (reg_addr[7:6] == `SEL_UART) ? reg_uart_ack :
+ (reg_addr[7:6] == `SEL_I2C) ? reg_i2c_ack :
+ (reg_addr[7:6] == `SEL_USB) ? reg_usb_ack : reg_spim_ack;
+
+wire reg_uart_cs = (reg_addr[7:6] == `SEL_UART) ? reg_cs : 1'b0;
+wire reg_i2cm_cs = (reg_addr[7:6] == `SEL_I2C) ? reg_cs : 1'b0;
+wire reg_usb_cs = (reg_addr[7:6] == `SEL_UART) ? reg_cs : 1'b0;
+wire reg_spim_cs = (reg_addr[7:6] == `SEL_SPI) ? reg_cs : 1'b0;
+
+uart_core u_uart_core (
+
+ .arst_n (uart_rstn ), // async reset
+ .app_clk (app_clk ),
+
+ // Reg Bus Interface Signal
+ .reg_cs (reg_uart_cs ),
+ .reg_wr (reg_wr ),
+ .reg_addr (reg_addr[5:2] ),
+ .reg_wdata (reg_wdata[7:0] ),
+ .reg_be (reg_be[0] ),
+
+ // Outputs
+ .reg_rdata (reg_uart_rdata[7:0]),
+ .reg_ack (reg_uart_ack ),
+
+ // Pad Control
+ .rxd (uart_rxd ),
+ .txd (uart_txd )
+ );
+
+i2cm_top u_i2cm (
+ // wishbone signals
+ .wb_clk_i (app_clk ), // master clock input
+ .sresetn (1'b1 ), // synchronous reset
+ .aresetn (i2c_rstn ), // asynchronous reset
+ .wb_adr_i (reg_addr[4:2] ), // lower address bits
+ .wb_dat_i (reg_wdata[7:0] ), // databus input
+ .wb_dat_o (reg_i2c_rdata ), // databus output
+ .wb_we_i (reg_wr ), // write enable input
+ .wb_stb_i (reg_i2cm_cs ), // stobe/core select signal
+ .wb_cyc_i (reg_i2cm_cs ), // valid bus cycle input
+ .wb_ack_o (reg_i2c_ack ), // bus cycle acknowledge output
+ .wb_inta_o (i2cm_intr_o ), // interrupt request signal output
+
+ // I2C signals
+ // i2c clock line
+ .scl_pad_i (scl_pad_i ), // SCL-line input
+ .scl_pad_o (scl_pad_o ), // SCL-line output (always 1'b0)
+ .scl_padoen_o (scl_pad_oen_o ), // SCL-line output enable (active low)
+
+ // i2c data line
+ .sda_pad_i (sda_pad_i ), // SDA-line input
+ .sda_pad_o (sda_pad_o ), // SDA-line output (always 1'b0)
+ .sda_padoen_o (sda_padoen_o ) // SDA-line output enable (active low)
+
+ );
+
+
+usb1_host u_usb_host (
+ .usb_clk_i (usb_clk ),
+ .usb_rstn_i (usb_rstn ),
+
+ // USB D+/D-
+ .in_dp (usb_in_dp ),
+ .in_dn (usb_in_dn ),
+
+ .out_dp (usb_out_dp ),
+ .out_dn (usb_out_dn ),
+ .out_tx_oen (usb_out_tx_oen),
+
+ // Master Port
+ .wbm_rst_n (usb_rstn ), // Regular Reset signal
+ .wbm_clk_i (app_clk ), // System clock
+ .wbm_stb_i (reg_usb_cs ), // strobe/request
+ .wbm_adr_i (reg_addr[5:0]), // address
+ .wbm_we_i (reg_wr ), // write
+ .wbm_dat_i (reg_wdata ), // data output
+ .wbm_sel_i (reg_be ), // byte enable
+ .wbm_dat_o (reg_usb_rdata ), // data input
+ .wbm_ack_o (reg_usb_ack ), // acknowlegement
+ .wbm_err_o ( ), // error
+
+ // Outputs
+ .usb_intr_o ( usb_intr_o )
+
+ );
+
+sspim_top u_sspim (
+ .clk (app_clk ),
+ .reset_n (spi_rstn ),
+
+
+ //---------------------------------
+ // Reg Bus Interface Signal
+ //---------------------------------
+ .reg_cs (reg_spim_cs ),
+ .reg_wr (reg_wr ),
+ .reg_addr (reg_addr ),
+ .reg_wdata (reg_wdata ),
+ .reg_be (reg_be ),
+
+ // Outputs
+ .reg_rdata (reg_spim_rdata ),
+ .reg_ack (reg_spim_ack ),
+
+ //-------------------------------------------
+ // Line Interface
+ //-------------------------------------------
+
+ .sck (sspim_sck), // clock out
+ .so (sspim_so), // serial data out
+ .si (sspim_si), // serial data in
+ .ssn (sspim_ssn) // cs_n
+
+ );
+
+endmodule
diff --git a/verilog/rtl/uprj_netlists.v b/verilog/rtl/uprj_netlists.v
new file mode 100644
index 0000000..b81ad7e
--- /dev/null
+++ b/verilog/rtl/uprj_netlists.v
@@ -0,0 +1,183 @@
+// SPDX-FileCopyrightText: 2020 Efabless Corporation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+// SPDX-License-Identifier: Apache-2.0
+
+// Include caravel global defines for the number of the user project IO pads
+`include "defines.v"
+`define USE_POWER_PINS
+`define UNIT_DELAY #0.1
+
+`ifdef GL
+ `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 "libs.ref//sky130_fd_sc_hd/verilog/sky130_ef_sc_hd__fakediode_2.v"
+
+ `include "glbl_cfg.v"
+ `include "spi_master.v"
+ `include "uart_i2cm.v"
+ `include "wb_interconnect.v"
+ `include "user_project_wrapper.v"
+ `include "yifive.v"
+ `include "wb_host.v"
+ `include "clk_skew_adjust.v"
+ `include "clk_buf.v"
+
+`else
+ `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"sar_adc/SAR.sv"
+ `include"sar_adc/ACMP.sv"
+ `include"sar_adc/sar_adc.sv"
+ `include"sar_adc/adc_reg.sv"
+ `include"sar_adc/DAC_8BIT.v"
+
+
+ `include "sram_macros/sky130_sram_2kbyte_1rw1r_32x512_8.v"
+ `include "pinmux/src/pinmux.sv"
+ `include "pinmux/src/pinmux_reg.sv"
+ `include "pinmux/src/gpio_intr.sv"
+ `include "pinmux/src/pwm.sv"
+ `include "lib/pulse_gen_type1.sv"
+ `include "lib/pulse_gen_type2.sv"
+
+ `include "qspim/src/qspim_top.sv"
+ `include "qspim/src/qspim_if.sv"
+ `include "qspim/src/qspim_fifo.sv"
+ `include "qspim/src/qspim_regs.sv"
+ `include "qspim/src/qspim_clkgen.sv"
+ `include "qspim/src/qspim_ctrl.sv"
+ `include "qspim/src/qspim_rx.sv"
+ `include "qspim/src/qspim_tx.sv"
+
+ `include "uart/src/uart_core.sv"
+ `include "uart/src/uart_cfg.sv"
+ `include "uart/src/uart_rxfsm.sv"
+ `include "uart/src/uart_txfsm.sv"
+ `include "lib/async_fifo_th.sv"
+ `include "lib/reset_sync.sv"
+ `include "lib/double_sync_low.v"
+ `include "lib/clk_buf.v"
+
+ `include "i2cm/src/core/i2cm_bit_ctrl.v"
+ `include "i2cm/src/core/i2cm_byte_ctrl.v"
+ `include "i2cm/src/core/i2cm_top.v"
+
+ `include "usb1_host/src/core/usbh_core.sv"
+ `include "usb1_host/src/core/usbh_crc16.sv"
+ `include "usb1_host/src/core/usbh_crc5.sv"
+ `include "usb1_host/src/core/usbh_fifo.sv"
+ `include "usb1_host/src/core/usbh_sie.sv"
+ `include "usb1_host/src/phy/usb_fs_phy.v"
+ `include "usb1_host/src/phy/usb_transceiver.v"
+ `include "usb1_host/src/top/usb1_host.sv"
+
+ `include "sspim/src/sspim_top.sv"
+ `include "sspim/src/sspim_ctl.sv"
+ `include "sspim/src/sspim_if.sv"
+ `include "sspim/src/sspim_cfg.sv"
+
+
+ `include "uart_i2c_usb_spi/src/uart_i2c_usb_spi.sv"
+
+ `include "lib/async_fifo.sv"
+ `include "lib/registers.v"
+ `include "lib/clk_ctl.v"
+ `include "lib/ser_inf_32b.sv"
+ `include "lib/ser_shift.sv"
+ `include "digital_core/src/glbl_cfg.sv"
+
+ `include "wb_host/src/wb_host.sv"
+ `include "lib/async_wb.sv"
+
+ `include "lib/sync_wbb.sv"
+ `include "lib/sync_fifo2.sv"
+ `include "wb_interconnect/src/wb_arb.sv"
+ `include "wb_interconnect/src/wb_interconnect.sv"
+
+
+ `include "yifive/ycr1c/src/core/pipeline/ycr1_pipe_hdu.sv"
+ `include "yifive/ycr1c/src/core/pipeline/ycr1_pipe_tdu.sv"
+ `include "yifive/ycr1c/src/core/pipeline/ycr1_ipic.sv"
+ `include "yifive/ycr1c/src/core/pipeline/ycr1_pipe_csr.sv"
+ `include "yifive/ycr1c/src/core/pipeline/ycr1_pipe_exu.sv"
+ `include "yifive/ycr1c/src/core/pipeline/ycr1_pipe_ialu.sv"
+ `include "yifive/ycr1c/src/core/pipeline/ycr1_pipe_idu.sv"
+ `include "yifive/ycr1c/src/core/pipeline/ycr1_pipe_ifu.sv"
+ `include "yifive/ycr1c/src/core/pipeline/ycr1_pipe_lsu.sv"
+ `include "yifive/ycr1c/src/core/pipeline/ycr1_pipe_mprf.sv"
+ `include "yifive/ycr1c/src/core/pipeline/ycr1_pipe_mul.sv"
+ `include "yifive/ycr1c/src/core/pipeline/ycr1_pipe_div.sv"
+ `include "yifive/ycr1c/src/core/pipeline/ycr1_pipe_top.sv"
+ `include "yifive/ycr1c/src/core/primitives/ycr1_reset_cells.sv"
+ `include "yifive/ycr1c/src/core/primitives/ycr1_cg.sv"
+ `include "yifive/ycr1c/src/core/ycr1_clk_ctrl.sv"
+ `include "yifive/ycr1c/src/core/ycr1_tapc_shift_reg.sv"
+ `include "yifive/ycr1c/src/core/ycr1_tapc.sv"
+ `include "yifive/ycr1c/src/core/ycr1_tapc_synchronizer.sv"
+ `include "yifive/ycr1c/src/core/ycr1_core_top.sv"
+ `include "yifive/ycr1c/src/core/ycr1_dm.sv"
+ `include "yifive/ycr1c/src/core/ycr1_dmi.sv"
+ `include "yifive/ycr1c/src/core/ycr1_scu.sv"
+ `include "yifive/ycr1c/src/top/ycr1_imem_router.sv"
+ `include "yifive/ycr1c/src/top/ycr1_dmem_router.sv"
+ `include "yifive/ycr1c/src/top/ycr1_dp_memory.sv"
+ `include "yifive/ycr1c/src/top/ycr1_tcm.sv"
+ `include "yifive/ycr1c/src/top/ycr1_timer.sv"
+ `include "yifive/ycr1c/src/top/ycr1_dmem_wb.sv"
+ `include "yifive/ycr1c/src/top/ycr1_imem_wb.sv"
+ `include "yifive/ycr1c/src/top/ycr1_intf.sv"
+ `include "yifive/ycr1c/src/top/ycr1_top_wb.sv"
+ `include "yifive/ycr1c/src/top/ycr1_icache_router.sv"
+ `include "yifive/ycr1c/src/top/ycr1_dcache_router.sv"
+ `include "yifive/ycr1c/src/cache/src/core/icache_top.sv"
+ `include "yifive/ycr1c/src/cache/src/core/icache_app_fsm.sv"
+ `include "yifive/ycr1c/src/cache/src/core/icache_tag_fifo.sv"
+ `include "yifive/ycr1c/src/cache/src/core/dcache_tag_fifo.sv"
+ `include "yifive/ycr1c/src/cache/src/core/dcache_top.sv"
+ `include "yifive/ycr1c/src/lib/ycr1_async_wbb.sv"
+ `include "yifive/ycr1c/src/lib/ycr1_arb.sv"
+
+ `include "lib/sync_fifo.sv"
+
+ `include "mbist/src/core/mbist_addr_gen.sv"
+ `include "mbist/src/core/mbist_fsm.sv"
+ `include "mbist/src/core/mbist_op_sel.sv"
+ `include "mbist/src/core/mbist_repair_addr.sv"
+ `include "mbist/src/core/mbist_sti_sel.sv"
+ `include "mbist/src/core/mbist_pat_sel.sv"
+ `include "mbist/src/core/mbist_mux.sv"
+ `include "mbist/src/core/mbist_data_cmp.sv"
+ `include "mbist/src/core/mbist_mem_wrapper.sv"
+
+ `include "mbist/src/top/mbist_top.sv"
+ `include "mbist_wrapper/src/mbist_wb.sv"
+ `include "mbist_wrapper/src/mbist_wrapper.sv"
+
+
+ `include "uart2wb/src/uart2wb.sv"
+ `include "uart2wb/src/uart2_core.sv"
+ `include "uart2wb/src/uart_msg_handler.v"
+ `include "lib/async_reg_bus.sv"
+
+ `include "user_project_wrapper.v"
+ // we are using netlist file for clk_skew_adjust as it has
+ // standard cell + power pin
+ `include "clk_skew_adjust/src/clk_skew_adjust.v"
+ `include "lib/ctech_cells.sv"
+`endif
diff --git a/verilog/rtl/usb1_host/src/core/usbh_core.sv b/verilog/rtl/usb1_host/src/core/usbh_core.sv
new file mode 100644
index 0000000..adffecb
--- /dev/null
+++ b/verilog/rtl/usb1_host/src/core/usbh_core.sv
@@ -0,0 +1,1019 @@
+//////////////////////////////////////////////////////////////////////////////
+// SPDX-FileCopyrightText: 2021 , Dinesh Annayya
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+// SPDX-License-Identifier: Apache-2.0
+// SPDX-FileContributor: Created by Dinesh Annayya <dinesha@opencores.org>
+//
+//-----------------------------------------------------------------
+// USB Full Speed Host
+// V0.6
+// Ultra-Embedded.com
+// Copyright 2015-2020
+//
+// Email: admin@ultra-embedded.com
+//
+// License: GPL
+// If you would like a version with a more permissive license for
+// use in closed source commercial applications please contact me
+// for details.
+//-----------------------------------------------------------------
+//
+// This file is open source HDL; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License as
+// published by the Free Software Foundation; either version 2 of
+// the License, or (at your option) any later version.
+//
+// This file is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public
+// License along with this file; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+// USA
+//-----------------------------------------------------------------
+
+//-----------------------------------------------------------------
+// Generated File
+//-----------------------------------------------------------------
+
+`include "usbh_host_defs.v"
+
+//-----------------------------------------------------------------
+// Module: USB Host IP
+//-----------------------------------------------------------------
+module usbh_core
+//-----------------------------------------------------------------
+// Params
+//-----------------------------------------------------------------
+#(
+ parameter USB_CLK_FREQ = 48000000
+)
+//-----------------------------------------------------------------
+// Ports
+//-----------------------------------------------------------------
+(
+ // Inputs
+ input logic clk_i,
+ input logic rstn_i,
+
+ // Reg Bus Interface Signal
+ input logic reg_cs,
+ input logic reg_wr,
+ input logic [5:0] reg_addr,
+ input logic [31:0] reg_wdata,
+ input logic [3:0] reg_be,
+
+ // Outputs
+ output logic [31:0] reg_rdata,
+ output logic reg_ack,
+
+ // UTMI Input
+ input logic [7:0] utmi_data_in_i,
+ input logic utmi_txready_i,
+ input logic utmi_rxvalid_i,
+ input logic utmi_rxactive_i,
+ input logic utmi_rxerror_i,
+ input logic [1:0] utmi_linestate_i,
+
+ // UTMI Outputs
+ output logic intr_o,
+ output logic [7:0] utmi_data_out_o,
+ output logic utmi_txvalid_o,
+ output logic [1:0] utmi_op_mode_o,
+ output logic [1:0] utmi_xcvrselect_o,
+ output logic utmi_termselect_o,
+ output logic utmi_dppulldown_o,
+ output logic utmi_dmpulldown_o
+);
+
+
+reg [31:0] reg_rdata_r;
+wire [15:0] usb_status_sof_time_in_w;
+wire usb_status_rx_error_in_w;
+wire [1:0] usb_status_linestate_bits_in_w;
+wire usb_irq_sts_device_detect_in_w;
+wire usb_irq_sts_err_in_w;
+wire usb_irq_sts_done_in_w;
+wire usb_irq_sts_sof_in_w;
+wire usb_rx_stat_start_pend_in_w;
+wire usb_rx_stat_crc_err_in_w;
+wire usb_rx_stat_resp_timeout_in_w;
+wire usb_rx_stat_idle_in_w;
+wire [7:0] usb_rx_stat_resp_bits_in_w;
+wire [15:0] usb_rx_stat_count_bits_in_w;
+wire [7:0] usb_rd_data_data_in_w;
+
+//-----------------------------------------------------------------------
+// Read path mux
+//-----------------------------------------------------------------------
+
+logic cfg_wr;
+
+always @ (posedge clk_i or negedge rstn_i)
+begin : preg_out_Seq
+ if (rstn_i == 1'b0) begin
+ reg_rdata [31:0] <= 32'h0000_0000;
+ reg_ack <= 1'b0;
+ cfg_wr <= 1'b0;
+ end else if (reg_cs && (reg_wr == 0) && !reg_ack) begin
+ reg_rdata [31:0] <= reg_rdata_r [31:0];
+ reg_ack <= 1'b1;
+ end else if (reg_cs && (reg_wr == 1) && !reg_ack) begin
+ reg_ack <= 1'b1;
+ cfg_wr <= 1'b1;
+ end else begin
+ reg_ack <= 1'b0;
+ cfg_wr <= 1'b0;
+ end
+end
+
+
+//-----------------------------------------------------------------
+// Register usb_ctrl
+//-----------------------------------------------------------------
+reg usb_ctrl_wr_q;
+
+always @ (posedge clk_i or negedge rstn_i)
+if (!rstn_i)
+ usb_ctrl_wr_q <= 1'b0;
+else if (cfg_wr && (reg_addr[5:0] == `USB_CTRL))
+ usb_ctrl_wr_q <= 1'b1;
+else
+ usb_ctrl_wr_q <= 1'b0;
+
+// usb_ctrl_tx_flush [auto_clr]
+reg usb_ctrl_tx_flush_q;
+
+always @ (posedge clk_i or negedge rstn_i)
+if (!rstn_i)
+ usb_ctrl_tx_flush_q <= 1'd`USB_CTRL_TX_FLUSH_DEFAULT;
+else if (cfg_wr && (reg_addr[5:0] == `USB_CTRL))
+ usb_ctrl_tx_flush_q <= reg_wdata[`USB_CTRL_TX_FLUSH_R];
+else
+ usb_ctrl_tx_flush_q <= 1'd`USB_CTRL_TX_FLUSH_DEFAULT;
+
+wire usb_ctrl_tx_flush_out_w = usb_ctrl_tx_flush_q;
+
+
+// usb_ctrl_phy_dmpulldown [internal]
+reg usb_ctrl_phy_dmpulldown_q;
+
+always @ (posedge clk_i or negedge rstn_i)
+if (!rstn_i)
+ usb_ctrl_phy_dmpulldown_q <= 1'd`USB_CTRL_PHY_DMPULLDOWN_DEFAULT;
+else if (cfg_wr && (reg_addr[5:0] == `USB_CTRL))
+ usb_ctrl_phy_dmpulldown_q <= reg_wdata[`USB_CTRL_PHY_DMPULLDOWN_R];
+
+wire usb_ctrl_phy_dmpulldown_out_w = usb_ctrl_phy_dmpulldown_q;
+
+
+// usb_ctrl_phy_dppulldown [internal]
+reg usb_ctrl_phy_dppulldown_q;
+
+always @ (posedge clk_i or negedge rstn_i)
+if (!rstn_i)
+ usb_ctrl_phy_dppulldown_q <= 1'd`USB_CTRL_PHY_DPPULLDOWN_DEFAULT;
+else if (cfg_wr && (reg_addr[5:0] == `USB_CTRL))
+ usb_ctrl_phy_dppulldown_q <= reg_wdata[`USB_CTRL_PHY_DPPULLDOWN_R];
+
+wire usb_ctrl_phy_dppulldown_out_w = usb_ctrl_phy_dppulldown_q;
+
+
+// usb_ctrl_phy_termselect [internal]
+reg usb_ctrl_phy_termselect_q;
+
+always @ (posedge clk_i or negedge rstn_i)
+if (!rstn_i)
+ usb_ctrl_phy_termselect_q <= 1'd`USB_CTRL_PHY_TERMSELECT_DEFAULT;
+else if (cfg_wr && (reg_addr[5:0] == `USB_CTRL))
+ usb_ctrl_phy_termselect_q <= reg_wdata[`USB_CTRL_PHY_TERMSELECT_R];
+
+wire usb_ctrl_phy_termselect_out_w = usb_ctrl_phy_termselect_q;
+
+
+// usb_ctrl_phy_xcvrselect [internal]
+reg [1:0] usb_ctrl_phy_xcvrselect_q;
+
+always @ (posedge clk_i or negedge rstn_i)
+if (!rstn_i)
+ usb_ctrl_phy_xcvrselect_q <= 2'd`USB_CTRL_PHY_XCVRSELECT_DEFAULT;
+else if (cfg_wr && (reg_addr[5:0] == `USB_CTRL))
+ usb_ctrl_phy_xcvrselect_q <= reg_wdata[`USB_CTRL_PHY_XCVRSELECT_R];
+
+wire [1:0] usb_ctrl_phy_xcvrselect_out_w = usb_ctrl_phy_xcvrselect_q;
+
+
+// usb_ctrl_phy_opmode [internal]
+reg [1:0] usb_ctrl_phy_opmode_q;
+
+always @ (posedge clk_i or negedge rstn_i)
+if (!rstn_i)
+ usb_ctrl_phy_opmode_q <= 2'd`USB_CTRL_PHY_OPMODE_DEFAULT;
+else if (cfg_wr && (reg_addr[5:0] == `USB_CTRL))
+ usb_ctrl_phy_opmode_q <= reg_wdata[`USB_CTRL_PHY_OPMODE_R];
+
+wire [1:0] usb_ctrl_phy_opmode_out_w = usb_ctrl_phy_opmode_q;
+
+
+// usb_ctrl_enable_sof [internal]
+reg usb_ctrl_enable_sof_q;
+
+always @ (posedge clk_i or negedge rstn_i)
+if (!rstn_i)
+ usb_ctrl_enable_sof_q <= 1'd`USB_CTRL_ENABLE_SOF_DEFAULT;
+else if (cfg_wr && (reg_addr[5:0] == `USB_CTRL))
+ usb_ctrl_enable_sof_q <= reg_wdata[`USB_CTRL_ENABLE_SOF_R];
+
+wire usb_ctrl_enable_sof_out_w = usb_ctrl_enable_sof_q;
+
+
+//-----------------------------------------------------------------
+// Register usb_status
+//-----------------------------------------------------------------
+reg usb_status_wr_q;
+
+always @ (posedge clk_i or negedge rstn_i)
+if (!rstn_i)
+ usb_status_wr_q <= 1'b0;
+else if (cfg_wr && (reg_addr[5:0] == `USB_STATUS))
+ usb_status_wr_q <= 1'b1;
+else
+ usb_status_wr_q <= 1'b0;
+
+
+
+
+//-----------------------------------------------------------------
+// Register usb_irq_ack
+//-----------------------------------------------------------------
+reg usb_irq_ack_wr_q;
+
+always @ (posedge clk_i or negedge rstn_i)
+if (!rstn_i)
+ usb_irq_ack_wr_q <= 1'b0;
+else if (cfg_wr && (reg_addr[5:0] == `USB_IRQ_ACK))
+ usb_irq_ack_wr_q <= 1'b1;
+else
+ usb_irq_ack_wr_q <= 1'b0;
+
+// usb_irq_ack_device_detect [auto_clr]
+reg usb_irq_ack_device_detect_q;
+
+always @ (posedge clk_i or negedge rstn_i)
+if (!rstn_i)
+ usb_irq_ack_device_detect_q <= 1'd`USB_IRQ_ACK_DEVICE_DETECT_DEFAULT;
+else if (cfg_wr && (reg_addr[5:0] == `USB_IRQ_ACK))
+ usb_irq_ack_device_detect_q <= reg_wdata[`USB_IRQ_ACK_DEVICE_DETECT_R];
+else
+ usb_irq_ack_device_detect_q <= 1'd`USB_IRQ_ACK_DEVICE_DETECT_DEFAULT;
+
+wire usb_irq_ack_device_detect_out_w = usb_irq_ack_device_detect_q;
+
+
+// usb_irq_ack_err [auto_clr]
+reg usb_irq_ack_err_q;
+
+always @ (posedge clk_i or negedge rstn_i)
+if (!rstn_i)
+ usb_irq_ack_err_q <= 1'd`USB_IRQ_ACK_ERR_DEFAULT;
+else if (cfg_wr && (reg_addr[5:0] == `USB_IRQ_ACK))
+ usb_irq_ack_err_q <= reg_wdata[`USB_IRQ_ACK_ERR_R];
+else
+ usb_irq_ack_err_q <= 1'd`USB_IRQ_ACK_ERR_DEFAULT;
+
+wire usb_irq_ack_err_out_w = usb_irq_ack_err_q;
+
+
+// usb_irq_ack_done [auto_clr]
+reg usb_irq_ack_done_q;
+
+always @ (posedge clk_i or negedge rstn_i)
+if (!rstn_i)
+ usb_irq_ack_done_q <= 1'd`USB_IRQ_ACK_DONE_DEFAULT;
+else if (cfg_wr && (reg_addr[5:0] == `USB_IRQ_ACK))
+ usb_irq_ack_done_q <= reg_wdata[`USB_IRQ_ACK_DONE_R];
+else
+ usb_irq_ack_done_q <= 1'd`USB_IRQ_ACK_DONE_DEFAULT;
+
+wire usb_irq_ack_done_out_w = usb_irq_ack_done_q;
+
+
+// usb_irq_ack_sof [auto_clr]
+reg usb_irq_ack_sof_q;
+
+always @ (posedge clk_i or negedge rstn_i)
+if (!rstn_i)
+ usb_irq_ack_sof_q <= 1'd`USB_IRQ_ACK_SOF_DEFAULT;
+else if (cfg_wr && (reg_addr[5:0] == `USB_IRQ_ACK))
+ usb_irq_ack_sof_q <= reg_wdata[`USB_IRQ_ACK_SOF_R];
+else
+ usb_irq_ack_sof_q <= 1'd`USB_IRQ_ACK_SOF_DEFAULT;
+
+wire usb_irq_ack_sof_out_w = usb_irq_ack_sof_q;
+
+
+//-----------------------------------------------------------------
+// Register usb_irq_sts
+//-----------------------------------------------------------------
+reg usb_irq_sts_wr_q;
+
+always @ (posedge clk_i or negedge rstn_i)
+if (!rstn_i)
+ usb_irq_sts_wr_q <= 1'b0;
+else if (cfg_wr && (reg_addr[5:0] == `USB_IRQ_STS))
+ usb_irq_sts_wr_q <= 1'b1;
+else
+ usb_irq_sts_wr_q <= 1'b0;
+
+
+
+
+
+//-----------------------------------------------------------------
+// Register usb_irq_mask
+//-----------------------------------------------------------------
+reg usb_irq_mask_wr_q;
+
+always @ (posedge clk_i or negedge rstn_i)
+if (!rstn_i)
+ usb_irq_mask_wr_q <= 1'b0;
+else if (cfg_wr && (reg_addr[5:0] == `USB_IRQ_MASK))
+ usb_irq_mask_wr_q <= 1'b1;
+else
+ usb_irq_mask_wr_q <= 1'b0;
+
+// usb_irq_mask_device_detect [internal]
+reg usb_irq_mask_device_detect_q;
+
+always @ (posedge clk_i or negedge rstn_i)
+if (!rstn_i)
+ usb_irq_mask_device_detect_q <= 1'd`USB_IRQ_MASK_DEVICE_DETECT_DEFAULT;
+else if (cfg_wr && (reg_addr[5:0] == `USB_IRQ_MASK))
+ usb_irq_mask_device_detect_q <= reg_wdata[`USB_IRQ_MASK_DEVICE_DETECT_R];
+
+wire usb_irq_mask_device_detect_out_w = usb_irq_mask_device_detect_q;
+
+
+// usb_irq_mask_err [internal]
+reg usb_irq_mask_err_q;
+
+always @ (posedge clk_i or negedge rstn_i)
+if (!rstn_i)
+ usb_irq_mask_err_q <= 1'd`USB_IRQ_MASK_ERR_DEFAULT;
+else if (cfg_wr && (reg_addr[5:0] == `USB_IRQ_MASK))
+ usb_irq_mask_err_q <= reg_wdata[`USB_IRQ_MASK_ERR_R];
+
+wire usb_irq_mask_err_out_w = usb_irq_mask_err_q;
+
+
+// usb_irq_mask_done [internal]
+reg usb_irq_mask_done_q;
+
+always @ (posedge clk_i or negedge rstn_i)
+if (!rstn_i)
+ usb_irq_mask_done_q <= 1'd`USB_IRQ_MASK_DONE_DEFAULT;
+else if (cfg_wr && (reg_addr[5:0] == `USB_IRQ_MASK))
+ usb_irq_mask_done_q <= reg_wdata[`USB_IRQ_MASK_DONE_R];
+
+wire usb_irq_mask_done_out_w = usb_irq_mask_done_q;
+
+
+// usb_irq_mask_sof [internal]
+reg usb_irq_mask_sof_q;
+
+always @ (posedge clk_i or negedge rstn_i)
+if (!rstn_i)
+ usb_irq_mask_sof_q <= 1'd`USB_IRQ_MASK_SOF_DEFAULT;
+else if (cfg_wr && (reg_addr[5:0] == `USB_IRQ_MASK))
+ usb_irq_mask_sof_q <= reg_wdata[`USB_IRQ_MASK_SOF_R];
+
+wire usb_irq_mask_sof_out_w = usb_irq_mask_sof_q;
+
+
+//-----------------------------------------------------------------
+// Register usb_xfer_data
+//-----------------------------------------------------------------
+reg usb_xfer_data_wr_q;
+
+always @ (posedge clk_i or negedge rstn_i)
+if (!rstn_i)
+ usb_xfer_data_wr_q <= 1'b0;
+else if (cfg_wr && (reg_addr[5:0] == `USB_XFER_DATA))
+ usb_xfer_data_wr_q <= 1'b1;
+else
+ usb_xfer_data_wr_q <= 1'b0;
+
+// usb_xfer_data_tx_len [internal]
+reg [15:0] usb_xfer_data_tx_len_q;
+
+always @ (posedge clk_i or negedge rstn_i)
+if (!rstn_i)
+ usb_xfer_data_tx_len_q <= 16'd`USB_XFER_DATA_TX_LEN_DEFAULT;
+else if (cfg_wr && (reg_addr[5:0] == `USB_XFER_DATA))
+ usb_xfer_data_tx_len_q <= reg_wdata[`USB_XFER_DATA_TX_LEN_R];
+
+wire [15:0] usb_xfer_data_tx_len_out_w = usb_xfer_data_tx_len_q;
+
+
+//-----------------------------------------------------------------
+// Register usb_xfer_token
+//-----------------------------------------------------------------
+reg usb_xfer_token_wr_q;
+
+always @ (posedge clk_i or negedge rstn_i)
+if (!rstn_i)
+ usb_xfer_token_wr_q <= 1'b0;
+else if (cfg_wr && (reg_addr[5:0] == `USB_XFER_TOKEN))
+ usb_xfer_token_wr_q <= 1'b1;
+else
+ usb_xfer_token_wr_q <= 1'b0;
+
+// usb_xfer_token_start [clearable]
+reg usb_xfer_token_start_q;
+
+wire usb_xfer_token_start_ack_in_w;
+
+always @ (posedge clk_i or negedge rstn_i)
+if (!rstn_i)
+ usb_xfer_token_start_q <= 1'b0;
+else if (cfg_wr && (reg_addr[5:0] == `USB_XFER_TOKEN))
+ usb_xfer_token_start_q <= reg_wdata[`USB_XFER_TOKEN_START_R];
+else if (usb_xfer_token_start_ack_in_w)
+ usb_xfer_token_start_q <= 1'b0;
+
+wire usb_xfer_token_start_out_w = usb_xfer_token_start_q;
+
+
+// usb_xfer_token_in [internal]
+reg usb_xfer_token_in_q;
+
+always @ (posedge clk_i or negedge rstn_i)
+if (!rstn_i)
+ usb_xfer_token_in_q <= 1'd`USB_XFER_TOKEN_IN_DEFAULT;
+else if (cfg_wr && (reg_addr[5:0] == `USB_XFER_TOKEN))
+ usb_xfer_token_in_q <= reg_wdata[`USB_XFER_TOKEN_IN_R];
+
+wire usb_xfer_token_in_out_w = usb_xfer_token_in_q;
+
+
+// usb_xfer_token_ack [internal]
+reg usb_xfer_token_ack_q;
+
+always @ (posedge clk_i or negedge rstn_i)
+if (!rstn_i)
+ usb_xfer_token_ack_q <= 1'd`USB_XFER_TOKEN_ACK_DEFAULT;
+else if (cfg_wr && (reg_addr[5:0] == `USB_XFER_TOKEN))
+ usb_xfer_token_ack_q <= reg_wdata[`USB_XFER_TOKEN_ACK_R];
+
+wire usb_xfer_token_ack_out_w = usb_xfer_token_ack_q;
+
+
+// usb_xfer_token_pid_datax [internal]
+reg usb_xfer_token_pid_datax_q;
+
+always @ (posedge clk_i or negedge rstn_i)
+if (!rstn_i)
+ usb_xfer_token_pid_datax_q <= 1'd`USB_XFER_TOKEN_PID_DATAX_DEFAULT;
+else if (cfg_wr && (reg_addr[5:0] == `USB_XFER_TOKEN))
+ usb_xfer_token_pid_datax_q <= reg_wdata[`USB_XFER_TOKEN_PID_DATAX_R];
+
+wire usb_xfer_token_pid_datax_out_w = usb_xfer_token_pid_datax_q;
+
+
+// usb_xfer_token_pid_bits [internal]
+reg [7:0] usb_xfer_token_pid_bits_q;
+
+always @ (posedge clk_i or negedge rstn_i)
+if (!rstn_i)
+ usb_xfer_token_pid_bits_q <= 8'd`USB_XFER_TOKEN_PID_BITS_DEFAULT;
+else if (cfg_wr && (reg_addr[5:0] == `USB_XFER_TOKEN))
+ usb_xfer_token_pid_bits_q <= reg_wdata[`USB_XFER_TOKEN_PID_BITS_R];
+
+wire [7:0] usb_xfer_token_pid_bits_out_w = usb_xfer_token_pid_bits_q;
+
+
+// usb_xfer_token_dev_addr [internal]
+reg [6:0] usb_xfer_token_dev_addr_q;
+
+always @ (posedge clk_i or negedge rstn_i)
+if (!rstn_i)
+ usb_xfer_token_dev_addr_q <= 7'd`USB_XFER_TOKEN_DEV_ADDR_DEFAULT;
+else if (cfg_wr && (reg_addr[5:0] == `USB_XFER_TOKEN))
+ usb_xfer_token_dev_addr_q <= reg_wdata[`USB_XFER_TOKEN_DEV_ADDR_R];
+
+wire [6:0] usb_xfer_token_dev_addr_out_w = usb_xfer_token_dev_addr_q;
+
+
+// usb_xfer_token_ep_addr [internal]
+reg [3:0] usb_xfer_token_ep_addr_q;
+
+always @ (posedge clk_i or negedge rstn_i)
+if (!rstn_i)
+ usb_xfer_token_ep_addr_q <= 4'd`USB_XFER_TOKEN_EP_ADDR_DEFAULT;
+else if (cfg_wr && (reg_addr[5:0] == `USB_XFER_TOKEN))
+ usb_xfer_token_ep_addr_q <= reg_wdata[`USB_XFER_TOKEN_EP_ADDR_R];
+
+wire [3:0] usb_xfer_token_ep_addr_out_w = usb_xfer_token_ep_addr_q;
+
+
+//-----------------------------------------------------------------
+// Register usb_rx_stat
+//-----------------------------------------------------------------
+reg usb_rx_stat_wr_q;
+
+always @ (posedge clk_i or negedge rstn_i)
+if (!rstn_i)
+ usb_rx_stat_wr_q <= 1'b0;
+else if (cfg_wr && (reg_addr[5:0] == `USB_RX_STAT))
+ usb_rx_stat_wr_q <= 1'b1;
+else
+ usb_rx_stat_wr_q <= 1'b0;
+
+
+
+//-----------------------------------------------------------------
+// Retime write data
+//-----------------------------------------------------------------
+reg [31:0] wr_data_q;
+
+always @ (posedge clk_i or negedge rstn_i)
+if (!rstn_i)
+ wr_data_q <= 32'b0;
+else if (cfg_wr)
+ wr_data_q <= reg_wdata;
+
+
+
+
+//-----------------------------------------------------------------
+// Register usb_wr_data
+//-----------------------------------------------------------------
+reg usb_wr_data_wr_q;
+
+always @ (posedge clk_i or negedge rstn_i)
+if (!rstn_i)
+ usb_wr_data_wr_q <= 1'b0;
+else if (cfg_wr && (reg_addr[5:0] == `USB_WR_DATA))
+ usb_wr_data_wr_q <= 1'b1;
+else
+ usb_wr_data_wr_q <= 1'b0;
+
+// usb_wr_data_data [external]
+wire [7:0] usb_wr_data_data_out_w = wr_data_q[`USB_WR_DATA_DATA_R];
+
+//-----------------------------------------------------------------
+// Read mux
+//-----------------------------------------------------------------
+
+always @ *
+begin
+ reg_rdata_r = 32'b0;
+
+ case (reg_addr[5:0])
+
+ `USB_CTRL:
+ begin
+ reg_rdata_r[`USB_CTRL_PHY_DMPULLDOWN_R] = usb_ctrl_phy_dmpulldown_q;
+ reg_rdata_r[`USB_CTRL_PHY_DPPULLDOWN_R] = usb_ctrl_phy_dppulldown_q;
+ reg_rdata_r[`USB_CTRL_PHY_TERMSELECT_R] = usb_ctrl_phy_termselect_q;
+ reg_rdata_r[`USB_CTRL_PHY_XCVRSELECT_R] = usb_ctrl_phy_xcvrselect_q;
+ reg_rdata_r[`USB_CTRL_PHY_OPMODE_R] = usb_ctrl_phy_opmode_q;
+ reg_rdata_r[`USB_CTRL_ENABLE_SOF_R] = usb_ctrl_enable_sof_q;
+ end
+ `USB_STATUS:
+ begin
+ reg_rdata_r[`USB_STATUS_SOF_TIME_R] = usb_status_sof_time_in_w;
+ reg_rdata_r[`USB_STATUS_RX_ERROR_R] = usb_status_rx_error_in_w;
+ reg_rdata_r[`USB_STATUS_LINESTATE_BITS_R] = usb_status_linestate_bits_in_w;
+ end
+ `USB_IRQ_STS:
+ begin
+ reg_rdata_r[`USB_IRQ_STS_DEVICE_DETECT_R] = usb_irq_sts_device_detect_in_w;
+ reg_rdata_r[`USB_IRQ_STS_ERR_R] = usb_irq_sts_err_in_w;
+ reg_rdata_r[`USB_IRQ_STS_DONE_R] = usb_irq_sts_done_in_w;
+ reg_rdata_r[`USB_IRQ_STS_SOF_R] = usb_irq_sts_sof_in_w;
+ end
+ `USB_IRQ_MASK:
+ begin
+ reg_rdata_r[`USB_IRQ_MASK_DEVICE_DETECT_R] = usb_irq_mask_device_detect_q;
+ reg_rdata_r[`USB_IRQ_MASK_ERR_R] = usb_irq_mask_err_q;
+ reg_rdata_r[`USB_IRQ_MASK_DONE_R] = usb_irq_mask_done_q;
+ reg_rdata_r[`USB_IRQ_MASK_SOF_R] = usb_irq_mask_sof_q;
+ end
+ `USB_XFER_DATA:
+ begin
+ reg_rdata_r[`USB_XFER_DATA_TX_LEN_R] = usb_xfer_data_tx_len_q;
+ end
+ `USB_XFER_TOKEN:
+ begin
+ reg_rdata_r[`USB_XFER_TOKEN_IN_R] = usb_xfer_token_in_q;
+ reg_rdata_r[`USB_XFER_TOKEN_ACK_R] = usb_xfer_token_ack_q;
+ reg_rdata_r[`USB_XFER_TOKEN_PID_DATAX_R] = usb_xfer_token_pid_datax_q;
+ reg_rdata_r[`USB_XFER_TOKEN_PID_BITS_R] = usb_xfer_token_pid_bits_q;
+ reg_rdata_r[`USB_XFER_TOKEN_DEV_ADDR_R] = usb_xfer_token_dev_addr_q;
+ reg_rdata_r[`USB_XFER_TOKEN_EP_ADDR_R] = usb_xfer_token_ep_addr_q;
+ end
+ `USB_RX_STAT:
+ begin
+ reg_rdata_r[`USB_RX_STAT_START_PEND_R] = usb_rx_stat_start_pend_in_w;
+ reg_rdata_r[`USB_RX_STAT_CRC_ERR_R] = usb_rx_stat_crc_err_in_w;
+ reg_rdata_r[`USB_RX_STAT_RESP_TIMEOUT_R] = usb_rx_stat_resp_timeout_in_w;
+ reg_rdata_r[`USB_RX_STAT_IDLE_R] = usb_rx_stat_idle_in_w;
+ reg_rdata_r[`USB_RX_STAT_RESP_BITS_R] = usb_rx_stat_resp_bits_in_w;
+ reg_rdata_r[`USB_RX_STAT_COUNT_BITS_R] = usb_rx_stat_count_bits_in_w;
+ end
+ `USB_RD_DATA:
+ begin
+ reg_rdata_r[`USB_RD_DATA_DATA_R] = usb_rd_data_data_in_w;
+ end
+ default :
+ reg_rdata_r = 32'b0;
+ endcase
+end
+
+//-----------------------------------------------------------------
+// Register usb_rd_data
+//-----------------------------------------------------------------
+reg usb_rd_data_wr_q;
+
+always @ (posedge clk_i or negedge rstn_i)
+if (!rstn_i)
+ usb_rd_data_wr_q <= 1'b0;
+else if (cfg_wr && (reg_addr[5:0] == `USB_RD_DATA))
+ usb_rd_data_wr_q <= 1'b1;
+else
+ usb_rd_data_wr_q <= 1'b0;
+
+
+
+wire usb_rd_data_rd_req_w = reg_cs & (reg_wr==0) & (!reg_ack) & (reg_addr[5:0] == `USB_RD_DATA);
+
+wire usb_wr_data_wr_req_w = usb_wr_data_wr_q;
+wire usb_rd_data_wr_req_w = usb_rd_data_wr_q;
+
+//-----------------------------------------------------------------
+// Registers / Wires
+//-----------------------------------------------------------------
+// SOF
+reg [10:0] sof_value_q;
+reg [15:0] sof_time_q;
+reg sof_irq_q;
+
+reg transfer_req_ack_q;
+
+wire [7:0] fifo_tx_data_w;
+wire fifo_tx_pop_w;
+
+wire [7:0] fifo_rx_data_w;
+wire fifo_rx_push_w;
+
+reg fifo_flush_q;
+
+wire [7:0] token_pid_w;
+wire [6:0] token_dev_w;
+wire [3:0] token_ep_w;
+
+reg transfer_start_q;
+reg in_transfer_q;
+reg sof_transfer_q;
+reg resp_expected_q;
+wire transfer_ack_w;
+
+wire status_crc_err_w;
+wire status_timeout_w;
+wire [7:0] status_response_w;
+wire [15:0] status_rx_count_w;
+wire status_sie_idle_w;
+wire status_tx_done_w;
+wire status_rx_done_w;
+
+wire send_sof_w;
+wire sof_gaurd_band_w;
+wire clear_to_send_w;
+
+reg usb_err_q;
+
+reg intr_done_q;
+reg intr_sof_q;
+reg intr_err_q;
+
+//-----------------------------------------------------------------
+// Definitions
+//-----------------------------------------------------------------
+localparam SOF_ZERO = 0;
+localparam SOF_INC = 1;
+localparam SOF_THRESHOLD = (USB_CLK_FREQ/1000)-1;
+
+localparam CLKS_PER_BIT = (USB_CLK_FREQ / 12000000); // input clks per FS bit time
+
+localparam EOF1_THRESHOLD = (50 * CLKS_PER_BIT); // EOF1 + some margin
+localparam MAX_XFER_SIZE = 64;
+localparam MAX_XFER_PERIOD = ((MAX_XFER_SIZE + 6) * 10 * CLKS_PER_BIT); // Max packet transfer time (+ margin)
+localparam SOF_GAURD_LOW = (20 * CLKS_PER_BIT);
+localparam SOF_GAURD_HIGH = SOF_THRESHOLD - EOF1_THRESHOLD - MAX_XFER_PERIOD;
+
+localparam PID_SOF = 8'hA5;
+
+//-----------------------------------------------------------------
+// SIE
+//-----------------------------------------------------------------
+usbh_sie
+#( .USB_CLK_FREQ(USB_CLK_FREQ) )
+u_sie
+(
+ // Clock & reset
+ .clk_i(clk_i),
+ .rstn_i(rstn_i),
+
+ // Control
+ .start_i(transfer_start_q),
+ .in_transfer_i(in_transfer_q),
+ .sof_transfer_i(sof_transfer_q),
+ .resp_expected_i(resp_expected_q),
+ .ack_o(transfer_ack_w),
+
+ // Token packet
+ .token_pid_i(token_pid_w),
+ .token_dev_i(token_dev_w),
+ .token_ep_i(token_ep_w),
+
+ // Data packet
+ .data_len_i(usb_xfer_data_tx_len_out_w),
+ .data_idx_i(usb_xfer_token_pid_datax_out_w),
+
+ // Tx Data FIFO
+ .tx_data_i(fifo_tx_data_w),
+ .tx_pop_o(fifo_tx_pop_w),
+
+ // Rx Data FIFO
+ .rx_data_o(fifo_rx_data_w),
+ .rx_push_o(fifo_rx_push_w),
+
+ // Status
+ .rx_done_o(status_rx_done_w),
+ .tx_done_o(status_tx_done_w),
+ .crc_err_o(status_crc_err_w),
+ .timeout_o(status_timeout_w),
+ .response_o(status_response_w),
+ .rx_count_o(status_rx_count_w),
+ .idle_o(status_sie_idle_w),
+
+ // UTMI Interface
+ .utmi_data_o(utmi_data_out_o),
+ .utmi_txvalid_o(utmi_txvalid_o),
+ .utmi_txready_i(utmi_txready_i),
+ .utmi_data_i(utmi_data_in_i),
+ .utmi_rxvalid_i(utmi_rxvalid_i),
+ .utmi_rxactive_i(utmi_rxactive_i),
+ .utmi_linestate_i(utmi_linestate_i)
+);
+
+//-----------------------------------------------------------------
+// Peripheral Interface
+//-----------------------------------------------------------------
+assign usb_status_sof_time_in_w = sof_time_q;
+assign usb_status_rx_error_in_w = usb_err_q;
+assign usb_status_linestate_bits_in_w = utmi_linestate_i;
+
+assign usb_irq_sts_err_in_w = intr_err_q;
+assign usb_irq_sts_done_in_w = intr_done_q;
+assign usb_irq_sts_sof_in_w = intr_sof_q;
+
+assign usb_rx_stat_start_pend_in_w = usb_xfer_token_start_out_w;
+assign usb_rx_stat_crc_err_in_w = status_crc_err_w;
+assign usb_rx_stat_resp_timeout_in_w = status_timeout_w;
+assign usb_rx_stat_idle_in_w = status_sie_idle_w;
+assign usb_rx_stat_resp_bits_in_w = status_response_w;
+assign usb_rx_stat_count_bits_in_w = status_rx_count_w;
+
+assign usb_xfer_token_start_ack_in_w = transfer_req_ack_q;
+
+assign utmi_op_mode_o = usb_ctrl_phy_opmode_out_w;
+assign utmi_xcvrselect_o = usb_ctrl_phy_xcvrselect_out_w;
+assign utmi_termselect_o = usb_ctrl_phy_termselect_out_w;
+assign utmi_dppulldown_o = usb_ctrl_phy_dppulldown_out_w;
+assign utmi_dmpulldown_o = usb_ctrl_phy_dmpulldown_out_w;
+
+//-----------------------------------------------------------------
+// Tx FIFO (Host -> Device)
+//-----------------------------------------------------------------
+usbh_fifo
+u_fifo_tx
+(
+ .clk_i(clk_i),
+ .rstn_i(rstn_i),
+
+ .data_i(usb_wr_data_data_out_w),
+ .push_i(usb_wr_data_wr_req_w),
+
+ .flush_i(usb_ctrl_tx_flush_out_w),
+
+ .full_o(),
+ .empty_o(),
+
+ .data_o(fifo_tx_data_w),
+ .pop_i(fifo_tx_pop_w)
+);
+
+//-----------------------------------------------------------------
+// Rx FIFO (Device -> Host)
+//-----------------------------------------------------------------
+usbh_fifo
+u_fifo_rx
+(
+ .clk_i(clk_i),
+ .rstn_i(rstn_i),
+
+ // Receive from UTMI interface
+ .data_i(fifo_rx_data_w),
+ .push_i(fifo_rx_push_w),
+
+ .flush_i(fifo_flush_q),
+
+ .full_o(),
+ .empty_o(),
+
+ .data_o(usb_rd_data_data_in_w),
+ .pop_i(usb_rd_data_rd_req_w)
+);
+
+//-----------------------------------------------------------------
+// Assignments
+//-----------------------------------------------------------------
+assign send_sof_w = ({16'b0, sof_time_q} == SOF_THRESHOLD && usb_ctrl_enable_sof_out_w) & status_sie_idle_w;
+assign sof_gaurd_band_w = ({16'b0, sof_time_q} <= SOF_GAURD_LOW || {16'b0, sof_time_q} >= SOF_GAURD_HIGH);
+assign clear_to_send_w = (~sof_gaurd_band_w | ~usb_ctrl_enable_sof_out_w) & status_sie_idle_w;
+
+assign token_pid_w = sof_transfer_q ? PID_SOF : usb_xfer_token_pid_bits_out_w;
+
+assign token_dev_w = sof_transfer_q ?
+ {sof_value_q[0], sof_value_q[1], sof_value_q[2],
+ sof_value_q[3], sof_value_q[4], sof_value_q[5], sof_value_q[6]} :
+ {usb_xfer_token_dev_addr_out_w[0], usb_xfer_token_dev_addr_out_w[1], usb_xfer_token_dev_addr_out_w[2], usb_xfer_token_dev_addr_out_w[3], usb_xfer_token_dev_addr_out_w[4], usb_xfer_token_dev_addr_out_w[5], usb_xfer_token_dev_addr_out_w[6]};
+
+assign token_ep_w = sof_transfer_q ?
+ {sof_value_q[7], sof_value_q[8], sof_value_q[9], sof_value_q[10]} :
+ {usb_xfer_token_ep_addr_out_w[0], usb_xfer_token_ep_addr_out_w[1], usb_xfer_token_ep_addr_out_w[2], usb_xfer_token_ep_addr_out_w[3]};
+
+//-----------------------------------------------------------------
+// Control logic
+//-----------------------------------------------------------------
+always @ (posedge clk_i or negedge rstn_i)
+if (!rstn_i)
+begin
+ fifo_flush_q <= 1'b0;
+ transfer_start_q <= 1'b0;
+ sof_transfer_q <= 1'b0;
+ transfer_req_ack_q <= 1'b0;
+ in_transfer_q <= 1'b0;
+ resp_expected_q <= 1'b0;
+end
+else
+begin
+ // Transfer in progress?
+ if (transfer_start_q)
+ begin
+ // Transfer accepted
+ if (transfer_ack_w)
+ transfer_start_q <= 1'b0;
+
+ fifo_flush_q <= 1'b0;
+ transfer_req_ack_q <= 1'b0;
+ end
+ // Time to send another SOF token?
+ else if (send_sof_w)
+ begin
+ // Start transfer
+ in_transfer_q <= 1'b0;
+ resp_expected_q <= 1'b0;
+ transfer_start_q <= 1'b1;
+ sof_transfer_q <= 1'b1;
+ end
+ // Not in SOF gaurd band region or SOF disabled?
+ else if (clear_to_send_w)
+ begin
+ // Transfer request
+ if (usb_xfer_token_start_out_w)
+ begin
+ // Flush un-used previous Rx data
+ fifo_flush_q <= 1'b1;
+
+ // Start transfer
+ in_transfer_q <= usb_xfer_token_in_out_w;
+ resp_expected_q <= usb_xfer_token_ack_out_w;
+ transfer_start_q <= 1'b1;
+ sof_transfer_q <= 1'b0;
+ transfer_req_ack_q <= 1'b1;
+ end
+ end
+end
+
+//-----------------------------------------------------------------
+// SOF Frame Number
+//-----------------------------------------------------------------
+always @ (posedge clk_i or negedge rstn_i)
+if (!rstn_i)
+begin
+ sof_value_q <= 11'd0;
+ sof_time_q <= SOF_ZERO;
+ sof_irq_q <= 1'b0;
+end
+// Time to send another SOF token?
+else if (send_sof_w)
+begin
+ sof_time_q <= SOF_ZERO;
+ sof_value_q <= sof_value_q + 11'd1;
+
+ // Start of frame interrupt
+ sof_irq_q <= 1'b1;
+end
+else
+begin
+ // Increment the SOF timer
+ if ({16'b0, sof_time_q} != SOF_THRESHOLD)
+ sof_time_q <= sof_time_q + SOF_INC;
+
+ sof_irq_q <= 1'b0;
+end
+
+//-----------------------------------------------------------------
+// Record Errors
+//-----------------------------------------------------------------
+always @ (posedge clk_i or negedge rstn_i)
+if (!rstn_i)
+ usb_err_q <= 1'b0;
+// Clear error
+else if (usb_ctrl_wr_q)
+ usb_err_q <= 1'b0;
+// Record bus errors
+else if (utmi_rxerror_i)
+ usb_err_q <= 1'b1;
+
+//-----------------------------------------------------------------
+// Interrupts
+//-----------------------------------------------------------------
+reg err_cond_q;
+reg intr_q;
+reg device_det_q;
+
+always @ (posedge clk_i or negedge rstn_i)
+if (!rstn_i)
+begin
+ intr_done_q <= 1'b0;
+ intr_sof_q <= 1'b0;
+ intr_err_q <= 1'b0;
+ err_cond_q <= 1'b0;
+ device_det_q <= 1'b0;
+ intr_q <= 1'b0;
+end
+else
+begin
+ if (status_rx_done_w || status_tx_done_w)
+ intr_done_q <= 1'b1;
+ else if (usb_irq_ack_done_out_w)
+ intr_done_q <= 1'b0;
+
+ if (sof_irq_q)
+ intr_sof_q <= 1'b1;
+ else if (usb_irq_ack_sof_out_w)
+ intr_sof_q <= 1'b0;
+
+ if ((status_crc_err_w || status_timeout_w) && (!err_cond_q))
+ intr_err_q <= 1'b1;
+ else if (usb_irq_ack_err_out_w)
+ intr_err_q <= 1'b0;
+
+ // Line state != SE0
+ if (utmi_linestate_i != 2'b0)
+ device_det_q <= 1'b1;
+ else if (usb_irq_ack_device_detect_out_w)
+ device_det_q <= 1'b0;
+
+ err_cond_q <= (status_crc_err_w | status_timeout_w);
+
+ intr_q <= (intr_done_q & usb_irq_mask_done_out_w) |
+ (intr_err_q & usb_irq_mask_err_out_w) |
+ (intr_sof_q & usb_irq_mask_sof_out_w) |
+ (device_det_q & usb_irq_mask_device_detect_out_w);
+end
+
+assign usb_irq_sts_device_detect_in_w = 1'b0;
+
+assign intr_o = intr_q;
+
+
+
+endmodule
diff --git a/verilog/rtl/usb1_host/src/core/usbh_crc16.sv b/verilog/rtl/usb1_host/src/core/usbh_crc16.sv
new file mode 100644
index 0000000..11f767c
--- /dev/null
+++ b/verilog/rtl/usb1_host/src/core/usbh_crc16.sv
@@ -0,0 +1,89 @@
+//////////////////////////////////////////////////////////////////////////////
+// SPDX-FileCopyrightText: 2021 , Dinesh Annayya
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+// SPDX-License-Identifier: Apache-2.0
+// SPDX-FileContributor: Created by Dinesh Annayya <dinesha@opencores.org>
+//
+//-----------------------------------------------------------------
+// USB Full Speed Host
+// V0.6
+// Ultra-Embedded.com
+// Copyright 2015-2020
+//
+// Email: admin@ultra-embedded.com
+//
+// License: GPL
+// If you would like a version with a more permissive license for
+// use in closed source commercial applications please contact me
+// for details.
+//-----------------------------------------------------------------
+//
+// This file is open source HDL; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License as
+// published by the Free Software Foundation; either version 2 of
+// the License, or (at your option) any later version.
+//
+// This file is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public
+// License along with this file; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+// USA
+//-----------------------------------------------------------------
+
+//-----------------------------------------------------------------
+// Generated File
+//-----------------------------------------------------------------
+//-----------------------------------------------------------------
+// Module: 16-bit CRC used by USB data packets
+//-----------------------------------------------------------------
+module usbh_crc16
+(
+ input [15:0] crc_i,
+ input [7:0] data_i,
+ output [15:0] crc_o
+);
+
+//-----------------------------------------------------------------
+// Implementation
+//-----------------------------------------------------------------
+assign crc_o[15] = data_i[0] ^ data_i[1] ^ data_i[2] ^ data_i[3] ^ data_i[4] ^
+ data_i[5] ^ data_i[6] ^ data_i[7] ^ crc_i[7] ^ crc_i[6] ^
+ crc_i[5] ^ crc_i[4] ^ crc_i[3] ^ crc_i[2] ^
+ crc_i[1] ^ crc_i[0];
+assign crc_o[14] = data_i[0] ^ data_i[1] ^ data_i[2] ^ data_i[3] ^ data_i[4] ^ data_i[5] ^
+ data_i[6] ^ crc_i[6] ^ crc_i[5] ^ crc_i[4] ^
+ crc_i[3] ^ crc_i[2] ^ crc_i[1] ^ crc_i[0];
+assign crc_o[13] = data_i[6] ^ data_i[7] ^ crc_i[7] ^ crc_i[6];
+assign crc_o[12] = data_i[5] ^ data_i[6] ^ crc_i[6] ^ crc_i[5];
+assign crc_o[11] = data_i[4] ^ data_i[5] ^ crc_i[5] ^ crc_i[4];
+assign crc_o[10] = data_i[3] ^ data_i[4] ^ crc_i[4] ^ crc_i[3];
+assign crc_o[9] = data_i[2] ^ data_i[3] ^ crc_i[3] ^ crc_i[2];
+assign crc_o[8] = data_i[1] ^ data_i[2] ^ crc_i[2] ^ crc_i[1];
+assign crc_o[7] = data_i[0] ^ data_i[1] ^ crc_i[15] ^ crc_i[1] ^ crc_i[0];
+assign crc_o[6] = data_i[0] ^ crc_i[14] ^ crc_i[0];
+assign crc_o[5] = crc_i[13];
+assign crc_o[4] = crc_i[12];
+assign crc_o[3] = crc_i[11];
+assign crc_o[2] = crc_i[10];
+assign crc_o[1] = crc_i[9];
+assign crc_o[0] = data_i[0] ^ data_i[1] ^ data_i[2] ^ data_i[3] ^ data_i[4] ^ data_i[5] ^
+ data_i[6] ^ data_i[7] ^ crc_i[8] ^ crc_i[7] ^ crc_i[6] ^
+ crc_i[5] ^ crc_i[4] ^ crc_i[3] ^ crc_i[2] ^
+ crc_i[1] ^ crc_i[0];
+
+endmodule
diff --git a/verilog/rtl/usb1_host/src/core/usbh_crc5.sv b/verilog/rtl/usb1_host/src/core/usbh_crc5.sv
new file mode 100644
index 0000000..f125905
--- /dev/null
+++ b/verilog/rtl/usb1_host/src/core/usbh_crc5.sv
@@ -0,0 +1,79 @@
+//////////////////////////////////////////////////////////////////////////////
+// SPDX-FileCopyrightText: 2021 , Dinesh Annayya
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+// SPDX-License-Identifier: Apache-2.0
+// SPDX-FileContributor: Created by Dinesh Annayya <dinesha@opencores.org>
+//
+//-----------------------------------------------------------------
+// USB Full Speed Host
+// V0.6
+// Ultra-Embedded.com
+// Copyright 2015-2020
+//
+// Email: admin@ultra-embedded.com
+//
+// License: GPL
+// If you would like a version with a more permissive license for
+// use in closed source commercial applications please contact me
+// for details.
+//-----------------------------------------------------------------
+//
+// This file is open source HDL; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License as
+// published by the Free Software Foundation; either version 2 of
+// the License, or (at your option) any later version.
+//
+// This file is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public
+// License along with this file; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+// USA
+//-----------------------------------------------------------------
+
+//-----------------------------------------------------------------
+// Generated File
+//-----------------------------------------------------------------
+//-----------------------------------------------------------------
+// Module: 5-bit CRC used by USB tokens
+//-----------------------------------------------------------------
+module usbh_crc5
+(
+ input [4:0] crc_i,
+ input [10:0] data_i,
+ output [4:0] crc_o
+);
+
+//-----------------------------------------------------------------
+// Implementation
+//-----------------------------------------------------------------
+assign crc_o[0] = data_i[10] ^ data_i[9] ^ data_i[6] ^ data_i[5] ^ data_i[3] ^ data_i[0] ^
+ crc_i[0] ^ crc_i[3] ^ crc_i[4];
+
+assign crc_o[1] = data_i[10] ^ data_i[7] ^ data_i[6] ^ data_i[4] ^ data_i[1] ^
+ crc_i[0] ^ crc_i[1] ^ crc_i[4];
+
+assign crc_o[2] = data_i[10] ^ data_i[9] ^ data_i[8] ^ data_i[7] ^ data_i[6] ^ data_i[3] ^ data_i[2] ^ data_i[0] ^
+ crc_i[0] ^ crc_i[1] ^ crc_i[2] ^ crc_i[3] ^ crc_i[4];
+
+assign crc_o[3] = data_i[10] ^ data_i[9] ^ data_i[8] ^ data_i[7] ^ data_i[4] ^ data_i[3] ^ data_i[1] ^
+ crc_i[1] ^ crc_i[2] ^ crc_i[3] ^ crc_i[4];
+
+assign crc_o[4] = data_i[10] ^ data_i[9] ^ data_i[8] ^ data_i[5] ^ data_i[4] ^ data_i[2] ^
+ crc_i[2] ^ crc_i[3] ^ crc_i[4];
+
+endmodule
diff --git a/verilog/rtl/usb1_host/src/core/usbh_fifo.sv b/verilog/rtl/usb1_host/src/core/usbh_fifo.sv
new file mode 100644
index 0000000..67113c3
--- /dev/null
+++ b/verilog/rtl/usb1_host/src/core/usbh_fifo.sv
@@ -0,0 +1,143 @@
+//////////////////////////////////////////////////////////////////////////////
+// SPDX-FileCopyrightText: 2021 , Dinesh Annayya
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+// SPDX-License-Identifier: Apache-2.0
+// SPDX-FileContributor: Created by Dinesh Annayya <dinesha@opencores.org>
+//
+//-----------------------------------------------------------------
+// USB Full Speed Host
+// V0.6
+// Ultra-Embedded.com
+// Copyright 2015-2020
+//
+// Email: admin@ultra-embedded.com
+//
+// License: GPL
+// If you would like a version with a more permissive license for
+// use in closed source commercial applications please contact me
+// for details.
+//-----------------------------------------------------------------
+//
+// This file is open source HDL; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License as
+// published by the Free Software Foundation; either version 2 of
+// the License, or (at your option) any later version.
+//
+// This file is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public
+// License along with this file; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+// USA
+//-----------------------------------------------------------------
+
+//-----------------------------------------------------------------
+// Generated File
+//-----------------------------------------------------------------
+
+module usbh_fifo
+(
+ // Inputs
+ input clk_i
+ ,input rstn_i
+ ,input [ 7:0] data_i
+ ,input push_i
+ ,input pop_i
+ ,input flush_i
+
+ // Outputs
+ ,output full_o
+ ,output empty_o
+ ,output [ 7:0] data_o
+);
+
+
+
+parameter WIDTH = 8;
+parameter DEPTH = 64;
+parameter ADDR_W = 6;
+
+//-----------------------------------------------------------------
+// Local Params
+//-----------------------------------------------------------------
+localparam COUNT_W = ADDR_W + 1;
+
+//-----------------------------------------------------------------
+// Registers
+//-----------------------------------------------------------------
+reg [WIDTH-1:0] ram [DEPTH-1:0];
+reg [ADDR_W-1:0] rd_ptr;
+reg [ADDR_W-1:0] wr_ptr;
+reg [COUNT_W-1:0] count;
+
+//-----------------------------------------------------------------
+// Sequential
+//-----------------------------------------------------------------
+always @ (posedge clk_i or negedge rstn_i)
+if (!rstn_i)
+begin
+ count <= {(COUNT_W) {1'b0}};
+ rd_ptr <= {(ADDR_W) {1'b0}};
+ wr_ptr <= {(ADDR_W) {1'b0}};
+end
+else
+begin
+
+ if (flush_i)
+ begin
+ count <= {(COUNT_W) {1'b0}};
+ rd_ptr <= {(ADDR_W) {1'b0}};
+ wr_ptr <= {(ADDR_W) {1'b0}};
+ end
+
+ // Push
+ if (push_i & ~full_o)
+ begin
+ ram[wr_ptr] <= data_i;
+ wr_ptr <= wr_ptr + 1;
+ end
+
+ // Pop
+ if (pop_i & ~empty_o)
+ begin
+ rd_ptr <= rd_ptr + 1;
+ end
+
+ // Count up
+ if ((push_i & ~full_o) & ~(pop_i & ~empty_o))
+ begin
+ count <= count + 1;
+ end
+ // Count down
+ else if (~(push_i & ~full_o) & (pop_i & ~empty_o))
+ begin
+ count <= count - 1;
+ end
+end
+
+//-------------------------------------------------------------------
+// Combinatorial
+//-------------------------------------------------------------------
+/* verilator lint_off WIDTH */
+assign full_o = (count == DEPTH);
+assign empty_o = (count == 0);
+/* verilator lint_on WIDTH */
+
+assign data_o = ram[rd_ptr];
+
+
+endmodule
diff --git a/verilog/rtl/usb1_host/src/core/usbh_sie.sv b/verilog/rtl/usb1_host/src/core/usbh_sie.sv
new file mode 100644
index 0000000..0d046c0
--- /dev/null
+++ b/verilog/rtl/usb1_host/src/core/usbh_sie.sv
@@ -0,0 +1,846 @@
+//////////////////////////////////////////////////////////////////////////////
+// SPDX-FileCopyrightText: 2021 , Dinesh Annayya
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+// SPDX-License-Identifier: Apache-2.0
+// SPDX-FileContributor: Created by Dinesh Annayya <dinesha@opencores.org>
+//
+//-----------------------------------------------------------------
+// USB Full Speed Host
+// V0.6
+// Ultra-Embedded.com
+// Copyright 2015-2020
+//
+// Email: admin@ultra-embedded.com
+//
+// License: GPL
+// If you would like a version with a more permissive license for
+// use in closed source commercial applications please contact me
+// for details.
+//-----------------------------------------------------------------
+//
+// This file is open source HDL; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License as
+// published by the Free Software Foundation; either version 2 of
+// the License, or (at your option) any later version.
+//
+// This file is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public
+// License along with this file; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+// USA
+//-----------------------------------------------------------------
+
+//-----------------------------------------------------------------
+// Generated File
+//-----------------------------------------------------------------
+
+module usbh_sie
+//-----------------------------------------------------------------
+// Params
+//-----------------------------------------------------------------
+#(
+ parameter USB_CLK_FREQ = 48000000
+)
+//-----------------------------------------------------------------
+// Ports
+//-----------------------------------------------------------------
+(
+ // Inputs
+ input clk_i,
+ input rstn_i,
+ input start_i,
+ input in_transfer_i,
+ input sof_transfer_i,
+ input resp_expected_i,
+ input [ 7:0] token_pid_i,
+ input [ 6:0] token_dev_i,
+ input [ 3:0] token_ep_i,
+ input [ 15:0] data_len_i,
+ input data_idx_i,
+ input [ 7:0] tx_data_i,
+ input utmi_txready_i,
+ input [ 7:0] utmi_data_i,
+ input utmi_rxvalid_i,
+ input utmi_rxactive_i,
+ input [ 1:0] utmi_linestate_i,
+
+ // Outputs
+ output ack_o,
+ output tx_pop_o,
+ output [ 7:0] rx_data_o,
+ output rx_push_o,
+ output tx_done_o,
+ output rx_done_o,
+ output crc_err_o,
+ output timeout_o,
+ output [ 7:0] response_o,
+ output [ 15:0] rx_count_o,
+ output idle_o,
+ output [ 7:0] utmi_data_o,
+ output utmi_txvalid_o
+);
+
+
+
+//-----------------------------------------------------------------
+// Registers / Wires
+//-----------------------------------------------------------------
+logic start_ack_q;
+
+// Status
+logic status_tx_done_q;
+logic status_rx_done_q;
+logic status_crc_err_q;
+logic status_timeout_q;
+logic [7:0] status_response_q;
+
+logic [15:0] byte_count_q;
+logic in_transfer_q;
+
+logic [8:0] last_tx_time_q;
+
+logic send_data1_q;
+logic send_sof_q;
+logic send_ack_q;
+
+// CRC16
+logic [15:0] crc_sum_q;
+logic [15:0] crc_out_w;
+logic [7:0] crc_data_in_w;
+
+// CRC5
+logic [4:0] crc5_out_w;
+wire [4:0] crc5_next_w = crc5_out_w ^ 5'h1F;
+
+logic [15:0] token_q;
+
+logic wait_resp_q;
+
+logic [3:0] state_q;
+
+//-----------------------------------------------------------------
+// Definitions
+//-----------------------------------------------------------------
+localparam RX_TIMEOUT = (USB_CLK_FREQ == 60000000) ? 9'd511 : 9'd255;
+ // 2 FS bit times (x5 CLKs @ 60MHz, x4 CLKs @ 48MHz)
+localparam TX_IFS = (USB_CLK_FREQ == 60000000) ? 4'd10 : 4'd7;
+
+localparam PID_OUT = 8'hE1;
+localparam PID_IN = 8'h69;
+localparam PID_SOF = 8'hA5;
+localparam PID_SETUP = 8'h2D;
+
+localparam PID_DATA0 = 8'hC3;
+localparam PID_DATA1 = 8'h4B;
+
+localparam PID_ACK = 8'hD2;
+localparam PID_NAK = 8'h5A;
+localparam PID_STALL = 8'h1E;
+
+// States
+localparam STATE_IDLE = 4'd0;
+localparam STATE_RX_DATA = 4'd1;
+localparam STATE_TX_PID = 4'd2;
+localparam STATE_TX_DATA = 4'd3;
+localparam STATE_TX_CRC1 = 4'd4;
+localparam STATE_TX_CRC2 = 4'd5;
+localparam STATE_TX_TOKEN1 = 4'd6;
+localparam STATE_TX_TOKEN2 = 4'd7;
+localparam STATE_TX_TOKEN3 = 4'd8;
+localparam STATE_TX_ACKNAK = 4'd9;
+localparam STATE_TX_WAIT = 4'd10;
+localparam STATE_RX_WAIT = 4'd11;
+localparam STATE_TX_IFS = 4'd12;
+
+//-----------------------------------------------------------------
+// Wires
+//-----------------------------------------------------------------
+// Rx data
+logic [7:0] rx_data_w;
+logic data_ready_w;
+logic crc_byte_w;
+logic rx_active_w;
+logic rx_active_rise_w;
+
+// Tx/Rx -> Tx IFS timeout
+logic ifs_busy_w;
+
+// Response timeout (no response after 500uS from transmit)
+wire rx_resp_timeout_w = (last_tx_time_q >= RX_TIMEOUT) & wait_resp_q;
+
+// CRC16 error on received data
+wire crc_error_w = (state_q == STATE_RX_DATA) && !rx_active_w && in_transfer_q &&
+ (status_response_q == PID_DATA0 || status_response_q == PID_DATA1) &&
+ (crc_sum_q != 16'hB001);
+
+//-----------------------------------------------------------------
+// State Machine
+//-----------------------------------------------------------------
+logic [3:0] next_state_r;
+
+always @ *
+begin
+ next_state_r = state_q;
+
+ //-----------------------------------------
+ // Tx State Machine
+ //-----------------------------------------
+ case (state_q)
+
+ //-----------------------------------------
+ // TX_TOKEN1 (byte 1 of token)
+ //-----------------------------------------
+ STATE_TX_TOKEN1 :
+ begin
+ // Data sent?
+ if (utmi_txready_i)
+ next_state_r = STATE_TX_TOKEN2;
+ end
+ //-----------------------------------------
+ // TX_TOKEN2 (byte 2 of token)
+ //-----------------------------------------
+ STATE_TX_TOKEN2 :
+ begin
+ // Data sent?
+ if (utmi_txready_i)
+ next_state_r = STATE_TX_TOKEN3;
+ end
+ //-----------------------------------------
+ // TX_TOKEN3 (byte 3 of token)
+ //-----------------------------------------
+ STATE_TX_TOKEN3 :
+ begin
+ // Data sent?
+ if (utmi_txready_i)
+ begin
+ // SOF - no data packet
+ if (send_sof_q)
+ next_state_r = STATE_TX_IFS;
+ // IN - wait for data
+ else if (in_transfer_q)
+ next_state_r = STATE_RX_WAIT;
+ // OUT/SETUP - Send data or ZLP
+ else
+ next_state_r = STATE_TX_IFS;
+ end
+ end
+ //-----------------------------------------
+ // TX_IFS
+ //-----------------------------------------
+ STATE_TX_IFS :
+ begin
+ // IFS expired
+ if (~ifs_busy_w)
+ begin
+ // SOF - no data packet
+ if (send_sof_q)
+ next_state_r = STATE_IDLE;
+ // OUT/SETUP - Send data or ZLP
+ else
+ next_state_r = STATE_TX_PID;
+ end
+ end
+ //-----------------------------------------
+ // TX_PID
+ //-----------------------------------------
+ STATE_TX_PID :
+ begin
+ // Last data byte sent?
+ if (utmi_txready_i && (byte_count_q == 16'b0))
+ next_state_r = STATE_TX_CRC1;
+ else if (utmi_txready_i)
+ next_state_r = STATE_TX_DATA;
+ end
+ //-----------------------------------------
+ // TX_DATA
+ //-----------------------------------------
+ STATE_TX_DATA :
+ begin
+ // Last data byte sent?
+ if (utmi_txready_i && (byte_count_q == 16'b0))
+ next_state_r = STATE_TX_CRC1;
+ end
+ //-----------------------------------------
+ // TX_CRC1 (first byte)
+ //-----------------------------------------
+ STATE_TX_CRC1 :
+ begin
+ // Data sent?
+ if (utmi_txready_i)
+ next_state_r = STATE_TX_CRC2;
+ end
+ //-----------------------------------------
+ // TX_CRC (second byte)
+ //-----------------------------------------
+ STATE_TX_CRC2 :
+ begin
+ // Data sent?
+ if (utmi_txready_i)
+ begin
+ // If a response is expected
+ if (wait_resp_q)
+ next_state_r = STATE_RX_WAIT;
+ // No response expected (e.g ISO transfer)
+ else
+ next_state_r = STATE_IDLE;
+ end
+ end
+ //-----------------------------------------
+ // STATE_TX_WAIT
+ //-----------------------------------------
+ STATE_TX_WAIT :
+ begin
+ // Waited long enough?
+ if (~ifs_busy_w)
+ next_state_r = STATE_TX_ACKNAK;
+ end
+ //-----------------------------------------
+ // STATE_TX_ACKNAK
+ //-----------------------------------------
+ STATE_TX_ACKNAK :
+ begin
+ // Data sent?
+ if (utmi_txready_i)
+ next_state_r = STATE_IDLE;
+ end
+ //-----------------------------------------
+ // STATE_RX_WAIT
+ //-----------------------------------------
+ STATE_RX_WAIT :
+ begin
+ // Data received?
+ if (data_ready_w)
+ next_state_r = STATE_RX_DATA;
+ // Waited long enough?
+ else if (rx_resp_timeout_w)
+ next_state_r = STATE_IDLE;
+ end
+ //-----------------------------------------
+ // RX_DATA
+ //-----------------------------------------
+ STATE_RX_DATA :
+ begin
+ // Receive complete
+ if (~rx_active_w)
+ begin
+ // Send ACK but incoming data had CRC error, do not ACK
+ if (send_ack_q && crc_error_w)
+ next_state_r = STATE_IDLE;
+ // Send an ACK response without CPU interaction?
+ else if (send_ack_q && (status_response_q == PID_DATA0 || status_response_q == PID_DATA1))
+ next_state_r = STATE_TX_WAIT;
+ else
+ next_state_r = STATE_IDLE;
+ end
+ end
+ //-----------------------------------------
+ // IDLE / RECEIVE BEGIN
+ //-----------------------------------------
+ STATE_IDLE :
+ begin
+ // Token transfer request
+ if (start_i)
+ next_state_r = STATE_TX_TOKEN1;
+ end
+ default :
+ ;
+ endcase
+end
+
+// Update state
+always @ (posedge clk_i or negedge rstn_i)
+if (!rstn_i)
+ state_q <= STATE_IDLE;
+else
+ state_q <= next_state_r;
+
+//-----------------------------------------------------------------
+// Tx Token
+//-----------------------------------------------------------------
+always @ (posedge clk_i or negedge rstn_i)
+if (!rstn_i)
+ token_q <= 16'h0000;
+else if (state_q == STATE_IDLE)
+ token_q <= {token_dev_i, token_ep_i, 5'b0};
+// PID of token sent, capture calculated CRC for token packet
+else if (state_q == STATE_TX_TOKEN1 && utmi_txready_i)
+ token_q[4:0] <= crc5_next_w;
+
+//-----------------------------------------------------------------
+// Tx EOP - detect end of transmit (token, data or ACK/NAK)
+//-----------------------------------------------------------------
+reg [1:0] utmi_linestate_q;
+reg se0_detect_q;
+reg wait_eop_q;
+
+always @ (posedge clk_i or negedge rstn_i)
+if (!rstn_i)
+ utmi_linestate_q <= 2'b0;
+else
+ utmi_linestate_q <= utmi_linestate_i;
+
+// SE0 filtering (2 cycles FS)
+wire se0_detect_w = (utmi_linestate_q == 2'b00 && utmi_linestate_i == 2'b00);
+
+always @ (posedge clk_i or negedge rstn_i)
+if (!rstn_i)
+ se0_detect_q <= 1'b0;
+else
+ se0_detect_q <= se0_detect_w;
+
+// TODO: This needs updating for HS USB...
+wire eop_detected_w = se0_detect_q & (utmi_linestate_i != 2'b00);
+
+// End of transmit detection
+always @ (posedge clk_i or negedge rstn_i)
+if (!rstn_i)
+ wait_eop_q <= 1'b0;
+else if (eop_detected_w)
+ wait_eop_q <= 1'b0;
+else if ((state_q == STATE_TX_CRC2 && next_state_r != STATE_TX_CRC2) ||
+ (state_q == STATE_TX_TOKEN3 && next_state_r != STATE_TX_TOKEN3) ||
+ (state_q == STATE_TX_ACKNAK && next_state_r != STATE_TX_ACKNAK))
+ wait_eop_q <= 1'b1;
+else if (rx_active_rise_w)
+ wait_eop_q <= 1'b1;
+
+localparam TX_IFS_W = 4;
+reg [TX_IFS_W-1:0] tx_ifs_q;
+
+always @ (posedge clk_i or negedge rstn_i)
+if (!rstn_i)
+ tx_ifs_q <= {(TX_IFS_W){1'b0}};
+// Start counting down from last Tx or EOP being detected at end of Rx
+else if (wait_eop_q || eop_detected_w)
+ tx_ifs_q <= TX_IFS;
+// Decrement IFS counter
+else if (tx_ifs_q != {(TX_IFS_W){1'b0}})
+ tx_ifs_q <= tx_ifs_q - 1;
+
+assign ifs_busy_w = wait_eop_q || (tx_ifs_q != {(TX_IFS_W){1'b0}});
+
+//-----------------------------------------------------------------
+// Tx Timer
+//-----------------------------------------------------------------
+always @ (posedge clk_i or negedge rstn_i)
+if (!rstn_i)
+ last_tx_time_q <= 9'd0;
+// Start counting from last Tx
+else if (state_q == STATE_IDLE || (utmi_txvalid_o && utmi_txready_i))
+ last_tx_time_q <= 9'd0;
+// Increment the Tx timeout
+else if (last_tx_time_q != RX_TIMEOUT)
+ last_tx_time_q <= last_tx_time_q + 9'd1;
+
+//-----------------------------------------------------------------
+// Transmit / Receive counter
+//-----------------------------------------------------------------
+always @ (posedge clk_i or negedge rstn_i)
+if (!rstn_i)
+ byte_count_q <= 16'h0000;
+// New transfer request (not automatic SOF request)
+else if (state_q == STATE_IDLE && start_i && !sof_transfer_i)
+ byte_count_q <= data_len_i;
+else if (state_q == STATE_RX_WAIT)
+ byte_count_q <= 16'h0000;
+// Transmit byte
+else if ((state_q == STATE_TX_PID || state_q == STATE_TX_DATA) && utmi_txready_i)
+begin
+ // Count down data left to send
+ if (byte_count_q != 16'd0)
+ byte_count_q <= byte_count_q - 16'd1;
+end
+// Received byte
+else if (state_q == STATE_RX_DATA && data_ready_w && !crc_byte_w)
+ byte_count_q <= byte_count_q + 16'd1;
+
+//-----------------------------------------------------------------
+// Transfer start ack
+//-----------------------------------------------------------------
+always @ (posedge clk_i or negedge rstn_i)
+if (!rstn_i)
+ start_ack_q <= 1'b0;
+// First byte of PID sent, ack transfer request
+else if (state_q == STATE_TX_TOKEN1 && utmi_txready_i)
+ start_ack_q <= 1'b1;
+else
+ start_ack_q <= 1'b0;
+
+//-----------------------------------------------------------------
+// Record request details
+//-----------------------------------------------------------------
+always @ (posedge clk_i or negedge rstn_i)
+if (!rstn_i)
+begin
+ in_transfer_q <= 1'b0;
+ send_ack_q <= 1'b0;
+ send_data1_q <= 1'b0;
+ send_sof_q <= 1'b0;
+end
+// Start of new request
+else if (state_q == STATE_IDLE && start_i)
+begin
+ // Transfer request
+ // e.g. (H)SOF [sof_transfer_i]
+ // (H)OUT + (H)DATA + (F)ACK/NACK/STALL [data_len_i >= 0 && !in_transfer_i]
+ // (H)IN + (F)DATA + (H)ACK [in_transfer_i]
+ // (H)IN + (F)NAK/STALL [in_transfer_i]
+ in_transfer_q <= in_transfer_i;
+
+ // Send ACK in response to IN DATA
+ send_ack_q <= in_transfer_i && resp_expected_i;
+
+ // DATA0/1
+ send_data1_q <= data_idx_i;
+
+ send_sof_q <= sof_transfer_i;
+end
+
+//-----------------------------------------------------------------
+// Response expected
+//-----------------------------------------------------------------
+always @ (posedge clk_i or negedge rstn_i)
+if (!rstn_i)
+ wait_resp_q <= 1'b0;
+// Incoming data
+else if (state_q == STATE_RX_WAIT && data_ready_w)
+ wait_resp_q <= 1'b0;
+else if (state_q == STATE_IDLE && start_i)
+ wait_resp_q <= resp_expected_i;
+
+//-----------------------------------------------------------------
+// Status
+//-----------------------------------------------------------------
+always @ (posedge clk_i or negedge rstn_i)
+begin
+ if (!rstn_i)
+ begin
+ status_response_q <= 8'h00;
+ status_timeout_q <= 1'b0;
+ status_rx_done_q <= 1'b0;
+ status_tx_done_q <= 1'b0;
+ end
+ else
+ begin
+ case (state_q)
+
+ //-----------------------------------------
+ // RX_WAIT
+ //-----------------------------------------
+ STATE_RX_WAIT :
+ begin
+ // Store response PID
+ if (data_ready_w)
+ status_response_q <= rx_data_w;
+
+ // Waited long enough?
+ if (rx_resp_timeout_w)
+ status_timeout_q <= 1'b1;
+
+ status_tx_done_q <= 1'b0;
+ end
+ //-----------------------------------------
+ // RX_DATA
+ //-----------------------------------------
+ STATE_RX_DATA :
+ begin
+ // Receive complete
+ if (!utmi_rxactive_i)
+ status_rx_done_q <= 1'b1;
+ else
+ status_rx_done_q <= 1'b0;
+ end
+ //-----------------------------------------
+ // TX_CRC (second byte)
+ //-----------------------------------------
+ STATE_TX_CRC2 :
+ begin
+ // Data sent?
+ if (utmi_txready_i && !wait_resp_q)
+ begin
+ // Transfer now complete
+ status_tx_done_q <= 1'b1;
+ end
+ end
+ //-----------------------------------------
+ // IDLE / RECEIVE BEGIN
+ //-----------------------------------------
+ STATE_IDLE :
+ begin
+ // Transfer request
+ // e.g. (H)SOF [sof_transfer_i]
+ // (H)OUT + (H)DATA + (F)ACK/NACK/STALL [data_len_i >= 0 && !in_transfer_i]
+ // (H)IN + (F)DATA + (H)ACK [in_transfer_i]
+ // (H)IN + (F)NAK/STALL [in_transfer_i]
+ if (start_i && !sof_transfer_i) // (not automatic SOF request)
+ begin
+ // Clear status
+ status_response_q <= 8'h00;
+ status_timeout_q <= 1'b0;
+ end
+
+ status_rx_done_q <= 1'b0;
+ status_tx_done_q <= 1'b0;
+ end
+ //-----------------------------------------
+ // DEFAULT
+ //-----------------------------------------
+ default :
+ begin
+ status_rx_done_q <= 1'b0;
+ status_tx_done_q <= 1'b0;
+ end
+ endcase
+ end
+end
+
+
+//-----------------------------------------------------------------
+// Data delay (to strip the CRC16 trailing bytes)
+//-----------------------------------------------------------------
+reg [31:0] data_buffer_q;
+reg [3:0] data_valid_q;
+reg [3:0] rx_active_q;
+
+wire shift_en_w = (utmi_rxvalid_i & utmi_rxactive_i) || !utmi_rxactive_i;
+
+always @ (posedge clk_i or negedge rstn_i)
+if (!rstn_i)
+ data_buffer_q <= 32'b0;
+else if (shift_en_w)
+ data_buffer_q <= {utmi_data_i, data_buffer_q[31:8]};
+
+always @ (posedge clk_i or negedge rstn_i)
+if (!rstn_i)
+ data_valid_q <= 4'b0;
+else if (shift_en_w)
+ data_valid_q <= {(utmi_rxvalid_i & utmi_rxactive_i), data_valid_q[3:1]};
+else
+ data_valid_q <= {data_valid_q[3:1], 1'b0};
+
+reg [1:0] data_crc_q;
+always @ (posedge clk_i or negedge rstn_i)
+if (!rstn_i)
+ data_crc_q <= 2'b0;
+else if (shift_en_w)
+ data_crc_q <= {!utmi_rxactive_i, data_crc_q[1]};
+
+always @ (posedge clk_i or negedge rstn_i)
+if (!rstn_i)
+ rx_active_q <= 4'b0;
+else
+ rx_active_q <= {utmi_rxactive_i, rx_active_q[3:1]};
+
+assign rx_data_w = data_buffer_q[7:0];
+assign data_ready_w = data_valid_q[0];
+assign crc_byte_w = data_crc_q[0];
+assign rx_active_w = rx_active_q[0];
+
+assign rx_active_rise_w = !rx_active_q[3] && utmi_rxactive_i;
+
+//-----------------------------------------------------------------
+// CRC
+//-----------------------------------------------------------------
+
+// CRC16 (Data)
+usbh_crc16
+u_crc16
+(
+ .crc_i(crc_sum_q),
+ .data_i(crc_data_in_w),
+ .crc_o(crc_out_w)
+);
+
+// CRC5 (Token)
+usbh_crc5
+u_crc5
+(
+ .crc_i(5'h1F),
+ .data_i(token_q[15:5]),
+ .crc_o(crc5_out_w)
+);
+
+// CRC control / check
+always @ (posedge clk_i or negedge rstn_i)
+begin
+ if (!rstn_i)
+ begin
+ crc_sum_q <= 16'hFFFF;
+ status_crc_err_q <= 1'b0;
+ end
+ else
+ begin
+ case (state_q)
+ //-----------------------------------------
+ // TX_PID
+ //-----------------------------------------
+ STATE_TX_PID :
+ begin
+ // First byte is PID (not CRC'd), reset CRC16
+ crc_sum_q <= 16'hFFFF;
+ end
+ //-----------------------------------------
+ // TX_DATA
+ //-----------------------------------------
+ STATE_TX_DATA :
+ begin
+ // Data sent?
+ if (utmi_txready_i)
+ begin
+ // Next CRC start value
+ crc_sum_q <= crc_out_w;
+ end
+ end
+ //-----------------------------------------
+ // RX_WAIT
+ //-----------------------------------------
+ STATE_RX_WAIT :
+ begin
+ // Reset CRC16
+ crc_sum_q <= 16'hFFFF;
+ end
+ //-----------------------------------------
+ // RX_DATA
+ //-----------------------------------------
+ STATE_RX_DATA :
+ begin
+ // Data received?
+ if (data_ready_w)
+ begin
+ // Next CRC start value
+ crc_sum_q <= crc_out_w;
+ end
+ // Receive complete
+ else if (!rx_active_w)
+ begin
+ // If some data received, check CRC
+ if (crc_error_w)
+ status_crc_err_q <= 1'b1;
+ else
+ status_crc_err_q <= 1'b0;
+ end
+ end
+
+ //-----------------------------------------
+ // IDLE / RECEIVE BEGIN
+ //-----------------------------------------
+ STATE_IDLE :
+ begin
+ // Start transfer request
+ if (start_i && !sof_transfer_i)
+ begin
+ // Clear error flag!
+ status_crc_err_q <= 1'b0;
+ end
+ end
+ default :
+ ;
+ endcase
+ end
+end
+
+//-----------------------------------------------------------------
+// Assignments
+//-----------------------------------------------------------------
+wire [15:0] token_rev_w;
+
+genvar i;
+generate
+for (i=0; i < 16; i=i+1)
+begin : LOOP
+ assign token_rev_w[i] = token_q[15-i];
+end
+endgenerate
+
+reg utmi_txvalid_r;
+reg [7:0] utmi_data_r;
+
+always @ *
+begin
+ if (state_q == STATE_TX_CRC1)
+ begin
+ utmi_txvalid_r = 1'b1;
+ utmi_data_r = crc_sum_q[7:0] ^ 8'hFF;
+ end
+ else if (state_q == STATE_TX_CRC2)
+ begin
+ utmi_txvalid_r = 1'b1;
+ utmi_data_r = crc_sum_q[15:8] ^ 8'hFF;
+ end
+ else if (state_q == STATE_TX_TOKEN1)
+ begin
+ utmi_txvalid_r = 1'b1;
+ utmi_data_r = token_pid_i;
+ end
+ else if (state_q == STATE_TX_TOKEN2)
+ begin
+ utmi_txvalid_r = 1'b1;
+ utmi_data_r = token_rev_w[7:0];
+ end
+ else if (state_q == STATE_TX_TOKEN3)
+ begin
+ utmi_txvalid_r = 1'b1;
+ utmi_data_r = token_rev_w[15:8];
+ end
+ else if (state_q == STATE_TX_PID)
+ begin
+ utmi_txvalid_r = 1'b1;
+ utmi_data_r = send_data1_q ? PID_DATA1 : PID_DATA0;
+ end
+ else if (state_q == STATE_TX_ACKNAK)
+ begin
+ utmi_txvalid_r = 1'b1;
+ utmi_data_r = PID_ACK;
+ end
+ else if (state_q == STATE_TX_DATA)
+ begin
+ utmi_txvalid_r = 1'b1;
+ utmi_data_r = tx_data_i;
+ end
+ else
+ begin
+ utmi_txvalid_r = 1'b0;
+ utmi_data_r = 8'b0;
+ end
+end
+
+assign utmi_txvalid_o = utmi_txvalid_r;
+assign utmi_data_o = utmi_data_r;
+
+// Push incoming data into FIFO (not PID or CRC)
+assign rx_data_o = rx_data_w;
+assign rx_push_o = (state_q != STATE_IDLE && state_q != STATE_RX_WAIT) & data_ready_w & !crc_byte_w;
+
+assign crc_data_in_w = (state_q == STATE_RX_DATA) ? rx_data_w : tx_data_i;
+
+assign rx_count_o = byte_count_q;
+assign idle_o = (state_q == STATE_IDLE);
+
+assign ack_o = start_ack_q;
+
+assign tx_pop_o = state_q == STATE_TX_DATA && utmi_txready_i;
+
+assign tx_done_o = status_tx_done_q;
+assign rx_done_o = status_rx_done_q;
+assign crc_err_o = status_crc_err_q;
+assign timeout_o = status_timeout_q;
+assign response_o = status_response_q;
+
+
+
+endmodule
diff --git a/verilog/rtl/usb1_host/src/filelist.f b/verilog/rtl/usb1_host/src/filelist.f
new file mode 100644
index 0000000..6288443
--- /dev/null
+++ b/verilog/rtl/usb1_host/src/filelist.f
@@ -0,0 +1,10 @@
+core/usbh_core.sv
+core/usbh_crc16.sv
+core/usbh_crc5.sv
+core/usbh_fifo.sv
+core/usbh_sie.sv
+phy/usb_fs_phy.v
+phy/usb_transceiver.v
+lib/async_wb.sv
+lib/async_fifo.sv
+top/usb1_host.sv
diff --git a/verilog/rtl/usb1_host/src/includes/usbh_host_defs.v b/verilog/rtl/usb1_host/src/includes/usbh_host_defs.v
new file mode 100644
index 0000000..ac0441d
--- /dev/null
+++ b/verilog/rtl/usb1_host/src/includes/usbh_host_defs.v
@@ -0,0 +1,325 @@
+//////////////////////////////////////////////////////////////////////////////
+// SPDX-FileCopyrightText: 2021 , Dinesh Annayya
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+// SPDX-License-Identifier: Apache-2.0
+// SPDX-FileContributor: Created by Dinesh Annayya <dinesha@opencores.org>
+//
+//-----------------------------------------------------------------
+// USB Full Speed Host
+// V0.6
+// Ultra-Embedded.com
+// Copyright 2015-2020
+//
+// Email: admin@ultra-embedded.com
+//
+// License: GPL
+// If you would like a version with a more permissive license for
+// use in closed source commercial applications please contact me
+// for details.
+//-----------------------------------------------------------------
+//
+// This file is open source HDL; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License as
+// published by the Free Software Foundation; either version 2 of
+// the License, or (at your option) any later version.
+//
+// This file is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public
+// License along with this file; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+// USA
+//-----------------------------------------------------------------
+
+//-----------------------------------------------------------------
+// Generated File
+//-----------------------------------------------------------------
+
+`define USB_CTRL 6'h0
+
+ `define USB_CTRL_TX_FLUSH 8
+ `define USB_CTRL_TX_FLUSH_DEFAULT 0
+ `define USB_CTRL_TX_FLUSH_B 8
+ `define USB_CTRL_TX_FLUSH_T 8
+ `define USB_CTRL_TX_FLUSH_W 1
+ `define USB_CTRL_TX_FLUSH_R 8:8
+
+ `define USB_CTRL_PHY_DMPULLDOWN 7
+ `define USB_CTRL_PHY_DMPULLDOWN_DEFAULT 0
+ `define USB_CTRL_PHY_DMPULLDOWN_B 7
+ `define USB_CTRL_PHY_DMPULLDOWN_T 7
+ `define USB_CTRL_PHY_DMPULLDOWN_W 1
+ `define USB_CTRL_PHY_DMPULLDOWN_R 7:7
+
+ `define USB_CTRL_PHY_DPPULLDOWN 6
+ `define USB_CTRL_PHY_DPPULLDOWN_DEFAULT 0
+ `define USB_CTRL_PHY_DPPULLDOWN_B 6
+ `define USB_CTRL_PHY_DPPULLDOWN_T 6
+ `define USB_CTRL_PHY_DPPULLDOWN_W 1
+ `define USB_CTRL_PHY_DPPULLDOWN_R 6:6
+
+ `define USB_CTRL_PHY_TERMSELECT 5
+ `define USB_CTRL_PHY_TERMSELECT_DEFAULT 0
+ `define USB_CTRL_PHY_TERMSELECT_B 5
+ `define USB_CTRL_PHY_TERMSELECT_T 5
+ `define USB_CTRL_PHY_TERMSELECT_W 1
+ `define USB_CTRL_PHY_TERMSELECT_R 5:5
+
+ `define USB_CTRL_PHY_XCVRSELECT_DEFAULT 0
+ `define USB_CTRL_PHY_XCVRSELECT_B 3
+ `define USB_CTRL_PHY_XCVRSELECT_T 4
+ `define USB_CTRL_PHY_XCVRSELECT_W 2
+ `define USB_CTRL_PHY_XCVRSELECT_R 4:3
+
+ `define USB_CTRL_PHY_OPMODE_DEFAULT 0
+ `define USB_CTRL_PHY_OPMODE_B 1
+ `define USB_CTRL_PHY_OPMODE_T 2
+ `define USB_CTRL_PHY_OPMODE_W 2
+ `define USB_CTRL_PHY_OPMODE_R 2:1
+
+ `define USB_CTRL_ENABLE_SOF 0
+ `define USB_CTRL_ENABLE_SOF_DEFAULT 0
+ `define USB_CTRL_ENABLE_SOF_B 0
+ `define USB_CTRL_ENABLE_SOF_T 0
+ `define USB_CTRL_ENABLE_SOF_W 1
+ `define USB_CTRL_ENABLE_SOF_R 0:0
+
+`define USB_STATUS 6'h4
+
+ `define USB_STATUS_SOF_TIME_DEFAULT 0
+ `define USB_STATUS_SOF_TIME_B 16
+ `define USB_STATUS_SOF_TIME_T 31
+ `define USB_STATUS_SOF_TIME_W 16
+ `define USB_STATUS_SOF_TIME_R 31:16
+
+ `define USB_STATUS_RX_ERROR 2
+ `define USB_STATUS_RX_ERROR_DEFAULT 0
+ `define USB_STATUS_RX_ERROR_B 2
+ `define USB_STATUS_RX_ERROR_T 2
+ `define USB_STATUS_RX_ERROR_W 1
+ `define USB_STATUS_RX_ERROR_R 2:2
+
+ `define USB_STATUS_LINESTATE_BITS_DEFAULT 0
+ `define USB_STATUS_LINESTATE_BITS_B 0
+ `define USB_STATUS_LINESTATE_BITS_T 1
+ `define USB_STATUS_LINESTATE_BITS_W 2
+ `define USB_STATUS_LINESTATE_BITS_R 1:0
+
+`define USB_IRQ_ACK 6'h8
+
+ `define USB_IRQ_ACK_DEVICE_DETECT 3
+ `define USB_IRQ_ACK_DEVICE_DETECT_DEFAULT 0
+ `define USB_IRQ_ACK_DEVICE_DETECT_B 3
+ `define USB_IRQ_ACK_DEVICE_DETECT_T 3
+ `define USB_IRQ_ACK_DEVICE_DETECT_W 1
+ `define USB_IRQ_ACK_DEVICE_DETECT_R 3:3
+
+ `define USB_IRQ_ACK_ERR 2
+ `define USB_IRQ_ACK_ERR_DEFAULT 0
+ `define USB_IRQ_ACK_ERR_B 2
+ `define USB_IRQ_ACK_ERR_T 2
+ `define USB_IRQ_ACK_ERR_W 1
+ `define USB_IRQ_ACK_ERR_R 2:2
+
+ `define USB_IRQ_ACK_DONE 1
+ `define USB_IRQ_ACK_DONE_DEFAULT 0
+ `define USB_IRQ_ACK_DONE_B 1
+ `define USB_IRQ_ACK_DONE_T 1
+ `define USB_IRQ_ACK_DONE_W 1
+ `define USB_IRQ_ACK_DONE_R 1:1
+
+ `define USB_IRQ_ACK_SOF 0
+ `define USB_IRQ_ACK_SOF_DEFAULT 0
+ `define USB_IRQ_ACK_SOF_B 0
+ `define USB_IRQ_ACK_SOF_T 0
+ `define USB_IRQ_ACK_SOF_W 1
+ `define USB_IRQ_ACK_SOF_R 0:0
+
+`define USB_IRQ_STS 6'hc
+
+ `define USB_IRQ_STS_DEVICE_DETECT 3
+ `define USB_IRQ_STS_DEVICE_DETECT_DEFAULT 0
+ `define USB_IRQ_STS_DEVICE_DETECT_B 3
+ `define USB_IRQ_STS_DEVICE_DETECT_T 3
+ `define USB_IRQ_STS_DEVICE_DETECT_W 1
+ `define USB_IRQ_STS_DEVICE_DETECT_R 3:3
+
+ `define USB_IRQ_STS_ERR 2
+ `define USB_IRQ_STS_ERR_DEFAULT 0
+ `define USB_IRQ_STS_ERR_B 2
+ `define USB_IRQ_STS_ERR_T 2
+ `define USB_IRQ_STS_ERR_W 1
+ `define USB_IRQ_STS_ERR_R 2:2
+
+ `define USB_IRQ_STS_DONE 1
+ `define USB_IRQ_STS_DONE_DEFAULT 0
+ `define USB_IRQ_STS_DONE_B 1
+ `define USB_IRQ_STS_DONE_T 1
+ `define USB_IRQ_STS_DONE_W 1
+ `define USB_IRQ_STS_DONE_R 1:1
+
+ `define USB_IRQ_STS_SOF 0
+ `define USB_IRQ_STS_SOF_DEFAULT 0
+ `define USB_IRQ_STS_SOF_B 0
+ `define USB_IRQ_STS_SOF_T 0
+ `define USB_IRQ_STS_SOF_W 1
+ `define USB_IRQ_STS_SOF_R 0:0
+
+`define USB_IRQ_MASK 6'h10
+
+ `define USB_IRQ_MASK_DEVICE_DETECT 3
+ `define USB_IRQ_MASK_DEVICE_DETECT_DEFAULT 0
+ `define USB_IRQ_MASK_DEVICE_DETECT_B 3
+ `define USB_IRQ_MASK_DEVICE_DETECT_T 3
+ `define USB_IRQ_MASK_DEVICE_DETECT_W 1
+ `define USB_IRQ_MASK_DEVICE_DETECT_R 3:3
+
+ `define USB_IRQ_MASK_ERR 2
+ `define USB_IRQ_MASK_ERR_DEFAULT 0
+ `define USB_IRQ_MASK_ERR_B 2
+ `define USB_IRQ_MASK_ERR_T 2
+ `define USB_IRQ_MASK_ERR_W 1
+ `define USB_IRQ_MASK_ERR_R 2:2
+
+ `define USB_IRQ_MASK_DONE 1
+ `define USB_IRQ_MASK_DONE_DEFAULT 0
+ `define USB_IRQ_MASK_DONE_B 1
+ `define USB_IRQ_MASK_DONE_T 1
+ `define USB_IRQ_MASK_DONE_W 1
+ `define USB_IRQ_MASK_DONE_R 1:1
+
+ `define USB_IRQ_MASK_SOF 0
+ `define USB_IRQ_MASK_SOF_DEFAULT 0
+ `define USB_IRQ_MASK_SOF_B 0
+ `define USB_IRQ_MASK_SOF_T 0
+ `define USB_IRQ_MASK_SOF_W 1
+ `define USB_IRQ_MASK_SOF_R 0:0
+
+`define USB_XFER_DATA 6'h14
+
+ `define USB_XFER_DATA_TX_LEN_DEFAULT 0
+ `define USB_XFER_DATA_TX_LEN_B 0
+ `define USB_XFER_DATA_TX_LEN_T 15
+ `define USB_XFER_DATA_TX_LEN_W 16
+ `define USB_XFER_DATA_TX_LEN_R 15:0
+
+`define USB_XFER_TOKEN 6'h18
+
+ `define USB_XFER_TOKEN_START 31
+ `define USB_XFER_TOKEN_START_DEFAULT 0
+ `define USB_XFER_TOKEN_START_B 31
+ `define USB_XFER_TOKEN_START_T 31
+ `define USB_XFER_TOKEN_START_W 1
+ `define USB_XFER_TOKEN_START_R 31:31
+
+ `define USB_XFER_TOKEN_IN 30
+ `define USB_XFER_TOKEN_IN_DEFAULT 0
+ `define USB_XFER_TOKEN_IN_B 30
+ `define USB_XFER_TOKEN_IN_T 30
+ `define USB_XFER_TOKEN_IN_W 1
+ `define USB_XFER_TOKEN_IN_R 30:30
+
+ `define USB_XFER_TOKEN_ACK 29
+ `define USB_XFER_TOKEN_ACK_DEFAULT 0
+ `define USB_XFER_TOKEN_ACK_B 29
+ `define USB_XFER_TOKEN_ACK_T 29
+ `define USB_XFER_TOKEN_ACK_W 1
+ `define USB_XFER_TOKEN_ACK_R 29:29
+
+ `define USB_XFER_TOKEN_PID_DATAX 28
+ `define USB_XFER_TOKEN_PID_DATAX_DEFAULT 0
+ `define USB_XFER_TOKEN_PID_DATAX_B 28
+ `define USB_XFER_TOKEN_PID_DATAX_T 28
+ `define USB_XFER_TOKEN_PID_DATAX_W 1
+ `define USB_XFER_TOKEN_PID_DATAX_R 28:28
+
+ `define USB_XFER_TOKEN_PID_BITS_DEFAULT 0
+ `define USB_XFER_TOKEN_PID_BITS_B 16
+ `define USB_XFER_TOKEN_PID_BITS_T 23
+ `define USB_XFER_TOKEN_PID_BITS_W 8
+ `define USB_XFER_TOKEN_PID_BITS_R 23:16
+
+ `define USB_XFER_TOKEN_DEV_ADDR_DEFAULT 0
+ `define USB_XFER_TOKEN_DEV_ADDR_B 9
+ `define USB_XFER_TOKEN_DEV_ADDR_T 15
+ `define USB_XFER_TOKEN_DEV_ADDR_W 7
+ `define USB_XFER_TOKEN_DEV_ADDR_R 15:9
+
+ `define USB_XFER_TOKEN_EP_ADDR_DEFAULT 0
+ `define USB_XFER_TOKEN_EP_ADDR_B 5
+ `define USB_XFER_TOKEN_EP_ADDR_T 8
+ `define USB_XFER_TOKEN_EP_ADDR_W 4
+ `define USB_XFER_TOKEN_EP_ADDR_R 8:5
+
+`define USB_RX_STAT 6'h1c
+
+ `define USB_RX_STAT_START_PEND 31
+ `define USB_RX_STAT_START_PEND_DEFAULT 0
+ `define USB_RX_STAT_START_PEND_B 31
+ `define USB_RX_STAT_START_PEND_T 31
+ `define USB_RX_STAT_START_PEND_W 1
+ `define USB_RX_STAT_START_PEND_R 31:31
+
+ `define USB_RX_STAT_CRC_ERR 30
+ `define USB_RX_STAT_CRC_ERR_DEFAULT 0
+ `define USB_RX_STAT_CRC_ERR_B 30
+ `define USB_RX_STAT_CRC_ERR_T 30
+ `define USB_RX_STAT_CRC_ERR_W 1
+ `define USB_RX_STAT_CRC_ERR_R 30:30
+
+ `define USB_RX_STAT_RESP_TIMEOUT 29
+ `define USB_RX_STAT_RESP_TIMEOUT_DEFAULT 0
+ `define USB_RX_STAT_RESP_TIMEOUT_B 29
+ `define USB_RX_STAT_RESP_TIMEOUT_T 29
+ `define USB_RX_STAT_RESP_TIMEOUT_W 1
+ `define USB_RX_STAT_RESP_TIMEOUT_R 29:29
+
+ `define USB_RX_STAT_IDLE 28
+ `define USB_RX_STAT_IDLE_DEFAULT 0
+ `define USB_RX_STAT_IDLE_B 28
+ `define USB_RX_STAT_IDLE_T 28
+ `define USB_RX_STAT_IDLE_W 1
+ `define USB_RX_STAT_IDLE_R 28:28
+
+ `define USB_RX_STAT_RESP_BITS_DEFAULT 0
+ `define USB_RX_STAT_RESP_BITS_B 16
+ `define USB_RX_STAT_RESP_BITS_T 23
+ `define USB_RX_STAT_RESP_BITS_W 8
+ `define USB_RX_STAT_RESP_BITS_R 23:16
+
+ `define USB_RX_STAT_COUNT_BITS_DEFAULT 0
+ `define USB_RX_STAT_COUNT_BITS_B 0
+ `define USB_RX_STAT_COUNT_BITS_T 15
+ `define USB_RX_STAT_COUNT_BITS_W 16
+ `define USB_RX_STAT_COUNT_BITS_R 15:0
+
+`define USB_WR_DATA 6'h20
+
+ `define USB_WR_DATA_DATA_DEFAULT 0
+ `define USB_WR_DATA_DATA_B 0
+ `define USB_WR_DATA_DATA_T 7
+ `define USB_WR_DATA_DATA_W 8
+ `define USB_WR_DATA_DATA_R 7:0
+
+`define USB_RD_DATA 6'h20
+
+ `define USB_RD_DATA_DATA_DEFAULT 0
+ `define USB_RD_DATA_DATA_B 0
+ `define USB_RD_DATA_DATA_T 7
+ `define USB_RD_DATA_DATA_W 8
+ `define USB_RD_DATA_DATA_R 7:0
+
diff --git a/verilog/rtl/usb1_host/src/phy/usb_fs_phy.v b/verilog/rtl/usb1_host/src/phy/usb_fs_phy.v
new file mode 100644
index 0000000..c7ac174
--- /dev/null
+++ b/verilog/rtl/usb1_host/src/phy/usb_fs_phy.v
@@ -0,0 +1,713 @@
+//////////////////////////////////////////////////////////////////////////////
+// SPDX-FileCopyrightText: 2021 , Dinesh Annayya
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+// SPDX-License-Identifier: Apache-2.0
+// SPDX-FileContributor: Created by Dinesh Annayya <dinesha@opencores.org>
+//
+//-----------------------------------------------------------------
+// USB Full Speed (12mbps) Phy
+// V0.2
+// Ultra-Embedded.com
+// Copyright 2015
+//
+// Email: admin@ultra-embedded.com
+//
+// License: LGPL
+//-----------------------------------------------------------------
+//
+// This source file may be used and distributed without
+// restriction provided that this copyright statement is not
+// removed from the file and that any derivative work contains
+// the original copyright notice and the associated disclaimer.
+//
+// This source file is free software; you can redistribute it
+// and/or modify it under the terms of the GNU Lesser General
+// Public License as published by the Free Software Foundation;
+// either version 2.1 of the License, or (at your option) any
+// later version.
+//
+// This source is distributed in the hope that it will be
+// useful, but WITHOUT ANY WARRANTY; without even the implied
+// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+// PURPOSE. See the GNU Lesser General Public License for more
+// details.
+//
+// You should have received a copy of the GNU Lesser General
+// Public License along with this source; if not, write to the
+// Free Software Foundation, Inc., 59 Temple Place, Suite 330,
+// Boston, MA 02111-1307 USA
+//-----------------------------------------------------------------
+
+//-----------------------------------------------------------------
+// Generated File
+//-----------------------------------------------------------------
+
+module usb_fs_phy
+(
+ // Inputs
+ input clk_i
+ ,input rstn_i
+ ,input [ 7:0] utmi_data_out_i
+ ,input utmi_txvalid_i
+ ,input [ 1:0] utmi_op_mode_i
+ ,input [ 1:0] utmi_xcvrselect_i
+ ,input utmi_termselect_i
+ ,input utmi_dppulldown_i
+ ,input utmi_dmpulldown_i
+ ,input usb_rx_rcv_i
+ ,input usb_rx_dp_i
+ ,input usb_rx_dn_i
+ ,input usb_reset_assert_i
+
+ // Outputs
+ ,output [ 7:0] utmi_data_in_o
+ ,output utmi_txready_o
+ ,output utmi_rxvalid_o
+ ,output utmi_rxactive_o
+ ,output utmi_rxerror_o
+ ,output [ 1:0] utmi_linestate_o
+ ,output usb_tx_dp_o
+ ,output usb_tx_dn_o
+ ,output usb_tx_oen_o
+ ,output usb_reset_detect_o
+ ,output usb_en_o
+);
+
+
+
+
+//-----------------------------------------------------------------
+// Wires / Registers
+//-----------------------------------------------------------------
+reg rx_en_q;
+
+// Xilinx placement pragmas:
+//synthesis attribute IOB of out_dp_q is "TRUE"
+//synthesis attribute IOB of out_dn_q is "TRUE"
+reg out_dp_q;
+reg out_dn_q;
+
+wire in_dp_w;
+wire in_dn_w;
+wire in_rx_w;
+
+wire in_j_w;
+wire in_k_w;
+wire in_se0_w;
+wire in_invalid_w;
+
+wire sample_w;
+
+wire bit_edge_w;
+wire bit_transition_w;
+
+reg [2:0] bit_count_q;
+reg [2:0] ones_count_q;
+reg [7:0] data_q;
+reg send_eop_q;
+
+reg sync_j_detected_q;
+
+wire bit_stuff_bit_w;
+wire next_is_bit_stuff_w;
+
+wire usb_reset_assert_w = usb_reset_assert_i |
+ (utmi_xcvrselect_i == 2'b00 &&
+ utmi_termselect_i == 1'b0 &&
+ utmi_op_mode_i == 2'b10 &&
+ utmi_dppulldown_i &&
+ utmi_dmpulldown_i);
+
+//-----------------------------------------------------------------
+// Resample async signals
+//-----------------------------------------------------------------
+reg rx_dp_ms;
+reg rx_dn_ms;
+reg rxd_ms;
+
+
+always @ (posedge clk_i or negedge rstn_i)
+if (!rstn_i)
+begin
+ rx_dp_ms <= 1'b0;
+ rx_dn_ms <= 1'b0;
+ rxd_ms <= 1'b0;
+end
+else
+begin
+ rx_dp_ms <= in_dp_w;
+ rx_dn_ms <= in_dn_w;
+ rxd_ms <= in_rx_w;
+end
+
+//-----------------------------------------------------------------
+// Edge Detection
+//-----------------------------------------------------------------
+reg rx_dp0_q;
+reg rx_dn0_q;
+reg rx_dp1_q;
+reg rx_dn1_q;
+reg rx_dp_q;
+reg rx_dn_q;
+reg rxd0_q;
+reg rxd1_q;
+reg rxd_q;
+
+always @ (posedge clk_i or negedge rstn_i)
+if (!rstn_i)
+begin
+ rx_dp0_q <= 1'b0;
+ rx_dn0_q <= 1'b0;
+ rx_dp1_q <= 1'b0;
+ rx_dn1_q <= 1'b0;
+ rx_dp_q <= 1'b0;
+ rx_dn_q <= 1'b0;
+ rxd0_q <= 1'b0;
+ rxd1_q <= 1'b0;
+ rxd_q <= 1'b0;
+end
+else
+begin
+ // Glitch free versions
+ if (rx_dp0_q & rx_dp1_q)
+ rx_dp_q <= 1'b1;
+ else if (!rx_dp0_q & !rx_dp1_q)
+ rx_dp_q <= 1'b0;
+
+ if (rx_dn0_q & rx_dn1_q)
+ rx_dn_q <= 1'b1;
+ else if (!rx_dn0_q & !rx_dn1_q)
+ rx_dn_q <= 1'b0;
+
+ if (rxd0_q & rxd1_q)
+ rxd_q <= 1'b1;
+ else if (!rxd0_q & !rxd1_q)
+ rxd_q <= 1'b0;
+
+ // Resyncs
+ rx_dp1_q <= rx_dp0_q;
+ rx_dp0_q <= rx_dp_ms;
+
+ rx_dn1_q <= rx_dn0_q;
+ rx_dn0_q <= rx_dn_ms;
+
+ rxd1_q <= rxd0_q;
+ rxd0_q <= rxd_ms;
+end
+
+// For Full Speed USB:
+// SE0 = D+ = 0 && D- = 0
+// J = D+ = 1 && D- = 0
+// K = D+ = 0 && D- = 1
+
+assign in_j_w = in_se0_w ? 1'b0 : rxd_q;
+assign in_k_w = in_se0_w ? 1'b0 : ~rxd_q;
+assign in_se0_w = (!rx_dp_q & !rx_dn_q);
+assign in_invalid_w = (rx_dp_q & rx_dn_q);
+
+// Line state matches tx outputs if drivers enabled
+assign utmi_linestate_o = usb_tx_oen_o ? {rx_dn_q, rx_dp_q} : {usb_tx_dn_o, usb_tx_dp_o};
+
+//-----------------------------------------------------------------
+// State Machine
+//-----------------------------------------------------------------
+localparam STATE_W = 4;
+localparam STATE_IDLE = 4'd0;
+localparam STATE_RX_DETECT = 4'd1;
+localparam STATE_RX_SYNC_J = 4'd2;
+localparam STATE_RX_SYNC_K = 4'd3;
+localparam STATE_RX_ACTIVE = 4'd4;
+localparam STATE_RX_EOP0 = 4'd5;
+localparam STATE_RX_EOP1 = 4'd6;
+localparam STATE_TX_SYNC = 4'd7;
+localparam STATE_TX_ACTIVE = 4'd8;
+localparam STATE_TX_EOP_STUFF = 4'd9;
+localparam STATE_TX_EOP0 = 4'd10;
+localparam STATE_TX_EOP1 = 4'd11;
+localparam STATE_TX_EOP2 = 4'd12;
+localparam STATE_TX_RST = 4'd13;
+
+// Current state
+reg [STATE_W-1:0] state_q;
+
+reg [STATE_W-1:0] next_state_r;
+always @ *
+begin
+ next_state_r = state_q;
+
+ case (state_q)
+ //-----------------------------------------
+ // STATE_IDLE
+ //-----------------------------------------
+ STATE_IDLE :
+ begin
+ if (in_k_w)
+ next_state_r = STATE_RX_DETECT;
+ else if (utmi_txvalid_i)
+ next_state_r = STATE_TX_SYNC;
+ else if (usb_reset_assert_w)
+ next_state_r = STATE_TX_RST;
+ end
+ //-----------------------------------------
+ // STATE_RX_DETECT
+ //-----------------------------------------
+ STATE_RX_DETECT :
+ begin
+ if (in_k_w && sample_w)
+ next_state_r = STATE_RX_SYNC_K;
+ else if (sample_w)
+ next_state_r = STATE_IDLE;
+ end
+ //-----------------------------------------
+ // STATE_RX_SYNC_J
+ //-----------------------------------------
+ STATE_RX_SYNC_J :
+ begin
+ if (in_k_w && sample_w)
+ next_state_r = STATE_RX_SYNC_K;
+ // K glitch followed by multiple J's - return to idle
+ else if ((bit_count_q == 3'd1) && sample_w)
+ next_state_r = STATE_IDLE;
+ end
+ //-----------------------------------------
+ // STATE_RX_SYNC_K
+ //-----------------------------------------
+ STATE_RX_SYNC_K :
+ begin
+ // End of SYNC field ends with 2 K's
+ // Must have seen at least 1 J state first!
+ if (sync_j_detected_q && in_k_w && sample_w)
+ next_state_r = STATE_RX_ACTIVE;
+ // No J detected since IDLE, must be an error!
+ else if (!sync_j_detected_q && in_k_w && sample_w)
+ next_state_r = STATE_IDLE;
+ else if (in_j_w && sample_w)
+ next_state_r = STATE_RX_SYNC_J;
+ end
+ //-----------------------------------------
+ // STATE_RX_ACTIVE
+ //-----------------------------------------
+ STATE_RX_ACTIVE :
+ begin
+ if (in_se0_w && sample_w)
+ next_state_r = STATE_RX_EOP0;
+ // Error!
+ else if (in_invalid_w && sample_w)
+ next_state_r = STATE_IDLE;
+ end
+ //-----------------------------------------
+ // STATE_RX_EOP0
+ //-----------------------------------------
+ STATE_RX_EOP0 :
+ begin
+ if (in_se0_w && sample_w)
+ next_state_r = STATE_RX_EOP1;
+ // Error!
+ else if (sample_w)
+ next_state_r = STATE_IDLE;
+ end
+ //-----------------------------------------
+ // STATE_RX_EOP1
+ //-----------------------------------------
+ STATE_RX_EOP1 :
+ begin
+ // Return to idle
+ if (in_j_w && sample_w)
+ next_state_r = STATE_IDLE;
+ // Error!
+ else if (sample_w)
+ next_state_r = STATE_IDLE;
+ end
+ //-----------------------------------------
+ // STATE_TX_SYNC
+ //-----------------------------------------
+ STATE_TX_SYNC :
+ begin
+ if (bit_count_q == 3'd7 && sample_w)
+ next_state_r = STATE_TX_ACTIVE;
+ end
+ //-----------------------------------------
+ // STATE_TX_ACTIVE
+ //-----------------------------------------
+ STATE_TX_ACTIVE :
+ begin
+ if (bit_count_q == 3'd7 && sample_w && (!utmi_txvalid_i || send_eop_q) && !bit_stuff_bit_w)
+ begin
+ // Bit stuff required at end of packet?
+ if (next_is_bit_stuff_w)
+ next_state_r = STATE_TX_EOP_STUFF;
+ else
+ next_state_r = STATE_TX_EOP0;
+ end
+ end
+ //-----------------------------------------
+ // STATE_TX_EOP_STUFF
+ //-----------------------------------------
+ STATE_TX_EOP_STUFF :
+ begin
+ if (sample_w)
+ next_state_r = STATE_TX_EOP0;
+ end
+ //-----------------------------------------
+ // STATE_TX_EOP0
+ //-----------------------------------------
+ STATE_TX_EOP0 :
+ begin
+ if (sample_w)
+ next_state_r = STATE_TX_EOP1;
+ end
+ //-----------------------------------------
+ // STATE_TX_EOP1
+ //-----------------------------------------
+ STATE_TX_EOP1 :
+ begin
+ if (sample_w)
+ next_state_r = STATE_TX_EOP2;
+ end
+ //-----------------------------------------
+ // STATE_TX_EOP2
+ //-----------------------------------------
+ STATE_TX_EOP2 :
+ begin
+ if (sample_w)
+ next_state_r = STATE_IDLE;
+ end
+ //-----------------------------------------
+ // STATE_TX_RST
+ //-----------------------------------------
+ STATE_TX_RST :
+ begin
+ if (!usb_reset_assert_w)
+ next_state_r = STATE_IDLE;
+ end
+ default:
+ ;
+ endcase
+end
+
+// Update state
+always @ (negedge rstn_i or posedge clk_i)
+if (!rstn_i)
+ state_q <= STATE_IDLE;
+else
+ state_q <= next_state_r;
+
+//-----------------------------------------------------------------
+// SYNC detect
+//-----------------------------------------------------------------
+always @ (posedge clk_i or negedge rstn_i)
+if (!rstn_i)
+ sync_j_detected_q <= 1'b0;
+// Reset sync detect state in IDLE
+else if (state_q == STATE_IDLE)
+ sync_j_detected_q <= 1'b0;
+// At least one J detected
+else if (state_q == STATE_RX_SYNC_J)
+ sync_j_detected_q <= 1'b1;
+
+//-----------------------------------------------------------------
+// Rx Error Detection
+//-----------------------------------------------------------------
+reg rx_error_q;
+
+always @ (posedge clk_i or negedge rstn_i)
+if (!rstn_i)
+ rx_error_q <= 1'b0;
+// Rx bit stuffing error
+else if (ones_count_q == 3'd7)
+ rx_error_q <= 1'b1;
+// Invalid line state detection
+else if (in_invalid_w && sample_w)
+ rx_error_q <= 1'b1;
+// Detect invalid SYNC sequence
+else if ((state_q == STATE_RX_SYNC_K) && !sync_j_detected_q && in_k_w && sample_w)
+ rx_error_q <= 1'b1;
+else
+ rx_error_q <= 1'b0;
+
+assign utmi_rxerror_o = rx_error_q;
+
+//-----------------------------------------------------------------
+// Edge Detector
+//-----------------------------------------------------------------
+reg rxd_last_q;
+
+always @ (posedge clk_i or negedge rstn_i)
+if (!rstn_i)
+ rxd_last_q <= 1'b0;
+else
+ rxd_last_q <= in_j_w;
+
+assign bit_edge_w = rxd_last_q ^ in_j_w;
+
+//-----------------------------------------------------------------
+// Sample Timer
+//-----------------------------------------------------------------
+reg [1:0] sample_cnt_q;
+reg adjust_delayed_q;
+
+always @ (posedge clk_i or negedge rstn_i)
+if (!rstn_i)
+begin
+ sample_cnt_q <= 2'd0;
+ adjust_delayed_q <= 1'b0;
+end
+// Delayed adjustment
+else if (adjust_delayed_q)
+ adjust_delayed_q <= 1'b0;
+else if (bit_edge_w && (sample_cnt_q != 2'd0) && (state_q < STATE_TX_SYNC))
+ sample_cnt_q <= 2'd0;
+// Can't adjust sampling point now?
+else if (bit_edge_w && (sample_cnt_q == 2'd0) && (state_q < STATE_TX_SYNC))
+begin
+ // Want to reset sampling point but need to delay adjustment by 1 cycle!
+ adjust_delayed_q <= 1'b1;
+ sample_cnt_q <= sample_cnt_q + 2'd1;
+end
+else
+ sample_cnt_q <= sample_cnt_q + 2'd1;
+
+assign sample_w = (sample_cnt_q == 2'd0);
+
+//-----------------------------------------------------------------
+// NRZI Receiver
+//-----------------------------------------------------------------
+reg rxd_last_j_q;
+
+// NRZI:
+// 0 = transition between J & K
+// 1 = same state
+// After 6 consequitive 1's, a 0 is inserted to maintain the transitions
+
+always @ (posedge clk_i or negedge rstn_i)
+if (!rstn_i)
+ rxd_last_j_q <= 1'b0;
+else if ((state_q == STATE_IDLE) || sample_w)
+ rxd_last_j_q <= in_j_w;
+
+assign bit_transition_w = sample_w ? rxd_last_j_q ^ in_j_w : 1'b0;
+
+//-----------------------------------------------------------------
+// Bit Counters
+//-----------------------------------------------------------------
+always @ (posedge clk_i or negedge rstn_i)
+if (!rstn_i)
+ ones_count_q <= 3'd1;
+// The packet starts with a double K (no transition)
+else if (state_q == STATE_IDLE)
+ ones_count_q <= 3'd1;
+// Rx
+else if ((state_q == STATE_RX_ACTIVE) && sample_w)
+begin
+ if (bit_transition_w)
+ ones_count_q <= 3'b0;
+ else
+ ones_count_q <= ones_count_q + 3'd1;
+end
+// Tx
+else if ((state_q == STATE_TX_ACTIVE) && sample_w)
+begin
+ // Toggle output data
+ if (!data_q[0] || bit_stuff_bit_w)
+ ones_count_q <= 3'b0;
+ else
+ ones_count_q <= ones_count_q + 3'd1;
+end
+
+assign bit_stuff_bit_w = (ones_count_q == 3'd6);
+assign next_is_bit_stuff_w = (ones_count_q == 3'd5) && !bit_transition_w;
+
+always @ (posedge clk_i or negedge rstn_i)
+if (!rstn_i)
+ bit_count_q <= 3'b0;
+else if ((state_q == STATE_IDLE) || (state_q == STATE_RX_SYNC_K))
+ bit_count_q <= 3'b0;
+else if ((state_q == STATE_RX_ACTIVE || state_q == STATE_TX_ACTIVE) && sample_w && !bit_stuff_bit_w)
+ bit_count_q <= bit_count_q + 3'd1;
+else if (((state_q == STATE_TX_SYNC) || (state_q == STATE_RX_SYNC_J)) && sample_w)
+ bit_count_q <= bit_count_q + 3'd1;
+
+//-----------------------------------------------------------------
+// Shift register
+//-----------------------------------------------------------------
+always @ (posedge clk_i or negedge rstn_i)
+if (!rstn_i)
+ data_q <= 8'b0;
+// Pre-load shift register with SYNC word
+else if (state_q == STATE_IDLE)
+ data_q <= 8'b00101010;
+else if ((state_q == STATE_RX_ACTIVE) && sample_w && !bit_stuff_bit_w)
+ data_q <= {~bit_transition_w, data_q[7:1]};
+else if ((state_q == STATE_TX_SYNC) && sample_w)
+begin
+ if (bit_count_q == 3'd7)
+ data_q <= utmi_data_out_i;
+ else
+ data_q <= {~bit_transition_w, data_q[7:1]};
+end
+else if ((state_q == STATE_TX_ACTIVE) && sample_w && !bit_stuff_bit_w)
+begin
+ if (bit_count_q == 3'd7)
+ data_q <= utmi_data_out_i;
+ else
+ data_q <= {~bit_transition_w, data_q[7:1]};
+end
+
+// Receive active (SYNC recieved)
+assign utmi_rxactive_o = (state_q == STATE_RX_ACTIVE);
+
+assign utmi_data_in_o = data_q;
+
+//-----------------------------------------------------------------
+// Rx Ready
+//-----------------------------------------------------------------
+reg rx_ready_q;
+
+always @ (posedge clk_i or negedge rstn_i)
+if (!rstn_i)
+ rx_ready_q <= 1'b0;
+else if ((state_q == STATE_RX_ACTIVE) && sample_w && (bit_count_q == 3'd7) && !bit_stuff_bit_w)
+ rx_ready_q <= 1'b1;
+else
+ rx_ready_q <= 1'b0;
+
+assign utmi_rxvalid_o = rx_ready_q;
+
+//-----------------------------------------------------------------
+// Tx Ready
+//-----------------------------------------------------------------
+reg tx_ready_q;
+
+always @ (posedge clk_i or negedge rstn_i)
+if (!rstn_i)
+ tx_ready_q <= 1'b0;
+else if ((state_q == STATE_TX_SYNC) && sample_w && (bit_count_q == 3'd7))
+ tx_ready_q <= 1'b1;
+else if ((state_q == STATE_TX_ACTIVE) && sample_w && !bit_stuff_bit_w && (bit_count_q == 3'd7) && !send_eop_q)
+ tx_ready_q <= 1'b1;
+else
+ tx_ready_q <= 1'b0;
+
+assign utmi_txready_o = tx_ready_q;
+
+//-----------------------------------------------------------------
+// EOP pending
+//-----------------------------------------------------------------
+always @ (negedge rstn_i or negedge clk_i)
+if (!rstn_i)
+ send_eop_q <= 1'b0;
+else if ((state_q == STATE_TX_ACTIVE) && !utmi_txvalid_i)
+ send_eop_q <= 1'b1;
+else if (state_q == STATE_TX_EOP0)
+ send_eop_q <= 1'b0;
+
+//-----------------------------------------------------------------
+// Tx
+//-----------------------------------------------------------------
+wire out_bit_w = sample_w ? data_q[0] : 1'bz;
+
+always @ (posedge clk_i or negedge rstn_i)
+if (!rstn_i)
+begin
+ out_dp_q <= 1'b0;
+ out_dn_q <= 1'b0;
+ rx_en_q <= 1'b1;
+end
+else if (state_q == STATE_IDLE)
+begin
+ // IDLE
+ out_dp_q <= 1'b1;
+ out_dn_q <= 1'b0;
+
+ if (utmi_txvalid_i || usb_reset_assert_w)
+ rx_en_q <= 1'b0;
+ else
+ rx_en_q <= 1'b1;
+end
+else if ((state_q == STATE_TX_SYNC) && sample_w)
+begin
+ out_dp_q <= data_q[0];
+ out_dn_q <= ~data_q[0];
+end
+else if ((state_q == STATE_TX_ACTIVE || state_q == STATE_TX_EOP_STUFF) && sample_w)
+begin
+ // 0 = toggle, 1 = hold
+ if (!data_q[0] || bit_stuff_bit_w)
+ begin
+ out_dp_q <= ~out_dp_q;
+ out_dn_q <= ~out_dn_q;
+ end
+end
+else if ((state_q == STATE_TX_EOP0 || state_q == STATE_TX_EOP1) && sample_w)
+begin
+ // SE0
+ out_dp_q <= 1'b0;
+ out_dn_q <= 1'b0;
+end
+else if ((state_q == STATE_TX_EOP2) && sample_w)
+begin
+ // IDLE
+ out_dp_q <= 1'b1;
+ out_dn_q <= 1'b0;
+
+ // Set bus to input
+ rx_en_q <= 1'b1;
+end
+else if (state_q == STATE_TX_RST)
+begin
+ // SE0
+ out_dp_q <= 1'b0;
+ out_dn_q <= 1'b0;
+end
+
+//-----------------------------------------------------------------
+// Reset detection
+//-----------------------------------------------------------------
+reg [6:0] se0_cnt_q;
+
+always @ (posedge clk_i or negedge rstn_i)
+if (!rstn_i)
+ se0_cnt_q <= 7'b0;
+else if (in_se0_w)
+begin
+ if (se0_cnt_q != 7'd127)
+ se0_cnt_q <= se0_cnt_q + 7'd1;
+end
+else
+ se0_cnt_q <= 7'b0;
+
+assign usb_reset_detect_o = (se0_cnt_q == 7'd127);
+
+//-----------------------------------------------------------------
+// Transceiver Interface
+//-----------------------------------------------------------------
+// Tx output enable (active low)
+assign usb_tx_oen_o = rx_en_q;
+
+// Tx +/-
+assign usb_tx_dp_o = out_dp_q;
+assign usb_tx_dn_o = out_dn_q;
+
+// Receive D+/D-
+assign in_dp_w = usb_rx_dp_i;
+assign in_dn_w = usb_rx_dn_i;
+
+// Receive data
+assign in_rx_w = usb_rx_rcv_i;
+
+// USB device pull-up enable
+assign usb_en_o = utmi_termselect_i;
+
+
+endmodule
diff --git a/verilog/rtl/usb1_host/src/phy/usb_transceiver.v b/verilog/rtl/usb1_host/src/phy/usb_transceiver.v
new file mode 100644
index 0000000..6a3575b
--- /dev/null
+++ b/verilog/rtl/usb1_host/src/phy/usb_transceiver.v
@@ -0,0 +1,187 @@
+//////////////////////////////////////////////////////////////////////////////
+// SPDX-FileCopyrightText: 2021 , Dinesh Annayya
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+// SPDX-License-Identifier: Apache-2.0
+// SPDX-FileContributor: Created by Dinesh Annayya <dinesha@opencores.org>
+//
+//-----------------------------------------------------------------
+// USB Full Speed (12mbps) Phy
+// V0.2
+// Ultra-Embedded.com
+// Copyright 2015
+//
+// Email: admin@ultra-embedded.com
+//
+// License: LGPL
+//-----------------------------------------------------------------
+//
+// This source file may be used and distributed without
+// restriction provided that this copyright statement is not
+// removed from the file and that any derivative work contains
+// the original copyright notice and the associated disclaimer.
+//
+// This source file is free software; you can redistribute it
+// and/or modify it under the terms of the GNU Lesser General
+// Public License as published by the Free Software Foundation;
+// either version 2.1 of the License, or (at your option) any
+// later version.
+//
+// This source is distributed in the hope that it will be
+// useful, but WITHOUT ANY WARRANTY; without even the implied
+// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+// PURPOSE. See the GNU Lesser General Public License for more
+// details.
+//
+// You should have received a copy of the GNU Lesser General
+// Public License along with this source; if not, write to the
+// Free Software Foundation, Inc., 59 Temple Place, Suite 330,
+// Boston, MA 02111-1307 USA
+//-----------------------------------------------------------------
+
+//-----------------------------------------------------------------
+// Generated File
+//-----------------------------------------------------------------
+
+module usb_transceiver
+(
+ // Inputs
+ input usb_phy_tx_dp_i,
+ input usb_phy_tx_dn_i,
+ input usb_phy_tx_oen_i,
+ input mode_i,
+
+ output reg out_dp,
+ output reg out_dn,
+ output out_tx_oen,
+
+ // Outputs
+ input in_dp,
+ input in_dn,
+
+ output usb_phy_rx_rcv_o,
+ output usb_phy_rx_dp_o,
+ output usb_phy_rx_dn_o
+);
+
+
+
+//-----------------------------------------------------------------
+// Module: usb_transceiver
+// Emulate standard USB PHY interface and produce a D+/D- outputs.
+// Allows direct connection of USB port to FPGA.
+// Limitations:
+// As no differential amplifier present, no common mode noise
+// rejection occurs.
+// Unlikely to work well with longer connections!
+//-----------------------------------------------------------------
+
+//-----------------------------------------------------------------
+// Wires
+//-----------------------------------------------------------------
+
+//-----------------------------------------------------------------
+// Assignments
+//-----------------------------------------------------------------
+
+// D+/D- Tristate buffers
+//assign usb_dp_io = (usb_phy_tx_oen_i == 1'b0) ? out_dp : 1'bz;
+//assign usb_dn_io = (usb_phy_tx_oen_i == 1'b0) ? out_dn : 1'bz;
+//
+assign out_tx_oen = usb_phy_tx_oen_i;
+
+// Receive D+/D-
+assign usb_phy_rx_dp_o = in_dp;
+assign usb_phy_rx_dn_o = in_dn;
+
+// Receive output
+assign usb_phy_rx_rcv_o = (in_dp == 1'b1 && in_dn == 1'b0) ? 1'b1 : 1'b0;
+
+// PHY Transmit Mode:
+// When phy_tx_mode_i is '0' the outputs are encoded as:
+// vmo_i, vpo_i
+// 0 0 Differential Logic '0'
+// 0 1 Differential Logic '1'
+// 1 0 Single Ended '0'
+// 1 1 Single Ended '0'
+// When phy_tx_mode_i is '1' the outputs are encoded as:
+// vmo_i, vpo_i
+// 0 0 Single Ended '0'
+// 0 1 Differential Logic '1'
+// 1 0 Differential Logic '0'
+// 1 1 Illegal State
+always_comb
+begin : MUX
+// Logic "0"
+out_dp = 1'b0;
+out_dn = 1'b1;
+ case(mode_i)
+ 1'b0:
+ begin
+ if (usb_phy_tx_dp_i == 1'b0 && usb_phy_tx_dn_i == 1'b0)
+ begin
+ // Logic "0"
+ out_dp = 1'b0;
+ out_dn = 1'b1;
+ end
+ else if (usb_phy_tx_dp_i == 1'b0 && usb_phy_tx_dn_i == 1'b1)
+ begin
+ // SE0 (both low)
+ out_dp = 1'b0;
+ out_dn = 1'b0;
+ end
+ else if (usb_phy_tx_dp_i == 1'b1 && usb_phy_tx_dn_i == 1'b0)
+ begin
+ // Logic "1"
+ out_dp = 1'b1;
+ out_dn = 1'b0;
+ end
+ else if (usb_phy_tx_dp_i == 1'b1 && usb_phy_tx_dn_i == 1'b1)
+ begin
+ // SE0 (both low)
+ out_dp = 1'b0;
+ out_dn = 1'b0;
+ end
+ end
+ 1'b1 :
+ begin
+ if (usb_phy_tx_dp_i == 1'b0 && usb_phy_tx_dn_i == 1'b0)
+ begin
+ // SE0 (both low)
+ out_dp = 1'b0;
+ out_dn = 1'b0;
+ end
+ else if (usb_phy_tx_dp_i == 1'b0 && usb_phy_tx_dn_i == 1'b1)
+ begin
+ // Logic "0"
+ out_dp = 1'b0;
+ out_dn = 1'b1;
+ end
+ else if (usb_phy_tx_dp_i == 1'b1 && usb_phy_tx_dn_i == 1'b0)
+ begin
+ // Logic "1"
+ out_dp = 1'b1;
+ out_dn = 1'b0;
+ end
+ else if (usb_phy_tx_dp_i == 1'b1 && usb_phy_tx_dn_i == 1'b1)
+ begin
+ // Illegal
+ out_dp = 1'b1;
+ out_dn = 1'b1;
+ end
+ end
+ endcase
+end
+
+
+endmodule
diff --git a/verilog/rtl/usb1_host/src/top/usb1_host.sv b/verilog/rtl/usb1_host/src/top/usb1_host.sv
new file mode 100644
index 0000000..1de70d4
--- /dev/null
+++ b/verilog/rtl/usb1_host/src/top/usb1_host.sv
@@ -0,0 +1,238 @@
+//////////////////////////////////////////////////////////////////////////////
+// SPDX-FileCopyrightText: 2021 , Dinesh Annayya
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+// SPDX-License-Identifier: Apache-2.0
+// SPDX-FileContributor: Created by Dinesh Annayya <dinesha@opencores.org>
+//
+//////////////////////////////////////////////////////////////////////
+//// ////
+//// USB1.1 HOST Controller + PHY ////
+//// ////
+//// This file is part of the YIFive cores project ////
+//// https://github.com/dineshannayya/yifive_r0.git ////
+//// USB1 Core from github.com/ultraembedded/core_usb_host ////
+//// USBB Phy from github.com/ultraembedded/core_usb_fs_phy.git ////
+//// ////
+//// Description ////
+//// Following Modification are Done ////
+//// 1. Integrated the Wishbone Interface ////
+//// 2. WishBone interface made async w.r.t usb clock ////
+//// 3. usb1 core Axi logic is modified to normal Register ////
+//// read/write I/F ////
+//// ////
+//// This module integrate following sub module ////
+//// 1. async_wb : Async wishbone interface does the wishbone ////
+//// to usbclk clock synchronization ////
+//// 2. usb1_core: usb1 core ////
+//// 3. usb1_host : usb phy ////
+//// ////
+//// Assumptiom: usb_clk is 48Mhz ////
+//// ////
+//// To Do: ////
+//// nothing ////
+//// ////
+//// Author(s): ////
+//// - Dinesh Annayya, dinesha@opencores.org ////
+//// ////
+//// Revision : ////
+//// ////
+//////////////////////////////////////////////////////////////////////
+
+module usb1_host (
+ input logic usb_clk_i ,
+ input logic usb_rstn_i ,
+
+ // USB D+/D-
+ input in_dp ,
+ input in_dn ,
+
+ input out_dp ,
+ input out_dn ,
+ output out_tx_oen,
+
+ // Master Port
+ input logic wbm_rst_n , // Regular Reset signal
+ input logic wbm_clk_i , // System clock
+ input logic wbm_stb_i , // strobe/request
+ input logic [5:0] wbm_adr_i , // address
+ input logic wbm_we_i , // write
+ input logic [31:0] wbm_dat_i , // data output
+ input logic [3:0] wbm_sel_i , // byte enable
+ output logic [31:0] wbm_dat_o , // data input
+ output logic wbm_ack_o , // acknowlegement
+ output logic wbm_err_o , // error
+
+ // Outputs
+ output usb_intr_o
+
+
+ );
+
+ logic [7:0] utmi_data_in_i;
+ logic utmi_txready_i;
+ logic utmi_rxvalid_i;
+ logic utmi_rxactive_i;
+ logic utmi_rxerror_i;
+ logic [1:0] utmi_linestate_i;
+
+ logic [7:0] utmi_data_out_o;
+ logic utmi_txvalid_o;
+ logic [1:0] utmi_op_mode_o;
+ logic [1:0] utmi_xcvrselect_o;
+ logic utmi_termselect_o;
+ logic utmi_dppulldown_o;
+ logic utmi_dmpulldown_o;
+ logic usb_pads_tx_dp_w;
+ logic usb_pads_tx_oen_w;
+ logic usb_pads_rx_dn_w;
+ logic usb_pads_tx_dn_w;
+ logic usb_pads_rx_rcv_w;
+ logic usb_pads_rx_dp_w;
+ logic usb_xcvr_mode_w = 1'h1;
+
+ // Reg Bus Interface Signal
+ logic reg_cs;
+ logic reg_wr;
+ logic [5:0] reg_addr;
+ logic [31:0] reg_wdata;
+ logic [3:0] reg_be;
+
+ // Outputs
+ logic [31:0] reg_rdata;
+ logic reg_ack;
+
+
+
+async_wb #(.AW (6))
+ u_async_wb(
+
+ // Master Port
+ .wbm_rst_n (wbm_rst_n ), // Regular Reset signal
+ .wbm_clk_i (wbm_clk_i ), // System clock
+ .wbm_cyc_i (wbm_stb_i ), // strobe/request
+ .wbm_stb_i (wbm_stb_i ), // strobe/request
+ .wbm_adr_i (wbm_adr_i ), // address
+ .wbm_we_i (wbm_we_i ), // write
+ .wbm_dat_i (wbm_dat_i ), // data output
+ .wbm_sel_i (wbm_sel_i ), // byte enable
+ .wbm_dat_o (wbm_dat_o ), // data input
+ .wbm_ack_o (wbm_ack_o ), // acknowlegement
+ .wbm_err_o (wbm_err_o ), // error
+
+ // Slave Port
+ .wbs_rst_n (usb_rstn_i ), // Regular Reset signal
+ .wbs_clk_i (usb_clk_i ), // System clock
+ .wbs_cyc_o ( ), // strobe/request
+ .wbs_stb_o (reg_cs ), // strobe/request
+ .wbs_adr_o (reg_addr ), // address
+ .wbs_we_o (reg_wr ), // write
+ .wbs_dat_o (reg_wdata ), // data output
+ .wbs_sel_o (reg_be ), // byte enable
+ .wbs_dat_i (reg_rdata ), // data input
+ .wbs_ack_i (reg_ack ), // acknowlegement
+ .wbs_err_i (1'b0 ) // error
+
+ );
+
+usbh_core u_core (
+ // Inputs
+ .clk_i (usb_clk_i ),
+ .rstn_i (usb_rstn_i ),
+
+ .reg_cs (reg_cs ),
+ .reg_wr (reg_wr ),
+ .reg_addr (reg_addr ),
+ .reg_wdata (reg_wdata ),
+ .reg_be (reg_be ),
+
+ // Outputs
+ .reg_rdata (reg_rdata ),
+ .reg_ack (reg_ack ),
+
+ // Outputs
+ .intr_o (usb_intr_o ),
+
+ .utmi_data_in_i (utmi_data_in_i ),
+ .utmi_rxvalid_i (utmi_rxvalid_i ),
+ .utmi_rxactive_i (utmi_rxactive_i ),
+ .utmi_rxerror_i (utmi_rxerror_i ),
+ .utmi_linestate_i (utmi_linestate_i ),
+
+ .utmi_txready_i (utmi_txready_i ),
+ .utmi_data_out_o (utmi_data_out_o ),
+ .utmi_txvalid_o (utmi_txvalid_o ),
+
+ .utmi_op_mode_o (utmi_op_mode_o ),
+ .utmi_xcvrselect_o (utmi_xcvrselect_o ),
+ .utmi_termselect_o (utmi_termselect_o ),
+ .utmi_dppulldown_o (utmi_dppulldown_o ),
+ .utmi_dmpulldown_o (utmi_dmpulldown_o )
+);
+
+
+
+usb_fs_phy u_phy(
+ // Inputs
+ .clk_i (usb_clk_i ),
+ .rstn_i (usb_rstn_i ),
+ .utmi_data_out_i (utmi_data_out_o ),
+ .utmi_txvalid_i (utmi_txvalid_o ),
+ .utmi_op_mode_i (utmi_op_mode_o ),
+ .utmi_xcvrselect_i (utmi_xcvrselect_o ),
+ .utmi_termselect_i (utmi_termselect_o ),
+ .utmi_dppulldown_i (utmi_dppulldown_o ),
+ .utmi_dmpulldown_i (utmi_dmpulldown_o ),
+ .usb_rx_rcv_i (usb_pads_rx_rcv_w ),
+ .usb_rx_dp_i (usb_pads_rx_dp_w ),
+ .usb_rx_dn_i (usb_pads_rx_dn_w ),
+ .usb_reset_assert_i ( 1'b0 ),
+
+ // Outputs
+ .utmi_data_in_o (utmi_data_in_i ),
+ .utmi_txready_o (utmi_txready_i ),
+ .utmi_rxvalid_o (utmi_rxvalid_i ),
+ .utmi_rxactive_o (utmi_rxactive_i ),
+ .utmi_rxerror_o (utmi_rxerror_i ),
+ .utmi_linestate_o (utmi_linestate_i ),
+ .usb_tx_dp_o (usb_pads_tx_dp_w ),
+ .usb_tx_dn_o (usb_pads_tx_dn_w ),
+ .usb_tx_oen_o (usb_pads_tx_oen_w ),
+ .usb_reset_detect_o ( ),
+ .usb_en_o ( )
+ );
+
+
+ usb_transceiver u_usb_xcvr (
+ // Inputs
+ .usb_phy_tx_dp_i (usb_pads_tx_dp_w ),
+ .usb_phy_tx_dn_i (usb_pads_tx_dn_w ),
+ .usb_phy_tx_oen_i (usb_pads_tx_oen_w ),
+ .mode_i (usb_xcvr_mode_w ),
+
+ .out_dp (out_dp ),
+ .out_dn (out_dn ),
+ .out_tx_oen (out_tx_oen ),
+
+ .in_dp (in_dp ),
+ .in_dn (in_dn ),
+
+
+ // Outputs
+ .usb_phy_rx_rcv_o (usb_pads_rx_rcv_w ),
+ .usb_phy_rx_dp_o (usb_pads_rx_dp_w ),
+ .usb_phy_rx_dn_o (usb_pads_rx_dn_w )
+);
+
+
+endmodule
diff --git a/verilog/rtl/user_project_wrapper.v b/verilog/rtl/user_project_wrapper.v
new file mode 100644
index 0000000..c39bf3b
--- /dev/null
+++ b/verilog/rtl/user_project_wrapper.v
@@ -0,0 +1,1632 @@
+//////////////////////////////////////////////////////////////////////////////
+// SPDX-FileCopyrightText: 2021 , Dinesh Annayya
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+// SPDX-License-Identifier: Apache-2.0
+// SPDX-FileContributor: Created by Dinesh Annayya <dinesha@opencores.org>
+//
+//////////////////////////////////////////////////////////////////////
+//// ////
+//// Digital core ////
+//// ////
+//// This file is part of the riscduino cores project ////
+//// https://github.com/dineshannayya/riscduino.git ////
+//// ////
+//// Description ////
+//// This is digital core and integrate all the main block ////
+//// here. Following block are integrated here ////
+//// 1. Risc V Core ////
+//// 2. Quad SPI Master ////
+//// 3. Wishbone Cross Bar ////
+//// 4. UART ////
+//// 5, USB 1.1 ////
+//// 6. SPI Master (Single) ////
+//// 7. TCM SRAM 2KB ////
+//// 8. 2KB icache and 2KB dcache ////
+//// 8. 6 Channel ADC ////
+//// 9. Pinmux with GPIO and 6 PWM ////
+//// ////
+//// To Do: ////
+//// nothing ////
+//// ////
+//// Author(s): ////
+//// - Dinesh Annayya, dinesha@opencores.org ////
+//// ////
+//// Revision : ////
+//// 0.1 - 16th Feb 2021, Dinesh A ////
+//// Initial integration with Risc-V core + ////
+//// Wishbone Cross Bar + SPI Master ////
+//// 0.2 - 17th June 2021, Dinesh A ////
+//// 1. In risc core, wishbone and core domain is ////
+//// created ////
+//// 2. cpu and rtc clock are generated in glbl reg block ////
+//// 3. in wishbone interconnect:- Stagging flop are added ////
+//// at interface to break wishbone timing path ////
+//// 4. buswidth warning are fixed inside spi_master ////
+//// modified rtl files are ////
+//// verilog/rtl/digital_core/src/digital_core.sv ////
+//// verilog/rtl/digital_core/src/glbl_cfg.sv ////
+//// verilog/rtl/lib/wb_stagging.sv ////
+//// verilog/rtl/syntacore/scr1/src/top/scr1_dmem_wb.sv ////
+//// verilog/rtl/syntacore/scr1/src/top/scr1_imem_wb.sv ////
+//// verilog/rtl/syntacore/scr1/src/top/scr1_top_wb.sv ////
+//// verilog/rtl/user_project_wrapper.v ////
+//// verilog/rtl/wb_interconnect/src/wb_interconnect.sv ////
+//// verilog/rtl/spi_master/src/spim_clkgen.sv ////
+//// verilog/rtl/spi_master/src/spim_ctrl.sv ////
+//// 0.3 - 20th June 2021, Dinesh A ////
+//// 1. uart core is integrated ////
+//// 2. 3rd Slave ported added to wishbone interconnect ////
+//// 0.4 - 25th June 2021, Dinesh A ////
+//// Moved the pad logic inside sdram,spi,uart block to ////
+//// avoid logic at digital core level ////
+//// 0.5 - 25th June 2021, Dinesh A ////
+//// Since carvel gives only 16MB address space for user ////
+//// space, we have implemented indirect address select ////
+//// with 8 bit bank select given inside wb_host ////
+//// core Address = {Bank_Sel[7:0], Wb_Address[23:0] ////
+//// caravel user address space is ////
+//// 0x3000_0000 to 0x30FF_FFFF ////
+//// 0.6 - 27th June 2021, Dinesh A ////
+//// Digital core level tie are moved inside IP to avoid ////
+//// power hook up at core level ////
+//// u_risc_top - test_mode & test_rst_n ////
+//// u_intercon - s*_wbd_err_i ////
+//// unused wb_cti_i is removed from u_sdram_ctrl ////
+//// 0.7 - 28th June 2021, Dinesh A ////
+//// wb_interconnect master port are interchanged for ////
+//// better physical placement. ////
+//// m0 - External HOST ////
+//// m1 - RISC IMEM ////
+//// m2 - RISC DMEM ////
+//// 0.8 - 6th July 2021, Dinesh A ////
+//// For Better SDRAM Interface timing we have taping ////
+//// sdram_clock goint to io_out[29] directly from ////
+//// global register block, this help in better SDRAM ////
+//// interface timing control ////
+//// 0.9 - 7th July 2021, Dinesh A ////
+//// Removed 2 Unused port connection io_in[31:30] to ////
+//// spi_master to avoid lvs issue ////
+//// 1.0 - 28th July 2021, Dinesh A ////
+//// i2cm integrated part of uart_i2cm module, ////
+//// due to number of IO pin limitation, ////
+//// Only UART OR I2C selected based on config mode ////
+//// 1.1 - 1st Aug 2021, Dinesh A ////
+//// usb1.1 host integrated part of uart_i2cm_usb module,////
+//// due to number of IO pin limitation, ////
+//// Only UART/I2C/USB selected based on config mode ////
+//// 1.2 - 29th Sept 2021, Dinesh.A ////
+//// 1. copied the repo from yifive and renames as ////
+//// riscdunino ////
+//// 2. Removed the SDRAM controlled ////
+//// 3. Added PinMux ////
+//// 4. Added SAR ADC for 6 channel ////
+//// 1.3 - 30th Sept 2021, Dinesh.A ////
+//// 2KB SRAM Interface added to RISC Core ////
+//// 1.4 - 13th Oct 2021, Dinesh A ////
+//// Basic verification and Synthesis cleanup ////
+//// 1.5 - 6th Nov 2021, Dinesh A ////
+//// Clock Skew block moved inside respective block due ////
+//// to top-level power hook-up challenges for small IP ////
+//// 1.6 Nov 14, 2021, Dinesh A ////
+//// Major bug, clock divider inside the wb_host reset ////
+//// connectivity open is fixed ////
+//// 1.7 Nov 15, 2021, Dinesh A ////
+//// Bug fix in clk_ctrl High/Low counter width ////
+//// Removed sram_clock ////
+//// 1.8 Nov 23, 2021, Dinesh A ////
+//// Three Chip Specific Signature added at PinMux Reg ////
+//// reg_22,reg_23,reg_24 ////
+//// 1.9 Dec 11, 2021, Dinesh A ////
+//// 2 x 2K SRAM added into Wishbone Interface ////
+//// Temporary ADC block removed ////
+//// 2.0 Dec 14, 2021, Dinesh A ////
+//// Added two more 2K SRAM added into Wishbone Interface ////
+//// 2.1 Dec 16, 2021, Dinesh A ////
+//// 1.4 MBIST controller changed to single one ////
+//// 2.Added one more SRAM to TCM memory ////
+//// 3.WishBone Interconnect chang to take care mbist changes////
+//// 4.Pinmux change to take care of mbist changes ////
+//// 2.2 Dec 20, 2021, Dinesh A ////
+//// 1. MBIST design issue fix for yosys ////
+//// 2. Full chip Timing and Transition clean-up ////
+//// 2.3 Dec 24, 2021, Dinesh A ////
+//// UART Master added with message handler at wb_host ////
+//// 2.4 Jan 01, 2022, Dinesh A ////
+//// LA[0] is added as soft reset option at wb_port ////
+//// 2.5 Jan 06, 2022, Dinesh A ////
+//// TCM RAM Bug fix inside syntacore ////
+//// 2.6 Jan 08, 2022, Dinesh A ////
+//// Pinmux Interrupt Logic change ////
+//// 3.0 Jan 14, 2022, Dinesh A ////
+//// Moving from riscv core from syntacore/scr1 to ////
+//// yfive/ycr1 on sankranti 2022 (A Hindu New Year) ////
+//// 3.1 Jan 15, 2022, Dinesh A ////
+//// Major changes in qspim logic to handle special mode ////
+//// 3.2 Feb 02, 2022, Dinesh A ////
+//// Bug fix around icache/dcache and wishbone burst ////
+//// access clean-up ////
+//// 3.3 Feb 08, 2022, Dinesh A ////
+//// support added spisram support in qspim ip ////
+//// There are 4 chip select available in qspim ////
+//// CS#0/CS#1 targeted for SPI FLASH ////
+//// CS#2/CS#3 targeted for SPI SRAM ////
+//// 3.4 Feb 14, 2022, Dinesh A ////
+//// burst mode supported added in imem buffer inside ////
+//// riscv core ////
+//// We have created seperate repo from this onwards ////
+//// SRAM based SOC is spin-out to ////
+//// dineshannayya/riscduino_sram.git ////
+//// This repo will remove mbist + SRAM and RISC SRAM will be ////
+//// replaced with DFRAM ////
+//////////////////////////////////////////////////////////////////////
+//// ////
+//// Copyright (C) 2000 Authors and OPENCORES.ORG ////
+//// ////
+//// This source file may be used and distributed without ////
+//// restriction provided that this copyright statement is not ////
+//// removed from the file and that any derivative work contains ////
+//// the original copyright notice and the associated disclaimer. ////
+//// ////
+//// This source file is free software; you can redistribute it ////
+//// and/or modify it under the terms of the GNU Lesser General ////
+//// Public License as published by the Free Software Foundation; ////
+//// either version 2.1 of the License, or (at your option) any ////
+//// later version. ////
+//// ////
+//// This source is distributed in the hope that it will be ////
+//// useful, but WITHOUT ANY WARRANTY; without even the implied ////
+//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR ////
+//// PURPOSE. See the GNU Lesser General Public License for more ////
+//// details. ////
+//// ////
+//// You should have received a copy of the GNU Lesser General ////
+//// Public License along with this source; if not, download it ////
+//// from http://www.opencores.org/lgpl.shtml ////
+//// ////
+//////////////////////////////////////////////////////////////////////
+
+
+module user_project_wrapper (
+`ifdef USE_POWER_PINS
+ inout vdda1, // User area 1 3.3V supply
+ inout vdda2, // User area 2 3.3V supply
+ inout vssa1, // User area 1 analog ground
+ inout vssa2, // User area 2 analog ground
+ inout vccd1, // User area 1 1.8V supply
+ inout vccd2, // User area 2 1.8v supply
+ inout vssd1, // User area 1 digital ground
+ inout vssd2, // User area 2 digital ground
+`endif
+ input wire wb_clk_i , // System clock
+ input wire user_clock2 , // user Clock
+ input wire wb_rst_i , // Regular Reset signal
+
+ input wire wbs_cyc_i , // strobe/request
+ input wire wbs_stb_i , // strobe/request
+ input wire [WB_WIDTH-1:0] wbs_adr_i , // address
+ input wire wbs_we_i , // write
+ input wire [WB_WIDTH-1:0] wbs_dat_i , // data output
+ input wire [3:0] wbs_sel_i , // byte enable
+ output wire [WB_WIDTH-1:0] wbs_dat_o , // data input
+ output wire wbs_ack_o , // acknowlegement
+
+ // Analog (direct connection to GPIO pad---use with caution)
+ // Note that analog I/O is not available on the 7 lowest-numbered
+ // GPIO pads, and so the analog_io indexing is offset from the
+ // GPIO indexing by 7 (also upper 2 GPIOs do not have analog_io).
+ inout [28:0] analog_io,
+
+ // Logic Analyzer Signals
+ input wire [127:0] la_data_in ,
+ output wire [127:0] la_data_out ,
+ input wire [127:0] la_oenb ,
+
+
+ // IOs
+ input wire [37:0] io_in ,
+ output wire [37:0] io_out ,
+ output wire [37:0] io_oeb ,
+
+ output wire [2:0] user_irq
+
+);
+
+//---------------------------------------------------
+// Local Parameter Declaration
+// --------------------------------------------------
+
+parameter BIST_NO_SRAM = 4; // NO of MBIST MEMORY
+parameter SDR_DW = 8; // SDR Data Width
+parameter SDR_BW = 1; // SDR Byte Width
+parameter WB_WIDTH = 32; // WB ADDRESS/DARA WIDTH
+parameter BIST1_ADDR_WD = 11; // 512x32 SRAM
+parameter BIST_DATA_WD = 32;
+
+//---------------------------------------------------------------------
+// Wishbone Risc V Dcache Memory Interface
+//---------------------------------------------------------------------
+wire wbd_riscv_dcache_stb_i ; // strobe/request
+wire [WB_WIDTH-1:0] wbd_riscv_dcache_adr_i ; // address
+wire wbd_riscv_dcache_we_i ; // write
+wire [WB_WIDTH-1:0] wbd_riscv_dcache_dat_i ; // data output
+wire [3:0] wbd_riscv_dcache_sel_i ; // byte enable
+wire [9:0] wbd_riscv_dcache_bl_i ; // burst length
+wire wbd_riscv_dcache_bry_i ; // burst ready
+wire [WB_WIDTH-1:0] wbd_riscv_dcache_dat_o ; // data input
+wire wbd_riscv_dcache_ack_o ; // acknowlegement
+wire wbd_riscv_dcache_lack_o ; // last burst acknowlegement
+wire wbd_riscv_dcache_err_o ; // error
+
+// CACHE SRAM Memory I/F
+wire dcache_mem_clk0 ; // CLK
+wire dcache_mem_csb0 ; // CS#
+wire dcache_mem_web0 ; // WE#
+wire [8:0] dcache_mem_addr0 ; // Address
+wire [3:0] dcache_mem_wmask0 ; // WMASK#
+wire [31:0] dcache_mem_din0 ; // Write Data
+wire [31:0] dcache_mem_dout0 ; // Read Data
+
+// SRAM-0 PORT-1, IMEM I/F
+wire dcache_mem_clk1 ; // CLK
+wire dcache_mem_csb1 ; // CS#
+wire [8:0] dcache_mem_addr1 ; // Address
+wire [31:0] dcache_mem_dout1 ; // Read Data
+//---------------------------------------------------------------------
+// Wishbone Risc V Icache Memory Interface
+//---------------------------------------------------------------------
+wire wbd_riscv_icache_stb_i ; // strobe/request
+wire [WB_WIDTH-1:0] wbd_riscv_icache_adr_i ; // address
+wire wbd_riscv_icache_we_i ; // write
+wire [3:0] wbd_riscv_icache_sel_i ; // byte enable
+wire [9:0] wbd_riscv_icache_bl_i ; // burst length
+wire wbd_riscv_icache_bry_i ; // burst ready
+wire [WB_WIDTH-1:0] wbd_riscv_icache_dat_o ; // data input
+wire wbd_riscv_icache_ack_o ; // acknowlegement
+wire wbd_riscv_icache_lack_o ; // last burst acknowlegement
+wire wbd_riscv_icache_err_o ; // error
+
+// CACHE SRAM Memory I/F
+wire icache_mem_clk0 ; // CLK
+wire icache_mem_csb0 ; // CS#
+wire icache_mem_web0 ; // WE#
+wire [8:0] icache_mem_addr0 ; // Address
+wire [3:0] icache_mem_wmask0 ; // WMASK#
+wire [31:0] icache_mem_din0 ; // Write Data
+// wire [31:0] icache_mem_dout0 ; // Read Data
+
+// SRAM-0 PORT-1, IMEM I/F
+wire icache_mem_clk1 ; // CLK
+wire icache_mem_csb1 ; // CS#
+wire [8:0] icache_mem_addr1 ; // Address
+wire [31:0] icache_mem_dout1 ; // Read Data
+
+//---------------------------------------------------------------------
+// RISC V Wishbone Data Memory Interface
+//---------------------------------------------------------------------
+wire wbd_riscv_dmem_stb_i ; // strobe/request
+wire [WB_WIDTH-1:0] wbd_riscv_dmem_adr_i ; // address
+wire wbd_riscv_dmem_we_i ; // write
+wire [WB_WIDTH-1:0] wbd_riscv_dmem_dat_i ; // data output
+wire [3:0] wbd_riscv_dmem_sel_i ; // byte enable
+wire [WB_WIDTH-1:0] wbd_riscv_dmem_dat_o ; // data input
+wire wbd_riscv_dmem_ack_o ; // acknowlegement
+wire wbd_riscv_dmem_err_o ; // error
+
+//---------------------------------------------------------------------
+// WB HOST Interface
+//---------------------------------------------------------------------
+wire wbd_int_cyc_i ; // strobe/request
+wire wbd_int_stb_i ; // strobe/request
+wire [WB_WIDTH-1:0] wbd_int_adr_i ; // address
+wire wbd_int_we_i ; // write
+wire [WB_WIDTH-1:0] wbd_int_dat_i ; // data output
+wire [3:0] wbd_int_sel_i ; // byte enable
+wire [WB_WIDTH-1:0] wbd_int_dat_o ; // data input
+wire wbd_int_ack_o ; // acknowlegement
+wire wbd_int_err_o ; // error
+//---------------------------------------------------------------------
+// SPI Master Wishbone Interface
+//---------------------------------------------------------------------
+wire wbd_spim_stb_o ; // strobe/request
+wire [WB_WIDTH-1:0] wbd_spim_adr_o ; // address
+wire wbd_spim_we_o ; // write
+wire [WB_WIDTH-1:0] wbd_spim_dat_o ; // data output
+wire [3:0] wbd_spim_sel_o ; // byte enable
+wire [9:0] wbd_spim_bl_o ; // Burst count
+wire wbd_spim_bry_o ; // Busrt Ready
+wire wbd_spim_cyc_o ;
+wire [WB_WIDTH-1:0] wbd_spim_dat_i ; // data input
+wire wbd_spim_ack_i ; // acknowlegement
+wire wbd_spim_lack_i ; // Last acknowlegement
+wire wbd_spim_err_i ; // error
+
+//---------------------------------------------------------------------
+// SPI Master Wishbone Interface
+//---------------------------------------------------------------------
+wire wbd_adc_stb_o ;
+wire [7:0] wbd_adc_adr_o ;
+wire wbd_adc_we_o ; // 1 - Write, 0 - Read
+wire [WB_WIDTH-1:0] wbd_adc_dat_o ;
+wire [WB_WIDTH/8-1:0] wbd_adc_sel_o ; // Byte enable
+wire wbd_adc_cyc_o ;
+wire [2:0] wbd_adc_cti_o ;
+wire [WB_WIDTH-1:0] wbd_adc_dat_i ;
+wire wbd_adc_ack_i ;
+
+//---------------------------------------------------------------------
+// Global Register Wishbone Interface
+//---------------------------------------------------------------------
+wire wbd_glbl_stb_o ; // strobe/request
+wire [7:0] wbd_glbl_adr_o ; // address
+wire wbd_glbl_we_o ; // write
+wire [WB_WIDTH-1:0] wbd_glbl_dat_o ; // data output
+wire [3:0] wbd_glbl_sel_o ; // byte enable
+wire wbd_glbl_cyc_o ;
+wire [WB_WIDTH-1:0] wbd_glbl_dat_i ; // data input
+wire wbd_glbl_ack_i ; // acknowlegement
+wire wbd_glbl_err_i ; // error
+
+//---------------------------------------------------------------------
+// Global Register Wishbone Interface
+//---------------------------------------------------------------------
+wire wbd_uart_stb_o ; // strobe/request
+wire [7:0] wbd_uart_adr_o ; // address
+wire wbd_uart_we_o ; // write
+wire [31:0] wbd_uart_dat_o ; // data output
+wire [3:0] wbd_uart_sel_o ; // byte enable
+wire wbd_uart_cyc_o ;
+wire [31:0] wbd_uart_dat_i ; // data input
+wire wbd_uart_ack_i ; // acknowlegement
+wire wbd_uart_err_i ; // error
+
+//---------------------------------------------------------------------
+// MBIST1
+//---------------------------------------------------------------------
+wire wbd_mbist_stb_o ; // strobe/request
+wire [12:0] wbd_mbist_adr_o ; // address
+wire wbd_mbist_we_o ; // write
+wire [WB_WIDTH-1:0] wbd_mbist_dat_o ; // data output
+wire [3:0] wbd_mbist_sel_o ; // byte enable
+wire [9:0] wbd_mbist_bl_o ; // byte enable
+wire wbd_mbist_bry_o ; // byte enable
+wire wbd_mbist_cyc_o ;
+wire [WB_WIDTH-1:0] wbd_mbist_dat_i ; // data input
+wire wbd_mbist_ack_i ; // acknowlegement
+wire wbd_mbist_lack_i ; // acknowlegement
+wire wbd_mbist_err_i ; // error
+
+//----------------------------------------------------
+// CPU Configuration
+//----------------------------------------------------
+wire cpu_rst_n ;
+wire qspim_rst_n ;
+wire sspim_rst_n ;
+wire uart_rst_n ; // uart reset
+wire i2c_rst_n ; // i2c reset
+wire usb_rst_n ; // i2c reset
+wire [3:0] boot_remap ; // Boot Remap
+wire [3:0] dcache_remap ; // Remap the dcache address
+wire cpu_clk ;
+wire rtc_clk ;
+wire usb_clk ;
+wire wbd_clk_int ;
+
+wire wbd_clk_pinmux ;
+//wire wbd_clk_int1 ;
+//wire wbd_clk_int2 ;
+wire wbd_int_rst_n ;
+//wire wbd_int1_rst_n ;
+//wire wbd_int2_rst_n ;
+
+wire [31:0] fuse_mhartid ;
+wire [15:0] irq_lines ;
+wire soft_irq ;
+
+
+wire [7:0] cfg_glb_ctrl ;
+wire [31:0] cfg_clk_ctrl1 ;
+wire [31:0] cfg_clk_ctrl2 ;
+wire [3:0] cfg_cska_wi ; // clock skew adjust for wishbone interconnect
+wire [3:0] cfg_cska_wh ; // clock skew adjust for web host
+
+wire [3:0] cfg_cska_riscv ; // clock skew adjust for riscv
+wire [3:0] cfg_cska_uart ; // clock skew adjust for uart
+wire [3:0] cfg_cska_qspi ; // clock skew adjust for spi
+wire [3:0] cfg_cska_pinmux ; // clock skew adjust for pinmux
+wire [3:0] cfg_cska_qspi_co ; // clock skew adjust for global reg
+wire [3:0] cfg_cska_mbist1 ;
+wire [3:0] cfg_cska_mbist2 ;
+wire [3:0] cfg_cska_mbist3 ;
+wire [3:0] cfg_cska_mbist4 ;
+
+// Bus Repeater Signals output from Wishbone Interface
+wire [3:0] cfg_cska_riscv_rp ; // clock skew adjust for riscv
+wire [3:0] cfg_cska_uart_rp ; // clock skew adjust for uart
+wire [3:0] cfg_cska_qspi_rp ; // clock skew adjust for spi
+wire [3:0] cfg_cska_pinmux_rp ; // clock skew adjust for pinmux
+wire [3:0] cfg_cska_qspi_co_rp ; // clock skew adjust for global reg
+wire [3:0] cfg_cska_mbist1_rp ;
+wire [3:0] cfg_cska_mbist2_rp ;
+wire [3:0] cfg_cska_mbist3_rp ;
+wire [3:0] cfg_cska_mbist4_rp ;
+
+wire [31:0] fuse_mhartid_rp ; // Repeater
+wire [15:0] irq_lines_rp ; // Repeater
+wire soft_irq_rp ; // Repeater
+
+wire wbd_clk_risc_rp ;
+wire wbd_clk_qspi_rp ;
+wire wbd_clk_uart_rp ;
+wire wbd_clk_pinmux_rp ;
+wire wbd_clk_mbist1_rp ;
+wire wbd_clk_mbist2_rp ;
+wire wbd_clk_mbist3_rp ;
+wire wbd_clk_mbist4_rp ;
+
+// Progammable Clock Skew inserted signals
+wire wbd_clk_wi_skew ; // clock for wishbone interconnect with clock skew
+wire wbd_clk_riscv_skew ; // clock for riscv with clock skew
+wire wbd_clk_uart_skew ; // clock for uart with clock skew
+wire wbd_clk_spi_skew ; // clock for spi with clock skew
+wire wbd_clk_glbl_skew ; // clock for global reg with clock skew
+wire wbd_clk_wh_skew ; // clock for global reg
+wire wbd_clk_mbist_skew ; // clock for global reg
+wire wbd_clk_mbist2_skew ; // clock for global reg
+wire wbd_clk_mbist3_skew ; // clock for global reg
+wire wbd_clk_mbist4_skew ; // clock for global reg
+
+
+
+wire [31:0] spi_debug ;
+wire [31:0] pinmux_debug ;
+wire [63:0] riscv_debug ;
+
+// SFLASH I/F
+wire sflash_sck ;
+wire [3:0] sflash_ss ;
+wire [3:0] sflash_oen ;
+wire [3:0] sflash_do ;
+wire [3:0] sflash_di ;
+
+// SSRAM I/F
+//wire ssram_sck ;
+//wire ssram_ss ;
+//wire ssram_oen ;
+//wire [3:0] ssram_do ;
+//wire [3:0] ssram_di ;
+
+// USB I/F
+wire usb_dp_o ;
+wire usb_dn_o ;
+wire usb_oen ;
+wire usb_dp_i ;
+wire usb_dn_i ;
+
+// UART I/F
+wire uart_txd ;
+wire uart_rxd ;
+
+// I2CM I/F
+wire i2cm_clk_o ;
+wire i2cm_clk_i ;
+wire i2cm_clk_oen ;
+wire i2cm_data_oen ;
+wire i2cm_data_o ;
+wire i2cm_data_i ;
+
+// SPI MASTER
+wire spim_sck ;
+wire spim_ss ;
+wire spim_miso ;
+wire spim_mosi ;
+
+wire [7:0] sar2dac ;
+wire analog_dac_out ;
+wire pulse1m_mclk ;
+wire h_reset_n ;
+
+`ifndef SCR1_TCM_MEM
+// SRAM-0 PORT-0 - DMEM I/F
+wire sram0_clk0 ; // CLK
+wire sram0_csb0 ; // CS#
+wire sram0_web0 ; // WE#
+wire [8:0] sram0_addr0 ; // Address
+wire [3:0] sram0_wmask0 ; // WMASK#
+wire [31:0] sram0_din0 ; // Write Data
+wire [31:0] sram0_dout0 ; // Read Data
+
+// SRAM-0 PORT-1, IMEM I/F
+wire sram0_clk1 ; // CLK
+wire sram0_csb1 ; // CS#
+wire [8:0] sram0_addr1 ; // Address
+wire [31:0] sram0_dout1 ; // Read Data
+
+// SRAM-1 PORT-0 - DMEM I/F
+wire sram1_clk0 ; // CLK
+wire sram1_csb0 ; // CS#
+wire sram1_web0 ; // WE#
+wire [8:0] sram1_addr0 ; // Address
+wire [3:0] sram1_wmask0 ; // WMASK#
+wire [31:0] sram1_din0 ; // Write Data
+wire [31:0] sram1_dout0 ; // Read Data
+
+// SRAM-1 PORT-1, IMEM I/F
+wire sram1_clk1 ; // CLK
+wire sram1_csb1 ; // CS#
+wire [8:0] sram1_addr1 ; // Address
+wire [31:0] sram1_dout1 ; // Read Data
+
+`endif
+
+// SPIM I/F
+wire sspim_sck ; // clock out
+wire sspim_so ; // serial data out
+wire sspim_si ; // serial data in
+wire sspim_ssn ; // cs_n
+
+
+wire usb_intr_o ;
+wire i2cm_intr_o ;
+
+//----------------------------------------------------------------
+// UART Master I/F
+// -------------------------------------------------------------
+wire uartm_rxd ;
+wire uartm_txd ;
+
+//----------------------------------------------------------
+// BIST I/F
+// ---------------------------------------------------------
+wire bist_en ;
+wire bist_run ;
+wire bist_load ;
+
+wire bist_sdi ;
+wire bist_shift ;
+wire bist_sdo ;
+
+wire bist_done ;
+wire [3:0] bist_error ;
+wire [3:0] bist_correct ;
+wire [3:0] bist_error_cnt0 ;
+wire [3:0] bist_error_cnt1 ;
+wire [3:0] bist_error_cnt2 ;
+wire [3:0] bist_error_cnt3 ;
+
+// With Repeater Buffer
+wire bist_en_rp ;
+wire bist_run_rp ;
+wire bist_load_rp ;
+
+wire bist_sdi_rp ;
+wire bist_shift_rp ;
+wire bist_sdo_rp ;
+
+wire bist_done_rp ;
+wire [3:0] bist_error_rp ;
+wire [3:0] bist_correct_rp ;
+wire [3:0] bist_error_cnt0_rp ;
+wire [3:0] bist_error_cnt1_rp ;
+wire [3:0] bist_error_cnt2_rp ;
+wire [3:0] bist_error_cnt3_rp ;
+
+// towards memory MBIST1
+// PORT-A
+wire [BIST_NO_SRAM-1:0] mem_clk_a ;
+wire [BIST1_ADDR_WD-1:2] mem0_addr_a ;
+wire [BIST1_ADDR_WD-1:2] mem1_addr_a ;
+wire [BIST1_ADDR_WD-1:2] mem2_addr_a ;
+wire [BIST1_ADDR_WD-1:2] mem3_addr_a ;
+wire [BIST_NO_SRAM-1:0] mem_cen_a ;
+wire [BIST_NO_SRAM-1:0] mem_web_a ;
+wire [BIST_DATA_WD/8-1:0] mem0_mask_a ;
+wire [BIST_DATA_WD/8-1:0] mem1_mask_a ;
+wire [BIST_DATA_WD/8-1:0] mem2_mask_a ;
+wire [BIST_DATA_WD/8-1:0] mem3_mask_a ;
+wire [BIST_DATA_WD-1:0] mem0_din_a ;
+wire [BIST_DATA_WD-1:0] mem1_din_a ;
+wire [BIST_DATA_WD-1:0] mem2_din_a ;
+wire [BIST_DATA_WD-1:0] mem3_din_a ;
+wire [BIST_DATA_WD-1:0] mem0_dout_a ;
+wire [BIST_DATA_WD-1:0] mem1_dout_a ;
+wire [BIST_DATA_WD-1:0] mem2_dout_a ;
+wire [BIST_DATA_WD-1:0] mem3_dout_a ;
+
+// PORT-B
+wire [BIST_NO_SRAM-1:0] mem_clk_b ;
+wire [BIST_NO_SRAM-1:0] mem_cen_b ;
+wire [BIST1_ADDR_WD-1:2] mem0_addr_b ;
+wire [BIST1_ADDR_WD-1:2] mem1_addr_b ;
+wire [BIST1_ADDR_WD-1:2] mem2_addr_b ;
+wire [BIST1_ADDR_WD-1:2] mem3_addr_b ;
+
+wire [3:0] spi_csn ;
+
+/////////////////////////////////////////////////////////
+// Clock Skew Ctrl
+////////////////////////////////////////////////////////
+
+assign cfg_cska_wi = cfg_clk_ctrl1[3:0];
+assign cfg_cska_wh = cfg_clk_ctrl1[7:4];
+assign cfg_cska_riscv = cfg_clk_ctrl1[11:8];
+assign cfg_cska_qspi = cfg_clk_ctrl1[15:12];
+assign cfg_cska_uart = cfg_clk_ctrl1[19:16];
+assign cfg_cska_pinmux = cfg_clk_ctrl1[23:20];
+assign cfg_cska_qspi_co = cfg_clk_ctrl1[27:24];
+
+assign cfg_cska_mbist1 = cfg_clk_ctrl2[3:0];
+assign cfg_cska_mbist2 = cfg_clk_ctrl2[7:4];
+assign cfg_cska_mbist3 = cfg_clk_ctrl2[11:8];
+assign cfg_cska_mbist4 = cfg_clk_ctrl2[15:12];
+assign dcache_remap = cfg_clk_ctrl2[27:24];
+assign boot_remap = cfg_clk_ctrl2[31:28];
+
+//assign la_data_out = {riscv_debug,spi_debug,sdram_debug};
+assign la_data_out[127:0] = {pinmux_debug,spi_debug,riscv_debug};
+
+//clk_buf u_buf1_wb_rstn (.clk_i(wbd_int_rst_n),.clk_o(wbd_int1_rst_n));
+//clk_buf u_buf2_wb_rstn (.clk_i(wbd_int1_rst_n),.clk_o(wbd_int2_rst_n));
+//
+//clk_buf u_buf1_wbclk (.clk_i(wbd_clk_int),.clk_o(wbd_clk_int1));
+//clk_buf u_buf2_wbclk (.clk_i(wbd_clk_int1),.clk_o(wbd_clk_int2));
+
+wb_host u_wb_host(
+`ifdef USE_POWER_PINS
+ .vccd1 (vccd1 ),// User area 1 1.8V supply
+ .vssd1 (vssd1 ),// User area 1 digital ground
+`endif
+ .user_clock1 (wb_clk_i ),
+ .user_clock2 (user_clock2 ),
+
+ .cpu_clk (cpu_clk ),
+ .rtc_clk (rtc_clk ),
+ .usb_clk (usb_clk ),
+
+ .wbd_int_rst_n (wbd_int_rst_n ),
+ .cpu_rst_n (cpu_rst_n ),
+ .qspim_rst_n (qspim_rst_n ),
+ .sspim_rst_n (sspim_rst_n ), // spi reset
+ .uart_rst_n (uart_rst_n ), // uart reset
+ .i2cm_rst_n (i2c_rst_n ), // i2c reset
+ .usb_rst_n (usb_rst_n ), // usb reset
+ .bist_rst_n (bist_rst_n ), // BIST Reset
+
+ // Master Port
+ .wbm_rst_i (wb_rst_i ),
+ .wbm_clk_i (wb_clk_i ),
+ .wbm_cyc_i (wbs_cyc_i ),
+ .wbm_stb_i (wbs_stb_i ),
+ .wbm_adr_i (wbs_adr_i ),
+ .wbm_we_i (wbs_we_i ),
+ .wbm_dat_i (wbs_dat_i ),
+ .wbm_sel_i (wbs_sel_i ),
+ .wbm_dat_o (wbs_dat_o ),
+ .wbm_ack_o (wbs_ack_o ),
+ .wbm_err_o ( ),
+
+ // Clock Skeq Adjust
+ .wbd_clk_int (wbd_clk_int ),
+ .wbd_clk_wh (wbd_clk_wh ),
+ .cfg_cska_wh (cfg_cska_wh ),
+
+ // Slave Port
+ .wbs_clk_out (wbd_clk_int ),
+ .wbs_clk_i (wbd_clk_wh ),
+ .wbs_cyc_o (wbd_int_cyc_i ),
+ .wbs_stb_o (wbd_int_stb_i ),
+ .wbs_adr_o (wbd_int_adr_i ),
+ .wbs_we_o (wbd_int_we_i ),
+ .wbs_dat_o (wbd_int_dat_i ),
+ .wbs_sel_o (wbd_int_sel_i ),
+ .wbs_dat_i (wbd_int_dat_o ),
+ .wbs_ack_i (wbd_int_ack_o ),
+ .wbs_err_i (wbd_int_err_o ),
+
+ .cfg_clk_ctrl1 (cfg_clk_ctrl1 ),
+ .cfg_clk_ctrl2 (cfg_clk_ctrl2 ),
+
+ .la_data_in (la_data_in[17:0] ),
+
+ .uartm_rxd (uartm_rxd ),
+ .uartm_txd (uartm_txd )
+
+
+ );
+
+
+
+
+//------------------------------------------------------------------------------
+// RISC V Core instance
+//------------------------------------------------------------------------------
+ycr1_top_wb u_riscv_top (
+`ifdef USE_POWER_PINS
+ .vccd1 (vccd1 ),// User area 1 1.8V supply
+ .vssd1 (vssd1 ),// User area 1 digital ground
+`endif
+ .wbd_clk_int (wbd_clk_risc_rp ),
+ .cfg_cska_riscv (cfg_cska_riscv_rp ),
+ .wbd_clk_riscv (wbd_clk_riscv_skew ),
+
+ // Reset
+ .pwrup_rst_n (wbd_int_rst_n ),
+ .rst_n (wbd_int_rst_n ),
+ .cpu_rst_n (cpu_rst_n ),
+ .riscv_debug (riscv_debug ),
+
+ // Clock
+ .core_clk (cpu_clk ),
+ .rtc_clk (rtc_clk ),
+
+ // Fuses
+ .fuse_mhartid (fuse_mhartid_rp ),
+
+ // IRQ
+ .irq_lines (irq_lines_rp ),
+ .soft_irq (soft_irq_rp ), // TODO - Interrupts
+
+ // DFT
+ // .test_mode (1'b0 ), // Moved inside IP
+ // .test_rst_n (1'b1 ), // Moved inside IP
+
+`ifndef SCR1_TCM_MEM
+ // SRAM-0 PORT-0
+ .sram0_clk0 (sram0_clk0 ),
+ .sram0_csb0 (sram0_csb0 ),
+ .sram0_web0 (sram0_web0 ),
+ .sram0_addr0 (sram0_addr0 ),
+ .sram0_wmask0 (sram0_wmask0 ),
+ .sram0_din0 (sram0_din0 ),
+ .sram0_dout0 (sram0_dout0 ),
+
+ // SRAM-0 PORT-0
+ .sram0_clk1 (sram0_clk1 ),
+ .sram0_csb1 (sram0_csb1 ),
+ .sram0_addr1 (sram0_addr1 ),
+ .sram0_dout1 (sram0_dout1 ),
+
+ // // SRAM-1 PORT-0
+ // .sram1_clk0 (sram1_clk0 ),
+ // .sram1_csb0 (sram1_csb0 ),
+ // .sram1_web0 (sram1_web0 ),
+ // .sram1_addr0 (sram1_addr0 ),
+ // .sram1_wmask0 (sram1_wmask0 ),
+ // .sram1_din0 (sram1_din0 ),
+ // .sram1_dout0 (sram1_dout0 ),
+ //
+ // // SRAM PORT-0
+ // .sram1_clk1 (sram1_clk1 ),
+ // .sram1_csb1 (sram1_csb1 ),
+ // .sram1_addr1 (sram1_addr1 ),
+ // .sram1_dout1 (sram1_dout1 ),
+`endif
+
+ .wb_rst_n (wbd_int_rst_n ),
+ .wb_clk (wbd_clk_riscv_skew ),
+
+ // Instruction cache memory interface
+ .wb_icache_stb_o (wbd_riscv_icache_stb_i ),
+ .wb_icache_adr_o (wbd_riscv_icache_adr_i ),
+ .wb_icache_we_o (wbd_riscv_icache_we_i ),
+ .wb_icache_sel_o (wbd_riscv_icache_sel_i ),
+ .wb_icache_bl_o (wbd_riscv_icache_bl_i ),
+ .wb_icache_bry_o (wbd_riscv_icache_bry_i ),
+ .wb_icache_dat_i (wbd_riscv_icache_dat_o ),
+ .wb_icache_ack_i (wbd_riscv_icache_ack_o ),
+ .wb_icache_lack_i (wbd_riscv_icache_lack_o ),
+ .wb_icache_err_i (wbd_riscv_icache_err_o ),
+
+ .icache_mem_clk0 (icache_mem_clk0 ), // CLK
+ .icache_mem_csb0 (icache_mem_csb0 ), // CS#
+ .icache_mem_web0 (icache_mem_web0 ), // WE#
+ .icache_mem_addr0 (icache_mem_addr0 ), // Address
+ .icache_mem_wmask0 (icache_mem_wmask0 ), // WMASK#
+ .icache_mem_din0 (icache_mem_din0 ), // Write Data
+// .icache_mem_dout0 (icache_mem_dout0 ), // Read Data
+
+
+ .icache_mem_clk1 (icache_mem_clk1 ), // CLK
+ .icache_mem_csb1 (icache_mem_csb1 ), // CS#
+ .icache_mem_addr1 (icache_mem_addr1 ), // Address
+ .icache_mem_dout1 (icache_mem_dout1 ), // Read Data
+
+ // Data cache memory interface
+ .wb_dcache_stb_o (wbd_riscv_dcache_stb_i ),
+ .wb_dcache_adr_o (wbd_riscv_dcache_adr_i ),
+ .wb_dcache_we_o (wbd_riscv_dcache_we_i ),
+ .wb_dcache_dat_o (wbd_riscv_dcache_dat_i ),
+ .wb_dcache_sel_o (wbd_riscv_dcache_sel_i ),
+ .wb_dcache_bl_o (wbd_riscv_dcache_bl_i ),
+ .wb_dcache_bry_o (wbd_riscv_dcache_bry_i ),
+ .wb_dcache_dat_i (wbd_riscv_dcache_dat_o ),
+ .wb_dcache_ack_i (wbd_riscv_dcache_ack_o ),
+ .wb_dcache_lack_i (wbd_riscv_dcache_lack_o ),
+ .wb_dcache_err_i (wbd_riscv_dcache_err_o ),
+
+ .dcache_mem_clk0 (dcache_mem_clk0 ), // CLK
+ .dcache_mem_csb0 (dcache_mem_csb0 ), // CS#
+ .dcache_mem_web0 (dcache_mem_web0 ), // WE#
+ .dcache_mem_addr0 (dcache_mem_addr0 ), // Address
+ .dcache_mem_wmask0 (dcache_mem_wmask0 ), // WMASK#
+ .dcache_mem_din0 (dcache_mem_din0 ), // Write Data
+ .dcache_mem_dout0 (dcache_mem_dout0 ), // Read Data
+
+
+ .dcache_mem_clk1 (dcache_mem_clk1 ), // CLK
+ .dcache_mem_csb1 (dcache_mem_csb1 ), // CS#
+ .dcache_mem_addr1 (dcache_mem_addr1 ), // Address
+ .dcache_mem_dout1 (dcache_mem_dout1 ), // Read Data
+
+
+ // Data memory interface
+ .wbd_dmem_stb_o (wbd_riscv_dmem_stb_i ),
+ .wbd_dmem_adr_o (wbd_riscv_dmem_adr_i ),
+ .wbd_dmem_we_o (wbd_riscv_dmem_we_i ),
+ .wbd_dmem_dat_o (wbd_riscv_dmem_dat_i ),
+ .wbd_dmem_sel_o (wbd_riscv_dmem_sel_i ),
+ .wbd_dmem_dat_i (wbd_riscv_dmem_dat_o ),
+ .wbd_dmem_ack_i (wbd_riscv_dmem_ack_o ),
+ .wbd_dmem_err_i (wbd_riscv_dmem_err_o )
+);
+
+`ifndef SCR1_TCM_MEM
+sky130_sram_2kbyte_1rw1r_32x512_8 u_tsram0_2kb(
+`ifdef USE_POWER_PINS
+ .vccd1 (vccd1 ),// area 1 1.8V supply
+ .vssd1 (vssd1 ),// area 1 digital ground
+`endif
+// Port 0: RW
+ .clk0 (sram0_clk0 ),
+ .csb0 (sram0_csb0 ),
+ .web0 (sram0_web0 ),
+ .wmask0 (sram0_wmask0 ),
+ .addr0 (sram0_addr0 ),
+ .din0 (sram0_din0 ),
+ .dout0 (sram0_dout0 ),
+// Port 1: R
+ .clk1 (sram0_clk1 ),
+ .csb1 (sram0_csb1 ),
+ .addr1 (sram0_addr1 ),
+ .dout1 (sram0_dout1 )
+ );
+
+/***
+sky130_sram_2kbyte_1rw1r_32x512_8 u_tsram1_2kb(
+`ifdef USE_POWER_PINS
+ .vccd1 (vccd1 ),// User area 1 1.8V supply
+ .vssd1 (vssd1 ),// User area 1 digital ground
+`endif
+// Port 0: RW
+ .clk0 (sram1_clk0 ),
+ .csb0 (sram1_csb0 ),
+ .web0 (sram1_web0 ),
+ .wmask0 (sram1_wmask0 ),
+ .addr0 (sram1_addr0 ),
+ .din0 (sram1_din0 ),
+ .dout0 (sram1_dout0 ),
+// Port 1: R
+ .clk1 (sram1_clk1 ),
+ .csb1 (sram1_csb1 ),
+ .addr1 (sram1_addr1 ),
+ .dout1 (sram1_dout1 )
+ );
+***/
+`endif
+
+
+sky130_sram_2kbyte_1rw1r_32x512_8 u_icache_2kb(
+`ifdef USE_POWER_PINS
+ .vccd1 (vccd1 ),// User area 1 1.8V supply
+ .vssd1 (vssd1 ),// User area 1 digital ground
+`endif
+// Port 0: RW
+ .clk0 (icache_mem_clk0 ),
+ .csb0 (icache_mem_csb0 ),
+ .web0 (icache_mem_web0 ),
+ .wmask0 (icache_mem_wmask0 ),
+ .addr0 (icache_mem_addr0 ),
+ .din0 (icache_mem_din0 ),
+ .dout0 ( ),
+// Port 1: R
+ .clk1 (icache_mem_clk1 ),
+ .csb1 (icache_mem_csb1 ),
+ .addr1 (icache_mem_addr1 ),
+ .dout1 (icache_mem_dout1 )
+ );
+
+sky130_sram_2kbyte_1rw1r_32x512_8 u_dcache_2kb(
+`ifdef USE_POWER_PINS
+ .vccd1 (vccd1 ),// User area 1 1.8V supply
+ .vssd1 (vssd1 ),// User area 1 digital ground
+`endif
+// Port 0: RW
+ .clk0 (dcache_mem_clk0 ),
+ .csb0 (dcache_mem_csb0 ),
+ .web0 (dcache_mem_web0 ),
+ .wmask0 (dcache_mem_wmask0 ),
+ .addr0 (dcache_mem_addr0 ),
+ .din0 (dcache_mem_din0 ),
+ .dout0 (dcache_mem_dout0 ),
+// Port 1: R
+ .clk1 (dcache_mem_clk1 ),
+ .csb1 (dcache_mem_csb1 ),
+ .addr1 (dcache_mem_addr1 ),
+ .dout1 (dcache_mem_dout1 )
+ );
+
+
+/*********************************************************
+* SPI Master
+* This is implementation of an SPI master that is controlled via an AXI bus .
+* It has FIFOs for transmitting and receiving data.
+* It supports both the normal SPI mode and QPI mode with 4 data lines.
+* *******************************************************/
+
+qspim_top
+# (
+`ifndef SYNTHESIS
+ .WB_WIDTH (WB_WIDTH )
+`endif
+) u_qspi_master
+(
+`ifdef USE_POWER_PINS
+ .vccd1 (vccd1 ),// User area 1 1.8V supply
+ .vssd1 (vssd1 ),// User area 1 digital ground
+`endif
+ .mclk (wbd_clk_spi ),
+ .rst_n (qspim_rst_n ),
+
+ // Clock Skew Adjust
+ .cfg_cska_sp_co (cfg_cska_qspi_co_rp ),
+ .cfg_cska_spi (cfg_cska_qspi_rp ),
+ .wbd_clk_int (wbd_clk_qspi_rp ),
+ .wbd_clk_spi (wbd_clk_spi ),
+
+ .wbd_stb_i (wbd_spim_stb_o ),
+ .wbd_adr_i (wbd_spim_adr_o ),
+ .wbd_we_i (wbd_spim_we_o ),
+ .wbd_dat_i (wbd_spim_dat_o ),
+ .wbd_sel_i (wbd_spim_sel_o ),
+ .wbd_bl_i (wbd_spim_bl_o ),
+ .wbd_bry_i (wbd_spim_bry_o ),
+ .wbd_dat_o (wbd_spim_dat_i ),
+ .wbd_ack_o (wbd_spim_ack_i ),
+ .wbd_lack_o (wbd_spim_lack_i ),
+ .wbd_err_o (wbd_spim_err_i ),
+
+ .spi_debug (spi_debug ),
+
+ // Pad Interface
+ .spi_sdi (sflash_di ),
+ .spi_clk (sflash_sck ),
+ .spi_csn (spi_csn ),
+ .spi_sdo (sflash_do ),
+ .spi_oen (sflash_oen )
+
+);
+
+
+
+wb_interconnect #(
+ `ifndef SYNTHESIS
+ .CH_CLK_WD (8 ),
+ .CH_DATA_WD (116 )
+ `endif
+ ) u_intercon (
+`ifdef USE_POWER_PINS
+ .vccd1 (vccd1 ),// User area 1 1.8V supply
+ .vssd1 (vssd1 ),// User area 1 digital ground
+`endif
+ .ch_clk_in ({
+ wbd_clk_int,
+ wbd_clk_int,
+ wbd_clk_int,
+ wbd_clk_int,
+ wbd_clk_int,
+ wbd_clk_int,
+ wbd_clk_int,
+ wbd_clk_int} ),
+ .ch_clk_out ({
+ wbd_clk_mbist4_rp,
+ wbd_clk_mbist3_rp,
+ wbd_clk_mbist2_rp,
+ wbd_clk_mbist1_rp,
+ wbd_clk_pinmux_rp,
+ wbd_clk_uart_rp,
+ wbd_clk_qspi_rp,
+ wbd_clk_risc_rp} ),
+ .ch_data_in ({
+ bist_error_cnt3[3:0],
+ bist_correct[3],
+ bist_error[3],
+
+ bist_error_cnt2[3:0],
+ bist_correct[2],
+ bist_error[2],
+
+ bist_error_cnt1[3:0],
+ bist_correct[1],
+ bist_error[1],
+
+ bist_error_cnt0[3:0],
+ bist_correct[0],
+ bist_error[0],
+ bist_done,
+ bist_sdo,
+ bist_shift,
+ bist_sdi,
+ bist_load,
+ bist_run,
+ bist_en,
+
+
+ soft_irq,
+ irq_lines[15:0],
+ fuse_mhartid[31:0],
+
+ cfg_cska_mbist4[3:0],
+ cfg_cska_mbist3[3:0],
+ cfg_cska_mbist2[3:0],
+ cfg_cska_mbist1[3:0],
+ cfg_cska_qspi_co[3:0],
+ cfg_cska_pinmux[3:0],
+ cfg_cska_uart[3:0],
+ cfg_cska_qspi[3:0],
+ cfg_cska_riscv[3:0]
+ } ),
+ .ch_data_out ({
+ bist_error_cnt3_rp[3:0],
+ bist_correct_rp[3],
+ bist_error_rp[3],
+
+ bist_error_cnt2_rp[3:0],
+ bist_correct_rp[2],
+ bist_error_rp[2],
+
+ bist_error_cnt1_rp[3:0],
+ bist_correct_rp[1],
+ bist_error_rp[1],
+
+ bist_error_cnt0_rp[3:0],
+ bist_correct_rp[0],
+ bist_error_rp[0],
+ bist_done_rp,
+ bist_sdo_rp,
+ bist_shift_rp,
+ bist_sdi_rp,
+ bist_load_rp,
+ bist_run_rp,
+ bist_en_rp,
+
+ soft_irq_rp,
+ irq_lines_rp[15:0],
+ fuse_mhartid_rp[31:0],
+
+ cfg_cska_mbist4_rp[3:0],
+ cfg_cska_mbist3_rp[3:0],
+ cfg_cska_mbist2_rp[3:0],
+ cfg_cska_mbist1_rp[3:0],
+ cfg_cska_qspi_co_rp[3:0],
+ cfg_cska_pinmux_rp[3:0],
+ cfg_cska_uart_rp[3:0],
+ cfg_cska_qspi_rp[3:0],
+ cfg_cska_riscv_rp[3:0]
+ }),
+ // Clock Skew adjust
+ .wbd_clk_int (wbd_clk_int ),
+ .cfg_cska_wi (cfg_cska_wi ),
+ .wbd_clk_wi (wbd_clk_wi_skew ),
+
+ .clk_i (wbd_clk_wi_skew ),
+ .rst_n (wbd_int_rst_n ),
+ .dcache_remap (dcache_remap ),
+ .boot_remap (boot_remap ),
+
+ // Master 0 Interface
+ .m0_wbd_dat_i (wbd_int_dat_i ),
+ .m0_wbd_adr_i (wbd_int_adr_i ),
+ .m0_wbd_sel_i (wbd_int_sel_i ),
+ .m0_wbd_we_i (wbd_int_we_i ),
+ .m0_wbd_cyc_i (wbd_int_cyc_i ),
+ .m0_wbd_stb_i (wbd_int_stb_i ),
+ .m0_wbd_dat_o (wbd_int_dat_o ),
+ .m0_wbd_ack_o (wbd_int_ack_o ),
+ .m0_wbd_err_o (wbd_int_err_o ),
+
+ // Master 1 Interface
+ .m1_wbd_dat_i (wbd_riscv_dmem_dat_i ),
+ .m1_wbd_adr_i (wbd_riscv_dmem_adr_i ),
+ .m1_wbd_sel_i (wbd_riscv_dmem_sel_i ),
+ .m1_wbd_we_i (wbd_riscv_dmem_we_i ),
+ .m1_wbd_cyc_i (wbd_riscv_dmem_stb_i ),
+ .m1_wbd_stb_i (wbd_riscv_dmem_stb_i ),
+ .m1_wbd_dat_o (wbd_riscv_dmem_dat_o ),
+ .m1_wbd_ack_o (wbd_riscv_dmem_ack_o ),
+ .m1_wbd_err_o (wbd_riscv_dmem_err_o ),
+
+ // Master 2 Interface
+ .m2_wbd_dat_i (wbd_riscv_dcache_dat_i ),
+ .m2_wbd_adr_i (wbd_riscv_dcache_adr_i ),
+ .m2_wbd_sel_i (wbd_riscv_dcache_sel_i ),
+ .m2_wbd_bl_i (wbd_riscv_dcache_bl_i ),
+ .m2_wbd_bry_i (wbd_riscv_dcache_bry_i ),
+ .m2_wbd_we_i (wbd_riscv_dcache_we_i ),
+ .m2_wbd_cyc_i (wbd_riscv_dcache_stb_i ),
+ .m2_wbd_stb_i (wbd_riscv_dcache_stb_i ),
+ .m2_wbd_dat_o (wbd_riscv_dcache_dat_o ),
+ .m2_wbd_ack_o (wbd_riscv_dcache_ack_o ),
+ .m2_wbd_lack_o (wbd_riscv_dcache_lack_o ),
+ .m2_wbd_err_o (wbd_riscv_dcache_err_o ),
+
+ // Master 3 Interface
+ .m3_wbd_adr_i (wbd_riscv_icache_adr_i ),
+ .m3_wbd_sel_i (wbd_riscv_icache_sel_i ),
+ .m3_wbd_bl_i (wbd_riscv_icache_bl_i ),
+ .m3_wbd_bry_i (wbd_riscv_icache_bry_i ),
+ .m3_wbd_we_i (wbd_riscv_icache_we_i ),
+ .m3_wbd_cyc_i (wbd_riscv_icache_stb_i ),
+ .m3_wbd_stb_i (wbd_riscv_icache_stb_i ),
+ .m3_wbd_dat_o (wbd_riscv_icache_dat_o ),
+ .m3_wbd_ack_o (wbd_riscv_icache_ack_o ),
+ .m3_wbd_lack_o (wbd_riscv_icache_lack_o ),
+ .m3_wbd_err_o (wbd_riscv_icache_err_o ),
+
+
+ // Slave 0 Interface
+ // .s0_wbd_err_i (1'b0 ), - Moved inside IP
+ .s0_wbd_dat_i (wbd_spim_dat_i ),
+ .s0_wbd_ack_i (wbd_spim_ack_i ),
+ .s0_wbd_lack_i (wbd_spim_lack_i ),
+ .s0_wbd_dat_o (wbd_spim_dat_o ),
+ .s0_wbd_adr_o (wbd_spim_adr_o ),
+ .s0_wbd_bry_o (wbd_spim_bry_o ),
+ .s0_wbd_bl_o (wbd_spim_bl_o ),
+ .s0_wbd_sel_o (wbd_spim_sel_o ),
+ .s0_wbd_we_o (wbd_spim_we_o ),
+ .s0_wbd_cyc_o (wbd_spim_cyc_o ),
+ .s0_wbd_stb_o (wbd_spim_stb_o ),
+
+ // Slave 1 Interface
+ // .s1_wbd_err_i (1'b0 ), - Moved inside IP
+ .s1_wbd_dat_i (wbd_uart_dat_i ),
+ .s1_wbd_ack_i (wbd_uart_ack_i ),
+ .s1_wbd_dat_o (wbd_uart_dat_o ),
+ .s1_wbd_adr_o (wbd_uart_adr_o ),
+ .s1_wbd_sel_o (wbd_uart_sel_o ),
+ .s1_wbd_we_o (wbd_uart_we_o ),
+ .s1_wbd_cyc_o (wbd_uart_cyc_o ),
+ .s1_wbd_stb_o (wbd_uart_stb_o ),
+
+ // Slave 2 Interface
+ // .s2_wbd_err_i (1'b0 ), - Moved inside IP
+ .s2_wbd_dat_i (wbd_glbl_dat_i ),
+ .s2_wbd_ack_i (wbd_glbl_ack_i ),
+ .s2_wbd_dat_o (wbd_glbl_dat_o ),
+ .s2_wbd_adr_o (wbd_glbl_adr_o ),
+ .s2_wbd_sel_o (wbd_glbl_sel_o ),
+ .s2_wbd_we_o (wbd_glbl_we_o ),
+ .s2_wbd_cyc_o (wbd_glbl_cyc_o ),
+ .s2_wbd_stb_o (wbd_glbl_stb_o ),
+
+ // Slave 3 Interface
+ // .s3_wbd_err_i (1'b0 ), - Moved inside IP
+ .s3_wbd_dat_i (wbd_mbist_dat_i ),
+ .s3_wbd_ack_i (wbd_mbist_ack_i ),
+ .s3_wbd_lack_i (wbd_mbist_lack_i ),
+ .s3_wbd_dat_o (wbd_mbist_dat_o ),
+ .s3_wbd_adr_o (wbd_mbist_adr_o ),
+ .s3_wbd_sel_o (wbd_mbist_sel_o ),
+ .s3_wbd_bry_o (wbd_mbist_bry_o ),
+ .s3_wbd_bl_o (wbd_mbist_bl_o ),
+ .s3_wbd_we_o (wbd_mbist_we_o ),
+ .s3_wbd_cyc_o (wbd_mbist_cyc_o ),
+ .s3_wbd_stb_o (wbd_mbist_stb_o )
+
+ );
+
+
+uart_i2c_usb_spi_top u_uart_i2c_usb_spi (
+`ifdef USE_POWER_PINS
+ .vccd1 (vccd1 ),// User area 1 1.8V supply
+ .vssd1 (vssd1 ),// User area 1 digital ground
+`endif
+ .wbd_clk_int (wbd_clk_uart_rp ),
+ .cfg_cska_uart (cfg_cska_uart_rp ),
+ .wbd_clk_uart (wbd_clk_uart_skew ),
+
+ .uart_rstn (uart_rst_n ), // uart reset
+ .i2c_rstn (i2c_rst_n ), // i2c reset
+ .usb_rstn (usb_rst_n ), // USB reset
+ .spi_rstn (sspim_rst_n ), // SPI reset
+ .app_clk (wbd_clk_uart_skew ),
+ .usb_clk (usb_clk ),
+
+ // Reg Bus Interface Signal
+ .reg_cs (wbd_uart_stb_o ),
+ .reg_wr (wbd_uart_we_o ),
+ .reg_addr (wbd_uart_adr_o[7:0] ),
+ .reg_wdata (wbd_uart_dat_o ),
+ .reg_be (wbd_uart_sel_o ),
+
+ // Outputs
+ .reg_rdata (wbd_uart_dat_i ),
+ .reg_ack (wbd_uart_ack_i ),
+
+ // Pad interface
+ .scl_pad_i (i2cm_clk_i ),
+ .scl_pad_o (i2cm_clk_o ),
+ .scl_pad_oen_o (i2cm_clk_oen ),
+
+ .sda_pad_i (i2cm_data_i ),
+ .sda_pad_o (i2cm_data_o ),
+ .sda_padoen_o (i2cm_data_oen ),
+
+ .i2cm_intr_o (i2cm_intr_o ),
+
+ .uart_rxd (uart_rxd ),
+ .uart_txd (uart_txd ),
+
+ .usb_in_dp (usb_dp_i ),
+ .usb_in_dn (usb_dn_i ),
+
+ .usb_out_dp (usb_dp_o ),
+ .usb_out_dn (usb_dn_o ),
+ .usb_out_tx_oen (usb_oen ),
+
+ .usb_intr_o (usb_intr_o ),
+
+ // SPIM Master
+ .sspim_sck (sspim_sck ),
+ .sspim_so (sspim_so ),
+ .sspim_si (sspim_si ),
+ .sspim_ssn (sspim_ssn )
+
+ );
+
+
+pinmux u_pinmux(
+`ifdef USE_POWER_PINS
+ .vccd1 (vccd1 ),// User area 1 1.8V supply
+ .vssd1 (vssd1 ),// User area 1 digital ground
+`endif
+ //clk skew adjust
+ .cfg_cska_pinmux (cfg_cska_pinmux_rp ),
+ .wbd_clk_int (wbd_clk_pinmux_rp ),
+ .wbd_clk_pinmux (wbd_clk_pinmux_skew ),
+
+ // System Signals
+ // Inputs
+ .mclk (wbd_clk_pinmux_skew ),
+ .h_reset_n (wbd_int_rst_n ),
+
+ // Reg Bus Interface Signal
+ .reg_cs (wbd_glbl_stb_o ),
+ .reg_wr (wbd_glbl_we_o ),
+ .reg_addr (wbd_glbl_adr_o ),
+ .reg_wdata (wbd_glbl_dat_o ),
+ .reg_be (wbd_glbl_sel_o ),
+
+ // Outputs
+ .reg_rdata (wbd_glbl_dat_i ),
+ .reg_ack (wbd_glbl_ack_i ),
+
+
+ // Risc configuration
+ .fuse_mhartid (fuse_mhartid ),
+ .irq_lines (irq_lines ),
+ .soft_irq (soft_irq ),
+ .user_irq (user_irq ),
+ .usb_intr (usb_intr_o ),
+ .i2cm_intr (i2cm_intr_o ),
+
+ // Digital IO
+ .digital_io_out (io_out ),
+ .digital_io_oen (io_oeb ),
+ .digital_io_in (io_in ),
+
+ // SFLASH I/F
+ .sflash_sck (sflash_sck ),
+ .sflash_ss (spi_csn ),
+ .sflash_oen (sflash_oen ),
+ .sflash_do (sflash_do ),
+ .sflash_di (sflash_di ),
+
+
+ // USB I/F
+ .usb_dp_o (usb_dp_o ),
+ .usb_dn_o (usb_dn_o ),
+ .usb_oen (usb_oen ),
+ .usb_dp_i (usb_dp_i ),
+ .usb_dn_i (usb_dn_i ),
+
+ // UART I/F
+ .uart_txd (uart_txd ),
+ .uart_rxd (uart_rxd ),
+
+ // I2CM I/F
+ .i2cm_clk_o (i2cm_clk_o ),
+ .i2cm_clk_i (i2cm_clk_i ),
+ .i2cm_clk_oen (i2cm_clk_oen ),
+ .i2cm_data_oen (i2cm_data_oen ),
+ .i2cm_data_o (i2cm_data_o ),
+ .i2cm_data_i (i2cm_data_i ),
+
+ // SPI MASTER
+ .spim_sck (sspim_sck ),
+ .spim_ss (sspim_ssn ),
+ .spim_miso (sspim_so ),
+ .spim_mosi (sspim_si ),
+
+ // UART MASTER I/F
+ .uartm_rxd (uartm_rxd ),
+ .uartm_txd (uartm_txd ),
+
+
+ .pulse1m_mclk (pulse1m_mclk ),
+
+ .pinmux_debug (pinmux_debug ),
+
+ // BIST I/F
+ .bist_en (bist_en ),
+ .bist_run (bist_run ),
+ .bist_load (bist_load ),
+
+ .bist_sdi (bist_sdi ),
+ .bist_shift (bist_shift ),
+ .bist_sdo (bist_sdo_rp ),
+
+ .bist_done (bist_done_rp ),
+ .bist_error (bist_error_rp ),
+ .bist_correct (bist_correct_rp ),
+ .bist_error_cnt0 (bist_error_cnt0_rp ),
+ .bist_error_cnt1 (bist_error_cnt1_rp ),
+ .bist_error_cnt2 (bist_error_cnt2_rp ),
+ .bist_error_cnt3 (bist_error_cnt3_rp )
+
+
+ );
+//------------- MBIST - 512x32 ----
+
+mbist_wrapper #(
+ `ifndef SYNTHESIS
+ .BIST_NO_SRAM (4 ),
+ .BIST_ADDR_WD (BIST1_ADDR_WD-2 ),
+ .BIST_DATA_WD (BIST_DATA_WD ),
+ .BIST_ADDR_START (9'h000 ),
+ .BIST_ADDR_END (9'h1FB ),
+ .BIST_REPAIR_ADDR_START (9'h1FC ),
+ .BIST_RAD_WD_I (BIST1_ADDR_WD-2 ),
+ .BIST_RAD_WD_O (BIST1_ADDR_WD-2 )
+ `endif
+ )
+ u_mbist (
+
+`ifdef USE_POWER_PINS
+ .vccd1 (vccd1 ),// User area 1 1.8V supply
+ .vssd1 (vssd1 ),// User area 1 digital ground
+`endif
+
+ // Clock Skew adjust
+ .wbd_clk_int (wbd_clk_mbist1_rp ),
+ .cfg_cska_mbist (cfg_cska_mbist1_rp ),
+ .wbd_clk_mbist (wbd_clk_mbist_skew ),
+
+ // WB I/F
+ .wb_clk2_i (wbd_clk_mbist_skew ),
+ .wb_clk_i (wbd_clk_mbist_skew ),
+ .wb_stb_i (wbd_mbist_stb_o),
+ .wb_cs_i (wbd_mbist_adr_o[12:11]),
+ .wb_adr_i (wbd_mbist_adr_o[BIST1_ADDR_WD-1:2]),
+ .wb_we_i (wbd_mbist_we_o ),
+ .wb_dat_i (wbd_mbist_dat_o),
+ .wb_sel_i (wbd_mbist_sel_o),
+ .wb_bl_i (wbd_mbist_bl_o),
+ .wb_bry_i (wbd_mbist_bry_o),
+ .wb_dat_o (wbd_mbist_dat_i),
+ .wb_ack_o (wbd_mbist_ack_i),
+ .wb_lack_o (wbd_mbist_lack_i),
+ .wb_err_o ( ),
+
+ .rst_n (bist_rst_n ),
+
+
+ .bist_en (bist_en_rp ),
+ .bist_run (bist_run_rp ),
+ .bist_shift (bist_shift_rp ),
+ .bist_load (bist_load_rp ),
+ .bist_sdi (bist_sdi_rp ),
+
+ .bist_error_cnt3 (bist_error_cnt3 ),
+ .bist_error_cnt2 (bist_error_cnt2 ),
+ .bist_error_cnt1 (bist_error_cnt1 ),
+ .bist_error_cnt0 (bist_error_cnt0 ),
+ .bist_correct (bist_correct ),
+ .bist_error (bist_error ),
+ .bist_done (bist_done ),
+ .bist_sdo (bist_sdo ),
+
+ // towards memory
+ // PORT-A
+ .mem_clk_a (mem_clk_a ),
+ .mem_addr_a0 (mem0_addr_a ),
+ .mem_addr_a1 (mem1_addr_a ),
+ .mem_addr_a2 (mem2_addr_a ),
+ .mem_addr_a3 (mem3_addr_a ),
+ .mem_cen_a (mem_cen_a ),
+ .mem_web_a (mem_web_a ),
+ .mem_mask_a0 (mem0_mask_a ),
+ .mem_mask_a1 (mem1_mask_a ),
+ .mem_mask_a2 (mem2_mask_a ),
+ .mem_mask_a3 (mem3_mask_a ),
+ .mem_din_a0 (mem0_din_a ),
+ .mem_din_a1 (mem1_din_a ),
+ .mem_din_a2 (mem2_din_a ),
+ .mem_din_a3 (mem3_din_a ),
+ .mem_dout_a0 (mem0_dout_a ),
+ .mem_dout_a1 (mem1_dout_a ),
+ .mem_dout_a2 (mem2_dout_a ),
+ .mem_dout_a3 (mem3_dout_a ),
+ // PORT-B
+ .mem_clk_b (mem_clk_b ),
+ .mem_cen_b (mem_cen_b ),
+ .mem_addr_b0 (mem0_addr_b ),
+ .mem_addr_b1 (mem1_addr_b ),
+ .mem_addr_b2 (mem2_addr_b ),
+ .mem_addr_b3 (mem3_addr_b )
+
+
+);
+
+sky130_sram_2kbyte_1rw1r_32x512_8 u_sram0_2kb(
+`ifdef USE_POWER_PINS
+ .vccd1 (vccd1 ),// User area 1 1.8V supply
+ .vssd1 (vssd1 ),// User area 1 digital ground
+`endif
+// Port 0: RW
+ .clk0 (mem_clk_a[0] ),
+ .csb0 (mem_cen_a[0] ),
+ .web0 (mem_web_a[0] ),
+ .wmask0 (mem0_mask_a ),
+ .addr0 (mem0_addr_a ),
+ .din0 (mem0_din_a ),
+ .dout0 (mem0_dout_a ),
+// Port 1: R
+ .clk1 (mem_clk_b[0] ),
+ .csb1 (mem_cen_b[0] ),
+ .addr1 (mem0_addr_b ),
+ .dout1 ( )
+ );
+
+sky130_sram_2kbyte_1rw1r_32x512_8 u_sram1_2kb(
+`ifdef USE_POWER_PINS
+ .vccd1 (vccd1 ),// User area 1 1.8V supply
+ .vssd1 (vssd1 ),// User area 1 digital ground
+`endif
+// Port 0: RW
+ .clk0 (mem_clk_a[1] ),
+ .csb0 (mem_cen_a[1] ),
+ .web0 (mem_web_a[1] ),
+ .wmask0 (mem1_mask_a ),
+ .addr0 (mem1_addr_a ),
+ .din0 (mem1_din_a ),
+ .dout0 (mem1_dout_a ),
+// Port 1: R
+ .clk1 (mem_clk_b[1] ),
+ .csb1 (mem_cen_b[1] ),
+ .addr1 (mem1_addr_b ),
+ .dout1 ( )
+ );
+
+sky130_sram_2kbyte_1rw1r_32x512_8 u_sram2_2kb(
+`ifdef USE_POWER_PINS
+ .vccd1 (vccd1 ),// User area 1 1.8V supply
+ .vssd1 (vssd1 ),// User area 1 digital ground
+`endif
+// Port 0: RW
+ .clk0 (mem_clk_a[2] ),
+ .csb0 (mem_cen_a[2] ),
+ .web0 (mem_web_a[2] ),
+ .wmask0 (mem2_mask_a ),
+ .addr0 (mem2_addr_a ),
+ .din0 (mem2_din_a ),
+ .dout0 (mem2_dout_a ),
+// Port 1: R
+ .clk1 (mem_clk_b[2] ),
+ .csb1 (mem_cen_b[2] ),
+ .addr1 (mem2_addr_b ),
+ .dout1 ( )
+ );
+
+
+sky130_sram_2kbyte_1rw1r_32x512_8 u_sram3_2kb(
+`ifdef USE_POWER_PINS
+ .vccd1 (vccd1 ),// User area 1 1.8V supply
+ .vssd1 (vssd1 ),// User area 1 digital ground
+`endif
+// Port 0: RW
+ .clk0 (mem_clk_a[3] ),
+ .csb0 (mem_cen_a[3] ),
+ .web0 (mem_web_a[3] ),
+ .wmask0 (mem3_mask_a ),
+ .addr0 (mem3_addr_a ),
+ .din0 (mem3_din_a ),
+ .dout0 (mem3_dout_a ),
+// Port 1: R
+ .clk1 (mem_clk_b[3] ),
+ .csb1 (mem_cen_b[3] ),
+ .addr1 (mem3_addr_b ),
+ .dout1 ( )
+ );
+
+
+/***
+sar_adc u_adc (
+`ifdef USE_POWER_PINS
+ .vccd1 (vccd1),// User area 1 1.8V supply
+ .vssd1 (vssd1),// User area 1 digital ground
+ .vccd2 (vccd1), // (vccd2),// User area 2 1.8V supply (analog) - DOTO: Need Fix
+ .vssd2 (vssd1), // (vssd2),// User area 2 ground (analog) - DOTO: Need Fix
+`endif
+
+
+ .clk (wbd_clk_adc_rp ),// The clock (digital)
+ .reset_n (wbd_int_rst_n ),// Active low reset (digital)
+
+ // Reg Bus Interface Signal
+ .reg_cs (wbd_adc_stb_o ),
+ .reg_wr (wbd_adc_we_o ),
+ .reg_addr (wbd_adc_adr_o[7:0] ),
+ .reg_wdata (wbd_adc_dat_o ),
+ .reg_be (wbd_adc_sel_o ),
+
+ // Outputs
+ .reg_rdata (wbd_adc_dat_i ),
+ .reg_ack (wbd_adc_ack_i ),
+
+ .pulse1m_mclk (pulse1m_mclk),
+
+
+ // DAC I/F
+ .sar2dac (sar2dac ),
+ //.analog_dac_out (analog_dac_out) , // TODO: Need to connect to DAC O/P
+ .analog_dac_out (analog_io[6]) ,
+
+ // ADC Input
+ .analog_din(analog_io[5:0]) // (Analog)
+
+);
+***/
+
+/****
+* TODO: Need to uncomment the DAC
+DAC_8BIT u_dac (
+ `ifdef USE_POWER_PINS
+ .vdd(vccd2),
+ .gnd(vssd2),
+ `endif
+ .d0(sar2dac[0]),
+ .d1(sar2dac[1]),
+ .d2(sar2dac[2]),
+ .d3(sar2dac[3]),
+ .d4(sar2dac[4]),
+ .d5(sar2dac[5]),
+ .d6(sar2dac[6]),
+ .d7(sar2dac[7]),
+ .inp1(analog_io[6]),
+ .out_v(analog_dac_out)
+ );
+
+**/
+
+endmodule : user_project_wrapper
diff --git a/verilog/rtl/wb_host/src/wb_host.sv b/verilog/rtl/wb_host/src/wb_host.sv
new file mode 100644
index 0000000..4cf0005
--- /dev/null
+++ b/verilog/rtl/wb_host/src/wb_host.sv
@@ -0,0 +1,574 @@
+//////////////////////////////////////////////////////////////////////////////
+// SPDX-FileCopyrightText: 2021 , Dinesh Annayya
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+// SPDX-License-Identifier: Apache-2.0
+// SPDX-FileContributor: Created by Dinesh Annayya <dinesha@opencores.org>
+//
+//////////////////////////////////////////////////////////////////////
+//// ////
+//// Wishbone host Interface ////
+//// ////
+//// This file is part of the YIFive cores project ////
+//// https://github.com/dineshannayya/yifive_r0.git ////
+//// http://www.opencores.org/cores/yifive/ ////
+//// ////
+//// Description ////
+//// This block does async Wishbone from one clock to other ////
+//// clock domain ////
+//// ////
+//// To Do: ////
+//// nothing ////
+//// ////
+//// Author(s): ////
+//// - Dinesh Annayya, dinesha@opencores.org ////
+//// ////
+//// Revision : ////
+//// 0.1 - 25th Feb 2021, Dinesh A ////
+//// initial version ////
+//// 0.2 - Nov 14 2021, Dinesh A ////
+//// Reset connectivity bug fix clk_ctl in u_sdramclk ////
+//// u_cpuclk,u_rtcclk,u_usbclk ////
+//// 0.3 - Nov 16 2021, Dinesh A ////
+//// Wishbone out are register for better timing ////
+//////////////////////////////////////////////////////////////////////
+//// ////
+//// Copyright (C) 2000 Authors and OPENCORES.ORG ////
+//// ////
+//// This source file may be used and distributed without ////
+//// restriction provided that this copyright statement is not ////
+//// removed from the file and that any derivative work contains ////
+//// the original copyright notice and the associated disclaimer. ////
+//// ////
+//// This source file is free software; you can redistribute it ////
+//// and/or modify it under the terms of the GNU Lesser General ////
+//// Public License as published by the Free Software Foundation; ////
+//// either version 2.1 of the License, or (at your option) any ////
+//// later version. ////
+//// ////
+//// This source is distributed in the hope that it will be ////
+//// useful, but WITHOUT ANY WARRANTY; without even the implied ////
+//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR ////
+//// PURPOSE. See the GNU Lesser General Public License for more ////
+//// details. ////
+//// ////
+//// You should have received a copy of the GNU Lesser General ////
+//// Public License along with this source; if not, download it ////
+//// from http://www.opencores.org/lgpl.shtml ////
+//// ////
+//////////////////////////////////////////////////////////////////////
+
+module wb_host (
+
+`ifdef USE_POWER_PINS
+ inout vccd1, // User area 1 1.8V supply
+ inout vssd1, // User area 1 digital ground
+`endif
+ input logic user_clock1 ,
+ input logic user_clock2 ,
+
+ output logic cpu_clk ,
+ output logic rtc_clk ,
+ output logic usb_clk ,
+ // Global Reset control
+ output logic wbd_int_rst_n ,
+ output logic cpu_rst_n ,
+ output logic qspim_rst_n ,
+ output logic sspim_rst_n ,
+ output logic uart_rst_n ,
+ output logic i2cm_rst_n ,
+ output logic usb_rst_n ,
+ output logic bist_rst_n ,
+
+ // Master Port
+ input logic wbm_rst_i , // Regular Reset signal
+ input logic wbm_clk_i , // System clock
+ input logic wbm_cyc_i , // strobe/request
+ input logic wbm_stb_i , // strobe/request
+ input logic [31:0] wbm_adr_i , // address
+ input logic wbm_we_i , // write
+ input logic [31:0] wbm_dat_i , // data output
+ input logic [3:0] wbm_sel_i , // byte enable
+ output logic [31:0] wbm_dat_o , // data input
+ output logic wbm_ack_o , // acknowlegement
+ output logic wbm_err_o , // error
+
+ // Clock Skew Adjust
+ input logic wbd_clk_int ,
+ output logic wbd_clk_wh ,
+ input logic [3:0] cfg_cska_wh , // clock skew adjust for web host
+
+ // Slave Port
+ output logic wbs_clk_out , // System clock
+ input logic wbs_clk_i , // System clock
+ output logic wbs_cyc_o , // strobe/request
+ output logic wbs_stb_o , // strobe/request
+ output logic [31:0] wbs_adr_o , // address
+ output logic wbs_we_o , // write
+ output logic [31:0] wbs_dat_o , // data output
+ output logic [3:0] wbs_sel_o , // byte enable
+ input logic [31:0] wbs_dat_i , // data input
+ input logic wbs_ack_i , // acknowlegement
+ input logic wbs_err_i , // error
+
+ output logic [31:0] cfg_clk_ctrl1 ,
+ output logic [31:0] cfg_clk_ctrl2 ,
+
+ input logic [17:0] la_data_in ,
+
+ input logic uartm_rxd ,
+ output logic uartm_txd
+
+ );
+
+
+//--------------------------------
+// local dec
+//
+//--------------------------------
+logic wbm_rst_n;
+logic wbs_rst_n;
+
+logic reg_sel ;
+logic [1:0] sw_addr ;
+logic sw_rd_en ;
+logic sw_wr_en ;
+logic [31:0] reg_rdata ;
+logic [31:0] reg_out ;
+logic reg_ack ;
+logic [7:0] config_reg ;
+logic [31:0] clk_ctrl1 ;
+logic [31:0] clk_ctrl2 ;
+logic sw_wr_en_0;
+logic sw_wr_en_1;
+logic sw_wr_en_2;
+logic sw_wr_en_3;
+logic [7:0] cfg_bank_sel;
+logic [31:0] reg_0; // Software_Reg_0
+
+logic [2:0] cfg_wb_clk_ctrl;
+logic [3:0] cfg_cpu_clk_ctrl;
+logic [7:0] cfg_rtc_clk_ctrl;
+logic [3:0] cfg_usb_clk_ctrl;
+logic [8:0] cfg_glb_ctrl;
+
+// uart Master Port
+logic wbm_uart_cyc_i ; // strobe/request
+logic wbm_uart_stb_i ; // strobe/request
+logic [31:0] wbm_uart_adr_i ; // address
+logic wbm_uart_we_i ; // write
+logic [31:0] wbm_uart_dat_i ; // data output
+logic [3:0] wbm_uart_sel_i ; // byte enable
+logic [31:0] wbm_uart_dat_o ; // data input
+logic wbm_uart_ack_o ; // acknowlegement
+logic wbm_uart_err_o ; // error
+
+// Selected Master Port
+logic wb_cyc_i ; // strobe/request
+logic wb_stb_i ; // strobe/request
+logic [31:0] wb_adr_i ; // address
+logic wb_we_i ; // write
+logic [31:0] wb_dat_i ; // data output
+logic [3:0] wb_sel_i ; // byte enable
+logic [31:0] wb_dat_o ; // data input
+logic wb_ack_o ; // acknowlegement
+logic wb_err_o ; // error
+logic [31:0] wb_adr_int ;
+logic wb_stb_int ;
+logic [31:0] wb_dat_int ; // data input
+logic wb_ack_int ; // acknowlegement
+logic wb_err_int ; // error
+
+
+ctech_buf u_buf_wb_rst (.A(cfg_glb_ctrl[0]),.X(wbd_int_rst_n));
+ctech_buf u_buf_cpu_rst (.A(cfg_glb_ctrl[1]),.X(cpu_rst_n));
+ctech_buf u_buf_qspim_rst (.A(cfg_glb_ctrl[2]),.X(qspim_rst_n));
+ctech_buf u_buf_sspim_rst (.A(cfg_glb_ctrl[3]),.X(sspim_rst_n));
+ctech_buf u_buf_uart_rst (.A(cfg_glb_ctrl[4]),.X(uart_rst_n));
+ctech_buf u_buf_i2cm_rst (.A(cfg_glb_ctrl[5]),.X(i2cm_rst_n));
+ctech_buf u_buf_usb_rst (.A(cfg_glb_ctrl[6]),.X(usb_rst_n));
+ctech_buf u_buf_bist_rst (.A(cfg_glb_ctrl[7]),.X(bist_rst_n));
+
+//--------------------------------------------------------------------------------
+// Look like wishbone reset removed early than user Power up sequence
+// To control the reset phase, we have added additional control through la[0]
+// ------------------------------------------------------------------------------
+wire arst_n = !wbm_rst_i & la_data_in[0];
+reset_sync u_wbm_rst (
+ .scan_mode (1'b0 ),
+ .dclk (wbm_clk_i ), // Destination clock domain
+ .arst_n (arst_n ), // active low async reset
+ .srst_n (wbm_rst_n )
+ );
+
+reset_sync u_wbs_rst (
+ .scan_mode (1'b0 ),
+ .dclk (wbs_clk_i ), // Destination clock domain
+ .arst_n (arst_n ), // active low async reset
+ .srst_n (wbs_rst_n )
+ );
+
+// UART Master
+uart2wb u_uart2wb (
+ .arst_n (wbm_rst_n ), // sync reset
+ .app_clk (wbm_clk_i ), // sys clock
+
+ // configuration control
+ .cfg_tx_enable (la_data_in[1] ), // Enable Transmit Path
+ .cfg_rx_enable (la_data_in[2] ), // Enable Received Path
+ .cfg_stop_bit (la_data_in[3] ), // 0 -> 1 Start , 1 -> 2 Stop Bits
+ .cfg_baud_16x (la_data_in[15:4] ), // 16x Baud clock generation
+ .cfg_pri_mod (la_data_in[17:16] ), // priority mode, 0 -> nop, 1 -> Even, 2 -> Odd
+
+ // Master Port
+ .wbm_cyc_o (wbm_uart_cyc_i ), // strobe/request
+ .wbm_stb_o (wbm_uart_stb_i ), // strobe/request
+ .wbm_adr_o (wbm_uart_adr_i ), // address
+ .wbm_we_o (wbm_uart_we_i ), // write
+ .wbm_dat_o (wbm_uart_dat_i ), // data output
+ .wbm_sel_o (wbm_uart_sel_i ), // byte enable
+ .wbm_dat_i (wbm_uart_dat_o ), // data input
+ .wbm_ack_i (wbm_uart_ack_o ), // acknowlegement
+ .wbm_err_i (wbm_uart_err_o ), // error
+
+ // Status information
+ .frm_error (), // framing error
+ .par_error (), // par error
+
+ .baud_clk_16x (), // 16x Baud clock
+
+ // Line Interface
+ .rxd (uartm_rxd) , // uart rxd
+ .txd (uartm_txd) // uart txd
+
+ );
+
+
+// Arbitor to select between external wb vs uart wb
+wire [1:0] grnt;
+wb_arb u_arb(
+ .clk (wbm_clk_i),
+ .rstn (wbm_rst_n),
+ .req ({1'b0,wbm_uart_stb_i,wbm_stb_i}),
+ .gnt (grnt)
+ );
+
+// Select the master based on the grant
+assign wb_cyc_i = (grnt == 2'b00) ? wbm_cyc_i : wbm_uart_cyc_i;
+assign wb_stb_i = (grnt == 2'b00) ? wbm_stb_i : wbm_uart_stb_i;
+assign wb_adr_i = (grnt == 2'b00) ? wbm_adr_i : wbm_uart_adr_i;
+assign wb_we_i = (grnt == 2'b00) ? wbm_we_i : wbm_uart_we_i;
+assign wb_dat_i = (grnt == 2'b00) ? wbm_dat_i : wbm_uart_dat_i;
+assign wb_sel_i = (grnt == 2'b00) ? wbm_sel_i : wbm_uart_sel_i;
+
+assign wbm_dat_o = (grnt == 2'b00) ? wb_dat_o : 'h0;
+assign wbm_ack_o = (grnt == 2'b00) ? wb_ack_o : 'h0;
+assign wbm_err_o = (grnt == 2'b00) ? wb_err_o : 'h0;
+
+
+assign wbm_uart_dat_o = (grnt == 2'b01) ? wb_dat_o : 'h0;
+assign wbm_uart_ack_o = (grnt == 2'b01) ? wb_ack_o : 'h0;
+assign wbm_uart_err_o = (grnt == 2'b01) ? wb_err_o : 'h0;
+
+
+
+
+
+// wb_host clock skew control
+clk_skew_adjust u_skew_wh
+ (
+`ifdef USE_POWER_PINS
+ .vccd1 (vccd1 ),// User area 1 1.8V supply
+ .vssd1 (vssd1 ),// User area 1 digital ground
+`endif
+ .clk_in (wbd_clk_int ),
+ .sel (cfg_cska_wh ),
+ .clk_out (wbd_clk_wh )
+ );
+
+
+// To reduce the load/Timing Wishbone I/F, Strobe is register to create
+// multi-cycle
+wire [31:0] wb_dat_o1 = (reg_sel) ? reg_rdata : wb_dat_int; // data input
+wire wb_ack_o1 = (reg_sel) ? reg_ack : wb_ack_int; // acknowlegement
+wire wb_err_o1 = (reg_sel) ? 1'b0 : wb_err_int; // error
+
+logic wb_req;
+// Hold fix for STROBE
+wire wb_stb_d1,wb_stb_d2,wb_stb_d3;
+ctech_delay_buf u_delay1_stb0 (.X(wb_stb_d1),.A(wb_stb_i));
+ctech_delay_buf u_delay2_stb1 (.X(wb_stb_d2),.A(wb_stb_d1));
+ctech_delay_buf u_delay2_stb2 (.X(wb_stb_d3),.A(wb_stb_d2));
+always_ff @(negedge wbm_rst_n or posedge wbm_clk_i) begin
+ if ( wbm_rst_n == 1'b0 ) begin
+ wb_req <= '0;
+ wb_dat_o <= '0;
+ wb_ack_o <= '0;
+ wb_err_o <= '0;
+ end else begin
+ wb_req <= wb_stb_d3 && ((wb_ack_o == 0) && (wb_ack_o1 == 0)) ;
+ wb_ack_o <= wb_ack_o1;
+ wb_err_o <= wb_err_o1;
+ if(wb_ack_o1) // Keep last data in the bus
+ wb_dat_o <= wb_dat_o1;
+ end
+end
+
+
+//-----------------------------------------------------------------------
+// Local register decide based on address[31] == 1
+//
+// Locally there register are define to control the reset and clock for user
+// area
+//-----------------------------------------------------------------------
+// caravel user space is 0x3000_0000 to 0x30FF_FFFF
+// So we have allocated
+// 0x3080_0000 - 0x3080_00FF - Assigned to WB Host Address Space
+// Since We need more than 16MB Address space to access SDRAM/SPI we have
+// added indirect MSB 8 bit address select option
+// So Address will be {Bank_Sel[7:0], wbm_adr_i[23:0}
+// ---------------------------------------------------------------------
+assign reg_sel = wb_req & (wb_adr_i[23] == 1'b1);
+
+assign sw_addr = wb_adr_i [3:2];
+assign sw_rd_en = reg_sel & !wb_we_i;
+assign sw_wr_en = reg_sel & wb_we_i;
+
+assign sw_wr_en_0 = sw_wr_en && (sw_addr==0);
+assign sw_wr_en_1 = sw_wr_en && (sw_addr==1);
+assign sw_wr_en_2 = sw_wr_en && (sw_addr==2);
+assign sw_wr_en_3 = sw_wr_en && (sw_addr==3);
+
+always @ (posedge wbm_clk_i or negedge wbm_rst_n)
+begin : preg_out_Seq
+ if (wbm_rst_n == 1'b0)
+ begin
+ reg_rdata <= 'h0;
+ reg_ack <= 1'b0;
+ end
+ else if (sw_rd_en && !reg_ack)
+ begin
+ reg_rdata <= reg_out ;
+ reg_ack <= 1'b1;
+ end
+ else if (sw_wr_en && !reg_ack)
+ reg_ack <= 1'b1;
+ else
+ begin
+ reg_ack <= 1'b0;
+ end
+end
+
+
+//-------------------------------------
+// Global + Clock Control
+// -------------------------------------
+assign cfg_glb_ctrl = reg_0[8:0];
+assign cfg_wb_clk_ctrl = reg_0[11:9];
+assign cfg_rtc_clk_ctrl = reg_0[19:12];
+assign cfg_cpu_clk_ctrl = reg_0[23:20];
+assign cfg_usb_clk_ctrl = reg_0[31:28];
+
+
+always @( *)
+begin
+ reg_out [31:0] = 8'd0;
+
+ case (sw_addr [1:0])
+ 2'b00 : reg_out [31:0] = reg_0;
+ 2'b01 : reg_out [31:0] = {24'h0,cfg_bank_sel [7:0]};
+ 2'b10 : reg_out [31:0] = cfg_clk_ctrl1 [31:0];
+ 2'b11 : reg_out [31:0] = cfg_clk_ctrl2 [31:0];
+ default : reg_out [31:0] = 'h0;
+ endcase
+end
+
+
+
+generic_register #(32,0 ) u_glb_ctrl (
+ .we ({32{sw_wr_en_0}} ),
+ .data_in (wb_dat_i[31:0] ),
+ .reset_n (wbm_rst_n ),
+ .clk (wbm_clk_i ),
+
+ //List of Outs
+ .data_out (reg_0[31:0])
+ );
+
+generic_register #(8,8'h10 ) u_bank_sel (
+ .we ({8{sw_wr_en_1}} ),
+ .data_in (wb_dat_i[7:0] ),
+ .reset_n (wbm_rst_n ),
+ .clk (wbm_clk_i ),
+
+ //List of Outs
+ .data_out (cfg_bank_sel[7:0] )
+ );
+
+
+generic_register #(32,0 ) u_clk_ctrl1 (
+ .we ({32{sw_wr_en_2}} ),
+ .data_in (wb_dat_i[31:0] ),
+ .reset_n (wbm_rst_n ),
+ .clk (wbm_clk_i ),
+
+ //List of Outs
+ .data_out (cfg_clk_ctrl1[31:0])
+ );
+
+generic_register #(32,0 ) u_clk_ctrl2 (
+ .we ({32{sw_wr_en_3}} ),
+ .data_in (wb_dat_i[31:0] ),
+ .reset_n (wbm_rst_n ),
+ .clk (wbm_clk_i ),
+
+ //List of Outs
+ .data_out (cfg_clk_ctrl2[31:0])
+ );
+
+
+assign wb_stb_int = wb_req & !reg_sel;
+
+// Since design need more than 16MB address space, we have implemented
+// indirect access
+assign wb_adr_int = {cfg_bank_sel[7:0],wb_adr_i[23:0]};
+
+async_wb u_async_wb(
+// Master Port
+ .wbm_rst_n (wbm_rst_n ),
+ .wbm_clk_i (wbm_clk_i ),
+ .wbm_cyc_i (wb_cyc_i ),
+ .wbm_stb_i (wb_stb_int ),
+ .wbm_adr_i (wb_adr_int ),
+ .wbm_we_i (wb_we_i ),
+ .wbm_dat_i (wb_dat_i ),
+ .wbm_sel_i (wb_sel_i ),
+ .wbm_dat_o (wb_dat_int ),
+ .wbm_ack_o (wb_ack_int ),
+ .wbm_err_o (wb_err_int ),
+
+// Slave Port
+ .wbs_rst_n (wbs_rst_n ),
+ .wbs_clk_i (wbs_clk_i ),
+ .wbs_cyc_o (wbs_cyc_o ),
+ .wbs_stb_o (wbs_stb_o ),
+ .wbs_adr_o (wbs_adr_o ),
+ .wbs_we_o (wbs_we_o ),
+ .wbs_dat_o (wbs_dat_o ),
+ .wbs_sel_o (wbs_sel_o ),
+ .wbs_dat_i (wbs_dat_i ),
+ .wbs_ack_i (wbs_ack_i ),
+ .wbs_err_i (wbs_err_i )
+
+ );
+
+
+//----------------------------------
+// Generate Internal WishBone Clock
+//----------------------------------
+logic wb_clk_div;
+logic cfg_wb_clk_div;
+logic [1:0] cfg_wb_clk_ratio;
+
+assign cfg_wb_clk_ratio = cfg_wb_clk_ctrl[1:0];
+assign cfg_wb_clk_div = cfg_wb_clk_ctrl[2];
+
+
+//assign wbs_clk_out = (cfg_wb_clk_div) ? wb_clk_div : wbm_clk_i;
+ctech_mux2x1 u_wbs_clk_sel (.A0 (wbm_clk_i), .A1 (wb_clk_div), .S (cfg_wb_clk_div), .X (wbs_clk_out));
+
+
+clk_ctl #(1) u_wbclk (
+ // Outputs
+ .clk_o (wb_clk_div ),
+ // Inputs
+ .mclk (wbm_clk_i ),
+ .reset_n (wbm_rst_n ),
+ .clk_div_ratio (cfg_wb_clk_ratio )
+ );
+
+
+//----------------------------------
+// Generate CORE Clock Generation
+//----------------------------------
+wire cpu_clk_div;
+wire cpu_ref_clk;
+wire cpu_clk_int;
+
+wire cfg_cpu_clk_src_sel = cfg_cpu_clk_ctrl[3];
+wire cfg_cpu_clk_div = cfg_cpu_clk_ctrl[2];
+wire [1:0] cfg_cpu_clk_ratio = cfg_cpu_clk_ctrl[1:0];
+
+//assign cpu_ref_clk = (cfg_cpu_clk_src_sel) ? user_clock2 : user_clock1;
+//assign cpu_clk_int = (cfg_cpu_clk_div) ? cpu_clk_div : cpu_ref_clk;
+
+ctech_mux2x1 u_cpu_ref_sel (.A0 (user_clock1), .A1 (user_clock2), .S (cfg_cpu_clk_src_sel), .X (cpu_ref_clk));
+ctech_mux2x1 u_cpu_clk_sel (.A0 (cpu_ref_clk), .A1 (cpu_clk_div), .S (cfg_cpu_clk_div), .X (cpu_clk_int));
+
+ctech_clk_buf u_clkbuf_cpu (.A (cpu_clk_int), . X(cpu_clk));
+
+clk_ctl #(1) u_cpuclk (
+ // Outputs
+ .clk_o (cpu_clk_div ),
+ // Inputs
+ .mclk (cpu_ref_clk ),
+ .reset_n (wbm_rst_n ),
+ .clk_div_ratio (cfg_cpu_clk_ratio)
+ );
+
+//----------------------------------
+// Generate RTC Clock Generation
+//----------------------------------
+wire rtc_clk_div;
+wire [7:0] cfg_rtc_clk_ratio = cfg_rtc_clk_ctrl[7:0];
+
+
+ctech_clk_buf u_clkbuf_rtc (.A (rtc_clk_div), . X(rtc_clk));
+
+clk_ctl #(7) u_rtcclk (
+ // Outputs
+ .clk_o (rtc_clk_div ),
+ // Inputs
+ .mclk (user_clock2 ),
+ .reset_n (wbm_rst_n ),
+ .clk_div_ratio (cfg_rtc_clk_ratio)
+ );
+
+
+//----------------------------------
+// Generate USB Clock Generation
+//----------------------------------
+wire usb_clk_div;
+wire usb_ref_clk;
+wire usb_clk_int;
+
+wire cfg_usb_clk_div = cfg_usb_clk_ctrl[3];
+wire [2:0] cfg_usb_clk_ratio = cfg_usb_clk_ctrl[2:0];
+
+assign usb_ref_clk = user_clock2 ;
+//assign usb_clk_int = (cfg_usb_clk_div) ? usb_clk_div : usb_ref_clk;
+ctech_mux2x1 u_usb_clk_sel (.A0 (usb_ref_clk), .A1 (usb_clk_div), .S (cfg_usb_clk_div), .X (usb_clk_int));
+
+
+ctech_clk_buf u_clkbuf_usb (.A (usb_clk_int), . X(usb_clk));
+
+clk_ctl #(2) u_usbclk (
+ // Outputs
+ .clk_o (usb_clk_div ),
+ // Inputs
+ .mclk (usb_ref_clk ),
+ .reset_n (wbm_rst_n ),
+ .clk_div_ratio (cfg_usb_clk_ratio)
+ );
+
+endmodule
diff --git a/verilog/rtl/wb_interconnect/src/wb_arb.sv b/verilog/rtl/wb_interconnect/src/wb_arb.sv
new file mode 100644
index 0000000..aefac4a
--- /dev/null
+++ b/verilog/rtl/wb_interconnect/src/wb_arb.sv
@@ -0,0 +1,146 @@
+//////////////////////////////////////////////////////////////////////////////
+// SPDX-FileCopyrightText: 2021 , Dinesh Annayya
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+// SPDX-License-Identifier: Apache-2.0
+// SPDX-FileContributor: Created by Dinesh Annayya <dinesha@opencores.org>
+//
+//////////////////////////////////////////////////////////////////////
+//// ////
+//// Wishbone Arbitor ////
+//// ////
+//// This file is part of the YIFive cores project ////
+//// https://github.com/dineshannayya/yifive_r0.git ////
+//// http://www.opencores.org/cores/yifive/ ////
+//// ////
+//// Description ////
+//// This block implement simple round robine request ////
+// arbitor for wishbone interface. ////
+//// ////
+//// To Do: ////
+//// nothing ////
+//// ////
+//// Author(s): ////
+//// - Dinesh Annayya, dinesha@opencores.org ////
+//// ////
+//// Revision : ////
+//// 0.1 - 12th June 2021, Dinesh A ////
+//// ////
+//////////////////////////////////////////////////////////////////////
+//// ////
+//// Copyright (C) 2000 Authors and OPENCORES.ORG ////
+//// ////
+//// This source file may be used and distributed without ////
+//// restriction provided that this copyright statement is not ////
+//// removed from the file and that any derivative work contains ////
+//// the original copyright notice and the associated disclaimer. ////
+//// ////
+//// This source file is free software; you can redistribute it ////
+//// and/or modify it under the terms of the GNU Lesser General ////
+//// Public License as published by the Free Software Foundation; ////
+//// either version 2.1 of the License, or (at your option) any ////
+//// later version. ////
+//// ////
+//// This source is distributed in the hope that it will be ////
+//// useful, but WITHOUT ANY WARRANTY; without even the implied ////
+//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR ////
+//// PURPOSE. See the GNU Lesser General Public License for more ////
+//// details. ////
+//// ////
+//// You should have received a copy of the GNU Lesser General ////
+//// Public License along with this source; if not, download it ////
+//// from http://www.opencores.org/lgpl.shtml ////
+//// ////
+//////////////////////////////////////////////////////////////////////
+
+
+module wb_arb(clk, rstn, req, gnt);
+
+input clk;
+input rstn;
+input [3:0] req; // Req input
+output [1:0] gnt; // Grant output
+
+///////////////////////////////////////////////////////////////////////
+//
+// Parameters
+//
+
+
+parameter [1:0]
+ grant0 = 3'h0,
+ grant1 = 3'h1,
+ grant2 = 3'h2,
+ grant3 = 3'h3;
+
+///////////////////////////////////////////////////////////////////////
+// Local Registers and Wires
+//////////////////////////////////////////////////////////////////////
+
+reg [1:0] state, next_state;
+
+///////////////////////////////////////////////////////////////////////
+// Misc Logic
+//////////////////////////////////////////////////////////////////////
+
+assign gnt = state;
+
+always@(posedge clk or negedge rstn)
+ if(!rstn) state <= grant0;
+ else state <= next_state;
+
+///////////////////////////////////////////////////////////////////////
+//
+// Next State Logic
+// - implements round robin arbitration algorithm
+// - switches grant if current req is dropped or next is asserted
+// - parks at last grant
+//////////////////////////////////////////////////////////////////////
+
+always@(state or req )
+ begin
+ next_state = state; // Default Keep State
+ case(state)
+ grant0:
+ // if this req is dropped or next is asserted, check for other req's
+ if(!req[0] ) begin
+ if(req[1]) next_state = grant1;
+ else if(req[2]) next_state = grant2;
+ else if(req[3]) next_state = grant3;
+ end
+ grant1:
+ // if this req is dropped or next is asserted, check for other req's
+ if(!req[1] ) begin
+ if(req[2]) next_state = grant2;
+ if(req[3]) next_state = grant3;
+ else if(req[0]) next_state = grant0;
+ end
+ grant2:
+ // if this req is dropped or next is asserted, check for other req's
+ if(!req[2] ) begin
+ if(req[0]) next_state = grant0;
+ else if(req[1]) next_state = grant1;
+ else if(req[3]) next_state = grant3;
+ end
+ grant3:
+ // if this req is dropped or next is asserted, check for other req's
+ if(!req[3] ) begin
+ if(req[0]) next_state = grant0;
+ else if(req[1]) next_state = grant1;
+ else if(req[2]) next_state = grant2;
+ end
+ endcase
+ end
+
+endmodule
+
diff --git a/verilog/rtl/wb_interconnect/src/wb_interconnect.sv b/verilog/rtl/wb_interconnect/src/wb_interconnect.sv
new file mode 100644
index 0000000..ef22d72
--- /dev/null
+++ b/verilog/rtl/wb_interconnect/src/wb_interconnect.sv
@@ -0,0 +1,609 @@
+//////////////////////////////////////////////////////////////////////////////
+// SPDX-FileCopyrightText: 2021 , Dinesh Annayya
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+// SPDX-License-Identifier: Apache-2.0
+// SPDX-FileContributor: Created by Dinesh Annayya <dinesha@opencores.org>
+//
+//////////////////////////////////////////////////////////////////////
+//// ////
+//// Wishbone Interconnect ////
+//// ////
+//// This file is part of the YIFive cores project ////
+//// https://github.com/dineshannayya/yifive_r0.git ////
+//// http://www.opencores.org/cores/yifive/ ////
+//// ////
+//// Description ////
+//// 1. 3 masters and 3 slaves share bus Wishbone connection ////
+//// 2. This block implement simple round robine request ////
+//// ////
+//// To Do: ////
+//// nothing ////
+//// ////
+//// Author(s): ////
+//// - Dinesh Annayya, dinesha@opencores.org ////
+//// ////
+//// Revision : ////
+//// 0.1 - 12th June 2021, Dinesh A ////
+//// 0.2 - 17th June 2021, Dinesh A ////
+//// Stagging FF added at Slave Interface to break ////
+//// path ////
+//// 0.3 - 21th June 2021, Dinesh A ////
+//// slave port 3 added for uart ////
+//// 0.4 - 25th June 2021, Dinesh A ////
+//// External Memory Map changed and made same as ////
+//// internal memory map ////
+//// 0.4 - 27th June 2021, Dinesh A ////
+//// unused tie off at digital core level brought inside ////
+//// to avoid core level power hook up ////
+//// 0.5 - 28th June 2021, Dinesh A ////
+//// interchange the Master port for better physical ////
+//// placement ////
+//// m0: external host ////
+//// m1: risc imem ////
+//// m2: risc dmem ////
+//// 0.6 - 06 Nov 2021, Dinesh A ////
+//// Push the clock skew logic inside the block due to ////
+//// global power hooking challanges for small block at ////
+//// top level ////
+//// 0.7 - 07 Dec 2021, Dinesh A ////
+//// Buffer channel are added insider wb_inter to simply ////
+//// global routing ////
+//// 0.8 -10 Dec 2021 , Dinesh A ////
+//// two more slave port added for MBIST and ADC port ////
+//// removed ////
+//// Memory remap added to move the RISC Program memory ////
+//// to SRAM Memory ////
+//// 0.9 - 15 Dec 2021, Dinesh A ////
+//// Consolidated 4 MBIST port into one 8KB Port ////
+//// ////
+//////////////////////////////////////////////////////////////////////
+//// ////
+//// Copyright (C) 2000 Authors and OPENCORES.ORG ////
+//// ////
+//// This source file may be used and distributed without ////
+//// restriction provided that this copyright statement is not ////
+//// removed from the file and that any derivative work contains ////
+//// the original copyright notice and the associated disclaimer. ////
+//// ////
+//// This source file is free software; you can redistribute it ////
+//// and/or modify it under the terms of the GNU Lesser General ////
+//// Public License as published by the Free Software Foundation; ////
+//// either version 2.1 of the License, or (at your option) any ////
+//// later version. ////
+//// ////
+//// This source is distributed in the hope that it will be ////
+//// useful, but WITHOUT ANY WARRANTY; without even the implied ////
+//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR ////
+//// PURPOSE. See the GNU Lesser General Public License for more ////
+//// details. ////
+//// ////
+//// You should have received a copy of the GNU Lesser General ////
+//// Public License along with this source; if not, download it ////
+//// from http://www.opencores.org/lgpl.shtml ////
+//// ////
+//////////////////////////////////////////////////////////////////////
+
+
+
+module wb_interconnect #(
+ parameter CH_CLK_WD = 7,
+ parameter CH_DATA_WD = 103
+ ) (
+`ifdef USE_POWER_PINS
+ input logic vccd1, // User area 1 1.8V supply
+ input logic vssd1, // User area 1 digital ground
+`endif
+ // Bus repeaters
+ input [CH_CLK_WD-1:0] ch_clk_in,
+ output [CH_CLK_WD-1:0] ch_clk_out,
+ input [CH_DATA_WD-1:0] ch_data_in,
+ output [CH_DATA_WD-1:0]ch_data_out,
+
+ // Clock Skew Adjust
+ input logic [3:0] cfg_cska_wi,
+ input logic wbd_clk_int,
+ output logic wbd_clk_wi,
+
+
+ input logic clk_i,
+ input logic rst_n,
+
+ input logic [3:0] boot_remap, // When remap is enabled
+ // [0] - 0x0000_0000 - 0x0000_07FF Map to MBIST1
+ // [1] - 0x0000_0800 - 0x0000_0FFF Map to MBIST2
+ // [2] - 0x0000_1000 - 0x0000_17FF Map to MBIST3
+ // [3] - 0x0000_1800 - 0x0000_1FFF Map to MBIST4
+ input logic [3:0] dcache_remap, // When dcache remap is enabled,
+ // [0] - 0x0800_0000 - 0x0800_07FF Map to MBIST1
+ // [1] - 0x0800_0800 - 0x0800_0FFF Map to MBIST2
+ // [2] - 0x0800_1000 - 0x0800_17FF Map to MBIST3
+ // [3] - 0x0800_1800 - 0x0800_1FFF Map to MBIST4
+
+ // Master 0 Interface
+ input logic [31:0] m0_wbd_dat_i,
+ input logic [31:0] m0_wbd_adr_i,
+ input logic [3:0] m0_wbd_sel_i,
+ input logic m0_wbd_we_i,
+ input logic m0_wbd_cyc_i,
+ input logic m0_wbd_stb_i,
+ output logic [31:0] m0_wbd_dat_o,
+ output logic m0_wbd_ack_o,
+ output logic m0_wbd_lack_o,
+ output logic m0_wbd_err_o,
+
+ // Master 1 Interface
+ input logic [31:0] m1_wbd_dat_i,
+ input logic [31:0] m1_wbd_adr_i,
+ input logic [3:0] m1_wbd_sel_i,
+ input logic m1_wbd_we_i,
+ input logic m1_wbd_cyc_i,
+ input logic m1_wbd_stb_i,
+ output logic [31:0] m1_wbd_dat_o,
+ output logic m1_wbd_ack_o,
+ output logic m1_wbd_lack_o,
+ output logic m1_wbd_err_o,
+
+ // Master 2 Interface
+ input logic [31:0] m2_wbd_dat_i,
+ input logic [31:0] m2_wbd_adr_i,
+ input logic [3:0] m2_wbd_sel_i,
+ input logic [9:0] m2_wbd_bl_i,
+ input logic m2_wbd_bry_i,
+ input logic m2_wbd_we_i,
+ input logic m2_wbd_cyc_i,
+ input logic m2_wbd_stb_i,
+ output logic [31:0] m2_wbd_dat_o,
+ output logic m2_wbd_ack_o,
+ output logic m2_wbd_lack_o,
+ output logic m2_wbd_err_o,
+
+ // Master 3 Interface
+ input logic [31:0] m3_wbd_adr_i,
+ input logic [3:0] m3_wbd_sel_i,
+ input logic [9:0] m3_wbd_bl_i,
+ input logic m3_wbd_bry_i,
+ input logic m3_wbd_we_i,
+ input logic m3_wbd_cyc_i,
+ input logic m3_wbd_stb_i,
+ output logic [31:0] m3_wbd_dat_o,
+ output logic m3_wbd_ack_o,
+ output logic m3_wbd_lack_o,
+ output logic m3_wbd_err_o,
+
+ // Slave 0 Interface
+ input logic [31:0] s0_wbd_dat_i,
+ input logic s0_wbd_ack_i,
+ input logic s0_wbd_lack_i,
+ //input logic s0_wbd_err_i, - unused
+ output logic [31:0] s0_wbd_dat_o,
+ output logic [31:0] s0_wbd_adr_o,
+ output logic [3:0] s0_wbd_sel_o,
+ output logic [9:0] s0_wbd_bl_o,
+ output logic s0_wbd_bry_o,
+ output logic s0_wbd_we_o,
+ output logic s0_wbd_cyc_o,
+ output logic s0_wbd_stb_o,
+
+ // Slave 1 Interface
+ input logic [31:0] s1_wbd_dat_i,
+ input logic s1_wbd_ack_i,
+ // input logic s1_wbd_err_i, - unused
+ output logic [31:0] s1_wbd_dat_o,
+ output logic [7:0] s1_wbd_adr_o,
+ output logic [3:0] s1_wbd_sel_o,
+ output logic s1_wbd_we_o,
+ output logic s1_wbd_cyc_o,
+ output logic s1_wbd_stb_o,
+
+ // Slave 2 Interface
+ input logic [31:0] s2_wbd_dat_i,
+ input logic s2_wbd_ack_i,
+ // input logic s2_wbd_err_i, - unused
+ output logic [31:0] s2_wbd_dat_o,
+ output logic [7:0] s2_wbd_adr_o, // glbl reg need only 8 bits
+ output logic [3:0] s2_wbd_sel_o,
+ output logic s2_wbd_we_o,
+ output logic s2_wbd_cyc_o,
+ output logic s2_wbd_stb_o,
+
+ // Slave 3 Interface
+ // MBIST
+ input logic [31:0] s3_wbd_dat_i,
+ input logic s3_wbd_ack_i,
+ input logic s3_wbd_lack_i,
+ // input logic s3_wbd_err_i,
+ output logic [31:0] s3_wbd_dat_o,
+ output logic [12:0] s3_wbd_adr_o,
+ output logic [3:0] s3_wbd_sel_o,
+ output logic [9:0] s3_wbd_bl_o,
+ output logic s3_wbd_bry_o,
+ output logic s3_wbd_we_o,
+ output logic s3_wbd_cyc_o,
+ output logic s3_wbd_stb_o
+ );
+
+////////////////////////////////////////////////////////////////////
+//
+// Type define
+//
+
+parameter TARGET_SPI_MEM = 4'b0000;
+parameter TARGET_SPI_REG = 4'b0000;
+parameter TARGET_UART = 4'b0001;
+parameter TARGET_PINMUX = 4'b0010;
+parameter TARGET_MBIST = 4'b0011;
+
+// WishBone Wr Interface
+typedef struct packed {
+ logic [31:0] wbd_dat;
+ logic [31:0] wbd_adr;
+ logic [3:0] wbd_sel;
+ logic [9:0] wbd_bl;
+ logic wbd_bry;
+ logic wbd_we;
+ logic wbd_cyc;
+ logic wbd_stb;
+ logic [3:0] wbd_tid; // target id
+} type_wb_wr_intf;
+
+// WishBone Rd Interface
+typedef struct packed {
+ logic [31:0] wbd_dat;
+ logic wbd_ack;
+ logic wbd_lack;
+ logic wbd_err;
+} type_wb_rd_intf;
+
+
+// Master Write Interface
+type_wb_wr_intf m0_wb_wr;
+type_wb_wr_intf m1_wb_wr;
+type_wb_wr_intf m2_wb_wr;
+type_wb_wr_intf m3_wb_wr;
+
+// Master Read Interface
+type_wb_rd_intf m0_wb_rd;
+type_wb_rd_intf m1_wb_rd;
+type_wb_rd_intf m2_wb_rd;
+type_wb_rd_intf m3_wb_rd;
+
+// Slave Write Interface
+type_wb_wr_intf s0_wb_wr;
+type_wb_wr_intf s1_wb_wr;
+type_wb_wr_intf s2_wb_wr;
+type_wb_wr_intf s3_wb_wr;
+
+// Slave Read Interface
+type_wb_rd_intf s0_wb_rd;
+type_wb_rd_intf s1_wb_rd;
+type_wb_rd_intf s2_wb_rd;
+type_wb_rd_intf s3_wb_rd;
+
+
+type_wb_wr_intf m_bus_wr; // Multiplexed Master I/F
+type_wb_rd_intf m_bus_rd; // Multiplexed Slave I/F
+
+type_wb_wr_intf s_bus_wr; // Multiplexed Master I/F
+type_wb_rd_intf s_bus_rd; // Multiplexed Slave I/F
+
+// channel repeater
+assign ch_clk_out = ch_clk_in;
+assign ch_data_out = ch_data_in;
+
+// Wishbone interconnect clock skew control
+clk_skew_adjust u_skew_wi
+ (
+`ifdef USE_POWER_PINS
+ .vccd1 (vccd1 ),// User area 1 1.8V supply
+ .vssd1 (vssd1 ),// User area 1 digital ground
+`endif
+ .clk_in (wbd_clk_int ),
+ .sel (cfg_cska_wi ),
+ .clk_out (wbd_clk_wi )
+ );
+
+//-------------------------------------------------------------------
+// EXTERNAL MEMORY MAP
+// 0x0000_0000 to 0x0FFF_FFFF - QSPI MEMORY
+// 0x1000_0000 to 0x1000_00FF - QSPIM REG
+// 0x1001_0000 to 0x1001_003F - UART
+// 0x1001_0040 to 0x1001_007F - I2C
+// 0x1001_0080 to 0x1001_00BF - USB
+// 0x1001_00C0 to 0x1001_00FF - SSPIM
+// 0x1002_0000 to 0x1002_00FF - PINMUX
+// 0x1003_0000 to 0x1003_07FF - SRAM-0 (2KB)
+// 0x1003_0800 to 0x1003_0FFF - SRAM-1 (2KB)
+// 0x1003_1000 to 0x1003_17FF - SRAM-2 (2KB)
+// 0x1003_1800 to 0x1003_1FFF - SRAM-3 (2KB)
+// 0x3080_0000 to 0x3080_00FF - WB HOST (This decoding happens at wb_host block)
+// ---------------------------------------------------------------------------
+//
+wire [3:0] m0_wbd_tid_i = (m0_wbd_adr_i[31:28] == 4'b0000 ) ? TARGET_SPI_MEM : // SPI
+ (m0_wbd_adr_i[31:16] == 16'h1000 ) ? TARGET_SPI_REG : // SPI REG
+ (m0_wbd_adr_i[31:16] == 16'h1001 ) ? TARGET_UART : // UART/I2C/USB/SPI
+ (m0_wbd_adr_i[31:16] == 16'h1002 ) ? TARGET_PINMUX : // PINMUX
+ (m0_wbd_adr_i[31:16] == 16'h1003 ) ? TARGET_MBIST : // MBIST
+ 4'b0000;
+
+//------------------------------
+// RISC Data Memory Map
+// 0x0000_0000 to 0x0FFF_FFFF - QSPIM MEMORY
+// 0x1000_0000 to 0x1000_00FF - QSPIM REG
+// 0x1001_0000 to 0x1001_003F - UART
+// 0x1001_0040 to 0x1001_007F - I2
+// 0x1001_0080 to 0x1001_00BF - USB
+// 0x1001_00C0 to 0x1001_00FF - SSPIM
+// 0x1002_0000 to 0x1002_00FF - PINMUX
+// 0x1003_0000 to 0x1003_07FF - SRAM-0 (2KB)
+// 0x1003_0800 to 0x1003_0FFF - SRAM-1 (2KB)
+// 0x1003_1000 to 0x1003_17FF - SRAM-2 (2KB)
+// 0x1003_1800 to 0x1003_1FFF - SRAM-3 (2KB)
+//-----------------------------
+//
+wire [3:0] m1_wbd_tid_i = (boot_remap[0] && m1_wbd_adr_i[31:11] == 21'h0) ? TARGET_MBIST:
+ (boot_remap[1] && m1_wbd_adr_i[31:11] == 21'h1) ? TARGET_MBIST:
+ (boot_remap[2] && m1_wbd_adr_i[31:11] == 21'h2) ? TARGET_MBIST:
+ (boot_remap[3] && m1_wbd_adr_i[31:11] == 21'h3) ? TARGET_MBIST:
+ (dcache_remap[0] && m1_wbd_adr_i[31:11] == 21'b0000_1000_0000_0000_0000_0) ? TARGET_MBIST:
+ (dcache_remap[1] && m1_wbd_adr_i[31:11] == 21'b0000_1000_0000_0000_0000_1) ? TARGET_MBIST:
+ (dcache_remap[2] && m1_wbd_adr_i[31:11] == 21'b0000_1000_0000_0000_0001_0) ? TARGET_MBIST:
+ (dcache_remap[3] && m1_wbd_adr_i[31:11] == 21'b0000_1000_0000_0000_0001_1) ? TARGET_MBIST:
+ (m1_wbd_adr_i[31:28] == 4'b0000 ) ? TARGET_SPI_MEM :
+ (m1_wbd_adr_i[31:16] == 16'h1000 ) ? TARGET_SPI_REG :
+ (m1_wbd_adr_i[31:16] == 16'h1001 ) ? TARGET_UART :
+ (m1_wbd_adr_i[31:16] == 16'h1002 ) ? TARGET_PINMUX :
+ (m1_wbd_adr_i[31:16] == 16'h1003 ) ? TARGET_MBIST :
+ 4'b0000;
+
+wire [3:0] m2_wbd_tid_i = (boot_remap[0] && m2_wbd_adr_i[31:11] == 21'h0) ? TARGET_MBIST:
+ (boot_remap[1] && m2_wbd_adr_i[31:11] == 21'h1) ? TARGET_MBIST:
+ (boot_remap[2] && m2_wbd_adr_i[31:11] == 21'h2) ? TARGET_MBIST:
+ (boot_remap[3] && m2_wbd_adr_i[31:11] == 21'h3) ? TARGET_MBIST:
+ (dcache_remap[0] && m2_wbd_adr_i[31:11] == 21'b0000_1000_0000_0000_0000_0) ? TARGET_MBIST:
+ (dcache_remap[1] && m2_wbd_adr_i[31:11] == 21'b0000_1000_0000_0000_0000_1) ? TARGET_MBIST:
+ (dcache_remap[2] && m2_wbd_adr_i[31:11] == 21'b0000_1000_0000_0000_0001_0) ? TARGET_MBIST:
+ (dcache_remap[3] && m2_wbd_adr_i[31:11] == 21'b0000_1000_0000_0000_0001_1) ? TARGET_MBIST:
+ (m2_wbd_adr_i[31:28] == 4'b0000 ) ? TARGET_SPI_MEM :
+ (m2_wbd_adr_i[31:16] == 16'h1000 ) ? TARGET_SPI_REG :
+ (m2_wbd_adr_i[31:16] == 16'h1001 ) ? TARGET_UART :
+ (m2_wbd_adr_i[31:16] == 16'h1002 ) ? TARGET_PINMUX :
+ (m2_wbd_adr_i[31:16] == 16'h1003 ) ? TARGET_MBIST :
+ 4'b0000;
+wire [3:0] m3_wbd_tid_i = (boot_remap[0] && m3_wbd_adr_i[31:11] == 21'h0) ? TARGET_MBIST:
+ (boot_remap[1] && m3_wbd_adr_i[31:11] == 21'h1) ? TARGET_MBIST:
+ (boot_remap[2] && m3_wbd_adr_i[31:11] == 21'h2) ? TARGET_MBIST:
+ (boot_remap[3] && m3_wbd_adr_i[31:11] == 21'h3) ? TARGET_MBIST:
+ (dcache_remap[0] && m3_wbd_adr_i[31:11] == 21'b0000_1000_0000_0000_0000_0) ? TARGET_MBIST:
+ (dcache_remap[1] && m3_wbd_adr_i[31:11] == 21'b0000_1000_0000_0000_0000_1) ? TARGET_MBIST:
+ (dcache_remap[2] && m3_wbd_adr_i[31:11] == 21'b0000_1000_0000_0000_0001_0) ? TARGET_MBIST:
+ (dcache_remap[3] && m3_wbd_adr_i[31:11] == 21'b0000_1000_0000_0000_0001_1) ? TARGET_MBIST:
+ (m3_wbd_adr_i[31:28] == 4'b0000 ) ? TARGET_SPI_MEM :
+ (m3_wbd_adr_i[31:16] == 16'h1000 ) ? TARGET_SPI_REG :
+ (m3_wbd_adr_i[31:16] == 16'h1001 ) ? TARGET_UART :
+ (m3_wbd_adr_i[31:16] == 16'h1002 ) ? TARGET_PINMUX :
+ (m3_wbd_adr_i[31:16] == 16'h1003 ) ? TARGET_MBIST :
+ 4'b0000;
+//----------------------------------------
+// Master Mapping
+// -------------------------------------
+assign m0_wb_wr.wbd_dat = m0_wbd_dat_i;
+assign m0_wb_wr.wbd_adr = {m0_wbd_adr_i[31:2],2'b00};
+assign m0_wb_wr.wbd_sel = m0_wbd_sel_i;
+assign m0_wb_wr.wbd_bl = 'h1;
+assign m0_wb_wr.wbd_bry = 'b1;
+assign m0_wb_wr.wbd_we = m0_wbd_we_i;
+assign m0_wb_wr.wbd_cyc = m0_wbd_cyc_i;
+assign m0_wb_wr.wbd_stb = m0_wbd_stb_i;
+assign m0_wb_wr.wbd_tid = m0_wbd_tid_i;
+
+assign m1_wb_wr.wbd_dat = m1_wbd_dat_i;
+assign m1_wb_wr.wbd_adr = {m1_wbd_adr_i[31:2],2'b00};
+assign m1_wb_wr.wbd_sel = m1_wbd_sel_i;
+assign m1_wb_wr.wbd_bl = 'h1;
+assign m1_wb_wr.wbd_bry = 'b1;
+assign m1_wb_wr.wbd_we = m1_wbd_we_i;
+assign m1_wb_wr.wbd_cyc = m1_wbd_cyc_i;
+assign m1_wb_wr.wbd_stb = m1_wbd_stb_i;
+assign m1_wb_wr.wbd_tid = m1_wbd_tid_i;
+
+assign m2_wb_wr.wbd_dat = m2_wbd_dat_i;
+assign m2_wb_wr.wbd_adr = {m2_wbd_adr_i[31:2],2'b00};
+assign m2_wb_wr.wbd_sel = m2_wbd_sel_i;
+assign m2_wb_wr.wbd_bl = m2_wbd_bl_i;
+assign m2_wb_wr.wbd_bry = m2_wbd_bry_i;
+assign m2_wb_wr.wbd_we = m2_wbd_we_i;
+assign m2_wb_wr.wbd_cyc = m2_wbd_cyc_i;
+assign m2_wb_wr.wbd_stb = m2_wbd_stb_i;
+assign m2_wb_wr.wbd_tid = m2_wbd_tid_i;
+
+assign m3_wb_wr.wbd_dat = 'h0;
+assign m3_wb_wr.wbd_adr = {m3_wbd_adr_i[31:2],2'b00};
+assign m3_wb_wr.wbd_sel = m3_wbd_sel_i;
+assign m3_wb_wr.wbd_bl = m3_wbd_bl_i;
+assign m3_wb_wr.wbd_bry = m3_wbd_bry_i;
+assign m3_wb_wr.wbd_we = m3_wbd_we_i;
+assign m3_wb_wr.wbd_cyc = m3_wbd_cyc_i;
+assign m3_wb_wr.wbd_stb = m3_wbd_stb_i;
+assign m3_wb_wr.wbd_tid = m3_wbd_tid_i;
+
+assign m0_wbd_dat_o = m0_wb_rd.wbd_dat;
+assign m0_wbd_ack_o = m0_wb_rd.wbd_ack;
+assign m0_wbd_lack_o = m0_wb_rd.wbd_lack;
+assign m0_wbd_err_o = m0_wb_rd.wbd_err;
+
+assign m1_wbd_dat_o = m1_wb_rd.wbd_dat;
+assign m1_wbd_ack_o = m1_wb_rd.wbd_ack;
+assign m1_wbd_lack_o = m1_wb_rd.wbd_lack;
+assign m1_wbd_err_o = m1_wb_rd.wbd_err;
+
+assign m2_wbd_dat_o = m2_wb_rd.wbd_dat;
+assign m2_wbd_ack_o = m2_wb_rd.wbd_ack;
+assign m2_wbd_lack_o = m2_wb_rd.wbd_lack;
+assign m2_wbd_err_o = m2_wb_rd.wbd_err;
+
+assign m3_wbd_dat_o = m3_wb_rd.wbd_dat;
+assign m3_wbd_ack_o = m3_wb_rd.wbd_ack;
+assign m3_wbd_lack_o = m3_wb_rd.wbd_lack;
+assign m3_wbd_err_o = m3_wb_rd.wbd_err;
+
+//----------------------------------------
+// Slave Mapping
+// -------------------------------------
+// Masked Now and added stagging FF now
+ assign s0_wbd_dat_o = s0_wb_wr.wbd_dat ;
+ assign s0_wbd_adr_o = s0_wb_wr.wbd_adr ;
+ assign s0_wbd_sel_o = s0_wb_wr.wbd_sel ;
+ assign s0_wbd_bl_o = s0_wb_wr.wbd_bl ;
+ assign s0_wbd_bry_o = s0_wb_wr.wbd_bry ;
+ assign s0_wbd_we_o = s0_wb_wr.wbd_we ;
+ assign s0_wbd_cyc_o = s0_wb_wr.wbd_cyc ;
+ assign s0_wbd_stb_o = s0_wb_wr.wbd_stb ;
+
+ assign s1_wbd_dat_o = s1_wb_wr.wbd_dat ;
+ assign s1_wbd_adr_o = s1_wb_wr.wbd_adr[7:0] ;
+ assign s1_wbd_sel_o = s1_wb_wr.wbd_sel ;
+ assign s1_wbd_we_o = s1_wb_wr.wbd_we ;
+ assign s1_wbd_cyc_o = s1_wb_wr.wbd_cyc ;
+ assign s1_wbd_stb_o = s1_wb_wr.wbd_stb ;
+
+ assign s2_wbd_dat_o = s2_wb_wr.wbd_dat ;
+ assign s2_wbd_adr_o = s2_wb_wr.wbd_adr[7:0] ; // Global Reg Need 8 bit
+ assign s2_wbd_sel_o = s2_wb_wr.wbd_sel ;
+ assign s2_wbd_we_o = s2_wb_wr.wbd_we ;
+ assign s2_wbd_cyc_o = s2_wb_wr.wbd_cyc ;
+ assign s2_wbd_stb_o = s2_wb_wr.wbd_stb ;
+
+ assign s3_wbd_dat_o = s3_wb_wr.wbd_dat[31:0] ;
+ assign s3_wbd_adr_o = s3_wb_wr.wbd_adr[12:0] ; // MBIST Need 13 bit
+ assign s3_wbd_sel_o = s3_wb_wr.wbd_sel[3:0] ;
+ assign s3_wbd_bl_o = s3_wb_wr.wbd_bl ;
+ assign s3_wbd_bry_o = s3_wb_wr.wbd_bry ;
+ assign s3_wbd_we_o = s3_wb_wr.wbd_we ;
+ assign s3_wbd_cyc_o = s3_wb_wr.wbd_cyc ;
+ assign s3_wbd_stb_o = s3_wb_wr.wbd_stb ;
+
+
+ assign s0_wb_rd.wbd_dat = s0_wbd_dat_i ;
+ assign s0_wb_rd.wbd_ack = s0_wbd_ack_i ;
+ assign s0_wb_rd.wbd_lack = s0_wbd_lack_i ;
+ assign s0_wb_rd.wbd_err = 1'b0; // s0_wbd_err_i ; - unused
+
+ assign s1_wb_rd.wbd_dat = s1_wbd_dat_i ;
+ assign s1_wb_rd.wbd_ack = s1_wbd_ack_i ;
+ assign s1_wb_rd.wbd_lack = s1_wbd_ack_i ;
+ assign s1_wb_rd.wbd_err = 1'b0; // s1_wbd_err_i ; - unused
+
+ assign s2_wb_rd.wbd_dat = s2_wbd_dat_i ;
+ assign s2_wb_rd.wbd_ack = s2_wbd_ack_i ;
+ assign s2_wb_rd.wbd_lack = s2_wbd_ack_i ;
+ assign s2_wb_rd.wbd_err = 1'b0; // s2_wbd_err_i ; - unused
+
+ assign s3_wb_rd.wbd_dat = s3_wbd_dat_i ;
+ assign s3_wb_rd.wbd_ack = s3_wbd_ack_i ;
+ assign s3_wb_rd.wbd_lack = s3_wbd_lack_i ;
+ assign s3_wb_rd.wbd_err = 1'b0; // s3_wbd_err_i ; - unused
+
+//
+// arbitor
+//
+logic [1:0] gnt;
+
+wb_arb u_wb_arb(
+ .clk(clk_i),
+ .rstn(rst_n),
+ .req({ m3_wbd_stb_i & !m3_wbd_lack_o,
+ m2_wbd_stb_i & !m2_wbd_lack_o,
+ m1_wbd_stb_i & !m1_wbd_lack_o,
+ m0_wbd_stb_i & !m0_wbd_lack_o}),
+ .gnt(gnt)
+);
+
+
+// Generate Multiplexed Master Interface based on grant
+always_comb begin
+ case(gnt)
+ 3'h0: m_bus_wr = m0_wb_wr;
+ 3'h1: m_bus_wr = m1_wb_wr;
+ 3'h2: m_bus_wr = m2_wb_wr;
+ 3'h3: m_bus_wr = m3_wb_wr;
+ default: m_bus_wr = m0_wb_wr;
+ endcase
+end
+
+
+// Generate Multiplexed Slave Interface based on target Id
+wire [3:0] s_wbd_tid = s_bus_wr.wbd_tid; // to fix iverilog warning
+always_comb begin
+ case(s_wbd_tid)
+ 4'h0: s_bus_rd = s0_wb_rd;
+ 4'h1: s_bus_rd = s1_wb_rd;
+ 4'h2: s_bus_rd = s2_wb_rd;
+ 4'h3: s_bus_rd = s3_wb_rd;
+ default: s_bus_rd = s0_wb_rd;
+ endcase
+end
+
+
+// Connect Master => Slave
+assign s0_wb_wr = (s_wbd_tid == 3'b000) ? s_bus_wr : 'h0;
+assign s1_wb_wr = (s_wbd_tid == 3'b001) ? s_bus_wr : 'h0;
+assign s2_wb_wr = (s_wbd_tid == 3'b010) ? s_bus_wr : 'h0;
+assign s3_wb_wr = (s_wbd_tid == 3'b011) ? s_bus_wr : 'h0;
+
+// Connect Slave to Master
+assign m0_wb_rd = (gnt == 2'b00) ? m_bus_rd : 'h0;
+assign m1_wb_rd = (gnt == 2'b01) ? m_bus_rd : 'h0;
+assign m2_wb_rd = (gnt == 2'b10) ? m_bus_rd : 'h0;
+assign m3_wb_rd = (gnt == 2'b11) ? m_bus_rd : 'h0;
+
+
+// Stagging FF to break write and read timing path
+sync_wbb u_sync_wbb(
+ .clk_i (clk_i ),
+ .rst_n (rst_n ),
+ // WishBone Input master I/P
+ .wbm_dat_i (m_bus_wr.wbd_dat ),
+ .wbm_adr_i (m_bus_wr.wbd_adr ),
+ .wbm_sel_i (m_bus_wr.wbd_sel ),
+ .wbm_bl_i (m_bus_wr.wbd_bl ),
+ .wbm_bry_i (m_bus_wr.wbd_bry ),
+ .wbm_we_i (m_bus_wr.wbd_we ),
+ .wbm_cyc_i (m_bus_wr.wbd_cyc ),
+ .wbm_stb_i (m_bus_wr.wbd_stb ),
+ .wbm_tid_i (m_bus_wr.wbd_tid ),
+ .wbm_dat_o (m_bus_rd.wbd_dat ),
+ .wbm_ack_o (m_bus_rd.wbd_ack ),
+ .wbm_lack_o (m_bus_rd.wbd_lack ),
+ .wbm_err_o (m_bus_rd.wbd_err ),
+
+ // Slave Interface
+ .wbs_dat_i (s_bus_rd.wbd_dat ),
+ .wbs_ack_i (s_bus_rd.wbd_ack ),
+ .wbs_lack_i (s_bus_rd.wbd_lack ),
+ .wbs_err_i (s_bus_rd.wbd_err ),
+ .wbs_dat_o (s_bus_wr.wbd_dat ),
+ .wbs_adr_o (s_bus_wr.wbd_adr ),
+ .wbs_sel_o (s_bus_wr.wbd_sel ),
+ .wbs_bl_o (s_bus_wr.wbd_bl ),
+ .wbs_bry_o (s_bus_wr.wbd_bry ),
+ .wbs_we_o (s_bus_wr.wbd_we ),
+ .wbs_cyc_o (s_bus_wr.wbd_cyc ),
+ .wbs_stb_o (s_bus_wr.wbd_stb ),
+ .wbs_tid_o (s_bus_wr.wbd_tid )
+
+);
+
+
+endmodule
+