OpenCores
URL https://opencores.org/ocsvn/qaz_libs/qaz_libs/trunk

Subversion Repositories qaz_libs

[/] [qaz_libs/] [trunk/] [basal/] [src/] [PRBS/] [cf_pnmon.v] - Blame information for rev 49

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 34 qaztronic
// ***************************************************************************
2
// ***************************************************************************
3
// Copyright 2011(c) Analog Devices, Inc.
4
// 
5
// All rights reserved.
6
// 
7
// Redistribution and use in source and binary forms, with or without modification,
8
// are permitted provided that the following conditions are met:
9
//     - Redistributions of source code must retain the above copyright
10
//       notice, this list of conditions and the following disclaimer.
11
//     - Redistributions in binary form must reproduce the above copyright
12
//       notice, this list of conditions and the following disclaimer in
13
//       the documentation and/or other materials provided with the
14
//       distribution.
15
//     - Neither the name of Analog Devices, Inc. nor the names of its
16
//       contributors may be used to endorse or promote products derived
17
//       from this software without specific prior written permission.
18
//     - The use of this software may or may not infringe the patent rights
19
//       of one or more patent holders.  This license does not release you
20
//       from the requirement that you obtain separate licenses from these
21
//       patent holders to use this software.
22
//     - Use of the software either in source or binary form, must be run
23
//       on or directly connected to an Analog Devices Inc. component.
24
//    
25
// THIS SOFTWARE IS PROVIDED BY ANALOG DEVICES "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
26
// INCLUDING, BUT NOT LIMITED TO, NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS FOR A
27
// PARTICULAR PURPOSE ARE DISCLAIMED.
28
//
29
// IN NO EVENT SHALL ANALOG DEVICES BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
30
// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, INTELLECTUAL PROPERTY
31
// RIGHTS, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR 
32
// BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
33
// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF 
34
// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
35
// ***************************************************************************
36
// ***************************************************************************
37
// ***************************************************************************
38
// ***************************************************************************
39
// PN monitors
40
 
41
`timescale 1ns/100ps
42
 
43
module cf_pnmon (
44
 
45
  // adc interface
46
 
47
  adc_clk,
48
  adc_data,
49
 
50
  // pn out of sync and error
51
 
52
  adc_pn_oos,
53
  adc_pn_err,
54
 
55
  // processor interface PN9 (0x0), PN23 (0x1)
56
 
57
  up_pn_type);
58
 
59
  // adc interface
60
 
61
  input           adc_clk;
62
  input   [13:0]  adc_data;
63
 
64
  // pn out of sync and error
65
 
66
  output          adc_pn_oos;
67
  output          adc_pn_err;
68
 
69
  // processor interface PN9 (0x0), PN23 (0x1)
70
 
71
  input           up_pn_type;
72
 
73
  reg             adc_pn_type_m1 = 'd0;
74
  reg             adc_pn_type_m2 = 'd0;
75
  reg             adc_pn_type = 'd0;
76
  reg             adc_pn_en = 'd0;
77
  reg     [13:0]  adc_data_d = 'd0;
78
  reg     [27:0]  adc_pn_data = 'd0;
79
  reg             adc_pn_en_d = 'd0;
80
  reg             adc_pn_match = 'd0;
81
  reg     [ 6:0]  adc_pn_oos_count = 'd0;
82
  reg             adc_pn_oos = 'd0;
83
  reg     [ 4:0]  adc_pn_err_count = 'd0;
84
  reg             adc_pn_err = 'd0;
85
 
86
  wire    [27:0]  adc_pn_data_in_s;
87
  wire            adc_pn_match0_s;
88
  wire            adc_pn_match1_s;
89
  wire            adc_pn_match2_s;
90
  wire            adc_pn_match_s;
91
  wire    [27:0]  adc_pn_data_s;
92
  wire            adc_pn_err_s;
93
 
94
  // PN23 function
95
 
96
  function [27:0] pn23;
97
    input [27:0] din;
98
    reg   [27:0] dout;
99
    begin
100
      dout[27] = din[22] ^ din[17];
101
      dout[26] = din[21] ^ din[16];
102
      dout[25] = din[20] ^ din[15];
103
      dout[24] = din[19] ^ din[14];
104
      dout[23] = din[18] ^ din[13];
105
      dout[22] = din[17] ^ din[12];
106
      dout[21] = din[16] ^ din[11];
107
      dout[20] = din[15] ^ din[10];
108
      dout[19] = din[14] ^ din[ 9];
109
      dout[18] = din[13] ^ din[ 8];
110
      dout[17] = din[12] ^ din[ 7];
111
      dout[16] = din[11] ^ din[ 6];
112
      dout[15] = din[10] ^ din[ 5];
113
      dout[14] = din[ 9] ^ din[ 4];
114
      dout[13] = din[ 8] ^ din[ 3];
115
      dout[12] = din[ 7] ^ din[ 2];
116
      dout[11] = din[ 6] ^ din[ 1];
117
      dout[10] = din[ 5] ^ din[ 0];
118
      dout[ 9] = din[ 4] ^ din[22] ^ din[17];
119
      dout[ 8] = din[ 3] ^ din[21] ^ din[16];
120
      dout[ 7] = din[ 2] ^ din[20] ^ din[15];
121
      dout[ 6] = din[ 1] ^ din[19] ^ din[14];
122
      dout[ 5] = din[ 0] ^ din[18] ^ din[13];
123
      dout[ 4] = din[22] ^ din[12];
124
      dout[ 3] = din[21] ^ din[11];
125
      dout[ 2] = din[20] ^ din[10];
126
      dout[ 1] = din[19] ^ din[ 9];
127
      dout[ 0] = din[18] ^ din[ 8];
128
      pn23 = dout;
129
    end
130
  endfunction
131
 
132
  // PN9 function
133
 
134
  function [27:0] pn9;
135
    input [27:0] din;
136
    reg   [27:0] dout;
137
    begin
138
      dout[27] = din[ 8] ^ din[ 4];
139
      dout[26] = din[ 7] ^ din[ 3];
140
      dout[25] = din[ 6] ^ din[ 2];
141
      dout[24] = din[ 5] ^ din[ 1];
142
      dout[23] = din[ 4] ^ din[ 0];
143
      dout[22] = din[ 3] ^ din[ 8] ^ din[ 4];
144
      dout[21] = din[ 2] ^ din[ 7] ^ din[ 3];
145
      dout[20] = din[ 1] ^ din[ 6] ^ din[ 2];
146
      dout[19] = din[ 0] ^ din[ 5] ^ din[ 1];
147
      dout[18] = din[ 8] ^ din[ 0];
148
      dout[17] = din[ 7] ^ din[ 8] ^ din[ 4];
149
      dout[16] = din[ 6] ^ din[ 7] ^ din[ 3];
150
      dout[15] = din[ 5] ^ din[ 6] ^ din[ 2];
151
      dout[14] = din[ 4] ^ din[ 5] ^ din[ 1];
152
      dout[13] = din[ 3] ^ din[ 4] ^ din[ 0];
153
      dout[12] = din[ 2] ^ din[ 3] ^ din[ 8] ^ din[ 4];
154
      dout[11] = din[ 1] ^ din[ 2] ^ din[ 7] ^ din[ 3];
155
      dout[10] = din[ 0] ^ din[ 1] ^ din[ 6] ^ din[ 2];
156
      dout[ 9] = din[ 8] ^ din[ 0] ^ din[ 4] ^ din[ 5] ^ din[ 1];
157
      dout[ 8] = din[ 7] ^ din[ 8] ^ din[ 3] ^ din[ 0];
158
      dout[ 7] = din[ 6] ^ din[ 7] ^ din[ 2] ^ din[ 8] ^ din[ 4];
159
      dout[ 6] = din[ 5] ^ din[ 6] ^ din[ 1] ^ din[ 7] ^ din[ 3];
160
      dout[ 5] = din[ 4] ^ din[ 5] ^ din[ 0] ^ din[ 6] ^ din[ 2];
161
      dout[ 4] = din[ 3] ^ din[ 8] ^ din[ 5] ^ din[ 1];
162
      dout[ 3] = din[ 2] ^ din[ 4] ^ din[ 7] ^ din[ 0];
163
      dout[ 2] = din[ 1] ^ din[ 3] ^ din[ 6] ^ din[ 8] ^ din[ 4];
164
      dout[ 1] = din[ 0] ^ din[ 2] ^ din[ 5] ^ din[ 7] ^ din[ 3];
165
      dout[ 0] = din[ 8] ^ din[ 1] ^ din[ 6] ^ din[ 2];
166
      pn9 = dout;
167
    end
168
  endfunction
169
 
170
  // This PN sequence checking algorithm is commonly used is most applications.
171
  // It is a simple function generated based on the OOS status.
172
  // If OOS is asserted (PN is OUT of sync):
173
  //    The next sequence is generated from the incoming data.
174
  //    If 16 sequences match CONSECUTIVELY, OOS is cleared (de-asserted).
175
  // If OOS is de-asserted (PN is IN sync)
176
  //    The next sequence is generated from the current sequence.
177
  //    If 64 sequences mismatch CONSECUTIVELY, OOS is set (asserted).
178
  // If OOS is de-asserted, any spurious mismatches sets the ERROR register.
179
  // Ideally, processor should make sure both OOS == 0x0 AND ERR == 0x0.
180
 
181
  assign adc_pn_data_in_s[27:14] = {adc_data_d[13], adc_data_d[12:0]};
182
  assign adc_pn_data_in_s[13: 0] = {adc_data[13], adc_data[12:0]};
183
  assign adc_pn_match0_s = (adc_pn_data_in_s[27:14] == adc_pn_data[27:14]) ? 1'b1 : 1'b0;
184
  assign adc_pn_match1_s = (adc_pn_data_in_s[13:0] == adc_pn_data[13:0]) ? 1'b1 : 1'b0;
185
  assign adc_pn_match2_s = ((adc_data == 14'd0) && (adc_data_d == 14'd0)) ? 1'b0 : 1'b1;
186
  assign adc_pn_match_s = adc_pn_match0_s & adc_pn_match1_s & adc_pn_match2_s;
187
  assign adc_pn_data_s = (adc_pn_oos == 1'b1) ? adc_pn_data_in_s : adc_pn_data;
188
  assign adc_pn_err_s = ~(adc_pn_oos | adc_pn_match);
189
 
190
  // PN running sequence
191
 
192
  always @(posedge adc_clk) begin
193
    adc_pn_type_m1 <= up_pn_type;
194
    adc_pn_type_m2 <= adc_pn_type_m1;
195
    adc_pn_type <= adc_pn_type_m2;
196
    adc_pn_en <= ~adc_pn_en;
197
    adc_data_d <= adc_data;
198
    if (adc_pn_en == 1'b1) begin
199
      if (adc_pn_type == 1'b0) begin
200
        adc_pn_data <= pn9(adc_pn_data_s);
201
      end else begin
202
        adc_pn_data <= pn23(adc_pn_data_s);
203
      end
204
    end
205
  end
206
 
207
  // PN OOS and counters (16 to clear, 64 to set). These numbers are actually determined
208
  // based on BER parameters set by the system (usually in network applications).
209
 
210
  always @(posedge adc_clk) begin
211
    adc_pn_en_d <= adc_pn_en;
212
    adc_pn_match <= adc_pn_match_s;
213
    if (adc_pn_en_d == 1'b1) begin
214
      if (adc_pn_oos == 1'b1) begin
215
        if (adc_pn_match == 1'b1) begin
216
          if (adc_pn_oos_count >= 16) begin
217
            adc_pn_oos_count <= 'd0;
218
            adc_pn_oos <= 'd0;
219
          end else begin
220
            adc_pn_oos_count <= adc_pn_oos_count + 1'b1;
221
            adc_pn_oos <= 'd1;
222
          end
223
        end else begin
224
          adc_pn_oos_count <= 'd0;
225
          adc_pn_oos <= 'd1;
226
        end
227
      end else begin
228
        if (adc_pn_match == 1'b0) begin
229
          if (adc_pn_oos_count >= 64) begin
230
            adc_pn_oos_count <= 'd0;
231
            adc_pn_oos <= 'd1;
232
          end else begin
233
            adc_pn_oos_count <= adc_pn_oos_count + 1'b1;
234
            adc_pn_oos <= 'd0;
235
          end
236
        end else begin
237
          adc_pn_oos_count <= 'd0;
238
          adc_pn_oos <= 'd0;
239
        end
240
      end
241
    end
242
  end
243
 
244
  // The error state is streched to multiple adc clocks such that processor
245
  // has enough time to sample the error condition.
246
 
247
  always @(posedge adc_clk) begin
248
    if (adc_pn_en_d == 1'b1) begin
249
      if (adc_pn_err_s == 1'b1) begin
250
        adc_pn_err_count <= 5'h10;
251
      end else if (adc_pn_err_count[4] == 1'b1) begin
252
        adc_pn_err_count <= adc_pn_err_count + 1'b1;
253
      end
254
    end
255
    adc_pn_err <= adc_pn_err_count[4];
256
  end
257
 
258
endmodule
259
 
260
// ***************************************************************************
261
// ***************************************************************************
262
 

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.