summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJosh Blum <josh@joshknows.com>2012-02-29 16:30:15 -0800
committerJosh Blum <josh@joshknows.com>2012-03-16 11:29:17 -0700
commit78b9db5833ddc7bdd2c7a388448d91b1ea463dd8 (patch)
treeee709bfe6e10b6f3085dba496d274b10b57edbe3
parent7a95ea36f86c512fbbaf34c99e1ba5c3a0237f54 (diff)
downloaduhd-78b9db5833ddc7bdd2c7a388448d91b1ea463dd8.tar.gz
uhd-78b9db5833ddc7bdd2c7a388448d91b1ea463dd8.tar.bz2
uhd-78b9db5833ddc7bdd2c7a388448d91b1ea463dd8.zip
usrp2: first pass implementation of fifo control
-rw-r--r--usrp2/control_lib/Makefile.srcs1
-rw-r--r--usrp2/control_lib/settings_readback_bus_fifo_ctrl.v221
-rw-r--r--usrp2/fifo/Makefile.srcs1
-rw-r--r--usrp2/fifo/packet_dispatcher36_x4.v316
-rw-r--r--usrp2/fifo/packet_router.v23
-rw-r--r--usrp2/top/N2x0/u2plus_core.v42
6 files changed, 594 insertions, 10 deletions
diff --git a/usrp2/control_lib/Makefile.srcs b/usrp2/control_lib/Makefile.srcs
index 6ee7ea262..2afefdd45 100644
--- a/usrp2/control_lib/Makefile.srcs
+++ b/usrp2/control_lib/Makefile.srcs
@@ -55,4 +55,5 @@ atr_controller16.v \
fifo_to_wb.v \
gpio_atr.v \
user_settings.v \
+settings_readback_bus_fifo_ctrl.v \
))
diff --git a/usrp2/control_lib/settings_readback_bus_fifo_ctrl.v b/usrp2/control_lib/settings_readback_bus_fifo_ctrl.v
new file mode 100644
index 000000000..2e6ff1b15
--- /dev/null
+++ b/usrp2/control_lib/settings_readback_bus_fifo_ctrl.v
@@ -0,0 +1,221 @@
+//
+// Copyright 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/>.
+//
+
+// A settings and readback bus controlled via fifo36 interface
+
+//TODO: take vita packets as input and use tsf to wait for time
+//currently we skip vita packet on input, strait to payload
+
+module settings_readback_bus_fifo_ctrl
+ #(
+ parameter SID = 0, //stream id for vita return packet
+ parameter PROT_DEST = 0 //protocol framer destination
+ )
+ (
+ //clock and synchronous reset for all interfaces
+ input clock, input reset,
+
+ //current system time
+ input [63:0] vita_time,
+
+ //input fifo36 interface control
+ input [35:0] in_data, input in_valid, output in_ready,
+
+ //output fifo36 interface status
+ output [35:0] out_data, output out_valid, input out_ready,
+
+ //32-bit settings bus outputs
+ output strobe, output [7:0] addr, output [31:0] data,
+
+ //16X 32-bit inputs for readback
+ input [31:0] word00,
+ input [31:0] word01,
+ input [31:0] word02,
+ input [31:0] word03,
+ input [31:0] word04,
+ input [31:0] word05,
+ input [31:0] word06,
+ input [31:0] word07,
+ input [31:0] word08,
+ input [31:0] word09,
+ input [31:0] word10,
+ input [31:0] word11,
+ input [31:0] word12,
+ input [31:0] word13,
+ input [31:0] word14,
+ input [31:0] word15,
+
+ //debug output
+ output [31:0] debug
+ );
+
+ wire [35:0] in_data0;
+ wire in_valid0, in_ready0;
+
+ fifo_cascade #(.WIDTH(36), .SIZE(9/*512 lines plenty for short pkts*/)) input_fifo (
+ .clk(clock), .reset(reset), .clear(0),
+ .datain(in_data), .src_rdy_i(in_valid), .dst_rdy_o(in_ready),
+ .dataout(in_data0), .src_rdy_o(in_valid0), .dst_rdy_i(in_ready0)
+ );
+
+ wire reading = in_valid0 && in_ready0;
+ wire writing = out_valid && out_ready;
+
+ //state machine constants
+ localparam READ_HDR = 0;
+ localparam READ_DATA = 1;
+ localparam WAIT_EOF = 2;
+ localparam ACTION_EVENT = 3;
+ localparam WRITE_PROT_HDR = 4;
+ localparam WRITE_VRT_HDR = 5;
+ localparam WRITE_VRT_SID = 6;
+ localparam WRITE_VRT_TSF0 = 7;
+ localparam WRITE_VRT_TSF1 = 8;
+ localparam WRITE_RB_HDR = 9;
+ localparam WRITE_RB_DATA = 10;
+
+ reg [3:0] state;
+
+ //holdover from current read inputs
+ reg [31:0] in_data_reg, in_hdr_reg;
+ wire [7:0] in_addr = in_hdr_reg[7:0];
+ wire [7:0] do_poke = in_hdr_reg[8];
+
+ always @(posedge clock) begin
+ if (reset) begin
+ state <= READ_HDR;
+ in_hdr_reg <= 0;
+ in_data_reg <= 0;
+ end
+ else begin
+ case (state)
+
+ READ_HDR: begin
+ if (reading/* && in_data0[32]*/) begin
+ in_hdr_reg <= in_data0[31:0];
+ state <= READ_DATA;
+ end
+ end
+
+ READ_DATA: begin
+ if (reading) begin
+ in_data_reg <= in_data0[31:0];
+ state <= (in_data0[33])? ACTION_EVENT : WAIT_EOF;
+ end
+ end
+
+ WAIT_EOF: begin
+ if (reading) begin
+ if (in_data0[33]) begin
+ state <= ACTION_EVENT;
+ end
+ end
+ end
+
+ ACTION_EVENT: begin // poking and peeking happens here!
+ state <= WRITE_PROT_HDR;
+ end
+
+ WRITE_RB_DATA: begin
+ if (writing) begin
+ state <= READ_HDR;
+ end
+ end
+
+ default: begin
+ if (writing) begin
+ state <= state + 1;
+ end
+ end
+
+ endcase //state
+ end
+ end
+
+ //readback mux
+ reg [31:0] rb_data;
+ reg [63:0] rb_time;
+ always @(posedge clock) begin
+ if (state == ACTION_EVENT) begin
+ rb_time <= vita_time;
+ case (in_addr[3:0])
+ 0 : rb_data <= word00;
+ 1 : rb_data <= word01;
+ 2 : rb_data <= word02;
+ 3 : rb_data <= word03;
+ 4 : rb_data <= word04;
+ 5 : rb_data <= word05;
+ 6 : rb_data <= word06;
+ 7 : rb_data <= word07;
+ 8 : rb_data <= word08;
+ 9 : rb_data <= word09;
+ 10: rb_data <= word10;
+ 11: rb_data <= word11;
+ 12: rb_data <= word12;
+ 13: rb_data <= word13;
+ 14: rb_data <= word14;
+ 15: rb_data <= word15;
+ endcase // case(addr_reg[3:0])
+ end
+ end
+
+ //assign protocol framer header
+ wire [31:0] prot_hdr;
+ assign prot_hdr[15:0] = 24; //bytes in proceeding vita packet
+ assign prot_hdr[16] = 1; //yes frame
+ assign prot_hdr[18:17] = PROT_DEST;
+ assign prot_hdr[31:19] = 0; //nothing
+
+ //register for output data
+ reg [31:0] out_data_int;
+ always @* begin
+ case (state)
+ WRITE_PROT_HDR: out_data_int <= prot_hdr;
+ WRITE_VRT_HDR: out_data_int <= {12'b010100000001, 4'b0/*seqno*/, 16'd6};
+ WRITE_VRT_SID: out_data_int <= SID;
+ WRITE_VRT_TSF0: out_data_int <= rb_time[63:32];
+ WRITE_VRT_TSF1: out_data_int <= rb_time[31:0];
+ WRITE_RB_HDR: out_data_int <= in_hdr_reg;
+ WRITE_RB_DATA: out_data_int <= rb_data;
+ default: out_data_int <= 0;
+ endcase //state
+ end
+
+ //assign to input fifo interface
+ assign in_ready0 = (state < ACTION_EVENT);
+
+ //assign to output fifo interface
+ assign out_valid = (state > ACTION_EVENT);
+ assign out_data[35:34] = 2'b0;
+ assign out_data[33] = (state == WRITE_RB_DATA);
+ assign out_data[32] = (state == WRITE_PROT_HDR);
+ assign out_data[31:0] = out_data_int;
+
+ //assign to settings bus interface
+ assign strobe = (state == ACTION_EVENT) && do_poke;
+ assign data = in_data_reg;
+ assign addr = in_addr;
+
+ assign debug = {
+ state,
+ in_valid, in_ready, in_data[33:32],
+ in_valid0, in_ready0, in_data0[33:32],
+ out_valid, out_ready, out_data[33:32],
+ 16'b0
+ };
+
+endmodule //settings_readback_bus_fifo_ctrl
diff --git a/usrp2/fifo/Makefile.srcs b/usrp2/fifo/Makefile.srcs
index 28d506571..6cbd5cd3f 100644
--- a/usrp2/fifo/Makefile.srcs
+++ b/usrp2/fifo/Makefile.srcs
@@ -32,6 +32,7 @@ splitter36.v \
valve36.v \
fifo_pacer.v \
packet_dispatcher36_x3.v \
+packet_dispatcher36_x4.v \
packet_generator32.v \
packet_generator.v \
packet_verifier32.v \
diff --git a/usrp2/fifo/packet_dispatcher36_x4.v b/usrp2/fifo/packet_dispatcher36_x4.v
new file mode 100644
index 000000000..7eedb3e74
--- /dev/null
+++ b/usrp2/fifo/packet_dispatcher36_x4.v
@@ -0,0 +1,316 @@
+//
+// Copyright 2011-2012 Ettus Research LLC
+//
+// Packet dispatcher with fifo36 interface and 4 outputs.
+//
+// The packet dispatcher expects 2-byte padded ethernet frames.
+// The frames will be inspected at ethernet, IPv4, UDP, and VRT layers.
+// Packets are dispatched into the following streams:
+// * tx dsp stream
+// * tx control stream
+// * to cpu stream
+// * to external stream
+// * to both cpu and external
+//
+// The following registers are used for dispatcher control:
+// * base + 0 = this ipv4 address (32 bits)
+// * base + 1 = udp control port (upper 16 bits), udp dsp port (lower 16 bits)
+//
+
+module packet_dispatcher36_x4
+ #(
+ parameter BASE = 0
+ )
+ (
+ //clocking and reset interface:
+ input clk, input rst, input clr,
+
+ //setting register interface:
+ input set_stb, input [7:0] set_addr, input [31:0] set_data,
+
+ //input stream interfaces:
+ input [35:0] com_inp_data, input com_inp_valid, output com_inp_ready,
+
+ //output stream interfaces:
+ output [35:0] ext_out_data, output ext_out_valid, input ext_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] cpu_out_data, output cpu_out_valid, input cpu_out_ready
+ );
+
+ //setting register to program the IP address
+ wire [31:0] my_ip_addr;
+ setting_reg #(.my_addr(BASE+0)) sreg_ip_addr(
+ .clk(clk),.rst(rst),
+ .strobe(set_stb),.addr(set_addr),.in(set_data),
+ .out(my_ip_addr),.changed()
+ );
+
+ //setting register to program the UDP DSP port
+ wire [15:0] dsp_udp_port, ctl_udp_port;
+ setting_reg #(.my_addr(BASE+1), .width(32)) sreg_data_port(
+ .clk(clk),.rst(rst),
+ .strobe(set_stb),.addr(set_addr),.in(set_data),
+ .out({ctl_udp_port, dsp_udp_port}),.changed()
+ );
+
+ ////////////////////////////////////////////////////////////////////
+ // Communication input inspector
+ // - inspect com input and send it to DSP, EXT, CPU, or BOTH
+ ////////////////////////////////////////////////////////////////////
+ localparam PD_STATE_READ_COM_PRE = 0;
+ localparam PD_STATE_READ_COM = 1;
+ localparam PD_STATE_WRITE_REGS = 2;
+ localparam PD_STATE_WRITE_LIVE = 3;
+
+ localparam PD_DEST_DSP = 0;
+ localparam PD_DEST_EXT = 1;
+ localparam PD_DEST_CPU = 2;
+ localparam PD_DEST_BOF = 3;
+ localparam PD_DEST_CTL = 4;
+
+ localparam PD_MAX_NUM_DREGS = 13; //padded_eth + ip + udp + seq + vrt_hdr
+ localparam PD_DREGS_DSP_OFFSET = 11; //offset to start dsp at
+
+ //output inspector interfaces
+ wire [35:0] pd_out_dsp_data;
+ wire pd_out_dsp_valid;
+ wire pd_out_dsp_ready;
+
+ wire [35:0] pd_out_ext_data;
+ wire pd_out_ext_valid;
+ wire pd_out_ext_ready;
+
+ wire [35:0] pd_out_cpu_data;
+ wire pd_out_cpu_valid;
+ wire pd_out_cpu_ready;
+
+ wire [35:0] pd_out_bof_data;
+ wire pd_out_bof_valid;
+ wire pd_out_bof_ready;
+
+ wire [35:0] pd_out_ctl_data;
+ wire pd_out_ctl_valid;
+ wire pd_out_ctl_ready;
+
+ reg [1:0] pd_state;
+ reg [2:0] pd_dest;
+ reg [3:0] pd_dreg_count; //data registers to buffer headers
+ wire [3:0] pd_dreg_count_next = pd_dreg_count + 1'b1;
+ wire pd_dreg_counter_done = (pd_dreg_count_next == PD_MAX_NUM_DREGS)? 1'b1 : 1'b0;
+ reg [35:0] pd_dregs [PD_MAX_NUM_DREGS-1:0];
+
+ reg is_eth_dst_mac_bcast;
+ reg is_eth_type_ipv4;
+ reg is_eth_ipv4_proto_udp;
+ reg is_eth_ipv4_dst_addr_here;
+ reg is_eth_udp_dsp_port_here;
+ reg is_eth_udp_ctl_port_here;
+ wire is_vrt_size_zero = (com_inp_data[15:0] == 16'h0); //needed on the same cycle, so it cant be registered
+
+ //Inspector output flags special case:
+ //Inject SOF into flags at first DSP line.
+ wire [3:0] pd_out_flags = (
+ (pd_dreg_count == PD_DREGS_DSP_OFFSET) &&
+ (pd_dest == PD_DEST_DSP)
+ )? 4'b0001 : pd_dregs[pd_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] pd_out_data = (pd_state == PD_STATE_WRITE_REGS)?
+ {pd_out_flags, pd_dregs[pd_dreg_count][31:0]} : com_inp_data
+ ;
+ wire pd_out_valid =
+ (pd_state == PD_STATE_WRITE_REGS)? 1'b1 : (
+ (pd_state == PD_STATE_WRITE_LIVE)? com_inp_valid : (
+ 1'b0));
+
+ //The communication inspector ouput ready signal:
+ //Mux between the various destination ready signals.
+ wire pd_out_ready =
+ (pd_dest == PD_DEST_DSP)? pd_out_dsp_ready : (
+ (pd_dest == PD_DEST_EXT)? pd_out_ext_ready : (
+ (pd_dest == PD_DEST_CPU)? pd_out_cpu_ready : (
+ (pd_dest == PD_DEST_BOF)? pd_out_bof_ready : (
+ (pd_dest == PD_DEST_CTL)? pd_out_ctl_ready : (
+ 1'b0)))));
+
+ //Always connected output data lines.
+ assign pd_out_dsp_data = pd_out_data;
+ assign pd_out_ext_data = pd_out_data;
+ assign pd_out_cpu_data = pd_out_data;
+ assign pd_out_bof_data = pd_out_data;
+ assign pd_out_ctl_data = pd_out_data;
+
+ //Destination output valid signals:
+ //Comes from inspector valid when destination is selected, and otherwise low.
+ assign pd_out_dsp_valid = (pd_dest == PD_DEST_DSP)? pd_out_valid : 1'b0;
+ assign pd_out_ext_valid = (pd_dest == PD_DEST_EXT)? pd_out_valid : 1'b0;
+ assign pd_out_cpu_valid = (pd_dest == PD_DEST_CPU)? pd_out_valid : 1'b0;
+ assign pd_out_bof_valid = (pd_dest == PD_DEST_BOF)? pd_out_valid : 1'b0;
+ assign pd_out_ctl_valid = (pd_dest == PD_DEST_CTL)? pd_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 =
+ (pd_state == PD_STATE_READ_COM_PRE) ? 1'b1 : (
+ (pd_state == PD_STATE_READ_COM) ? 1'b1 : (
+ (pd_state == PD_STATE_WRITE_LIVE) ? pd_out_ready : (
+ 1'b0)));
+
+ //inspect the incoming data and mark register booleans
+ always @(posedge clk)
+ if (com_inp_ready & com_inp_valid) begin
+ case(pd_dreg_count)
+ 0: begin
+ is_eth_dst_mac_bcast <= (com_inp_data[15:0] == 16'hffff);
+ end
+ 1: begin
+ is_eth_dst_mac_bcast <= is_eth_dst_mac_bcast && (com_inp_data[31:0] == 32'hffffffff);
+ end
+ 3: begin
+ is_eth_type_ipv4 <= (com_inp_data[15:0] == 16'h800);
+ end
+ 6: begin
+ is_eth_ipv4_proto_udp <= (com_inp_data[23:16] == 8'h11);
+ end
+ 8: begin
+ is_eth_ipv4_dst_addr_here <= (com_inp_data[31:0] == my_ip_addr);
+ end
+ 9: begin
+ is_eth_udp_dsp_port_here <= (com_inp_data[15:0] == dsp_udp_port);
+ is_eth_udp_ctl_port_here <= (com_inp_data[15:0] == ctl_udp_port);
+ end
+ endcase //pd_dreg_count
+ end
+
+ always @(posedge clk)
+ if(rst | clr) begin
+ pd_state <= PD_STATE_READ_COM_PRE;
+ pd_dreg_count <= 0;
+ end
+ else begin
+ case(pd_state)
+ PD_STATE_READ_COM_PRE: begin
+ if (com_inp_ready & com_inp_valid & com_inp_data[32]) begin
+ pd_state <= PD_STATE_READ_COM;
+ pd_dreg_count <= pd_dreg_count_next;
+ pd_dregs[pd_dreg_count] <= com_inp_data;
+ end
+ end
+
+ PD_STATE_READ_COM: begin
+ if (com_inp_ready & com_inp_valid) begin
+ pd_dregs[pd_dreg_count] <= com_inp_data;
+ if (pd_dreg_counter_done | com_inp_data[33]) begin
+ pd_state <= PD_STATE_WRITE_REGS;
+ pd_dreg_count <= 0;
+
+ //---------- begin inspection decision -----------//
+ //EOF or bcast or not IPv4 or not UDP:
+ if (
+ com_inp_data[33] || is_eth_dst_mac_bcast ||
+ ~is_eth_type_ipv4 || ~is_eth_ipv4_proto_udp
+ ) begin
+ pd_dest <= PD_DEST_BOF;
+ end
+
+ //not my IP address:
+ else if (~is_eth_ipv4_dst_addr_here) begin
+ pd_dest <= PD_DEST_EXT;
+ end
+
+ //UDP control port and VRT:
+ else if (is_eth_udp_ctl_port_here && ~is_vrt_size_zero) begin
+ pd_dest <= PD_DEST_CTL;
+ pd_dreg_count <= PD_DREGS_DSP_OFFSET;
+ end
+
+ //UDP data port and VRT:
+ else if (is_eth_udp_dsp_port_here && ~is_vrt_size_zero) begin
+ pd_dest <= PD_DEST_DSP;
+ pd_dreg_count <= PD_DREGS_DSP_OFFSET;
+ end
+
+ //other:
+ else begin
+ pd_dest <= PD_DEST_CPU;
+ end
+ //---------- end inspection decision -------------//
+
+ end
+ else begin
+ pd_dreg_count <= pd_dreg_count_next;
+ end
+ end
+ end
+
+ PD_STATE_WRITE_REGS: begin
+ if (pd_out_ready & pd_out_valid) begin
+ if (pd_out_data[33]) begin
+ pd_state <= PD_STATE_READ_COM_PRE;
+ pd_dreg_count <= 0;
+ end
+ else if (pd_dreg_counter_done) begin
+ pd_state <= PD_STATE_WRITE_LIVE;
+ pd_dreg_count <= 0;
+ end
+ else begin
+ pd_dreg_count <= pd_dreg_count_next;
+ end
+ end
+ end
+
+ PD_STATE_WRITE_LIVE: begin
+ if (pd_out_ready & pd_out_valid & pd_out_data[33]) begin
+ pd_state <= PD_STATE_READ_COM_PRE;
+ end
+ end
+
+ endcase //pd_state
+ end
+
+ //connect this fast-path signals directly to the DSP out
+ assign dsp_out_data = pd_out_dsp_data;
+ assign dsp_out_valid = pd_out_dsp_valid;
+ assign pd_out_dsp_ready = dsp_out_ready;
+
+ assign ctl_out_data = pd_out_ctl_data;
+ assign ctl_out_valid = pd_out_ctl_valid;
+ assign pd_out_ctl_ready = ctl_out_ready;
+
+ ////////////////////////////////////////////////////////////////////
+ // 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;
+ wire _split_to_ext_valid, _split_to_cpu_valid;
+ wire _split_to_ext_ready, _split_to_cpu_ready;
+
+ splitter36 bof_out_splitter(
+ .clk(clk), .rst(rst), .clr(clr),
+ .inp_data(pd_out_bof_data), .inp_valid(pd_out_bof_valid), .inp_ready(pd_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(clk), .reset(rst), .clear(clr),
+ .data0_i(pd_out_ext_data), .src0_rdy_i(pd_out_ext_valid), .dst0_rdy_o(pd_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(clk), .reset(rst), .clear(clr),
+ .data0_i(pd_out_cpu_data), .src0_rdy_i(pd_out_cpu_valid), .dst0_rdy_o(pd_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)
+ );
+
+endmodule // packet_dispatcher36_x3
diff --git a/usrp2/fifo/packet_router.v b/usrp2/fifo/packet_router.v
index 7bfa6893d..4c0fe14b1 100644
--- a/usrp2/fifo/packet_router.v
+++ b/usrp2/fifo/packet_router.v
@@ -1,5 +1,5 @@
//
-// Copyright 2011 Ettus Research LLC
+// 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
@@ -54,10 +54,12 @@ module packet_router
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
);
@@ -188,9 +190,9 @@ module packet_router
////////////////////////////////////////////////////////////////////
//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;
+ 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(
@@ -201,6 +203,14 @@ module packet_router
);
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),
@@ -211,7 +221,7 @@ module packet_router
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(_combiner0_data), .src0_rdy_i(_combiner0_valid), .dst0_rdy_o(_combiner0_ready),
+ .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)
);
@@ -248,12 +258,13 @@ module packet_router
wire _cpu_out_valid;
wire _cpu_out_ready;
- packet_dispatcher36_x3 #(.BASE(CTRL_BASE+1)) packet_dispatcher(
+ 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)
);
diff --git a/usrp2/top/N2x0/u2plus_core.v b/usrp2/top/N2x0/u2plus_core.v
index 369f01183..3459bbc6f 100644
--- a/usrp2/top/N2x0/u2plus_core.v
+++ b/usrp2/top/N2x0/u2plus_core.v
@@ -373,6 +373,10 @@ module u2plus_core
wire wr3_ready_i, wr3_ready_o;
wire [35:0] wr0_dat, wr1_dat, wr2_dat, wr3_dat;
+ wire [35:0] srb_wr_data, srb_rd_data;
+ wire srb_wr_ready, srb_rd_ready;
+ wire srb_wr_valid, srb_rd_valid;
+
wire [35:0] tx_err_data;
wire tx_err_src_rdy, tx_err_dst_rdy;
@@ -393,10 +397,12 @@ module u2plus_core
.dsp0_inp_data(wr1_dat), .dsp0_inp_valid(wr1_ready_i), .dsp0_inp_ready(wr1_ready_o),
.dsp1_inp_data(wr3_dat), .dsp1_inp_valid(wr3_ready_i), .dsp1_inp_ready(wr3_ready_o),
.eth_inp_data(wr2_dat), .eth_inp_valid(wr2_ready_i), .eth_inp_ready(wr2_ready_o),
- .err_inp_data(tx_err_data), .err_inp_ready(tx_err_dst_rdy), .err_inp_valid(tx_err_src_rdy),
+ .err_inp_data(tx_err_data), .err_inp_valid(tx_err_src_rdy), .err_inp_ready(tx_err_dst_rdy),
+ .ctl_inp_data(srb_wr_data), .ctl_inp_valid(srb_wr_valid), .ctl_inp_ready(srb_wr_ready),
.ser_out_data(rd0_dat), .ser_out_valid(rd0_ready_o), .ser_out_ready(rd0_ready_i),
.dsp_out_data(rd1_dat), .dsp_out_valid(rd1_ready_o), .dsp_out_ready(rd1_ready_i),
+ .ctl_out_data(srb_rd_data), .ctl_out_valid(srb_rd_valid), .ctl_out_ready(srb_rd_ready),
.eth_out_data(rd2_dat), .eth_out_valid(rd2_ready_o), .eth_out_ready(rd2_ready_i)
);
@@ -437,13 +443,13 @@ module u2plus_core
//compatibility number -> increment when the fpga has been sufficiently altered
localparam compat_num = {16'd9, 16'd0}; //major, minor
- wire [31:0] churn = status; //tweak churn until timing meets!
+ wire [31:0] churn = 0; //tweak churn until timing meets!
wb_readback_mux buff_pool_status
(.wb_clk_i(wb_clk), .wb_rst_i(wb_rst), .wb_stb_i(s5_stb),
.wb_adr_i(s5_adr), .wb_dat_o(s5_dat_i), .wb_ack_o(s5_ack),
- .word00(churn),.word01(32'b0),.word02(32'b0),.word03(32'b0),
+ .word00(32'b0),.word01(32'b0),.word02(32'b0),.word03(32'b0),
.word04(32'b0),.word05(32'b0),.word06(32'b0),.word07(32'b0),
.word08(status),.word09(gpio_readback),.word10(vita_time[63:32]),
.word11(vita_time[31:0]),.word12(compat_num),.word13({18'b0, button, 1'b0, clk_status, serdes_link_up, 10'b0}),
@@ -477,9 +483,18 @@ module u2plus_core
assign s7_dat_i = 32'd0;
+ wire set_stb_dsp0, set_stb_dsp1;
+ wire [31:0] set_data_dsp0, set_data_dsp1;
+ wire [7:0] set_addr_dsp0, set_addr_dsp1;
+
+ //mux settings_bus_crossclock and settings_readback_bus_fifo_ctrl with prio
+ assign set_stb_dsp = set_stb_dsp0 | set_stb_dsp1;
+ assign set_addr_dsp = set_stb_dsp0? set_addr_dsp0 : set_addr_dsp1;
+ assign set_data_dsp = set_stb_dsp0? set_data_dsp0 : set_data_dsp1;
+
settings_bus_crossclock settings_bus_crossclock
(.clk_i(wb_clk), .rst_i(wb_rst), .set_stb_i(set_stb), .set_addr_i(set_addr), .set_data_i(set_data),
- .clk_o(dsp_clk), .rst_o(dsp_rst), .set_stb_o(set_stb_dsp), .set_addr_o(set_addr_dsp), .set_data_o(set_data_dsp));
+ .clk_o(dsp_clk), .rst_o(dsp_rst), .set_stb_o(set_stb_dsp0), .set_addr_o(set_addr_dsp0), .set_data_o(set_data_dsp0));
user_settings #(.BASE(SR_USER_REGS)) user_settings
(.clk(dsp_clk),.rst(dsp_rst),.set_stb(set_stb_dsp),
@@ -487,6 +502,25 @@ module u2plus_core
.set_addr_user(set_addr_user),.set_data_user(set_data_user),
.set_stb_user(set_stb_user) );
+ // /////////////////////////////////////////////////////////////////////////
+ // Settings + Readback Bus -- FIFO controlled
+
+ wire [31:0] srb_debug;
+ settings_readback_bus_fifo_ctrl #(.PROT_DEST(3)) srb
+ (
+ .clock(dsp_clk), .reset(dsp_rst),
+ .vita_time(vita_time),
+ .in_data(srb_rd_data), .in_valid(srb_rd_valid), .in_ready(srb_rd_ready),
+ .out_data(srb_wr_data), .out_valid(srb_wr_valid), .out_ready(srb_wr_ready),
+ .strobe(set_stb_dsp1), .addr(set_addr_dsp1), .data(set_data_dsp1),
+ .word00(32'b0),.word01(32'b0),.word02(32'b0),.word03(32'b0),
+ .word04(32'b0),.word05(32'b0),.word06(32'b0),.word07(32'b0),
+ .word08(status),.word09(gpio_readback),.word10(vita_time[63:32]),
+ .word11(vita_time[31:0]),.word12(compat_num),.word13({18'b0, button, 1'b0, clk_status, serdes_link_up, 10'b0}),
+ .word14(vita_time_pps[63:32]),.word15(vita_time_pps[31:0]),
+ .debug(srb_debug)
+ );
+
// Output control lines
wire [7:0] clock_outs, serdes_outs, adc_outs;
assign {clock_ready, clk_en[1:0], clk_sel[1:0]} = clock_outs[4:0];