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 69

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

powered by: WebSVN 2.1.0

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