diff options
author | Matt Ettus <matt@ettus.com> | 2010-05-27 17:31:46 -0700 |
---|---|---|
committer | Matt Ettus <matt@ettus.com> | 2010-05-27 17:31:46 -0700 |
commit | 3d06fb26c5a59451b26680b6096fca7ee37e8018 (patch) | |
tree | ce172a14304474b2a46854bea6b47c2ed1f8380b /usrp2/vrt/vita_rx_control.v | |
parent | 621ad7cc9e68b4e304b616d8f840d3a03a047c8b (diff) | |
parent | b38d2424b1ac3242146fc9305d9e4ae80e21dede (diff) | |
download | uhd-3d06fb26c5a59451b26680b6096fca7ee37e8018.tar.gz uhd-3d06fb26c5a59451b26680b6096fca7ee37e8018.tar.bz2 uhd-3d06fb26c5a59451b26680b6096fca7ee37e8018.zip |
Merge branch 'udp' into master_merge_take2
* udp: (67 commits)
better test program for just the tx side
fix typo, no functionality difference
ignores
move dsp settings regs to reclocked setting bus. Works, gets us to within 18ps of passing timing
reverting logic clean up which should have made timing better, but made it worse instead
moved fifos around, now easier to see where they are and how big
bigger fifo on UDP TX path, to possibly fix overruns on decim=4
Xilinx ISE is incorrectly parsing the verilog case statement, this is a workaround
pps and vita time debug pins
ignore emacs backup files
more debug for fixing E's
better debug pins for going after cascading E's
copy in wrong place
copied over from quad radio
just debug pin changes
typo caused the tx udp chain to be disconnected
moved into subdir
speed up timing by ignoring the too_early error. We'll need to FIXME this later
Added set time and set time at next pps. Removed the old sync pps commands, they dont make sense to use anymore.
moved around regs, added a bit to allow for alternate PPS source
...
Diffstat (limited to 'usrp2/vrt/vita_rx_control.v')
-rw-r--r-- | usrp2/vrt/vita_rx_control.v | 180 |
1 files changed, 180 insertions, 0 deletions
diff --git a/usrp2/vrt/vita_rx_control.v b/usrp2/vrt/vita_rx_control.v new file mode 100644 index 000000000..669b8299d --- /dev/null +++ b/usrp2/vrt/vita_rx_control.v @@ -0,0 +1,180 @@ + +module vita_rx_control + #(parameter BASE=0, + parameter WIDTH=32) + (input clk, input reset, input clear, + input set_stb, input [7:0] set_addr, input [31:0] set_data, + + input [63:0] vita_time, + output overrun, + + // To vita_rx_framer + output [4+64+WIDTH-1:0] sample_fifo_o, + output sample_fifo_src_rdy_o, + input sample_fifo_dst_rdy_i, + + // From DSP Core + input [WIDTH-1:0] sample, + output run, + input strobe, + + output [31:0] debug_rx + ); + + // FIXME add TX Interruption (halt, pause, continue) functionality + + wire [63:0] new_time; + wire [31:0] new_command; + wire sc_pre1, clear_int, clear_reg; + + assign clear_int = clear | clear_reg; + + wire [63:0] rcvtime_pre; + reg [63:0] rcvtime; + wire [29:0] numlines_pre; + wire send_imm_pre, chain_pre; + reg send_imm, chain; + wire full_ctrl, read_ctrl, empty_ctrl, write_ctrl; + reg sc_pre2; + wire [33:0] fifo_line; + reg [29:0] lines_left; + reg [2:0] ibs_state; + wire now, early, late; + wire sample_fifo_in_rdy; + + setting_reg #(.my_addr(BASE)) sr_cmd + (.clk(clk),.rst(reset),.strobe(set_stb),.addr(set_addr), + .in(set_data),.out(new_command),.changed()); + + setting_reg #(.my_addr(BASE+1)) sr_time_h + (.clk(clk),.rst(reset),.strobe(set_stb),.addr(set_addr), + .in(set_data),.out(new_time[63:32]),.changed()); + + setting_reg #(.my_addr(BASE+2)) sr_time_l + (.clk(clk),.rst(reset),.strobe(set_stb),.addr(set_addr), + .in(set_data),.out(new_time[31:0]),.changed(sc_pre1)); + + setting_reg #(.my_addr(BASE+3)) sr_clear + (.clk(clk),.rst(reset),.strobe(set_stb),.addr(set_addr), + .in(set_data),.out(),.changed(clear_reg)); + + // FIFO to store commands sent from the settings bus + always @(posedge clk) + sc_pre2 <= sc_pre1; + assign write_ctrl = sc_pre1 & ~sc_pre2; + + wire [4:0] command_queue_len; + shortfifo #(.WIDTH(96)) commandfifo + (.clk(clk),.rst(reset),.clear(clear_int), + .datain({new_command,new_time}), .write(write_ctrl&~full_ctrl), .full(full_ctrl), + .dataout({send_imm_pre,chain_pre,numlines_pre,rcvtime_pre}), + .read(read_ctrl), .empty(empty_ctrl), + .occupied(command_queue_len), .space() ); + + reg [33:0] pkt_fifo_line; + + localparam IBS_IDLE = 0; + localparam IBS_WAITING = 1; + localparam IBS_RUNNING = 2; + localparam IBS_OVERRUN = 4; + localparam IBS_BROKENCHAIN = 5; + localparam IBS_LATECMD = 6; + + wire signal_cmd_done = (lines_left == 1) & (~chain | (~empty_ctrl & (numlines_pre==0))); + wire signal_overrun = (ibs_state == IBS_OVERRUN); + wire signal_brokenchain = (ibs_state == IBS_BROKENCHAIN); + wire signal_latecmd = (ibs_state == IBS_LATECMD); + + // Buffer of samples for while we're writing the packet headers + wire [3:0] flags = {signal_overrun,signal_brokenchain,signal_latecmd,signal_cmd_done}; + + wire attempt_sample_write = ((run & strobe) | (ibs_state==IBS_OVERRUN) | + (ibs_state==IBS_BROKENCHAIN) | (ibs_state==IBS_LATECMD)); + + fifo_short #(.WIDTH(4+64+WIDTH)) rx_sample_fifo + (.clk(clk),.reset(reset),.clear(clear_int), + .datain({flags,vita_time,sample}), .src_rdy_i(attempt_sample_write), .dst_rdy_o(sample_fifo_in_rdy), + .dataout(sample_fifo_o), + .src_rdy_o(sample_fifo_src_rdy_o), .dst_rdy_i(sample_fifo_dst_rdy_i), + .space(), .occupied() ); + + // Inband Signalling State Machine + time_compare + time_compare (.time_now(vita_time), .trigger_time(rcvtime), .now(now), .early(early), .late(late)); + + wire too_late = late & ~send_imm; + wire go_now = now | send_imm; + wire full = ~sample_fifo_in_rdy; + + always @(posedge clk) + if(reset | clear_int) + begin + ibs_state <= IBS_IDLE; + lines_left <= 0; + rcvtime <= 0; + send_imm <= 0; + chain <= 0; + end + else + case(ibs_state) + IBS_IDLE : + if(~empty_ctrl) + begin + lines_left <= numlines_pre; + rcvtime <= rcvtime_pre; + ibs_state <= IBS_WAITING; + send_imm <= send_imm_pre; + chain <= chain_pre; + end + IBS_WAITING : + if(go_now) + ibs_state <= IBS_RUNNING; + else if(too_late) + ibs_state <= IBS_LATECMD; + IBS_RUNNING : + if(strobe) + if(full) + ibs_state <= IBS_OVERRUN; + else + begin + lines_left <= lines_left - 1; + if(lines_left == 1) + if(~chain) + ibs_state <= IBS_IDLE; + else if(empty_ctrl) + ibs_state <= IBS_BROKENCHAIN; + else + begin + lines_left <= numlines_pre; + rcvtime <= rcvtime_pre; + send_imm <= send_imm_pre; + chain <= chain_pre; + if(numlines_pre == 0) // If we are told to stop here + ibs_state <= IBS_IDLE; + else + ibs_state <= IBS_RUNNING; + end + end // else: !if(full) + IBS_OVERRUN : + if(sample_fifo_in_rdy) + ibs_state <= IBS_IDLE; + IBS_LATECMD : + if(sample_fifo_in_rdy) + ibs_state <= IBS_IDLE; + IBS_BROKENCHAIN : + if(sample_fifo_in_rdy) + ibs_state <= IBS_IDLE; + endcase // case(ibs_state) + + assign overrun = (ibs_state == IBS_OVERRUN); + assign run = (ibs_state == IBS_RUNNING); + + assign read_ctrl = ( (ibs_state == IBS_IDLE) | ((ibs_state == IBS_RUNNING) & strobe & ~full & (lines_left==1) & chain) ) + & ~empty_ctrl; + + assign debug_rx = { { ibs_state[2:0], command_queue_len }, + { 8'd0 }, + { go_now, too_late, run, strobe, read_ctrl, write_ctrl, full_ctrl, empty_ctrl }, + { 2'b0, overrun, chain_pre, sample_fifo_in_rdy, attempt_sample_write, sample_fifo_src_rdy_o,sample_fifo_dst_rdy_i} }; + +endmodule // rx_control |