summaryrefslogtreecommitdiff
path: root/rtl/bus/ari_framemux.sv
diff options
context:
space:
mode:
Diffstat (limited to 'rtl/bus/ari_framemux.sv')
-rw-r--r--rtl/bus/ari_framemux.sv91
1 files changed, 91 insertions, 0 deletions
diff --git a/rtl/bus/ari_framemux.sv b/rtl/bus/ari_framemux.sv
new file mode 100644
index 0000000..9b76a51
--- /dev/null
+++ b/rtl/bus/ari_framemux.sv
@@ -0,0 +1,91 @@
+//
+// Copyright (c) 2026, Apollo Telephone Laboratories.
+// Provided under the BSD-3 clause.
+//
+
+`include "bus/ari.svh"
+
+//
+// Represents an ARI segment frame multiplexer
+//
+// @clk_i: Clock input
+// @reset_i: Reset input
+// @ingress_i: Ingress frame input
+// @tap_i: Tap port input
+// @egress_o: Egress frame output
+//
+module ari_framemux (
+ input wire clk_i,
+ input wire reset_i,
+ input AriFrame ingress_i,
+ input AriFrame tap_i,
+
+ output AriFrame egress_o
+);
+ // Multiplexer attributes
+ parameter MUX_PERIOD = 2;
+ parameter MUX_N_INPUT = 2;
+ parameter MUX_N_STATES = (MUX_PERIOD * MUX_N_INPUT);
+
+ // Multiplexer states
+ parameter MUX_STATE_INGRESS0 = 0;
+ parameter MUX_STATE_INGRESS1 = 1;
+ parameter MUX_STATE_TAP0 = 2;
+ parameter MUX_STATE_TAP1 = 3;
+
+ // TDM selector
+ logic [2:0] mux_sel;
+
+ //
+ // Handle reset logic and time division multiplexing for
+ // frame routing. If there is nothing on the channel that
+ // is currently being selected, we are to route the other
+ // channel instead.
+ //
+ always_ff @(posedge clk_i) begin
+ if (reset_i) begin
+ mux_sel <= 0;
+ egress_o <= 0;
+ end else begin
+ case (mux_sel)
+ // TDM ingress slice
+ MUX_STATE_INGRESS0: begin
+ if (ingress_i == 0) begin
+ egress_o <= tap_i;
+ end else begin
+ egress_o <= ingress_i;
+ end
+ end
+ MUX_STATE_INGRESS1: begin
+ if (ingress_i == 0) begin
+ egress_o <= tap_i;
+ end else begin
+ egress_o <= ingress_i;
+ end
+ end
+
+ // TDM tap slice
+ MUX_STATE_TAP0: begin
+ if (tap_i == 0) begin
+ egress_o <= ingress_i;
+ end else begin
+ egress_o <= tap_i;
+ end
+ end
+ MUX_STATE_TAP1: begin
+ if (tap_i == 0) begin
+ egress_o <= ingress_i;
+ end else begin
+ egress_o <= tap_i;
+ end
+ end
+ endcase
+ end
+
+ if (!reset_i && mux_sel < MUX_N_STATES) begin
+ mux_sel <= mux_sel + 1;
+ end else if (!reset_i && mux_sel >= MUX_N_STATES) begin
+ mux_sel <= 0;
+ end
+ end
+endmodule