diff options
author | Martin Braun <martin.braun@ettus.com> | 2020-01-23 16:10:22 -0800 |
---|---|---|
committer | Martin Braun <martin.braun@ettus.com> | 2020-01-28 09:35:36 -0800 |
commit | bafa9d95453387814ef25e6b6256ba8db2df612f (patch) | |
tree | 39ba24b5b67072d354775272e687796bb511848d /fpga/usrp3/lib/packet_proc_200 | |
parent | 3075b981503002df3115d5f1d0b97d2619ba30f2 (diff) | |
download | uhd-bafa9d95453387814ef25e6b6256ba8db2df612f.tar.gz uhd-bafa9d95453387814ef25e6b6256ba8db2df612f.tar.bz2 uhd-bafa9d95453387814ef25e6b6256ba8db2df612f.zip |
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>
Diffstat (limited to 'fpga/usrp3/lib/packet_proc_200')
4 files changed, 471 insertions, 0 deletions
diff --git a/fpga/usrp3/lib/packet_proc_200/Makefile.srcs b/fpga/usrp3/lib/packet_proc_200/Makefile.srcs new file mode 100644 index 000000000..3f0834df9 --- /dev/null +++ b/fpga/usrp3/lib/packet_proc_200/Makefile.srcs @@ -0,0 +1,14 @@ +# +# Copyright 2013 Ettus Research LLC +# Copyright 2016 Ettus Research, a National Instruments Company +# +# SPDX-License-Identifier: LGPL-3.0-or-later +# + +################################################## +# Packet Processing Sources +################################################## +PACKET_PROC_200_SRCS = $(abspath $(addprefix $(BASE_DIR)/../lib/packet_proc_200/, \ +cvita_dest_lookup_legacy.v \ +source_flow_control_legacy.v \ +)) diff --git a/fpga/usrp3/lib/packet_proc_200/cvita_dest_lookup_legacy.v b/fpga/usrp3/lib/packet_proc_200/cvita_dest_lookup_legacy.v new file mode 100644 index 000000000..17954baaa --- /dev/null +++ b/fpga/usrp3/lib/packet_proc_200/cvita_dest_lookup_legacy.v @@ -0,0 +1,53 @@ +// +// Copyright 2014 Ettus Research LLC +// Copyright 2018 Ettus Research, a National Instruments Company +// +// SPDX-License-Identifier: LGPL-3.0-or-later +// +// Map the endpoint dest part of the SID in the CVITA header to a destination +// This destination (o_tdest) signal will be valid with o_tdata +// This only works with VALID CVITA frames + +module cvita_dest_lookup_legacy +#( + parameter DEST_WIDTH = 4 +) +( + input clk, input rst, + input set_stb, input [7:0] set_addr, input [DEST_WIDTH-1:0] set_data, + input [63:0] i_tdata, input i_tlast, input i_tvalid, output i_tready, + output [63:0] o_tdata, output o_tlast, output o_tvalid, input o_tready, + output [DEST_WIDTH-1:0] o_tdest +); + + reg [7:0] endpoint; + ram_2port #(.DWIDTH(DEST_WIDTH), .AWIDTH(8)) dest_lut + ( + .clka(clk), .ena(1'b1), .wea(set_stb), .addra(set_addr), .dia(set_data), .doa(), + .clkb(clk), .enb(1'b1), .web(1'b0), .addrb(endpoint), .dib(8'hff), .dob(o_tdest) + ); + + reg forward; + reg [1:0] count; + always @(posedge clk) begin + if (rst) begin + forward <= 1'b0; + count <= 2'b0; + end + else if (forward == 1'b0 && i_tvalid) begin + if (count == 2'b11) forward <= 1'b1; + endpoint <= i_tdata[23:16]; + count <= count + 1'b1; + end + else if (forward == 1'b1 && i_tvalid && i_tready && i_tlast) begin + forward <= 1'b0; + count <= 2'b0; + end + end + + assign o_tdata = i_tdata; + assign o_tlast = i_tlast; + assign o_tvalid = i_tvalid && forward; + assign i_tready = o_tready && forward; + +endmodule // cvita_dest_lookup_legacy diff --git a/fpga/usrp3/lib/packet_proc_200/source_flow_control_legacy.v b/fpga/usrp3/lib/packet_proc_200/source_flow_control_legacy.v new file mode 100644 index 000000000..46906f97d --- /dev/null +++ b/fpga/usrp3/lib/packet_proc_200/source_flow_control_legacy.v @@ -0,0 +1,150 @@ +// +// 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 diff --git a/fpga/usrp3/lib/packet_proc_200/source_flow_control_legacy_tb.v b/fpga/usrp3/lib/packet_proc_200/source_flow_control_legacy_tb.v new file mode 100644 index 000000000..e8f7cccdf --- /dev/null +++ b/fpga/usrp3/lib/packet_proc_200/source_flow_control_legacy_tb.v @@ -0,0 +1,254 @@ +// +// Copyright 2016 Ettus Research, a National Instruments Company +// +// SPDX-License-Identifier: LGPL-3.0-or-later +// +`timescale 1ns/1ps + +module source_flow_control_legacy_tb(); + + reg clk = 0; + reg reset = 1; + + always #10 clk = ~clk; + + initial $dumpfile("source_flow_control_legacy_tb.vcd"); + initial $dumpvars(0,source_flow_control_legacy_tb); + + initial + begin + #1000 reset = 0; + #20000; + $finish; + end + + reg [63:0] tdata; + wire [63:0] tdata_int; + reg tlast; + wire tlast_int; + reg tvalid = 1'b0; + wire tvalid_int; + wire tready, tready_int; + + reg [63:0] fc_tdata; + reg fc_tlast, fc_tvalid; + wire fc_tready; + + wire [63:0] out_tdata; + wire out_tlast, out_tready, out_tvalid; + + wire [15:0] occ_in, occ_out; + reg set_stb = 0; + reg [7:0] set_addr; + reg [31:0] set_data; + + + task send_fc_packet; + input [31:0] seqnum; + input [31:0] sid; + input always_go; + + begin + @(posedge clk); + fc_tlast <= 1'b0; + fc_tdata <= { 1'b1, 1'b0, 1'b0, 1'b0, 12'hABC, 16'd4, sid }; + fc_tvalid <= 1; + @(posedge clk); + fc_tlast <= 1'b1; + //fc_tdata <= { 52'h0,seqnum }; + fc_tdata <= { 31'h0,always_go, seqnum }; + @(posedge clk); + fc_tvalid <= 0; + @(posedge clk); + end + endtask // send_packet + + task send_packet; + input ec; + input timed; + input [11:0] seqnum; + input [31:0] sid; + input [63:0] vtime; + input [15:0] addr; + input [31:0] data; + + begin + // Send a packet + @(posedge clk); + tlast <= 1'b0; + tdata <= { ec, 1'b0, timed, 1'b0, seqnum, timed ? 16'd6 : 16'd4, sid }; + tvalid <= 1; + @(posedge clk); + if(timed) + begin + tdata <= vtime; + @(posedge clk); + end + tlast <= 1'b1; + tdata <= { 16'h0, addr, data }; + @(posedge clk); + tlast <= 1'b0; + tvalid <= 0; + @(posedge clk); + end + endtask // send_packet + + initial + begin + tvalid <= 1'b0; + while(reset) + @(posedge clk); + @(posedge clk); + // Set flow control window to be 2 + set_stb <= 1; + set_addr <= 0; + set_data <= 2; + @(posedge clk); + set_stb <= 0; + // ExtContext. Time. Seq=0, SID=DEAD_6789, Time=10 + send_packet(1'b1,1'b1,12'h0,32'hDEAD_6789,64'h10,16'hB,32'hF00D_1234); + send_packet(1'b1,1'b1,12'h1,32'hDEAD_6789,64'h20,16'hC,32'hABCD_4321); + send_packet(1'b1,1'b1,12'h2,32'hDEAD_6789,64'h30,16'hC,32'hABCD_4321); + send_packet(1'b1,1'b1,12'h3,32'hDEAD_6789,64'h30,16'hC,32'hABCD_4321); + send_packet(1'b1,1'b1,12'h4,32'hDEAD_6789,64'h30,16'hC,32'hABCD_4321); + send_packet(1'b1,1'b1,12'h5,32'hDEAD_6789,64'h30,16'hC,32'hABCD_4321); + send_packet(1'b1,1'b1,12'h6,32'hDEAD_6789,64'h30,16'hC,32'hABCD_4321); + send_packet(1'b1,1'b1,12'h7,32'hDEAD_6789,64'h30,16'hC,32'hABCD_4321); + send_packet(1'b1,1'b1,12'h8,32'hDEAD_6789,64'h30,16'hC,32'hABCD_4321); + #500; + // Consumed 2 packets + send_fc_packet(32'd1,32'h3,1'b0); + #300; + // Consumed 1 packet + send_fc_packet(32'd2,32'h3,1'b0); + #500; + // Consumed 2 packets + send_fc_packet(32'd4,32'h3,1'b0); + #400; + // Send same SEQ ID again to test it causes no changes. + send_fc_packet(32'd4,32'h3,1'b0); + #300; + // Consumed 1 packet + send_fc_packet(32'd5,32'h3,1'b0); + #500; + // Consumed 2 packets + send_fc_packet(32'd7,32'h3,1'b0); + #500; + send_packet(1'b1,1'b1,12'h9,32'hDEAD_6789,64'h30,16'hC,32'hABCD_4321); + send_packet(1'b1,1'b1,12'hA,32'hDEAD_6789,64'h30,16'hC,32'hABCD_4321); + #300; + // Consumed 1 packet + send_fc_packet(32'd8,32'h3,1'b0); + // + // Now force internal sequence count to close to wrap value to test corner case + // + #100; + source_flow_control_legacy.current_seqnum <= 32'hFFFF_FFFC; + #100; + send_fc_packet(32'hFFFF_FFFA,32'h3,1'b0); + #100; + send_packet(1'b1,1'b1,12'hFFC,32'hDEAD_6789,64'h40,16'hC,32'hABCD_4321); + #200; + send_packet(1'b1,1'b1,12'hFFD,32'hDEAD_6789,64'h40,16'hC,32'hABCD_4321); + send_packet(1'b1,1'b1,12'hFFE,32'hDEAD_6789,64'h40,16'hC,32'hABCD_4321); + send_packet(1'b1,1'b1,12'hFFF,32'hDEAD_6789,64'h40,16'hC,32'hABCD_4321); + send_packet(1'b1,1'b1,12'h000,32'hDEAD_6789,64'h40,16'hC,32'hABCD_4321); + send_packet(1'b1,1'b1,12'h001,32'hDEAD_6789,64'h40,16'hC,32'hABCD_4321); + send_packet(1'b1,1'b1,12'h002,32'hDEAD_6789,64'h40,16'hC,32'hABCD_4321); + #200; + // Consumed 2 packets + send_fc_packet(32'hFFFF_FFFC,32'h3,1'b0); + #200; + // Consumed 2 packets + send_fc_packet(32'hFFFF_FFFE,32'h3,1'b0); + send_packet(1'b1,1'b1,12'h003,32'hDEAD_6789,64'h40,16'hC,32'hABCD_4321); + send_packet(1'b1,1'b1,12'h004,32'hDEAD_6789,64'h40,16'hC,32'hABCD_4321); + #200; + // Consumed 2 packets + send_fc_packet(32'h0,32'h3,1'b0); + #200; + // Consumed 2 packets + send_fc_packet(32'h2,32'h3,1'b0); + #500; + // + // Again force internal sequence count to close to wrap value to test new corner case + // + #100; + source_flow_control_legacy.current_seqnum <= 32'hFFFF_FFFC; + #100; + send_fc_packet(32'hFFFF_FFFA,32'h3,1'b0); + #100; + send_packet(1'b1,1'b1,12'hFFC,32'hDEAD_6789,64'h40,16'hC,32'hABCD_4321); + #200; + send_packet(1'b1,1'b1,12'hFFD,32'hDEAD_6789,64'h40,16'hC,32'hABCD_4321); + send_packet(1'b1,1'b1,12'hFFE,32'hDEAD_6789,64'h40,16'hC,32'hABCD_4321); + send_packet(1'b1,1'b1,12'hFFF,32'hDEAD_6789,64'h40,16'hC,32'hABCD_4321); + send_packet(1'b1,1'b1,12'h000,32'hDEAD_6789,64'h40,16'hC,32'hABCD_4321); + send_packet(1'b1,1'b1,12'h001,32'hDEAD_6789,64'h40,16'hC,32'hABCD_4321); + send_packet(1'b1,1'b1,12'h002,32'hDEAD_6789,64'h40,16'hC,32'hABCD_4321); + #200; + // Consumed 1 packets + send_fc_packet(32'hFFFF_FFFB,32'h3,1'b0); + #200; + // Consumed 1 packets + send_fc_packet(32'hFFFF_FFFC,32'h3,1'b0); + send_packet(1'b1,1'b1,12'h003,32'hDEAD_6789,64'h40,16'hC,32'hABCD_4321); + send_packet(1'b1,1'b1,12'h004,32'hDEAD_6789,64'h40,16'hC,32'hABCD_4321); + #200; + // Consumed 1 packets + send_fc_packet(32'hFFFF_FFFD,32'h3,1'b0); + #200; + // Consumed 1 packets + send_fc_packet(32'hFFFF_FFFE,32'h3,1'b0); + #200; + // Consumed 1 packets + send_fc_packet(32'hFFFF_FFFF,32'h3,1'b0); + #200; + // Consumed 1 packets + send_fc_packet(32'h0,32'h3,1'b0); + #200; + // Consumed 1 packets + send_fc_packet(32'h1,32'h3,1'b0); + #200; + // Consumed 1 packets + send_fc_packet(32'h2,32'h3,1'b0); + #500; + + + + + end + + axi_fifo #(.WIDTH(65), .SIZE(10)) fifo_in + (.clk(clk), .reset(reset), .clear(1'b0), + .i_tdata({tlast,tdata}), .i_tvalid(tvalid), .i_tready(tready), + .o_tdata({tlast_int,tdata_int}), .o_tvalid(tvalid_int), .o_tready(tready_int), + .occupied(occ_in)); + + source_flow_control_legacy source_flow_control_legacy + (.clk(clk), .reset(reset), .clear(1'b0), + .set_stb(set_stb), .set_addr(set_addr), .set_data(set_data), + .fc_tdata(fc_tdata), .fc_tlast(fc_tlast), .fc_tvalid(fc_tvalid), .fc_tready(fc_tready), + .in_tdata(tdata_int), .in_tlast(tlast_int), .in_tvalid(tvalid_int), .in_tready(tready_int), + .out_tdata(out_tdata), .out_tlast(out_tlast), .out_tvalid(out_tvalid), .out_tready(out_tready) + ); + + wire [63:0] dump_tdata; + wire dump_tlast, dump_tvalid, dump_tready; + + axi_fifo #(.WIDTH(65), .SIZE(10)) fifo_out + (.clk(clk), .reset(reset), .clear(1'b0), + .i_tdata({out_tlast,out_tdata}), .i_tvalid(out_tvalid), .i_tready(out_tready), + .o_tdata({dump_tlast,dump_tdata}), .o_tvalid(dump_tvalid), .o_tready(dump_tready), + .occupied(occ_out)); + + assign dump_tready = 0; + + always @(posedge clk) + if(out_tvalid & out_tready) + begin + $display("%x",out_tdata); + if(out_tlast) + $display("TLAST"); + end +endmodule // source_flow_control_legacy_tb |