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

Subversion Repositories sdram

[/] [sdram/] [trunk/] [hostcont.v] - Blame information for rev 12

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 2 jlee
`include "inc.h"
2
 
3 4 jlee
//*******************************************************************************
4 6 jlee
//  S Y N T H E S I Z A B L E      S D R A M     C O N T R O L L E R    C O R E
5 4 jlee
//
6
//  This core adheres to the GNU Public License  
7
// 
8
//  This is a synthesizable Synchronous DRAM controller Core.  As it stands,
9
//  it is ready to work with 8Mbyte SDRAMs, organized as 2M x 32 at 100MHz
10
//  and 125MHz. For example: Samsung KM432S2030CT,  Fujitsu MB81F643242B.
11
//
12
//  The core has been carefully coded so as to be "platform-independent".  
13
//  It has been successfully compiled and simulated under three separate
14
//  FPGA/CPLD platforms:
15
//      Xilinx Foundation Base Express V2.1i
16
//      Altera Max+PlusII V9.21
17
//      Lattice ispExpert V7.0
18
//  
19
//  The interface to the host (i.e. microprocessor, DSP, etc) is synchronous
20
//  and supports ony one transfer at a time.  That is, burst-mode transfers
21
//  are not yet supported.  In may ways, the interface to this core is much
22
//  like that of a typical SRAM.  The hand-shaking between the host and the 
23
//  SDRAM core is done through the "sdram_busy_l" signal generated by the 
24
//  core.  Whenever this signal is active low, the host must hold the address,
25
//  data (if doing a write), size and the controls (cs, rd/wr).  
26
//
27
//  Connection Diagram:
28
//  SDRAM side:
29
//  sd_wr_l                     connect to -WR pin of SDRAM
30
//  sd_cs_l                     connect to -CS pin of SDRAM
31
//  sd_ras_l                    connect to -RAS pin of SDRAM
32
//  sd_cas_l                    connect to -CAS pin of SDRAM
33
//  sd_dqm[3:0]                 connect to the DQM3,DQM2,DQM1,DQM0 pins
34
//  sd_addx[10:0]               connect to the Address bus [10:0]
35
//  sd_data[31:0]               connect to the data bus [31:0]
36
//  sd_ba[1:0]                  connect to BA1, BA0 pins of SDRAM
37
//   
38
//  HOST side:
39
//  mp_addx[22:0]               connect to the address bus of the host. 
40
//                              23 bit address bus give access to 8Mbyte
41
//                              of the SDRAM, as byte, half-word (16bit)
42
//                              or word (32bit)
43
//  mp_data_in[31:0]            Unidirectional bus connected to the data out
44
//                              of the host. To use this, enable 
45
//                              "databus_is_unidirectional" in INC.H
46
//  mp_data_out[31:0]           Unidirectional bus connected to the data in 
47
//                              of the host.  To use this, enable
48
//                              "databus_is_unidirectional" in INC.H
49
//  mp_data[31:0]               Bi-directional bus connected to the host's
50
//                              data bus.  To use the bi-directionla bus,
51
//                              disable "databus_is_unidirectional" in INC.H
52
//  mp_rd_l                     Connect to the -RD output of the host
53
//  mp_wr_l                     Connect to the -WR output of the host
54
//  mp_cs_l                     Connect to the -CS of the host
55
//  mp_size[1:0]                Connect to the size output of the host
56
//                              if there is one.  When set to 0
57
//                              all trasnfers are 32 bits, when set to 1
58
//                              all transfers are 8 bits, and when set to
59
//                              2 all xfers are 16 bits.  If you want the
60
//                              data to be lower order aligned, turn on
61
//                              "align_data_bus" option in INC.H
62
//  sdram_busy_l                Connect this to the wait or hold equivalent
63
//                              input of the host.  The host, must hold the
64
//                              bus if it samples this signal as low.
65
//  sdram_mode_set_l            When a write occurs with this set low,
66
//                              the SDRAM's mode set register will be programmed
67
//                              with the data supplied on the data_bus[10:0].
68
//
69
//
70
//  Author:  Jeung Joon Lee  joon.lee@quantum.com,  cmosexod@ix.netcom.com
71
//  
72
//*******************************************************************************
73
//
74
//  Hierarchy:
75
//
76
//  SDRAM.V         Top Level Module
77
//  HOSTCONT.V      Controls the interfacing between the micro and the SDRAM
78
//  SDRAMCNT.V      This is the SDRAM controller.  All data passed to and from
79
//                  is with the HOSTCONT.
80
//  optional
81
//  MICRO.V         This is the built in SDRAM tester.  This module generates 
82
//                  a number of test logics which is used to test the SDRAM
83
//                  It is basically a Micro bus generator. 
84
//  
85 2 jlee
/*
86 4 jlee
*/
87 2 jlee
 
88
module hostcont (
89
                    // system connections
90
                    sys_rst_l,
91
                    sys_clk,
92
 
93
                    // microprocessor side connections
94
                    mp_addx,
95
                    mp_data_in,
96
                    mp_data_out,
97
                    mp_rd_l,
98
                    mp_wr_l,
99
                    mp_cs_l,
100
                    sdram_mode_set_l,
101
                    sdram_busy_l,
102 4 jlee
                    mp_size,
103 2 jlee
 
104
                    // SDRAM side connections
105
                    sd_addx,
106 4 jlee
                    sd_data_out,
107
                    sd_data_in,
108 2 jlee
                    sd_ba,
109
 
110
                    // SDRAMCNT side
111
                    sd_addx10_mux,
112
                    sd_addx_mux,
113
                    sd_rd_ena,
114
                    do_read,
115
                    do_write,
116
                    doing_refresh,
117
                    do_modeset,
118
                    modereg_cas_latency,
119
                    modereg_burst_length,
120
                    mp_data_mux,
121 4 jlee
                    decoded_dqm,
122
                    do_write_ack,
123
                    do_read_ack,
124
                    do_modeset_ack,
125
                    pwrup,
126 2 jlee
 
127
 
128
                    // debug
129
//                    rd_wr_clk
130 4 jlee
                    reg_mp_data_mux,
131
                    reg_mp_addx,
132 6 jlee
                    reg_sd_data,
133
                    reg_modeset
134 2 jlee
 
135
             );
136
 
137
 
138
// ****************************************
139
//
140
//   I/O  DEFINITION
141
//
142
// ****************************************
143
 
144
// system connections
145
input           sys_rst_l;          // asynch active low reset
146
input           sys_clk;            // clock source to the SDRAM
147
 
148
// microprocessor side connections
149 4 jlee
input   [22:0]  mp_addx;         // ABW bits for the addx
150
input   [31:0]  mp_data_in;      // DBW bits of data bus input (see INC.H)
151
output  [31:0]  mp_data_out;     // DBW bits of data bus output (see INC.H)
152 2 jlee
input           mp_rd_l;            // micro bus read , active low
153
input           mp_wr_l;            // micro bus write, active low
154
input           mp_cs_l;
155
input           sdram_mode_set_l;   // acive low request for SDRAM mode set
156
output          sdram_busy_l;       // active low busy output
157 4 jlee
input   [1:0]   mp_size;
158 2 jlee
 
159
// SDRAM side connections
160
output  [10:0]  sd_addx;            // 11 bits of muxed SDRAM addx
161 4 jlee
input   [31:0]  sd_data_in;
162
output  [31:0]  sd_data_out;
163
output  [1:0]   sd_ba;              // bank select output to the SDRAM
164
input           pwrup;
165 2 jlee
 
166
// SDRAMCNT side
167
input   [1:0]   sd_addx10_mux;
168
input   [1:0]   sd_addx_mux;
169
input           sd_rd_ena;
170
output          do_write;
171
output          do_read;
172
input           doing_refresh;
173
output          do_modeset;
174
output  [2:0]   modereg_cas_latency;
175
output  [2:0]   modereg_burst_length;
176
input           mp_data_mux;
177 4 jlee
output  [3:0]   decoded_dqm;        // this is the decoded DQM according to the size. Used during writes
178
input           do_write_ack;       // acknowledge signal from sdramcont state machine
179
                                    // saying that it is now ok to clear 'do_write' signal
180
input           do_read_ack;        // acknowledge signal from sdramcont state machine
181
                                    // saying that is is now ok to clear 'do_read' signal
182
input           do_modeset_ack;
183 2 jlee
 
184
 
185
//debug
186
//output          rd_wr_clk;
187 4 jlee
output  [31:0]  reg_mp_data_mux;
188
output  [22:0]  reg_mp_addx;
189
output  [31:0]  reg_sd_data;
190 6 jlee
output  [10:0]  reg_modeset;
191 2 jlee
 
192
// ****************************************
193
//
194
// Memory Elements 
195
//
196
// ****************************************
197
//
198 4 jlee
wire    [22:0]  reg_mp_addx;
199
reg     [31:0]  reg_mp_data;
200
reg     [31:0]  reg_sd_data;
201
reg     [3:0]   decoded_dqm;
202 2 jlee
reg     [10:0]  reg_modeset;
203
reg     [10:0]  sd_addx;
204
reg             do_read;
205
reg             do_write;
206 4 jlee
reg     [2:0]   do_state;
207 2 jlee
reg             do_modeset;
208 4 jlee
reg     [1:0]   sd_ba;
209
reg             busy_a_ena;
210
 
211
//wire  [31:0]  sd_data;
212
wire    [31:0]  sd_data_buff;
213
wire    [31:0]  reg_mp_data_mux;
214
reg     [31:0]  mp_data_out;
215
wire            busy_a;
216 2 jlee
wire            mp_data_ena;
217
wire            do_read_clk;
218 4 jlee
wire            do_read_rst_clk;
219 2 jlee
wire            do_write_clk;
220 4 jlee
wire            do_modeset_clk;
221
wire            do_modeset_rst_clk;
222 2 jlee
wire            clock_xx;
223 4 jlee
wire            modereg_ena;
224 2 jlee
wire            read_busy;
225
wire            write_busy;
226
wire            refresh_busy;
227 4 jlee
wire            modeset_busy;
228 2 jlee
wire            do_write_rst;
229 4 jlee
wire            do_read_rst;
230
wire            do_modeset_rst;
231 2 jlee
 
232
 
233
assign mp_data_ena  = ~mp_rd_l;
234
assign modereg_cas_latency  =  reg_modeset[6:4];
235
assign modereg_burst_length =  reg_modeset[2:0];
236
 
237 4 jlee
assign read_busy    = do_read  | (~mp_rd_l & busy_a_ena);
238
assign write_busy   = do_write | (~mp_wr_l & busy_a_ena);
239
assign modeset_busy = do_modeset;
240 2 jlee
assign refresh_busy = `LO;
241
 
242
// SDRAM BUSY SIGNAL GENERATION
243
//
244
// The BUSY signal is NOR'd of READ_BUSY, WRITE_BUSY and DUMB_BUSY.
245
// READ_BUSY is generated while the SDRAM is performing a read.  This 
246
// does not necessarily have to he synchronous to the micro's read.  
247
// The WRITE_BUSY is generated while the SDRAM is performing WRITE.
248
// Again, due to the "dump-n-run" mode (only in SMART_H=1) the micro's
249
// write bus cycle does not necessarily align with SDRAM's write cycle.
250
// DUMB_BUSY is a signal which generates the BUSY at the falling edge of
251
// micro's SDRAM_CS.  This is used for those microprocessors which 
252
// require a device BUSY as soon as the address is placed on its bus.  For
253
// example, most Intel microcontrollers and small processors do have this
254
// requirement.  This means that one will fofeit on the dump-n-go feature.
255
// 
256 4 jlee
assign sdram_busy_l = ~(  read_busy                |
257
                          write_busy               |
258
                         (doing_refresh & ~mp_cs_l)|
259
                         (modeset_busy  & ~mp_cs_l)
260
                       );
261 2 jlee
 
262
 
263
// MP ADDRESS LATCH
264
// Transparent latch
265
// Used to hold the addx from the micro. Latch on the falling edge of
266 4 jlee
// do_write.
267
// BAsed on the way "do_write" is generated, we only need to latch on the writes
268
// since the write can be queued, but since all reads are blocked, the latch
269
// will not latch the addx on reads.  
270
assign reg_mp_addx = mp_addx;
271 2 jlee
 
272 4 jlee
 
273
//
274
// DECODED DQM LATCH
275
// generate the proper DQM[3:0] masks based on the address and on the mp_size 
276
//
277
always @(do_write or sys_rst_l or mp_addx or mp_size)
278
    // 32 bit masks
279
    // all masks are enabled (LOW)
280
    if (mp_size==2'b00)
281
       decoded_dqm <= 4'h0;
282
    // 16 bit masks
283
    // enable the masks accorsing to the half-word selected
284
    else if (mp_size==2'b10)
285
       case (mp_addx[1])
286
          `LO:      decoded_dqm <= 4'b1100;     // lower half-word enabled
287
           default: decoded_dqm <= 4'b0011;     // upper half-word enabled
288
       endcase
289
    // 8 bit masks
290
    // enablethe masks according to the byte specified.
291
    else if (mp_size==2'b01)
292
       case (mp_addx[1:0])
293
       2'b00:   decoded_dqm <= 4'b1110;
294
       2'b01:   decoded_dqm <= 4'b1101;
295
       2'b10:   decoded_dqm <= 4'b1011;
296
           default: decoded_dqm <= 4'b0111;
297
       endcase
298
    else
299
        decoded_dqm <= 4'bxxxx;
300
 
301
 
302 2 jlee
// MP DATA LATCH
303
// Used to hold the data from the micro.  Latch on the rising edge
304
// of mp_wr_l
305 4 jlee
//
306
`ifdef align_data_bus
307
always @(mp_data_in or reg_mp_addx)
308
    // 32 bit writes
309
    if (mp_size==2'b00)
310
       reg_mp_data <= mp_data_in;
311
    // 16 bit writes
312
    else if (mp_size==2'b10)
313
       case(reg_mp_addx[1])
314
            `LO:     reg_mp_data[15:0] <= mp_data_in[15:0];
315
            default: reg_mp_data[31:16] <= mp_data_in[15:0];
316
       endcase
317
    // 8 bit writes
318
    else if (mp_size==2'b01)
319
       case(reg_mp_addx[1:0])
320
            2'b00:   reg_mp_data[7:0]   <= mp_data_in[7:0];
321
            2'b01:   reg_mp_data[15:8]  <= mp_data_in[7:0];
322
            2'b10:   reg_mp_data[23:16] <= mp_data_in[7:0];
323
            default: reg_mp_data[31:24] <= mp_data_in[7:0];
324
       endcase
325
//---------------------------------- if data aligning is not desired -------------------
326 2 jlee
`else
327 4 jlee
always @(mp_data_in)
328
     reg_mp_data <= mp_data_in;
329 2 jlee
`endif
330
 
331
 
332 4 jlee
//
333
// MODE REG REG
334
//
335
`define default_mode_reg {4'b0000,`default_mode_reg_CAS_LATENCY,`defulat_mode_reg_BURST_TYPE,`default_mode_reg_BURST_LENGHT}
336 2 jlee
always @(posedge sys_clk or negedge sys_rst_l)
337 4 jlee
    if (~sys_rst_l)
338
        reg_modeset <= 10'h000;
339
    else
340
    if (pwrup)
341
        reg_modeset <= `default_mode_reg;
342
    else
343
    if (~sdram_mode_set_l & ~mp_cs_l & ~mp_wr_l)
344
        reg_modeset <= mp_data_in[10:0];
345
 
346
// SD DATA REGISTER
347
// This register holds in the data from the SDRAM
348
//
349
always @(posedge sys_clk or negedge sys_rst_l)
350 2 jlee
  if (~sys_rst_l)
351 4 jlee
    reg_sd_data <= 32'h00000000;
352 2 jlee
  else if (sd_rd_ena)
353
    reg_sd_data <= sd_data_buff;
354
 
355
 
356 4 jlee
//
357
// SD DATA BUS BUFFERS
358
//
359
assign sd_data_out  = reg_mp_data;
360
assign sd_data_buff = sd_data_in;
361
 
362
 
363
 
364 2 jlee
// SDRAM SIDE ADDX
365 6 jlee
always @(sd_addx10_mux or reg_mp_data or reg_mp_addx or reg_modeset)
366 2 jlee
  case (sd_addx10_mux)
367 4 jlee
    2'b00:   sd_addx[10] <= reg_mp_addx[20];
368 2 jlee
    2'b01:   sd_addx[10] <= 1'b0;
369 6 jlee
    2'b10:   sd_addx[10] <= reg_modeset[10];
370 2 jlee
    default: sd_addx[10] <= 1'b1;
371
  endcase
372
 
373
always @(sd_addx_mux or reg_modeset or reg_mp_addx)
374
  case (sd_addx_mux)
375 4 jlee
    2'b00:   sd_addx[9:0] <= reg_mp_addx[19:10];               // ROW
376
    2'b01:   sd_addx[9:0] <= {2'b00, reg_mp_addx[9:2]};        // COLUMN
377 2 jlee
    2'b10:   sd_addx[9:0] <= reg_modeset[9:0];
378
    default: sd_addx[9:0] <= 10'h000;
379
  endcase
380
 
381
 
382
// SD_BA
383
always @(sd_addx_mux or reg_mp_addx)
384
  case (sd_addx_mux)
385 4 jlee
    2'b00:    sd_ba <= reg_mp_addx[22:21];
386
    2'b01:    sd_ba <= reg_mp_addx[22:21];
387
    default:  sd_ba <= 2'b00;
388 2 jlee
  endcase
389
 
390
 
391
 
392
// Micro data mux
393 4 jlee
assign reg_mp_data_mux = mp_data_mux ? 32'h00000000 : reg_mp_data;
394 2 jlee
 
395 4 jlee
// MP_DATA_OUT mux
396
// ------------------------------- do this only if the DATA aligning is desired -------
397
`ifdef align_data_bus
398
always @(mp_size or reg_sd_data or mp_addx)
399
  case (mp_size)
400
     // 32 bit reads
401
     2'b00:
402
         mp_data_out <= reg_sd_data;
403
     // 16 bit reads
404
     2'b10:
405
         if (mp_addx[1])
406
            mp_data_out[15:0] <= reg_sd_data[31:16];
407
         else
408
            mp_data_out[15:0] <= reg_sd_data[15:0];
409
     // 8 bit reads
410
     default:
411
         case (mp_addx[1:0])
412
             2'b00:   mp_data_out[7:0] <= reg_sd_data[7:0];
413
             2'b01:   mp_data_out[7:0] <= reg_sd_data[15:0];
414
             2'b10:   mp_data_out[7:0] <= reg_sd_data[23:16];
415
             default: mp_data_out[7:0] <= reg_sd_data[31:24];
416
         endcase
417
  endcase
418
`else
419
//---------------------------------- if data aligning is not desired -------------------
420
always @(reg_sd_data)
421
  mp_data_out <= reg_sd_data;
422
`endif
423 2 jlee
 
424
//
425 4 jlee
// DO_READ   DO_WRITE   DO_MODESET
426
// signal generation
427 2 jlee
//
428
 
429 4 jlee
always @(posedge sys_clk or negedge sys_rst_l)
430
  if (~sys_rst_l) begin
431
    do_read  <= `LO;
432 2 jlee
    do_write <= `LO;
433 4 jlee
    do_modeset <= `LO;
434
    do_state <= 3'b000;
435
    busy_a_ena <= `HI;
436
  end
437 2 jlee
  else
438 4 jlee
    case (do_state)
439
        // hang in here until a read or write is requested 
440
        // (mp_rd_l = 1'b0) or (mp_wr_l = 1'b0)
441
        3'b000: begin
442
            // a read request
443
            if (~mp_rd_l & ~mp_cs_l) begin
444
                do_read <= `HI;
445
                do_state <= 3'b001;
446
            end
447
            // a write request
448
            else if (~mp_wr_l & ~mp_cs_l & sdram_mode_set_l) begin
449
                do_write <= `HI;
450
                do_state <= 3'b001;
451
            end
452
            // a mode set request
453
            else if (~mp_wr_l & ~mp_cs_l & ~sdram_mode_set_l) begin
454
                do_modeset <= `HI;
455
                do_state <= 3'b001;
456
            end
457
            else
458
                do_state <= 3'b000;
459
        end
460
 
461
        // This cycle is dummy cycle.  Just to extend 'busy_ena_a' 
462
        // to a total of 2 cycles 
463
        3'b001:
464
            begin
465
                busy_a_ena <= `LO;      // disable busy_a generation
466
                if (do_write)
467
                   do_state <= 3'b011;
468
                else if (do_read)
469
                   do_state <= 3'b010;
470
                else if (do_modeset)
471
                   do_state <= 3'b110;
472
                else
473
                   do_state <= 3'b001;
474
            end
475 2 jlee
 
476 4 jlee
        // hang in here until the sdramcnt has acknowledged the
477
        // read
478
        3'b010:
479
            if (do_read_ack) begin
480
                do_read <= `LO;
481
                do_state <= 3'b100;
482
            end
483
            else
484
                do_state <= 3'b010;
485 2 jlee
 
486 4 jlee
        // hang in here until the sdramcnt has acknowledged the 
487
        // write
488
        3'b011:
489
            if (do_write_ack) begin
490
                do_write <= `LO;
491
                do_state <= 3'b101;
492
            end
493
            else
494
                do_state <= 3'b011;
495 2 jlee
 
496 4 jlee
        // wait in here until the host has read the data
497
        // (i.e. has raised its mp_rd_l high)
498
        3'b100:
499
            if (mp_rd_l) begin
500
                busy_a_ena <= `HI;      // re-enable busy_a generation
501
                do_state <= 3'b000;
502
            end
503
            else
504
                do_state <= 3'b100;
505
 
506
        // wait in here until the host has relinquieshed the write bus
507
        // (i.e. has raised its mp_wr_l high)
508
        3'b101:
509
            if (mp_wr_l) begin
510
                busy_a_ena <= `HI;      // re-enable busy_a generation
511
                do_state <= 3'b000;
512
            end
513
            else
514
                do_state <= 3'b101;
515 2 jlee
 
516 4 jlee
        // hang in here until the sdramcnt has acknowledged the 
517
        // mode set
518
        3'b110:
519
            if (do_modeset_ack) begin
520
                do_modeset <= `LO;
521
                do_state <= 3'b101;
522
            end else
523
                do_state <= 3'b110;
524 2 jlee
 
525
 
526 4 jlee
    endcase
527
 
528 2 jlee
 
529
 
530 4 jlee
 
531 2 jlee
endmodule
532
 

powered by: WebSVN 2.1.0

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