Tx_empty in fpga

(originally posted on nabble without subscribing- previously was
subscribed
as [email protected])

Trying to fix the problem of the transmitter repeating the last sample
when
the fifo empties for doing gmsk on BasicTX/RX and/or LFRX/TX.

bus_interface.v line 116 has:
assign txdata = tx_empty ? 32’b0 : txd;

which says to me, load 32 bits of 0 when tx_empty, otherwise load the
data…
so why doesn’t this work? Did I miss something (probably!)

As an alternative, what about in tx_buffer around line 69:
if((load_next != channels) & !tx_empty)
begin
load_next <= #1 load_next + 4’d1;
case(load_next)
4’d0 : tx_i_0 <= #1 fifodata;
4’d1 : tx_q_0 <= #1 fifodata;
4’d2 : tx_i_1 <= #1 fifodata;
4’d3 : tx_q_1 <= #1 fifodata;
4’d4 : tx_i_2 <= #1 fifodata;
4’d5 : tx_q_2 <= #1 fifodata;
4’d6 : tx_i_3 <= #1 fifodata;
4’d7 : tx_q_3 <= #1 fifodata;
endcase // case(load_next)
end // if ((load_next != channels) & !tx_empty)

what if instead of checking for tx_empty and loading fifodata we do
this:
if(load_next != channels)
begin
load_next <= #1 load_next + 4’d1;
case(load_next)
4’d0 : tx_i_0 <= #1 tx_empty ? 16’d0 : fifodata;
4’d1 : tx_q_0 <= #1 tx_empty ? 16’d0 : fifodata;
4’d2 : tx_i_1 <= #1 tx_empty ? 16’d0 : fifodata;
4’d3 : tx_q_1 <= #1 tx_empty ? 16’d0 : fifodata;
4’d4 : tx_i_2 <= #1 tx_empty ? 16’d0 : fifodata;
4’d5 : tx_q_2 <= #1 tx_empty ? 16’d0 : fifodata;
4’d6 : tx_i_3 <= #1 tx_empty ? 16’d0 : fifodata;
4’d7 : tx_q_3 <= #1 tx_empty ? 16’d0 : fifodata;
endcase // case(load_next)
end // if ((load_next != channels) & !tx_empty)


View this message in context:
http://www.nabble.com/tx_empty-in-fpga-tf2980108.html#a8327128
Sent from the GnuRadio mailing list archive at Nabble.com.

On Sun, Jan 14, 2007 at 12:45:48PM -0800, Matt E. wrote:

  [ Don't let this comment stop you from trying this ;) ]

I believe that a
delay on the order of 12 clocks is about right. You’ll need to count
pipeline stages through the tx path to get it right.

The delay through the interpolators is variable – it depends on the
intepolation ratio. Again, this is why this should be done before the
interpolators.

Agreed as long as the input being pushed into the signal processing
pipeline is interpreted as samples. I think we’re going to need to
visit this problem again when somebody put a modulator into the
FPGA.

Eric

Eric B. wrote:

Have to disagree with you here. The best place to do this is before the
signal processing chain, for exactly the reasons you state below…

(2) You’re going to get the equivalent of a “key click”. That is,
wide band harmonics in the freq domain from the discontinuity in the
time domain (step function). It would be better to ramp the last
value down, say be doing the equivalent of an arithmetic shift right
by 2. This really ought to be done by the code that feeds the DACs.

The key clicks will get filtered if you do this before the upconverter.
They’ll still be there, but they’ll only be as wide as the baseband
bandwidth instead of the full 32 MHz.

I think a better place to fix this would be to filter the output of
tx_a_a, tx_b_a, tx_a_b and tx_b_b in usrp_std.v based on their
previous values and the delayed value of tx_empty.

You don’t need this filter if you do it before the interpolators.

I believe that a
delay on the order of 12 clocks is about right. You’ll need to count
pipeline stages through the tx path to get it right.

The delay through the interpolators is variable – it depends on the
intepolation ratio. Again, this is why this should be done before the
interpolators.

Matt

On Sat, Jan 13, 2007 at 06:54:20PM -0800, Loconut wrote:

which says to me, load 32 bits of 0 when tx_empty, otherwise load the data…
so why doesn’t this work? Did I miss something (probably!)

bus_interface.v is not used :wink:

    4'd5 : tx_q_2 <= #1 fifodata;
          4'd0 : tx_i_0 <= #1 tx_empty ? 16'd0 : fifodata;
          4'd1 : tx_q_0 <= #1 tx_empty ? 16'd0 : fifodata;
          4'd2 : tx_i_1 <= #1 tx_empty ? 16'd0 : fifodata;
          4'd3 : tx_q_1 <= #1 tx_empty ? 16'd0 : fifodata;
          4'd4 : tx_i_2 <= #1 tx_empty ? 16'd0 : fifodata;
          4'd5 : tx_q_2 <= #1 tx_empty ? 16'd0 : fifodata;
          4'd6 : tx_i_3 <= #1 tx_empty ? 16'd0 : fifodata;
          4'd7 : tx_q_3 <= #1 tx_empty ? 16'd0 : fifodata;
        endcase // case(load_next)
     end // if ((load_next != channels) & !tx_empty) 

This could work, with two caveats:

(1) you’re stuffing 0’s into the input of the signal processing
chain, instead of handing the underrun at the output of the
signal processing chain. With the existing code, you’re
probably OK, but in general, if the idea is to zero the output
when there’s no input, I’d prefer to do it closer to the DACs.
[ Don’t let this comment stop you from trying this :wink: ]

(2) You’re going to get the equivalent of a “key click”. That is,
wide band harmonics in the freq domain from the discontinuity in
the
time domain (step function). It would be better to ramp the last
value down, say be doing the equivalent of an arithmetic shift
right
by 2. This really ought to be done by the code that feeds the
DACs.

I think a better place to fix this would be to filter the output of
tx_a_a, tx_b_a, tx_a_b and tx_b_b in usrp_std.v based on their
previous values and the delayed value of tx_empty. I believe that a
delay on the order of 12 clocks is about right. You’ll need to count
pipeline stages through the tx path to get it right.

create a module, say

module ramp_down_dac_when_empty
( input clock,
input reset,
input tx_empty,
input [15:0] in,
output reg [15:0] out
);

// your code here…

endmodule // ramp_down_dac_when_empty

Then instantiate 4 of them to handle the filtering.

Eric