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

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [orpsocv2/] [boards/] [xilinx/] [atlys/] [rtl/] [verilog/] [xilinx_ddr2/] [iodrp_mcb_controller.v] - Blame information for rev 627

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 627 stekern
//*****************************************************************************
2
// (c) Copyright 2009 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: iodrp_mcb_controller.v
55
// /___/   /\     Date Last Modified: $Date: 2010/10/27 17:40:12 $
56
// \   \  /  \    Date Created: Mon Feb 9 2009
57
//  \___\/\___\
58
//
59
//Device: Spartan6
60
//Design Name: DDR/DDR2/DDR3/LPDDR
61
//Purpose:  Xilinx reference design for IODRP controller for v0.9 device
62
//Reference:
63
//
64
//  Revision:      Date:  Comment
65
//       1.0:  3/19/09:  Initial version for IODRP_MCB read operations.
66
//       1.1:  4/03/09:  SLH - Added left shift for certain IOI's
67
// End Revision
68
//**********************************************************************************
69
 
70
`timescale 1ps/1ps
71
 
72
`ifdef ALTERNATE_READ
73
`else
74
  `define ALTERNATE_READ 1'b1
75
`endif
76
 
77
module iodrp_mcb_controller(
78
  input   wire  [7:0] memcell_address,
79
  input   wire  [7:0] write_data,
80
  output  reg   [7:0] read_data = 0,
81
  input   wire        rd_not_write,
82
  input   wire        cmd_valid,
83
  output  wire        rdy_busy_n,
84
  input   wire        use_broadcast,
85
  input   wire  [4:0] drp_ioi_addr,
86
  input   wire        sync_rst,
87
  input   wire        DRP_CLK,
88
  output  reg         DRP_CS,
89
  output  wire        DRP_SDI,  //output to IODRP SDI pin
90
  output  reg         DRP_ADD,
91
  output  reg         DRP_BKST,
92
  input   wire        DRP_SDO,   //input from IODRP SDO pin
93
  output  reg         MCB_UIREAD = 1'b0
94
  );
95
 
96
   reg [7:0]          memcell_addr_reg;     // Register where memcell_address is captured during the READY state
97
   reg [7:0]          data_reg;             // Register which stores the write data until it is ready to be shifted out
98
   reg [8:0]          shift_through_reg;    // The shift register which shifts out SDO and shifts in SDI.
99
                                            //    This register is loaded before the address or data phase, but continues to shift for a writeback of read data
100
   reg                load_shift_n;         // The signal which causes shift_through_reg to load the new value from data_out_mux, or continue to shift data in from DRP_SDO
101
   reg                addr_data_sel_n;      // The signal which indicates where the shift_through_reg should load from.  0 -> data_reg  1 -> memcell_addr_reg
102
   reg [2:0]          bit_cnt= 3'b0;        // The counter for which bit is being shifted during address or data phase
103
   reg                rd_not_write_reg;
104
   reg                AddressPhase;         // This is set after the first address phase has executed
105
   reg                DRP_CS_pre;
106
   reg                extra_cs;
107
 
108
   (* FSM_ENCODING="GRAY" *) reg [3:0] state, nextstate;
109
 
110
   wire [8:0]   data_out;
111
   reg  [8:0]   data_out_mux; // The mux which selects between data_reg and memcell_addr_reg for sending to shift_through_reg
112
   wire DRP_SDI_pre;          //added so that DRP_SDI output is only active when DRP_CS is active
113
 
114
   localparam READY             = 4'h0;
115
   localparam DECIDE            = 4'h1;
116
   localparam ADDR_PHASE        = 4'h2;
117
   localparam ADDR_TO_DATA_GAP  = 4'h3;
118
   localparam ADDR_TO_DATA_GAP2 = 4'h4;
119
   localparam ADDR_TO_DATA_GAP3 = 4'h5;
120
   localparam DATA_PHASE        = 4'h6;
121
   localparam ALMOST_READY      = 4'h7;
122
   localparam ALMOST_READY2     = 4'h8;
123
   localparam ALMOST_READY3     = 4'h9;
124
 
125
   localparam IOI_DQ0           = 5'h01;
126
   localparam IOI_DQ1           = 5'h00;
127
   localparam IOI_DQ2           = 5'h03;
128
   localparam IOI_DQ3           = 5'h02;
129
   localparam IOI_DQ4           = 5'h05;
130
   localparam IOI_DQ5           = 5'h04;
131
   localparam IOI_DQ6           = 5'h07;
132
   localparam IOI_DQ7           = 5'h06;
133
   localparam IOI_DQ8           = 5'h09;
134
   localparam IOI_DQ9           = 5'h08;
135
   localparam IOI_DQ10          = 5'h0B;
136
   localparam IOI_DQ11          = 5'h0A;
137
   localparam IOI_DQ12          = 5'h0D;
138
   localparam IOI_DQ13          = 5'h0C;
139
   localparam IOI_DQ14          = 5'h0F;
140
   localparam IOI_DQ15          = 5'h0E;
141
   localparam IOI_UDQS_CLK      = 5'h1D;
142
   localparam IOI_UDQS_PIN      = 5'h1C;
143
   localparam IOI_LDQS_CLK      = 5'h1F;
144
   localparam IOI_LDQS_PIN      = 5'h1E;
145
 
146
   //synthesis translate_off
147
   reg [32*8-1:0] state_ascii;
148
   always @ (state) begin
149
      case (state)
150
  READY     :state_ascii<="READY";
151
  DECIDE      :state_ascii<="DECIDE";
152
  ADDR_PHASE    :state_ascii<="ADDR_PHASE";
153
  ADDR_TO_DATA_GAP  :state_ascii<="ADDR_TO_DATA_GAP";
154
  ADDR_TO_DATA_GAP2 :state_ascii<="ADDR_TO_DATA_GAP2";
155
  ADDR_TO_DATA_GAP3 :state_ascii<="ADDR_TO_DATA_GAP3";
156
  DATA_PHASE    :state_ascii<="DATA_PHASE";
157
  ALMOST_READY    :state_ascii<="ALMOST_READY";
158
  ALMOST_READY2   :state_ascii<="ALMOST_READY2";
159
  ALMOST_READY3   :state_ascii<="ALMOST_READY3";
160
      endcase // case(state)
161
   end
162
   //synthesis translate_on
163
 
164
   /*********************************************
165
    *   Input Registers
166
    *********************************************/
167
   always @ (posedge DRP_CLK) begin
168
      if(state == READY) begin
169
        memcell_addr_reg <= memcell_address;
170
        data_reg <= write_data;
171
        rd_not_write_reg <= rd_not_write;
172
      end
173
   end
174
 
175
   assign rdy_busy_n = (state == READY);
176
 
177
   // The changes below are to compensate for an issue with 1.0 silicon.
178
   // It may still be necessary to add a clock cycle to the ADD and CS signals
179
 
180
//`define DRP_v1_0_FIX    // Uncomment out this line for synthesis
181
 
182
task shift_n_expand (
183
  input   [7:0] data_in,
184
  output  [8:0] data_out
185
  );
186
 
187
  begin
188
    if (data_in[0])
189
      data_out[1:0]  = 2'b11;
190
    else
191
      data_out[1:0]  = 2'b00;
192
 
193
    if (data_in[1:0] == 2'b10)
194
      data_out[2:1]  = 2'b11;
195
    else
196
      data_out[2:1]  = {data_in[1], data_out[1]};
197
 
198
    if (data_in[2:1] == 2'b10)
199
      data_out[3:2]  = 2'b11;
200
    else
201
      data_out[3:2]  = {data_in[2], data_out[2]};
202
 
203
    if (data_in[3:2] == 2'b10)
204
      data_out[4:3]  = 2'b11;
205
    else
206
      data_out[4:3]  = {data_in[3], data_out[3]};
207
 
208
    if (data_in[4:3] == 2'b10)
209
      data_out[5:4]  = 2'b11;
210
    else
211
      data_out[5:4]  = {data_in[4], data_out[4]};
212
 
213
    if (data_in[5:4] == 2'b10)
214
      data_out[6:5]  = 2'b11;
215
    else
216
      data_out[6:5]  = {data_in[5], data_out[5]};
217
 
218
    if (data_in[6:5] == 2'b10)
219
      data_out[7:6]  = 2'b11;
220
    else
221
      data_out[7:6]  = {data_in[6], data_out[6]};
222
 
223
    if (data_in[7:6] == 2'b10)
224
      data_out[8:7]  = 2'b11;
225
    else
226
      data_out[8:7]  = {data_in[7], data_out[7]};
227
  end
228
endtask
229
 
230
 
231
   always @(*) begin
232
    case(drp_ioi_addr)
233
`ifdef DRP_v1_0_FIX
234
      IOI_DQ0       : data_out_mux  = data_out<<1;
235
      IOI_DQ1       : data_out_mux  = data_out;
236
      IOI_DQ2       : data_out_mux  = data_out<<1;
237
//      IOI_DQ2       : data_out_mux  = data_out;
238
      IOI_DQ3       : data_out_mux  = data_out;
239
      IOI_DQ4       : data_out_mux  = data_out;
240
      IOI_DQ5       : data_out_mux  = data_out;
241
      IOI_DQ6       : shift_n_expand (data_out, data_out_mux);
242
//      IOI_DQ6       : data_out_mux  = data_out;
243
      IOI_DQ7       : data_out_mux  = data_out;
244
      IOI_DQ8       : data_out_mux  = data_out<<1;
245
      IOI_DQ9       : data_out_mux  = data_out;
246
      IOI_DQ10      : data_out_mux  = data_out<<1;
247
      IOI_DQ11      : data_out_mux  = data_out;
248
      IOI_DQ12      : data_out_mux  = data_out<<1;
249
      IOI_DQ13      : data_out_mux  = data_out;
250
      IOI_DQ14      : data_out_mux  = data_out<<1;
251
      IOI_DQ15      : data_out_mux  = data_out;
252
      IOI_UDQS_CLK  : data_out_mux  = data_out<<1;
253
      IOI_UDQS_PIN  : data_out_mux  = data_out<<1;
254
      IOI_LDQS_CLK  : data_out_mux  = data_out;
255
      IOI_LDQS_PIN  : data_out_mux  = data_out;
256
`else
257
`endif
258
      IOI_DQ0       : data_out_mux  = data_out;
259
      IOI_DQ1       : data_out_mux  = data_out;
260
      IOI_DQ2       : data_out_mux  = data_out;
261
      IOI_DQ3       : data_out_mux  = data_out;
262
      IOI_DQ4       : data_out_mux  = data_out;
263
      IOI_DQ5       : data_out_mux  = data_out;
264
      IOI_DQ6       : data_out_mux  = data_out;
265
      IOI_DQ7       : data_out_mux  = data_out;
266
      IOI_DQ8       : data_out_mux  = data_out;
267
      IOI_DQ9       : data_out_mux  = data_out;
268
      IOI_DQ10      : data_out_mux  = data_out;
269
      IOI_DQ11      : data_out_mux  = data_out;
270
      IOI_DQ12      : data_out_mux  = data_out;
271
      IOI_DQ13      : data_out_mux  = data_out;
272
      IOI_DQ14      : data_out_mux  = data_out;
273
      IOI_DQ15      : data_out_mux  = data_out;
274
      IOI_UDQS_CLK  : data_out_mux  = data_out;
275
      IOI_UDQS_PIN  : data_out_mux  = data_out;
276
      IOI_LDQS_CLK  : data_out_mux  = data_out;
277
      IOI_LDQS_PIN  : data_out_mux  = data_out;
278
      default       : data_out_mux  = data_out;
279
    endcase
280
   end
281
 
282
 
283
   /*********************************************
284
    *   Shift Registers / Bit Counter
285
    *********************************************/
286
   assign     data_out = (addr_data_sel_n)? {1'b0, memcell_addr_reg} : {1'b0, data_reg};
287
 
288
   always @ (posedge DRP_CLK) begin
289
      if(sync_rst)
290
        shift_through_reg <= 9'b0;
291
      else begin
292
        if (load_shift_n)     //Assume the shifter is either loading or shifting, bit 0 is shifted out first
293
          shift_through_reg <= data_out_mux;
294
        else
295
          shift_through_reg <= {1'b0, DRP_SDO, shift_through_reg[7:1]};
296
      end
297
   end
298
 
299
   always @ (posedge DRP_CLK) begin
300
      if (((state == ADDR_PHASE) | (state == DATA_PHASE)) & !sync_rst)
301
        bit_cnt <= bit_cnt + 1;
302
      else
303
        bit_cnt <= 3'b0;
304
   end
305
 
306
  always @ (posedge DRP_CLK) begin
307
    if(sync_rst) begin
308
      read_data <= 8'h00;
309
    end
310
    else begin
311
      if(state == ALMOST_READY3)
312
        read_data <= shift_through_reg;
313
    end
314
  end
315
 
316
  always @ (posedge DRP_CLK) begin
317
    if(sync_rst) begin
318
      AddressPhase  <= 1'b0;
319
    end
320
    else begin
321
      if (AddressPhase) begin
322
        // Keep it set until we finish the cycle
323
        AddressPhase <= AddressPhase && ~(state == ALMOST_READY2);
324
      end
325
      else begin
326
        // set the address phase when ever we finish the address phase
327
        AddressPhase <= (state == ADDR_PHASE) && (bit_cnt == 3'b111);
328
      end
329
    end
330
  end
331
 
332
   /*********************************************
333
    *   DRP Signals
334
    *********************************************/
335
   always @ (posedge DRP_CLK) begin
336
      DRP_ADD     <= (nextstate == ADDR_PHASE);
337
      DRP_CS      <= (nextstate == ADDR_PHASE) | (nextstate == DATA_PHASE);
338
//      DRP_CS      <= (drp_ioi_addr != IOI_DQ0) ? (nextstate == ADDR_PHASE) | (nextstate == DATA_PHASE) : (bit_cnt != 3'b111) && (nextstate == ADDR_PHASE) | (nextstate == DATA_PHASE);
339
      MCB_UIREAD  <= (nextstate == DATA_PHASE) && rd_not_write_reg;
340
      if (state == READY)
341
        DRP_BKST  <= use_broadcast;
342
   end
343
 
344
   assign DRP_SDI_pre = (DRP_CS)? shift_through_reg[0] : 1'b0;  //if DRP_CS is inactive, just drive 0 out - this is a possible place to pipeline for increased performance
345
   assign DRP_SDI = (rd_not_write_reg & DRP_CS & !DRP_ADD)? DRP_SDO : DRP_SDI_pre; //If reading, then feed SDI back out SDO - this is a possible place to pipeline for increased performance
346
 
347
 
348
   /*********************************************
349
    *   State Machine
350
    *********************************************/
351
  always @ (*) begin
352
    addr_data_sel_n = 1'b0;
353
    load_shift_n = 1'b0;
354
    case (state)
355
      READY:  begin
356
         load_shift_n = 0;
357
         if(cmd_valid)
358
          nextstate = DECIDE;
359
         else
360
          nextstate = READY;
361
        end
362
      DECIDE: begin
363
          load_shift_n = 1;
364
          addr_data_sel_n = 1;
365
          nextstate = ADDR_PHASE;
366
        end
367
      ADDR_PHASE: begin
368
         load_shift_n = 0;
369
         if(&bit_cnt[2:0])
370
           if (`ALTERNATE_READ && rd_not_write_reg)
371
             if (AddressPhase)
372
               // After the second pass go to end of statemachine
373
               nextstate = ALMOST_READY;
374
             else
375
               // execute a second address phase for the alternative access method.
376
               nextstate = DECIDE;
377
           else
378
            nextstate = ADDR_TO_DATA_GAP;
379
         else
380
          nextstate = ADDR_PHASE;
381
        end
382
      ADDR_TO_DATA_GAP: begin
383
          load_shift_n = 1;
384
          nextstate = ADDR_TO_DATA_GAP2;
385
        end
386
      ADDR_TO_DATA_GAP2: begin
387
         load_shift_n = 1;
388
         nextstate = ADDR_TO_DATA_GAP3;
389
        end
390
      ADDR_TO_DATA_GAP3: begin
391
         load_shift_n = 1;
392
         nextstate = DATA_PHASE;
393
        end
394
      DATA_PHASE: begin
395
         load_shift_n = 0;
396
         if(&bit_cnt)
397
            nextstate = ALMOST_READY;
398
         else
399
          nextstate = DATA_PHASE;
400
        end
401
      ALMOST_READY: begin
402
         load_shift_n = 0;
403
         nextstate = ALMOST_READY2;
404
         end
405
      ALMOST_READY2: begin
406
         load_shift_n = 0;
407
         nextstate = ALMOST_READY3;
408
         end
409
      ALMOST_READY3: begin
410
         load_shift_n = 0;
411
         nextstate = READY;
412
         end
413
      default: begin
414
         load_shift_n = 0;
415
         nextstate = READY;
416
       end
417
    endcase
418
  end
419
 
420
  always @ (posedge DRP_CLK) begin
421
    if(sync_rst)
422
      state <= READY;
423
    else
424
      state <= nextstate;
425
   end
426
 
427
endmodule

powered by: WebSVN 2.1.0

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