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

Subversion Repositories sdr_ctrl

[/] [sdr_ctrl/] [trunk/] [rtl/] [wb2sdrc/] [wb2sdrc.v] - Blame information for rev 37

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

Line No. Rev Author Line
1 31 dinesha
/*********************************************************************
2
 
3
  This file is part of the sdram controller project
4
  http://www.opencores.org/cores/sdr_ctrl/
5
 
6
  Description: WISHBONE to SDRAM Controller Bus Transalator
7 33 dinesha
     1. This module translate the WISHBONE protocol to custom sdram controller i/f
8
     2. Also Handle the clock domain change from Application layer to Sdram layer
9 31 dinesha
 
10
  To Do:
11
    nothing
12
 
13
  Author(s):  Dinesh Annayya, dinesha@opencores.org
14
 
15
 Copyright (C) 2000 Authors and OPENCORES.ORG
16
 
17
 This source file may be used and distributed without
18
 restriction provided that this copyright statement is not
19
 removed from the file and that any derivative work contains
20
 the original copyright notice and the associated disclaimer.
21
 
22
 This source file is free software; you can redistribute it
23
 and/or modify it under the terms of the GNU Lesser General
24
 Public License as published by the Free Software Foundation;
25
 either version 2.1 of the License, or (at your option) any
26
later version.
27
 
28
 This source is distributed in the hope that it will be
29
 useful, but WITHOUT ANY WARRANTY; without even the implied
30
 warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
31
 PURPOSE.  See the GNU Lesser General Public License for more
32
 details.
33
 
34
 You should have received a copy of the GNU Lesser General
35
 Public License along with this source; if not, download it
36
 from http://www.opencores.org/lgpl.shtml
37
 
38
*******************************************************************/
39
 
40
 
41
module wb2sdrc (
42
      // WB bus
43 33 dinesha
                    wb_rst_i            ,
44
                    wb_clk_i            ,
45 31 dinesha
 
46 33 dinesha
                    wb_stb_i            ,
47
                    wb_ack_o            ,
48
                    wb_addr_i           ,
49
                    wb_we_i             ,
50
                    wb_dat_i            ,
51
                    wb_sel_i            ,
52
                    wb_dat_o            ,
53
                    wb_cyc_i            ,
54
                    wb_cti_i            ,
55 31 dinesha
 
56
 
57
      //SDRAM Controller Hand-Shake Signal 
58 33 dinesha
                    sdram_clk           ,
59
                    sdram_resetn        ,
60
                    sdr_req             ,
61
                    sdr_req_addr        ,
62
                    sdr_req_len         ,
63
                    sdr_req_wr_n        ,
64
                    sdr_req_ack         ,
65
                    sdr_busy_n          ,
66
                    sdr_wr_en_n         ,
67
                    sdr_wr_next         ,
68
                    sdr_rd_valid        ,
69
                    sdr_last_rd         ,
70
                    sdr_wr_data         ,
71
                    sdr_rd_data
72 31 dinesha
 
73
      );
74
 
75
parameter      dw              = 32;  // data width
76
parameter      tw              = 8;   // tag id width
77
parameter      bl              = 9;   // burst_lenght_width 
78
//--------------------------------------
79
// Wish Bone Interface
80
// -------------------------------------      
81 33 dinesha
input                   wb_rst_i           ;
82
input                   wb_clk_i           ;
83 31 dinesha
 
84 33 dinesha
input                   wb_stb_i           ;
85
output                  wb_ack_o           ;
86
input [29:0]            wb_addr_i          ;
87
input                   wb_we_i            ; // 1 - Write , 0 - Read
88
input [dw-1:0]          wb_dat_i           ;
89
input [dw/8-1:0]        wb_sel_i           ; // Byte enable
90
output [dw-1:0]         wb_dat_o           ;
91
input                   wb_cyc_i           ;
92
input  [2:0]            wb_cti_i           ;
93 31 dinesha
/***************************************************
94
The Cycle Type Idenfier [CTI_IO()] Address Tag provides
95
additional information about the current cycle.
96
The MASTER sends this information to the SLAVE. The SLAVE can use this
97
information to prepare the response for the next cycle.
98
Table 4-2 Cycle Type Identifiers
99
CTI_O(2:0) Description
100
000 Classic cycle.
101
001 Constant address burst cycle
102
010 Incrementing burst cycle
103
011 Reserved
104
100 Reserved
105
101 Reserved
106
110 Reserved
107
111 End-of-Burst
108
****************************************************/
109
//--------------------------------------------
110
// SDRAM controller Interface 
111
//--------------------------------------------
112 33 dinesha
input                   sdram_clk          ; // sdram clock
113
input                   sdram_resetn       ; // sdram reset
114 31 dinesha
output                  sdr_req            ; // SDRAM request
115
output [29:0]           sdr_req_addr       ; // SDRAM Request Address
116
output [bl-1:0]         sdr_req_len        ;
117
output                  sdr_req_wr_n       ; // 0 - Write, 1 -> Read
118
input                   sdr_req_ack        ; // SDRAM request Accepted
119
input                   sdr_busy_n         ; // 0 -> sdr busy
120
output [dw/8-1:0]       sdr_wr_en_n        ; // Active low sdr byte-wise write data valid
121
input                   sdr_wr_next        ; // Ready to accept the next write
122
input                   sdr_rd_valid       ; // sdr read valid
123
input                   sdr_last_rd        ; // Indicate last Read of Burst Transfer
124
output [dw-1:0]         sdr_wr_data        ; // sdr write data
125
input  [dw-1:0]         sdr_rd_data        ; // sdr read data
126
 
127
//----------------------------------------------------
128
// Wire Decleration
129
// ---------------------------------------------------
130 33 dinesha
wire                    cmdfifo_full       ;
131
wire                    cmdfifo_empty      ;
132
wire                    wrdatafifo_full    ;
133
wire                    wrdatafifo_empty   ;
134
wire                    tagfifo_full       ;
135
wire                    tagfifo_empty      ;
136
wire                    rddatafifo_empty   ;
137
wire                    rddatafifo_full    ;
138 31 dinesha
 
139 33 dinesha
reg                     pending_read       ;
140 31 dinesha
 
141
 
142 33 dinesha
//-----------------------------------------------------------------------------
143
// Ack Generaltion Logic
144
//  If Write Request - Acknowledge if the command and write FIFO are not full
145
//  If Read Request  - Generate the Acknowledgment once read fifo has data
146
//                     available
147
//-----------------------------------------------------------------------------
148 31 dinesha
 
149
assign wb_ack_o = (wb_stb_i && wb_cyc_i && wb_we_i) ?  // Write Phase
150
                          ((!cmdfifo_full) && (!wrdatafifo_full)) :
151
                  (wb_stb_i && wb_cyc_i && !wb_we_i) ? // Read Phase 
152
                           !rddatafifo_empty : 1'b0;
153
 
154 33 dinesha
//---------------------------------------------------------------------------
155
// Command FIFO Write Generation
156
//    If Write Request - Generate write, when Write fifo and command fifo is
157
//                       not full
158
//    If Read Request - Generate write, when command fifo not full and there
159
//                      is no pending read request.
160
//---------------------------------------------------------------------------
161
wire           cmdfifo_wr   = (wb_stb_i && wb_cyc_i && wb_we_i && (!cmdfifo_full) ) ? wb_ack_o :
162
                              (wb_stb_i && wb_cyc_i && !wb_we_i && (!cmdfifo_full)) ? !pending_read: 1'b0 ;
163
 
164
//---------------------------------------------------------------------------
165
// command fifo read generation
166
//    Command FIFo read will be generated, whenever SDRAM Controller
167
//    Acknowldge the Request
168
//----------------------------------------------------------------------------
169
 
170 31 dinesha
wire           cmdfifo_rd   = sdr_req_ack;
171 33 dinesha
 
172
//---------------------------------------------------------------------------
173
// Application layer request is generated towards the controller, whenever
174
// Command FIFO is not full
175
// --------------------------------------------------------------------------
176 31 dinesha
assign         sdr_req      = !cmdfifo_empty;
177
 
178 33 dinesha
//----------------------------------------------------------------------------
179
// Since Burst length is not known at the start of the Burst, It's assumed as
180
// Single Cycle Burst. We need to improvise this ...
181
// --------------------------------------------------------------------------
182 31 dinesha
wire [bl-1:0]  burst_length  = 1;  // 0 Mean 1 Transfer
183
 
184 33 dinesha
//-----------------------------------------------------------------------------
185
// In Wish Bone Spec, For Read Request has to be acked along with data.
186
// We need to identify the pending read request.
187
// Once we accept the read request, we should not accept one more read
188
// request, untill we have transmitted the read data.
189
//  Pending Read will 
190
//     set - with Read Request 
191
//     reset - with Read Request + Ack
192
// ----------------------------------------------------------------------------
193 31 dinesha
always @(posedge wb_rst_i or posedge wb_clk_i) begin
194
   if(wb_rst_i) begin
195
       pending_read <= 1'b0;
196
   end else begin
197
      pending_read <=  wb_stb_i & wb_cyc_i & !wb_we_i & !wb_ack_o;
198
   end
199
end
200
 
201 33 dinesha
//---------------------------------------------------------------------
202
// Async Command FIFO. This block handle the clock domain change from
203
// Application layer to SDRAM Controller
204
// ------------------------------------------------------------------
205 31 dinesha
   // Address + Burst Length + W/R Request 
206
    async_fifo #(.W(30+bl+1),.DP(4)) u_cmdfifo (
207
     // Write Path Sys CLock Domain
208 33 dinesha
          .wr_clk             (wb_clk_i           ),
209
          .wr_reset_n         (!wb_rst_i          ),
210
          .wr_en              (cmdfifo_wr         ),
211
          .wr_data            ({burst_length,
212
                                !wb_we_i,
213
                                wb_addr_i}        ),
214
          .afull              (                   ),
215
          .full               (cmdfifo_full       ),
216 31 dinesha
 
217
     // Read Path, SDRAM clock domain
218 33 dinesha
          .rd_clk             (sdram_clk          ),
219
          .rd_reset_n         (sdram_resetn       ),
220
          .aempty             (                   ),
221
          .empty              (cmdfifo_empty      ),
222
          .rd_en              (cmdfifo_rd         ),
223
          .rd_data            ({sdr_req_len,
224
                                sdr_req_wr_n,
225
                                sdr_req_addr}     )
226 31 dinesha
     );
227
 
228
// synopsys translate_off
229
always @(posedge wb_clk_i) begin
230
  if (cmdfifo_full == 1'b1 && cmdfifo_wr == 1'b1)  begin
231
     $display("ERROR:%m COMMAND FIFO WRITE OVERFLOW");
232
  end
233
end
234 37 dinesha
// synopsys translate_on
235 31 dinesha
// synopsys translate_off
236
always @(posedge sdram_clk) begin
237
   if (cmdfifo_empty == 1'b1 && cmdfifo_rd == 1'b1) begin
238
      $display("ERROR:%m COMMAND FIFO READ OVERFLOW");
239
   end
240
end
241
// synopsys translate_on
242
 
243 33 dinesha
//---------------------------------------------------------------------
244
// Write Data FIFO Write Generation, when ever Acked + Write Request
245
//   Note: Ack signal generation already taking account of FIFO full condition
246
// ---------------------------------------------------------------------
247 31 dinesha
 
248
wire  wrdatafifo_wr  = wb_ack_o & wb_we_i ;
249 33 dinesha
 
250
//------------------------------------------------------------------------
251
// Write Data FIFO Read Generation, When ever Next Write request generated
252
// from SDRAM Controller
253
// ------------------------------------------------------------------------
254 31 dinesha
wire  wrdatafifo_rd  = sdr_wr_next;
255
 
256
 
257 33 dinesha
//------------------------------------------------------------------------
258
// Async Write Data FIFO
259
//    This block handle the clock domain change over + Write Data + Byte mask 
260
//    From Application layer to SDRAM controller layer
261
//------------------------------------------------------------------------
262
 
263 31 dinesha
   // Write DATA + Data Mask FIFO
264
    async_fifo #(.W(dw+(dw/8)), .DP(16)) u_wrdatafifo (
265
       // Write Path , System clock domain
266 33 dinesha
          .wr_clk             (wb_clk_i           ),
267
          .wr_reset_n         (!wb_rst_i          ),
268
          .wr_en              (wrdatafifo_wr      ),
269
          .wr_data            ({~wb_sel_i,
270
                                 wb_dat_i}        ),
271
          .afull              (                   ),
272
          .full               (wrdatafifo_full    ),
273 31 dinesha
 
274
 
275
       // Read Path , SDRAM clock domain
276 33 dinesha
          .rd_clk             (sdram_clk          ),
277
          .rd_reset_n         (sdram_resetn       ),
278
          .aempty             (                   ),
279
          .empty              (wrdatafifo_empty   ),
280
          .rd_en              (wrdatafifo_rd      ),
281
          .rd_data            ({sdr_wr_en_n,
282
                                sdr_wr_data}      )
283 31 dinesha
     );
284
// synopsys translate_off
285
always @(posedge wb_clk_i) begin
286
  if (wrdatafifo_full == 1'b1 && wrdatafifo_wr == 1'b1)  begin
287
     $display("ERROR:%m WRITE DATA FIFO WRITE OVERFLOW");
288
  end
289
end
290
 
291
always @(posedge sdram_clk) begin
292
   if (wrdatafifo_empty == 1'b1 && wrdatafifo_rd == 1'b1) begin
293
      $display("ERROR:%m WRITE DATA FIFO READ OVERFLOW");
294
   end
295
end
296
// synopsys translate_on
297
 
298
// -------------------------------------------------------------------
299
//  READ DATA FIFO
300
//  ------------------------------------------------------------------
301
wire    rd_eop; // last read indication
302 33 dinesha
 
303
// Read FIFO write generation, when ever SDRAM controller issues the read
304
// valid signal
305 31 dinesha
wire    rddatafifo_wr = sdr_rd_valid;
306
 
307 33 dinesha
// Read FIFO read generation, when ever ack is generated along with read
308
// request.
309
// Note: Ack generation is already accounted the write FIFO Not Empty
310
//       condition
311
wire    rddatafifo_rd = wb_ack_o & !wb_we_i;
312
 
313
//-------------------------------------------------------------------------
314
// Async Read FIFO
315
// This block handles the clock domain change over + Read data from SDRAM
316
// controller to Application layer.
317
//  Note: 
318
//    1. READ DATA FIFO depth is kept small, assuming that Sys-CLock > SDRAM Clock
319
//       READ DATA + EOP
320
//    2. EOP indicate, last transfer of Burst Read Access. use-full for future
321
//       Tag handling per burst
322
//
323
// ------------------------------------------------------------------------
324 31 dinesha
    async_fifo #(.W(dw+1), .DP(4)) u_rddatafifo (
325
       // Write Path , SDRAM clock domain
326 33 dinesha
          .wr_clk             (sdram_clk          ),
327
          .wr_reset_n         (sdram_resetn       ),
328
          .wr_en              (rddatafifo_wr      ),
329
          .wr_data            ({sdr_last_rd,
330
                                sdr_rd_data}      ),
331
          .afull              (                   ),
332
          .full               (rddatafifo_full    ),
333 31 dinesha
 
334
 
335
       // Read Path , SYS clock domain
336 33 dinesha
          .rd_clk             (wb_clk_i           ),
337
          .rd_reset_n         (!wb_rst_i          ),
338
          .empty              (rddatafifo_empty   ),
339
          .aempty             (                   ),
340
          .rd_en              (rddatafifo_rd      ),
341
          .rd_data            ({rd_eop,
342
                                wb_dat_o}         )
343 31 dinesha
     );
344
 
345
// synopsys translate_off
346
always @(posedge sdram_clk) begin
347
  if (rddatafifo_full == 1'b1 && rddatafifo_wr == 1'b1)  begin
348
     $display("ERROR:%m READ DATA FIFO WRITE OVERFLOW");
349
  end
350
end
351
 
352
always @(posedge wb_clk_i) begin
353
   if (rddatafifo_empty == 1'b1 && rddatafifo_rd == 1'b1) begin
354
      $display("ERROR:%m READ DATA FIFO READ OVERFLOW");
355
   end
356
end
357
// synopsys translate_on
358
 
359
 
360
endmodule

powered by: WebSVN 2.1.0

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