AMC13
Firmwares for the different applications of the AMC13 uTCA board made at Boston University
 All Classes Variables
mig_7series_v1_9_ddr_phy_tempmon.v
1  //*****************************************************************************
2 // (c) Copyright 2008 - 2013 Xilinx, Inc. All rights reserved.
3 //
4 // This file contains confidential and proprietary information
5 // of Xilinx, Inc. and is protected under U.S. and
6 // international copyright and other intellectual property
7 // laws.
8 //
9 // DISCLAIMER
10 // This disclaimer is not a license and does not grant any
11 // rights to the materials distributed herewith. Except as
12 // otherwise provided in a valid license issued to you by
13 // Xilinx, and to the maximum extent permitted by applicable
14 // law: (1) THESE MATERIALS ARE MADE AVAILABLE "AS IS" AND
15 // WITH ALL FAULTS, AND XILINX HEREBY DISCLAIMS ALL WARRANTIES
16 // AND CONDITIONS, EXPRESS, IMPLIED, OR STATUTORY, INCLUDING
17 // BUT NOT LIMITED TO WARRANTIES OF MERCHANTABILITY, NON-
18 // INFRINGEMENT, OR FITNESS FOR ANY PARTICULAR PURPOSE; and
19 // (2) Xilinx shall not be liable (whether in contract or tort,
20 // including negligence, or under any other theory of
21 // liability) for any loss or damage of any kind or nature
22 // related to, arising under or in connection with these
23 // materials, including for any direct, or any indirect,
24 // special, incidental, or consequential loss or damage
25 // (including loss of data, profits, goodwill, or any type of
26 // loss or damage suffered as a result of any action brought
27 // by a third party) even if such damage or loss was
28 // reasonably foreseeable or Xilinx had been advised of the
29 // possibility of the same.
30 //
31 // CRITICAL APPLICATIONS
32 // Xilinx products are not designed or intended to be fail-
33 // safe, or for use in any application requiring fail-safe
34 // performance, such as life-support or safety devices or
35 // systems, Class III medical devices, nuclear facilities,
36 // applications related to the deployment of airbags, or any
37 // other applications that could lead to death, personal
38 // injury, or severe property or environmental damage
39 // (individually and collectively, "Critical
40 // Applications"). Customer assumes the sole risk and
41 // liability of any use of Xilinx products in Critical
42 // Applications, subject only to applicable laws and
43 // regulations governing limitations on product liability.
44 //
45 // THIS COPYRIGHT NOTICE AND DISCLAIMER MUST BE RETAINED AS
46 // PART OF THIS FILE AT ALL TIMES.
47 //
48 //*****************************************************************************
49 // ____ ____
50 // / /\/ /
51 // /___/ \ / Vendor : Xilinx
52 // \ \ \/ Version : %version
53 // \ \ Application : MIG
54 // / / Filename : mig_7series_v1_9_ddr_phy_tempmon.v
55 // /___/ /\ Date Last Modified : $date$
56 // \ \ / \ Date Created : Jul 25 2012
57 // \___\/\___\
58 //
59 //Device : 7 Series
60 //Design Name : DDR3 SDRAM
61 //Purpose : Monitors chip temperature via the XADC and adjusts the
62 // stage 2 tap values as appropriate.
63 //Reference :
64 //Revision History :
65 //*****************************************************************************
66 
67 `timescale 1 ps / 1 ps
68 
70 (
71  parameter TCQ = 100, // Register delay (simulation only)
72  // Temperature bands must be in order. To disable bands, set to extreme.
73  parameter BAND1_TEMP_MIN = 0, // Degrees C. Min=-273. Max=231
74  parameter BAND2_TEMP_MIN = 12, // Degrees C. Min=-273. Max=231
75  parameter BAND3_TEMP_MIN = 46, // Degrees C. Min=-273. Max=231
76  parameter BAND4_TEMP_MIN = 82, // Degrees C. Min=-273. Max=231
77  parameter TEMP_HYST = 5
78 )
79 (
80  input clk, // Fabric clock
81  input rst, // System reset
82  input calib_complete, // Calibration complete
83  input tempmon_sample_en, // Signal to enable sampling
84  input [11:0] device_temp, // Current device temperature
85  output tempmon_pi_f_inc, // Increment PHASER_IN taps
86  output tempmon_pi_f_dec, // Decrement PHASER_IN taps
87  output tempmon_sel_pi_incdec // Assume control of PHASER_IN taps
88 );
89 
90  // translate hysteresis into XADC units
91  localparam HYST_OFFSET = (TEMP_HYST * 4096) / 504;
92 
93  // translate band boundaries into XADC units
94  localparam BAND1_OFFSET = ((BAND1_TEMP_MIN + 273) * 4096) / 504;
95  localparam BAND2_OFFSET = ((BAND2_TEMP_MIN + 273) * 4096) / 504;
96  localparam BAND3_OFFSET = ((BAND3_TEMP_MIN + 273) * 4096) / 504;
97  localparam BAND4_OFFSET = ((BAND4_TEMP_MIN + 273) * 4096) / 504;
98 
99  // incorporate hysteresis into band boundaries
100  localparam BAND0_DEC_OFFSET =
101  BAND1_OFFSET - HYST_OFFSET > 0 ? BAND1_OFFSET - HYST_OFFSET : 0 ;
102  localparam BAND1_INC_OFFSET =
103  BAND1_OFFSET + HYST_OFFSET < 4096 ? BAND1_OFFSET + HYST_OFFSET : 4096 ;
104  localparam BAND1_DEC_OFFSET =
105  BAND2_OFFSET - HYST_OFFSET > 0 ? BAND2_OFFSET - HYST_OFFSET : 0 ;
106  localparam BAND2_INC_OFFSET =
107  BAND2_OFFSET + HYST_OFFSET < 4096 ? BAND2_OFFSET + HYST_OFFSET : 4096 ;
108  localparam BAND2_DEC_OFFSET =
109  BAND3_OFFSET - HYST_OFFSET > 0 ? BAND3_OFFSET - HYST_OFFSET : 0 ;
110  localparam BAND3_INC_OFFSET =
111  BAND3_OFFSET + HYST_OFFSET < 4096 ? BAND3_OFFSET + HYST_OFFSET : 4096 ;
112  localparam BAND3_DEC_OFFSET =
113  BAND4_OFFSET - HYST_OFFSET > 0 ? BAND4_OFFSET - HYST_OFFSET : 0 ;
114  localparam BAND4_INC_OFFSET =
115  BAND4_OFFSET + HYST_OFFSET < 4096 ? BAND4_OFFSET + HYST_OFFSET : 4096 ;
116 
117  // Temperature sampler FSM encoding
118  localparam INIT = 2'b00;
119  localparam IDLE = 2'b01;
120  localparam UPDATE = 2'b10;
121  localparam WAIT = 2'b11;
122 
123  // Temperature sampler state
124  reg [2:0] tempmon_state = INIT;
125  reg [2:0] tempmon_next_state = INIT;
126 
127  // Temperature storage
128  reg [11:0] previous_temp = 12'b0;
129 
130  // Temperature bands
131  reg [2:0] target_band = 3'b000;
132  reg [2:0] current_band = 3'b000;
133 
134  // Tap count and control
135  reg pi_f_inc = 1'b0;
136  reg pi_f_dec = 1'b0;
137  reg sel_pi_incdec = 1'b0;
138 
139  // Temperature and band comparisons
140  reg device_temp_lt_previous_temp = 1'b0;
141  reg device_temp_gt_previous_temp = 1'b0;
142 
143  reg device_temp_lt_band1 = 1'b0;
144  reg device_temp_lt_band2 = 1'b0;
145  reg device_temp_lt_band3 = 1'b0;
146  reg device_temp_lt_band4 = 1'b0;
147 
148  reg device_temp_lt_band0_dec = 1'b0;
149  reg device_temp_lt_band1_dec = 1'b0;
150  reg device_temp_lt_band2_dec = 1'b0;
151  reg device_temp_lt_band3_dec = 1'b0;
152 
153  reg device_temp_gt_band1_inc = 1'b0;
154  reg device_temp_gt_band2_inc = 1'b0;
155  reg device_temp_gt_band3_inc = 1'b0;
156  reg device_temp_gt_band4_inc = 1'b0;
157 
158  reg current_band_lt_target_band = 1'b0;
159  reg current_band_gt_target_band = 1'b0;
160 
161  reg target_band_gt_1 = 1'b0;
162  reg target_band_gt_2 = 1'b0;
163  reg target_band_gt_3 = 1'b0;
164 
165  reg target_band_lt_1 = 1'b0;
166  reg target_band_lt_2 = 1'b0;
167  reg target_band_lt_3 = 1'b0;
168 
169  // Pass tap control signals back up to PHY
170  assign tempmon_pi_f_inc = pi_f_inc;
171  assign tempmon_pi_f_dec = pi_f_dec;
172  assign tempmon_sel_pi_incdec = sel_pi_incdec;
173 
174  // XADC sampler state transition
175  always @(posedge clk)
176  if(rst)
177  tempmon_state <= #TCQ INIT;
178  else
179  tempmon_state <= #TCQ tempmon_next_state;
180 
181  // XADC sampler next state transition
182  always @(tempmon_state or calib_complete or tempmon_sample_en) begin
183 
184  tempmon_next_state = tempmon_state;
185 
186  case(tempmon_state)
187 
188  INIT:
189  if(calib_complete)
190  tempmon_next_state = IDLE;
191 
192  IDLE:
193  if(tempmon_sample_en)
194  tempmon_next_state = UPDATE;
195 
196  UPDATE:
197  tempmon_next_state = WAIT;
198 
199  WAIT:
200  if(~tempmon_sample_en)
201  tempmon_next_state = IDLE;
202 
203  default:
204  tempmon_next_state = INIT;
205 
206  endcase
207 
208  end
209 
210  // Record previous temperature during update cycle
211  always @(posedge clk)
212  if((tempmon_state == INIT) || (tempmon_state == UPDATE))
213  previous_temp <= #TCQ device_temp;
214 
215  // Update target band
216  always @(posedge clk) begin
217 
218  // register temperature comparisons
219  device_temp_lt_previous_temp <= #TCQ (device_temp < previous_temp) ? 1'b1 : 1'b0;
220  device_temp_gt_previous_temp <= #TCQ (device_temp > previous_temp) ? 1'b1 : 1'b0;
221 
222  device_temp_lt_band1 <= #TCQ (device_temp < BAND1_OFFSET) ? 1'b1 : 1'b0;
223  device_temp_lt_band2 <= #TCQ (device_temp < BAND2_OFFSET) ? 1'b1 : 1'b0;
224  device_temp_lt_band3 <= #TCQ (device_temp < BAND3_OFFSET) ? 1'b1 : 1'b0;
225  device_temp_lt_band4 <= #TCQ (device_temp < BAND4_OFFSET) ? 1'b1 : 1'b0;
226 
227  device_temp_lt_band0_dec <= #TCQ (device_temp < BAND0_DEC_OFFSET) ? 1'b1 : 1'b0;
228  device_temp_lt_band1_dec <= #TCQ (device_temp < BAND1_DEC_OFFSET) ? 1'b1 : 1'b0;
229  device_temp_lt_band2_dec <= #TCQ (device_temp < BAND2_DEC_OFFSET) ? 1'b1 : 1'b0;
230  device_temp_lt_band3_dec <= #TCQ (device_temp < BAND3_DEC_OFFSET) ? 1'b1 : 1'b0;
231 
232  device_temp_gt_band1_inc <= #TCQ (device_temp > BAND1_INC_OFFSET) ? 1'b1 : 1'b0;
233  device_temp_gt_band2_inc <= #TCQ (device_temp > BAND2_INC_OFFSET) ? 1'b1 : 1'b0;
234  device_temp_gt_band3_inc <= #TCQ (device_temp > BAND3_INC_OFFSET) ? 1'b1 : 1'b0;
235  device_temp_gt_band4_inc <= #TCQ (device_temp > BAND4_INC_OFFSET) ? 1'b1 : 1'b0;
236 
237  target_band_gt_1 <= #TCQ (target_band > 3'b001) ? 1'b1 : 1'b0;
238  target_band_gt_2 <= #TCQ (target_band > 3'b010) ? 1'b1 : 1'b0;
239  target_band_gt_3 <= #TCQ (target_band > 3'b011) ? 1'b1 : 1'b0;
240 
241  target_band_lt_1 <= #TCQ (target_band < 3'b001) ? 1'b1 : 1'b0;
242  target_band_lt_2 <= #TCQ (target_band < 3'b010) ? 1'b1 : 1'b0;
243  target_band_lt_3 <= #TCQ (target_band < 3'b011) ? 1'b1 : 1'b0;
244 
245  // Initialize band
246  if(tempmon_state == INIT) begin
247 
248  if(device_temp_lt_band1)
249  target_band <= #TCQ 3'b000;
250  else if(device_temp_lt_band2)
251  target_band <= #TCQ 3'b001;
252  else if(device_temp_lt_band3)
253  target_band <= #TCQ 3'b010;
254  else if(device_temp_lt_band4)
255  target_band <= #TCQ 3'b011;
256  else
257  target_band <= #TCQ 3'b100;
258 
259  end
260 
261  // Ready to update
262  else if(tempmon_state == IDLE) begin
263 
264  // Temperature has increased, see if it is in a new band
265  if(device_temp_gt_previous_temp) begin
266 
267  if(device_temp_gt_band4_inc)
268  target_band <= #TCQ 3'b100;
269 
270  else if(device_temp_gt_band3_inc && target_band_lt_3)
271  target_band <= #TCQ 3'b011;
272 
273  else if(device_temp_gt_band2_inc && target_band_lt_2)
274  target_band <= #TCQ 3'b010;
275 
276  else if(device_temp_gt_band1_inc && target_band_lt_1)
277  target_band <= #TCQ 3'b001;
278 
279  end
280 
281  // Temperature has decreased, see if it is in new band
282  else if(device_temp_lt_previous_temp) begin
283 
284  if(device_temp_lt_band0_dec)
285  target_band <= #TCQ 3'b000;
286 
287  else if(device_temp_lt_band1_dec && target_band_gt_1)
288  target_band <= #TCQ 3'b001;
289 
290  else if(device_temp_lt_band2_dec && target_band_gt_2)
291  target_band <= #TCQ 3'b010;
292 
293  else if(device_temp_lt_band3_dec && target_band_gt_3)
294  target_band <= #TCQ 3'b011;
295 
296  end
297 
298  end
299 
300  end
301 
302  // Current band
303  always @(posedge clk) begin
304 
305  current_band_lt_target_band = (current_band < target_band) ? 1'b1 : 1'b0;
306  current_band_gt_target_band = (current_band > target_band) ? 1'b1 : 1'b0;
307 
308  if(tempmon_state == INIT) begin
309 
310  if(device_temp_lt_band1)
311  current_band <= #TCQ 3'b000;
312  else if(device_temp_lt_band2)
313  current_band <= #TCQ 3'b001;
314  else if(device_temp_lt_band3)
315  current_band <= #TCQ 3'b010;
316  else if(device_temp_lt_band4)
317  current_band <= #TCQ 3'b011;
318  else
319  current_band <= #TCQ 3'b100;
320 
321  end
322 
323  else if(tempmon_state == UPDATE) begin
324 
325  if(current_band_lt_target_band)
326  current_band <= #TCQ current_band + 1;
327  else if(current_band_gt_target_band)
328  current_band <= #TCQ current_band - 1;
329 
330  end
331 
332  end
333 
334  // Tap control
335  always @(posedge clk) begin
336 
337  if(rst) begin
338  pi_f_inc <= #TCQ 1'b0;
339  pi_f_dec <= #TCQ 1'b0;
340  sel_pi_incdec <= #TCQ 1'b0;
341  end
342 
343  else if(tempmon_state == UPDATE) begin
344 
345  if(current_band_lt_target_band) begin
346  sel_pi_incdec <= #TCQ 1'b1;
347  pi_f_dec <= #TCQ 1'b1;
348  end
349 
350  else if(current_band_gt_target_band) begin
351  sel_pi_incdec <= #TCQ 1'b1;
352  pi_f_inc <= #TCQ 1'b1;
353  end
354 
355  end
356 
357  else begin
358 
359  pi_f_inc <= #TCQ 1'b0;
360  pi_f_dec <= #TCQ 1'b0;
361  sel_pi_incdec <= #TCQ 1'b0;
362 
363  end
364 
365  end
366 
367 endmodule