pull the git change from https://github.com/dineshannayya/riscduino.git on 15th Feb 2022 with SRAM
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
+