massive overhaul of fpga code
[fleet.git] / src / edu / berkeley / fleet / fpga / mem / ddr_init.v
1 //----------------------------------------------------------------------------
2 // Wishbone DDR Controller
3 // 
4 // (c) Joerg Bornschein (<jb@capsec.org>)
5 //----------------------------------------------------------------------------
6 `include "ddr_include.v"
7
8 module ddr_init 
9 #(
10         parameter               wait200_init = 26
11 ) (
12         input                   clk, 
13         input                   reset,
14         input                   pulse78,
15         output                  wait200,
16         output                  init_done,
17         //
18         output                  mngt_req,
19         input                   mngt_ack,
20         output [`CBA_RNG]       mngt_cba       // CMD, BA and ADDRESS
21 );
22
23 reg              cmd_req_reg;
24 reg [`CMD_RNG]   cmd_cmd_reg;
25 reg [ `BA_RNG]   cmd_ba_reg;
26 reg [  `A_RNG]   cmd_a_reg;
27 reg [7:0]        cmd_idle_reg;
28
29 //---------------------------------------------------------------------------
30 // Initial 200us delay
31 //---------------------------------------------------------------------------
32
33 // `define WAIT200_INIT 26
34 // `define WAIT200_INIT 1
35
36 reg [4:0] wait200_counter;
37 reg       wait200_reg;
38
39 always @(posedge clk)
40 begin
41         if (reset) begin
42                 wait200_reg     <= 1;
43                 wait200_counter <= wait200_init;
44         end else begin
45                 if (wait200_counter == 0)
46                         wait200_reg <= 0;
47
48                 if (wait200_reg & pulse78)
49                         wait200_counter <= wait200_counter - 1;
50         end
51 end
52
53 assign wait200 = wait200_reg;
54
55 //---------------------------------------------------------------------------
56 // Auto refresh counter
57 //---------------------------------------------------------------------------
58
59 reg [2:0] ar_counter;
60 wire      ar_cmd_acked;
61 wire      ar_needed;
62 wire      ar_badly_needed;
63
64 assign ar_cmd_acked    = (cmd_cmd_reg == `DDR_CMD_AR) & mngt_ack;
65 assign ar_needed       = (ar_counter != 0) & ~ar_cmd_acked; 
66 assign ar_badly_needed = ar_counter[2] == 1'b1;  // >= 4
67
68 always @(posedge clk)
69 begin
70         if (reset) begin
71                 ar_counter <= 0;
72         end else begin
73                 if (~init_done)
74                         ar_counter <= 0;
75                 else if (pulse78 & ~ar_cmd_acked) 
76                         ar_counter <= ar_counter + 1;
77                 else if (ar_cmd_acked & ~pulse78) 
78                         ar_counter <= ar_counter - 1;
79         end
80 end
81
82 //----------------------------------------------------------------------------
83 // DDR Initialization State Machine
84 //----------------------------------------------------------------------------
85
86 parameter s_wait200 = 0;
87 parameter s_init1   = 1;
88 parameter s_init2   = 2;
89 parameter s_init3   = 3;
90 parameter s_init4   = 4;
91 parameter s_init5   = 5;
92 parameter s_init6   = 6;
93 parameter s_waitack = 7;
94 parameter s_idle    = 8;
95
96 reg [3:0]        state;
97 reg              init_done_reg;
98
99 assign mngt_cba     = {cmd_cmd_reg, cmd_ba_reg, cmd_a_reg};
100 assign mngt_req     = cmd_req_reg;
101 assign mngt_pri_req = ~init_done_reg;
102 assign init_done    = init_done_reg;
103
104 always @(posedge clk or posedge reset)
105 begin
106         if (reset) begin
107                 init_done_reg <= 0;
108                 state         <= s_wait200;
109                 cmd_idle_reg  <= 0;
110                 cmd_req_reg   <= 0;
111                 cmd_cmd_reg   <= 'b0;
112                 cmd_ba_reg    <= 'b0;
113                 cmd_a_reg     <= 'b0;
114         end else begin
115                 case (state)
116                         s_wait200: begin
117                                 if (~wait200_reg) begin
118                                                 state         <= s_init1;
119                                                 cmd_req_reg   <= 1;
120                                                 cmd_cmd_reg   <= `DDR_CMD_PRE;   // PRE ALL
121                                                 cmd_a_reg[10] <= 1'b1;
122                                         end
123                                 end
124                         s_init1: begin
125                                         if (mngt_ack) begin
126                                                 state         <= s_init2;
127                                                 cmd_req_reg   <= 1;
128                                                 cmd_cmd_reg   <= `DDR_CMD_MRS;   // EMRS
129                                                 cmd_ba_reg    <= 2'b01;
130                                                 cmd_a_reg     <= `DDR_INIT_EMRS;
131                                         end
132                                 end
133                         s_init2: begin
134                                         if (mngt_ack) begin
135                                                 state         <= s_init3;
136                                                 cmd_req_reg   <= 1;
137                                                 cmd_cmd_reg   <= `DDR_CMD_MRS;   // MRS
138                                                 cmd_ba_reg    <= 2'b00;
139                                                 cmd_a_reg     <= `DDR_INIT_MRS1;
140                                         end
141                                 end
142                         s_init3: begin
143                                         if (mngt_ack) begin
144                                                 state         <= s_init4;
145                                                 cmd_req_reg   <= 1;
146                                                 cmd_cmd_reg   <= `DDR_CMD_PRE;   // PRE ALL
147                                                 cmd_a_reg[10] <= 1'b1;
148                                         end
149                                 end
150                         s_init4: begin
151                                         if (mngt_ack) begin
152                                                 state         <= s_init5;
153                                                 cmd_req_reg   <= 1;
154                                                 cmd_cmd_reg   <= `DDR_CMD_AR;   // AR
155                                         end
156                                 end
157                         s_init5: begin
158                                         if (mngt_ack) begin
159                                                 state         <= s_init6;
160                                                 cmd_req_reg   <= 1;
161                                                 cmd_cmd_reg   <= `DDR_CMD_AR;   // AR
162                                         end
163                                 end
164                         s_init6: begin
165                                         if (mngt_ack) begin
166                                                 init_done_reg <= 1;
167                                                 state         <= s_waitack;
168                                                 cmd_req_reg   <= 1;
169                                                 cmd_cmd_reg   <= `DDR_CMD_MRS;  // MRS
170                                                 cmd_ba_reg    <= 2'b00;
171                                                 cmd_a_reg     <= `DDR_INIT_MRS2;
172                                         end
173                                 end
174                         s_waitack: begin
175                                         if (mngt_ack) begin
176                                                 state         <= s_idle;
177                                                 cmd_req_reg   <= 0;
178                                                 cmd_cmd_reg   <= 'b0;
179                                                 cmd_ba_reg    <= 'b0;
180                                                 cmd_a_reg     <= 'b0;
181                                         end
182                                 end
183                         s_idle: begin
184                                 end
185                 endcase ///////////////////////////////////////// INIT STATE MACHINE ///
186         end
187 end
188
189
190 endmodule
191