diff options
Diffstat (limited to 'fpga/usrp3/lib/vita_200/new_tx_tb.v')
-rw-r--r-- | fpga/usrp3/lib/vita_200/new_tx_tb.v | 366 |
1 files changed, 366 insertions, 0 deletions
diff --git a/fpga/usrp3/lib/vita_200/new_tx_tb.v b/fpga/usrp3/lib/vita_200/new_tx_tb.v new file mode 100644 index 000000000..29926fd78 --- /dev/null +++ b/fpga/usrp3/lib/vita_200/new_tx_tb.v @@ -0,0 +1,366 @@ +// +// Copyright 2016 Ettus Research, a National Instruments Company +// +// SPDX-License-Identifier: LGPL-3.0-or-later +// +`timescale 1ns/1ps + +module new_tx_tb(); +`ifdef ISIM +`else //iverilog implied. + xlnx_glbl glbl (.GSR(),.GTS()); +`endif + + + localparam SR_TX_DSP = 8; + localparam SR_TX_RESPONDER = 16; + localparam SR_TX_CTRL = 24; + + localparam SR_CYCLES = SR_TX_RESPONDER + 0; + localparam SR_PACKETS = SR_TX_RESPONDER + 1; + + localparam SR_PHASE_INC = SR_TX_DSP + 0; + localparam SR_SCALE_FACTOR = SR_TX_DSP + 1; + localparam SR_INTERP = SR_TX_DSP + 2; + + localparam SR_ERROR_POLICY = SR_TX_CTRL + 0; + + + reg clk = 0; + reg reset = 1; + + always #10 clk = ~clk; + + initial $dumpfile("new_tx_tb.vcd"); + initial $dumpvars(0,new_tx_tb); + wire run, strobe; + + initial + begin + #1000 reset = 0; + #30000; + $finish; + end + + reg [63:0] tdata; + reg tlast; + reg tvalid = 1'b0; + wire tready; + + wire [63:0] i_tdata; + wire i_tlast, i_tvalid, i_tready; + + reg [7:0] set_addr; + reg [31:0] set_data; + reg set_stb = 1'b0; + + reg [63:0] vita_time; + wire [31:0] sample; + + wire [175:0] sample_tdata; + wire sample_tready, sample_tvalid; + + wire [11:0] seqnum; + wire [63:0] error_code; + wire [31:0] sid; + + reg [31:0] samp0, samp1; + + reg [11:0] seqno; + + wire ack_or_error, packet_consumed; + + + // + // Task Libaray + // + task write_setting_bus; + input [7:0] address; + input [31:0] data; + + begin + + @(negedge clk); + set_stb = 1'b0; + set_addr = 8'h0; + set_data = 32'h0; + @(negedge clk); + set_stb = 1'b1; + set_addr = address; + set_data = data; + @(negedge clk); + set_stb = 1'b0; + set_addr = 8'h0; + set_data = 32'h0; + + end + endtask // write_setting_bus + + + task send_ramp; + input [31:0] burst_count; + input [31:0] len; + input [31:0] sid; + + reg [31:0] data; + + begin + seqno = 0; + data = 0; + send_packet(len, data, 0, seqno, (burst_count==1), 0, sid); + seqno = seqno + 1; + data <= data + len; + + if(burst_count > 2) + repeat (burst_count - 2) + begin + send_packet(len, data, 64'h0, seqno, 0, 0, sid); + seqno = seqno + 1; + data <= data + len; + end + if(burst_count > 1) + send_packet(len, data, 64'h0, seqno, 1, 0, sid); + end + endtask // send_ramp + + + task send_dc; + input [31:0] burst_count; + input [31:0] len; + input [31:0] sid; + + reg [31:0] data; + + begin + seqno = 0; + data = 1 << 14; + send_packet(len, data, 0, seqno, (burst_count==1), 0, sid); + seqno = seqno + 1; + + + if(burst_count > 2) + repeat (burst_count - 2) + begin + send_packet(len, data, 64'h0, seqno, 0, 0, sid); + seqno = seqno + 1; + + end + if(burst_count > 1) + send_packet(len, data, 64'h0, seqno, 1, 0, sid); + end + endtask // send_ramp + + task send_burst; + input [31:0] burst_count; + input [31:0] len; + input [31:0] start_data; + input [63:0] send_time; + input [11:0] start_seqnum; + input send_at; + input [31:0] sid; + + begin + seqno = start_seqnum; + send_packet(len, {seqno,start_data[15:0]}, send_time, seqno, (burst_count==1), send_at, sid); + seqno = seqno + 1; + + if(burst_count > 2) + repeat (burst_count - 2) + begin + send_packet(len, {seqno,start_data[15:0]}, 64'h0, seqno, 0, 0, sid); + seqno = seqno + 1; + end + if(burst_count > 1) + send_packet(len, {seqno,start_data[15:0]}, 64'h0, seqno, 1, 0, sid); + end + endtask // send_burst + + task send_burst_with_seqid_error; + input [31:0] burst_count; + input [31:0] len; + input [31:0] start_data; + input [63:0] send_time; + input [11:0] start_seqnum; + input send_at; + input [31:0] sid; + + + begin + seqno = start_seqnum; + send_packet(len, {seqno,start_data[15:0]}, send_time, seqno, (burst_count==1), send_at, sid); + seqno = seqno + 1; + + if(burst_count > 2) + repeat (burst_count - 2) + begin + // Add a SeqID error in the middle of the packet burst + if (seqno == (start_seqnum + burst_count/2)) + seqno = seqno + 1; + send_packet(len, {seqno,start_data[15:0]}, 64'h0, seqno, 0, 0, sid); + seqno = seqno + 1; + end + if(burst_count > 1) + send_packet(len, {seqno,start_data[15:0]}, 64'h0, seqno, 1, 0, sid); + end + endtask // send_burst + + task send_packet; + input [31:0] len; + input [31:0] start_data; + input [63:0] send_time; + input [11:0] pkt_seqnum; + input eob; + input send_at; + input [31:0] sid; + + begin + // Send a packet + samp0 <= start_data; + samp1 <= start_data + 1; + @(posedge clk); + + tlast <= 0; + tdata <= { 1'b0, 1'b0 /*trl*/, send_at, eob, pkt_seqnum, len[15:0]+16'd2+send_at+send_at, sid }; + tvalid <= 1; + @(posedge clk) + if(send_at) + begin + tdata <= send_time; + @(posedge clk); + end + + repeat (len[31:1]+len[0]-1) + begin + tdata <= {samp0,samp1}; + samp0 <= samp0 + 2; + samp1 <= samp1 + 2; + @(posedge clk); + end + + tdata <= {samp0,samp1}; + tlast <= 1'b1; + @(posedge clk); + tvalid <= 0; + @(posedge clk); + end + endtask // send_packet + +`ifdef SIM_SCRIPT + // Load simulation script from local directory +`include "simulation_script.v" + +`else + initial + begin + tvalid <= 1'b0; + while(reset) + @(posedge clk); + write_setting_bus(SR_ERROR_POLICY,32'h4); + write_setting_bus(SR_PACKETS,32'h8000_0002); + + write_setting_bus(SR_INTERP,32'h1); + + send_burst(2/*count*/,5/*len*/,32'hA000_0000/*start*/,64'h100/*time*/,12'h000/*seqnum*/,1/*sendat*/, 32'hDEADBEEF/*sid*/); + //send_burst(3/*count*/,6/*len*/,32'hB000_0000/*start*/,64'h0/*time*/,12'h004/*seqnum*/,0/*sendat*/, 32'hDEADBEEF/*sid*/); + + //Intra burst seq_id error + send_burst_with_seqid_error(8/*count*/,10/*len*/,32'hC000_0000/*start*/,64'h200/*time*/,12'h002/*seqnum*/,1/*sendat*/, 32'hDEADBEEF/*sid*/); + + + // Inter burst sequence error + send_burst(2/*count*/,10/*len*/,32'hC000_0000/*start*/,64'h300/*time*/,12'h015/*seqnum*/,1/*sendat*/, 32'hDEADBEEF/*sid*/); + + // Single Packet burst, timed + //send_packet(3/*count*/,32'hA000_0000/*data*/,64'h100/*time*/,1/*SEQ*/,1/*EOP*/,1/*eob*/,1/*timed*/,0/*odd*/); + + // 2 packet burst, timed + //send_packet(3/*count*/,32'hB000_0000/*data*/,64'h200/*time*/,2/*SEQ*/,1/*EOP*/,0/*eob*/,1/*timed*/,0/*odd*/); + //send_packet(3/*count*/,32'hC000_0000/*data*/,64'h0/*time*/,3/*SEQ*/,1/*EOP*/,1/*eob*/,0/*timed*/,0/*odd*/); + + // single odd packet + //send_packet(3/*count*/,32'h0A00_0000/*data*/,64'h300/*time*/,4/*SEQ*/,1/*EOP*/,1/*eob*/,1/*timed*/,1/*odd*/); + + // 2 packet burst, timed, odd + //send_packet(3/*count*/,32'hD000_0000/*data*/,64'h400/*time*/,5/*SEQ*/,1/*EOP*/,0/*eob*/,1/*timed*/,1/*odd*/); + //send_packet(3/*count*/,32'hE000_0000/*data*/,64'd0/*time*/,6/*SEQ*/,1/*EOP*/,1/*eob*/,0/*timed*/,1/*odd*/); + + // 2 packet burst, untimed, no eob set + //send_packet(3/*count*/,32'hF000_0000/*data*/,64'd0/*time*/,7/*SEQ*/,1/*EOP*/,0/*eob*/,0/*timed*/,0/*odd*/); + //send_packet(3/*count*/,32'h9000_0000/*data*/,64'd0/*time*/,8/*SEQ*/,1/*EOP*/,0/*eob*/,0/*timed*/,0/*odd*/); + + // single packet late + //send_packet(3/*count*/,32'hD000_0000/*data*/,64'h0/*time*/,4/*SEQ*/,1/*EOP*/,1/*eob*/,1/*timed*/,1/*odd*/); + + end +`endif // !`ifdef SIM_SCRIPT + + always @(posedge clk) + if(reset) + vita_time <= 0; + else + vita_time <= vita_time + 1; + + axi_fifo #(.WIDTH(65)) axi_fifo_short + (.clk(clk), .reset(reset), .clear(1'b0), + .i_tdata({tlast,tdata}), .i_tvalid(tvalid), .i_tready(tready), + .o_tdata({i_tlast,i_tdata}), .o_tvalid(i_tvalid), .o_tready(i_tready)); + + new_tx_deframer new_tx_deframer + (.clk(clk), .reset(reset), .clear(1'b0), + .i_tdata(i_tdata), .i_tlast(i_tlast), .i_tvalid(i_tvalid), .i_tready(i_tready), + .sample_tdata(sample_tdata), .sample_tvalid(sample_tvalid), .sample_tready(sample_tready)); + + new_tx_control #(.BASE(SR_TX_CTRL)) new_tx_control + (.clk(clk), .reset(reset), .clear(1'b0), + .set_stb(set_stb), .set_addr(set_addr), .set_data(set_data), + + .vita_time(vita_time), + .ack_or_error(ack_or_error), .packet_consumed(packet_consumed), + .seqnum(seqnum), .error_code(error_code), .sid(sid), + + .sample_tdata(sample_tdata), .sample_tvalid(sample_tvalid), .sample_tready(sample_tready), + + .sample(sample), .run(run), .strobe(strobe), + .debug() + ); + + wire [63:0] o_tdata; + wire o_tlast, o_tvalid, o_tready; + assign o_tready = 1; + + tx_responder #(.BASE(SR_TX_RESPONDER)) tx_responder + (.clk(clk), .reset(reset), .clear(1'b0), + .set_stb(set_stb), .set_addr(set_addr), .set_data(set_data), + .ack_or_error(ack_or_error), .packet_consumed(packet_consumed), + .seqnum(seqnum), .error_code(error_code), .sid(sid), + .vita_time(vita_time), + .o_tdata(o_tdata), .o_tlast(o_tlast), .o_tvalid(o_tvalid), .o_tready(o_tready)); + + always @(posedge clk) + if(o_tvalid & o_tready) + $display("\t\t\t\t\tRESP %x\t%x",o_tdata,o_tlast); + + always @(posedge clk) + if(~reset) + begin + if(strobe & run) + $display("%x\t%x", vita_time, sample); + if(strobe & ~run) $display("Spurious Strobe at time %x",vita_time); + if(packet_consumed) $display("CONSUMED %x", seqnum); + if(ack_or_error) + if(error_code[63:32] == 1) + $display("ACK -- SEQNUM %x", error_code[31:0]); + else + $display("ERROR -- SEQNUM %x ERRCODE %x", error_code[31:0],error_code[63:32]); + end + + wire [23:0] tx_fe_i, tx_fe_q; + + duc_chain #(.BASE(SR_TX_DSP), .DSPNO(0), .WIDTH(24)) duc_chain + (.clk(clk), .rst(reset), .clr(1'b0), + .set_stb(set_stb),.set_addr(set_addr),.set_data(set_data), + .tx_fe_i(tx_fe_i),.tx_fe_q(tx_fe_q), + .sample(sample), .run(run), .strobe(strobe), + .debug() ); + +endmodule // new_tx_tb |