6a9eff0ea0a1f99d5bcd9cd139a9d0f18aa2e06a
[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/1ps
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
34 module sounder_tb;
35
36    // System bus
37    reg         clk;
38    reg         rst;
39    reg         ena;
40    
41    // Configuration bus
42    reg [6:0]   saddr;
43    reg [31:0]  sdata;
44    reg         s_strobe;
45
46    // DAC bus
47    reg         tx_strobe;
48    wire [13:0] tx_dac_i;
49    wire [13:0] tx_dac_q;
50
51    // ADC bus
52    reg         rx_strobe;
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_i(tx_strobe),.tx_dac_i_o(tx_dac_i),.tx_dac_q_o(tx_dac_q),
68       .rx_strobe_i(rx_strobe),.rx_adc_i_i(rx_adc_i),.rx_adc_q_i(rx_adc_q),
69       .rx_strobe_o(fifo_strobe),.rx_imp_i_o(fifo_i),.rx_imp_q_o(fifo_q));
70
71    // Drive tx_strobe @ half clock rate
72    always @(posedge clk)
73      tx_strobe <= ~tx_strobe;
74    
75    // Start up initialization
76    initial
77      begin
78         clk = 0;
79         rst = 0;
80         ena = 0;
81         saddr = 0;
82         sdata = 0;
83         s_strobe = 0;
84         tx_strobe = 0;
85         rx_strobe = 1;
86         rx_adc_i = 0;
87         rx_adc_q = 0;
88         mode = 0;
89         degree = 0;
90         
91         @(posedge clk);
92         rst = 1;
93         @(posedge clk);
94         rst = 0;
95         @(posedge clk);
96         ena = 1;
97      end
98    
99    always
100      #5 clk <= ~clk;
101    
102    initial
103      begin
104         $monitor($time, " clk=%b rst=%b tx_strobe=%b fifo_strobe=%b phs=%x pn_o=%b pn_ref=%b fifo_i=%x fifo_q=", 
105                  clk, uut.reset, tx_strobe, fifo_strobe, uut.receiver.phase_strobe.count_o,
106                  uut.transmitter.pn, uut.receiver.pn_ref, fifo_i, fifo_q);
107         $dumpfile("sounder_tb.vcd");
108         $dumpvars(0, sounder_tb);
109      end
110
111    // Test tasks
112    task write_cfg_register;
113       input [6:0]  regno;
114       input [31:0] value;
115       
116       begin
117          @(posedge clk);
118          saddr <= regno;
119          sdata <= value;
120          s_strobe <= 1'b1;
121          @(posedge clk);
122          s_strobe <= 0;
123       end
124    endtask // write_cfg_register
125    
126    // Application reset line
127    task set_reset;
128       input reset;
129       
130       begin
131          mode = reset ? (mode | `bmFR_MODE_RESET) : (mode & ~`bmFR_MODE_RESET);
132          write_cfg_register(`FR_MODE, mode);
133       end
134    endtask // reset
135    
136    // Set the PN code degree
137    task set_degree;
138       input [5:0] degree;
139       begin
140          write_cfg_register(`FR_DEGREE, degree);
141       end
142    endtask // set_degree
143    
144    // Turn on or off the transmitter
145    task enable_tx;
146       input tx;
147
148       begin
149          mode = tx ? (mode | `bmFR_MODE_TX) : (mode & ~`bmFR_MODE_TX);
150          write_cfg_register(`FR_MODE, mode);
151       end
152    endtask // enable_tx
153
154    // Turn on or off the receiver
155    task enable_rx;
156       input rx;
157
158       begin
159          mode = rx ? (mode | `bmFR_MODE_RX) : (mode & ~`bmFR_MODE_RX);
160          write_cfg_register(`FR_MODE, mode);
161       end
162    endtask // enable_rx
163
164
165    // Turn on or off digital loopback
166    task enable_lp;
167       input lp;
168
169       begin
170          mode = lp ? (mode | `bmFR_MODE_LP) : (mode & ~`bmFR_MODE_LP);
171          write_cfg_register(`FR_MODE, mode);
172       end
173    endtask // enable_lp
174    
175    // Test transmitter functionality
176    task test_tx;
177       input [5:0] degree;
178       
179       begin
180          #20 set_reset(1);
181          #20 set_degree(degree);
182          #20 enable_tx(1);
183          #20 set_reset(0);
184          #(uut.len*20);         // One PN code period
185
186       end
187    endtask // test_tx
188    
189    // Test loopback functionality
190    task test_lp;
191       input [5:0] degree;
192       
193       begin
194          #20 set_reset(1);
195          #20 set_degree(degree);
196          #20 enable_tx(1);
197          #20 enable_rx(1);
198          #20 enable_lp(1);
199          #20 set_reset(0);
200          #((uut.len+1)*uut.len*20*2);
201       end
202    endtask // test_lp
203    
204    // Execute tests
205    initial
206      begin
207         // #20 test_tx(12);
208         #20 test_lp(12);
209         #100 $finish;
210      end
211 endmodule
212