diff options
| -rw-r--r-- | usrp2/control_lib/Makefile.srcs | 1 | ||||
| -rw-r--r-- | usrp2/control_lib/settings_readback_bus_fifo_ctrl.v | 221 | ||||
| -rw-r--r-- | usrp2/fifo/Makefile.srcs | 1 | ||||
| -rw-r--r-- | usrp2/fifo/packet_dispatcher36_x4.v | 316 | ||||
| -rw-r--r-- | usrp2/fifo/packet_router.v | 23 | ||||
| -rw-r--r-- | usrp2/top/N2x0/u2plus_core.v | 42 | 
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]; | 
