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

Subversion Repositories next186mp3

[/] [next186mp3/] [trunk/] [HW/] [sdram.v] - Blame information for rev 2

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 2 ndumitrach
`timescale 1ns / 100ps
2
//////////////////////////////////////////////////////////////////////////////////
3
//
4
// This file is part of the Next186 Soc PC project
5
// http://opencores.org/project,next186
6
//
7
// Filename: sdram.v
8
// Description: Part of the Next186 SoC PC project, SDRAM controller
9
// Version 1.0
10
// Creation date: Feb2014
11
//
12
// Author: Nicolae Dumitrache 
13
// e-mail: ndumitrache@opencores.org
14
//
15
/////////////////////////////////////////////////////////////////////////////////
16
// 
17
// Copyright (C) 2014 Nicolae Dumitrache
18
// 
19
// This source file may be used and distributed without 
20
// restriction provided that this copyright statement is not 
21
// removed from the file and that any derivative work contains 
22
// the original copyright notice and the associated disclaimer.
23
// 
24
// This source file is free software; you can redistribute it 
25
// and/or modify it under the terms of the GNU Lesser General 
26
// Public License as published by the Free Software Foundation;
27
// either version 2.1 of the License, or (at your option) any 
28
// later version. 
29
// 
30
// This source is distributed in the hope that it will be 
31
// useful, but WITHOUT ANY WARRANTY; without even the implied 
32
// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR 
33
// PURPOSE. See the GNU Lesser General Public License for more 
34
// details. 
35
// 
36
// You should have received a copy of the GNU Lesser General 
37
// Public License along with this source; if not, download it 
38
// from http://www.opencores.org/lgpl.shtml 
39
// 
40
///////////////////////////////////////////////////////////////////////////////////
41
// Additional Comments: 
42
//////////////////////////////////////////////////////////////////////////////////
43
 
44
`define RD1 8'h10               // 32 bytes  - cmd 10
45
`define RD2 8'h80               // 256 bytes - cmd 11
46
`define WR2 8'h80               // 256 bytes - cmd 01
47
`define PitchBits       1
48
 
49
`define ColBits 8       // column bits
50
`define RowBits 12      // row bits
51
`define BankBits        2       // bank bits
52
 
53
`define tRP             3
54
`define tMRD    2
55
`define tRCD    3
56
`define tRC             9
57
`define CL              3               // CAS latency
58
`define tREF    64              // ms
59
 
60
`define RFB 11                  // refresh bit = floor(log2(CLK*`tREF/(2^RowBits)))
61
 
62
 
63
module SDRAM_16bit(
64
                input sys_CLK,                                          // clock
65
                input [1:0]sys_CMD,                                      // 00=nop, 01 = write WR2 bytes, 10=read RD1 bytes, 11=read RD2 bytes
66
                input [`RowBits+`BankBits+`ColBits-`PitchBits-1:0]sys_ADDR,                      // word address, multiple of 2^PitchBits words
67
                input [15:0]sys_DIN,                             // data input
68
                output reg [15:0]sys_DOUT,
69
                output reg sys_rd_data_valid = 0,        // data valid out
70
                output reg sys_wr_data_valid = 0,        // data valid in
71
                output reg [1:0]sys_cmd_ack = 0,  // command acknowledged
72
 
73
                output reg [3:0]sdr_n_CS_WE_RAS_CAS = 4'b1111,                   // SDRAM #CS, #WE, #RAS, #CAS
74
                output reg [1:0]sdr_BA,                          // SDRAM bank address
75
                output reg [12:0]sdr_ADDR,                       // SDRAM address
76
                inout [15:0]sdr_DATA,                            // SDRAM data
77
                output reg [1:0]sdr_DQM = 2'b11          // SDRAM DQM
78
        );
79
 
80
        reg [`RowBits-1:0]actLine[3:0];
81
        reg [(1<<`BankBits)-1:0]actBank = 0;
82
        reg [2:0]STATE = 0;
83
        reg [2:0]RET;            // return state
84
        reg [6:0]DLY;            // delay
85
        reg [15:0]counter = 0;    // refresh counter
86
        reg rfsh = 1;                   // refresh bit
87
        reg [`ColBits-`PitchBits-1:0]colAddr;
88
        reg [`BankBits-1:0]bAddr;
89
        reg [`RowBits-1:0]linAddr;
90
        reg [15:0]reg_din;
91
        reg [2:0]out_data_valid = 0;
92
 
93
        assign sdr_DATA = out_data_valid[2] ? reg_din : 16'hzzzz;
94
 
95
        always @(posedge sys_CLK) begin
96
                        counter <= counter + 1;
97
                        sdr_n_CS_WE_RAS_CAS <= 4'b1xxx; // NOP
98
                        STATE <= 1;
99
                        reg_din <= sys_DIN;
100
                        out_data_valid <= {out_data_valid[1:0], sys_wr_data_valid};
101
                        DLY <= DLY - 1;
102
                        sys_DOUT <= sdr_DATA;
103
 
104
                        case(STATE)
105
                                0: begin
106
                                        sys_rd_data_valid <= 1'b0;
107
                                        if(sdr_DQM[0]) STATE <= counter[15] ? 2 : 0;      // initialization, wait >200uS
108
                                        else begin      // wait new command
109
                                                if(rfsh != counter[`RFB]) begin
110
                                                        rfsh <= counter[`RFB];
111
                                                        STATE <= 2;     // precharge all
112
                                                end else if(|sys_CMD) begin
113
                                                        sys_cmd_ack <= sys_CMD;
114
                                                        {linAddr, bAddr, colAddr} <= sys_ADDR;
115
                                                        STATE <= 5;
116
                                                end else STATE <= 0;
117
                                        end
118
                                end
119
 
120
                                1: begin
121
                                        if(DLY == 2) sys_wr_data_valid <= 1'b0;
122
                                        if(DLY == 0) STATE <= RET;       // NOP for DLY clocks, return to RET state
123
                                 end
124
 
125
                                2: begin        // precharge all
126
                                        sdr_n_CS_WE_RAS_CAS <= 4'b0001;
127
                                        sdr_ADDR[10] <= 1'b1;
128
                                        RET <= sdr_DQM[0] ? 3 : 4;
129
                                        DLY <= `tRP - 2;
130
                                        actBank <= 0;
131
                                end
132
 
133
                                3: begin        // Mode Register Set
134
                                        sdr_n_CS_WE_RAS_CAS <= 4'b0000;
135
                                        sdr_ADDR <= 13'b00_0_0_00_000_0_111 + (`CL<<4); // burst read/burst write _ normal mode _ `CL CAS latency _ sequential _ full page burst
136
                                        sdr_BA <= 2'b00;
137
                                        RET <= 4;
138
                                        DLY <= `tMRD - 2;
139
                                end
140
 
141
                                4: begin // autorefresh
142
                                        sdr_n_CS_WE_RAS_CAS <= 4'b0100;
143
                                        if(rfsh != counter[`RFB]) RET <= 4;
144
                                        else begin
145
                                                sdr_DQM <= 2'b00;
146
                                                RET <= 0;
147
                                        end
148
                                        DLY <= `tRC - 2;
149
                                end
150
 
151
                                5: begin        // read/write
152
                                        sdr_BA <= bAddr;
153
                                        if(actBank[bAddr]) // bank active
154
                                                if(actLine[bAddr] == linAddr) begin // line already active
155
                                                        sdr_ADDR[10] <= 1'b0; // no auto precharge
156
                                                        sdr_ADDR[`ColBits-1:0] <= {colAddr, {`PitchBits{1'b0}}};
157
                                                        RET <= 7;
158
                                                        if(sys_cmd_ack[1]) begin        // read
159
                                                                sdr_n_CS_WE_RAS_CAS <= 4'b0110; // read command
160
                                                                DLY <= `CL - 1;
161
                                                        end else begin  // write
162
                                                                DLY <= 1;
163
                                                                sys_wr_data_valid <= 1'b1;
164
                                                        end
165
                                                end else begin // bank precharge
166
                                                        sdr_n_CS_WE_RAS_CAS <= 4'b0001;
167
                                                        sdr_ADDR[10] <= 1'b0;
168
                                                        actBank[bAddr] <= 1'b0;
169
                                                        RET <= 5;
170
                                                        DLY <= `tRP - 2;
171
                                                end
172
                                        else begin // bank activate
173
                                                sdr_n_CS_WE_RAS_CAS <= 4'b0101;
174
                                                sdr_ADDR[`RowBits-1:0] <= linAddr;
175
                                                actBank[bAddr] <= 1'b1;
176
                                                actLine[bAddr] <= linAddr;
177
                                                RET <= 5;
178
                                                DLY <= `tRCD - 2;
179
                                        end
180
                                end
181
 
182
                                6: begin        // end read/write phase
183
                                        sys_cmd_ack <= 2'b00;
184
                                        sdr_n_CS_WE_RAS_CAS <= 4'b0011; // burst stop
185
                                        STATE <= sys_cmd_ack[1] ? 1 : 0; // read write
186
                                        RET <= 0;
187
                                        DLY <= 2;
188
                                end
189
 
190
                                7: begin        // init read/write phase
191
                                        if(sys_cmd_ack[1]) sys_rd_data_valid <= 1'b1;
192
                                        else sdr_n_CS_WE_RAS_CAS <= 4'b0010;    // write command
193
                                        RET <= 6;
194
                                        DLY <= sys_cmd_ack[1] ? sys_cmd_ack[0] ? `RD2 - 6 : `RD1 - 6 : `WR2 - 2;
195
                                end
196
 
197
                        endcase
198
        end
199
 
200
endmodule

powered by: WebSVN 2.1.0

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