diff options
| author | Wade Fife <wade.fife@ettus.com> | 2020-08-12 14:57:49 -0500 | 
|---|---|---|
| committer | Wade Fife <wade.fife@ettus.com> | 2020-08-13 15:23:26 -0500 | 
| commit | cee09d96aee51795ba2c6578f75f25f30ea11548 (patch) | |
| tree | 3e32999e5edb851ad6f416d0633bc18d96c84550 /fpga/usrp3 | |
| parent | 08ad272ad490a66960ef6c0859d9878f7b82df32 (diff) | |
| download | uhd-cee09d96aee51795ba2c6578f75f25f30ea11548.tar.gz uhd-cee09d96aee51795ba2c6578f75f25f30ea11548.tar.bz2 uhd-cee09d96aee51795ba2c6578f75f25f30ea11548.zip | |
fpga: lib: Fix SWITCH_ON_LAST in axi_mux_select
Thange allows the mux to switch cleanly between packets, if the mux
select input is changed while a packet is in flight.
Diffstat (limited to 'fpga/usrp3')
| -rw-r--r-- | fpga/usrp3/lib/fifo/axi_mux_select.v | 57 | 
1 files changed, 39 insertions, 18 deletions
| diff --git a/fpga/usrp3/lib/fifo/axi_mux_select.v b/fpga/usrp3/lib/fifo/axi_mux_select.v index d3c38ba30..b69f1d8d2 100644 --- a/fpga/usrp3/lib/fifo/axi_mux_select.v +++ b/fpga/usrp3/lib/fifo/axi_mux_select.v @@ -4,7 +4,7 @@  //  // SPDX-License-Identifier: LGPL-3.0-or-later  // -// AXI-Stream multipler with select line +// AXI-Stream multiplexer with select line  //  module axi_mux_select #( @@ -29,12 +29,12 @@ module axi_mux_select #(    genvar n;    generate -    if (PRE_FIFO_SIZE == 0) begin +    if (PRE_FIFO_SIZE == 0) begin : gen_no_pre_fifo        assign i_tdata_int  = i_tdata;        assign i_tlast_int  = i_tlast;        assign i_tvalid_int = i_tvalid;        assign i_tready     = i_tready_int; -    end else begin +    end else begin : gen_pre_fifo        for (n = 0; n < SIZE; n = n + 1) begin          axi_fifo #(.WIDTH(WIDTH+1), .SIZE(PRE_FIFO_SIZE)) axi_fifo (            .clk(clk), .reset(reset), .clear(clear), @@ -48,32 +48,53 @@ module axi_mux_select #(    // Make arrays for easier muxing    genvar i;    generate -    for (i = 0; i < SIZE; i = i + 1) begin +    for (i = 0; i < SIZE; i = i + 1) begin : gen_muxing        assign i_tdata_arr[i] = i_tdata_int[WIDTH*(i+1)-1:WIDTH*i];      end    endgenerate -  // Switch select line either immediately or after the last word in a packet -  reg [$clog2(SIZE)-1:0] select_hold; +  // Switch select line either immediately or if we're not in the middle of a +  // packet. +  reg [$clog2(SIZE)-1:0] select_hold = 0; +    generate -    if (SWITCH_ON_LAST) begin -      reg init; +    if (SWITCH_ON_LAST) begin : gen_switch_on_last +      reg  in_packet_reg = 1'b0; +      wire in_packet; +      wire end_of_packet; +      wire enable_switch; + +      // Create a signal to indicate if we're in the middle of a packet +      assign in_packet = in_packet_reg || o_tvalid_int; + +      // Create a signal to indicate if this is the last transfer of the packet +      assign end_of_packet = o_tlast_int & o_tvalid_int & o_tready_int; + +      // Create a signal that indicates when it's OK to switch the mux select. +      // We can switch if we're not in the middle of outputting a packet, or if +      // we're on the last transfer of a packet. +      assign enable_switch = !in_packet || end_of_packet; +        always @(posedge clk) begin          if (reset | clear) begin -          init        <= 1'b0; -          select_hold <= 'd0; +          select_hold   <= 0; +          in_packet_reg <= 1'b0;          end else begin -          if (|i_tvalid) begin -            init        <= 1'b1; +          // Use in_packet_reg to indicate if we're in a packet. But this +          // register is delayed by a clock cycle, so we need the in_pakcet +          // signal above to add the first clock cycle of a packet. +          if (end_of_packet) begin +            in_packet_reg <= 1'b0; +          end else if (o_tvalid_int) begin +            in_packet_reg <= 1'b1;            end -          // Set select any time after reset and before the first packet OR -          // at the end of a packet -          if (~init | (o_tlast_int & o_tvalid_int & o_tready_int)) begin + +          if (enable_switch) begin              select_hold <= select;            end          end        end -    end else begin +    end else begin : gen_no_switch_on_last        always @(*) begin          select_hold <= select;        end @@ -87,12 +108,12 @@ module axi_mux_select #(    assign i_tready_int = (1'b1 << select_hold) & {SIZE{o_tready_int}};    generate -    if(POST_FIFO_SIZE == 0) begin +    if(POST_FIFO_SIZE == 0) begin : gen_no_post_fifo        assign o_tdata = o_tdata_int;        assign o_tlast = o_tlast_int;        assign o_tvalid = o_tvalid_int;        assign o_tready_int = o_tready; -    end else begin +    end else begin : gen_post_fifo        axi_fifo #(.WIDTH(WIDTH+1),.SIZE(POST_FIFO_SIZE)) axi_fifo (          .clk(clk), .reset(reset), .clear(clear),          .i_tdata({o_tlast_int,o_tdata_int}), .i_tvalid(o_tvalid_int), .i_tready(o_tready_int), | 
