summaryrefslogtreecommitdiffstats
path: root/usrp2/fifo
diff options
context:
space:
mode:
Diffstat (limited to 'usrp2/fifo')
-rw-r--r--usrp2/fifo/Makefile.srcs6
-rw-r--r--usrp2/fifo/buffer_int.v1
-rw-r--r--usrp2/fifo/buffer_int2.v173
-rw-r--r--usrp2/fifo/crossbar36.v40
-rw-r--r--usrp2/fifo/dsp_framer36.v98
-rw-r--r--usrp2/fifo/packet_router.v536
-rw-r--r--usrp2/fifo/splitter36.v68
-rw-r--r--usrp2/fifo/valve36.v28
8 files changed, 949 insertions, 1 deletions
diff --git a/usrp2/fifo/Makefile.srcs b/usrp2/fifo/Makefile.srcs
index c66979132..f0b5b7bae 100644
--- a/usrp2/fifo/Makefile.srcs
+++ b/usrp2/fifo/Makefile.srcs
@@ -7,7 +7,10 @@
##################################################
FIFO_SRCS = $(abspath $(addprefix $(BASE_DIR)/../fifo/, \
buffer_int.v \
+buffer_int2.v \
buffer_pool.v \
+crossbar36.v \
+dsp_framer36.v \
fifo_2clock.v \
fifo_2clock_cascade.v \
ll8_shortfifo.v \
@@ -22,4 +25,7 @@ fifo36_to_fifo19.v \
fifo19_to_fifo36.v \
fifo36_mux.v \
fifo36_demux.v \
+packet_router.v \
+splitter36.v \
+valve36.v \
))
diff --git a/usrp2/fifo/buffer_int.v b/usrp2/fifo/buffer_int.v
index b45ed3532..49ded8c8d 100644
--- a/usrp2/fifo/buffer_int.v
+++ b/usrp2/fifo/buffer_int.v
@@ -14,7 +14,6 @@ module buffer_int
output done,
output error,
output idle,
- output [1:0] flag,
// Buffer Interface
output en_o,
diff --git a/usrp2/fifo/buffer_int2.v b/usrp2/fifo/buffer_int2.v
new file mode 100644
index 000000000..765b125fb
--- /dev/null
+++ b/usrp2/fifo/buffer_int2.v
@@ -0,0 +1,173 @@
+
+// FIFO Interface to the 2K buffer RAMs
+// Read port is read-acknowledge
+// FIXME do we want to be able to interleave reads and writes?
+
+module buffer_int2
+ #(parameter BASE = 0,
+ parameter BUF_SIZE = 9)
+ (input clk, input rst,
+ input set_stb, input [7:0] set_addr, input [31:0] set_data,
+ output [31:0] status,
+
+ // Wishbone interface to RAM
+ 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,
+
+ // Write FIFO Interface
+ input [35:0] wr_data_i,
+ input wr_ready_i,
+ output wr_ready_o,
+
+ // Read FIFO Interface
+ output [35:0] rd_data_o,
+ output rd_ready_o,
+ input rd_ready_i
+ );
+
+ reg [BUF_SIZE-1:0] rd_addr, wr_addr;
+ wire [31:0] ctrl;
+ wire wr_done, wr_error, wr_idle;
+ wire rd_done, rd_error, rd_idle;
+ wire we, en, go;
+
+ reg [BUF_SIZE-1:0] lastline;
+ wire read = ctrl[3];
+ wire rd_clear = ctrl[2];
+ wire write = ctrl[1];
+ wire wr_clear = ctrl[0];
+
+ reg [2:0] rd_state, wr_state;
+ reg rd_sop, rd_eop;
+ wire wr_sop, wr_eop;
+ reg [1:0] rd_occ;
+ wire [1:0] wr_occ;
+
+ localparam IDLE = 3'd0;
+ localparam PRE_READ = 3'd1;
+ localparam READING = 3'd2;
+ localparam WRITING = 3'd3;
+ localparam ERROR = 3'd4;
+ localparam DONE = 3'd5;
+
+ // read state machine
+ always @(posedge clk)
+ if(rst | (rd_clear & go))
+ begin
+ rd_state <= IDLE;
+ rd_sop <= 0;
+ rd_eop <= 0;
+ rd_occ <= 0;
+ end
+ else
+ case(rd_state)
+ IDLE :
+ if(go & read)
+ begin
+ rd_addr <= 0;
+ rd_state <= PRE_READ;
+ lastline <= ctrl[15+BUF_SIZE:16];
+ end
+
+ PRE_READ :
+ begin
+ rd_state <= READING;
+ rd_addr <= rd_addr + 1;
+ rd_occ <= 2'b00;
+ rd_sop <= 1;
+ rd_eop <= 0;
+ end
+
+ READING :
+ if(rd_ready_i)
+ begin
+ rd_sop <= 0;
+ rd_addr <= rd_addr + 1;
+ if(rd_addr == lastline)
+ begin
+ rd_eop <= 1;
+ // FIXME assign occ here
+ rd_occ <= 0;
+ end
+ else
+ rd_eop <= 0;
+ if(rd_eop)
+ rd_state <= DONE;
+ end
+
+ endcase // case(rd_state)
+
+ // write state machine
+ always @(posedge clk)
+ if(rst | (wr_clear & go))
+ wr_state <= IDLE;
+ else
+ case(wr_state)
+ IDLE :
+ if(go & write)
+ begin
+ wr_addr <= 0;
+ wr_state <= WRITING;
+ end
+
+ WRITING :
+ if(wr_ready_i)
+ begin
+ wr_addr <= wr_addr + 1;
+ if(wr_sop & wr_eop)
+ wr_state <= ERROR; // Should save OCC flags here
+ else if(wr_eop)
+ wr_state <= DONE;
+ end // if (wr_ready_i)
+ endcase // case(wr_state)
+
+ assign rd_data_o[35:32] = { rd_occ[1:0], rd_eop, rd_sop };
+ assign rd_ready_o = (rd_state == READING);
+
+ assign wr_sop = wr_data_i[32];
+ assign wr_eop = wr_data_i[33];
+ assign wr_occ = wr_data_i[35:34];
+ assign wr_ready_o = (wr_state == WRITING);
+
+ assign we = (wr_state == WRITING); // always write to avoid timing issue
+ assign en = ~((rd_state==READING)& ~rd_ready_i); // FIXME potential critical path
+
+ assign rd_done = (rd_state == DONE);
+ assign wr_done = (wr_state == DONE);
+ assign rd_error = (rd_state == ERROR);
+ assign wr_error = (wr_state == ERROR);
+ assign rd_idle = (rd_state == IDLE);
+ assign wr_idle = (wr_state == IDLE);
+
+ ram_2port #(.DWIDTH(32),.AWIDTH(BUF_SIZE)) buffer_in // CPU reads here
+ (.clka(wb_clk_i),.ena(wb_stb_i),.wea(1'b0),
+ .addra(wb_adr_i[BUF_SIZE+1:2]),.dia(0),.doa(wb_dat_o),
+ .clkb(clk),.enb(1'b1),.web(we),
+ .addrb(wr_addr),.dib(wr_data_i[31:0]),.dob());
+
+ ram_2port #(.DWIDTH(32),.AWIDTH(BUF_SIZE)) buffer_out // CPU writes here
+ (.clka(wb_clk_i),.ena(wb_stb_i),.wea(wb_we_i),
+ .addra(wb_adr_i[BUF_SIZE+1:2]),.dia(wb_dat_i),.doa(),
+ .clkb(clk),.enb(en),.web(1'b0),
+ .addrb(rd_addr),.dib(0),.dob(rd_data_o[31:0]));
+
+ always @(posedge wb_clk_i)
+ if(wb_rst_i)
+ wb_ack_o <= 0;
+ else
+ wb_ack_o <= wb_stb_i & ~wb_ack_o;
+
+ setting_reg #(.my_addr(BASE))
+ sreg(.clk(clk),.rst(rst),.strobe(set_stb),.addr(set_addr),.in(set_data),
+ .out(ctrl),.changed(go));
+
+ assign status = { {(16-BUF_SIZE){1'b0}},wr_addr,
+ 8'b0,1'b0,rd_idle,rd_error,rd_done, 1'b0,wr_idle,wr_error,wr_done};
+
+endmodule // buffer_int2
diff --git a/usrp2/fifo/crossbar36.v b/usrp2/fifo/crossbar36.v
new file mode 100644
index 000000000..d90f5659c
--- /dev/null
+++ b/usrp2/fifo/crossbar36.v
@@ -0,0 +1,40 @@
+
+
+module crossbar36
+ (input clk, input reset, input clear,
+ input cross,
+ input [35:0] data0_i, input src0_rdy_i, output dst0_rdy_o,
+ input [35:0] data1_i, input src1_rdy_i, output dst1_rdy_o,
+ output [35:0] data0_o, output src0_rdy_o, input dst0_rdy_i,
+ output [35:0] data1_o, output src1_rdy_o, input dst1_rdy_i);
+
+ reg cross_int, active0, active1;
+
+ assign data0_o = cross_int ? data1_i : data0_i;
+ assign data1_o = cross_int ? data0_i : data1_i;
+
+ assign src0_rdy_o = cross_int ? src1_rdy_i : src0_rdy_i;
+ assign src1_rdy_o = cross_int ? src0_rdy_i : src1_rdy_i;
+
+ assign dst0_rdy_o = cross_int ? dst1_rdy_i : dst0_rdy_i;
+ assign dst1_rdy_o = cross_int ? dst0_rdy_i : dst1_rdy_i;
+
+ always @(posedge clk)
+ if(reset | clear)
+ active0 <= 0;
+ else if(src0_rdy_i & dst0_rdy_o)
+ active0 <= ~data0_i[33];
+
+ always @(posedge clk)
+ if(reset | clear)
+ active1 <= 0;
+ else if(src1_rdy_i & dst1_rdy_o)
+ active1 <= ~data1_i[33];
+
+ always @(posedge clk)
+ if(reset | clear)
+ cross_int <= 0;
+ else if(~active0 & ~active1)
+ cross_int <= cross;
+
+endmodule // crossbar36
diff --git a/usrp2/fifo/dsp_framer36.v b/usrp2/fifo/dsp_framer36.v
new file mode 100644
index 000000000..34a05d91e
--- /dev/null
+++ b/usrp2/fifo/dsp_framer36.v
@@ -0,0 +1,98 @@
+
+// Frame DSP packets with a header line to be handled by the protocol machine
+
+module dsp_framer36
+ #(parameter BUF_SIZE = 9)
+ (
+ input clk, input rst, input clr,
+ input [35:0] inp_data, input inp_valid, output inp_ready,
+ output [35:0] out_data, output out_valid, input out_ready
+ );
+
+ localparam DSP_FRM_STATE_WAIT_SOF = 0;
+ localparam DSP_FRM_STATE_WAIT_EOF = 1;
+ localparam DSP_FRM_STATE_WRITE_HDR = 2;
+ localparam DSP_FRM_STATE_WRITE = 3;
+
+ reg [1:0] dsp_frm_state;
+ reg [BUF_SIZE-1:0] dsp_frm_addr;
+ reg [BUF_SIZE-1:0] dsp_frm_count;
+ wire [BUF_SIZE-1:0] dsp_frm_addr_next = dsp_frm_addr + 1'b1;
+
+ //DSP input stream ready in the following states
+ assign inp_ready = (
+ dsp_frm_state == DSP_FRM_STATE_WAIT_SOF ||
+ dsp_frm_state == DSP_FRM_STATE_WAIT_EOF
+ )? 1'b1 : 1'b0;
+
+ //DSP framer output data mux (header or BRAM):
+ //The header is generated here from the count.
+ wire [31:0] dsp_frm_data_bram;
+ wire [15:0] dsp_frm_bytes = {dsp_frm_count, 2'b00};
+ assign out_data =
+ (dsp_frm_state == DSP_FRM_STATE_WRITE_HDR)? {4'b0001, 16'b1, dsp_frm_bytes} : (
+ (dsp_frm_addr == dsp_frm_count) ? {4'b0010, dsp_frm_data_bram} : (
+ {4'b0000, dsp_frm_data_bram}));
+ assign out_valid = (
+ (dsp_frm_state == DSP_FRM_STATE_WRITE_HDR) ||
+ (dsp_frm_state == DSP_FRM_STATE_WRITE)
+ )? 1'b1 : 1'b0;
+
+ RAMB16_S36_S36 dsp_frm_buff(
+ //port A = DSP input interface (writes to BRAM)
+ .DOA(),.ADDRA(dsp_frm_addr),.CLKA(clk),.DIA(inp_data[31:0]),.DIPA(4'h0),
+ .ENA(inp_ready & inp_valid),.SSRA(0),.WEA(inp_ready & inp_valid),
+ //port B = DSP framer interface (reads from BRAM)
+ .DOB(dsp_frm_data_bram),.ADDRB(dsp_frm_addr),.CLKB(clk),.DIB(36'b0),.DIPB(4'h0),
+ .ENB(out_ready & out_valid),.SSRB(0),.WEB(1'b0)
+ );
+
+ always @(posedge clk)
+ if(rst | clr) begin
+ dsp_frm_state <= DSP_FRM_STATE_WAIT_SOF;
+ dsp_frm_addr <= 0;
+ end
+ else begin
+ case(dsp_frm_state)
+ DSP_FRM_STATE_WAIT_SOF: begin
+ if (inp_ready & inp_valid & inp_data[32]) begin
+ dsp_frm_addr <= dsp_frm_addr_next;
+ dsp_frm_state <= DSP_FRM_STATE_WAIT_EOF;
+ end
+ end
+
+ DSP_FRM_STATE_WAIT_EOF: begin
+ if (inp_ready & inp_valid) begin
+ if (inp_data[33]) begin
+ dsp_frm_count <= dsp_frm_addr_next;
+ dsp_frm_addr <= 0;
+ dsp_frm_state <= DSP_FRM_STATE_WRITE_HDR;
+ end
+ else begin
+ dsp_frm_addr <= dsp_frm_addr_next;
+ end
+ end
+ end
+
+ DSP_FRM_STATE_WRITE_HDR: begin
+ if (out_ready & out_valid) begin
+ dsp_frm_addr <= dsp_frm_addr_next;
+ dsp_frm_state <= DSP_FRM_STATE_WRITE;
+ end
+ end
+
+ DSP_FRM_STATE_WRITE: begin
+ if (out_ready & out_valid) begin
+ if (out_data[33]) begin
+ dsp_frm_addr <= 0;
+ dsp_frm_state <= DSP_FRM_STATE_WAIT_SOF;
+ end
+ else begin
+ dsp_frm_addr <= dsp_frm_addr_next;
+ end
+ end
+ end
+ endcase //dsp_frm_state
+ end
+
+endmodule //dsp_framer36
diff --git a/usrp2/fifo/packet_router.v b/usrp2/fifo/packet_router.v
new file mode 100644
index 000000000..ff1f80927
--- /dev/null
+++ b/usrp2/fifo/packet_router.v
@@ -0,0 +1,536 @@
+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] dsp_inp_data, input dsp_inp_valid, output dsp_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,
+
+ // 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] 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 = _sreg_mode_ctrl[0];
+ setting_reg #(.my_addr(CTRL_BASE+0)) sreg_mode_ctrl(
+ .clk(stream_clk),.rst(stream_rst),
+ .strobe(set_stb),.addr(set_addr),.in(set_data),
+ .out(_sreg_mode_ctrl),.changed()
+ );
+
+ //setting register to program the IP address
+ wire [31:0] my_ip_addr;
+ setting_reg #(.my_addr(CTRL_BASE+1)) sreg_ip_addr(
+ .clk(stream_clk),.rst(stream_rst),
+ .strobe(set_stb),.addr(set_addr),.in(set_data),
+ .out(my_ip_addr),.changed()
+ );
+
+ //setting register to program the UDP data ports
+ wire [15:0] dsp0_udp_port, dsp1_udp_port;
+ setting_reg #(.my_addr(CTRL_BASE+2)) sreg_data_ports(
+ .clk(stream_clk),.rst(stream_rst),
+ .strobe(set_stb),.addr(set_addr),.in(set_data),
+ .out({dsp1_udp_port, dsp0_udp_port}),.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;
+
+ 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)
+ );
+
+ ////////////////////////////////////////////////////////////////////
+ // 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 framer
+ // - CPU input
+ // - ERR input
+ ////////////////////////////////////////////////////////////////////
+
+ //streaming signals from the dsp framer to the combiner
+ wire [35:0] dsp_frm_data;
+ wire dsp_frm_valid;
+ wire dsp_frm_ready;
+
+ //dummy signals to join the the muxes below
+ wire [35:0] _combiner0_data, _combiner1_data;
+ wire _combiner0_valid, _combiner1_valid;
+ wire _combiner0_ready, _combiner1_ready;
+
+ fifo36_mux _com_output_combiner0(
+ .clk(stream_clk), .reset(stream_rst), .clear(stream_clr),
+ .data0_i(dsp_frm_data), .src0_rdy_i(dsp_frm_valid), .dst0_rdy_o(dsp_frm_ready),
+ .data1_i(err_inp_data), .src1_rdy_i(err_inp_valid), .dst1_rdy_o(err_inp_ready),
+ .data_o(_combiner0_data), .src_rdy_o(_combiner0_valid), .dst_rdy_i(_combiner0_ready)
+ );
+
+ fifo36_mux _com_output_combiner1(
+ .clk(stream_clk), .reset(stream_rst), .clear(stream_clr),
+ .data0_i(32'b0), .src0_rdy_i(1'b0), .dst0_rdy_o(), //mux out from dsp1 can go here
+ .data1_i(cpu_inp_data), .src1_rdy_i(cpu_inp_valid), .dst1_rdy_o(cpu_inp_ready),
+ .data_o(_combiner1_data), .src_rdy_o(_combiner1_valid), .dst_rdy_i(_combiner1_ready)
+ );
+
+ fifo36_mux com_output_source(
+ .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(_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
+ ////////////////////////////////////////////////////////////////////
+ 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)
+ );
+
+ ////////////////////////////////////////////////////////////////////
+ // Communication input inspector
+ // - inspect com input and send it to DSP, EXT, CPU, or BOTH
+ ////////////////////////////////////////////////////////////////////
+ localparam COM_INSP_STATE_READ_COM_PRE = 0;
+ localparam COM_INSP_STATE_READ_COM = 1;
+ localparam COM_INSP_STATE_WRITE_REGS = 2;
+ localparam COM_INSP_STATE_WRITE_LIVE = 3;
+
+ localparam COM_INSP_DEST_DSP = 0;
+ localparam COM_INSP_DEST_EXT = 1;
+ localparam COM_INSP_DEST_CPU = 2;
+ localparam COM_INSP_DEST_BOF = 3;
+
+ localparam COM_INSP_MAX_NUM_DREGS = 13; //padded_eth + ip + udp + seq + vrt_hdr
+ localparam COM_INSP_DREGS_DSP_OFFSET = 11; //offset to start dsp at
+
+ //output inspector interfaces
+ wire [35:0] com_insp_out_dsp_data;
+ wire com_insp_out_dsp_valid;
+ wire com_insp_out_dsp_ready;
+
+ wire [35:0] com_insp_out_ext_data;
+ wire com_insp_out_ext_valid;
+ wire com_insp_out_ext_ready;
+
+ wire [35:0] com_insp_out_cpu_data;
+ wire com_insp_out_cpu_valid;
+ wire com_insp_out_cpu_ready;
+
+ wire [35:0] com_insp_out_bof_data;
+ wire com_insp_out_bof_valid;
+ wire com_insp_out_bof_ready;
+
+ //connect this fast-path signals directly to the DSP out
+ assign dsp_out_data = com_insp_out_dsp_data;
+ assign dsp_out_valid = com_insp_out_dsp_valid;
+ assign com_insp_out_dsp_ready = dsp_out_ready;
+
+ reg [1:0] com_insp_state;
+ reg [1:0] com_insp_dest;
+ reg [3:0] com_insp_dreg_count; //data registers to buffer headers
+ wire [3:0] com_insp_dreg_count_next = com_insp_dreg_count + 1'b1;
+ wire com_insp_dreg_counter_done = (com_insp_dreg_count_next == COM_INSP_MAX_NUM_DREGS)? 1'b1 : 1'b0;
+ reg [35:0] com_insp_dregs [COM_INSP_MAX_NUM_DREGS-1:0];
+
+ //extract various packet components:
+ wire [47:0] com_insp_dregs_eth_dst_mac = {com_insp_dregs[0][15:0], com_insp_dregs[1][31:0]};
+ wire [15:0] com_insp_dregs_eth_type = com_insp_dregs[3][15:0];
+ wire [7:0] com_insp_dregs_ipv4_proto = com_insp_dregs[6][23:16];
+ wire [31:0] com_insp_dregs_ipv4_dst_addr = com_insp_dregs[8][31:0];
+ wire [15:0] com_insp_dregs_udp_dst_port = com_insp_dregs[9][15:0];
+ wire [15:0] com_insp_dregs_vrt_size = com_inp_data[15:0];
+
+ //Inspector output flags special case:
+ //Inject SOF into flags at first DSP line.
+ wire [3:0] com_insp_out_flags = (
+ (com_insp_dreg_count == COM_INSP_DREGS_DSP_OFFSET) &&
+ (com_insp_dest == COM_INSP_DEST_DSP)
+ )? 4'b0001 : com_insp_dregs[com_insp_dreg_count][35:32];
+
+ //The communication inspector ouput data and valid signals:
+ //Mux between com input and data registers based on the state.
+ wire [35:0] com_insp_out_data = (com_insp_state == COM_INSP_STATE_WRITE_REGS)?
+ {com_insp_out_flags, com_insp_dregs[com_insp_dreg_count][31:0]} : com_inp_data
+ ;
+ wire com_insp_out_valid =
+ (com_insp_state == COM_INSP_STATE_WRITE_REGS)? 1'b1 : (
+ (com_insp_state == COM_INSP_STATE_WRITE_LIVE)? com_inp_valid : (
+ 1'b0));
+
+ //The communication inspector ouput ready signal:
+ //Mux between the various destination ready signals.
+ wire com_insp_out_ready =
+ (com_insp_dest == COM_INSP_DEST_DSP)? com_insp_out_dsp_ready : (
+ (com_insp_dest == COM_INSP_DEST_EXT)? com_insp_out_ext_ready : (
+ (com_insp_dest == COM_INSP_DEST_CPU)? com_insp_out_cpu_ready : (
+ (com_insp_dest == COM_INSP_DEST_BOF)? com_insp_out_bof_ready : (
+ 1'b0))));
+
+ //Always connected output data lines.
+ assign com_insp_out_dsp_data = com_insp_out_data;
+ assign com_insp_out_ext_data = com_insp_out_data;
+ assign com_insp_out_cpu_data = com_insp_out_data;
+ assign com_insp_out_bof_data = com_insp_out_data;
+
+ //Destination output valid signals:
+ //Comes from inspector valid when destination is selected, and otherwise low.
+ assign com_insp_out_dsp_valid = (com_insp_dest == COM_INSP_DEST_DSP)? com_insp_out_valid : 1'b0;
+ assign com_insp_out_ext_valid = (com_insp_dest == COM_INSP_DEST_EXT)? com_insp_out_valid : 1'b0;
+ assign com_insp_out_cpu_valid = (com_insp_dest == COM_INSP_DEST_CPU)? com_insp_out_valid : 1'b0;
+ assign com_insp_out_bof_valid = (com_insp_dest == COM_INSP_DEST_BOF)? com_insp_out_valid : 1'b0;
+
+ //The communication inspector ouput ready signal:
+ //Always ready when storing to data registers,
+ //comes from inspector ready output when live,
+ //and otherwise low.
+ assign com_inp_ready =
+ (com_insp_state == COM_INSP_STATE_READ_COM_PRE) ? 1'b1 : (
+ (com_insp_state == COM_INSP_STATE_READ_COM) ? 1'b1 : (
+ (com_insp_state == COM_INSP_STATE_WRITE_LIVE) ? com_insp_out_ready : (
+ 1'b0)));
+
+ always @(posedge stream_clk)
+ if(stream_rst | stream_clr) begin
+ com_insp_state <= COM_INSP_STATE_READ_COM_PRE;
+ com_insp_dreg_count <= 0;
+ end
+ else begin
+ case(com_insp_state)
+ COM_INSP_STATE_READ_COM_PRE: begin
+ if (com_inp_ready & com_inp_valid & com_inp_data[32]) begin
+ com_insp_state <= COM_INSP_STATE_READ_COM;
+ com_insp_dreg_count <= com_insp_dreg_count_next;
+ com_insp_dregs[com_insp_dreg_count] <= com_inp_data;
+ end
+ end
+
+ COM_INSP_STATE_READ_COM: begin
+ if (com_inp_ready & com_inp_valid) begin
+ com_insp_dregs[com_insp_dreg_count] <= com_inp_data;
+ if (com_insp_dreg_counter_done | com_inp_data[33]) begin
+ com_insp_state <= COM_INSP_STATE_WRITE_REGS;
+ com_insp_dreg_count <= 0;
+
+ //---------- begin inspection decision -----------//
+ //EOF or bcast or not IPv4 or not UDP:
+ if (
+ com_inp_data[33] || (com_insp_dregs_eth_dst_mac == 48'hffffffffffff) ||
+ (com_insp_dregs_eth_type != 16'h800) || (com_insp_dregs_ipv4_proto != 8'h11)
+ ) begin
+ com_insp_dest <= COM_INSP_DEST_BOF;
+ end
+
+ //not my IP address:
+ else if (com_insp_dregs_ipv4_dst_addr != my_ip_addr) begin
+ com_insp_dest <= COM_INSP_DEST_EXT;
+ end
+
+ //UDP data port and VRT:
+ else if ((com_insp_dregs_udp_dst_port == dsp0_udp_port) && (com_insp_dregs_vrt_size != 16'h0)) begin
+ com_insp_dest <= COM_INSP_DEST_DSP;
+ com_insp_dreg_count <= COM_INSP_DREGS_DSP_OFFSET;
+ end
+
+ //other:
+ else begin
+ com_insp_dest <= COM_INSP_DEST_CPU;
+ end
+ //---------- end inspection decision -------------//
+
+ end
+ else begin
+ com_insp_dreg_count <= com_insp_dreg_count_next;
+ end
+ end
+ end
+
+ COM_INSP_STATE_WRITE_REGS: begin
+ if (com_insp_out_ready & com_insp_out_valid) begin
+ if (com_insp_out_data[33]) begin
+ com_insp_state <= COM_INSP_STATE_READ_COM_PRE;
+ com_insp_dreg_count <= 0;
+ end
+ else if (com_insp_dreg_counter_done) begin
+ com_insp_state <= COM_INSP_STATE_WRITE_LIVE;
+ com_insp_dreg_count <= 0;
+ end
+ else begin
+ com_insp_dreg_count <= com_insp_dreg_count_next;
+ end
+ end
+ end
+
+ COM_INSP_STATE_WRITE_LIVE: begin
+ if (com_insp_out_ready & com_insp_out_valid & com_insp_out_data[33]) begin
+ com_insp_state <= COM_INSP_STATE_READ_COM_PRE;
+ end
+ end
+
+ endcase //com_insp_state
+ end
+
+ ////////////////////////////////////////////////////////////////////
+ // Splitter and output muxes for the bof packets
+ // - split the bof packets into two streams
+ // - mux split packets into cpu out and ext out
+ ////////////////////////////////////////////////////////////////////
+
+ //dummy signals to join the the splitter and muxes below
+ wire [35:0] _split_to_ext_data, _split_to_cpu_data, _cpu_out_data;
+ wire _split_to_ext_valid, _split_to_cpu_valid, _cpu_out_valid;
+ wire _split_to_ext_ready, _split_to_cpu_ready, _cpu_out_ready;
+
+ splitter36 bof_out_splitter(
+ .clk(stream_clk), .rst(stream_rst), .clr(stream_clr),
+ .inp_data(com_insp_out_bof_data), .inp_valid(com_insp_out_bof_valid), .inp_ready(com_insp_out_bof_ready),
+ .out0_data(_split_to_ext_data), .out0_valid(_split_to_ext_valid), .out0_ready(_split_to_ext_ready),
+ .out1_data(_split_to_cpu_data), .out1_valid(_split_to_cpu_valid), .out1_ready(_split_to_cpu_ready)
+ );
+
+ fifo36_mux ext_out_mux(
+ .clk(stream_clk), .reset(stream_rst), .clear(stream_clr),
+ .data0_i(com_insp_out_ext_data), .src0_rdy_i(com_insp_out_ext_valid), .dst0_rdy_o(com_insp_out_ext_ready),
+ .data1_i(_split_to_ext_data), .src1_rdy_i(_split_to_ext_valid), .dst1_rdy_o(_split_to_ext_ready),
+ .data_o(ext_out_data), .src_rdy_o(ext_out_valid), .dst_rdy_i(ext_out_ready)
+ );
+
+ fifo36_mux cpu_out_mux(
+ .clk(stream_clk), .reset(stream_rst), .clear(stream_clr),
+ .data0_i(com_insp_out_cpu_data), .src0_rdy_i(com_insp_out_cpu_valid), .dst0_rdy_o(com_insp_out_cpu_ready),
+ .data1_i(_split_to_cpu_data), .src1_rdy_i(_split_to_cpu_valid), .dst1_rdy_o(_split_to_cpu_ready),
+ .data_o(_cpu_out_data), .src_rdy_o(_cpu_out_valid), .dst_rdy_i(_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)
+ );
+
+ ////////////////////////////////////////////////////////////////////
+ // DSP input framer
+ ////////////////////////////////////////////////////////////////////
+
+ dsp_framer36 #(.BUF_SIZE(BUF_SIZE)) dsp0_framer36(
+ .clk(stream_clk), .rst(stream_rst), .clr(stream_clr),
+ .inp_data(dsp_inp_data), .inp_valid(dsp_inp_valid), .inp_ready(dsp_inp_ready),
+ .out_data(dsp_frm_data), .out_valid(dsp_frm_valid), .out_ready(dsp_frm_ready)
+ );
+
+ ////////////////////////////////////////////////////////////////////
+ // UDP TX Protocol machine
+ ////////////////////////////////////////////////////////////////////
+
+ //dummy signals to connect the components below
+ wire [18:0] _udp_r2s_data, _udp_s2p_data, _udp_p2s_data, _udp_s2r_data;
+ wire _udp_r2s_valid, _udp_s2p_valid, _udp_p2s_valid, _udp_s2r_valid;
+ wire _udp_r2s_ready, _udp_s2p_ready, _udp_p2s_ready, _udp_s2r_ready;
+
+ wire [35:0] _com_out_data;
+ wire _com_out_valid, _com_out_ready;
+
+ fifo36_to_fifo19 udp_fifo36_to_fifo19
+ (.clk(stream_clk), .reset(stream_rst), .clear(stream_clr),
+ .f36_datain(udp_out_data), .f36_src_rdy_i(udp_out_valid), .f36_dst_rdy_o(udp_out_ready),
+ .f19_dataout(_udp_r2s_data), .f19_src_rdy_o(_udp_r2s_valid), .f19_dst_rdy_i(_udp_r2s_ready) );
+
+ fifo_short #(.WIDTH(19)) udp_shortfifo19_inp
+ (.clk(stream_clk), .reset(stream_rst), .clear(stream_clr),
+ .datain(_udp_r2s_data), .src_rdy_i(_udp_r2s_valid), .dst_rdy_o(_udp_r2s_ready),
+ .dataout(_udp_s2p_data), .src_rdy_o(_udp_s2p_valid), .dst_rdy_i(_udp_s2p_ready),
+ .space(), .occupied() );
+
+ 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_s2p_data), .src_rdy_i(_udp_s2p_valid), .dst_rdy_o(_udp_s2p_ready),
+ .dataout(_udp_p2s_data), .src_rdy_o(_udp_p2s_valid), .dst_rdy_i(_udp_p2s_ready) );
+
+ fifo_short #(.WIDTH(19)) udp_shortfifo19_out
+ (.clk(stream_clk), .reset(stream_rst), .clear(stream_clr),
+ .datain(_udp_p2s_data), .src_rdy_i(_udp_p2s_valid), .dst_rdy_o(_udp_p2s_ready),
+ .dataout(_udp_s2r_data), .src_rdy_o(_udp_s2r_valid), .dst_rdy_i(_udp_s2r_ready),
+ .space(), .occupied() );
+
+ fifo19_to_fifo36 udp_fifo19_to_fifo36
+ (.clk(stream_clk), .reset(stream_rst), .clear(stream_clr),
+ .f19_datain(_udp_s2r_data), .f19_src_rdy_i(_udp_s2r_valid), .f19_dst_rdy_o(_udp_s2r_ready),
+ .f36_dataout(_com_out_data), .f36_src_rdy_o(_com_out_valid), .f36_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 (8)
+ dsp_inp_ready, dsp_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,
+
+ //inspector interfaces (8)
+ com_insp_out_dsp_ready, com_insp_out_dsp_valid,
+ com_insp_out_ext_ready, com_insp_out_ext_valid,
+ com_insp_out_cpu_ready, com_insp_out_cpu_valid,
+ com_insp_out_bof_ready, com_insp_out_bof_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
+ };
+
+endmodule // packet_router
diff --git a/usrp2/fifo/splitter36.v b/usrp2/fifo/splitter36.v
new file mode 100644
index 000000000..ed998b4f5
--- /dev/null
+++ b/usrp2/fifo/splitter36.v
@@ -0,0 +1,68 @@
+
+// Split packets from a fifo based interface so it goes out identically on two interfaces
+
+module splitter36
+ (
+ input clk, input rst, input clr,
+ input [35:0] inp_data, input inp_valid, output inp_ready,
+ output [35:0] out0_data, output out0_valid, input out0_ready,
+ output [35:0] out1_data, output out1_valid, input out1_ready
+ );
+
+ localparam STATE_COPY_BOTH = 0;
+ localparam STATE_COPY_ZERO = 1;
+ localparam STATE_COPY_ONE = 2;
+
+ reg [1:0] state;
+ reg [35:0] data_reg;
+
+ assign out0_data = (state == STATE_COPY_BOTH)? inp_data : data_reg;
+ assign out1_data = (state == STATE_COPY_BOTH)? inp_data : data_reg;
+
+ assign out0_valid =
+ (state == STATE_COPY_BOTH)? inp_valid : (
+ (state == STATE_COPY_ZERO)? 1'b1 : (
+ 1'b0));
+
+ assign out1_valid =
+ (state == STATE_COPY_BOTH)? inp_valid : (
+ (state == STATE_COPY_ONE)? 1'b1 : (
+ 1'b0));
+
+ assign inp_ready = (state == STATE_COPY_BOTH)? (out0_ready | out1_ready) : 1'b0;
+
+ always @(posedge clk)
+ if (rst | clr) begin
+ state <= STATE_COPY_BOTH;
+ end
+ else begin
+ case (state)
+
+ STATE_COPY_BOTH: begin
+ if ((out0_valid & out0_ready) & ~(out1_valid & out1_ready)) begin
+ state <= STATE_COPY_ONE;
+ end
+ else if (~(out0_valid & out0_ready) & (out1_valid & out1_ready)) begin
+ state <= STATE_COPY_ZERO;
+ end
+ data_reg <= inp_data;
+ end
+
+ STATE_COPY_ZERO: begin
+ if (out0_valid & out0_ready) begin
+ state <= STATE_COPY_BOTH;
+ end
+ end
+
+ STATE_COPY_ONE: begin
+ if (out1_valid & out1_ready) begin
+ state <= STATE_COPY_BOTH;
+ end
+ end
+
+ endcase //state
+ end
+
+
+
+endmodule //splitter36
diff --git a/usrp2/fifo/valve36.v b/usrp2/fifo/valve36.v
new file mode 100644
index 000000000..b4b23e5a6
--- /dev/null
+++ b/usrp2/fifo/valve36.v
@@ -0,0 +1,28 @@
+
+
+module valve36
+ (input clk, input reset, input clear,
+ input shutoff,
+ input [35:0] data_i, input src_rdy_i, output dst_rdy_o,
+ output [35:0] data_o, output src_rdy_o, input dst_rdy_i);
+
+ reg shutoff_int, active;
+
+ assign data_o = data_i;
+
+ assign dst_rdy_o = shutoff_int ? 1'b1 : dst_rdy_i;
+ assign src_rdy_o = shutoff_int ? 1'b0 : src_rdy_i;
+
+ always @(posedge clk)
+ if(reset | clear)
+ active <= 0;
+ else if(src_rdy_i & dst_rdy_o)
+ active <= ~data_i[33];
+
+ always @(posedge clk)
+ if(reset | clear)
+ shutoff_int <= 0;
+ else if(~active)
+ shutoff_int <= shutoff;
+
+endmodule // valve36