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 42

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 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
//--------------------------------------
87
// Wish Bone Interface
88
// -------------------------------------      
89 33 dinesha
input                   wb_rst_i           ;
90
input                   wb_clk_i           ;
91 31 dinesha
 
92 33 dinesha
input                   wb_stb_i           ;
93
output                  wb_ack_o           ;
94
input [29:0]            wb_addr_i          ;
95
input                   wb_we_i            ; // 1 - Write , 0 - Read
96
input [dw-1:0]          wb_dat_i           ;
97
input [dw/8-1:0]        wb_sel_i           ; // Byte enable
98
output [dw-1:0]         wb_dat_o           ;
99
input                   wb_cyc_i           ;
100
input  [2:0]            wb_cti_i           ;
101 31 dinesha
/***************************************************
102
The Cycle Type Idenfier [CTI_IO()] Address Tag provides
103
additional information about the current cycle.
104
The MASTER sends this information to the SLAVE. The SLAVE can use this
105
information to prepare the response for the next cycle.
106
Table 4-2 Cycle Type Identifiers
107
CTI_O(2:0) Description
108
000 Classic cycle.
109
001 Constant address burst cycle
110
010 Incrementing burst cycle
111
011 Reserved
112
100 Reserved
113
101 Reserved
114
110 Reserved
115
111 End-of-Burst
116
****************************************************/
117
//--------------------------------------------
118
// SDRAM controller Interface 
119
//--------------------------------------------
120 33 dinesha
input                   sdram_clk          ; // sdram clock
121
input                   sdram_resetn       ; // sdram reset
122 31 dinesha
output                  sdr_req            ; // SDRAM request
123
output [29:0]           sdr_req_addr       ; // SDRAM Request Address
124
output [bl-1:0]         sdr_req_len        ;
125
output                  sdr_req_wr_n       ; // 0 - Write, 1 -> Read
126
input                   sdr_req_ack        ; // SDRAM request Accepted
127
input                   sdr_busy_n         ; // 0 -> sdr busy
128
output [dw/8-1:0]       sdr_wr_en_n        ; // Active low sdr byte-wise write data valid
129
input                   sdr_wr_next        ; // Ready to accept the next write
130
input                   sdr_rd_valid       ; // sdr read valid
131
input                   sdr_last_rd        ; // Indicate last Read of Burst Transfer
132
output [dw-1:0]         sdr_wr_data        ; // sdr write data
133
input  [dw-1:0]         sdr_rd_data        ; // sdr read data
134
 
135
//----------------------------------------------------
136
// Wire Decleration
137
// ---------------------------------------------------
138 33 dinesha
wire                    cmdfifo_full       ;
139
wire                    cmdfifo_empty      ;
140
wire                    wrdatafifo_full    ;
141
wire                    wrdatafifo_empty   ;
142
wire                    tagfifo_full       ;
143
wire                    tagfifo_empty      ;
144
wire                    rddatafifo_empty   ;
145
wire                    rddatafifo_full    ;
146 31 dinesha
 
147 33 dinesha
reg                     pending_read       ;
148 31 dinesha
 
149
 
150 33 dinesha
//-----------------------------------------------------------------------------
151
// Ack Generaltion Logic
152
//  If Write Request - Acknowledge if the command and write FIFO are not full
153
//  If Read Request  - Generate the Acknowledgment once read fifo has data
154
//                     available
155
//-----------------------------------------------------------------------------
156 31 dinesha
 
157
assign wb_ack_o = (wb_stb_i && wb_cyc_i && wb_we_i) ?  // Write Phase
158
                          ((!cmdfifo_full) && (!wrdatafifo_full)) :
159
                  (wb_stb_i && wb_cyc_i && !wb_we_i) ? // Read Phase 
160
                           !rddatafifo_empty : 1'b0;
161
 
162 33 dinesha
//---------------------------------------------------------------------------
163
// Command FIFO Write Generation
164
//    If Write Request - Generate write, when Write fifo and command fifo is
165
//                       not full
166
//    If Read Request - Generate write, when command fifo not full and there
167
//                      is no pending read request.
168
//---------------------------------------------------------------------------
169
wire           cmdfifo_wr   = (wb_stb_i && wb_cyc_i && wb_we_i && (!cmdfifo_full) ) ? wb_ack_o :
170
                              (wb_stb_i && wb_cyc_i && !wb_we_i && (!cmdfifo_full)) ? !pending_read: 1'b0 ;
171
 
172
//---------------------------------------------------------------------------
173
// command fifo read generation
174
//    Command FIFo read will be generated, whenever SDRAM Controller
175
//    Acknowldge the Request
176
//----------------------------------------------------------------------------
177
 
178 31 dinesha
wire           cmdfifo_rd   = sdr_req_ack;
179 33 dinesha
 
180
//---------------------------------------------------------------------------
181
// Application layer request is generated towards the controller, whenever
182
// Command FIFO is not full
183
// --------------------------------------------------------------------------
184 31 dinesha
assign         sdr_req      = !cmdfifo_empty;
185
 
186 33 dinesha
//----------------------------------------------------------------------------
187
// Since Burst length is not known at the start of the Burst, It's assumed as
188
// Single Cycle Burst. We need to improvise this ...
189
// --------------------------------------------------------------------------
190 31 dinesha
wire [bl-1:0]  burst_length  = 1;  // 0 Mean 1 Transfer
191
 
192 33 dinesha
//-----------------------------------------------------------------------------
193
// In Wish Bone Spec, For Read Request has to be acked along with data.
194
// We need to identify the pending read request.
195
// Once we accept the read request, we should not accept one more read
196
// request, untill we have transmitted the read data.
197
//  Pending Read will 
198
//     set - with Read Request 
199
//     reset - with Read Request + Ack
200
// ----------------------------------------------------------------------------
201 31 dinesha
always @(posedge wb_rst_i or posedge wb_clk_i) begin
202
   if(wb_rst_i) begin
203
       pending_read <= 1'b0;
204
   end else begin
205 42 dinesha
      //pending_read <=  wb_stb_i & wb_cyc_i & !wb_we_i & !wb_ack_o;
206
      pending_read <=   (cmdfifo_wr && !wb_we_i) ? 1'b1:
207
                        (wb_stb_i & wb_cyc_i & !wb_we_i & wb_ack_o) ? 1'b0: pending_read;
208 31 dinesha
   end
209
end
210
 
211 33 dinesha
//---------------------------------------------------------------------
212
// Async Command FIFO. This block handle the clock domain change from
213
// Application layer to SDRAM Controller
214
// ------------------------------------------------------------------
215 31 dinesha
   // Address + Burst Length + W/R Request 
216 40 dinesha
    async_fifo #(.W(30+bl+1),.DP(4),.WR_FAST(1'b0), .RD_FAST(1'b1)) u_cmdfifo (
217 31 dinesha
     // Write Path Sys CLock Domain
218 33 dinesha
          .wr_clk             (wb_clk_i           ),
219
          .wr_reset_n         (!wb_rst_i          ),
220
          .wr_en              (cmdfifo_wr         ),
221
          .wr_data            ({burst_length,
222
                                !wb_we_i,
223
                                wb_addr_i}        ),
224
          .afull              (                   ),
225
          .full               (cmdfifo_full       ),
226 31 dinesha
 
227
     // Read Path, SDRAM clock domain
228 33 dinesha
          .rd_clk             (sdram_clk          ),
229
          .rd_reset_n         (sdram_resetn       ),
230
          .aempty             (                   ),
231
          .empty              (cmdfifo_empty      ),
232
          .rd_en              (cmdfifo_rd         ),
233
          .rd_data            ({sdr_req_len,
234
                                sdr_req_wr_n,
235
                                sdr_req_addr}     )
236 31 dinesha
     );
237
 
238
// synopsys translate_off
239
always @(posedge wb_clk_i) begin
240
  if (cmdfifo_full == 1'b1 && cmdfifo_wr == 1'b1)  begin
241
     $display("ERROR:%m COMMAND FIFO WRITE OVERFLOW");
242
  end
243
end
244 37 dinesha
// synopsys translate_on
245 31 dinesha
// synopsys translate_off
246
always @(posedge sdram_clk) begin
247
   if (cmdfifo_empty == 1'b1 && cmdfifo_rd == 1'b1) begin
248
      $display("ERROR:%m COMMAND FIFO READ OVERFLOW");
249
   end
250
end
251
// synopsys translate_on
252
 
253 33 dinesha
//---------------------------------------------------------------------
254
// Write Data FIFO Write Generation, when ever Acked + Write Request
255
//   Note: Ack signal generation already taking account of FIFO full condition
256
// ---------------------------------------------------------------------
257 31 dinesha
 
258
wire  wrdatafifo_wr  = wb_ack_o & wb_we_i ;
259 33 dinesha
 
260
//------------------------------------------------------------------------
261
// Write Data FIFO Read Generation, When ever Next Write request generated
262
// from SDRAM Controller
263
// ------------------------------------------------------------------------
264 31 dinesha
wire  wrdatafifo_rd  = sdr_wr_next;
265
 
266
 
267 33 dinesha
//------------------------------------------------------------------------
268
// Async Write Data FIFO
269
//    This block handle the clock domain change over + Write Data + Byte mask 
270
//    From Application layer to SDRAM controller layer
271
//------------------------------------------------------------------------
272
 
273 31 dinesha
   // Write DATA + Data Mask FIFO
274 40 dinesha
    async_fifo #(.W(dw+(dw/8)), .DP(8), .WR_FAST(1'b0), .RD_FAST(1'b1)) u_wrdatafifo (
275 31 dinesha
       // Write Path , System clock domain
276 33 dinesha
          .wr_clk             (wb_clk_i           ),
277
          .wr_reset_n         (!wb_rst_i          ),
278
          .wr_en              (wrdatafifo_wr      ),
279
          .wr_data            ({~wb_sel_i,
280
                                 wb_dat_i}        ),
281
          .afull              (                   ),
282
          .full               (wrdatafifo_full    ),
283 31 dinesha
 
284
 
285
       // Read Path , SDRAM clock domain
286 33 dinesha
          .rd_clk             (sdram_clk          ),
287
          .rd_reset_n         (sdram_resetn       ),
288
          .aempty             (                   ),
289
          .empty              (wrdatafifo_empty   ),
290
          .rd_en              (wrdatafifo_rd      ),
291
          .rd_data            ({sdr_wr_en_n,
292
                                sdr_wr_data}      )
293 31 dinesha
     );
294
// synopsys translate_off
295
always @(posedge wb_clk_i) begin
296
  if (wrdatafifo_full == 1'b1 && wrdatafifo_wr == 1'b1)  begin
297
     $display("ERROR:%m WRITE DATA FIFO WRITE OVERFLOW");
298
  end
299
end
300
 
301
always @(posedge sdram_clk) begin
302
   if (wrdatafifo_empty == 1'b1 && wrdatafifo_rd == 1'b1) begin
303
      $display("ERROR:%m WRITE DATA FIFO READ OVERFLOW");
304
   end
305
end
306
// synopsys translate_on
307
 
308
// -------------------------------------------------------------------
309
//  READ DATA FIFO
310
//  ------------------------------------------------------------------
311
wire    rd_eop; // last read indication
312 33 dinesha
 
313
// Read FIFO write generation, when ever SDRAM controller issues the read
314
// valid signal
315 31 dinesha
wire    rddatafifo_wr = sdr_rd_valid;
316
 
317 33 dinesha
// Read FIFO read generation, when ever ack is generated along with read
318
// request.
319
// Note: Ack generation is already accounted the write FIFO Not Empty
320
//       condition
321
wire    rddatafifo_rd = wb_ack_o & !wb_we_i;
322
 
323
//-------------------------------------------------------------------------
324
// Async Read FIFO
325
// This block handles the clock domain change over + Read data from SDRAM
326
// controller to Application layer.
327
//  Note: 
328
//    1. READ DATA FIFO depth is kept small, assuming that Sys-CLock > SDRAM Clock
329
//       READ DATA + EOP
330
//    2. EOP indicate, last transfer of Burst Read Access. use-full for future
331
//       Tag handling per burst
332
//
333
// ------------------------------------------------------------------------
334 40 dinesha
    async_fifo #(.W(dw+1), .DP(4), .WR_FAST(1'b0), .RD_FAST(1'b1) ) u_rddatafifo (
335 31 dinesha
       // Write Path , SDRAM clock domain
336 33 dinesha
          .wr_clk             (sdram_clk          ),
337
          .wr_reset_n         (sdram_resetn       ),
338
          .wr_en              (rddatafifo_wr      ),
339
          .wr_data            ({sdr_last_rd,
340
                                sdr_rd_data}      ),
341
          .afull              (                   ),
342
          .full               (rddatafifo_full    ),
343 31 dinesha
 
344
 
345
       // Read Path , SYS clock domain
346 33 dinesha
          .rd_clk             (wb_clk_i           ),
347
          .rd_reset_n         (!wb_rst_i          ),
348
          .empty              (rddatafifo_empty   ),
349
          .aempty             (                   ),
350
          .rd_en              (rddatafifo_rd      ),
351
          .rd_data            ({rd_eop,
352
                                wb_dat_o}         )
353 31 dinesha
     );
354
 
355
// synopsys translate_off
356
always @(posedge sdram_clk) begin
357
  if (rddatafifo_full == 1'b1 && rddatafifo_wr == 1'b1)  begin
358
     $display("ERROR:%m READ DATA FIFO WRITE OVERFLOW");
359
  end
360
end
361
 
362
always @(posedge wb_clk_i) begin
363
   if (rddatafifo_empty == 1'b1 && rddatafifo_rd == 1'b1) begin
364
      $display("ERROR:%m READ DATA FIFO READ OVERFLOW");
365
   end
366
end
367
// synopsys translate_on
368
 
369
 
370
endmodule

powered by: WebSVN 2.1.0

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