Hi,
I have a custom RFNoC block that is working with the exception that the
sample timing isn't quite right. I'm not getting a consistent group delay
from run to run even though I'm using timed starts for both tx and rx
streaming. (I'm using my own C++ app and calling UHD 3.14.1.0 directly for
an N310 device).
The following graph (using stock blocks) produces a consistent group delay
(from host_tx to host_rx):
host_tx -> DUC -> Radio_0 -> DDC -> host_rx
The following graph (adding MyBlock) produces a seemingly random group
delay (as if the transmitter Radio is no longer respecting the time stamp):
host_tx -> MyBlock -> DUC -> Radio_0 -> DDC -> host_rx
With either of these graphs, I'm basically measuring the Tx/Rx leakage
signal.
Please let me know if you have any ideas why the graph with MyBlock does
not seem to be handling the packet header correctly. Or, perhaps it's not
the packet header, but something else that could be causing this?? Here
are a few remarks:
- MyBlock is similar in function to the "replay" block. Myblock stores
up one burst of incoming samples and then continuously plays this burst
repeatedly until told to stop.
- In MyBlock, I am storing the tuser data of the first incoming packet
to use as the first outgoing packet tuser data. After that, the subsequent
outgoing packets do not include any timestamp (has_timestamp bit set to
zero).
- I have created a reasonably detailed test bench which seems to work as
expected such that the data streams as expected and the first packet header
matches the packet header that I send to it
- I have run an RFNoC graph with only MyBlock and it looks to me like
the timestamp info is forwarded as expected
- In the second graph above (the one that doesn't work), I am able to
produce "Late" errors ('L' on terminal) if I purposely use a start time in
the past. So, I know that in some way the time stamp is getting through.
- I am using the default block controller for MyBlock (in UHD)
Below is the Verilog related to the tuser data. Thanks for any help.
Rob
// this reg stores the incoming tuser so that the it can
// be sent with the first outgoing tuser
reg [127:0] in_tuser;
// these keep track of when the first output packet is
// sent so that only the first one contains a replica
// of the incoming tuser timestamp and the rest of the
// outgoing packets have 'has_time' set to zero.
reg first_pkt_sent;
wire modify_time = first_pkt_sent ? 1'b1:1'b0;
// the following creates the output tuser based on the
// previously stored input tuser. In addition to
// handling the time stamp, this block also fixes the
// SIDs and eob appropriately
cvita_hdr_modify #() hdr_modify
(.header_in(in_tuser),
.header_out(samp_out_tuser),
.use_pkt_type(1'b0), .pkt_type(2'b0),
.use_has_time(modify_time), .has_time(1'b0),
.use_eob(1'b1), .eob(eob_out),
.use_seqnum(1'b0), .seqnum(12'b0),
.use_length(1'b0), .length(16'b0),
.use_payload_length(1'b0), .payload_length(16'd1024),
.use_src_sid(1'b1), .src_sid(src_sid),
.use_dst_sid(1'b1), .dst_sid(next_dst_sid),
.use_vita_time(1'b0), .vita_time(64'b0));
// Store the input tuser but only if its the first packet
reg first_pkt_received;
always @(posedge ce_clk) begin
case(state)
RESET:
begin
in_tuser <= 128'b0;
first_pkt_received = 1'b0;
end
STORING:
if (~first_pkt_received) begin
if (samp_in_received & samp_in_tlast) begin
in_tuser <= samp_in_tuser;
first_pkt_received <= 1'b1;
end
end
endcase
end
// Keep track of the first output packet so that once it is sent
// we can remove the time stamp from subsequent output packets
always @(posedge ce_clk) begin
case(state)
RESET: first_pkt_sent <= 1'b0;
STREAMING,FLUSHING :
if (~first_pkt_sent) begin
if (samp_out_sent & samp_out_tlast) begin
first_pkt_sent <= 1'b1;
end
end
endcase
end
_______________________________________________
USRP-users mailing list
[email protected]
http://lists.ettus.com/mailman/listinfo/usrp-users_lists.ettus.com