1//
2// Copyright 2011 Ettus Research LLC
3//
4// This program is free software: you can redistribute it and/or modify
5// it under the terms of the GNU General Public License as published by
6// the Free Software Foundation, either version 3 of the License, or
7// (at your option) any later version.
8//
9// This program is distributed in the hope that it will be useful,
10// but WITHOUT ANY WARRANTY; without even the implied warranty of
11// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12// GNU General Public License for more details.
13//
14// You should have received a copy of the GNU General Public License
15// along with this program.  If not, see <http://www.gnu.org/licenses/>.
16//
17
18module halfband_tb( ) ;
19
20    // Parameters for instantiation
21    parameter               clocks  = 2 ; // Number of clocks per input
22    parameter               decim   = 0 ; // Sets the filter to decimate
23    parameter               rate    = 2 ; // Sets the decimation rate
24
25    reg                     clock ;
26    reg                     reset ;
27    reg                     enable ;
28    reg                     strobe_in ;
29    reg     signed  [17:0]  data_in ;
30    wire                    strobe_out ;
31    wire    signed  [17:0]  data_out ;
32
33    // Setup the clock
34    initial clock = 1'b0 ;
35    always #5 clock <= ~clock ;
36
37    // Come out of reset after a while
38    initial reset = 1'b1 ;
39    initial #100 reset = 1'b0 ;
40
41    // Enable the entire system
42    initial enable = 1'b1 ;
43
44    // Instantiate UUT
45    halfband_ideal
46      #(
47        .decim      ( decim         ),
48        .rate       ( rate          )
49      ) uut(
50        .clock      ( clock         ),
51        .reset      ( reset         ),
52        .enable     ( enable        ),
53        .strobe_in  ( strobe_in     ),
54        .data_in    ( data_in       ),
55        .strobe_out ( strobe_out    ),
56        .data_out   ( data_out      )
57      ) ;
58
59    integer i, ri, ro, infile, outfile ;
60
61    // Setup file IO
62    initial begin
63        infile = $fopen("input.dat","r") ;
64        outfile = $fopen("output.dat","r") ;
65        $timeformat(-9, 2, " ns", 10) ;
66    end
67
68    reg                 endofsim ;
69    reg signed  [17:0]  compare ;
70    integer             noe ;
71    initial             noe = 0 ;
72
73    initial begin
74        // Initialize inputs
75        strobe_in <= 1'd0 ;
76        data_in <= 18'd0 ;
77
78        // Wait for reset to go away
79        @(negedge reset) #0 ;
80
81        // While we're still simulating ...
82        while( !endofsim ) begin
83
84            // Write the input from the file or 0 if EOF...
85            @( posedge clock ) begin
86                #1 ;
87                strobe_in <= 1'b1 ;
88                if( !$feof(infile) )
89                    ri = $fscanf( infile, "%d", data_in ) ;
90                else
91                    data_in <= 18'd0 ;
92            end
93
94            // Clocked in - set the strobe to 0 if the number of
95            // clocks per sample is greater than 1
96            if( clocks > 1 ) begin
97                @(posedge clock) begin
98                    strobe_in <= 1'b0  ;
99                end
100
101                // Wait for the specified number of cycles
102                for( i = 0 ; i < (clocks-2) ; i = i + 1 ) begin
103                    @(posedge clock) #1 ;
104                end
105            end
106        end
107
108        // Print out the number of errors that occured
109        if( noe )
110            $display( "FAILED: %d errors during simulation", noe ) ;
111        else
112            $display( "PASSED: Simulation successful" ) ;
113
114        $stop ;
115    end
116
117    // Output comparison of simulated values versus known good values
118    always @ (posedge clock) begin
119        if( reset )
120            endofsim <= 1'b0 ;
121        else begin
122            if( !$feof(outfile) ) begin
123                if( strobe_out ) begin
124                    ro = $fscanf( outfile, "%d\n", compare ) ;
125                    if( compare != data_out ) begin
126                        $display( "%t: %d != %d", $realtime, data_out, compare ) ;
127                        noe = noe + 1 ;
128                    end
129                end
130            end else begin
131                // Signal end of simulation when no more outputs
132                endofsim <= 1'b1 ;
133            end
134        end
135    end
136
137endmodule
138