From 85dcec03a24950bccc7c4dbdb709edc4bf18168b Mon Sep 17 00:00:00 2001 From: Nikos Patsiatzis Date: Fri, 18 Aug 2023 09:58:16 +0300 Subject: [PATCH] added SV implementation --- rtl/SystemVerilog/Makefile | 6 ++++ rtl/SystemVerilog/recirculation_mux.sv | 34 ++++++++++++++++++ rtl/SystemVerilog/toggle_synchronizer.sv | 44 ++++++++++++++++++++++++ 3 files changed, 84 insertions(+) create mode 100644 rtl/SystemVerilog/Makefile create mode 100644 rtl/SystemVerilog/recirculation_mux.sv create mode 100644 rtl/SystemVerilog/toggle_synchronizer.sv diff --git a/rtl/SystemVerilog/Makefile b/rtl/SystemVerilog/Makefile new file mode 100644 index 0000000..ae007e3 --- /dev/null +++ b/rtl/SystemVerilog/Makefile @@ -0,0 +1,6 @@ +RTL_DIR = $(PWD) + +.PHONY:lint +lint: + @verilator --lint-only $(RTL_DIR)/*.sv + @verible-verilog-lint $(RTL_DIR)/*.sv diff --git a/rtl/SystemVerilog/recirculation_mux.sv b/rtl/SystemVerilog/recirculation_mux.sv new file mode 100644 index 0000000..7aca681 --- /dev/null +++ b/rtl/SystemVerilog/recirculation_mux.sv @@ -0,0 +1,34 @@ +`default_nettype none + +module recirculation_mux + # + ( + parameter int G_STAGES = 2, + parameter int G_WIDTH = 4 + ) + + ( + input logic i_clk_A, + input logic i_rst_A, + input logic i_pulse_A, + input logic [G_WIDTH - 1 : 0] i_data_A, + + input logic i_clk_B, + input logic i_rst_B, + output logic [G_WIDTH - 1 : 0] o_data_B + ); + + logic w_pulse_B; + + toggle_synchronizer #(.G_STAGES(G_STAGES)) sync (.*,.o_pulse_B(w_pulse_B)); + + always_ff @(posedge i_clk_B) begin : mux_recirculation + if(i_rst_B) begin + o_data_B <= 0; + end else begin + if (w_pulse_B) + o_data_B <= i_data_A; + end + end + +endmodule : recirculation_mux diff --git a/rtl/SystemVerilog/toggle_synchronizer.sv b/rtl/SystemVerilog/toggle_synchronizer.sv new file mode 100644 index 0000000..f829ca8 --- /dev/null +++ b/rtl/SystemVerilog/toggle_synchronizer.sv @@ -0,0 +1,44 @@ +`default_nettype none + +module toggle_synchronizer + # + ( + parameter int G_STAGES = 2 + ) + + ( + input logic i_clk_A, + input logic i_rst_A, + input logic i_pulse_A, + + input logic i_clk_B, + input logic i_rst_B, + output logic o_pulse_B + ); + + logic r_pulse_A; + logic [G_STAGES - 1 : 0] r_syncB_pulse_A; + logic r_edge_detect_ff; + + always_ff @(posedge i_clk_A) begin : pulse_to_level + if(i_rst_A) begin + r_pulse_A <= 0; + end else begin + if (i_pulse_A) + r_pulse_A <= ~r_pulse_A; + end + end + + always_ff @(posedge i_clk_B) begin : sync_domain_B + if(i_rst_B) begin + r_syncB_pulse_A <= '0; + r_edge_detect_ff <= 1'b0; + end else begin + r_syncB_pulse_A <= {r_syncB_pulse_A[G_STAGES - 2 : 0], r_pulse_A}; + r_edge_detect_ff <= r_syncB_pulse_A[G_STAGES - 1]; + end + end + + assign o_pulse_B = r_edge_detect_ff ^ r_syncB_pulse_A[G_STAGES - 1]; + +endmodule : toggle_synchronizer