// -*- verilog -*- // // USRP - Universal Software Radio Peripheral // // Copyright (C) 2007 Corgan Enterprises LLC // // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation; either version 2 of the License, or // (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 51 Franklin Street, Boston, MA 02110-1301 USA // `timescale 1ns/100ps `include "../lib/sounder.v" `define FR_MODE 7'd64 `define bmFR_MODE_RESET 32'h0001 `define bmFR_MODE_TX 32'h0002 `define bmFR_MODE_RX 32'h0004 `define bmFR_MODE_LP 32'h0008 `define FR_DEGREE 7'd65 `define FR_AMPL 7'd66 module sounder_tb; // System bus reg clk; reg rst; reg ena; // Configuration bus reg [6:0] saddr; reg [31:0] sdata; reg s_strobe; // DAC bus wire tx_strobe; wire [13:0] tx_dac_i; wire [13:0] tx_dac_q; // ADC bus reg [15:0] rx_adc_i; reg [15:0] rx_adc_q; // FIFO bus wire fifo_strobe; wire [15:0] fifo_i; wire [15:0] fifo_q; // Configuration shadow registers reg [31:0] mode; reg [31:0] degree; sounder uut (.clk_i(clk),.saddr_i(saddr),.sdata_i(sdata),.s_strobe_i(s_strobe), .tx_strobe_o(tx_strobe),.tx_dac_i_o(tx_dac_i),.tx_dac_q_o(tx_dac_q), .rx_strobe_o(fifo_strobe),.rx_adc_i_i(rx_adc_i),.rx_adc_q_i(rx_adc_q), .rx_imp_i_o(fifo_i),.rx_imp_q_o(fifo_q)); // Start up initialization initial begin clk = 0; rst = 0; ena = 0; saddr = 0; sdata = 0; s_strobe = 0; rx_adc_i = 0; rx_adc_q = 0; mode = 0; degree = 0; @(posedge clk); rst = 1; @(posedge clk); rst = 0; @(posedge clk); ena = 1; end always #5 clk <= ~clk; initial begin $monitor($time, " c=%b r=%b phs=%d txs=%b rfs=%b rxs=%b sms=%b pn=%b pnr=%b prd=%x sum=%x tot=%x", clk, rst, uut.master.phase, uut.tx_strobe_o, uut.ref_strobe, uut.rx_strobe_o, uut.sum_strobe, uut.transmitter.pn, uut.receiver.pn_ref, uut.receiver.prod_i, uut.receiver.sum_i, uut.receiver.total_i); $dumpfile("sounder_tb.vcd"); $dumpvars(0, sounder_tb); end // Test tasks task write_cfg_register; input [6:0] regno; input [31:0] value; begin @(posedge clk); saddr <= #5 regno; sdata <= #5 value; s_strobe <= #5 1'b1; @(posedge clk); s_strobe <= #5 0; end endtask // write_cfg_register // Application reset line task set_reset; input reset; begin mode = reset ? (mode | `bmFR_MODE_RESET) : (mode & ~`bmFR_MODE_RESET); write_cfg_register(`FR_MODE, mode); end endtask // reset // Set the PN code degree task set_degree; input [5:0] degree; begin write_cfg_register(`FR_DEGREE, degree); end endtask // set_degree // Set the PN amplitude task set_amplitude; input [13:0] ampl; begin write_cfg_register(`FR_AMPL, ampl); end endtask // set_ampl // Turn on or off the transmitter task enable_tx; input tx; begin mode = tx ? (mode | `bmFR_MODE_TX) : (mode & ~`bmFR_MODE_TX); write_cfg_register(`FR_MODE, mode); end endtask // enable_tx // Turn on or off the receiver task enable_rx; input rx; begin mode = rx ? (mode | `bmFR_MODE_RX) : (mode & ~`bmFR_MODE_RX); write_cfg_register(`FR_MODE, mode); end endtask // enable_rx // Turn on or off digital loopback task enable_lp; input lp; begin mode = lp ? (mode | `bmFR_MODE_LP) : (mode & ~`bmFR_MODE_LP); write_cfg_register(`FR_MODE, mode); end endtask // enable_lp // Test transmitter functionality task test_tx; input [5:0] degree; input [31:0] test_len; begin #20 set_reset(1); #20 set_degree(degree); #20 set_amplitude(14'h1000); #20 enable_tx(1); #20 enable_rx(0); #20 enable_lp(0); #20 set_reset(0); #(test_len); end endtask // test_tx // Test loopback functionality task test_lp; input [5:0] degree; input [31:0] test_len; begin #20 set_reset(1); #20 set_degree(degree); #20 enable_tx(1); #20 enable_rx(1); #20 enable_lp(1); #20 set_reset(0); #(test_len); end endtask // test_lp // Test receiver only functionality task test_rx; input [5:0] degree; input [31:0] test_len; begin #20 set_reset(1); #20 set_degree(degree); #20 enable_tx(0); #20 enable_rx(1); #20 enable_lp(0); #20 set_reset(0); #(test_len); end endtask // test_rx // Execute tests initial begin #20 test_tx(8,255*20); #20 test_lp(8,255*255*20*5); //#20 test_rx(8,255*255*20*5); #500 $finish; end endmodule