summaryrefslogtreecommitdiffstats
path: root/usrp2/fifo/packet_router.v
blob: 53cf1bcce8820c68c80207ec85ef55fc7414cf54 (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
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
module packet_router
    #(parameter BUF_SIZE = 9)
    (
        //wishbone interface for memory mapped CPU frames
        input wb_clk_i,
        input wb_rst_i,
        input wb_we_i,
        input wb_stb_i,
        input [15:0] wb_adr_i,
        input [31:0] wb_dat_i,
        output [31:0] wb_dat_o,
        output reg wb_ack_o,
        output wb_err_o,
        output wb_rty_o,

        input stream_clk,
        input stream_rst,

        //input control register
        input [31:0] control,

        //output status register
        output [31:0] status,

        output sys_int_o, //want an interrupt?

        // Input Interfaces (in to router)
        input [35:0] eth_inp_data, input eth_inp_valid, output eth_inp_ready,

        // Output Interfaces (out of router)
        output [35:0] eth_out_data, output eth_out_valid, input eth_out_ready
    );

    //which buffer: 0 = CPU read buffer, 1 = CPU write buffer
    wire which_buf = wb_adr_i[BUF_SIZE+2];

    ////////////////////////////////////////////////////////////////////
    // status and controls
    ////////////////////////////////////////////////////////////////////
    wire eth_to_cpu_flag_ack = control[0];

    wire eth_to_cpu_flag_rdy;
    assign status[0] = eth_to_cpu_flag_rdy;

    ////////////////////////////////////////////////////////////////////
    // Ethernet input control
    ////////////////////////////////////////////////////////////////////

    localparam ETH_TO_CPU_STATE_WAIT_SOF = 0;
    localparam ETH_TO_CPU_STATE_WAIT_EOF = 1;
    localparam ETH_TO_CPU_STATE_WAIT_ACK_HI = 2;
    localparam ETH_TO_CPU_STATE_WAIT_ACK_LO = 3;

    reg [1:0] eth_to_cpu_state;
    reg [BUF_SIZE-1:0] eth_to_cpu_addr;
    wire [BUF_SIZE-1:0] eth_to_cpu_addr_next = eth_to_cpu_addr + 1'b1;
    
    wire eth_to_cpu_reading_input = (
        eth_to_cpu_state == ETH_TO_CPU_STATE_WAIT_SOF ||
        eth_to_cpu_state == ETH_TO_CPU_STATE_WAIT_EOF
    )? 1'b1 : 1'b0;

    wire eth_to_cpu_we = eth_to_cpu_reading_input;
    assign eth_inp_ready = eth_to_cpu_reading_input;
    assign eth_to_cpu_flag_rdy = (eth_to_cpu_state == ETH_TO_CPU_STATE_WAIT_ACK_HI)? 1'b1 : 1'b0;

    assign wb_err_o = 1'b0;  // Unused for now
    assign wb_rty_o = 1'b0;  // Unused for now
    always @(posedge wb_clk_i)
        wb_ack_o <= wb_stb_i & ~wb_ack_o;

    RAMB16_S36_S36 eth_to_cpu_buff(
        //port A = wishbone memory mapped address space
        .DOA(wb_dat_o),.ADDRA(wb_adr_i[BUF_SIZE+1:2]),.CLKA(wb_clk_i),.DIA(wb_dat_i),.DIPA(4'h0),
        .ENA(wb_stb_i & (which_buf == 1'b0)),.SSRA(0),.WEA(wb_we_i),
        //port B = input from ethernet packets
        .DOB(),.ADDRB(eth_to_cpu_addr),.CLKB(stream_clk),.DIB(eth_inp_data),.DIPB(4'h0),
        .ENB(eth_to_cpu_we),.SSRB(0),.WEB(eth_to_cpu_we)
    );

    always @(posedge stream_clk)
    if(stream_rst) begin
        eth_to_cpu_state <= ETH_TO_CPU_STATE_WAIT_SOF;
        eth_to_cpu_addr <= 0;
    end
    else begin
        case(eth_to_cpu_state)
        ETH_TO_CPU_STATE_WAIT_SOF: begin
            if (eth_inp_ready & eth_inp_valid & (eth_inp_data[32] == 1'b1)) begin
                eth_to_cpu_state <= ETH_TO_CPU_STATE_WAIT_EOF;
                eth_to_cpu_addr <= eth_to_cpu_addr_next;
            end
        end

        ETH_TO_CPU_STATE_WAIT_EOF: begin
            if (eth_inp_ready & eth_inp_valid & (eth_inp_data[33] == 1'b1)) begin
                eth_to_cpu_state <= ETH_TO_CPU_STATE_WAIT_ACK_HI;
            end
            if (eth_inp_ready & eth_inp_valid) begin
                eth_to_cpu_addr <= eth_to_cpu_addr_next;
            end
        end

        ETH_TO_CPU_STATE_WAIT_ACK_HI: begin
            if (eth_to_cpu_flag_ack == 1'b1) begin
                eth_to_cpu_state <= ETH_TO_CPU_STATE_WAIT_ACK_LO;
            end
        end

        ETH_TO_CPU_STATE_WAIT_ACK_LO: begin
            if (eth_to_cpu_flag_ack == 0'b1) begin
                eth_to_cpu_state <= ETH_TO_CPU_STATE_WAIT_SOF;
            end
        end

        endcase //eth_to_cpu_state
    end


endmodule // packet_router