source: XOpenSparcT1/trunk/Xilinx/ddr2_phy_dq_iob.v @ 10

Revision 10, 21.4 KB checked in by pntsvt00, 14 years ago (diff)

versione sintetizzabile

RevLine 
[10]1//*****************************************************************************
2// DISCLAIMER OF LIABILITY
3//
4// This file contains proprietary and confidential information of
5// Xilinx, Inc. ("Xilinx"), that is distributed under a license
6// from Xilinx, and may be used, copied and/or disclosed only
7// pursuant to the terms of a valid license agreement with Xilinx.
8//
9// XILINX IS PROVIDING THIS DESIGN, CODE, OR INFORMATION
10// ("MATERIALS") "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER
11// EXPRESSED, IMPLIED, OR STATUTORY, INCLUDING WITHOUT
12// LIMITATION, ANY WARRANTY WITH RESPECT TO NONINFRINGEMENT,
13// MERCHANTABILITY OR FITNESS FOR ANY PARTICULAR PURPOSE. Xilinx
14// does not warrant that functions included in the Materials will
15// meet the requirements of Licensee, or that the operation of the
16// Materials will be uninterrupted or error-free, or that defects
17// in the Materials will be corrected. Furthermore, Xilinx does
18// not warrant or make any representations regarding use, or the
19// results of the use, of the Materials in terms of correctness,
20// accuracy, reliability or otherwise.
21//
22// Xilinx products are not designed or intended to be fail-safe,
23// or for use in any application requiring fail-safe performance,
24// such as life-support or safety devices or systems, Class III
25// medical devices, nuclear facilities, applications related to
26// the deployment of airbags, or any other applications that could
27// lead to death, personal injury or severe property or
28// environmental damage (individually and collectively, "critical
29// applications"). Customer assumes the sole risk and liability
30// of any use of Xilinx products in critical applications,
31// subject only to applicable laws and regulations governing
32// limitations on product liability.
33//
34// Copyright 2006, 2007, 2008 Xilinx, Inc.
35// All rights reserved.
36//
37// This disclaimer and copyright notice must be retained as part
38// of this file at all times.
39//*****************************************************************************
40//   ____  ____
41//  /   /\/   /
42// /___/  \  /    Vendor: Xilinx
43// \   \   \/     Version: 3.6
44//  \   \         Application: MIG
45//  /   /         Filename: ddr2_phy_dq_iob.v
46// /___/   /\     Date Last Modified: $Date: 2010/06/29 12:03:43 $
47// \   \  /  \    Date Created: Wed Aug 16 2006
48//  \___\/\___\
49//
50//Device: Virtex-5
51//Design Name: DDR2
52//Purpose:
53//   This module places the data in the IOBs.
54//Reference:
55//Revision History:
56//   Rev 1.1 - Parameter HIGH_PERFORMANCE_MODE added. PK. 7/10/08
57//   Rev 1.2 - DIRT strings removed and modified the code. PK. 11/13/08
58//   Rev 1.3 - Parameter IODELAY_GRP added and constraint IODELAY_GROUP added
59//             on IODELAY primitive. PK. 11/27/08
60//*****************************************************************************
61
62`timescale 1ns/1ps
63
64module ddr2_phy_dq_iob #
65  (
66   // Following parameters are for 72-bit RDIMM design (for ML561 Reference
67   // board design). Actual values may be different. Actual parameters values
68   // are passed from design top module dram module. Please refer to
69   // the dram module for actual values.
70   parameter HIGH_PERFORMANCE_MODE = "TRUE",
71   parameter IODELAY_GRP           = "IODELAY_MIG",
72   parameter FPGA_SPEED_GRADE      = 2
73   )
74  (
75   input        clk0,
76   input        clk90,
77   input        clkdiv0,
78   input        rst90,
79   input        dlyinc,
80   input        dlyce,
81   input        dlyrst,
82   input  [1:0] dq_oe_n,
83   input        dqs,
84   input        ce,
85   input        rd_data_sel,
86   input        wr_data_rise,
87   input        wr_data_fall,
88   output       rd_data_rise,
89   output       rd_data_fall,
90   inout        ddr_dq
91   );
92
93  wire       dq_iddr_clk;
94  wire       dq_idelay;
95  wire       dq_in;
96  wire       dq_oe_n_r;
97  wire       dq_out;
98  wire       stg2a_out_fall;
99  wire       stg2a_out_rise;
100  (* XIL_PAR_DELAY = "0 ps", XIL_PAR_IP_NAME = "MIG", syn_keep = "1", keep = "TRUE" *)
101  wire       stg2b_out_fall;
102  (* XIL_PAR_DELAY = "0 ps", XIL_PAR_IP_NAME = "MIG", syn_keep = "1", keep = "TRUE" *)
103  wire       stg2b_out_rise;
104  wire       stg3a_out_fall;
105  wire       stg3a_out_rise;
106  wire       stg3b_out_fall;
107  wire       stg3b_out_rise;
108
109  //***************************************************************************
110  // Directed routing constraints for route between IDDR and stage 2 capture
111  // in fabric.
112  // Only 2 out of the 12 wire declarations will be used for any given
113  // instantiation of this module.
114  // Varies according:
115  //  (1) I/O column (left, center, right) used
116  //  (2) Which I/O in I/O pair (master, slave) used
117  // Nomenclature: _Xy, X = column (0 = left, 1 = center, 2 = right),
118  //  y = master or slave
119  //***************************************************************************
120
121  // MODIFIED, RC, 06/13/08: Remove all references to DIRT, master/slave
122
123  (* XIL_PAR_DELAY = "515 ps", XIL_PAR_SKEW = "55 ps", XIL_PAR_IP_NAME = "MIG", syn_keep = "1", keep = "TRUE" *)
124  wire stg1_out_rise_sg3;
125  (* XIL_PAR_DELAY = "515 ps", XIL_PAR_SKEW = "55 ps", XIL_PAR_IP_NAME = "MIG", syn_keep = "1", keep = "TRUE" *)
126  wire stg1_out_fall_sg3;
127  (* XIL_PAR_DELAY = "575 ps", XIL_PAR_SKEW = "65 ps", XIL_PAR_IP_NAME = "MIG", syn_keep = "1", keep = "TRUE" *)
128  wire stg1_out_rise_sg2;
129  (* XIL_PAR_DELAY = "575 ps", XIL_PAR_SKEW = "65 ps", XIL_PAR_IP_NAME = "MIG", syn_keep = "1", keep = "TRUE" *)
130  wire stg1_out_fall_sg2;
131  (* XIL_PAR_DELAY = "650 ps", XIL_PAR_SKEW = "70 ps", XIL_PAR_IP_NAME = "MIG", syn_keep = "1", keep = "TRUE" *)
132  wire stg1_out_rise_sg1;
133  (* XIL_PAR_DELAY = "650 ps", XIL_PAR_SKEW = "70 ps", XIL_PAR_IP_NAME = "MIG", syn_keep = "1", keep = "TRUE" *)
134  wire stg1_out_fall_sg1;
135
136  //***************************************************************************
137  // Bidirectional I/O
138  //***************************************************************************
139
140  IOBUF u_iobuf_dq
141    (
142     .I  (dq_out),
143     .T  (dq_oe_n_r),
144     .IO (ddr_dq),
145     .O  (dq_in)
146     );
147
148  //***************************************************************************
149  // Write (output) path
150  //***************************************************************************
151
152  // on a write, rising edge of DQS corresponds to rising edge of CLK180
153  // (aka falling edge of CLK0 -> rising edge DQS). We also know:
154  //  1. data must be driven 1/4 clk cycle before corresponding DQS edge
155  //  2. first rising DQS edge driven on falling edge of CLK0
156  //  3. rising data must be driven 1/4 cycle before falling edge of CLK0
157  //  4. therefore, rising data driven on rising edge of CLK
158  ODDR #
159    (
160     .SRTYPE("SYNC"),
161     .DDR_CLK_EDGE("SAME_EDGE")
162     )
163    u_oddr_dq
164      (
165       .Q  (dq_out),
166       .C  (clk90),
167       .CE (1'b1),
168       .D1 (wr_data_rise),
169       .D2 (wr_data_fall),
170       .R  (1'b0),
171       .S  (1'b0)
172       );
173
174  // make sure output is tri-state during reset (DQ_OE_N_R = 1)
175  ODDR #
176    (
177     .SRTYPE("ASYNC"),
178     .DDR_CLK_EDGE("SAME_EDGE")
179     )
180    u_tri_state_dq
181      (
182       .Q  (dq_oe_n_r),
183       .C  (clk90),
184       .CE (1'b1),
185       .D1 (dq_oe_n[0]),
186       .D2 (dq_oe_n[1]),
187       .R  (1'b0),
188       .S  (rst90)
189       );
190
191  //***************************************************************************
192  // Read data capture scheme description:
193  // Data capture consists of 3 ranks of flops, and a MUX
194  //  1. Rank 1 ("Stage 1"): IDDR captures delayed DDR DQ from memory using
195  //     delayed DQS.
196  //     - Data is split into 2 SDR streams, one each for rise and fall data.
197  //     - BUFIO (DQS) input inverted to IDDR. IDDR configured in SAME_EDGE
198  //       mode. This means that: (1) Q1 = fall data, Q2 = rise data,
199  //       (2) Both rise and fall data are output on falling edge of DQS -
200  //       rather than rise output being output on one edge of DQS, and fall
201  //       data on the other edge if the IDDR were configured in OPPOSITE_EDGE
202  //       mode. This simplifies Stage 2 capture (only one core clock edge
203  //       used, removing effects of duty-cycle-distortion), and saves one
204  //       fabric flop in Rank 3.
205  //  2. Rank 2 ("Stage 2"): Fabric flops are used to capture output of first
206  //     rank into FPGA clock (CLK) domain. Each rising/falling SDR stream
207  //     from IDDR is feed into two flops, one clocked off rising and one off
208  //     falling edge of CLK. One of these flops is chosen, with the choice
209  //     being the one that reduces # of DQ/DQS taps necessary to align Stage
210  //     1 and Stage 2. Same edge is used to capture both rise and fall SDR
211  //     streams.
212  //  3. Rank 3 ("Stage 3"): Removes half-cycle paths in CLK domain from
213  //     output of Rank 2. This stage, like Stage 2, is clocked by CLK. Note
214  //     that Stage 3 can be expanded to also support SERDES functionality
215  //  4. Output MUX: Selects whether Stage 1 output is aligned to rising or
216  //     falling edge of CLK (i.e. specifically this selects whether IDDR
217  //     rise/fall output is transfered to rising or falling edge of CLK).
218  // Implementation:
219  //  1. Rank 1 is implemented using an IDDR primitive
220  //  2. Rank 2 is implemented using:
221  //     - An RPM to fix the location of the capture flops near the DQ I/O.
222  //       The exact RPM used depends on which I/O column (left, center,
223  //       right) the DQ I/O is placed at - this affects the optimal location
224  //       of the slice flops (or does it - can we always choose the two
225  //       columns to slices to the immediate right of the I/O to use, no
226  //       matter what the column?). The origin of the RPM must be set in the
227  //       UCF file using the RLOC_ORIGIN constraint (where the original is
228  //       based on the DQ I/O location).
229  //     - Directed Routing Constraints ("DIRT strings") to fix the routing
230  //       to the rank 2 fabric flops. This is done to minimize: (1) total
231  //       route delay (and therefore minimize voltage/temperature-related
232  //       variations), and (2) minimize skew both within each rising and
233  //       falling data net, as well as between the rising and falling nets.
234  //       The exact DIRT string used depends on: (1) which I/O column the
235  //       DQ I/O is placed, and (2) whether the DQ I/O is placed on the
236  //       "Master" or "Slave" I/O of a diff pair (DQ is not differential, but
237  //       the routing will be affected by which of each I/O pair is used)
238  // 3. Rank 3 is implemented using fabric flops. No LOC or DIRT contraints
239  //    are used, tools are expected to place these and meet PERIOD timing
240  //    without constraints (constraints may be necessary for "full" designs,
241  //    in this case, user may need to add LOC constraints - if this is the
242  //    case, there are no constraints - other than meeting PERIOD timing -
243  //    for rank 3 flops.
244  //***************************************************************************
245
246  //***************************************************************************
247  // MIG 2.2: Define AREA_GROUP = "DDR_CAPTURE_FFS" contain all RPM flops in
248  //          design. In UCF file, add constraint:
249  //             AREA_GROUP "DDR_CAPTURE_FFS" GROUP = CLOSED;
250  //          This is done to prevent MAP from packing unrelated logic into
251  //          the slices used by the RPMs. Doing so may cause the DIRT strings
252  //          that define the IDDR -> fabric flop routing to later become
253  //          unroutable during PAR because the unrelated logic placed by MAP
254  //          may use routing resources required by the DIRT strings. MAP
255  //          does not currently take into account DIRT strings when placing
256  //          logic
257  //***************************************************************************
258
259  // IDELAY to delay incoming data for synchronization purposes
260  (* IODELAY_GROUP = IODELAY_GRP *) IODELAY #
261    (
262     .DELAY_SRC             ("I"),
263     .IDELAY_TYPE           ("VARIABLE"),
264     .HIGH_PERFORMANCE_MODE (HIGH_PERFORMANCE_MODE),
265     .IDELAY_VALUE          (0),
266     .ODELAY_VALUE          (0)
267     )
268    u_idelay_dq
269      (
270       .DATAOUT (dq_idelay),
271       .C       (clkdiv0),
272       .CE      (dlyce),
273       .DATAIN  (),
274       .IDATAIN (dq_in),
275       .INC     (dlyinc),
276       .ODATAIN (),
277       .RST     (dlyrst),
278       .T       ()
279       );
280
281  //***************************************************************************
282  // Rank 1 capture: Use IDDR to generate two SDR outputs
283  //***************************************************************************
284
285  // invert clock to IDDR in order to use SAME_EDGE mode (otherwise, we "run
286  // out of clocks" because DQS is not continuous
287  assign dq_iddr_clk = ~dqs;
288
289  //***************************************************************************
290  // Rank 2 capture: Use fabric flops to capture Rank 1 output. Use RPM and
291  // DIRT strings here.
292  // BEL ("Basic Element of Logic") and relative location constraints for
293  // second stage capture. C
294  // Varies according:
295  //  (1) I/O column (left, center, right) used
296  //  (2) Which I/O in I/O pair (master, slave) used
297  //***************************************************************************
298
299  // MODIFIED, RC, 06/13/08: Remove all references to DIRT, master/slave
300  //  Take out generate statements - collapses to a single case
301
302  generate
303    if (FPGA_SPEED_GRADE == 3) begin: gen_stg2_sg3
304      IDDR #
305        (
306         .DDR_CLK_EDGE ("SAME_EDGE")
307         )
308        u_iddr_dq
309          (
310           .Q1 (stg1_out_fall_sg3),
311           .Q2 (stg1_out_rise_sg3),
312           .C  (dq_iddr_clk),
313           .CE (ce),
314           .D  (dq_idelay),
315           .R  (1'b0),
316           .S  (1'b0)
317           );
318
319      //*********************************************************
320      // Slice #1 (posedge CLK): Used for:
321      //  1. IDDR transfer to CLK0 rising edge domain ("stg2a")
322      //  2. stg2 falling edge -> stg3 rising edge transfer
323      //*********************************************************
324
325      // Stage 2 capture
326      FDRSE u_ff_stg2a_fall
327        (
328         .Q   (stg2a_out_fall),
329         .C   (clk0),
330         .CE  (1'b1),
331         .D   (stg1_out_fall_sg3),
332         .R   (1'b0),
333         .S   (1'b0)
334         )/* synthesis syn_preserve = 1 */
335          /* synthesis syn_replicate = 0 */;
336      FDRSE u_ff_stg2a_rise
337        (
338         .Q   (stg2a_out_rise),
339         .C   (clk0),
340         .CE  (1'b1),
341         .D   (stg1_out_rise_sg3),
342         .R   (1'b0),
343         .S   (1'b0)
344         )/* synthesis syn_preserve = 1 */
345          /* synthesis syn_replicate = 0 */;
346      // Stage 3 falling -> rising edge translation
347      FDRSE u_ff_stg3b_fall
348        (
349         .Q   (stg3b_out_fall),
350         .C   (clk0),
351         .CE  (1'b1),
352         .D   (stg2b_out_fall),
353         .R   (1'b0),
354         .S   (1'b0)
355         )/* synthesis syn_preserve = 1 */
356          /* synthesis syn_replicate = 0 */;
357      FDRSE u_ff_stg3b_rise
358        (
359         .Q   (stg3b_out_rise),
360         .C   (clk0),
361         .CE  (1'b1),
362         .D   (stg2b_out_rise),
363         .R   (1'b0),
364         .S   (1'b0)
365         )/* synthesis syn_preserve = 1 */
366          /* synthesis syn_replicate = 0 */;
367
368      //*********************************************************
369      // Slice #2 (posedge CLK): Used for:
370      //  1. IDDR transfer to CLK0 falling edge domain ("stg2b")
371      //*********************************************************
372
373      FDRSE_1 u_ff_stg2b_fall
374        (
375         .Q   (stg2b_out_fall),
376         .C   (clk0),
377         .CE  (1'b1),
378         .D   (stg1_out_fall_sg3),
379         .R   (1'b0),
380         .S   (1'b0)
381         )/* synthesis syn_preserve = 1 */
382          /* synthesis syn_replicate = 0 */;
383
384      FDRSE_1 u_ff_stg2b_rise
385        (
386         .Q   (stg2b_out_rise),
387         .C   (clk0),
388         .CE  (1'b1),
389         .D   (stg1_out_rise_sg3),
390         .R   (1'b0),
391         .S   (1'b0)
392         )/* synthesis syn_preserve = 1 */
393          /* synthesis syn_replicate = 0 */;
394    end else if (FPGA_SPEED_GRADE == 2) begin: gen_stg2_sg2
395      IDDR #
396        (
397         .DDR_CLK_EDGE ("SAME_EDGE")
398         )
399        u_iddr_dq
400          (
401           .Q1 (stg1_out_fall_sg2),
402           .Q2 (stg1_out_rise_sg2),
403           .C  (dq_iddr_clk),
404           .CE (ce),
405           .D  (dq_idelay),
406           .R  (1'b0),
407           .S  (1'b0)
408           );
409
410      //*********************************************************
411      // Slice #1 (posedge CLK): Used for:
412      //  1. IDDR transfer to CLK0 rising edge domain ("stg2a")
413      //  2. stg2 falling edge -> stg3 rising edge transfer
414      //*********************************************************
415
416      // Stage 2 capture
417      FDRSE u_ff_stg2a_fall
418        (
419         .Q   (stg2a_out_fall),
420         .C   (clk0),
421         .CE  (1'b1),
422         .D   (stg1_out_fall_sg2),
423         .R   (1'b0),
424         .S   (1'b0)
425         )/* synthesis syn_preserve = 1 */
426          /* synthesis syn_replicate = 0 */;
427      FDRSE u_ff_stg2a_rise
428        (
429         .Q   (stg2a_out_rise),
430         .C   (clk0),
431         .CE  (1'b1),
432         .D   (stg1_out_rise_sg2),
433         .R   (1'b0),
434         .S   (1'b0)
435         )/* synthesis syn_preserve = 1 */
436          /* synthesis syn_replicate = 0 */;
437      // Stage 3 falling -> rising edge translation
438      FDRSE u_ff_stg3b_fall
439        (
440         .Q   (stg3b_out_fall),
441         .C   (clk0),
442         .CE  (1'b1),
443         .D   (stg2b_out_fall),
444         .R   (1'b0),
445         .S   (1'b0)
446         )/* synthesis syn_preserve = 1 */
447          /* synthesis syn_replicate = 0 */;
448      FDRSE u_ff_stg3b_rise
449        (
450         .Q   (stg3b_out_rise),
451         .C   (clk0),
452         .CE  (1'b1),
453         .D   (stg2b_out_rise),
454         .R   (1'b0),
455         .S   (1'b0)
456         )/* synthesis syn_preserve = 1 */
457          /* synthesis syn_replicate = 0 */;
458
459      //*********************************************************
460      // Slice #2 (posedge CLK): Used for:
461      //  1. IDDR transfer to CLK0 falling edge domain ("stg2b")
462      //*********************************************************
463
464      FDRSE_1 u_ff_stg2b_fall
465        (
466         .Q   (stg2b_out_fall),
467         .C   (clk0),
468         .CE  (1'b1),
469         .D   (stg1_out_fall_sg2),
470         .R   (1'b0),
471         .S   (1'b0)
472         )/* synthesis syn_preserve = 1 */
473          /* synthesis syn_replicate = 0 */;
474
475      FDRSE_1 u_ff_stg2b_rise
476        (
477         .Q   (stg2b_out_rise),
478         .C   (clk0),
479         .CE  (1'b1),
480         .D   (stg1_out_rise_sg2),
481         .R   (1'b0),
482         .S   (1'b0)
483          )/* synthesis syn_preserve = 1 */
484           /* synthesis syn_replicate = 0 */;
485    end else if (FPGA_SPEED_GRADE == 1) begin: gen_stg2_sg1
486      IDDR #
487        (
488         .DDR_CLK_EDGE ("SAME_EDGE")
489         )
490        u_iddr_dq
491          (
492           .Q1 (stg1_out_fall_sg1),
493           .Q2 (stg1_out_rise_sg1),
494           .C  (dq_iddr_clk),
495           .CE (ce),
496           .D  (dq_idelay),
497           .R  (1'b0),
498           .S  (1'b0)
499           );
500
501      //*********************************************************
502      // Slice #1 (posedge CLK): Used for:
503      //  1. IDDR transfer to CLK0 rising edge domain ("stg2a")
504      //  2. stg2 falling edge -> stg3 rising edge transfer
505      //*********************************************************
506
507      // Stage 2 capture
508      FDRSE u_ff_stg2a_fall
509        (
510         .Q   (stg2a_out_fall),
511         .C   (clk0),
512         .CE  (1'b1),
513         .D   (stg1_out_fall_sg1),
514         .R   (1'b0),
515         .S   (1'b0)
516         )/* synthesis syn_preserve = 1 */
517          /* synthesis syn_replicate = 0 */;
518      FDRSE u_ff_stg2a_rise
519        (
520         .Q   (stg2a_out_rise),
521         .C   (clk0),
522         .CE  (1'b1),
523         .D   (stg1_out_rise_sg1),
524         .R   (1'b0),
525         .S   (1'b0)
526         )/* synthesis syn_preserve = 1 */
527          /* synthesis syn_replicate = 0 */;
528      // Stage 3 falling -> rising edge translation
529      FDRSE u_ff_stg3b_fall
530        (
531         .Q   (stg3b_out_fall),
532         .C   (clk0),
533         .CE  (1'b1),
534         .D   (stg2b_out_fall),
535         .R   (1'b0),
536         .S   (1'b0)
537         )/* synthesis syn_preserve = 1 */
538          /* synthesis syn_replicate = 0 */;
539      FDRSE u_ff_stg3b_rise
540        (
541         .Q   (stg3b_out_rise),
542         .C   (clk0),
543         .CE  (1'b1),
544         .D   (stg2b_out_rise),
545         .R   (1'b0),
546         .S   (1'b0)
547         )/* synthesis syn_preserve = 1 */
548          /* synthesis syn_replicate = 0 */;
549
550      //*********************************************************
551      // Slice #2 (posedge CLK): Used for:
552      //  1. IDDR transfer to CLK0 falling edge domain ("stg2b")
553      //*********************************************************
554
555      FDRSE_1 u_ff_stg2b_fall
556        (
557         .Q   (stg2b_out_fall),
558         .C   (clk0),
559         .CE  (1'b1),
560         .D   (stg1_out_fall_sg1),
561         .R   (1'b0),
562         .S   (1'b0)
563         )/* synthesis syn_preserve = 1 */
564          /* synthesis syn_replicate = 0 */;
565
566      FDRSE_1 u_ff_stg2b_rise
567        (
568         .Q   (stg2b_out_rise),
569         .C   (clk0),
570         .CE  (1'b1),
571         .D   (stg1_out_rise_sg1),
572         .R   (1'b0),
573         .S   (1'b0)
574         )/* synthesis syn_preserve = 1 */
575          /* synthesis syn_replicate = 0 */;
576    end
577  endgenerate
578
579  //***************************************************************************
580  // Second stage flops clocked by posedge CLK0 don't need another layer of
581  // registering
582  //***************************************************************************
583
584  assign stg3a_out_rise = stg2a_out_rise;
585  assign stg3a_out_fall = stg2a_out_fall;
586
587  //*******************************************************************
588
589  assign rd_data_rise = (rd_data_sel) ? stg3a_out_rise : stg3b_out_rise;
590  assign rd_data_fall = (rd_data_sel) ? stg3a_out_fall : stg3b_out_fall;
591
592endmodule
Note: See TracBrowser for help on using the repository browser.