initial version of mbist
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_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..34f5989
--- /dev/null
+++ b/verilog/rtl/lib/clk_ctl.v
@@ -0,0 +1,143 @@
+//////////////////////////////////////////////////////////////////////////////
+// SPDX-FileCopyrightText: 2021 , Dinesh Annayya
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+// SPDX-License-Identifier: Apache-2.0
+// SPDX-FileContributor: Created by Dinesh Annayya <dinesha@opencores.org>
+////////////////////////////////////////////////////////////////////////
+//// ////
+//// 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 : 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: 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-1:0] high_count ; // high level counter
+reg [WD-1: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/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..b209ca0
--- /dev/null
+++ b/verilog/rtl/lib/pulse_gen_type1.sv
@@ -0,0 +1,54 @@
+///////////////////////////////////////////////////////////////////////
+// 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 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..f9bcae3
--- /dev/null
+++ b/verilog/rtl/lib/pulse_gen_type2.sv
@@ -0,0 +1,53 @@
+///////////////////////////////////////////////////////////////////////
+// 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 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/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/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..8f54f0f
--- /dev/null
+++ b/verilog/rtl/lib/wb_stagging.sv
@@ -0,0 +1,173 @@
+//////////////////////////////////////////////////////////////////////////////
+// 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 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_err_o,
+
+ // Slave Interface
+ input logic [31:0] s_wbd_dat_i,
+ input logic s_wbd_ack_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 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 holding_busy ; // Indicate Stagging for Free or not
+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 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_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_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_err_o = s_wbd_err_i_ff;
+
+always @(negedge rst_n or posedge clk_i)
+begin
+ if(rst_n == 1'b0) begin
+ holding_busy <= 1'b0;
+ 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;
+ s_wbd_dat_i_ff <= 'h0;
+ s_wbd_ack_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_err_i_ff <= s_wbd_err_i;
+ if(m_wbd_stb_i && holding_busy == 0 && m_wbd_ack_o == 0) begin
+ holding_busy <= 1'b1;
+ 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;
+ end else if (holding_busy && s_wbd_ack_i) begin
+ holding_busy <= 1'b0;
+ 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;
+ end
+ end
+end
+
+
+endmodule
+