mirror of
https://github.com/EttusResearch/uhd.git
synced 2026-10-25 17:36:10 +00:00
fpga: rfnoc: add TS-on-first-only option to axi_rate_change_ms
Add a parameter to the axi_rate_change_ms module called EN_TIME_ALL_PKTS. Set to 1, the module will calculate timestamps for all packets of the output burst. Set to 0, the module will only insert a timestamp in the first pkt of each generated output burst.
This commit is contained in:
parent
45ea2365b1
commit
d91c2293d1
@ -18,17 +18,20 @@
|
||||
// internal state machine will terminate each burst even if the tlast does not
|
||||
// make it through the user logic due to input data not matching the decimation
|
||||
// rate.
|
||||
// Generates timestamps on each packet of the burst or none depending on the
|
||||
// first received packet of the burst.
|
||||
// Generates timestamps on each packet of the burst or only the first packet,
|
||||
// depending on EN_TIME_ALL_PKTS, when the burst is timed.
|
||||
//
|
||||
// Parameters:
|
||||
//
|
||||
// WIDTH : Data bus width in bits (must match user logic).
|
||||
// SPC : Samples per clock cycle (must match user logic).
|
||||
// Width of sample stream tags.
|
||||
// SPC_MTU_LOG2 : Log2 of the maximum packet size in internal
|
||||
// words(SPC*WIDTH wide). Internal counter widths
|
||||
// are derived from this value.
|
||||
// WIDTH : Data bus width in bits (must match user logic).
|
||||
// SPC : Samples per clock cycle (must match user logic).
|
||||
// Width of sample stream tags.
|
||||
// SPC_MTU_LOG2 : Log2 of the maximum packet size in internal
|
||||
// words(SPC*WIDTH wide). Internal counter widths
|
||||
// are derived from this value.
|
||||
// EN_TIME_ALL_PKTS : When set to 1, generate timestamps for all packets in
|
||||
// a timed burst. When 0, generate a timestamp only for
|
||||
// the first packet in a timed burst.
|
||||
// MAX_USER_LOGIC_LATENCY : Maximum latency of the user logic in cycles for the transfer from
|
||||
// m_axis_data_tlast to s_axis_data_tlast assuming that s_axis_data_tready is
|
||||
// always high.
|
||||
@ -41,6 +44,7 @@ module axi_rate_change_ms
|
||||
int WIDTH = 32,
|
||||
int SPC = 1,
|
||||
int SPC_MTU_LOG2 = 10,
|
||||
bit EN_TIME_ALL_PKTS = 1'b1,
|
||||
int MAX_USER_LOGIC_LATENCY = 85 + 5*SPC // current value for DDC Multisample user logic
|
||||
)(
|
||||
input wire logic clk,
|
||||
@ -247,6 +251,7 @@ module axi_rate_change_ms
|
||||
logic first_pkt_timestamp_valid;
|
||||
logic burst_has_time = '0;
|
||||
logic first_burst_transfer = '1;
|
||||
logic first_output_packet = '1;
|
||||
|
||||
// determine first packet in burst
|
||||
always_ff @(posedge clk) begin
|
||||
@ -288,6 +293,16 @@ module axi_rate_change_ms
|
||||
end
|
||||
end
|
||||
|
||||
// Track the first output packet boundary in the burst. The state is
|
||||
// consumed only when the packet boundary is accepted by the NoC shell.
|
||||
always_ff @(posedge clk) begin
|
||||
if (rst || clear) begin
|
||||
first_output_packet <= 1'b1;
|
||||
end else if (o_tvalid && o_tready && o_tlast) begin
|
||||
first_output_packet <= o_teob;
|
||||
end
|
||||
end
|
||||
|
||||
// update outgoing timestamp
|
||||
// always updated at the beginning of the burst through input state machine
|
||||
logic [CHDR_TIMESTAMP_W-1:0] timestamp_out = '0;
|
||||
@ -360,7 +375,8 @@ module axi_rate_change_ms
|
||||
// insert generated signals
|
||||
assign o_tlast = end_of_packet | o_teob | terminate_burst;
|
||||
assign o_ttimestamp = timestamp_out;
|
||||
assign o_thas_time = o_tlast && burst_has_time; //only valid on tlast
|
||||
assign o_thas_time = o_tlast && burst_has_time &&
|
||||
(EN_TIME_ALL_PKTS || first_output_packet);
|
||||
|
||||
|
||||
endmodule
|
||||
|
||||
@ -43,6 +43,14 @@ module axi_rate_change_ms_all_tb;
|
||||
.MAX_M(1)
|
||||
) tb_4 ();
|
||||
|
||||
// First-packet-only timestamp mode
|
||||
axi_rate_change_ms_tb #(
|
||||
.WIDTH(32),
|
||||
.MAX_N(1),
|
||||
.MAX_M(1),
|
||||
.EN_TIME_ALL_PKTS(1'b0)
|
||||
) tb_5 ();
|
||||
|
||||
endmodule : axi_rate_change_ms_all_tb
|
||||
|
||||
`default_nettype wire
|
||||
|
||||
@ -17,7 +17,8 @@
|
||||
module axi_rate_change_ms_tb #(
|
||||
parameter int WIDTH = 32,
|
||||
parameter int MAX_N = 16,
|
||||
parameter int MAX_M = 16
|
||||
parameter int MAX_M = 16,
|
||||
parameter bit EN_TIME_ALL_PKTS = 1'b1
|
||||
);
|
||||
`include "test_exec.svh"
|
||||
|
||||
@ -130,7 +131,8 @@ module axi_rate_change_ms_tb #(
|
||||
axi_rate_change_ms #(
|
||||
.WIDTH(WIDTH),
|
||||
.SPC(SPC),
|
||||
.SPC_MTU_LOG2(SPC_MTU_LOG2)
|
||||
.SPC_MTU_LOG2(SPC_MTU_LOG2),
|
||||
.EN_TIME_ALL_PKTS(EN_TIME_ALL_PKTS)
|
||||
) dut (
|
||||
.clk(clk),
|
||||
.rst(rst),
|
||||
@ -402,7 +404,7 @@ module axi_rate_change_ms_tb #(
|
||||
|
||||
always_ff @(posedge clk) begin
|
||||
if (clock_cnt_en) begin
|
||||
if (noc_out.tvalid && !clock_cnt_start) begin
|
||||
if (noc_out.tvalid && noc_out.tready && !clock_cnt_start) begin
|
||||
clock_cnt_start <= 1'b1;
|
||||
clock_cnt <= clock_cnt + 1;
|
||||
end else if (clock_cnt_start) begin
|
||||
@ -675,8 +677,10 @@ module axi_rate_change_ms_tb #(
|
||||
int last_idx = actual_pkt_size - 1;
|
||||
user_t actual_user = user_t'(actual_packet.user[last_idx]);
|
||||
logic [CHDR_TIMESTAMP_W-1:0] expected_last_timestamp;
|
||||
bit expected_has_time;
|
||||
|
||||
expected_last_timestamp = expected_timestamp;
|
||||
expected_has_time = EN_TIME_ALL_PKTS || (pkt_idx == 0);
|
||||
|
||||
`ASSERT_ERROR(
|
||||
actual_user.eob == is_last_packet,
|
||||
@ -685,17 +689,19 @@ module axi_rate_change_ms_tb #(
|
||||
pkt_idx, actual_user.eob, is_last_packet)
|
||||
)
|
||||
`ASSERT_ERROR(
|
||||
actual_user.has_time == 1'b1,
|
||||
actual_user.has_time == expected_has_time,
|
||||
$sformatf({"random_spp pkt %0d:",
|
||||
" Last-word HAS_TIME mismatch. Actual=%0d Expected=1"},
|
||||
pkt_idx, actual_user.has_time)
|
||||
)
|
||||
`ASSERT_ERROR(
|
||||
actual_user.timestamp == expected_last_timestamp,
|
||||
$sformatf({"random_spp pkt %0d:",
|
||||
" Last-word timestamp mismatch. Actual=%0d Expected=%0d"},
|
||||
pkt_idx, actual_user.timestamp, expected_last_timestamp)
|
||||
" Last-word HAS_TIME mismatch. Actual=%0d Expected=%0d"},
|
||||
pkt_idx, actual_user.has_time, expected_has_time)
|
||||
)
|
||||
if (expected_has_time) begin
|
||||
`ASSERT_ERROR(
|
||||
actual_user.timestamp == expected_last_timestamp,
|
||||
$sformatf({"random_spp pkt %0d:",
|
||||
" Last-word timestamp mismatch. Actual=%0d Expected=%0d"},
|
||||
pkt_idx, actual_user.timestamp, expected_last_timestamp)
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
// Advance running timestamp for the next packet
|
||||
@ -830,6 +836,7 @@ module axi_rate_change_ms_tb #(
|
||||
axis_pkt_t packet = new();
|
||||
int words_in_packet;
|
||||
bit is_last_output_packet;
|
||||
bit has_time;
|
||||
|
||||
if (words_left_to_recv >= spp) begin
|
||||
words_in_packet = spp;
|
||||
@ -837,6 +844,7 @@ module axi_rate_change_ms_tb #(
|
||||
words_in_packet = words_left_to_recv;
|
||||
end
|
||||
is_last_output_packet = (words_left_to_recv <= spp);
|
||||
has_time = EN_TIME_ALL_PKTS || (expected_packets.size() == 0);
|
||||
|
||||
for (int i = 0; i < words_in_packet; i++) begin
|
||||
user_t user_word;
|
||||
@ -853,7 +861,7 @@ module axi_rate_change_ms_tb #(
|
||||
user_word = pack_user(
|
||||
16'd0,
|
||||
expected_timestamp,
|
||||
1'b1,
|
||||
has_time,
|
||||
is_last_output_packet
|
||||
);
|
||||
end
|
||||
@ -1007,8 +1015,9 @@ module axi_rate_change_ms_tb #(
|
||||
string tb_name;
|
||||
|
||||
tb_name = $sformatf(
|
||||
"AXI Rate Change CHDR Testbench (WIDTH=%0d, MAX_N=%0d, MAX_M=%0d)",
|
||||
WIDTH, MAX_N, MAX_M);
|
||||
{"AXI Rate Change CHDR Testbench (WIDTH=%0d, MAX_N=%0d, MAX_M=%0d, ",
|
||||
"EN_TIME_ALL_PKTS=%0d)"},
|
||||
WIDTH, MAX_N, MAX_M, EN_TIME_ALL_PKTS);
|
||||
test.start_tb(tb_name, 1s);
|
||||
|
||||
//`ASSERT_ERROR(
|
||||
@ -1070,6 +1079,22 @@ module axi_rate_change_ms_tb #(
|
||||
test_rate(1, 1, DEFAULT_SPP * 4, DEFAULT_SPP * 4, 1'b0, 1'b0, 0);
|
||||
test.end_test();
|
||||
|
||||
if (!EN_TIME_ALL_PKTS) begin
|
||||
test.start_test("Test First Packet Timestamp Only");
|
||||
repeat (2) begin
|
||||
test_rate(
|
||||
.n(1),
|
||||
.m(1),
|
||||
.num_words(DEFAULT_SPP * 3),
|
||||
.spp(DEFAULT_SPP),
|
||||
.rand_delay_in(1'b1),
|
||||
.rand_delay_out(1'b1),
|
||||
.time_incr(3)
|
||||
);
|
||||
end
|
||||
test.end_test();
|
||||
end
|
||||
|
||||
if (MAX_M >= 2) begin
|
||||
test.start_test("Test Interpolation Early Sideband Metadata");
|
||||
test_rate(
|
||||
|
||||
Loading…
Reference in New Issue
Block a user