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 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326
|
//
// Copyright 2011-2012 Ettus Research LLC
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
//
module packet_router
#(
parameter BUF_SIZE = 9,
parameter UDP_BASE = 0,
parameter CTRL_BASE = 0
)
(
//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 wb_ack_o,
output wb_err_o,
output wb_rty_o,
//setting register interface
input set_stb, input [7:0] set_addr, input [31:0] set_data,
input stream_clk,
input stream_rst,
input stream_clr,
//output status register
output [31:0] status,
output sys_int_o, //want an interrupt?
output [31:0] debug,
// Input Interfaces (in to router)
input [35:0] ser_inp_data, input ser_inp_valid, output ser_inp_ready,
input [35:0] dsp0_inp_data, input dsp0_inp_valid, output dsp0_inp_ready,
input [35:0] dsp1_inp_data, input dsp1_inp_valid, output dsp1_inp_ready,
input [35:0] eth_inp_data, input eth_inp_valid, output eth_inp_ready,
input [35:0] err_inp_data, input err_inp_valid, output err_inp_ready,
input [35:0] ctl_inp_data, input ctl_inp_valid, output ctl_inp_ready,
// Output Interfaces (out of router)
output [35:0] ser_out_data, output ser_out_valid, input ser_out_ready,
output [35:0] dsp_out_data, output dsp_out_valid, input dsp_out_ready,
output [35:0] ctl_out_data, output ctl_out_valid, input ctl_out_ready,
output [35:0] eth_out_data, output eth_out_valid, input eth_out_ready
);
assign wb_err_o = 1'b0; // Unused for now
assign wb_rty_o = 1'b0; // Unused for now
////////////////////////////////////////////////////////////////////
// CPU interface to this packet router
////////////////////////////////////////////////////////////////////
wire [35:0] cpu_inp_data, cpu_out_data;
wire cpu_inp_valid, cpu_out_valid;
wire cpu_inp_ready, cpu_out_ready;
////////////////////////////////////////////////////////////////////
// Communication interfaces
////////////////////////////////////////////////////////////////////
wire [35:0] com_inp_data, com_out_data, udp_out_data;
wire com_inp_valid, com_out_valid, udp_out_valid;
wire com_inp_ready, com_out_ready, udp_out_ready;
////////////////////////////////////////////////////////////////////
// Control signals (setting registers and status signals)
// - handshake lines for the CPU communication
// - setting registers to program the inspector
////////////////////////////////////////////////////////////////////
//setting register for mode control
wire [31:0] _sreg_mode_ctrl;
wire master_mode_flag;
setting_reg #(.my_addr(CTRL_BASE+0), .width(1)) sreg_mode_ctrl(
.clk(stream_clk),.rst(stream_rst),
.strobe(set_stb),.addr(set_addr),.in(set_data),
.out(master_mode_flag),.changed()
);
//assign status output signals
wire [31:0] cpu_iface_status;
assign status = {
cpu_iface_status[31:9], master_mode_flag, cpu_iface_status[7:0]
};
////////////////////////////////////////////////////////////////////
// Communication input source crossbar
// When in master mode:
// - serdes input -> comm output combiner
// - ethernet input -> comm input inspector
// When in slave mode:
// - serdes input -> comm input inspector
// - ethernet input -> null sink
////////////////////////////////////////////////////////////////////
//streaming signals from the crossbar to the combiner
wire [35:0] ext_inp_data;
wire ext_inp_valid;
wire ext_inp_ready;
//dummy signals for valve/xbar below
wire [35:0] _eth_inp_data;
wire _eth_inp_valid;
wire _eth_inp_ready;
// dummy signals to connect fifo_short
wire [35:0] _com_inp_data;
wire _com_inp_valid;
wire _com_inp_ready;
valve36 eth_inp_valve (
.clk(stream_clk), .reset(stream_rst), .clear(stream_clr), .shutoff(~master_mode_flag),
.data_i(eth_inp_data), .src_rdy_i(eth_inp_valid), .dst_rdy_o(eth_inp_ready),
.data_o(_eth_inp_data), .src_rdy_o(_eth_inp_valid), .dst_rdy_i(_eth_inp_ready)
);
crossbar36 com_inp_xbar (
.clk(stream_clk), .reset(stream_rst), .clear(stream_clr), .cross(~master_mode_flag),
.data0_i(_eth_inp_data), .src0_rdy_i(_eth_inp_valid), .dst0_rdy_o(_eth_inp_ready),
.data1_i(ser_inp_data), .src1_rdy_i(ser_inp_valid), .dst1_rdy_o(ser_inp_ready),
.data0_o(_com_inp_data), .src0_rdy_o(_com_inp_valid), .dst0_rdy_i(_com_inp_ready),
.data1_o(ext_inp_data), .src1_rdy_o(ext_inp_valid), .dst1_rdy_i(ext_inp_ready)
);
// short fifo in the packet inspection path to help timing
fifo_short #(.WIDTH(36)) com_inp_fifo
(.clk(stream_clk), .reset(stream_rst), .clear(stream_clr),
.datain(_com_inp_data), .src_rdy_i(_com_inp_valid), .dst_rdy_o(_com_inp_ready),
.dataout(com_inp_data), .src_rdy_o(com_inp_valid), .dst_rdy_i(com_inp_ready),
.space(), .occupied() );
////////////////////////////////////////////////////////////////////
// Communication output sink crossbar
// When in master mode:
// - comm output -> ethernet output
// - insp output -> serdes output
// When in slave mode:
// - com output -> serdes output
// - insp output -> null sink
////////////////////////////////////////////////////////////////////
//streaming signals from the inspector to the crossbar
wire [35:0] ext_out_data;
wire ext_out_valid;
wire ext_out_ready;
//dummy signals for valve/xbar below
wire [35:0] _eth_out_data;
wire _eth_out_valid;
wire _eth_out_ready;
crossbar36 com_out_xbar (
.clk(stream_clk), .reset(stream_rst), .clear(stream_clr), .cross(~master_mode_flag),
.data0_i(com_out_data), .src0_rdy_i(com_out_valid), .dst0_rdy_o(com_out_ready),
.data1_i(ext_out_data), .src1_rdy_i(ext_out_valid), .dst1_rdy_o(ext_out_ready),
.data0_o(_eth_out_data), .src0_rdy_o(_eth_out_valid), .dst0_rdy_i(_eth_out_ready),
.data1_o(ser_out_data), .src1_rdy_o(ser_out_valid), .dst1_rdy_i(ser_out_ready)
);
valve36 eth_out_valve (
.clk(stream_clk), .reset(stream_rst), .clear(stream_clr), .shutoff(~master_mode_flag),
.data_i(_eth_out_data), .src_rdy_i(_eth_out_valid), .dst_rdy_o(_eth_out_ready),
.data_o(eth_out_data), .src_rdy_o(eth_out_valid), .dst_rdy_i(eth_out_ready)
);
////////////////////////////////////////////////////////////////////
// Communication output source combiner (feeds UDP proto machine)
// - DSP input
// - CPU input
// - ERR input
////////////////////////////////////////////////////////////////////
//dummy signals to join the the muxes below
wire [35:0] _combiner0_data, _combiner1_data, _combiner2_data;
wire _combiner0_valid, _combiner1_valid, _combiner2_valid;
wire _combiner0_ready, _combiner1_ready, _combiner2_ready;
fifo36_mux #(.prio(0)) // No priority, fair sharing
_com_output_combiner0(
.clk(stream_clk), .reset(stream_rst), .clear(stream_clr),
.data0_i(err_inp_data), .src0_rdy_i(err_inp_valid), .dst0_rdy_o(err_inp_ready),
.data1_i(cpu_inp_data), .src1_rdy_i(cpu_inp_valid), .dst1_rdy_o(cpu_inp_ready),
.data_o(_combiner0_data), .src_rdy_o(_combiner0_valid), .dst_rdy_i(_combiner0_ready)
);
fifo36_mux #(.prio(0)) // No priority, fair sharing
_com_output_combiner2(
.clk(stream_clk), .reset(stream_rst), .clear(stream_clr),
.data0_i(_combiner0_data), .src0_rdy_i(_combiner0_valid), .dst0_rdy_o(_combiner0_ready),
.data1_i(ctl_inp_data), .src1_rdy_i(ctl_inp_valid), .dst1_rdy_o(ctl_inp_ready),
.data_o(_combiner2_data), .src_rdy_o(_combiner2_valid), .dst_rdy_i(_combiner2_ready)
);
fifo36_mux #(.prio(0)) // No priority, fair sharing
_com_output_combiner1(
.clk(stream_clk), .reset(stream_rst), .clear(stream_clr),
.data0_i(dsp0_inp_data), .src0_rdy_i(dsp0_inp_valid), .dst0_rdy_o(dsp0_inp_ready),
.data1_i(dsp1_inp_data), .src1_rdy_i(dsp1_inp_valid), .dst1_rdy_o(dsp1_inp_ready),
.data_o(_combiner1_data), .src_rdy_o(_combiner1_valid), .dst_rdy_i(_combiner1_ready)
);
fifo36_mux #(.prio(1)) // Give priority to err/cpu over dsp
com_output_source(
.clk(stream_clk), .reset(stream_rst), .clear(stream_clr),
.data0_i(_combiner2_data), .src0_rdy_i(_combiner2_valid), .dst0_rdy_o(_combiner2_ready),
.data1_i(_combiner1_data), .src1_rdy_i(_combiner1_valid), .dst1_rdy_o(_combiner1_ready),
.data_o(udp_out_data), .src_rdy_o(udp_out_valid), .dst_rdy_i(udp_out_ready)
);
////////////////////////////////////////////////////////////////////
// Interface CPU to memory mapped wishbone
// - Uses 1 setting register
////////////////////////////////////////////////////////////////////
buffer_int2 #(.BASE(CTRL_BASE+3), .BUF_SIZE(BUF_SIZE)) cpu_to_wb(
.clk(stream_clk), .rst(stream_rst | stream_clr),
.set_stb(set_stb), .set_addr(set_addr), .set_data(set_data),
.status(cpu_iface_status),
// Wishbone interface to RAM
.wb_clk_i(wb_clk_i), .wb_rst_i(wb_rst_i),
.wb_we_i(wb_we_i), .wb_stb_i(wb_stb_i),
.wb_adr_i(wb_adr_i), .wb_dat_i(wb_dat_i),
.wb_dat_o(wb_dat_o), .wb_ack_o(wb_ack_o),
// Write FIFO Interface (from PR and into WB)
.wr_data_i(cpu_out_data),
.wr_ready_i(cpu_out_valid),
.wr_ready_o(cpu_out_ready),
// Read FIFO Interface (from WB and into PR)
.rd_data_o(cpu_inp_data),
.rd_ready_o(cpu_inp_valid),
.rd_ready_i(cpu_inp_ready)
);
////////////////////////////////////////////////////////////////////
// Packet Dispatcher
// - Uses 2 setting registers
// - provide buffering before cpu for random + small packet bursts
////////////////////////////////////////////////////////////////////
wire [35:0] _cpu_out_data;
wire _cpu_out_valid;
wire _cpu_out_ready;
packet_dispatcher36_x4 #(.BASE(CTRL_BASE+1)) packet_dispatcher(
.clk(stream_clk), .rst(stream_rst), .clr(stream_clr),
.set_stb(set_stb), .set_addr(set_addr), .set_data(set_data),
.com_inp_data(com_inp_data), .com_inp_valid(com_inp_valid), .com_inp_ready(com_inp_ready),
.ext_out_data(ext_out_data), .ext_out_valid(ext_out_valid), .ext_out_ready(ext_out_ready),
.dsp_out_data(dsp_out_data), .dsp_out_valid(dsp_out_valid), .dsp_out_ready(dsp_out_ready),
.ctl_out_data(ctl_out_data), .ctl_out_valid(ctl_out_valid), .ctl_out_ready(ctl_out_ready),
.cpu_out_data(_cpu_out_data), .cpu_out_valid(_cpu_out_valid), .cpu_out_ready(_cpu_out_ready)
);
fifo_cascade #(.WIDTH(36), .SIZE(9/*512 lines plenty for short pkts*/)) cpu_out_fifo (
.clk(stream_clk), .reset(stream_rst), .clear(stream_clr),
.datain(_cpu_out_data), .src_rdy_i(_cpu_out_valid), .dst_rdy_o(_cpu_out_ready),
.dataout(cpu_out_data), .src_rdy_o(cpu_out_valid), .dst_rdy_i(cpu_out_ready)
);
////////////////////////////////////////////////////////////////////
// UDP TX Protocol machine
////////////////////////////////////////////////////////////////////
//dummy signals to connect the components below
wire [35:0] _com_out_data;
wire _com_out_valid, _com_out_ready;
prot_eng_tx #(.BASE(UDP_BASE)) udp_prot_eng_tx
(.clk(stream_clk), .reset(stream_rst), .clear(stream_clr),
.set_stb(set_stb), .set_addr(set_addr), .set_data(set_data),
.datain(udp_out_data), .src_rdy_i(udp_out_valid), .dst_rdy_o(udp_out_ready),
.dataout(_com_out_data), .src_rdy_o(_com_out_valid), .dst_rdy_i(_com_out_ready) );
fifo36_mux com_out_mux(
.clk(stream_clk), .reset(stream_rst), .clear(stream_clr),
.data0_i(ext_inp_data), .src0_rdy_i(ext_inp_valid), .dst0_rdy_o(ext_inp_ready),
.data1_i(_com_out_data), .src1_rdy_i(_com_out_valid), .dst1_rdy_o(_com_out_ready),
.data_o(com_out_data), .src_rdy_o(com_out_valid), .dst_rdy_i(com_out_ready)
);
////////////////////////////////////////////////////////////////////
// Assign debugs
////////////////////////////////////////////////////////////////////
assign debug = {
//inputs to the router (12)
dsp0_inp_ready, dsp0_inp_valid,
dsp1_inp_ready, dsp1_inp_valid,
err_inp_ready, err_inp_valid,
ser_inp_ready, ser_inp_valid,
eth_inp_ready, eth_inp_valid,
cpu_inp_ready, cpu_inp_valid,
//outputs from the router (8)
dsp_out_ready, dsp_out_valid,
ser_out_ready, ser_out_valid,
eth_out_ready, eth_out_valid,
cpu_out_ready, cpu_out_valid,
//other interfaces (8)
ext_inp_ready, ext_inp_valid,
com_out_ready, com_out_valid,
ext_out_ready, ext_out_valid,
com_inp_ready, com_inp_valid,
4'b0
};
endmodule // packet_router
|