fpga: rfnoc: Remove deprecated files
Original-commit: db0d2dddcc5d8e39e2b7843a326ad9392bbb4c3f
This commit is contained in:
@@ -148,7 +148,7 @@ module radio_legacy
|
||||
wire [2:0] rb_addr;
|
||||
|
||||
wire [63:0] vita_time, vita_time_lastpps;
|
||||
timekeeper #(.SR_TIME_HI(SR_TIME), .SR_TIME_LO(SR_TIME+1), .SR_TIME_CTRL(SR_TIME+2)) timekeeper
|
||||
timekeeper_legacy #(.SR_TIME_HI(SR_TIME), .SR_TIME_LO(SR_TIME+1), .SR_TIME_CTRL(SR_TIME+2)) timekeeper
|
||||
(.clk(radio_clk), .reset(radio_rst), .pps(pps), .sync_in(time_sync), .strobe(1'b1),
|
||||
.set_stb(set_stb), .set_addr(set_addr), .set_data(set_data),
|
||||
.vita_time(vita_time), .vita_time_lastpps(vita_time_lastpps),
|
||||
|
||||
@@ -1,15 +1,10 @@
|
||||
noc_shell_tb
|
||||
moving_sum_tb
|
||||
noc_dsp_flow_tb
|
||||
simple_axi_wrapper_tb
|
||||
simple_fir_tb
|
||||
schmidl_cox_tb
|
||||
coregen.log
|
||||
top_block.py
|
||||
test.dat
|
||||
output.dat
|
||||
isim
|
||||
#*
|
||||
axi_wrapper_tb
|
||||
*.dat
|
||||
*.sav
|
||||
|
||||
@@ -19,13 +19,7 @@ RFNOC_FRAMEWORK_SRCS = $(RFNOC_CORE_SRCS) $(RFNOC_XBAR_SRCS) $(RFNOC_UTIL_SRCS)
|
||||
##################################################
|
||||
RFNOC_SRCS = $(abspath $(addprefix $(BASE_DIR)/../lib/rfnoc/, \
|
||||
chdr_fifo_large.v \
|
||||
chdr_framer.v \
|
||||
chdr_framer_2clk.v \
|
||||
chdr_deframer.v \
|
||||
chdr_deframer_2clk.v \
|
||||
chdr_pkt_types.vh \
|
||||
axi_packet_mux.v \
|
||||
axi_wrapper.v \
|
||||
noc_shell_regs.vh \
|
||||
axi_bit_reduce.v \
|
||||
null_source.v \
|
||||
split_stream.v \
|
||||
@@ -49,7 +43,6 @@ cadd.v \
|
||||
keep_one_in_n.v \
|
||||
vector_iir.v \
|
||||
addsub.v \
|
||||
packet_resizer.v \
|
||||
axi_pipe.v \
|
||||
multiply.v \
|
||||
mult.v \
|
||||
|
||||
@@ -1,41 +0,0 @@
|
||||
//
|
||||
// Copyright 2016 Ettus Research
|
||||
// Copyright 2018 Ettus Research, a National Instruments Company
|
||||
//
|
||||
// SPDX-License-Identifier: LGPL-3.0-or-later
|
||||
//
|
||||
// Muxes and packetizes input AXI-streams. Assumes header on tuser.
|
||||
|
||||
module axi_packet_mux #(
|
||||
parameter NUM_INPUTS = 1,
|
||||
parameter MUX_PRE_FIFO_SIZE = 0, // Use 0 (most efficient) unless there is need to compensate for unbalanced input path latencies
|
||||
parameter MUX_POST_FIFO_SIZE = 0, // Generally leave at 0, similar effect as FIFO_SIZE
|
||||
parameter FIFO_SIZE = 5 // Size of FIFO in CHDR framer
|
||||
)(
|
||||
input clk, input reset, input clear,
|
||||
input [NUM_INPUTS*64-1:0] i_tdata, input [NUM_INPUTS-1:0] i_tlast, input [NUM_INPUTS-1:0] i_tvalid, output [NUM_INPUTS-1:0] i_tready, input [NUM_INPUTS*128-1:0] i_tuser,
|
||||
output [63:0] o_tdata, output o_tlast, output o_tvalid, input o_tready
|
||||
);
|
||||
|
||||
wire [NUM_INPUTS*(64+128)-1:0] i_tdata_flat;
|
||||
genvar i;
|
||||
generate
|
||||
for (i = 0; i < NUM_INPUTS; i = i + 1) begin
|
||||
assign i_tdata_flat[(128+64)*(i+1)-1:(128+64)*i] = {i_tuser[128*(i+1)-1:128*i],i_tdata[64*(i+1)-1:64*i]};
|
||||
end
|
||||
endgenerate
|
||||
|
||||
wire [63:0] int_tdata;
|
||||
wire [127:0] int_tuser;
|
||||
wire int_tlast, int_tvalid, int_tready;
|
||||
axi_mux #(.PRIO(0), .WIDTH(128+64), .PRE_FIFO_SIZE(MUX_PRE_FIFO_SIZE), .POST_FIFO_SIZE(MUX_POST_FIFO_SIZE), .SIZE(NUM_INPUTS)) axi_mux (
|
||||
.clk(clk), .reset(reset), .clear(1'b0),
|
||||
.i_tdata(i_tdata_flat), .i_tlast(i_tlast), .i_tvalid(i_tvalid), .i_tready(i_tready),
|
||||
.o_tdata({int_tuser, int_tdata}), .o_tlast(int_tlast), .o_tvalid(int_tvalid), .o_tready(int_tready));
|
||||
|
||||
chdr_framer #(.SIZE(FIFO_SIZE), .WIDTH(64)) chdr_framer (
|
||||
.clk(clk), .reset(reset), .clear(1'b0),
|
||||
.i_tdata(int_tdata), .i_tuser(int_tuser), .i_tlast(int_tlast), .i_tvalid(int_tvalid), .i_tready(int_tready),
|
||||
.o_tdata(o_tdata), .o_tlast(o_tlast), .o_tvalid(o_tvalid), .o_tready(o_tready));
|
||||
|
||||
endmodule
|
||||
@@ -1,217 +0,0 @@
|
||||
//
|
||||
// Copyright 2015 Ettus Research
|
||||
// Copyright 2018 Ettus Research, a National Instruments Company
|
||||
//
|
||||
// SPDX-License-Identifier: LGPL-3.0-or-later
|
||||
//
|
||||
// Assumes 32-bit elements (such as sc16) carried over AXI-Stream
|
||||
// SIMPLE_MODE -- Automatically handle header (s_axis_data_tuser), packets must be consumed / produced 1-to-1
|
||||
// RESIZE_INPUT_PACKET -- Resize input packets. m_axis_data_tlast will be based on m_axis_pkt_len_tdata. Otherwise packet length based on actual input packet length (via i_tlast).
|
||||
// RESIZE_OUTPUT_PACKET -- Resize output packets. s_axis_data_tlast will be ignored and instead use packet length in s_axis_tuser_data. Otherwise use s_axis_data_tlast.
|
||||
//
|
||||
// Note: When SIMPLE_MODE = 1 and RESIZE_OUTPUT_PACKET = 1, s_axis_data_tlast is ignored and output packets are sized according to the length
|
||||
// of the input packet (via the packet length field in the received header). Useful if the user design wants output packet length to
|
||||
// match the input packet length without having to drive s_axis_data_tlast.
|
||||
//
|
||||
// *** Warning: Care should be taken when using RESIZE_INPUT_PACKET and/or RESIZE_OUTPUT_PACKET along with SIMPLE_MODE
|
||||
// as issues could arise if packets are not produced / consumed in a 1:1 ratio. For instance, the header
|
||||
// FIFO could overflow or underflow.
|
||||
|
||||
// _tuser bit definitions
|
||||
// [127:64] == CHDR header
|
||||
// [127:126] == Packet type -- 00 for data, 01 for flow control, 10 for command, 11 for response
|
||||
// [125] == Has time? (0 for no, 1 for time field on next line)
|
||||
// [124] == EOB (end of burst indicator)
|
||||
// [123:112] == 12-bit sequence number
|
||||
// [111: 96] == 16-bit length in bytes
|
||||
// [ 95: 80] == SRC SID (stream ID)
|
||||
// [ 79: 64] == DST SID
|
||||
// [ 63: 0] == timestamp
|
||||
|
||||
module axi_wrapper
|
||||
#(parameter MTU=10,
|
||||
parameter SR_AXI_CONFIG_BASE=129, // AXI configuration bus base, settings bus address range size is 2*NUM_AXI_CONFIG_BUS
|
||||
parameter NUM_AXI_CONFIG_BUS=1, // Number of AXI configuration buses
|
||||
parameter CONFIG_BUS_FIFO_DEPTH=1, // Depth of AXI configuration bus FIFO. Note: AXI configuration bus lacks back pressure.
|
||||
parameter SIMPLE_MODE=1, // 0 = User handles CHDR insertion via tuser signals, 1 = Automatically save / insert CHDR with internal FIFO
|
||||
parameter USE_SEQ_NUM=0, // 0 = Frame will automatically handle sequence number, 1 = Use sequence number provided in s_axis_data_tuser
|
||||
parameter RESIZE_INPUT_PACKET=0, // 0 = Do not resize, packet length determined by i_tlast, 1 = Generate m_axis_data_tlast based on user input m_axis_pkt_len_tdata
|
||||
parameter RESIZE_OUTPUT_PACKET=0, // 0 = Do not resize, packet length determined by s_axis_data_tlast, 1 = Use packet length from user header (s_axis_data_tuser)
|
||||
parameter WIDTH=32) // Specify the output width for the AXI stream data (can be 32 or 64)
|
||||
(input clk, input reset,
|
||||
input bus_clk, input bus_rst,
|
||||
|
||||
input clear_tx_seqnum,
|
||||
input [15:0] next_dst, // Used with SIMPLE_MODE=1
|
||||
|
||||
// To NoC Shell
|
||||
input set_stb, input [7:0] set_addr, input [31: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,
|
||||
|
||||
// To AXI IP
|
||||
output [WIDTH-1:0] m_axis_data_tdata, output [127:0] m_axis_data_tuser, output m_axis_data_tlast, output m_axis_data_tvalid, input m_axis_data_tready,
|
||||
input [WIDTH-1:0] s_axis_data_tdata, input [127:0] s_axis_data_tuser, input s_axis_data_tlast, input s_axis_data_tvalid, output s_axis_data_tready,
|
||||
input [15:0] m_axis_pkt_len_tdata, input m_axis_pkt_len_tvalid, output m_axis_pkt_len_tready, // Used when RESIZE_INPUT_PACKET=1
|
||||
|
||||
// Variable number of AXI configuration buses
|
||||
output [NUM_AXI_CONFIG_BUS*32-1:0] m_axis_config_tdata,
|
||||
output [NUM_AXI_CONFIG_BUS-1:0] m_axis_config_tlast,
|
||||
output [NUM_AXI_CONFIG_BUS-1:0] m_axis_config_tvalid,
|
||||
input [NUM_AXI_CONFIG_BUS-1:0] m_axis_config_tready
|
||||
);
|
||||
|
||||
|
||||
wire clear_tx_seqnum_bclk;
|
||||
pulse_synchronizer clear_tx_seqnum_sync_i (
|
||||
.clk_a(clk), .rst_a(reset), .pulse_a(clear_tx_seqnum), .busy_a(/*Ignored: Pulses from SW are slow*/),
|
||||
.clk_b(bus_clk), .pulse_b(clear_tx_seqnum_bclk)
|
||||
);
|
||||
|
||||
// /////////////////////////////////////////////////////////
|
||||
// Input side handling, chdr_deframer
|
||||
wire [127:0] s_axis_data_tuser_int, m_axis_data_tuser_int;
|
||||
wire s_axis_data_tlast_int, m_axis_data_tlast_int;
|
||||
reg [15:0] m_axis_pkt_len_reg = 16'd8;
|
||||
reg sof_in = 1'b1;
|
||||
wire [127:0] header_fifo_i_tdata = {m_axis_data_tuser[127:96],m_axis_data_tuser[79:64],next_dst,m_axis_data_tuser[63:0]};
|
||||
wire header_fifo_i_tvalid = sof_in & m_axis_data_tvalid & m_axis_data_tready;
|
||||
|
||||
chdr_deframer_2clk #(.WIDTH(WIDTH)) chdr_deframer (
|
||||
.samp_clk(clk), .samp_rst(reset | clear_tx_seqnum), .pkt_clk(bus_clk), .pkt_rst(bus_rst | clear_tx_seqnum_bclk),
|
||||
.i_tdata(i_tdata), .i_tlast(i_tlast), .i_tvalid(i_tvalid), .i_tready(i_tready),
|
||||
.o_tdata(m_axis_data_tdata), .o_tuser(m_axis_data_tuser_int), .o_tlast(m_axis_data_tlast_int), .o_tvalid(m_axis_data_tvalid), .o_tready(m_axis_data_tready)
|
||||
);
|
||||
|
||||
assign m_axis_data_tuser[127:80] = m_axis_data_tuser_int[127:80];
|
||||
assign m_axis_data_tuser[79:64] = RESIZE_INPUT_PACKET ? (m_axis_data_tuser_int[125] ? m_axis_pkt_len_reg+16 : m_axis_pkt_len_reg+8) : m_axis_data_tuser_int[79:64];
|
||||
assign m_axis_data_tuser[63:0] = m_axis_data_tuser_int[63:0];
|
||||
|
||||
// Only store header once per packet
|
||||
always @(posedge clk)
|
||||
if(reset | clear_tx_seqnum)
|
||||
sof_in <= 1'b1;
|
||||
else
|
||||
if(m_axis_data_tvalid & m_axis_data_tready)
|
||||
if(m_axis_data_tlast)
|
||||
sof_in <= 1'b1;
|
||||
else
|
||||
sof_in <= 1'b0;
|
||||
|
||||
// SIMPLE MODE: Store input packet header to reuse as output packet header.
|
||||
generate
|
||||
if(SIMPLE_MODE)
|
||||
begin
|
||||
// FIFO
|
||||
axi_fifo #(.WIDTH(128), .SIZE(5)) header_fifo
|
||||
(.clk(clk), .reset(reset), .clear(clear_tx_seqnum),
|
||||
.i_tdata(header_fifo_i_tdata),
|
||||
.i_tvalid(header_fifo_i_tvalid), .i_tready(),
|
||||
.o_tdata(s_axis_data_tuser_int), .o_tvalid(), .o_tready(s_axis_data_tlast_int & s_axis_data_tvalid & s_axis_data_tready),
|
||||
.occupied(), .space());
|
||||
end else begin
|
||||
assign s_axis_data_tuser_int = s_axis_data_tuser;
|
||||
end
|
||||
endgenerate
|
||||
|
||||
// RESIZE INPUT PACKET
|
||||
// Size input packets based on m_axis_pkt_len_tdata (RESIZE_INPUT_PACKET=1) or based on i_tdata
|
||||
generate
|
||||
if (RESIZE_INPUT_PACKET) begin
|
||||
reg m_axis_data_tlast_reg;
|
||||
reg [15:0] m_axis_pkt_cnt;
|
||||
always @(posedge clk) begin
|
||||
if (reset | clear_tx_seqnum) begin
|
||||
m_axis_data_tlast_reg <= 1'b0;
|
||||
m_axis_pkt_cnt <= (WIDTH/8); // Number of bytes in packet
|
||||
m_axis_pkt_len_reg <= 2*(WIDTH/8); // Double size by default
|
||||
end else begin
|
||||
// Only update packet length at the beginning of a new packet
|
||||
if (m_axis_pkt_len_tvalid & m_axis_pkt_len_tready) begin
|
||||
m_axis_pkt_len_reg <= m_axis_pkt_len_tdata;
|
||||
end
|
||||
if (m_axis_data_tvalid & m_axis_data_tready) begin
|
||||
if (m_axis_pkt_cnt >= m_axis_pkt_len_reg) begin
|
||||
m_axis_pkt_cnt <= (WIDTH/8);
|
||||
end else begin
|
||||
m_axis_pkt_cnt <= m_axis_pkt_cnt + (WIDTH/8);
|
||||
end
|
||||
if (m_axis_pkt_cnt >= m_axis_pkt_len_reg-(WIDTH/8)) begin
|
||||
m_axis_data_tlast_reg <= 1'b1;
|
||||
end else begin
|
||||
m_axis_data_tlast_reg <= 1'b0;
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
assign m_axis_data_tlast = m_axis_data_tlast_reg;
|
||||
assign m_axis_pkt_len_tready = sof_in;
|
||||
end else begin
|
||||
assign m_axis_data_tlast = m_axis_data_tlast_int;
|
||||
assign m_axis_pkt_len_tready = 1'b0;
|
||||
end
|
||||
endgenerate
|
||||
|
||||
// RESIZE OUTPUT PACKET
|
||||
// Size output packets based on either s_axis_data_tlast (RESIZE_OUTPUT_PACKETS=1) or packet length from user header (s_axis_data_tuser)
|
||||
// TODO: There could be a race condition on s_axis_data_tuser_int when
|
||||
// receiving very short packets, but latency in chdr_deframer
|
||||
// prevents this from occurring. Need to fix so it cannot
|
||||
// occur by design.
|
||||
generate
|
||||
if (RESIZE_OUTPUT_PACKET) begin
|
||||
reg [15:0] s_axis_pkt_cnt;
|
||||
reg [15:0] s_axis_pkt_len;
|
||||
always @(posedge clk) begin
|
||||
if (reset | clear_tx_seqnum) begin
|
||||
s_axis_pkt_cnt <= (WIDTH/8);
|
||||
s_axis_pkt_len <= 0;
|
||||
end else begin
|
||||
// Remove header
|
||||
s_axis_pkt_len <= s_axis_data_tuser_int[125] ? s_axis_data_tuser_int[111:96]-16 : s_axis_data_tuser_int[111:96]-8;
|
||||
if (s_axis_data_tvalid & s_axis_data_tready) begin
|
||||
if ((s_axis_pkt_cnt >= s_axis_pkt_len) | s_axis_data_tlast) begin
|
||||
s_axis_pkt_cnt <= (WIDTH/8);
|
||||
end else begin
|
||||
s_axis_pkt_cnt <= s_axis_pkt_cnt + (WIDTH/8);
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
assign s_axis_data_tlast_int = (s_axis_pkt_cnt >= s_axis_pkt_len) | s_axis_data_tlast;
|
||||
end else begin
|
||||
// chdr_framer will automatically fill in the packet length based on user provided tlast
|
||||
assign s_axis_data_tlast_int = s_axis_data_tlast;
|
||||
end
|
||||
endgenerate
|
||||
|
||||
// /////////////////////////////////////////////////////////
|
||||
// Output side handling, chdr_framer
|
||||
chdr_framer_2clk #(.SIZE(MTU), .WIDTH(WIDTH), .USE_SEQ_NUM(USE_SEQ_NUM)) chdr_framer (
|
||||
.samp_clk(clk), .samp_rst(reset | clear_tx_seqnum), .pkt_clk(bus_clk), .pkt_rst(bus_rst | clear_tx_seqnum_bclk),
|
||||
.i_tdata(s_axis_data_tdata), .i_tuser(s_axis_data_tuser_int), .i_tlast(s_axis_data_tlast_int), .i_tvalid(s_axis_data_tvalid), .i_tready(s_axis_data_tready),
|
||||
.o_tdata(o_tdata), .o_tlast(o_tlast), .o_tvalid(o_tvalid), .o_tready(o_tready)
|
||||
);
|
||||
|
||||
// /////////////////////////////////////////////////////////
|
||||
// Control bus handling
|
||||
// FIXME we could put inline control here...
|
||||
// Generate additional AXI stream interfaces for configuration.
|
||||
// FIXME need to make sure we don't overrun this if core can backpressure us
|
||||
// Write to SR_AXI_CONFIG_BASE+1+2*(CONFIG BUS #) asserts tvalid, SR_AXI_CONFIG_BASE+1+2*(CONFIG BUS #)+1 asserts tvalid & tlast
|
||||
genvar k;
|
||||
generate
|
||||
for (k = 0; k < NUM_AXI_CONFIG_BUS; k = k + 1) begin
|
||||
axi_fifo #(.WIDTH(33), .SIZE(CONFIG_BUS_FIFO_DEPTH)) config_stream
|
||||
(.clk(clk), .reset(reset), .clear(clear_tx_seqnum),
|
||||
.i_tdata({(set_addr == (SR_AXI_CONFIG_BASE+2*k+1)),set_data}),
|
||||
.i_tvalid(set_stb & ((set_addr == (SR_AXI_CONFIG_BASE+2*k))|(set_addr == (SR_AXI_CONFIG_BASE+2*k+1)))),
|
||||
.i_tready(),
|
||||
.o_tdata({m_axis_config_tlast[k],m_axis_config_tdata[32*k+31:32*k]}),
|
||||
.o_tvalid(m_axis_config_tvalid[k]),
|
||||
.o_tready(m_axis_config_tready[k]),
|
||||
.occupied(), .space());
|
||||
end
|
||||
endgenerate
|
||||
|
||||
endmodule // axi_wrapper
|
||||
@@ -1,108 +0,0 @@
|
||||
//
|
||||
// Copyright 2014 Ettus Research LLC
|
||||
// Copyright 2018 Ettus Research, a National Instruments Company
|
||||
//
|
||||
// SPDX-License-Identifier: LGPL-3.0-or-later
|
||||
//
|
||||
// FIXME -- detect seqnum errors?
|
||||
|
||||
module chdr_deframer #(
|
||||
parameter WIDTH = 32 // Can be 32 or 64
|
||||
)( input clk, input reset, input clear,
|
||||
input [63:0] i_tdata, input i_tlast, input i_tvalid, output i_tready,
|
||||
output [WIDTH-1:0] o_tdata, output [127:0] o_tuser, output o_tlast, output o_tvalid, input o_tready);
|
||||
|
||||
localparam ST_HEAD = 2'd0;
|
||||
localparam ST_TIME = 2'd1;
|
||||
localparam ST_BODY = 2'd2;
|
||||
|
||||
reg [1:0] chdr_state;
|
||||
reg odd_length;
|
||||
|
||||
wire [127:0] hdr_i_tuser, hdr_o_tuser;
|
||||
wire hdr_i_tvalid, hdr_i_tready;
|
||||
wire hdr_o_tvalid, hdr_o_tready;
|
||||
|
||||
wire [63:0] body_i_tdata, body_o_tdata;
|
||||
wire body_i_tlast, body_o_tlast;
|
||||
wire body_i_tvalid, body_o_tvalid;
|
||||
wire body_i_tready, body_o_tready;
|
||||
|
||||
wire has_time = i_tdata[61];
|
||||
wire [15:0] len = i_tdata[47:32];
|
||||
reg [63:0] held_i_tdata;
|
||||
|
||||
assign body_i_tdata = i_tdata;
|
||||
assign body_i_tlast = i_tlast;
|
||||
assign body_i_tvalid = (chdr_state == ST_BODY) ? i_tvalid : 1'b0;
|
||||
|
||||
assign hdr_i_tuser = (chdr_state == ST_HEAD) ? { i_tdata, i_tdata } : { held_i_tdata, i_tdata }; // 2nd half ignored if no time
|
||||
assign hdr_i_tvalid = (chdr_state == ST_TIME) ? i_tvalid :
|
||||
((chdr_state == ST_HEAD) & ~has_time) ? i_tvalid :
|
||||
1'b0;
|
||||
|
||||
assign i_tready = (chdr_state == ST_BODY) ? body_i_tready : hdr_i_tready;
|
||||
|
||||
// FIXME handle packets with no body
|
||||
always @(posedge clk)
|
||||
if(reset | clear)
|
||||
chdr_state <= ST_HEAD;
|
||||
else
|
||||
case(chdr_state)
|
||||
ST_HEAD :
|
||||
if(i_tvalid & hdr_i_tready)
|
||||
if(has_time)
|
||||
begin
|
||||
chdr_state <= ST_TIME;
|
||||
held_i_tdata <= i_tdata;
|
||||
end
|
||||
else
|
||||
chdr_state <= ST_BODY;
|
||||
ST_TIME :
|
||||
if(i_tvalid & hdr_i_tready)
|
||||
chdr_state <= ST_BODY;
|
||||
ST_BODY :
|
||||
if(i_tvalid & body_i_tready & i_tlast)
|
||||
chdr_state <= ST_HEAD;
|
||||
endcase // case (chdr_state)
|
||||
|
||||
axi_fifo #(.WIDTH(128), .SIZE(5)) hdr_fifo
|
||||
(.clk(clk), .reset(reset), .clear(clear),
|
||||
.i_tdata(hdr_i_tuser), .i_tvalid(hdr_i_tvalid), .i_tready(hdr_i_tready),
|
||||
.o_tdata(hdr_o_tuser), .o_tvalid(hdr_o_tvalid), .o_tready(hdr_o_tready),
|
||||
.occupied(), .space());
|
||||
|
||||
axi_fifo #(.WIDTH(65), .SIZE(5)) body_fifo
|
||||
(.clk(clk), .reset(reset), .clear(clear),
|
||||
.i_tdata({body_i_tlast, body_i_tdata}), .i_tvalid(body_i_tvalid), .i_tready(body_i_tready),
|
||||
.o_tdata({body_o_tlast, body_o_tdata}), .o_tvalid(body_o_tvalid), .o_tready(body_o_tready),
|
||||
.occupied(), .space());
|
||||
|
||||
assign o_tuser = hdr_o_tuser;
|
||||
assign o_tvalid = hdr_o_tvalid & body_o_tvalid;
|
||||
assign hdr_o_tready = o_tvalid & o_tready & o_tlast;
|
||||
|
||||
generate if (WIDTH == 32) begin
|
||||
reg second_half;
|
||||
wire odd_len = hdr_o_tuser[98] ^ |hdr_o_tuser[97:96];
|
||||
|
||||
always @(posedge clk)
|
||||
if(reset | clear)
|
||||
second_half <= 1'b0;
|
||||
else
|
||||
if(o_tvalid & o_tready)
|
||||
if(o_tlast)
|
||||
second_half <= 1'b0;
|
||||
else
|
||||
second_half <= ~second_half;
|
||||
|
||||
assign o_tdata = second_half ? body_o_tdata[31:0] : body_o_tdata[63:32];
|
||||
assign o_tlast = body_o_tlast & (second_half | odd_len);
|
||||
assign body_o_tready = o_tvalid & o_tready & (o_tlast | second_half);
|
||||
end else if (WIDTH == 64) begin
|
||||
assign o_tdata = body_o_tdata;
|
||||
assign o_tlast = body_o_tlast;
|
||||
assign body_o_tready = o_tvalid & o_tready;
|
||||
end endgenerate
|
||||
|
||||
endmodule // chdr_deframer
|
||||
@@ -1,139 +0,0 @@
|
||||
/////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright 2018 Ettus Research, A National Instruments Company
|
||||
//
|
||||
// SPDX-License-Identifier: LGPL-3.0-or-later
|
||||
//
|
||||
// Module: chdr_deframer_2clk
|
||||
// Description:
|
||||
// - Takes a sample stream in and uses the tuser input to frame
|
||||
// a CHDR packet which is output by the module
|
||||
// samples at the output
|
||||
//
|
||||
/////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
module chdr_deframer_2clk #(
|
||||
parameter WIDTH = 32 // 32 and 64 bits supported
|
||||
) (
|
||||
input samp_clk, input samp_rst, input pkt_clk, input pkt_rst,
|
||||
input [63:0] i_tdata, input i_tlast, input i_tvalid, output i_tready,
|
||||
output [WIDTH-1:0] o_tdata, output [127:0] o_tuser, output o_tlast, output o_tvalid, input o_tready
|
||||
);
|
||||
|
||||
localparam [1:0] ST_HEAD = 2'd0;
|
||||
localparam [1:0] ST_TIME = 2'd1;
|
||||
localparam [1:0] ST_BODY = 2'd2;
|
||||
|
||||
reg [1:0] chdr_state;
|
||||
|
||||
wire [127:0] hdr_i_tuser, hdr_o_tuser;
|
||||
wire hdr_i_tvalid, hdr_i_tready;
|
||||
wire hdr_o_tvalid, hdr_o_tready;
|
||||
|
||||
wire [63:0] body_i_tdata, body_o_tdata;
|
||||
wire body_i_tlast, body_o_tlast;
|
||||
wire body_i_tvalid, body_o_tvalid;
|
||||
wire body_i_tready, body_o_tready;
|
||||
|
||||
wire has_time = i_tdata[61];
|
||||
reg [63:0] held_i_tdata;
|
||||
reg second_half;
|
||||
|
||||
assign body_i_tdata = i_tdata;
|
||||
assign body_i_tlast = i_tlast;
|
||||
assign body_i_tvalid = (chdr_state == ST_BODY) ? i_tvalid : 1'b0;
|
||||
|
||||
assign hdr_i_tuser = (chdr_state == ST_HEAD) ? { i_tdata, i_tdata } : { held_i_tdata, i_tdata }; // 2nd half ignored if no time
|
||||
assign hdr_i_tvalid = (chdr_state == ST_TIME) ? i_tvalid :
|
||||
((chdr_state == ST_HEAD) & ~has_time) ? i_tvalid :
|
||||
1'b0;
|
||||
|
||||
assign i_tready = (chdr_state == ST_BODY) ? body_i_tready : hdr_i_tready;
|
||||
|
||||
// FIXME handle packets with no body
|
||||
always @(posedge pkt_clk) begin
|
||||
if (pkt_rst) begin
|
||||
chdr_state <= ST_HEAD;
|
||||
end else begin
|
||||
case(chdr_state)
|
||||
ST_HEAD:
|
||||
if (i_tvalid & hdr_i_tready)
|
||||
if (has_time) begin
|
||||
chdr_state <= ST_TIME;
|
||||
held_i_tdata <= i_tdata;
|
||||
end else begin
|
||||
chdr_state <= ST_BODY;
|
||||
end
|
||||
ST_TIME:
|
||||
if (i_tvalid & hdr_i_tready)
|
||||
chdr_state <= ST_BODY;
|
||||
ST_BODY:
|
||||
if (i_tvalid & body_i_tready & i_tlast)
|
||||
chdr_state <= ST_HEAD;
|
||||
endcase
|
||||
end
|
||||
end
|
||||
|
||||
wire pkt_rst_stretch;
|
||||
pulse_stretch #(.SCALE('d10)) pkt_reset_i (
|
||||
.clk(pkt_clk),
|
||||
.rst(1'b0),
|
||||
.pulse(pkt_rst),
|
||||
.pulse_stretched(pkt_rst_stretch)
|
||||
);
|
||||
|
||||
axi_fifo_2clk #(.WIDTH(128), .SIZE(5)) hdr_fifo_i (
|
||||
.i_aclk(pkt_clk), .o_aclk(samp_clk), .reset(pkt_rst_stretch),
|
||||
.i_tdata(hdr_i_tuser), .i_tvalid(hdr_i_tvalid), .i_tready(hdr_i_tready),
|
||||
.o_tdata(hdr_o_tuser), .o_tvalid(hdr_o_tvalid), .o_tready(hdr_o_tready)
|
||||
);
|
||||
|
||||
axi_fifo_2clk #(.WIDTH(65), .SIZE(9)) body_fifo (
|
||||
.i_aclk(pkt_clk), .o_aclk(samp_clk), .reset(pkt_rst_stretch),
|
||||
.i_tdata({body_i_tlast, body_i_tdata}), .i_tvalid(body_i_tvalid), .i_tready(body_i_tready),
|
||||
.o_tdata({body_o_tlast, body_o_tdata}), .o_tvalid(body_o_tvalid), .o_tready(body_o_tready)
|
||||
);
|
||||
|
||||
wire odd_len = hdr_o_tuser[98] ^ |hdr_o_tuser[97:96];
|
||||
|
||||
generate
|
||||
if (WIDTH == 32) begin : gen_32bit_output
|
||||
// 32-bit Output
|
||||
|
||||
always @(posedge samp_clk) begin
|
||||
if(samp_rst) begin
|
||||
second_half <= 1'b0;
|
||||
end else begin
|
||||
if(o_tvalid & o_tready) begin
|
||||
if(o_tlast)
|
||||
second_half <= 1'b0;
|
||||
else
|
||||
second_half <= ~second_half;
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
assign o_tdata = second_half ? body_o_tdata[WIDTH-1:0] : body_o_tdata[(2*WIDTH)-1:WIDTH];
|
||||
assign o_tlast = body_o_tlast & (second_half | odd_len);
|
||||
assign o_tuser = hdr_o_tuser;
|
||||
assign o_tvalid = hdr_o_tvalid & body_o_tvalid;
|
||||
|
||||
assign hdr_o_tready = o_tvalid & o_tready & o_tlast;
|
||||
assign body_o_tready = o_tvalid & o_tready & (o_tlast | second_half);
|
||||
|
||||
end else begin : gen_64bit_output
|
||||
// 64-bit Output
|
||||
|
||||
assign o_tdata = body_o_tdata;
|
||||
assign o_tlast = body_o_tlast;
|
||||
assign o_tuser = hdr_o_tuser;
|
||||
assign o_tvalid = hdr_o_tvalid & body_o_tvalid;
|
||||
|
||||
assign hdr_o_tready = o_tvalid & o_tready & o_tlast;
|
||||
assign body_o_tready = o_tvalid & o_tready;
|
||||
|
||||
end
|
||||
endgenerate
|
||||
|
||||
endmodule
|
||||
@@ -1,128 +0,0 @@
|
||||
//
|
||||
// Copyright 2014 Ettus Research LLC
|
||||
// Copyright 2018 Ettus Research, a National Instruments Company
|
||||
//
|
||||
// SPDX-License-Identifier: LGPL-3.0-or-later
|
||||
//
|
||||
// FIXME handle odd length inputs
|
||||
//
|
||||
// Warning: Currently only 32 / 64-bit input widths are supported.
|
||||
// If 64-bit is selected, there will be a bubble state.
|
||||
//
|
||||
|
||||
module chdr_framer
|
||||
#(parameter SIZE=10,
|
||||
parameter WIDTH=32, // 32 or 64 only! TODO: Extend to other widths.
|
||||
parameter USE_SEQ_NUM=0) // Use provided seq number in tuser
|
||||
(input clk, input reset, input clear,
|
||||
input [WIDTH-1:0] i_tdata, input [127:0] i_tuser, input i_tlast, input i_tvalid, output i_tready,
|
||||
output [63:0] o_tdata, output o_tlast, output o_tvalid, input o_tready);
|
||||
|
||||
wire header_i_tvalid, header_i_tready;
|
||||
wire [63:0] body_i_tdata;
|
||||
wire body_i_tlast, body_i_tvalid, body_i_tready;
|
||||
|
||||
wire [127:0] header_o_tdata;
|
||||
wire header_o_tvalid, header_o_tready;
|
||||
wire [63:0] body_o_tdata;
|
||||
wire body_o_tlast, body_o_tvalid, body_o_tready;
|
||||
reg [15:0] length;
|
||||
reg [11:0] seqnum;
|
||||
|
||||
assign i_tready = header_i_tready & body_i_tready;
|
||||
assign header_i_tvalid = i_tlast & i_tvalid & i_tready;
|
||||
assign body_i_tlast = i_tlast;
|
||||
|
||||
// Handle 32 and 64 widths
|
||||
generate
|
||||
if (WIDTH == 32) begin
|
||||
reg even;
|
||||
always @(posedge clk)
|
||||
if(reset | clear)
|
||||
even <= 0;
|
||||
else
|
||||
if(i_tvalid & i_tready)
|
||||
if(i_tlast)
|
||||
even <= 0;
|
||||
else
|
||||
even <= ~even;
|
||||
|
||||
reg [31:0] held_i_tdata;
|
||||
always @(posedge clk) begin
|
||||
if (i_tvalid & i_tready) held_i_tdata <= i_tdata;
|
||||
end
|
||||
assign body_i_tvalid = i_tvalid & i_tready & (i_tlast | even);
|
||||
assign body_i_tdata = even ? { held_i_tdata, i_tdata } : {i_tdata, i_tdata}; // really should be 0 in bottom, but this simplifies mux
|
||||
end else begin
|
||||
assign body_i_tvalid = i_tvalid;
|
||||
assign body_i_tdata = i_tdata;
|
||||
end
|
||||
endgenerate
|
||||
|
||||
// FIXME handle lengths of partial 32-bit words
|
||||
always @(posedge clk)
|
||||
if(reset | clear)
|
||||
length <= (WIDTH == 32) ? 4 : 8;
|
||||
else if(header_i_tready & header_i_tvalid)
|
||||
length <= (WIDTH == 32) ? 4 : 8;
|
||||
else if(i_tvalid & i_tready)
|
||||
length <= (WIDTH == 32) ? length + 4 : length + 8;
|
||||
|
||||
axi_fifo_flop2 #(.WIDTH(128)) header_fifo_flop2
|
||||
(.clk(clk), .reset(reset), .clear(clear),
|
||||
.i_tdata({i_tuser[127:112],length,i_tuser[95:0]}), .i_tvalid(header_i_tvalid), .i_tready(header_i_tready),
|
||||
.o_tdata(header_o_tdata), .o_tvalid(header_o_tvalid), .o_tready(header_o_tready),
|
||||
.occupied(), .space());
|
||||
|
||||
axi_fifo #(.WIDTH(65), .SIZE(SIZE)) body_fifo
|
||||
(.clk(clk), .reset(reset), .clear(clear),
|
||||
.i_tdata({body_i_tlast,body_i_tdata}), .i_tvalid(body_i_tvalid), .i_tready(body_i_tready),
|
||||
.o_tdata({body_o_tlast,body_o_tdata}), .o_tvalid(body_o_tvalid), .o_tready(body_o_tready),
|
||||
.occupied(), .space());
|
||||
|
||||
reg [3:0] chdr_state;
|
||||
localparam ST_IDLE = 0;
|
||||
localparam ST_HEAD = 1;
|
||||
localparam ST_TIME = 2;
|
||||
localparam ST_BODY = 3;
|
||||
|
||||
always @(posedge clk)
|
||||
if(reset | clear)
|
||||
chdr_state <= ST_IDLE;
|
||||
else
|
||||
case(chdr_state)
|
||||
ST_IDLE :
|
||||
if(header_o_tvalid & body_o_tvalid)
|
||||
chdr_state <= ST_HEAD;
|
||||
ST_HEAD :
|
||||
if(o_tready)
|
||||
if(header_o_tdata[125]) // time
|
||||
chdr_state <= ST_TIME;
|
||||
else
|
||||
chdr_state <= ST_BODY;
|
||||
ST_TIME :
|
||||
if(o_tready)
|
||||
chdr_state <= ST_BODY;
|
||||
ST_BODY :
|
||||
if(o_tready & body_o_tlast)
|
||||
chdr_state <= ST_IDLE;
|
||||
endcase // case (chdr_state)
|
||||
|
||||
always @(posedge clk)
|
||||
if(reset | clear)
|
||||
seqnum <= 12'd0;
|
||||
else
|
||||
if(o_tvalid & o_tready & o_tlast)
|
||||
seqnum <= seqnum + 12'd1;
|
||||
|
||||
wire [15:0] out_length = header_o_tdata[111:96] + (header_o_tdata[125] ? 16'd16 : 16'd8);
|
||||
|
||||
assign o_tvalid = (chdr_state == ST_HEAD) | (chdr_state == ST_TIME) | (body_o_tvalid & (chdr_state == ST_BODY));
|
||||
assign o_tlast = (chdr_state == ST_BODY) & body_o_tlast;
|
||||
assign o_tdata = (chdr_state == ST_HEAD) ? {header_o_tdata[127:124], (USE_SEQ_NUM ? header_o_tdata[123:112] : seqnum), out_length, header_o_tdata[95:64] } :
|
||||
(chdr_state == ST_TIME) ? header_o_tdata[63:0] :
|
||||
body_o_tdata;
|
||||
assign body_o_tready = (chdr_state == ST_BODY) & o_tready;
|
||||
assign header_o_tready = ((chdr_state == ST_TIME) | ((chdr_state == ST_HEAD) & ~header_o_tdata[125])) & o_tready;
|
||||
|
||||
endmodule // chdr_framer
|
||||
@@ -1,146 +0,0 @@
|
||||
/////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright 2018 Ettus Research, A National Instruments Company
|
||||
//
|
||||
// SPDX-License-Identifier: LGPL-3.0-or-later
|
||||
//
|
||||
// Module: chdr_framer_2clk
|
||||
// Description:
|
||||
// - Takes a sample stream in and uses the tuser input to frame
|
||||
// a CHDR packet which is output by the module
|
||||
// samples at the output
|
||||
// - FIXME Currently only 32 / 64-bit input widths are supported.
|
||||
//
|
||||
/////////////////////////////////////////////////////////////////////
|
||||
|
||||
module chdr_framer_2clk #(
|
||||
parameter SIZE = 10,
|
||||
parameter WIDTH = 32, // 32 or 64 only! TODO: Extend to other widths.
|
||||
parameter USE_SEQ_NUM = 0 // Use provided seq number in tuser
|
||||
) (
|
||||
input samp_clk, input samp_rst, input pkt_clk, input pkt_rst,
|
||||
input [WIDTH-1:0] i_tdata, input [127:0] i_tuser, input i_tlast, input i_tvalid, output i_tready,
|
||||
output [63:0] o_tdata, output o_tlast, output o_tvalid, input o_tready
|
||||
);
|
||||
|
||||
wire header_i_tvalid, header_i_tready;
|
||||
wire [63:0] body_i_tdata;
|
||||
wire body_i_tlast, body_i_tvalid, body_i_tready;
|
||||
|
||||
wire [127:0] header_o_tdata;
|
||||
wire header_o_tvalid, header_o_tready;
|
||||
wire [63:0] body_o_tdata;
|
||||
wire body_o_tlast, body_o_tvalid, body_o_tready;
|
||||
reg [15:0] length;
|
||||
reg [11:0] seqnum;
|
||||
|
||||
assign i_tready = header_i_tready & body_i_tready;
|
||||
assign header_i_tvalid = i_tlast & i_tvalid & i_tready;
|
||||
assign body_i_tlast = i_tlast;
|
||||
|
||||
// Handle 32 and 64 widths
|
||||
generate
|
||||
if (WIDTH == 32) begin
|
||||
reg even = 1'b0;
|
||||
always @(posedge samp_clk)
|
||||
if(samp_rst)
|
||||
even <= 1'b0;
|
||||
else
|
||||
if(i_tvalid & i_tready)
|
||||
if(i_tlast)
|
||||
even <= 1'b0;
|
||||
else
|
||||
even <= ~even;
|
||||
|
||||
reg [31:0] held_i_tdata;
|
||||
always @(posedge samp_clk) begin
|
||||
if (i_tvalid & i_tready) held_i_tdata <= i_tdata;
|
||||
end
|
||||
assign body_i_tvalid = i_tvalid & i_tready & (i_tlast | even);
|
||||
assign body_i_tdata = even ? { held_i_tdata, i_tdata } : {i_tdata, i_tdata}; // really should be 0 in bottom, but this simplifies mux
|
||||
end else begin
|
||||
assign body_i_tvalid = i_tvalid & i_tready;
|
||||
assign body_i_tdata = i_tdata;
|
||||
end
|
||||
endgenerate
|
||||
|
||||
// FIXME handle lengths of partial 32-bit words
|
||||
always @(posedge samp_clk)
|
||||
if (samp_rst)
|
||||
length <= (WIDTH == 32) ? 16'd4 : 16'd8;
|
||||
else if(header_i_tready & header_i_tvalid)
|
||||
length <= (WIDTH == 32) ? 16'd4 : 16'd8;
|
||||
else if(i_tvalid & i_tready)
|
||||
length <= (WIDTH == 32) ? length + 16'd4 : length + 16'd8;
|
||||
|
||||
// Extended reset signal to ensure longer reset on axi_fifo_2clk
|
||||
// as recommended by Xilinx. It clears all partial packets seen
|
||||
// after clearing the fifos.
|
||||
// This pulse stretch ratio works in this case and may not work
|
||||
// for all clocks.
|
||||
wire samp_rst_stretch;
|
||||
pulse_stretch #(.SCALE('d10)) samp_reset_i (
|
||||
.clk(samp_clk),
|
||||
.rst(1'b0),
|
||||
.pulse(samp_rst),
|
||||
.pulse_stretched(samp_rst_stretch)
|
||||
);
|
||||
|
||||
axi_fifo_2clk #(.WIDTH(128), .SIZE(5)) hdr_fifo_i (
|
||||
.i_aclk(samp_clk), .o_aclk(pkt_clk), .reset(samp_rst_stretch),
|
||||
.i_tdata({i_tuser[127:112],length,i_tuser[95:0]}), .i_tvalid(header_i_tvalid), .i_tready(header_i_tready),
|
||||
.o_tdata(header_o_tdata), .o_tvalid(header_o_tvalid), .o_tready(header_o_tready)
|
||||
);
|
||||
|
||||
axi_fifo_2clk #(.WIDTH(65), .SIZE(SIZE)) body_fifo_i (
|
||||
.i_aclk(samp_clk), .o_aclk(pkt_clk), .reset(samp_rst_stretch),
|
||||
.i_tdata({body_i_tlast,body_i_tdata}), .i_tvalid(body_i_tvalid), .i_tready(body_i_tready),
|
||||
.o_tdata({body_o_tlast,body_o_tdata}), .o_tvalid(body_o_tvalid), .o_tready(body_o_tready)
|
||||
);
|
||||
|
||||
reg [1:0] chdr_state;
|
||||
localparam [1:0] ST_IDLE = 0;
|
||||
localparam [1:0] ST_HEAD = 1;
|
||||
localparam [1:0] ST_TIME = 2;
|
||||
localparam [1:0] ST_BODY = 3;
|
||||
|
||||
always @(posedge pkt_clk)
|
||||
if(pkt_rst)
|
||||
chdr_state <= ST_IDLE;
|
||||
else
|
||||
case(chdr_state)
|
||||
ST_IDLE :
|
||||
if(header_o_tvalid & body_o_tvalid)
|
||||
chdr_state <= ST_HEAD;
|
||||
ST_HEAD :
|
||||
if(o_tready)
|
||||
if(header_o_tdata[125]) // time
|
||||
chdr_state <= ST_TIME;
|
||||
else
|
||||
chdr_state <= ST_BODY;
|
||||
ST_TIME :
|
||||
if(o_tready)
|
||||
chdr_state <= ST_BODY;
|
||||
ST_BODY :
|
||||
if(o_tready & body_o_tlast)
|
||||
chdr_state <= ST_IDLE;
|
||||
endcase
|
||||
|
||||
always @(posedge pkt_clk)
|
||||
if(pkt_rst)
|
||||
seqnum <= 12'd0;
|
||||
else
|
||||
if(o_tvalid & o_tready & o_tlast)
|
||||
seqnum <= seqnum + 12'd1;
|
||||
|
||||
wire [15:0] out_length = header_o_tdata[111:96] + (header_o_tdata[125] ? 16'd16 : 16'd8);
|
||||
|
||||
assign o_tvalid = (chdr_state == ST_HEAD) | (chdr_state == ST_TIME) | (body_o_tvalid & (chdr_state == ST_BODY));
|
||||
assign o_tlast = (chdr_state == ST_BODY) & body_o_tlast;
|
||||
assign o_tdata = (chdr_state == ST_HEAD) ? {header_o_tdata[127:124], (USE_SEQ_NUM == 1 ? header_o_tdata[123:112] : seqnum), out_length, header_o_tdata[95:64] } :
|
||||
(chdr_state == ST_TIME) ? header_o_tdata[63:0] :
|
||||
body_o_tdata;
|
||||
assign body_o_tready = (chdr_state == ST_BODY) & o_tready;
|
||||
assign header_o_tready = ((chdr_state == ST_TIME) | ((chdr_state == ST_HEAD) & ~header_o_tdata[125])) & o_tready;
|
||||
|
||||
endmodule
|
||||
@@ -1,11 +0,0 @@
|
||||
// CHDR Packet types
|
||||
// [2:1]: Type
|
||||
// [0]: EOB
|
||||
localparam [2:0] DATA_PKT = 3'b000;
|
||||
localparam [2:0] DATA_EOB_PKT = 3'b001;
|
||||
localparam [2:0] FC_RESP_PKT = 3'b010;
|
||||
localparam [2:0] FC_ACK_PKT = 3'b011;
|
||||
localparam [2:0] CMD_PKT = 3'b100;
|
||||
localparam [2:0] CMD_EOB_PKT = 3'b101; // Unused
|
||||
localparam [2:0] RESP_PKT = 3'b110;
|
||||
localparam [2:0] RESP_ERR_PKT = 3'b111;
|
||||
@@ -21,10 +21,8 @@ axis_ctrl_slave.v \
|
||||
chdr_compute_tkeep.v \
|
||||
chdr_to_chdr_data.v \
|
||||
chdr_to_axis_pyld_ctxt.v \
|
||||
chdr_to_axis_data_mdata.v \
|
||||
chdr_to_axis_data.v \
|
||||
axis_pyld_ctxt_to_chdr.v \
|
||||
axis_data_mdata_to_chdr.v \
|
||||
axis_data_to_chdr.v \
|
||||
chdr_ingress_fifo.v \
|
||||
chdr_mgmt_pkt_handler.v \
|
||||
|
||||
@@ -1,603 +0,0 @@
|
||||
//
|
||||
// Copyright 2019 Ettus Research, A National Instruments Company
|
||||
//
|
||||
// SPDX-License-Identifier: LGPL-3.0-or-later
|
||||
//
|
||||
// Module: axis_data_mdata_to_chdr
|
||||
//
|
||||
// Description:
|
||||
//
|
||||
// A framer module for CHDR data packets. It accepts an input data stream
|
||||
// (with sideband information for packet flags and timestamp) and a separate
|
||||
// metadata stream. A data packet and a metadata packet are required to be
|
||||
// input in order for a single CHDR packet to be generated. If no metadata is
|
||||
// associated with the payload, then an empty metadata packet must be input
|
||||
// along with the data packet (i.e., input a metadata packet with
|
||||
// s_axis_mdata_tkeep set to 0).
|
||||
//
|
||||
// The sideband information (e.g., timestamp, flags) must be input coincident
|
||||
// with the AXI-Stream data input and will be sampled coincident with the
|
||||
// last word of data in the packet (i.e., when tlast is asserted).
|
||||
//
|
||||
// This module also performs an optional clock crossing and data width
|
||||
// conversion from a user requested width for the payload bus to CHDR_W.
|
||||
//
|
||||
// In order to guarantee a gapless CHDR data stream, the metadata packet
|
||||
// should be input before the end of the data packet, although this is not
|
||||
// required.
|
||||
//
|
||||
// Parameters:
|
||||
//
|
||||
// CHDR_W : Width of the input CHDR bus in bits
|
||||
// ITEM_W : Width of the output item bus in bits
|
||||
// NIPC : The number of output items delivered per cycle
|
||||
// SYNC_CLKS : Are the CHDR and data clocks synchronous to each other?
|
||||
// MTU : Log2 of the maximum packet size in CHDR words
|
||||
// INFO_FIFO_SIZE : Log2 of the info FIFO size. This determines the number of
|
||||
// packets that can be simultaneously buffered in the
|
||||
// payload FIFO.
|
||||
// PYLD_FIFO_SIZE : Log2 of the payload FIFO size. The actual FIFO size will
|
||||
// be the maximum of 2**MTU or 2**PYLD_FIFO_SIZE, since the
|
||||
// FIFO must be at least one MTU so that we can calculate
|
||||
// the packet length in the header.
|
||||
//
|
||||
// Signals:
|
||||
//
|
||||
// m_axis_chdr_* : Output CHDR stream
|
||||
// s_axis_* : Input data stream (AXI-Stream)
|
||||
// s_axis_mdata_* : Input metadata stream (AXI-Stream)
|
||||
// flush_* : Signals for flush control and status
|
||||
//
|
||||
|
||||
module axis_data_mdata_to_chdr #(
|
||||
parameter CHDR_W = 256,
|
||||
parameter ITEM_W = 32,
|
||||
parameter NIPC = 2,
|
||||
parameter SYNC_CLKS = 0,
|
||||
parameter MTU = 10,
|
||||
parameter INFO_FIFO_SIZE = 4,
|
||||
parameter PYLD_FIFO_SIZE = MTU
|
||||
)(
|
||||
// Clock, reset and settings
|
||||
input wire axis_chdr_clk,
|
||||
input wire axis_chdr_rst,
|
||||
input wire axis_data_clk,
|
||||
input wire axis_data_rst,
|
||||
// CHDR out (AXI-Stream)
|
||||
output wire [CHDR_W-1:0] m_axis_chdr_tdata,
|
||||
output wire m_axis_chdr_tlast,
|
||||
output wire m_axis_chdr_tvalid,
|
||||
input wire m_axis_chdr_tready,
|
||||
// Payload data stream in (AXI-Stream)
|
||||
input wire [(ITEM_W*NIPC)-1:0] s_axis_tdata,
|
||||
input wire [NIPC-1:0] s_axis_tkeep,
|
||||
input wire s_axis_tlast,
|
||||
input wire s_axis_tvalid,
|
||||
output wire s_axis_tready,
|
||||
// Payload sideband info
|
||||
input wire [63:0] s_axis_ttimestamp,
|
||||
input wire s_axis_thas_time,
|
||||
input wire s_axis_teov,
|
||||
input wire s_axis_teob,
|
||||
// Metadata stream in (AXI-Stream)
|
||||
input wire [CHDR_W-1:0] s_axis_mdata_tdata,
|
||||
input wire s_axis_mdata_tlast,
|
||||
input wire s_axis_mdata_tkeep,
|
||||
input wire s_axis_mdata_tvalid,
|
||||
output wire s_axis_mdata_tready,
|
||||
// Flush signals
|
||||
input wire flush_en,
|
||||
input wire [31:0] flush_timeout,
|
||||
output wire flush_active,
|
||||
output wire flush_done
|
||||
);
|
||||
|
||||
// Make sure the metadata FIFO is large enough to store an entire packet's
|
||||
// worth of metadata (32 words).
|
||||
localparam MDATA_FIFO_SIZE = 5;
|
||||
|
||||
// Make sure the payload FIFO is large enough to store an entire packet's
|
||||
// worth of payload data. This will ensure that we can buffer the entire
|
||||
// packet to calculate its length.
|
||||
localparam PAYLOAD_FIFO_SIZE = PYLD_FIFO_SIZE > MTU ?
|
||||
PYLD_FIFO_SIZE : MTU;
|
||||
|
||||
|
||||
// ---------------------------------------------------
|
||||
// RFNoC Includes
|
||||
// ---------------------------------------------------
|
||||
|
||||
`include "rfnoc_chdr_utils.vh"
|
||||
`include "rfnoc_axis_ctrl_utils.vh"
|
||||
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
// Timestamp and Flags Capture
|
||||
//---------------------------------------------------------------------------
|
||||
//
|
||||
// The timestamp and flags that we use for each packet is that of the last
|
||||
// data word. Here, we capture this information at the end of the packet.
|
||||
//
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
reg [63:0] packet_timestamp;
|
||||
reg packet_has_time;
|
||||
reg packet_eov;
|
||||
reg packet_eob;
|
||||
|
||||
always @(posedge axis_data_clk) begin
|
||||
if (s_axis_tvalid & s_axis_tready & s_axis_tlast) begin
|
||||
packet_timestamp <= s_axis_ttimestamp;
|
||||
packet_has_time <= s_axis_thas_time;
|
||||
packet_eov <= s_axis_teov;
|
||||
packet_eob <= s_axis_teob;
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
// Length Counters
|
||||
//---------------------------------------------------------------------------
|
||||
//
|
||||
// Here We track the state of the incoming packet to determine the payload
|
||||
// and mdata length.
|
||||
//
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
localparam HDR_LEN = CHDR_W/8; // Length of CHDR header word in bytes
|
||||
|
||||
reg [15:0] packet_length;
|
||||
reg [15:0] length_count = HDR_LEN;
|
||||
reg in_pkt_info_tvalid = 0;
|
||||
wire in_pkt_info_tready;
|
||||
|
||||
always @(posedge axis_data_clk) begin : pkt_length_counter
|
||||
if (axis_data_rst) begin
|
||||
length_count <= HDR_LEN;
|
||||
in_pkt_info_tvalid <= 1'b0;
|
||||
end else begin : pkt_length_counter_main
|
||||
// Calculate the length of this word in bytes, taking tkeep into account
|
||||
integer i;
|
||||
integer num_bytes;
|
||||
num_bytes = 0;
|
||||
for (i = 0; i < NIPC; i = i + 1) begin
|
||||
num_bytes = num_bytes + (s_axis_tkeep[i]*(ITEM_W/8));
|
||||
end
|
||||
|
||||
// Update the packet length if the word is accepted
|
||||
in_pkt_info_tvalid <= 1'b0;
|
||||
if (s_axis_tvalid && s_axis_tready) begin
|
||||
if (s_axis_tlast) begin
|
||||
length_count <= HDR_LEN;
|
||||
packet_length <= length_count + num_bytes;
|
||||
in_pkt_info_tvalid <= 1'b1;
|
||||
end else begin
|
||||
length_count <= length_count + num_bytes;
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
reg [4:0] num_mdata = 0;
|
||||
reg [4:0] mdata_count = 0;
|
||||
reg in_mdata_info_tvalid = 0;
|
||||
wire in_mdata_info_tready;
|
||||
|
||||
always @(posedge axis_data_clk) begin : num_mdata_counter
|
||||
if (axis_data_rst) begin
|
||||
mdata_count <= 0;
|
||||
num_mdata <= 0;
|
||||
in_mdata_info_tvalid <= 1'b0;
|
||||
end else begin : num_mdata_counter_main
|
||||
// Update the mdata length if the word is accepted
|
||||
in_mdata_info_tvalid <= 1'b0;
|
||||
if (s_axis_mdata_tvalid && s_axis_mdata_tready) begin
|
||||
if (s_axis_mdata_tlast) begin
|
||||
mdata_count <= 0;
|
||||
num_mdata <= mdata_count + s_axis_mdata_tkeep;
|
||||
in_mdata_info_tvalid <= 1'b1;
|
||||
end else begin
|
||||
mdata_count <= mdata_count + s_axis_mdata_tkeep;
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
// Data Width Converter (ITEM_W*NIPC => CHDR_W)
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
wire [CHDR_W-1:0] in_pyld_tdata;
|
||||
wire in_pyld_tlast;
|
||||
wire in_pyld_tvalid;
|
||||
wire in_pyld_tready;
|
||||
wire width_conv_tready;
|
||||
|
||||
assign width_conv_tready = in_pyld_tready & in_pkt_info_tready;
|
||||
|
||||
generate
|
||||
if (NIPC != CHDR_W/ITEM_W) begin : gen_axis_width_conv
|
||||
axis_width_conv #(
|
||||
.WORD_W (ITEM_W),
|
||||
.IN_WORDS (NIPC),
|
||||
.OUT_WORDS (CHDR_W/ITEM_W),
|
||||
.SYNC_CLKS (1),
|
||||
.PIPELINE ("IN")
|
||||
) payload_width_conv_i (
|
||||
.s_axis_aclk (axis_data_clk),
|
||||
.s_axis_rst (axis_data_rst),
|
||||
.s_axis_tdata (s_axis_tdata),
|
||||
.s_axis_tkeep ({NIPC{1'b1}}),
|
||||
.s_axis_tlast (s_axis_tlast),
|
||||
.s_axis_tvalid (s_axis_tvalid),
|
||||
.s_axis_tready (s_axis_tready),
|
||||
.m_axis_aclk (axis_data_clk),
|
||||
.m_axis_rst (axis_data_rst),
|
||||
.m_axis_tdata (in_pyld_tdata),
|
||||
.m_axis_tkeep (),
|
||||
.m_axis_tlast (in_pyld_tlast),
|
||||
.m_axis_tvalid (in_pyld_tvalid),
|
||||
.m_axis_tready (width_conv_tready)
|
||||
);
|
||||
end else begin : no_gen_axis_width_conv
|
||||
assign in_pyld_tdata = s_axis_tdata;
|
||||
assign in_pyld_tlast = s_axis_tlast;
|
||||
assign in_pyld_tvalid = s_axis_tvalid;
|
||||
assign s_axis_tready = width_conv_tready;
|
||||
end
|
||||
endgenerate
|
||||
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
// Input FIFOs
|
||||
//---------------------------------------------------------------------------
|
||||
//
|
||||
// Buffer the data, packet info, metadata, and cross it into the CHDR clock
|
||||
// domain, if needed. The payload FIFO is sized to match the MTU so that an
|
||||
// entire packet can be buffered while the length is calculated.
|
||||
//
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
wire [CHDR_W-1:0] out_mdata_tdata, out_pyld_tdata;
|
||||
wire out_mdata_tlast, out_pyld_tlast;
|
||||
wire out_mdata_tvalid, out_pyld_tvalid;
|
||||
reg out_mdata_tready, out_pyld_tready;
|
||||
|
||||
wire out_pkt_info_tvalid;
|
||||
reg out_pkt_info_tready;
|
||||
wire out_eob, out_eov, out_has_time;
|
||||
wire [63:0] out_timestamp;
|
||||
wire [15:0] out_length;
|
||||
|
||||
wire [4:0] out_num_mdata;
|
||||
reg out_mdata_info_tready;
|
||||
wire out_mdata_info_tvalid;
|
||||
|
||||
wire in_mdata_tready;
|
||||
|
||||
|
||||
assign s_axis_mdata_tready = in_mdata_tready & in_mdata_info_tready;
|
||||
|
||||
generate if (SYNC_CLKS) begin : gen_sync_fifo
|
||||
axi_fifo #(
|
||||
.WIDTH (CHDR_W+1),
|
||||
.SIZE (PAYLOAD_FIFO_SIZE)
|
||||
) pyld_fifo (
|
||||
.clk (axis_chdr_clk),
|
||||
.reset (axis_chdr_rst),
|
||||
.clear (1'b0),
|
||||
.i_tdata ({in_pyld_tlast, in_pyld_tdata}),
|
||||
.i_tvalid (in_pyld_tvalid),
|
||||
.i_tready (in_pyld_tready),
|
||||
.o_tdata ({out_pyld_tlast, out_pyld_tdata}),
|
||||
.o_tvalid (out_pyld_tvalid),
|
||||
.o_tready (out_pyld_tready),
|
||||
.space (),
|
||||
.occupied ()
|
||||
);
|
||||
axi_fifo #(
|
||||
.WIDTH (CHDR_W + 1),
|
||||
.SIZE (MDATA_FIFO_SIZE)
|
||||
) mdata_fifo (
|
||||
.clk (axis_chdr_clk),
|
||||
.reset (axis_chdr_rst),
|
||||
.clear (1'b0),
|
||||
.i_tdata ({s_axis_mdata_tlast, s_axis_mdata_tdata}),
|
||||
.i_tvalid (s_axis_mdata_tvalid),
|
||||
.i_tready (in_mdata_tready),
|
||||
.o_tdata ({out_mdata_tlast, out_mdata_tdata}),
|
||||
.o_tvalid (out_mdata_tvalid),
|
||||
.o_tready (out_mdata_tready),
|
||||
.space (),
|
||||
.occupied ()
|
||||
);
|
||||
axi_fifo #(
|
||||
.WIDTH (3 + 64 + 16),
|
||||
.SIZE (INFO_FIFO_SIZE)
|
||||
) pkt_info_fifo (
|
||||
.clk (axis_chdr_clk),
|
||||
.reset (axis_chdr_rst),
|
||||
.clear (1'b0),
|
||||
.i_tdata ({packet_eob, packet_eov, packet_has_time,packet_timestamp, packet_length}),
|
||||
.i_tvalid (in_pkt_info_tvalid),
|
||||
.i_tready (in_pkt_info_tready),
|
||||
.o_tdata ({out_eob, out_eov, out_has_time, out_timestamp, out_length}),
|
||||
.o_tvalid (out_pkt_info_tvalid),
|
||||
.o_tready (out_pkt_info_tready),
|
||||
.space (),
|
||||
.occupied ()
|
||||
);
|
||||
axi_fifo #(
|
||||
.WIDTH (5),
|
||||
.SIZE (INFO_FIFO_SIZE)
|
||||
) mdata_info_fifo (
|
||||
.clk (axis_chdr_clk),
|
||||
.reset (axis_chdr_rst),
|
||||
.clear (1'b0),
|
||||
.i_tdata (num_mdata),
|
||||
.i_tvalid (in_mdata_info_tvalid),
|
||||
.i_tready (in_mdata_info_tready),
|
||||
.o_tdata (out_num_mdata),
|
||||
.o_tvalid (out_mdata_info_tvalid),
|
||||
.o_tready (out_mdata_info_tready),
|
||||
.space (),
|
||||
.occupied ()
|
||||
);
|
||||
|
||||
end else begin : gen_async_fifo
|
||||
axi_fifo_2clk #(
|
||||
.WIDTH (CHDR_W + 1),
|
||||
.SIZE (PAYLOAD_FIFO_SIZE)
|
||||
) pyld_fifo (
|
||||
.reset (axis_data_rst),
|
||||
.i_aclk (axis_data_clk),
|
||||
.i_tdata ({in_pyld_tlast, in_pyld_tdata}),
|
||||
.i_tvalid (in_pyld_tvalid),
|
||||
.i_tready (in_pyld_tready),
|
||||
.o_aclk (axis_chdr_clk),
|
||||
.o_tdata ({out_pyld_tlast, out_pyld_tdata}),
|
||||
.o_tvalid (out_pyld_tvalid),
|
||||
.o_tready (out_pyld_tready)
|
||||
);
|
||||
axi_fifo_2clk #(
|
||||
.WIDTH (CHDR_W + 1),
|
||||
.SIZE (MDATA_FIFO_SIZE)
|
||||
) mdata_fifo (
|
||||
.reset (axis_data_rst),
|
||||
.i_aclk (axis_data_clk),
|
||||
.i_tdata ({s_axis_mdata_tlast, s_axis_mdata_tdata}),
|
||||
.i_tvalid (s_axis_mdata_tvalid),
|
||||
.i_tready (in_mdata_tready),
|
||||
.o_aclk (axis_chdr_clk),
|
||||
.o_tdata ({out_mdata_tlast, out_mdata_tdata}),
|
||||
.o_tvalid (out_mdata_tvalid),
|
||||
.o_tready (out_mdata_tready)
|
||||
);
|
||||
axi_fifo_2clk #(
|
||||
.WIDTH (3 + 64 + 16),
|
||||
.SIZE (INFO_FIFO_SIZE)
|
||||
) pkt_info_fifo (
|
||||
.reset (axis_data_rst),
|
||||
.i_aclk (axis_data_clk),
|
||||
.i_tdata ({packet_eob, packet_eov, packet_has_time,packet_timestamp, packet_length}),
|
||||
.i_tvalid (in_pkt_info_tvalid),
|
||||
.i_tready (in_pkt_info_tready),
|
||||
.o_aclk (axis_chdr_clk),
|
||||
.o_tdata ({out_eob, out_eov, out_has_time, out_timestamp, out_length}),
|
||||
.o_tvalid (out_pkt_info_tvalid),
|
||||
.o_tready (out_pkt_info_tready)
|
||||
);
|
||||
axi_fifo_2clk #(
|
||||
.WIDTH (5),
|
||||
.SIZE (INFO_FIFO_SIZE)
|
||||
) mdata_info_fifo (
|
||||
.reset (axis_data_rst),
|
||||
.i_aclk (axis_data_clk),
|
||||
.i_tdata (num_mdata),
|
||||
.i_tvalid (in_mdata_info_tvalid),
|
||||
.i_tready (in_mdata_info_tready),
|
||||
.o_aclk (axis_chdr_clk),
|
||||
.o_tdata (out_num_mdata),
|
||||
.o_tvalid (out_mdata_info_tvalid),
|
||||
.o_tready (out_mdata_info_tready)
|
||||
);
|
||||
end endgenerate
|
||||
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
// Output State Machine
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
reg [CHDR_W-1:0] chdr_pf_tdata;
|
||||
reg chdr_pf_tlast, chdr_pf_tvalid;
|
||||
wire chdr_pf_tready;
|
||||
|
||||
localparam [1:0] ST_HDR = 0; // Processing the output CHDR header
|
||||
localparam [1:0] ST_TS = 1; // Processing the output CHDR timestamp
|
||||
localparam [1:0] ST_MDATA = 2; // Processing the output CHDR metadata word
|
||||
localparam [1:0] ST_PYLD = 3; // Processing the output CHDR payload word
|
||||
|
||||
reg [1:0] state = ST_HDR;
|
||||
|
||||
reg [15:0] seq_num = 0;
|
||||
|
||||
wire [63:0] header;
|
||||
reg [63:0] timestamp;
|
||||
wire [15:0] length;
|
||||
reg has_mdata;
|
||||
|
||||
// Some the payload, metadata, and timestamp lengths (out_length already
|
||||
// includes the header).
|
||||
assign length = (CHDR_W > 64) ?
|
||||
out_length + out_num_mdata * (CHDR_W/8) :
|
||||
out_length + out_num_mdata * (CHDR_W/8) + 8*out_has_time;
|
||||
|
||||
// Build the header word
|
||||
assign header = chdr_build_header(
|
||||
6'b0, // vc
|
||||
out_eob, // eob
|
||||
out_eov, // eov
|
||||
out_has_time ? CHDR_PKT_TYPE_DATA_TS :
|
||||
CHDR_PKT_TYPE_DATA, // pkt_type
|
||||
out_num_mdata, // num_mdata
|
||||
seq_num, // seq_num
|
||||
length, // length
|
||||
16'b0 // dst_epid
|
||||
);
|
||||
|
||||
always @(posedge axis_chdr_clk) begin
|
||||
if (axis_chdr_rst) begin
|
||||
state <= ST_HDR;
|
||||
seq_num <= 0;
|
||||
end else begin
|
||||
case (state)
|
||||
|
||||
// ST_HDR: CHDR Header
|
||||
// -------------------
|
||||
ST_HDR: begin
|
||||
timestamp <= out_timestamp;
|
||||
has_mdata <= (out_num_mdata != CHDR_NO_MDATA);
|
||||
|
||||
if (out_pkt_info_tvalid && out_mdata_info_tvalid && chdr_pf_tready) begin
|
||||
if (CHDR_W > 64) begin
|
||||
// When CHDR_W > 64, the timestamp is a part of the header word.
|
||||
// If this is a data packet (with or without a TS), we skip the
|
||||
// timestamp state move directly to metadata/body.
|
||||
if (out_num_mdata == CHDR_NO_MDATA) begin
|
||||
state <= ST_PYLD;
|
||||
end else begin
|
||||
state <= ST_MDATA;
|
||||
end
|
||||
end else begin
|
||||
// When CHDR_W == 64, the timestamp comes after the header. Check
|
||||
// if this is a data packet with a timestamp or metadata to
|
||||
// figure out the next state.
|
||||
if (out_has_time) begin
|
||||
state <= ST_TS;
|
||||
end else if (out_num_mdata != CHDR_NO_MDATA) begin
|
||||
state <= ST_MDATA;
|
||||
end else begin
|
||||
state <= ST_PYLD;
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
// ST_TS: Timestamp (CHDR_W == 64 only)
|
||||
// ------------------------------------
|
||||
ST_TS: begin
|
||||
if (chdr_pf_tready) begin
|
||||
state <= has_mdata ? ST_MDATA : ST_PYLD;
|
||||
end
|
||||
end
|
||||
|
||||
// ST_MDATA: Metadata word
|
||||
// -----------------------
|
||||
ST_MDATA: begin
|
||||
if (out_mdata_tvalid && out_mdata_tready && out_mdata_tlast) begin
|
||||
state <= ST_PYLD;
|
||||
end
|
||||
end
|
||||
|
||||
// ST_PYLD: Payload word
|
||||
// ---------------------
|
||||
ST_PYLD: begin
|
||||
if (out_pyld_tvalid && out_pyld_tready && out_pyld_tlast) begin
|
||||
state <= ST_HDR;
|
||||
seq_num <= seq_num + 1;
|
||||
end
|
||||
end
|
||||
|
||||
default: begin
|
||||
// We should never get here
|
||||
state <= ST_HDR;
|
||||
end
|
||||
endcase
|
||||
end
|
||||
end
|
||||
|
||||
always @(*) begin
|
||||
case (state)
|
||||
ST_HDR: begin
|
||||
// Insert header word
|
||||
chdr_pf_tdata = (CHDR_W > 64) ? { out_timestamp, header } : header;
|
||||
chdr_pf_tvalid = out_pkt_info_tvalid & out_mdata_info_tvalid;
|
||||
chdr_pf_tlast = 1'b0;
|
||||
out_mdata_tready = chdr_pf_tready & // Remove empty mdata packet from FIFO
|
||||
(out_num_mdata == CHDR_NO_MDATA);
|
||||
out_mdata_info_tready = chdr_pf_tready; // Remove mdata info word from FIFO
|
||||
out_pyld_tready = 1'b0;
|
||||
out_pkt_info_tready = chdr_pf_tready; // Remove packet info word from FIFO
|
||||
end
|
||||
ST_TS: begin
|
||||
// Insert timestamp
|
||||
chdr_pf_tdata[63:0] = timestamp;
|
||||
chdr_pf_tvalid = 1'b1; // Timestamp register is always valid in this state
|
||||
chdr_pf_tlast = 1'b0;
|
||||
out_mdata_tready = 1'b0;
|
||||
out_mdata_info_tready = 1'b0;
|
||||
out_pyld_tready = 1'b0;
|
||||
out_pkt_info_tready = 1'b0;
|
||||
end
|
||||
ST_MDATA: begin
|
||||
// Insert mdata words
|
||||
chdr_pf_tdata = out_mdata_tdata;
|
||||
chdr_pf_tvalid = out_mdata_tvalid;
|
||||
chdr_pf_tlast = 1'b0;
|
||||
out_mdata_tready = chdr_pf_tready;
|
||||
out_mdata_info_tready = 1'b0;
|
||||
out_pyld_tready = 1'b0;
|
||||
out_pkt_info_tready = 1'b0;
|
||||
end
|
||||
ST_PYLD: begin
|
||||
// Insert payload words
|
||||
chdr_pf_tdata = out_pyld_tdata;
|
||||
chdr_pf_tvalid = out_pyld_tvalid;
|
||||
chdr_pf_tlast = out_pyld_tlast;
|
||||
out_mdata_tready = 1'b0;
|
||||
out_mdata_info_tready = 1'b0;
|
||||
out_pyld_tready = chdr_pf_tready;
|
||||
out_pkt_info_tready = 1'b0;
|
||||
end
|
||||
default: begin
|
||||
chdr_pf_tdata = out_pyld_tdata;
|
||||
chdr_pf_tvalid = 1'b0;
|
||||
chdr_pf_tlast = 1'b0;
|
||||
out_mdata_tready = 1'b0;
|
||||
out_mdata_info_tready = 1'b0;
|
||||
out_pyld_tready = 1'b0;
|
||||
out_pkt_info_tready = 1'b0;
|
||||
end
|
||||
endcase
|
||||
end
|
||||
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
// Flushing Logic
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
axis_packet_flush #(
|
||||
.WIDTH (CHDR_W),
|
||||
.FLUSH_PARTIAL_PKTS (0),
|
||||
.TIMEOUT_W (32),
|
||||
.PIPELINE ("IN")
|
||||
) chdr_flusher_i (
|
||||
.clk (axis_chdr_clk),
|
||||
.reset (axis_chdr_rst),
|
||||
.enable (flush_en),
|
||||
.timeout (flush_timeout),
|
||||
.flushing (flush_active),
|
||||
.done (flush_done),
|
||||
.s_axis_tdata (chdr_pf_tdata),
|
||||
.s_axis_tlast (chdr_pf_tlast),
|
||||
.s_axis_tvalid (chdr_pf_tvalid),
|
||||
.s_axis_tready (chdr_pf_tready),
|
||||
.m_axis_tdata (m_axis_chdr_tdata),
|
||||
.m_axis_tlast (m_axis_chdr_tlast),
|
||||
.m_axis_tvalid (m_axis_chdr_tvalid),
|
||||
.m_axis_tready (m_axis_chdr_tready)
|
||||
);
|
||||
|
||||
endmodule
|
||||
@@ -1,538 +0,0 @@
|
||||
//
|
||||
// Copyright 2019 Ettus Research, A National Instruments Company
|
||||
//
|
||||
// SPDX-License-Identifier: LGPL-3.0-or-later
|
||||
//
|
||||
// Module: chdr_to_axis_data_mdata
|
||||
//
|
||||
// Description:
|
||||
//
|
||||
// A deframer module for CHDR data packets. It accepts an input CHDR stream,
|
||||
// and produces two output streams:
|
||||
//
|
||||
// 1) Payload data, which includes the payload of the packet, as well as
|
||||
// timestamp and packet flags presented as sideband information.
|
||||
// 2) Metadata (mdata), which contains only the metadata of the packet.
|
||||
//
|
||||
// This module also performs an optional clock crossing and data width
|
||||
// conversion from CHDR_W to a user requested width for the payload data bus.
|
||||
//
|
||||
// The metadata and data packets are interleaved, i.e., a mdata packet will
|
||||
// arrive before its corresponding data packet. However, if mdata prefetching
|
||||
// is enabled, the mdata for the next packet might arrive before the data for
|
||||
// the current packet has been consumed. In the case of a rate reduction,
|
||||
// this allows the module to sustain a gapless stream of payload items and a
|
||||
// bursty sideband mdata path. If there is no metadata in a packet, then an
|
||||
// empty packet is output on m_axis_mdata_* (i.e., m_axis_mdata_tkeep will be
|
||||
// set to 0).
|
||||
//
|
||||
// Parameters:
|
||||
//
|
||||
// - CHDR_W : Width of the input CHDR bus in bits
|
||||
// - ITEM_W : Width of the output item bus in bits
|
||||
// - NIPC : The number of output items delivered per cycle
|
||||
// - SYNC_CLKS : Are the CHDR and data clocks synchronous to each other?
|
||||
// - MDATA_FIFO_SIZE : FIFO size for the mdata path
|
||||
// - INFO_FIFO_SIZE : FIFO size for the packet info path
|
||||
// - PAYLOAD_FIFO_SIZE : FIFO size for the payload path
|
||||
// - MDATA_PREFETCH_EN : Is mdata prefetching enabled?
|
||||
//
|
||||
// Signals:
|
||||
//
|
||||
// - s_axis_chdr_* : Input CHDR stream (AXI-Stream)
|
||||
// - m_axis_* : Output payload data stream (AXI-Stream)
|
||||
// - m_axis_mdata_* : Output mdata stream (AXI-Stream)
|
||||
// - flush_* : Signals for flush control and status
|
||||
//
|
||||
|
||||
module chdr_to_axis_data_mdata #(
|
||||
parameter CHDR_W = 256,
|
||||
parameter ITEM_W = 32,
|
||||
parameter NIPC = 2,
|
||||
parameter SYNC_CLKS = 0,
|
||||
parameter MDATA_FIFO_SIZE = 1,
|
||||
parameter INFO_FIFO_SIZE = 1,
|
||||
parameter PAYLOAD_FIFO_SIZE = 1,
|
||||
parameter MDATA_PREFETCH_EN = 1
|
||||
)(
|
||||
// Clock, reset and settings
|
||||
input wire axis_chdr_clk,
|
||||
input wire axis_chdr_rst,
|
||||
input wire axis_data_clk,
|
||||
input wire axis_data_rst,
|
||||
// CHDR in (AXI-Stream)
|
||||
input wire [CHDR_W-1:0] s_axis_chdr_tdata,
|
||||
input wire s_axis_chdr_tlast,
|
||||
input wire s_axis_chdr_tvalid,
|
||||
output wire s_axis_chdr_tready,
|
||||
// Payload data stream out (AXI-Stream)
|
||||
output wire [(ITEM_W*NIPC)-1:0] m_axis_tdata,
|
||||
output wire [NIPC-1:0] m_axis_tkeep,
|
||||
output wire m_axis_tlast,
|
||||
output wire m_axis_tvalid,
|
||||
input wire m_axis_tready,
|
||||
// Payload sideband information
|
||||
output wire [63:0] m_axis_ttimestamp,
|
||||
output wire m_axis_thas_time,
|
||||
output wire [15:0] m_axis_tlength,
|
||||
output wire m_axis_teob,
|
||||
output wire m_axis_teov,
|
||||
// Metadata stream out (AXI-Stream)
|
||||
output wire [CHDR_W-1:0] m_axis_mdata_tdata,
|
||||
output wire m_axis_mdata_tlast,
|
||||
output wire m_axis_mdata_tkeep,
|
||||
output wire m_axis_mdata_tvalid,
|
||||
input wire m_axis_mdata_tready,
|
||||
// Flush signals
|
||||
input wire flush_en,
|
||||
input wire [31:0] flush_timeout,
|
||||
output wire flush_active,
|
||||
output wire flush_done
|
||||
);
|
||||
|
||||
// ---------------------------------------------------
|
||||
// RFNoC Includes
|
||||
// ---------------------------------------------------
|
||||
`include "rfnoc_chdr_utils.vh"
|
||||
`include "rfnoc_axis_ctrl_utils.vh"
|
||||
|
||||
// ---------------------------------------------------
|
||||
// Pipeline
|
||||
// ---------------------------------------------------
|
||||
localparam CHDR_KEEP_W = CHDR_W/ITEM_W;
|
||||
|
||||
wire [CHDR_W-1:0] in_chdr_tdata;
|
||||
wire [CHDR_KEEP_W-1:0] in_chdr_tkeep;
|
||||
wire in_chdr_tlast, in_chdr_tvalid;
|
||||
reg in_chdr_tready;
|
||||
|
||||
axi_fifo_flop2 #(.WIDTH(CHDR_W+1)) in_pipe_i (
|
||||
.clk(axis_chdr_clk), .reset(axis_chdr_rst), .clear(1'b0),
|
||||
.i_tdata({s_axis_chdr_tlast, s_axis_chdr_tdata}),
|
||||
.i_tvalid(s_axis_chdr_tvalid), .i_tready(s_axis_chdr_tready),
|
||||
.o_tdata({in_chdr_tlast, in_chdr_tdata}),
|
||||
.o_tvalid(in_chdr_tvalid), .o_tready(in_chdr_tready),
|
||||
.space(), .occupied()
|
||||
);
|
||||
|
||||
chdr_compute_tkeep #(.CHDR_W(CHDR_W), .ITEM_W(ITEM_W)) tkeep_gen_i (
|
||||
.clk(axis_chdr_clk), .rst(axis_chdr_rst),
|
||||
.axis_tdata(in_chdr_tdata), .axis_tlast(in_chdr_tlast),
|
||||
.axis_tvalid(in_chdr_tvalid), .axis_tready(in_chdr_tready),
|
||||
.axis_tkeep(in_chdr_tkeep)
|
||||
);
|
||||
|
||||
// ---------------------------------------------------
|
||||
// Input State Machine
|
||||
// ---------------------------------------------------
|
||||
localparam INFO_W = 64+1+16+1+1; // timestamp, has_time, length, eob, eov
|
||||
|
||||
wire [CHDR_W-1:0] in_pyld_tdata;
|
||||
wire [CHDR_KEEP_W-1:0] in_pyld_tkeep;
|
||||
wire in_pyld_tlast, in_pyld_tvalid, in_pyld_tready;
|
||||
|
||||
reg [INFO_W-1:0] in_info_tdata;
|
||||
reg in_info_tvalid;
|
||||
wire in_info_tready;
|
||||
|
||||
wire [CHDR_W-1:0] in_mdata_tdata;
|
||||
wire in_mdata_tkeep;
|
||||
wire in_mdata_tlast, in_mdata_tvalid, in_mdata_tready;
|
||||
|
||||
|
||||
localparam [2:0] ST_HDR = 3'd0; // Processing the input CHDR header
|
||||
localparam [2:0] ST_TS = 3'd1; // Processing the input CHDR timestamp
|
||||
localparam [2:0] ST_MDATA = 3'd2; // Processing the input CHDR metadata word
|
||||
localparam [2:0] ST_BODY = 3'd3; // Processing the input CHDR payload word
|
||||
localparam [2:0] ST_DROP = 3'd4; // Something went wrong... Dropping packet
|
||||
|
||||
reg [2:0] state = ST_HDR;
|
||||
reg [4:0] mdata_pending = CHDR_NO_MDATA;
|
||||
reg last_mdata_line;
|
||||
|
||||
reg [15:0] chdr_length_reg;
|
||||
reg chdr_eob_reg, chdr_eov_reg;
|
||||
|
||||
// Shortcuts: CHDR header
|
||||
wire [2:0] in_pkt_type = chdr_get_pkt_type(in_chdr_tdata[63:0]);
|
||||
wire [4:0] in_num_mdata = chdr_get_num_mdata(in_chdr_tdata[63:0]);
|
||||
|
||||
always @(posedge axis_chdr_clk) begin
|
||||
if (axis_chdr_rst) begin
|
||||
state <= ST_HDR;
|
||||
end else if (in_chdr_tvalid & in_chdr_tready) begin
|
||||
case (state)
|
||||
|
||||
// ST_HDR: CHDR Header
|
||||
// -------------------
|
||||
ST_HDR: begin
|
||||
// Always cache the number of metadata words
|
||||
mdata_pending <= in_num_mdata;
|
||||
// Figure out the next state
|
||||
if (!in_chdr_tlast) begin
|
||||
if (CHDR_W > 64) begin
|
||||
// When CHDR_W > 64, the timestamp is a part of the header word.
|
||||
// If this is a data packet (with/without a TS), we move on to the metadata/body
|
||||
// state otherwise we drop it. Non-data packets should never reach here.
|
||||
if (in_pkt_type == CHDR_PKT_TYPE_DATA || in_pkt_type == CHDR_PKT_TYPE_DATA_TS) begin
|
||||
if (in_num_mdata != CHDR_NO_MDATA) begin
|
||||
state <= ST_MDATA;
|
||||
end else begin
|
||||
state <= ST_BODY;
|
||||
end
|
||||
end else begin
|
||||
state <= ST_DROP;
|
||||
end
|
||||
end else begin
|
||||
// When CHDR_W == 64, the timestamp comes after the header. Check if this is a data
|
||||
// packet with a TS to figure out the next state. If no TS, then check for metadata
|
||||
// to move to the next state. Drop any non-data packets.
|
||||
chdr_length_reg <= chdr_calc_payload_length(CHDR_W, in_chdr_tdata);
|
||||
chdr_eob_reg <= chdr_get_eob(in_chdr_tdata);
|
||||
chdr_eov_reg <= chdr_get_eov(in_chdr_tdata);
|
||||
if (in_pkt_type == CHDR_PKT_TYPE_DATA_TS) begin
|
||||
state <= ST_TS;
|
||||
end else if (in_pkt_type == CHDR_PKT_TYPE_DATA) begin
|
||||
if (in_num_mdata != CHDR_NO_MDATA) begin
|
||||
state <= ST_MDATA;
|
||||
end else begin
|
||||
state <= ST_BODY;
|
||||
end
|
||||
end else begin
|
||||
state <= ST_DROP;
|
||||
end
|
||||
end
|
||||
end else begin // Premature termination
|
||||
// Packets must have at least one payload line
|
||||
state <= ST_HDR;
|
||||
end
|
||||
end
|
||||
|
||||
// ST_TS: Timestamp (CHDR_W == 64 only)
|
||||
// ------------------------------------
|
||||
ST_TS: begin
|
||||
if (!in_chdr_tlast) begin
|
||||
if (mdata_pending != CHDR_NO_MDATA) begin
|
||||
state <= ST_MDATA;
|
||||
end else begin
|
||||
state <= ST_BODY;
|
||||
end
|
||||
end else begin // Premature termination
|
||||
// Packets must have at least one payload line
|
||||
state <= ST_HDR;
|
||||
end
|
||||
end
|
||||
|
||||
// ST_MDATA: Metadata word
|
||||
// -----------------------
|
||||
ST_MDATA: begin
|
||||
if (!in_chdr_tlast) begin
|
||||
// Count down metadata and stop at 1
|
||||
if (mdata_pending == 5'd1) begin
|
||||
state <= ST_BODY;
|
||||
end else begin
|
||||
mdata_pending <= mdata_pending - 5'd1;
|
||||
end
|
||||
end else begin // Premature termination
|
||||
// Packets must have at least one payload line
|
||||
state <= ST_HDR;
|
||||
end
|
||||
end
|
||||
|
||||
// ST_BODY: Payload word
|
||||
// ---------------------
|
||||
ST_BODY: begin
|
||||
if (in_chdr_tlast) begin
|
||||
state <= ST_HDR;
|
||||
end
|
||||
end
|
||||
|
||||
// ST_DROP: Drop current packet
|
||||
// ----------------------------
|
||||
ST_DROP: begin
|
||||
if (in_chdr_tlast) begin
|
||||
state <= ST_HDR;
|
||||
end
|
||||
end
|
||||
|
||||
default: begin
|
||||
// We should never get here
|
||||
state <= ST_HDR;
|
||||
end
|
||||
endcase
|
||||
end
|
||||
end
|
||||
|
||||
// CHDR data goes to the payload stream only in the BODY state.
|
||||
// Packets are expected to have at least one payload word so the
|
||||
// CHDR tlast can be used as the payload tlast
|
||||
assign in_pyld_tdata = in_chdr_tdata;
|
||||
assign in_pyld_tkeep = in_chdr_tkeep;
|
||||
assign in_pyld_tlast = in_chdr_tlast;
|
||||
assign in_pyld_tvalid = in_chdr_tvalid && (state == ST_BODY);
|
||||
|
||||
// Only metadata goes into the mdata FIFO. However, if there is no metadata,
|
||||
// then we want an empty packet to go into the mdata FIFO. We check the
|
||||
// packet type because non-data packets will be discarded.
|
||||
assign in_mdata_tdata = in_chdr_tdata;
|
||||
assign in_mdata_tlast = in_chdr_tlast || last_mdata_line;
|
||||
assign in_mdata_tkeep = (state == ST_MDATA);
|
||||
assign in_mdata_tvalid = in_chdr_tvalid && (
|
||||
(state == ST_MDATA) ||
|
||||
(state == ST_HDR && in_num_mdata == CHDR_NO_MDATA &&
|
||||
(in_pkt_type == CHDR_PKT_TYPE_DATA || in_pkt_type == CHDR_PKT_TYPE_DATA_TS)));
|
||||
|
||||
always @(*) begin
|
||||
// Packet timestamp and flags go into the info FIFO, but only if it's a
|
||||
// data packet since non-data packets will be discarded.
|
||||
if (CHDR_W > 64) begin
|
||||
// When CHDR_W > 64, all info will be in the first word of the CHDR packet
|
||||
in_info_tdata = { in_chdr_tdata[127:64],
|
||||
chdr_get_has_time(in_chdr_tdata),
|
||||
chdr_calc_payload_length(CHDR_W, in_chdr_tdata),
|
||||
chdr_get_eob(in_chdr_tdata),
|
||||
chdr_get_eov(in_chdr_tdata) };
|
||||
in_info_tvalid = in_chdr_tvalid && (state == ST_HDR &&
|
||||
(in_pkt_type == CHDR_PKT_TYPE_DATA || in_pkt_type == CHDR_PKT_TYPE_DATA_TS));
|
||||
end else begin
|
||||
// When CHDR_W == 64, the flags will be in the first word of the packet,
|
||||
// but the timestamp will be in the second word, if there is a timestamp.
|
||||
if (state == ST_HDR && in_pkt_type == CHDR_PKT_TYPE_DATA) begin
|
||||
// No timestamp in this case
|
||||
in_info_tdata = { in_chdr_tdata[63:0], 1'b0,
|
||||
chdr_calc_payload_length(CHDR_W, in_chdr_tdata),
|
||||
chdr_get_eob(in_chdr_tdata), chdr_get_eov(in_chdr_tdata) };
|
||||
in_info_tvalid = in_chdr_tvalid;
|
||||
end else begin
|
||||
// Assuming timestamp is present, so use flags from previous clock cycle
|
||||
in_info_tdata = { in_chdr_tdata[63:0], 1'b1, chdr_length_reg,
|
||||
chdr_eob_reg, chdr_eov_reg };
|
||||
in_info_tvalid = in_chdr_tvalid && (state == ST_TS);
|
||||
end
|
||||
end
|
||||
|
||||
case (state)
|
||||
ST_HDR: begin
|
||||
in_chdr_tready = in_info_tready && in_mdata_tready;
|
||||
last_mdata_line = (in_num_mdata == CHDR_NO_MDATA);
|
||||
end
|
||||
ST_TS: begin
|
||||
in_chdr_tready = in_info_tready && in_mdata_tready;
|
||||
last_mdata_line = 1'b0;
|
||||
end
|
||||
ST_MDATA: begin
|
||||
in_chdr_tready = in_mdata_tready;
|
||||
last_mdata_line = (mdata_pending == 5'd1);
|
||||
end
|
||||
ST_BODY: begin
|
||||
in_chdr_tready = in_pyld_tready;
|
||||
last_mdata_line = 1'b0;
|
||||
end
|
||||
ST_DROP: begin
|
||||
in_chdr_tready = 1'b1;
|
||||
last_mdata_line = 1'b0;
|
||||
end
|
||||
default: begin
|
||||
in_chdr_tready = 1'b0;
|
||||
last_mdata_line = 1'b0;
|
||||
end
|
||||
endcase
|
||||
end
|
||||
|
||||
// ---------------------------------------------------
|
||||
// Payload and mdata FIFOs
|
||||
// ---------------------------------------------------
|
||||
wire [CHDR_W-1:0] out_pyld_tdata;
|
||||
wire [CHDR_KEEP_W-1:0] out_pyld_tkeep;
|
||||
wire out_pyld_tlast, out_pyld_tvalid, out_pyld_tready;
|
||||
|
||||
wire tmp_mdata_tvalid, tmp_mdata_tready;
|
||||
wire tmp_info_tready;
|
||||
|
||||
wire [(ITEM_W*NIPC)-1:0] flush_pyld_tdata;
|
||||
wire [NIPC-1:0] flush_pyld_tkeep;
|
||||
wire flush_pyld_tlast, flush_pyld_tvalid, flush_pyld_tready;
|
||||
wire [INFO_W-1:0] flush_info_tdata;
|
||||
wire [CHDR_W-1:0] flush_mdata_tdata;
|
||||
wire flush_mdata_tkeep;
|
||||
wire flush_mdata_tlast, flush_mdata_tvalid, flush_mdata_tready;
|
||||
|
||||
generate if (SYNC_CLKS) begin : gen_sync_fifo
|
||||
axi_fifo #(.WIDTH(CHDR_W+2), .SIZE(MDATA_FIFO_SIZE)) mdata_fifo_i (
|
||||
.clk(axis_data_clk), .reset(axis_data_rst), .clear(1'b0),
|
||||
.i_tdata({in_mdata_tkeep, in_mdata_tlast, in_mdata_tdata}),
|
||||
.i_tvalid(in_mdata_tvalid), .i_tready(in_mdata_tready),
|
||||
.o_tdata({flush_mdata_tkeep, flush_mdata_tlast, flush_mdata_tdata}),
|
||||
.o_tvalid(tmp_mdata_tvalid), .o_tready(tmp_mdata_tready),
|
||||
.space(), .occupied()
|
||||
);
|
||||
axi_fifo #(.WIDTH(INFO_W), .SIZE(INFO_FIFO_SIZE)) info_fifo_i (
|
||||
.clk(axis_data_clk), .reset(axis_data_rst), .clear(1'b0),
|
||||
.i_tdata(in_info_tdata),
|
||||
.i_tvalid(in_info_tvalid), .i_tready(in_info_tready),
|
||||
.o_tdata(flush_info_tdata),
|
||||
.o_tvalid(), .o_tready(tmp_info_tready),
|
||||
.space(), .occupied()
|
||||
);
|
||||
axi_fifo #(.WIDTH(CHDR_W+CHDR_KEEP_W+1), .SIZE(PAYLOAD_FIFO_SIZE)) pyld_fifo_i (
|
||||
.clk(axis_data_clk), .reset(axis_data_rst), .clear(1'b0),
|
||||
.i_tdata({in_pyld_tlast, in_pyld_tkeep, in_pyld_tdata}),
|
||||
.i_tvalid(in_pyld_tvalid), .i_tready(in_pyld_tready),
|
||||
.o_tdata({out_pyld_tlast, out_pyld_tkeep, out_pyld_tdata}),
|
||||
.o_tvalid(out_pyld_tvalid), .o_tready(out_pyld_tready),
|
||||
.space(), .occupied()
|
||||
);
|
||||
end else begin : gen_async_fifo
|
||||
axi_fifo_2clk #(.WIDTH(CHDR_W+2), .SIZE(MDATA_FIFO_SIZE)) mdata_fifo_i (
|
||||
.reset(axis_chdr_rst),
|
||||
.i_aclk(axis_chdr_clk),
|
||||
.i_tdata({in_mdata_tkeep, in_mdata_tlast, in_mdata_tdata}),
|
||||
.i_tvalid(in_mdata_tvalid), .i_tready(in_mdata_tready),
|
||||
.o_aclk(axis_data_clk),
|
||||
.o_tdata({flush_mdata_tkeep, flush_mdata_tlast, flush_mdata_tdata}),
|
||||
.o_tvalid(tmp_mdata_tvalid), .o_tready(tmp_mdata_tready)
|
||||
);
|
||||
axi_fifo_2clk #(.WIDTH(INFO_W), .SIZE(INFO_FIFO_SIZE)) info_fifo_i (
|
||||
.reset(axis_chdr_rst),
|
||||
.i_aclk(axis_chdr_clk),
|
||||
.i_tdata(in_info_tdata),
|
||||
.i_tvalid(in_info_tvalid), .i_tready(in_info_tready),
|
||||
.o_aclk(axis_data_clk),
|
||||
.o_tdata(flush_info_tdata),
|
||||
.o_tvalid(), .o_tready(tmp_info_tready)
|
||||
);
|
||||
axi_fifo_2clk #(.WIDTH(CHDR_W+CHDR_KEEP_W+1), .SIZE(PAYLOAD_FIFO_SIZE)) pyld_fifo_i (
|
||||
.reset(axis_chdr_rst),
|
||||
.i_aclk(axis_chdr_clk),
|
||||
.i_tdata({in_pyld_tlast, in_pyld_tkeep, in_pyld_tdata}),
|
||||
.i_tvalid(in_pyld_tvalid), .i_tready(in_pyld_tready),
|
||||
.o_aclk(axis_data_clk),
|
||||
.o_tdata({out_pyld_tlast, out_pyld_tkeep, out_pyld_tdata}),
|
||||
.o_tvalid(out_pyld_tvalid), .o_tready(out_pyld_tready)
|
||||
);
|
||||
end endgenerate
|
||||
|
||||
// ---------------------------------------------------
|
||||
// Data Width Converter: CHDR_W => ITEM_W*NIPC
|
||||
// ---------------------------------------------------
|
||||
wire tmp_pyld_tvalid, tmp_pyld_tready;
|
||||
|
||||
generate
|
||||
if (CHDR_W != ITEM_W*NIPC) begin : gen_axis_width_conv
|
||||
axis_width_conv #(
|
||||
.WORD_W(ITEM_W), .IN_WORDS(CHDR_W/ITEM_W), .OUT_WORDS(NIPC),
|
||||
.SYNC_CLKS(1), .PIPELINE("NONE")
|
||||
) payload_width_conv_i (
|
||||
.s_axis_aclk(axis_data_clk), .s_axis_rst(axis_data_rst),
|
||||
.s_axis_tdata(out_pyld_tdata), .s_axis_tkeep(out_pyld_tkeep),
|
||||
.s_axis_tlast(out_pyld_tlast), .s_axis_tvalid(out_pyld_tvalid),
|
||||
.s_axis_tready(out_pyld_tready),
|
||||
.m_axis_aclk(axis_data_clk), .m_axis_rst(axis_data_rst),
|
||||
.m_axis_tdata(flush_pyld_tdata), .m_axis_tkeep(flush_pyld_tkeep),
|
||||
.m_axis_tlast(flush_pyld_tlast), .m_axis_tvalid(tmp_pyld_tvalid),
|
||||
.m_axis_tready(tmp_pyld_tready)
|
||||
);
|
||||
end else begin : no_gen_axis_width_conv
|
||||
assign flush_pyld_tdata = out_pyld_tdata;
|
||||
assign flush_pyld_tkeep = out_pyld_tkeep;
|
||||
assign flush_pyld_tlast = out_pyld_tlast;
|
||||
assign tmp_pyld_tvalid = out_pyld_tvalid;
|
||||
assign out_pyld_tready = tmp_pyld_tready;
|
||||
end
|
||||
endgenerate
|
||||
|
||||
|
||||
// ---------------------------------------------------
|
||||
// Output State Machine
|
||||
// ---------------------------------------------------
|
||||
reg [2:0] mdata_pkt_cnt = 3'd0, pyld_pkt_cnt = 3'd0;
|
||||
|
||||
// A payload packet can pass only if it is preceded by a mdata packet
|
||||
wire pass_pyld = ((mdata_pkt_cnt - pyld_pkt_cnt) > 3'd0);
|
||||
// A mdata packet has to be blocked if its corresponding payload packet hasn't passed except
|
||||
// when prefetching is enabled. In that case one additional mdata packet is allowed to pass
|
||||
wire pass_mdata = ((mdata_pkt_cnt - pyld_pkt_cnt) < (MDATA_PREFETCH_EN == 1 ? 3'd2 : 3'd1));
|
||||
|
||||
always @(posedge axis_data_clk) begin
|
||||
if (axis_data_rst) begin
|
||||
mdata_pkt_cnt <= 3'd0;
|
||||
pyld_pkt_cnt <= 3'd0;
|
||||
end else begin
|
||||
if (flush_mdata_tvalid && flush_mdata_tready && flush_mdata_tlast)
|
||||
mdata_pkt_cnt <= mdata_pkt_cnt + 3'd1;
|
||||
if (flush_pyld_tvalid && flush_pyld_tready && flush_pyld_tlast)
|
||||
pyld_pkt_cnt <= pyld_pkt_cnt + 3'd1;
|
||||
end
|
||||
end
|
||||
|
||||
assign flush_pyld_tvalid = tmp_pyld_tvalid && pass_pyld;
|
||||
assign tmp_pyld_tready = flush_pyld_tready && pass_pyld;
|
||||
|
||||
// Only read the info FIFO once per packet
|
||||
assign tmp_info_tready = tmp_pyld_tready && flush_pyld_tlast && tmp_pyld_tvalid;
|
||||
|
||||
assign flush_mdata_tvalid = tmp_mdata_tvalid && pass_mdata;
|
||||
assign tmp_mdata_tready = flush_mdata_tready && pass_mdata;
|
||||
|
||||
// ---------------------------------------------------
|
||||
// Flushing Logic
|
||||
// ---------------------------------------------------
|
||||
wire [31:0] flush_timeout_dclk;
|
||||
wire flush_en_dclk;
|
||||
wire flush_active_pyld_cclk, flush_active_mdata_cclk;
|
||||
wire flush_done_pyld_cclk, flush_done_mdata_cclk;
|
||||
wire flush_active_pyld, flush_active_mdata;
|
||||
wire flush_done_pyld, flush_done_mdata;
|
||||
|
||||
synchronizer #(.WIDTH(4), .INITIAL_VAL(4'd0)) flush_2clk_rb_i (
|
||||
.clk(axis_chdr_clk), .rst(1'b0),
|
||||
.in({flush_active_pyld, flush_done_pyld,
|
||||
flush_active_mdata, flush_done_mdata}),
|
||||
.out({flush_active_pyld_cclk, flush_done_pyld_cclk,
|
||||
flush_active_mdata_cclk, flush_done_mdata_cclk})
|
||||
);
|
||||
assign flush_active = flush_active_pyld_cclk | flush_active_mdata_cclk;
|
||||
assign flush_done = flush_done_pyld_cclk & flush_done_mdata_cclk;
|
||||
|
||||
axi_fifo_2clk #(.WIDTH(33), .SIZE(1)) flush_2clk_ctrl_i (
|
||||
.reset(axis_chdr_rst),
|
||||
.i_aclk(axis_chdr_clk),
|
||||
.i_tdata({flush_en, flush_timeout}), .i_tvalid(1'b1), .i_tready(),
|
||||
.o_aclk(axis_data_clk),
|
||||
.o_tdata({flush_en_dclk, flush_timeout_dclk}), .o_tvalid(), .o_tready(1'b1)
|
||||
);
|
||||
|
||||
axis_packet_flush #(
|
||||
.WIDTH(INFO_W+(ITEM_W+1)*NIPC), .FLUSH_PARTIAL_PKTS(0), .TIMEOUT_W(32), .PIPELINE("OUT")
|
||||
) pyld_flusher_i (
|
||||
.clk(axis_data_clk), .reset(axis_data_rst),
|
||||
.enable(flush_en_dclk), .timeout(flush_timeout_dclk),
|
||||
.flushing(flush_active_pyld), .done(flush_done_pyld),
|
||||
.s_axis_tdata({flush_info_tdata, flush_pyld_tkeep, flush_pyld_tdata}),
|
||||
.s_axis_tlast(flush_pyld_tlast),
|
||||
.s_axis_tvalid(flush_pyld_tvalid),
|
||||
.s_axis_tready(flush_pyld_tready),
|
||||
.m_axis_tdata({m_axis_ttimestamp, m_axis_thas_time, m_axis_tlength,
|
||||
m_axis_teob, m_axis_teov, m_axis_tkeep, m_axis_tdata}),
|
||||
.m_axis_tlast(m_axis_tlast),
|
||||
.m_axis_tvalid(m_axis_tvalid),
|
||||
.m_axis_tready(m_axis_tready)
|
||||
);
|
||||
|
||||
axis_packet_flush #(
|
||||
.WIDTH(CHDR_W+1), .FLUSH_PARTIAL_PKTS(0), .TIMEOUT_W(32), .PIPELINE("OUT")
|
||||
) mdata_flusher_i (
|
||||
.clk(axis_data_clk), .reset(axis_data_rst),
|
||||
.enable(flush_en_dclk), .timeout(flush_timeout_dclk),
|
||||
.flushing(flush_active_mdata), .done(flush_done_mdata),
|
||||
.s_axis_tdata({flush_mdata_tkeep, flush_mdata_tdata}),
|
||||
.s_axis_tlast(flush_mdata_tlast),
|
||||
.s_axis_tvalid(flush_mdata_tvalid),
|
||||
.s_axis_tready(flush_mdata_tready),
|
||||
.m_axis_tdata({m_axis_mdata_tkeep, m_axis_mdata_tdata}),
|
||||
.m_axis_tlast(m_axis_mdata_tlast),
|
||||
.m_axis_tvalid(m_axis_mdata_tvalid),
|
||||
.m_axis_tready(m_axis_mdata_tready)
|
||||
);
|
||||
|
||||
endmodule
|
||||
@@ -1,70 +0,0 @@
|
||||
//
|
||||
// Copyright 2014 Ettus Research LLC
|
||||
// Copyright 2018 Ettus Research, a National Instruments Company
|
||||
//
|
||||
// SPDX-License-Identifier: LGPL-3.0-or-later
|
||||
//
|
||||
// Not necessarily that useful in general, but a good test block
|
||||
|
||||
module packet_resizer
|
||||
#(parameter SR_PKT_SIZE=1)
|
||||
(input clk, input reset,
|
||||
input [15:0] next_dst_sid,
|
||||
input set_stb, input [7:0] set_addr, input [31:0] set_data,
|
||||
input [31:0] i_tdata, input [127:0] i_tuser, input i_tlast, input i_tvalid, output i_tready,
|
||||
output [31:0] o_tdata, output [127:0] o_tuser, output o_tlast, output o_tvalid, input o_tready);
|
||||
|
||||
wire [15:0] pkt_size;
|
||||
reg [15:0] count;
|
||||
reg first_packet_in_burst = 1'b1;
|
||||
|
||||
setting_reg #(.my_addr(SR_PKT_SIZE), .width(16)) reg_pkt_size
|
||||
(.clk(clk), .rst(reset), .strobe(set_stb), .addr(set_addr), .in(set_data),
|
||||
.out(pkt_size));
|
||||
|
||||
// Parse i_tuser
|
||||
wire [1:0] TYPE_in = i_tuser[127:126];
|
||||
wire TSI_in = i_tuser[125];
|
||||
wire EOB_in = i_tuser[124];
|
||||
wire [11:0] SEQ_in = i_tuser[123:112];
|
||||
wire [15:0] LEN_in = i_tuser[111:96];
|
||||
wire [15:0] SRC_in = i_tuser[95:80];
|
||||
wire [15:0] DST_in = i_tuser[79:64];
|
||||
wire [63:0] TIME_in = i_tuser[63:0];
|
||||
|
||||
// Generate o_tuser
|
||||
wire [1:0] TYPE_out = TYPE_in;
|
||||
wire TSI_out = TSI_in & first_packet_in_burst;
|
||||
wire EOB_out = EOB_in & i_tlast;
|
||||
wire [11:0] SEQ_out = SEQ_in; // Doesn't actually matter, it gets overwritten by chdr_framer
|
||||
wire [15:0] LEN_out = LEN_in; // Only the bottom 2 bits actually matter, rest gets overwritten
|
||||
wire [15:0] SRC_out = DST_in;
|
||||
wire [15:0] DST_out = next_dst_sid;
|
||||
wire [63:0] TIME_out = TIME_in;
|
||||
|
||||
// Pass nearly everything through unchanged
|
||||
assign o_tdata = i_tdata;
|
||||
assign o_tlast = (count == pkt_size) | EOB_out;
|
||||
assign o_tuser = { TYPE_out, TSI_out, EOB_out, SEQ_out, LEN_out, SRC_out, DST_out, TIME_out };
|
||||
|
||||
assign o_tvalid = i_tvalid;
|
||||
assign i_tready = o_tready;
|
||||
|
||||
always @(posedge clk)
|
||||
if(reset)
|
||||
count <= 16'd4;
|
||||
else
|
||||
if(o_tvalid & o_tready)
|
||||
if(o_tlast)
|
||||
count <= 16'd4;
|
||||
else
|
||||
count <= count + 16'd4;
|
||||
|
||||
always @(posedge clk)
|
||||
if(reset)
|
||||
first_packet_in_burst <= 1'b1;
|
||||
else
|
||||
if(o_tvalid & o_tready & o_tlast)
|
||||
first_packet_in_burst <= EOB_out;
|
||||
|
||||
endmodule // packet_resizer
|
||||
@@ -1,144 +0,0 @@
|
||||
//
|
||||
// Copyright 2012-2013 Ettus Research LLC
|
||||
// Copyright 2018 Ettus Research, a National Instruments Company
|
||||
//
|
||||
// SPDX-License-Identifier: LGPL-3.0-or-later
|
||||
//
|
||||
|
||||
|
||||
module axi_wrapper_tb();
|
||||
|
||||
xlnx_glbl glbl (.GSR(),.GTS());
|
||||
|
||||
localparam STR_SINK_FIFOSIZE = 9;
|
||||
|
||||
reg clk, reset;
|
||||
always
|
||||
#100 clk = ~clk;
|
||||
|
||||
initial clk = 0;
|
||||
initial reset = 1;
|
||||
initial #1000 reset = 0;
|
||||
|
||||
initial $dumpfile("axi_wrapper_tb.vcd");
|
||||
initial $dumpvars(0,axi_wrapper_tb);
|
||||
|
||||
initial #1000000 $finish;
|
||||
|
||||
wire [31:0] set_data;
|
||||
wire [7:0] set_addr;
|
||||
wire set_stb;
|
||||
|
||||
wire [63:0] noci_tdata[PORTS-1:0];
|
||||
wire noci_tlast[PORTS-1:0];
|
||||
wire noci_tvalid[PORTS-1:0];
|
||||
wire noci_tready[PORTS-1:0];
|
||||
|
||||
wire [63:0] noco_tdata[PORTS-1:0];
|
||||
wire noco_tlast[PORTS-1:0];
|
||||
wire noco_tvalid[PORTS-1:0];
|
||||
wire noco_tready[PORTS-1:0];
|
||||
|
||||
reg [63:0] src_tdata;
|
||||
reg src_tlast, src_tvalid;
|
||||
wire src_tready;
|
||||
|
||||
localparam PORTS = 4;
|
||||
|
||||
wire [63:0] s1o_tdata, s1i_tdata;
|
||||
wire s1o_tlast, s1i_tlast, s1o_tvalid, s1i_tvalid, s1o_tready, s1i_tready;
|
||||
|
||||
wire [31:0] pre_tdata, post_tdata;
|
||||
wire pre_tlast, post_tlast, pre_tvalid, post_tvalid, pre_tready, post_tready;
|
||||
wire [127:0] pre_tuser, post_tuser;
|
||||
|
||||
axi_wrapper #(.BASE(8), .NUM_AXI_CONFIG_BUS(1), .CONFIG_BUS_FIFO_DEPTH(5), .SIMPLE_MODE(1)) axi_wrapper_ce1
|
||||
(.clk(clk), .reset(reset),
|
||||
.set_stb(set_stb), .set_addr(set_addr), .set_data(set_data),
|
||||
.i_tdata(src_tdata), .i_tlast(src_tlast), .i_tvalid(src_tvalid), .i_tready(src_tready),
|
||||
.o_tdata(s1i_tdata), .o_tlast(s1i_tlast), .o_tvalid(s1i_tvalid), .o_tready(s1i_tready),
|
||||
.m_axis_data_tdata(pre_tdata),
|
||||
.m_axis_data_tuser(pre_tuser),
|
||||
.m_axis_data_tlast(pre_tlast),
|
||||
.m_axis_data_tvalid(pre_tvalid),
|
||||
.m_axis_data_tready(pre_tready),
|
||||
.s_axis_data_tdata(post_tdata),
|
||||
.s_axis_data_tuser(post_tuser),
|
||||
.s_axis_data_tlast(post_tlast),
|
||||
.s_axis_data_tvalid(post_tvalid),
|
||||
.s_axis_data_tready(post_tready)
|
||||
);
|
||||
|
||||
axi_fifo #(.WIDTH(33)) afifo
|
||||
(.clk(clk), .reset(reset), .clear(1'b0),
|
||||
.i_tdata({pre_tlast,pre_tdata}), .i_tvalid(pre_tvalid), .i_tready(pre_tready),
|
||||
.o_tdata({post_tlast,post_tdata}), .o_tvalid(post_tvalid), .o_tready(post_tready));
|
||||
|
||||
assign s1i_tready = 1'b1;
|
||||
|
||||
|
||||
task SendPacket;
|
||||
input [3:0] flags;
|
||||
input [11:0] seqnum;
|
||||
input [15:0] len;
|
||||
input [31:0] sid;
|
||||
input [63:0] data;
|
||||
|
||||
begin
|
||||
@(posedge clk);
|
||||
src_tdata <= { flags, seqnum, len+16'd8 + (flags[1] ? 16'd8 : 16'd0), sid };
|
||||
src_tlast <= 0;
|
||||
src_tvalid <= 1;
|
||||
@(posedge clk);
|
||||
while(~src_tready)
|
||||
@(posedge clk);
|
||||
|
||||
// send time if flags request it
|
||||
if(flags[1])
|
||||
begin
|
||||
src_tdata <= 64'h0123_4567_89ab_cdef;
|
||||
src_tlast <= 0;
|
||||
src_tvalid <= 1;
|
||||
@(posedge clk);
|
||||
while(~src_tready)
|
||||
@(posedge clk);
|
||||
end
|
||||
|
||||
src_tdata <= data;
|
||||
repeat(len[15:3] + (len[2]|len[1]|len[0])- 1 )
|
||||
begin
|
||||
@(posedge clk);
|
||||
while(~src_tready)
|
||||
@(posedge clk);
|
||||
src_tdata <= src_tdata + 64'd1;
|
||||
end
|
||||
src_tlast <= 1;
|
||||
@(posedge clk);
|
||||
while(~src_tready)
|
||||
@(posedge clk);
|
||||
src_tvalid <= 0;
|
||||
@(posedge clk);
|
||||
end
|
||||
endtask // SendPacket
|
||||
|
||||
initial
|
||||
begin
|
||||
src_tdata <= 64'd0;
|
||||
src_tlast <= 1'b0;
|
||||
src_tvalid <= 1'b0;
|
||||
@(negedge reset);
|
||||
@(posedge clk);
|
||||
|
||||
@(posedge clk);
|
||||
|
||||
#10000;
|
||||
SendPacket(4'h0, 12'd7, 16'd64, 32'h0002_0003, 64'hAAAA_AAAA_0000_0000); // data packet
|
||||
SendPacket(4'h0, 12'd8, 16'd68, 32'h0004_0005, 64'hBBBB_BBBB_0000_0000); // data packet
|
||||
//SendPacket(4'h0, 12'd2, 16'd8, 32'h0000_0001, 64'hCCCC_CCCC_0000_0000); // data packet
|
||||
//SendPacket(4'h0, 12'd3, 16'd8, 32'h0000_0001, 64'hDDDD_DDDD_0000_0000); // data packet
|
||||
//SendPacket(4'h0, 12'd4, 16'd8, 32'h0000_0001, 64'hEEEE_EEEE_0000_0000); // data packet
|
||||
//SendPacket(4'h0, 12'd5, 16'd8, 32'h0000_0001, 64'hFFFF_FFFF_0000_0000); // data packet
|
||||
//SendPacket(4'h0, 12'd6, 16'd8, 32'h0000_0001, 64'h2222_2222_0000_0000); // data packet
|
||||
end
|
||||
|
||||
endmodule // axi_wrapper_tb
|
||||
@@ -1 +0,0 @@
|
||||
iverilog -o axi_wrapper_tb axi_wrapper_tb.v -y . -y ../control/ -y ../fifo/ -y /opt/Xilinx/14.6/ISE_DS/ISE/verilog/src/unisims/ -y ../packet_proc/ -y ../timing/ -y ../vita/ -y ../../top/x300/coregen -y /opt/Xilinx/14.4/ISE_DS/ISE/verilog/src/XilinxCoreLib -y ../coregen/ -y ../ -y ../../../usrp2/models/ -Wall
|
||||
@@ -1,87 +0,0 @@
|
||||
//
|
||||
// Copyright 2012-2013 Ettus Research LLC
|
||||
// Copyright 2018 Ettus Research, a National Instruments Company
|
||||
//
|
||||
// SPDX-License-Identifier: LGPL-3.0-or-later
|
||||
//
|
||||
|
||||
//`timescale 1ns
|
||||
module chdr_deframer_tb();
|
||||
|
||||
reg clk, reset;
|
||||
always
|
||||
#100 clk = ~clk;
|
||||
|
||||
initial $dumpfile("chdr_deframer_tb.vcd");
|
||||
initial $dumpvars(0,chdr_deframer_tb);
|
||||
|
||||
reg [63:0] i_tdata;
|
||||
reg i_tlast, i_tvalid;
|
||||
wire i_tready;
|
||||
|
||||
wire [31:0] o_tdata;
|
||||
wire [127:0] o_tuser;
|
||||
wire o_tlast, o_tvalid;
|
||||
|
||||
reg o_tready = 1;
|
||||
|
||||
wire [63:0] int_tdata;
|
||||
wire int_tlast, int_tvalid, int_tready;
|
||||
|
||||
axi_fifo #(.SIZE(10), .WIDTH(65)) fifo
|
||||
(.clk(clk), .reset(reset), .clear(0),
|
||||
.i_tdata({i_tlast, i_tdata}), .i_tvalid(i_tvalid), .i_tready(i_tready),
|
||||
.o_tdata({int_tlast, int_tdata}), .o_tvalid(int_tvalid), .o_tready(int_tready));
|
||||
|
||||
chdr_deframer chdr_deframer
|
||||
(.clk(clk), .reset(reset), .clear(0),
|
||||
.i_tdata(int_tdata), .i_tlast(int_tlast), .i_tvalid(int_tvalid), .i_tready(int_tready),
|
||||
.o_tdata(o_tdata), .o_tuser(o_tuser), .o_tlast(o_tlast), .o_tvalid(o_tvalid), .o_tready(o_tready));
|
||||
|
||||
reg [63:0] hdr, vtime, data;
|
||||
|
||||
initial
|
||||
begin
|
||||
clk = 0;
|
||||
reset = 1;
|
||||
i_tlast = 0;
|
||||
i_tvalid = 0;
|
||||
hdr = 64'hFF00_AAB9_BEEF_0000;
|
||||
vtime = 64'h8888_7777_6666_0000;
|
||||
data = 64'hEEEE_0000_FFFF_0001;
|
||||
#1000 reset = 0;
|
||||
repeat (10)
|
||||
@(posedge clk);
|
||||
repeat (6)
|
||||
begin
|
||||
#1 i_tdata = hdr;
|
||||
#1 i_tlast = 0;
|
||||
#1 i_tvalid = 1;
|
||||
@(posedge clk);
|
||||
#1 i_tdata = vtime;
|
||||
@(posedge clk);
|
||||
#1 hdr = hdr + 1;
|
||||
#1 vtime = vtime + 1;
|
||||
repeat (10)
|
||||
begin
|
||||
#1 i_tdata = data;
|
||||
#1 data = data + 64'h0000_0002_0000_0002;
|
||||
@(posedge clk);
|
||||
end
|
||||
#1 i_tdata = data;
|
||||
#1 data = data + 64'h0000_0002_0000_0002;
|
||||
#1 i_tlast <= 1;
|
||||
@(posedge clk);
|
||||
end // repeat (20)
|
||||
#1 i_tvalid <= 0;
|
||||
#200000 $finish;
|
||||
end
|
||||
|
||||
always @(posedge clk)
|
||||
if(o_tvalid & o_tready)
|
||||
if(o_tlast)
|
||||
$display("%x LAST",o_tdata);
|
||||
else
|
||||
$display("%x",o_tdata);
|
||||
|
||||
endmodule // chdr_deframer_tb
|
||||
@@ -1,80 +0,0 @@
|
||||
//
|
||||
// Copyright 2012-2013 Ettus Research LLC
|
||||
// Copyright 2018 Ettus Research, a National Instruments Company
|
||||
//
|
||||
// SPDX-License-Identifier: LGPL-3.0-or-later
|
||||
//
|
||||
|
||||
//`timescale 1ns
|
||||
module chdr_framer_tb();
|
||||
|
||||
reg clk, reset;
|
||||
always
|
||||
#100 clk = ~clk;
|
||||
|
||||
initial $dumpfile("chdr_framer_tb.vcd");
|
||||
initial $dumpvars(0,chdr_framer_tb);
|
||||
|
||||
reg [31:0] i_tdata;
|
||||
reg [127:0] i_tuser;
|
||||
reg i_tlast, i_tvalid;
|
||||
wire i_tready;
|
||||
|
||||
wire [63:0] o_tdata;
|
||||
wire o_tlast, o_tvalid;
|
||||
|
||||
reg o_tready = 0;
|
||||
|
||||
chdr_framer #(.SIZE(10)) chdr_framer
|
||||
(.clk(clk), .reset(reset), .clear(0),
|
||||
.i_tdata(i_tdata), .i_tuser(i_tuser), .i_tlast(i_tlast), .i_tvalid(i_tvalid), .i_tready(i_tready),
|
||||
.o_tdata(o_tdata), .o_tlast(o_tlast), .o_tvalid(o_tvalid), .o_tready(o_tready));
|
||||
|
||||
always
|
||||
begin
|
||||
#1 o_tready = 1;
|
||||
repeat (200)
|
||||
@(posedge clk);
|
||||
#1 o_tready = 0;
|
||||
repeat (120)
|
||||
@(posedge clk);
|
||||
end
|
||||
|
||||
|
||||
initial
|
||||
begin
|
||||
clk = 0;
|
||||
reset = 1;
|
||||
i_tlast = 0;
|
||||
i_tvalid = 0;
|
||||
i_tdata = 32'hBEEF_0000;
|
||||
i_tuser = 128'hF123_4567_89ab_cdef_0011_2233_4455_0000;
|
||||
#1000 reset = 0;
|
||||
repeat (10)
|
||||
@(posedge clk);
|
||||
#1 i_tvalid = 1;
|
||||
repeat (400)
|
||||
begin
|
||||
#1 i_tlast = 0;
|
||||
repeat (22)
|
||||
begin
|
||||
#1 i_tdata = i_tdata + 1;
|
||||
@(posedge clk);
|
||||
end
|
||||
#1 i_tdata = i_tdata + 1;
|
||||
#1 i_tlast = 1;
|
||||
@(posedge clk);
|
||||
#1 i_tuser <= i_tuser + 1;
|
||||
end // repeat (20)
|
||||
#1 i_tvalid <= 0;
|
||||
#100000 $finish;
|
||||
end
|
||||
|
||||
always @(posedge clk)
|
||||
if(o_tvalid & o_tready)
|
||||
if(o_tlast)
|
||||
$display("%x LAST",o_tdata);
|
||||
else
|
||||
$display("%x",o_tdata);
|
||||
|
||||
endmodule // chdr_framer_tb
|
||||
@@ -1 +0,0 @@
|
||||
iverilog -o window_tb window_tb.v -y ../coregen -y ../../../usrp2/models -y . -y ../control/ -y ../fifo/ -y /opt/Xilinx/14.6/ISE_DS/ISE/verilog/src/unisims/ -y ../packet_proc/ -y ../timing/ -y ../vita/
|
||||
@@ -1,341 +0,0 @@
|
||||
`timescale 1ns/1ps
|
||||
|
||||
//
|
||||
// Copyright 2012-2013 Ettus Research LLC
|
||||
// Copyright 2018 Ettus Research, a National Instruments Company
|
||||
//
|
||||
// SPDX-License-Identifier: LGPL-3.0-or-later
|
||||
//
|
||||
|
||||
|
||||
module window_tb();
|
||||
xlnx_glbl glbl (.GSR(),.GTS());
|
||||
|
||||
localparam STR_SINK_FIFOSIZE = 11;
|
||||
|
||||
reg clk, reset;
|
||||
|
||||
localparam PORTS = 5;
|
||||
|
||||
wire [63:0] noci_tdata[PORTS-1:0];
|
||||
wire [PORTS-1:0] noci_tlast;
|
||||
wire [PORTS-1:0] noci_tvalid;
|
||||
wire [PORTS-1:0] noci_tready;
|
||||
|
||||
wire [63:0] noco_tdata[PORTS-1:0];
|
||||
wire [PORTS-1:0] noco_tlast;
|
||||
wire [PORTS-1:0] noco_tvalid;
|
||||
wire [PORTS-1:0] noco_tready;
|
||||
|
||||
wire [63:0] src_tdata;
|
||||
wire src_tlast, src_tvalid;
|
||||
wire src_tready;
|
||||
|
||||
reg [63:0] cmdout_tdata;
|
||||
reg cmdout_tlast, cmdout_tvalid;
|
||||
wire cmdout_tready;
|
||||
|
||||
wire [63:0] dst_tdata;
|
||||
wire dst_tlast, dst_tvalid;
|
||||
wire dst_tready = 1;
|
||||
|
||||
reg set_stb_xbar;
|
||||
reg [15:0] set_addr_xbar;
|
||||
reg [31:0] set_data_xbar;
|
||||
|
||||
always
|
||||
#100 clk = ~clk;
|
||||
|
||||
initial clk = 0;
|
||||
initial reset = 1;
|
||||
initial #1000 reset = 0;
|
||||
|
||||
initial $dumpfile("window_tb.vcd");
|
||||
initial $dumpvars(0,window_tb);
|
||||
|
||||
initial #3000000 $finish;
|
||||
|
||||
|
||||
axi_crossbar #(.FIFO_WIDTH(64), .DST_WIDTH(16), .NUM_INPUTS(PORTS), .NUM_OUTPUTS(PORTS)) crossbar
|
||||
(.clk(clk), .reset(reset), .clear(1'b0),
|
||||
.local_addr(8'd0),
|
||||
.pkt_present({noci_tvalid[4],noci_tvalid[3],noci_tvalid[2],noci_tvalid[1],noci_tvalid[0]}),
|
||||
|
||||
.i_tdata({noci_tdata[4],noci_tdata[3],noci_tdata[2],noci_tdata[1],noci_tdata[0]}),
|
||||
.i_tlast({noci_tlast[4],noci_tlast[3],noci_tlast[2],noci_tlast[1],noci_tlast[0]}),
|
||||
.i_tvalid({noci_tvalid[4],noci_tvalid[3],noci_tvalid[2],noci_tvalid[1],noci_tvalid[0]}),
|
||||
.i_tready({noci_tready[4],noci_tready[3],noci_tready[2],noci_tready[1],noci_tready[0]}),
|
||||
|
||||
.o_tdata({noco_tdata[4],noco_tdata[3],noco_tdata[2],noco_tdata[1],noco_tdata[0]}),
|
||||
.o_tlast({noco_tlast[4],noco_tlast[3],noco_tlast[2],noco_tlast[1],noco_tlast[0]}),
|
||||
.o_tvalid({noco_tvalid[4],noco_tvalid[3],noco_tvalid[2],noco_tvalid[1],noco_tvalid[0]}),
|
||||
.o_tready({noco_tready[4],noco_tready[3],noco_tready[2],noco_tready[1],noco_tready[0]}),
|
||||
|
||||
.set_stb(set_stb_xbar), .set_addr(set_addr_xbar), .set_data(set_data_xbar),
|
||||
.rb_rd_stb(1'b0), .rb_addr(4'd0), .rb_data());
|
||||
|
||||
// Generator on port 0
|
||||
wire set_stb_0;
|
||||
wire [7:0] set_addr_0;
|
||||
wire [31:0] set_data_0;
|
||||
|
||||
noc_shell #(.STR_SINK_FIFOSIZE(STR_SINK_FIFOSIZE)) noc_shell_0
|
||||
(.bus_clk(clk), .bus_rst(reset),
|
||||
.i_tdata(noco_tdata[0]), .i_tlast(noco_tlast[0]), .i_tvalid(noco_tvalid[0]), .i_tready(noco_tready[0]),
|
||||
.o_tdata(noci_tdata[0]), .o_tlast(noci_tlast[0]), .o_tvalid(noci_tvalid[0]), .o_tready(noci_tready[0]),
|
||||
.clk(clk), .reset(reset),
|
||||
.set_data(set_data_0), .set_addr(set_addr_0), .set_stb(set_stb_0), .rb_data(64'd0),
|
||||
|
||||
.cmdout_tdata(64'h0), .cmdout_tlast(1'b0), .cmdout_tvalid(1'b0), .cmdout_tready(),
|
||||
.ackin_tdata(), .ackin_tlast(), .ackin_tvalid(), .ackin_tready(1'b1),
|
||||
|
||||
.str_sink_tdata(), .str_sink_tlast(), .str_sink_tvalid(), .str_sink_tready(1'b1), // unused port
|
||||
.str_src_tdata(src_tdata), .str_src_tlast(src_tlast), .str_src_tvalid(src_tvalid), .str_src_tready(src_tready)
|
||||
);
|
||||
|
||||
file_source #(.BASE(8), .FILENAME("test.dat")) file_source
|
||||
(.clk(clk), .reset(reset),
|
||||
.set_data(set_data_0), .set_addr(set_addr_0), .set_stb(set_stb_0),
|
||||
.o_tdata(src_tdata), .o_tlast(src_tlast), .o_tvalid(src_tvalid), .o_tready(src_tready));
|
||||
|
||||
// Simple FIR on port 1
|
||||
wire [31:0] set_data_1;
|
||||
wire [7:0] set_addr_1;
|
||||
wire set_stb_1;
|
||||
wire [63:0] s1o_tdata, s1i_tdata;
|
||||
wire s1o_tlast, s1i_tlast, s1o_tvalid, s1i_tvalid, s1o_tready, s1i_tready;
|
||||
|
||||
wire [31:0] pre_tdata, post_tdata;
|
||||
wire pre_tlast, pre_tvalid, pre_tready;
|
||||
wire post_tlast, post_tvalid, post_tready;
|
||||
|
||||
wire [15:0] pre_i = pre_tdata[31:16];
|
||||
wire [15:0] pre_q = pre_tdata[15:0];
|
||||
wire [15:0] post_i = post_tdata[31:16];
|
||||
wire [15:0] post_q = post_tdata[15:0];
|
||||
|
||||
noc_shell #(.STR_SINK_FIFOSIZE(STR_SINK_FIFOSIZE)) noc_shell_1
|
||||
(.bus_clk(clk), .bus_rst(reset),
|
||||
.i_tdata(noco_tdata[1]), .i_tlast(noco_tlast[1]), .i_tvalid(noco_tvalid[1]), .i_tready(noco_tready[1]),
|
||||
.o_tdata(noci_tdata[1]), .o_tlast(noci_tlast[1]), .o_tvalid(noci_tvalid[1]), .o_tready(noci_tready[1]),
|
||||
.clk(clk), .reset(reset),
|
||||
.set_data(set_data_1), .set_addr(set_addr_1), .set_stb(set_stb_1), .rb_data(64'd0),
|
||||
|
||||
.cmdout_tdata(64'h0), .cmdout_tlast(1'b0), .cmdout_tvalid(1'b0), .cmdout_tready(),
|
||||
.ackin_tdata(), .ackin_tlast(), .ackin_tvalid(), .ackin_tready(1'b1),
|
||||
|
||||
.str_sink_tdata(s1o_tdata), .str_sink_tlast(s1o_tlast), .str_sink_tvalid(s1o_tvalid), .str_sink_tready(s1o_tready),
|
||||
.str_src_tdata(s1i_tdata), .str_src_tlast(s1i_tlast), .str_src_tvalid(s1i_tvalid), .str_src_tready(s1i_tready)
|
||||
);
|
||||
|
||||
wire [31:0] axis_config_tdata1;
|
||||
wire axis_config_tvalid1, axis_config_tready1, axis_config_tlast1;
|
||||
|
||||
axi_wrapper #(.BASE(8)) axi_wrapper_ce1
|
||||
(.clk(clk), .reset(reset),
|
||||
.set_stb(set_stb_1), .set_addr(set_addr_1), .set_data(set_data_1),
|
||||
.i_tdata(s1o_tdata), .i_tlast(s1o_tlast), .i_tvalid(s1o_tvalid), .i_tready(s1o_tready),
|
||||
.o_tdata(s1i_tdata), .o_tlast(s1i_tlast), .o_tvalid(s1i_tvalid), .o_tready(s1i_tready),
|
||||
.m_axis_data_tdata(pre_tdata),
|
||||
.m_axis_data_tlast(pre_tlast),
|
||||
.m_axis_data_tvalid(pre_tvalid),
|
||||
.m_axis_data_tready(pre_tready),
|
||||
.s_axis_data_tdata(post_tdata),
|
||||
.s_axis_data_tlast(post_tlast),
|
||||
.s_axis_data_tvalid(post_tvalid),
|
||||
.s_axis_data_tready(post_tready),
|
||||
.m_axis_config_tdata(axis_config_tdata1),
|
||||
.m_axis_config_tlast(axis_config_tlast1),
|
||||
.m_axis_config_tvalid(axis_config_tvalid1),
|
||||
.m_axis_config_tready(axis_config_tready1)
|
||||
);
|
||||
|
||||
window #(.BASE(0)) window
|
||||
(.clk(clk), .reset(reset), .clear(clear),
|
||||
.set_stb(set_stb_1), .set_addr(set_addr_1), .set_data(set_data_1),
|
||||
.i_tdata(pre_tdata), .i_tlast(pre_tlast), .i_tvalid(pre_tvalid), .i_tready(pre_tready),
|
||||
.o_tdata(post_tdata), .o_tlast(post_tlast), .o_tvalid(post_tvalid), .o_tready(post_tready));
|
||||
|
||||
assign axis_config_tready1 = 1'b1;
|
||||
|
||||
// Dumper on port 2
|
||||
noc_shell #(.STR_SINK_FIFOSIZE(STR_SINK_FIFOSIZE)) noc_shell_2
|
||||
(.bus_clk(clk), .bus_rst(reset),
|
||||
.i_tdata(noco_tdata[2]), .i_tlast(noco_tlast[2]), .i_tvalid(noco_tvalid[2]), .i_tready(noco_tready[2]),
|
||||
.o_tdata(noci_tdata[2]), .o_tlast(noci_tlast[2]), .o_tvalid(noci_tvalid[2]), .o_tready(noci_tready[2]),
|
||||
|
||||
.clk(clk), .reset(reset),
|
||||
.set_data(), .set_addr(), .set_stb(), .rb_data(64'd0),
|
||||
|
||||
.cmdout_tdata(64'h0), .cmdout_tlast(1'b0), .cmdout_tvalid(1'b0), .cmdout_tready(),
|
||||
.ackin_tdata(), .ackin_tlast(), .ackin_tvalid(), .ackin_tready(1'b1),
|
||||
|
||||
.str_sink_tdata(dst_tdata), .str_sink_tlast(dst_tlast), .str_sink_tvalid(dst_tvalid), .str_sink_tready(dst_tready),
|
||||
.str_src_tdata(64'd0), .str_src_tlast(1'd0), .str_src_tvalid(1'b0), .str_src_tready() // unused port
|
||||
);
|
||||
|
||||
// Control Source on port 3
|
||||
noc_shell #(.STR_SINK_FIFOSIZE(STR_SINK_FIFOSIZE)) noc_shell_3
|
||||
(.bus_clk(clk), .bus_rst(reset),
|
||||
.i_tdata(noco_tdata[3]), .i_tlast(noco_tlast[3]), .i_tvalid(noco_tvalid[3]), .i_tready(noco_tready[3]),
|
||||
.o_tdata(noci_tdata[3]), .o_tlast(noci_tlast[3]), .o_tvalid(noci_tvalid[3]), .o_tready(noci_tready[3]),
|
||||
|
||||
.clk(clk), .reset(reset),
|
||||
.set_data(), .set_addr(), .set_stb(), .rb_data(64'd0),
|
||||
|
||||
.cmdout_tdata(cmdout_tdata), .cmdout_tlast(cmdout_tlast), .cmdout_tvalid(cmdout_tvalid), .cmdout_tready(cmdout_tready),
|
||||
.ackin_tdata(), .ackin_tlast(), .ackin_tvalid(), .ackin_tready(1'b1),
|
||||
|
||||
.str_sink_tdata(), .str_sink_tlast(), .str_sink_tvalid(), .str_sink_tready(1'b1), // unused port
|
||||
.str_src_tdata(64'd0), .str_src_tlast(1'd0), .str_src_tvalid(1'b0), .str_src_tready() // unused port
|
||||
);
|
||||
|
||||
// ////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
task SetXbar;
|
||||
input [15:0] start_reg;
|
||||
input [7:0] start_val;
|
||||
|
||||
begin
|
||||
repeat (PORTS)
|
||||
begin
|
||||
repeat (1)
|
||||
begin
|
||||
SetXbar_reg(start_reg,start_val);
|
||||
start_reg <= start_reg + 1;
|
||||
@(posedge clk);
|
||||
end
|
||||
start_val <= start_val + 1;
|
||||
@(posedge clk);
|
||||
end
|
||||
end
|
||||
endtask // SetXbar
|
||||
|
||||
task SetXbar_reg;
|
||||
input [15:0] addr;
|
||||
input [31:0] data;
|
||||
begin
|
||||
@(posedge clk);
|
||||
set_stb_xbar <= 1'b1;
|
||||
set_addr_xbar <= addr;
|
||||
set_data_xbar <= data;
|
||||
@(posedge clk);
|
||||
set_stb_xbar <= 1'b0;
|
||||
@(posedge clk);
|
||||
end
|
||||
endtask // set_xbar
|
||||
|
||||
task SendCtrlPacket;
|
||||
input [11:0] seqnum;
|
||||
input [31:0] sid;
|
||||
input [63:0] data;
|
||||
|
||||
begin
|
||||
@(posedge clk);
|
||||
cmdout_tdata <= { 4'h8, seqnum, 16'h16, sid };
|
||||
cmdout_tlast <= 0;
|
||||
cmdout_tvalid <= 1;
|
||||
while(~cmdout_tready) #1;
|
||||
|
||||
@(posedge clk);
|
||||
cmdout_tdata <= data;
|
||||
cmdout_tlast <= 1;
|
||||
while(~cmdout_tready) #1;
|
||||
|
||||
@(posedge clk);
|
||||
cmdout_tvalid <= 0;
|
||||
@(posedge clk);
|
||||
end
|
||||
endtask // SendCtrlPacket
|
||||
|
||||
initial
|
||||
begin
|
||||
cmdout_tdata <= 64'd0;
|
||||
cmdout_tlast <= 1'b0;
|
||||
cmdout_tvalid <= 1'b0;
|
||||
|
||||
@(negedge reset);
|
||||
@(posedge clk);
|
||||
SetXbar(256,0);
|
||||
|
||||
@(posedge clk);
|
||||
// Port 0
|
||||
SendCtrlPacket(12'd0, 32'h0003_0000, {32'h0, 32'h0000_0003}); // Command packet to set up source control window size
|
||||
SendCtrlPacket(12'd0, 32'h0003_0000, {32'h1, 32'h0000_0001}); // Command packet to set up source control window enable
|
||||
SendCtrlPacket(12'd0, 32'h0003_0000, {32'h3, 32'h8000_0001}); // Command packet to set up flow control
|
||||
SendCtrlPacket(12'd0, 32'h0003_0000, {32'h8, 32'h0000_0001}); // Command packet to set up SID
|
||||
SendCtrlPacket(12'd0, 32'h0003_0000, {32'hA, 32'h0000_0002}); // Command packet to set up Rate
|
||||
SendCtrlPacket(12'd0, 32'h0003_0000, {32'hB, 32'h0000_0001}); // Command packet to set up send_time_field
|
||||
SendCtrlPacket(12'd0, 32'h0003_0000, {32'h9, 32'h0000_0200}); // Command packet to set up Len
|
||||
#10000;
|
||||
// Port 1
|
||||
SendCtrlPacket(12'd0, 32'h0003_0001, {32'h0, 32'h0000_0013}); // Command packet to set up source control window size
|
||||
SendCtrlPacket(12'd0, 32'h0003_0001, {32'h1, 32'h0000_0001}); // Command packet to set up source control window enable
|
||||
SendCtrlPacket(12'd0, 32'h0003_0001, {32'h3, 32'h8000_0001}); // Command packet to set up flow control
|
||||
SendCtrlPacket(12'd0, 32'h0003_0001, {32'h8, 32'h0001_0002}); // Rewrite SID, send on to port 2
|
||||
|
||||
|
||||
#10000;
|
||||
// Port 2
|
||||
SendCtrlPacket(12'd0, 32'h0003_0002, {32'h0, 32'h0000_0003}); // Command packet to set up source control window size
|
||||
SendCtrlPacket(12'd0, 32'h0003_0002, {32'h1, 32'h0000_0001}); // Command packet to set up source control window enable
|
||||
SendCtrlPacket(12'd0, 32'h0003_0002, {32'h3, 32'h8000_0001}); // Command packet to set up flow control
|
||||
|
||||
#1000000;
|
||||
// WINDOW filter
|
||||
SendCtrlPacket(12'd0, 32'h0003_0001, {32'h10, 32'd0}); // frame_len (FFTsize)
|
||||
SendCtrlPacket(12'd0, 32'h0003_0001, {32'h10, 32'd1}); // frame_len (FFTsize)
|
||||
SendCtrlPacket(12'd0, 32'h0003_0001, {32'h10, 32'd2}); // frame_len (FFTsize)
|
||||
SendCtrlPacket(12'd0, 32'h0003_0001, {32'h10, 32'd3}); // frame_len (FFTsize)
|
||||
SendCtrlPacket(12'd0, 32'h0003_0001, {32'h10, 32'd4}); // frame_len (FFTsize)
|
||||
SendCtrlPacket(12'd0, 32'h0003_0001, {32'h10, 32'd5}); // frame_len (FFTsize)
|
||||
SendCtrlPacket(12'd0, 32'h0003_0001, {32'h10, 32'd6}); // frame_len (FFTsize)
|
||||
SendCtrlPacket(12'd0, 32'h0003_0001, {32'h10, 32'd7}); // frame_len (FFTsize)
|
||||
SendCtrlPacket(12'd0, 32'h0003_0001, {32'h11, 32'd8}); // frame_len (FFTsize)
|
||||
|
||||
#1000000;
|
||||
SendCtrlPacket(12'd0, 32'h0003_0001, {32'h10, 32'd100000}); // frame_len (FFTsize)
|
||||
SendCtrlPacket(12'd0, 32'h0003_0001, {32'h10, 32'd100000}); // frame_len (FFTsize)
|
||||
SendCtrlPacket(12'd0, 32'h0003_0001, {32'h10, 32'd100000}); // frame_len (FFTsize)
|
||||
SendCtrlPacket(12'd0, 32'h0003_0001, {32'h10, 32'd100000}); // frame_len (FFTsize)
|
||||
SendCtrlPacket(12'd0, 32'h0003_0001, {32'h10, 32'd100000}); // frame_len (FFTsize)
|
||||
SendCtrlPacket(12'd0, 32'h0003_0001, {32'h10, 32'd100000}); // frame_len (FFTsize)
|
||||
SendCtrlPacket(12'd0, 32'h0003_0001, {32'h10, 32'd100000}); // frame_len (FFTsize)
|
||||
SendCtrlPacket(12'd0, 32'h0003_0001, {32'h10, 32'd100000}); // frame_len (FFTsize)
|
||||
SendCtrlPacket(12'd0, 32'h0003_0001, {32'h11, 32'd100000}); // frame_len (FFTsize)
|
||||
|
||||
end
|
||||
|
||||
reg in_packet = 0;
|
||||
|
||||
integer outfile;
|
||||
|
||||
initial
|
||||
begin
|
||||
outfile = $fopen("output.dat","wb");
|
||||
//src_tready <= 1'b1;
|
||||
end
|
||||
|
||||
wire signed [15:0] a,b,c,d;
|
||||
assign a = src_tdata[63:48];
|
||||
assign b = src_tdata[47:32];
|
||||
assign c = src_tdata[31:16];
|
||||
assign d = src_tdata[15:0];
|
||||
|
||||
always @(posedge clk)
|
||||
if(src_tready & src_tvalid)
|
||||
begin
|
||||
if(src_tlast)
|
||||
in_packet <= 0;
|
||||
else
|
||||
in_packet <= 1;
|
||||
if(in_packet)
|
||||
begin
|
||||
//$fwrite(outfile,"%u",{q_out[15:0],i_out[15:0]}); // Correct endianness for GR
|
||||
//$write("%d,%d,%d,%d,",a,b,c,d);
|
||||
$fwrite(outfile,"%u",{dst_tdata[47:32],dst_tdata[63:48]});
|
||||
$fwrite(outfile,"%u",{dst_tdata[15:0],dst_tdata[31:16]});
|
||||
end
|
||||
end
|
||||
|
||||
endmodule // window_tb
|
||||
@@ -10,7 +10,7 @@
|
||||
##################################################
|
||||
TIMING_SRCS = $(abspath $(addprefix $(BASE_DIR)/../lib/timing/, \
|
||||
time_compare.v \
|
||||
timekeeper.v \
|
||||
timekeeper_legacy.v \
|
||||
pps_generator.v \
|
||||
pps_synchronizer.v \
|
||||
pulse_generator.v \
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
//
|
||||
|
||||
|
||||
module timekeeper
|
||||
module timekeeper_legacy
|
||||
#(parameter SR_TIME_HI = 0,
|
||||
parameter SR_TIME_LO = 1,
|
||||
parameter SR_TIME_CTRL = 2,
|
||||
@@ -84,4 +84,4 @@ module timekeeper
|
||||
else
|
||||
vita_time_lastpps <= vita_time + INCREMENT;
|
||||
|
||||
endmodule // timekeeper
|
||||
endmodule // timekeeper_legacy
|
||||
@@ -2,17 +2,12 @@
|
||||
# list discovered by run_testbenches.py
|
||||
# NOTE: Lines containing "#" are treated as a comment
|
||||
|
||||
lib/rfnoc/noc_block_eq_tb
|
||||
lib/rfnoc/noc_block_ofdm_tb
|
||||
lib/rfnoc/noc_block_schmidl_cox_tb
|
||||
top/e31x/sim/dram_test
|
||||
top/n3xx/sim/arm_to_sfp_loopback
|
||||
top/n3xx/sim/aurora_loopback
|
||||
top/n3xx/sim/one_gig_eth_loopback
|
||||
top/n3xx/sim/ten_gig_eth_loopback
|
||||
top/x300/sim/x300_pcie_int
|
||||
top/n3xx/dboards/eiscat/radio/noc_block_ddc_eiscat_tb
|
||||
top/n3xx/dboards/eiscat/radio/noc_block_radio_core_eiscat_tb
|
||||
|
||||
# These testbenches only work in ModelSim
|
||||
lib/axi4s_sv/axi4s_remove_bytes_tb
|
||||
|
||||
Reference in New Issue
Block a user