summaryrefslogtreecommitdiff
path: root/rtl/bus/ari_framemux.sv
blob: 9b76a51034dfe2380c4b07cc4c823f0a9c05fb8f (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
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