Statistics
| Branch: | Tag: | Revision:

root / usrp2 / fifo / packet_router.v @ 64e01dbe

History | View | Annotate | Download (7.93 KB)

1
module packet_router
2
    #(parameter BUF_SIZE = 9)
3
    (
4
        //wishbone interface for memory mapped CPU frames
5
        input wb_clk_i,
6
        input wb_rst_i,
7
        input wb_we_i,
8
        input wb_stb_i,
9
        input [15:0] wb_adr_i,
10
        input [31:0] wb_dat_i,
11
        output [31:0] wb_dat_o,
12
        output reg wb_ack_o,
13
        output wb_err_o,
14
        output wb_rty_o,
15

    
16
        input stream_clk,
17
        input stream_rst,
18

    
19
        //input control register
20
        input [31:0] control,
21

    
22
        //output status register
23
        output [31:0] status,
24

    
25
        output sys_int_o, //want an interrupt?
26

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

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

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

    
39
    ////////////////////////////////////////////////////////////////////
40
    // CPU interface to this packet router
41
    ////////////////////////////////////////////////////////////////////
42
    wire [35:0] cpu_inp_data;
43
    wire        cpu_inp_valid;
44
    wire        cpu_inp_ready;
45
    wire [35:0] cpu_out_data;
46
    wire        cpu_out_valid;
47
    wire        cpu_out_ready;
48

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

    
52
    ////////////////////////////////////////////////////////////////////
53
    // status and control handshakes
54
    ////////////////////////////////////////////////////////////////////
55
    wire cpu_inp_hs_ctrl = control[0];
56
    wire cpu_out_hs_ctrl = control[1];
57
    wire [BUF_SIZE-1:0] cpu_out_line_count = control[BUF_SIZE-1+16:0+16];
58

    
59
    wire cpu_inp_hs_stat;
60
    assign status[0] = cpu_inp_hs_stat;
61

    
62
    wire [BUF_SIZE-1:0] cpu_inp_line_count;
63
    assign status[BUF_SIZE-1+16:0+16] = cpu_inp_line_count;
64

    
65
    wire cpu_out_hs_stat;
66
    assign status[1] = cpu_out_hs_stat;
67

    
68
    ////////////////////////////////////////////////////////////////////
69
    // Ethernet input control
70
    ////////////////////////////////////////////////////////////////////
71
    //TODO: just connect eth input to cpu input for now
72
    assign cpu_inp_data = eth_inp_data;
73
    assign cpu_inp_valid = eth_inp_valid;
74
    assign eth_inp_ready = cpu_inp_ready;
75

    
76
    ////////////////////////////////////////////////////////////////////
77
    // Ethernet output control
78
    ////////////////////////////////////////////////////////////////////
79
    //TODO: just connect eth output to cpu output for now
80
    assign eth_out_data = cpu_out_data;
81
    assign eth_out_valid = cpu_out_valid;
82
    assign cpu_out_ready = eth_out_ready;
83

    
84
    ////////////////////////////////////////////////////////////////////
85
    // Interface CPU input interface to memory mapped wishbone
86
    ////////////////////////////////////////////////////////////////////
87
    localparam CPU_INP_STATE_WAIT_SOF = 0;
88
    localparam CPU_INP_STATE_WAIT_EOF = 1;
89
    localparam CPU_INP_STATE_WAIT_CTRL_HI = 2;
90
    localparam CPU_INP_STATE_WAIT_CTRL_LO = 3;
91

    
92
    reg [1:0] cpu_inp_state;
93
    reg [BUF_SIZE-1:0] cpu_inp_addr;
94
    assign cpu_inp_line_count = cpu_inp_addr;
95
    wire [BUF_SIZE-1:0] cpu_inp_addr_next = cpu_inp_addr + 1'b1;
96
    
97
    wire cpu_inp_reading = (
98
        cpu_inp_state == CPU_INP_STATE_WAIT_SOF ||
99
        cpu_inp_state == CPU_INP_STATE_WAIT_EOF
100
    )? 1'b1 : 1'b0;
101

    
102
    wire cpu_inp_we = cpu_inp_reading;
103
    assign cpu_inp_ready = cpu_inp_reading;
104
    assign cpu_inp_hs_stat = (cpu_inp_state == CPU_INP_STATE_WAIT_CTRL_HI)? 1'b1 : 1'b0;
105

    
106
    RAMB16_S36_S36 cpu_inp_buff(
107
        //port A = wishbone memory mapped address space (output only)
108
        .DOA(wb_dat_o),.ADDRA(wb_adr_i[BUF_SIZE+1:2]),.CLKA(wb_clk_i),.DIA(36'b0),.DIPA(4'h0),
109
        .ENA(wb_stb_i & (which_buf == 1'b0)),.SSRA(0),.WEA(wb_we_i),
110
        //port B = packet router interface to CPU (input only)
111
        .DOB(),.ADDRB(cpu_inp_addr),.CLKB(stream_clk),.DIB(cpu_inp_data),.DIPB(4'h0),
112
        .ENB(cpu_inp_we),.SSRB(0),.WEB(cpu_inp_we)
113
    );
114

    
115
    always @(posedge stream_clk)
116
    if(stream_rst) begin
117
        cpu_inp_state <= CPU_INP_STATE_WAIT_SOF;
118
        cpu_inp_addr <= 0;
119
    end
120
    else begin
121
        case(cpu_inp_state)
122
        CPU_INP_STATE_WAIT_SOF: begin
123
            if (cpu_inp_ready & cpu_inp_valid & (cpu_inp_data[32] == 1'b1)) begin
124
                cpu_inp_state <= CPU_INP_STATE_WAIT_EOF;
125
                cpu_inp_addr <= cpu_inp_addr_next;
126
            end
127
        end
128

    
129
        CPU_INP_STATE_WAIT_EOF: begin
130
            if (cpu_inp_ready & cpu_inp_valid & (cpu_inp_data[33] == 1'b1)) begin
131
                cpu_inp_state <= CPU_INP_STATE_WAIT_CTRL_HI;
132
            end
133
            if (cpu_inp_ready & cpu_inp_valid) begin
134
                cpu_inp_addr <= cpu_inp_addr_next;
135
            end
136
        end
137

    
138
        CPU_INP_STATE_WAIT_CTRL_HI: begin
139
            if (cpu_inp_hs_ctrl == 1'b1) begin
140
                cpu_inp_state <= CPU_INP_STATE_WAIT_CTRL_LO;
141
            end
142
        end
143

    
144
        CPU_INP_STATE_WAIT_CTRL_LO: begin
145
            if (cpu_inp_hs_ctrl == 1'b0) begin
146
                cpu_inp_state <= CPU_INP_STATE_WAIT_SOF;
147
            end
148
            cpu_inp_addr <= 0; //reset the address counter
149
        end
150

    
151
        endcase //cpu_inp_state
152
    end
153

    
154
    ////////////////////////////////////////////////////////////////////
155
    // Interface CPU output interface to memory mapped wishbone
156
    ////////////////////////////////////////////////////////////////////
157
    localparam CPU_OUT_STATE_WAIT_CTRL_HI = 0;
158
    localparam CPU_OUT_STATE_WAIT_CTRL_LO = 1;
159
    localparam CPU_OUT_STATE_UNLOAD = 2;
160

    
161
    reg [1:0] cpu_out_state;
162
    reg [BUF_SIZE-1:0] cpu_out_addr;
163
    wire [BUF_SIZE-1:0] cpu_out_addr_next = cpu_out_addr + 1'b1;
164

    
165
    reg [BUF_SIZE-1:0] cpu_out_line_count_reg;
166

    
167
    reg cpu_out_flag_sof;
168
    reg cpu_out_flag_eof;
169
    assign cpu_out_data[35:32] = {2'b0, cpu_out_flag_eof, cpu_out_flag_sof};
170

    
171
    assign cpu_out_valid = (cpu_out_state == CPU_OUT_STATE_UNLOAD)? 1'b1 : 1'b0;
172
    assign cpu_out_hs_stat = (cpu_out_state == CPU_OUT_STATE_WAIT_CTRL_HI)? 1'b1 : 1'b0;
173

    
174
    RAMB16_S36_S36 cpu_out_buff(
175
        //port A = wishbone memory mapped address space (input only)
176
        .DOA(),.ADDRA(wb_adr_i[BUF_SIZE+1:2]),.CLKA(wb_clk_i),.DIA(wb_dat_i),.DIPA(4'h0),
177
        .ENA(wb_stb_i & (which_buf == 1'b1)),.SSRA(0),.WEA(wb_we_i),
178
        //port B = packet router interface from CPU (output only)
179
        .DOB(cpu_out_data[31:0]),.ADDRB(cpu_out_addr),.CLKB(stream_clk),.DIB(36'b0),.DIPB(4'h0),
180
        .ENB(1'b1),.SSRB(0),.WEB(1'b0)
181
    );
182

    
183
    always @(posedge stream_clk)
184
    if(stream_rst) begin
185
        cpu_out_state <= CPU_OUT_STATE_WAIT_CTRL_HI;
186
        cpu_out_addr <= 0;
187
    end
188
    else begin
189
        case(cpu_out_state)
190
        CPU_OUT_STATE_WAIT_CTRL_HI: begin
191
            if (cpu_out_hs_ctrl == 1'b1) begin
192
                cpu_out_state <= CPU_OUT_STATE_WAIT_CTRL_LO;
193
            end
194
            cpu_out_line_count_reg <= cpu_out_line_count;
195
            cpu_out_addr <= 0; //reset the address counter
196
        end
197

    
198
        CPU_OUT_STATE_WAIT_CTRL_LO: begin
199
            if (cpu_out_hs_ctrl == 1'b0) begin
200
                cpu_out_state <= CPU_OUT_STATE_UNLOAD;
201
                cpu_out_addr <= cpu_out_addr_next;
202
            end
203
            cpu_out_flag_sof <= 1'b1;
204
            cpu_out_flag_eof <= 1'b0;
205
        end
206

    
207
        CPU_OUT_STATE_UNLOAD: begin
208
            if (cpu_out_ready & cpu_out_valid) begin
209
                cpu_out_addr <= cpu_out_addr_next;
210
                cpu_out_flag_sof <= 1'b0;
211
                if (cpu_out_addr == cpu_out_line_count_reg) begin
212
                    cpu_out_flag_eof <= 1'b1;
213
                end
214
                else begin
215
                    cpu_out_flag_eof <= 1'b0;
216
                end
217
                if (cpu_out_flag_eof) begin
218
                    cpu_out_state <= CPU_OUT_STATE_WAIT_CTRL_HI;
219
                end
220
            end
221
        end
222

    
223
        endcase //cpu_out_state
224
    end
225

    
226
endmodule // packet_router