Imported Upstream version 3.2.2
[debian/gnuradio] / gr-sounder / src / fpga / tb / sounder_tb.v
1 // -*- verilog -*-
2 //
3 //  USRP - Universal Software Radio Peripheral
4 //
5 //  Copyright (C) 2007 Corgan Enterprises LLC
6 //
7 //  This program is free software; you can redistribute it and/or modify
8 //  it under the terms of the GNU General Public License as published by
9 //  the Free Software Foundation; either version 2 of the License, or
10 //  (at your option) any later version.
11 //
12 //  This program is distributed in the hope that it will be useful,
13 //  but WITHOUT ANY WARRANTY; without even the implied warranty of
14 //  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 //  GNU General Public License for more details.
16 //
17 //  You should have received a copy of the GNU General Public License
18 //  along with this program; if not, write to the Free Software
19 //  Foundation, Inc., 51 Franklin Street, Boston, MA  02110-1301  USA
20 //
21
22 `timescale 1ns/100ps
23
24 `include "../lib/sounder.v"
25
26 `define FR_MODE                 7'd64
27 `define bmFR_MODE_RESET         32'h0001
28 `define bmFR_MODE_TX            32'h0002
29 `define bmFR_MODE_RX            32'h0004
30 `define bmFR_MODE_LP            32'h0008
31
32 `define FR_DEGREE               7'd65
33 `define FR_AMPL                 7'd66
34
35 module sounder_tb;
36
37    // System bus
38    reg         clk;
39    reg         rst;
40    reg         ena;
41    
42    // Configuration bus
43    reg [6:0]   saddr;
44    reg [31:0]  sdata;
45    reg         s_strobe;
46
47    // DAC bus
48    wire        tx_strobe;
49    wire [13:0] tx_dac_i;
50    wire [13:0] tx_dac_q;
51
52    // ADC bus
53    reg [15:0]  rx_adc_i;
54    reg [15:0]  rx_adc_q;
55    
56    // FIFO bus
57    wire        fifo_strobe;
58    wire [15:0] fifo_i;
59    wire [15:0] fifo_q;
60    
61    // Configuration shadow registers
62    reg [31:0]  mode;
63    reg [31:0]  degree;
64    
65    sounder uut
66      (.clk_i(clk),.saddr_i(saddr),.sdata_i(sdata),.s_strobe_i(s_strobe),
67       .tx_strobe_o(tx_strobe),.tx_dac_i_o(tx_dac_i),.tx_dac_q_o(tx_dac_q),
68       .rx_strobe_o(fifo_strobe),.rx_adc_i_i(rx_adc_i),.rx_adc_q_i(rx_adc_q),
69       .rx_imp_i_o(fifo_i),.rx_imp_q_o(fifo_q));
70
71    // Start up initialization
72    initial
73      begin
74         clk = 0;
75         rst = 0;
76         ena = 0;
77         saddr = 0;
78         sdata = 0;
79         s_strobe = 0;
80         rx_adc_i = 0;
81         rx_adc_q = 0;
82         mode = 0;
83         degree = 0;
84         
85         @(posedge clk);
86         rst = 1;
87         @(posedge clk);
88         rst = 0;
89         @(posedge clk);
90         ena = 1;
91      end
92    
93    always
94      #5 clk <= ~clk;
95    
96    initial
97      begin
98         $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",
99                  clk, rst, uut.master.phase, uut.tx_strobe_o, uut.ref_strobe, uut.rx_strobe_o, 
100                  uut.sum_strobe, uut.transmitter.pn, uut.receiver.pn_ref, uut.receiver.prod_i,
101                  uut.receiver.sum_i, uut.receiver.total_i);
102
103         $dumpfile("sounder_tb.vcd");
104         $dumpvars(0, sounder_tb);
105      end
106
107    // Test tasks
108    task write_cfg_register;
109       input [6:0]  regno;
110       input [31:0] value;
111       
112       begin
113          @(posedge clk);
114          saddr <= #5 regno;
115          sdata <= #5 value;
116          s_strobe <= #5 1'b1;
117          @(posedge clk);
118          s_strobe <= #5 0;
119       end
120    endtask // write_cfg_register
121    
122    // Application reset line
123    task set_reset;
124       input reset;
125       
126       begin
127          mode = reset ? (mode | `bmFR_MODE_RESET) : (mode & ~`bmFR_MODE_RESET);
128          write_cfg_register(`FR_MODE, mode);
129       end
130    endtask // reset
131    
132    // Set the PN code degree
133    task set_degree;
134       input [5:0] degree;
135       begin
136          write_cfg_register(`FR_DEGREE, degree);
137       end
138    endtask // set_degree
139    
140    // Set the PN amplitude
141    task set_amplitude;
142       input [13:0] ampl;
143       begin
144          write_cfg_register(`FR_AMPL, ampl);
145       end
146    endtask // set_ampl
147    
148    // Turn on or off the transmitter
149    task enable_tx;
150       input tx;
151
152       begin
153          mode = tx ? (mode | `bmFR_MODE_TX) : (mode & ~`bmFR_MODE_TX);
154          write_cfg_register(`FR_MODE, mode);
155       end
156    endtask // enable_tx
157
158    // Turn on or off the receiver
159    task enable_rx;
160       input rx;
161
162       begin
163          mode = rx ? (mode | `bmFR_MODE_RX) : (mode & ~`bmFR_MODE_RX);
164          write_cfg_register(`FR_MODE, mode);
165       end
166    endtask // enable_rx
167
168
169    // Turn on or off digital loopback
170    task enable_lp;
171       input lp;
172
173       begin
174          mode = lp ? (mode | `bmFR_MODE_LP) : (mode & ~`bmFR_MODE_LP);
175          write_cfg_register(`FR_MODE, mode);
176       end
177    endtask // enable_lp
178    
179    // Test transmitter functionality
180    task test_tx;
181       input [5:0] degree;
182       input [31:0] test_len;
183       
184       begin
185          #20 set_reset(1);
186          #20 set_degree(degree);
187          #20 set_amplitude(14'h1000);
188          #20 enable_tx(1);
189          #20 enable_rx(0);
190          #20 enable_lp(0);
191          #20 set_reset(0);
192          #(test_len);
193       end
194    endtask // test_tx
195    
196    // Test loopback functionality
197    task test_lp;
198       input [5:0] degree;
199       input [31:0] test_len;
200       
201       begin
202          #20 set_reset(1);
203          #20 set_degree(degree);
204          #20 enable_tx(1);
205          #20 enable_rx(1);
206          #20 enable_lp(1);
207          #20 set_reset(0);
208          #(test_len);
209       end
210    endtask // test_lp
211    
212    // Test receiver only functionality
213    task test_rx;
214       input [5:0] degree;
215       input [31:0] test_len;
216       
217       begin
218          #20 set_reset(1);
219          #20 set_degree(degree);
220          #20 enable_tx(0);
221          #20 enable_rx(1);
222          #20 enable_lp(0);
223          #20 set_reset(0);
224          #(test_len);
225       end
226    endtask // test_rx
227    
228    // Execute tests
229    initial
230      begin
231         #20 test_tx(8,255*20);
232         #20 test_lp(8,255*255*20*5);
233         //#20 test_rx(8,255*255*20*5);
234         #500 $finish;
235      end
236
237 endmodule
238