1//
2// Copyright 2011 Ettus Research LLC
3//
4// This program is free software: you can redistribute it and/or modify
5// it under the terms of the GNU General Public License as published by
6// the Free Software Foundation, either version 3 of the License, or
7// (at your option) any later version.
8//
9// This program is distributed in the hope that it will be useful,
10// but WITHOUT ANY WARRANTY; without even the implied warranty of
11// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12// GNU General Public License for more details.
13//
14// You should have received a copy of the GNU General Public License
15// along with this program.  If not, see <http://www.gnu.org/licenses/>.
16//
17
18
19// Split packets from a fifo based interface so it goes out identically on two interfaces
20
21module splitter36
22    (
23        input clk, input rst, input clr,
24        input [35:0] inp_data, input inp_valid, output inp_ready,
25        output [35:0] out0_data, output out0_valid, input out0_ready,
26        output [35:0] out1_data, output out1_valid, input out1_ready
27    );
28
29    localparam STATE_COPY_BOTH = 0;
30    localparam STATE_COPY_ZERO = 1;
31    localparam STATE_COPY_ONE = 2;
32
33    reg [1:0] state;
34    reg [35:0] data_reg;
35
36    assign out0_data = (state == STATE_COPY_BOTH)? inp_data : data_reg;
37    assign out1_data = (state == STATE_COPY_BOTH)? inp_data : data_reg;
38
39    assign out0_valid =
40        (state == STATE_COPY_BOTH)? inp_valid : (
41        (state == STATE_COPY_ZERO)? 1'b1      : (
42    1'b0));
43
44    assign out1_valid =
45        (state == STATE_COPY_BOTH)? inp_valid : (
46        (state == STATE_COPY_ONE)?  1'b1      : (
47    1'b0));
48
49    assign inp_ready = (state == STATE_COPY_BOTH)? (out0_ready | out1_ready) : 1'b0;
50
51    always @(posedge clk)
52    if (rst | clr) begin
53        state <= STATE_COPY_BOTH;
54    end
55    else begin
56        case (state)
57
58        STATE_COPY_BOTH: begin
59            if ((out0_valid & out0_ready) & ~(out1_valid & out1_ready)) begin
60                state <= STATE_COPY_ONE;
61            end
62            else if (~(out0_valid & out0_ready) & (out1_valid & out1_ready)) begin
63                state <= STATE_COPY_ZERO;
64            end
65            data_reg <= inp_data;
66        end
67
68        STATE_COPY_ZERO: begin
69            if (out0_valid & out0_ready) begin
70                state <= STATE_COPY_BOTH;
71            end
72        end
73
74        STATE_COPY_ONE: begin
75            if (out1_valid & out1_ready) begin
76                state <= STATE_COPY_BOTH;
77            end
78        end
79
80        endcase //state
81    end
82
83
84
85endmodule //splitter36
86