Files
b210-k7-fpga/lib/packet_proc_200/source_flow_control_legacy.v
T
+18 6b67702ad7 Merge FPGA repository back into UHD repository
The FPGA codebase was removed from the UHD repository in 2014 to reduce
the size of the repository. However, over the last half-decade, the
split between the repositories has proven more burdensome than it has
been helpful. By merging the FPGA code back, it will be possible to
create atomic commits that touch both FPGA and UHD codebases. Continuous
integration testing is also simplified by merging the repositories,
because it was previously difficult to automatically derive the correct
UHD branch when testing a feature branch on the FPGA repository.

This commit also updates the license files and paths therein.

We are therefore merging the repositories again. Future development for
FPGA code will happen in the same repository as the UHD host code and
MPM code.

== Original Codebase and Rebasing ==

The original FPGA repository will be hosted for the foreseeable future
at its original local location: https://github.com/EttusResearch/fpga/

It can be used for bisecting, reference, and a more detailed history.

The final commit from said repository to be merged here is
05003794e2da61cabf64dd278c45685a7abad7ec. This commit is tagged as
v4.0.0.0-pre-uhd-merge.

If you have changes in the FPGA repository that you want to rebase onto
the UHD repository, simply run the following commands:

- Create a directory to store patches (this should be an empty
  directory):

    mkdir ~/patches

- Now make sure that your FPGA codebase is based on the same state as
  the code that was merged:

    cd src/fpga # Or wherever your FPGA code is stored
    git rebase v4.0.0.0-pre-uhd-merge

  Note: The rebase command may look slightly different depending on what
  exactly you're trying to rebase.

- Create a patch set for your changes versus v4.0.0.0-pre-uhd-merge:

    git format-patch v4.0.0.0-pre-uhd-merge -o ~/patches

  Note: Make sure that only patches are stored in your output directory.
  It should otherwise be empty. Make sure that you picked the correct
  range of commits, and only commits you wanted to rebase were exported
  as patch files.

- Go to the UHD repository and apply the patches:

    cd src/uhd # Or wherever your UHD repository is stored
    git am --directory fpga ~/patches/*
    rm -rf ~/patches # This is for cleanup

== Contributors ==

The following people have contributed mainly to these files (this list
is not complete):

Co-authored-by: Alex Williams <alex.williams@ni.com>
Co-authored-by: Andrej Rode <andrej.rode@ettus.com>
Co-authored-by: Ashish Chaudhari <ashish@ettus.com>
Co-authored-by: Ben Hilburn <ben.hilburn@ettus.com>
Co-authored-by: Ciro Nishiguchi <ciro.nishiguchi@ni.com>
Co-authored-by: Daniel Jepson <daniel.jepson@ni.com>
Co-authored-by: Derek Kozel <derek.kozel@ettus.com>
Co-authored-by: EJ Kreinar <ej@he360.com>
Co-authored-by: Humberto Jimenez <humberto.jimenez@ni.com>
Co-authored-by: Ian Buckley <ian.buckley@gmail.com>
Co-authored-by: Jörg Hofrichter <joerg.hofrichter@ni.com>
Co-authored-by: Jon Kiser <jon.kiser@ni.com>
Co-authored-by: Josh Blum <josh@joshknows.com>
Co-authored-by: Jonathon Pendlum <jonathan.pendlum@ettus.com>
Co-authored-by: Martin Braun <martin.braun@ettus.com>
Co-authored-by: Matt Ettus <matt@ettus.com>
Co-authored-by: Michael West <michael.west@ettus.com>
Co-authored-by: Moritz Fischer <moritz.fischer@ettus.com>
Co-authored-by: Nick Foster <nick@ettus.com>
Co-authored-by: Nicolas Cuervo <nicolas.cuervo@ettus.com>
Co-authored-by: Paul Butler <paul.butler@ni.com>
Co-authored-by: Paul David <paul.david@ettus.com>
Co-authored-by: Ryan Marlow <ryan.marlow@ettus.com>
Co-authored-by: Sugandha Gupta <sugandha.gupta@ettus.com>
Co-authored-by: Sylvain Munaut <tnt@246tNt.com>
Co-authored-by: Trung Tran <trung.tran@ettus.com>
Co-authored-by: Vidush Vishwanath <vidush.vishwanath@ettus.com>
Co-authored-by: Wade Fife <wade.fife@ettus.com>


Original-commit: bafa9d95453387814ef25e6b6256ba8db2df612f
2020-01-28 09:35:36 -08:00

151 lines
6.1 KiB
Verilog

//
// Copyright 2014-2016 Ettus Research
// Copyright 2018 Ettus Research, a National Instruments Company
//
// SPDX-License-Identifier: LGPL-3.0-or-later
//
// This block passes the in_* AXI port to the out_* AXI port only when it has
// enough flow control credits. Data is held when there are not enough credits.
// Credits are replenished with extension context packets which update the
// last_consumed packet register. Max credits are controlled by settings regs.
// The 2nd line of the packet contains the sequence number in the low 12 bits.
// These packets should not have a time value, but if they do it will be ignored.
module source_flow_control_legacy #(
parameter BASE=0
) (
input clk, input reset, input clear,
input set_stb, input [7:0] set_addr, input [31:0] set_data,
input [63:0] fc_tdata, input fc_tlast, input fc_tvalid, output fc_tready,
input [63:0] in_tdata, input in_tlast, input in_tvalid, output in_tready,
output [63:0] out_tdata, output out_tlast, output out_tvalid, input out_tready,
output busy
);
reg [31:0] last_seqnum_consumed;
wire [31:0] window_size;
wire [31:0] go_until_seqnum = last_seqnum_consumed + window_size + 1;
reg [31:0] current_seqnum;
wire window_reset;
wire window_enable;
//Sets the size of the flow control window
setting_reg #(.my_addr(BASE)) sr_window_size
(.clk(clk),.rst(reset),.strobe(set_stb),.addr(set_addr),.in(set_data),
.out(window_size),.changed());
//Setting to enable/disable the flow control window
//When this register is hit, the window will reset.
//As a part of the reset process, all FC blocked data upstream will be
//dropped by this module and it will reset to the SFC_HEAD head state.
//The reset sequence can take more than one cycle during which this
//module will hold off all flow control data.
setting_reg #(.my_addr(BASE+1), .width(1)) sr_window_enable
(.clk(clk),.rst(reset),.strobe(set_stb),.addr(set_addr),.in(set_data),
.out(window_enable),.changed(window_reset));
reg go;
reg window_reseting;
reg [11:0] window_reset_cnt; //Counter to make reset tolerant to bubble cycles
reg [1:0] sfc_state;
always @(posedge clk) begin
if (reset | clear) begin
window_reseting <= 1'b0;
end else if (window_reset) begin //Reset start
window_reseting <= 1'b1;
window_reset_cnt <= 12'd0;
end else if (window_reseting & ~in_tvalid) begin //Reset end
window_reset_cnt <= window_reset_cnt + 12'd1;
window_reseting <= (window_reset_cnt == 12'hFFF);
end
end
localparam SFC_HEAD = 2'd0;
localparam SFC_TIME = 2'd1;
localparam SFC_BODY = 2'd2;
localparam SFC_DUMP = 2'd3;
always @(posedge clk)
if (reset | clear | window_reset) begin
last_seqnum_consumed <= 32'hFFFFFFFF;
sfc_state <= SFC_HEAD;
end else if (fc_tvalid & fc_tready)
case(sfc_state)
SFC_HEAD :
if(fc_tlast)
sfc_state <= SFC_HEAD; // Error. CHDR packet with only a header is an error.
else if(~fc_tdata[63]) // Is this NOT an extension context packet?
sfc_state <= SFC_DUMP; // Error. Only extension context packets should come in on this interface.
else if(fc_tdata[61]) // Does this packet have time?
sfc_state <= SFC_TIME;
else
sfc_state <= SFC_BODY;
SFC_TIME :
if(fc_tlast)
sfc_state <= SFC_HEAD; // Error, CHDR packet with only header and time is an error.
else
sfc_state <= SFC_BODY;
SFC_BODY :
begin
last_seqnum_consumed <= fc_tdata[31:0]; // Sequence number is in lower 32bits.
if(fc_tlast)
sfc_state <= SFC_HEAD;
else
sfc_state <= SFC_DUMP; // Error. Not expecting any more data in a CHDR packet.
end
SFC_DUMP : // shouldn't ever need to be here, this is an error condition
if(fc_tlast)
sfc_state <= SFC_HEAD;
endcase // case (sfc_state)
assign busy = window_reseting;
assign fc_tready = ~window_reseting; // Consume FC if not in reset
assign out_tdata = in_tdata; // CHDR data flows through combinatorially.
assign out_tlast = in_tlast;
assign in_tready = (go ? out_tready : 1'b0) | window_reseting;
assign out_tvalid = (go & ~window_reseting) ? in_tvalid : 1'b0;
//
// Each time we receive the end of an IF data packet increment the current_seqnum.
// We bravely assume that no packets go missing...or at least that they will be detected elsewhere
// and then handled appropriately.
// The SEQNUM needs to be initialized every time we start a new stream. In new_rx_framer this is done
// as a side effect of writing a new SID value to the setting reg.
//
// By incrementing current_seqnum on the last signal we get the nice effect that packet flow is
// always suspended between packets rather than within a packet.
//
always @(posedge clk)
if(reset | clear | window_reseting)
current_seqnum <= 32'd0;
else if (in_tvalid && in_tready && in_tlast)
current_seqnum <= current_seqnum + 32'd1;
always @(posedge clk)
if(reset | clear) begin
go <= 1'b0;
end else begin
if(~window_enable)
go <= 1'b1;
else
case(go)
1'b0:
// This test assumes the host is well behaved in sending good numbers for packets consumed
// and that current_seqnum increments always by 1 only.
// This way wraps are dealt with without a large logic penalty.
if (in_tvalid & (go_until_seqnum - current_seqnum != 0))
go <= 1'b1;
//if(in_tvalid & (go_until_seqnum > current_seqnum)) // FIXME will need to handle wrap of 32-bit seqnum
1'b1:
if(in_tvalid & in_tready & in_tlast)
go <= 1'b0;
endcase // case (go)
end
endmodule // source_flow_control_legacy