1 | module FLASH_CTL (
|
2 |
|
3 | ////////////// avalon interface///////////////////
|
4 |
|
5 | input wire [23:0] avalon_slave_address,
|
6 | input wire [3:0] avalon_slave_byteenable,
|
7 | input wire avalon_slave_read, // .read
|
8 | input wire avalon_slave_write, // .write
|
9 | input wire [31:0] avalon_slave_writedata, // .writedata
|
10 | input wire reset_sink_reset, // reset_sink.reset
|
11 | input wire clock_sink_clk, // clock_sink_1.clk
|
12 |
|
13 | output wire [31:0] avalon_slave_readdata, // .readdata
|
14 | output wire avalon_slave_readdatavalid, // .readdatavalid
|
15 | output wire avalon_slave_waitrequest, // .waitrequest
|
16 |
|
17 |
|
18 | //////////////// chip interface ///////////////////
|
19 | input wire SO,
|
20 | output reg SI,
|
21 | output reg CS,
|
22 | output wire WP,
|
23 | output wire HOLD,
|
24 | output reg SCLK
|
25 | );
|
26 |
|
27 | parameter ST_0 = 4'd0; parameter ST_1 = 4'd1; parameter ST_2 = 4'd2; parameter ST_3 = 4'd3;
|
28 | parameter ST_4 = 4'd4; parameter ST_5 = 4'd5; parameter ST_6 = 4'd6; parameter ST_7 = 4'd7;
|
29 | parameter ST_8 = 4'd8; parameter ST_9 = 4'd9; parameter ST_10 = 4'd10; parameter ST_11 = 4'd11;
|
30 |
|
31 | parameter wr_comm = 8'b0000_0010; // PROGRAM 0X02, write 0000_0010
|
32 | parameter rd_comm = 8'b0000_0011; // PROGRAM 0X03, read 0000_0011
|
33 |
|
34 |
|
35 | ///////////////////////////////////////////////
|
36 | parameter test_A = 8'b0001_1111;
|
37 |
|
38 |
|
39 | reg [7:0] test_reg;
|
40 |
|
41 |
|
42 | always@ (posedge clock_sink_clk or negedge reset_sink_reset) begin
|
43 | if (~reset_sink_reset)
|
44 | test_reg <= 0;
|
45 | else
|
46 | test_reg <= test_A;
|
47 | end
|
48 |
|
49 | ////////////////////////////////////////////
|
50 |
|
51 |
|
52 |
|
53 | reg [31:0] av_wrdata;
|
54 | reg f_cyc_count, enable, rd_SO, f_bit_count, wr_mode, word_ak, clear_byte_c;
|
55 | reg av_rd7, av_rd6, av_rd5, av_rd4, av_rd3, av_rd2, av_rd1, av_rd0;
|
56 | reg [3:0] state, nextstate;
|
57 | reg [4:0] cyc_count, byte_count;
|
58 | reg [7:0] comm_in, data_in, av_rd_byte1, av_rd_byte2, av_rd_byte3, av_rd_byte4;
|
59 | reg [23:0] addr_in;
|
60 | reg [4:0] bit_count;
|
61 | wire [7:0] av_rd_buff;
|
62 | reg [2:0] bytes_enabled;
|
63 | wire burstcount, debugaccess;
|
64 |
|
65 | assign WP = 1;
|
66 | assign HOLD = 1;
|
67 | assign avalon_slave_waitrequest = ~ CS;
|
68 | assign avalon_slave_readdatavalid = (CS && state >= 1 && wr_mode)? 1'b1:1'b0;
|
69 | assign avalon_slave_readdata = {av_rd_byte1, av_rd_byte2, av_rd_byte3, av_rd_byte4};
|
70 | assign av_rd_buff = {av_rd7, av_rd6, av_rd5, av_rd4, av_rd3, av_rd2, av_rd1, av_rd0};
|
71 | assign burstcount = 0;
|
72 | assign debugaccess = 0;
|
73 |
|
74 |
|
75 | always@ (posedge clock_sink_clk or negedge reset_sink_reset)begin
|
76 | if (~reset_sink_reset)
|
77 | bytes_enabled <= 1;
|
78 | else begin
|
79 | bytes_enabled <= bytes_enabled;
|
80 | case (avalon_slave_byteenable)
|
81 | 4'b0001: bytes_enabled <= 3'd0;
|
82 | 4'b0011: bytes_enabled <= 3'd1;
|
83 | 4'b0111: bytes_enabled <= 3'd2;
|
84 | 4'b1111: bytes_enabled <= 3'd3;
|
85 | default: bytes_enabled <= bytes_enabled;
|
86 | endcase
|
87 | end
|
88 | end
|
89 |
|
90 | always@ (posedge clock_sink_clk or negedge reset_sink_reset)
|
91 | if (~reset_sink_reset)
|
92 | state <= ST_0;
|
93 | else
|
94 | state <= nextstate;
|
95 |
|
96 |
|
97 | always@ (*) begin
|
98 | CS <= 0; SI <= 0; SCLK <= 0; f_bit_count <= 0; f_cyc_count <= 0; rd_SO <= 0; word_ak <= 0; clear_byte_c <= 0;
|
99 | case (state)
|
100 | ST_0: begin
|
101 | if (enable) begin
|
102 | nextstate <= ST_1;
|
103 | CS <= 0;
|
104 | end
|
105 | else begin
|
106 | nextstate <= ST_0;
|
107 | CS <= 1;
|
108 | end
|
109 | end
|
110 |
|
111 | ST_1: begin
|
112 | SI <= 0; // dont care
|
113 | SCLK <= 1;
|
114 | if (cyc_count == 10) begin
|
115 | f_cyc_count <= 0;
|
116 | nextstate <= ST_2;
|
117 | end
|
118 | else begin
|
119 | f_cyc_count <= 1;
|
120 | nextstate <= ST_1;
|
121 | end
|
122 | end
|
123 |
|
124 | ST_2: begin ///// send command
|
125 | SI <= comm_in [7 - bit_count];
|
126 | SCLK <= 0;
|
127 | if (cyc_count == 10) begin
|
128 | f_cyc_count <= 0;
|
129 | nextstate <= ST_3;
|
130 | end
|
131 | else begin
|
132 | f_cyc_count <= 1;
|
133 | nextstate <= ST_2;
|
134 | end
|
135 | end
|
136 |
|
137 | ST_3: begin
|
138 | SI <= comm_in [7 - bit_count];
|
139 | SCLK <= 1;
|
140 | if (cyc_count == 10) begin
|
141 | f_cyc_count <= 0;
|
142 | f_bit_count <= 1;
|
143 | if (bit_count == 7) begin
|
144 | nextstate <= ST_4;
|
145 | word_ak <= 1;
|
146 | clear_byte_c <= 1;
|
147 | end
|
148 | else begin
|
149 | clear_byte_c <= 0;
|
150 | nextstate = ST_2;
|
151 | word_ak <= 0;
|
152 | end
|
153 | end
|
154 | else begin
|
155 | word_ak <= 0;
|
156 | f_bit_count <= 0;
|
157 | f_cyc_count <= 1;
|
158 | nextstate <= ST_3;
|
159 | end
|
160 | end
|
161 |
|
162 | ST_4: begin ///// send address
|
163 | SI <= addr_in [23 - bit_count];
|
164 | SCLK <= 0;
|
165 | f_bit_count <= 0;
|
166 | if (cyc_count == 10) begin
|
167 | f_cyc_count <= 0;
|
168 | nextstate <= ST_5;
|
169 | end
|
170 | else begin
|
171 | f_cyc_count <= 1;
|
172 | nextstate <= ST_4;
|
173 | end
|
174 | end
|
175 |
|
176 |
|
177 | ST_5: begin
|
178 | SI <= addr_in [23 - bit_count];
|
179 | SCLK <= 1;
|
180 | if (cyc_count == 10) begin
|
181 | f_cyc_count <= 0;
|
182 | f_bit_count <= 1;
|
183 | if (bit_count == 23) begin
|
184 | word_ak <= 1;
|
185 | clear_byte_c <= 1;
|
186 | if (wr_mode)
|
187 | nextstate = ST_6;
|
188 | else
|
189 | nextstate = ST_9;
|
190 | end
|
191 | else begin
|
192 | clear_byte_c <= 0;
|
193 | nextstate = ST_4;
|
194 | word_ak <= 0;
|
195 | end
|
196 | end
|
197 | else begin
|
198 | word_ak <= 0;
|
199 | f_cyc_count <= 1;
|
200 | nextstate <= ST_5;
|
201 | end
|
202 | end
|
203 |
|
204 | ST_6: begin /// write
|
205 | SI <= data_in [7 - bit_count];
|
206 | SCLK <= 0;
|
207 | f_bit_count <= 0;
|
208 | if (cyc_count == 10) begin
|
209 | f_cyc_count <= 0;
|
210 | nextstate <= ST_7;
|
211 | end
|
212 | else begin
|
213 | f_cyc_count <= 1;
|
214 | nextstate <= ST_6;
|
215 | end
|
216 | end
|
217 |
|
218 | ST_7: begin
|
219 | SI <= data_in [7 - bit_count];
|
220 | SCLK <= 1;
|
221 | if (cyc_count == 10) begin
|
222 | f_cyc_count <= 0;
|
223 | f_bit_count <= 1;
|
224 | if (bit_count == 7) begin
|
225 | word_ak <= 1;
|
226 | if (byte_count == bytes_enabled) begin
|
227 | clear_byte_c <= 1;
|
228 | nextstate <= ST_8;
|
229 | end
|
230 | else begin
|
231 | clear_byte_c <= 0;
|
232 | nextstate <= ST_6;
|
233 | end
|
234 | end
|
235 | else begin
|
236 | clear_byte_c <= 0;
|
237 | word_ak <= 0;
|
238 | nextstate = ST_6;
|
239 | end
|
240 | end
|
241 | else begin
|
242 | clear_byte_c <= 0;
|
243 | word_ak <= 0;
|
244 | f_bit_count <= 0;
|
245 | f_cyc_count <= 1;
|
246 | nextstate <= ST_7;
|
247 | end
|
248 | end
|
249 |
|
250 | ST_8: begin
|
251 | rd_SO <= 0;
|
252 | CS <= 1;
|
253 | if (cyc_count == 10) begin
|
254 | f_cyc_count <= 0;
|
255 | nextstate <= ST_0;
|
256 | end
|
257 | else begin
|
258 | f_cyc_count <= 1;
|
259 | nextstate <= ST_8;
|
260 | end
|
261 | end
|
262 |
|
263 | ///////
|
264 | ST_9: begin
|
265 | rd_SO <= 0; // read
|
266 | SI <= 0;
|
267 | SCLK <= 0;
|
268 | f_bit_count <= 0;
|
269 | if (cyc_count == 10) begin
|
270 | f_cyc_count <= 0;
|
271 | nextstate <= ST_10;
|
272 | end
|
273 | else begin
|
274 | f_cyc_count <= 1;
|
275 | nextstate <= ST_9;
|
276 | end
|
277 | end
|
278 |
|
279 | ST_10: begin
|
280 | rd_SO <= 1;
|
281 | SI <= 0; // dont care
|
282 | SCLK <= 1;
|
283 | if (cyc_count == 10) begin
|
284 | f_cyc_count <= 0;
|
285 | f_bit_count <= 1;
|
286 | if (bit_count == 7) begin
|
287 | word_ak <= 1;
|
288 | if (byte_count == bytes_enabled) begin
|
289 | clear_byte_c <= 1;
|
290 | nextstate <= ST_11;
|
291 | end
|
292 | else begin
|
293 | clear_byte_c <= 0;
|
294 | nextstate <= ST_9;
|
295 | end
|
296 | end
|
297 | else begin
|
298 | clear_byte_c <= 0;
|
299 | word_ak <= 0;
|
300 | nextstate = ST_9;
|
301 | end
|
302 | end
|
303 | else begin
|
304 | clear_byte_c <= 0;
|
305 | word_ak <= 0;
|
306 | f_bit_count <= 0;
|
307 | f_cyc_count <= 1;
|
308 | nextstate <= ST_10;
|
309 | end
|
310 | end
|
311 |
|
312 |
|
313 | ST_11: begin
|
314 | rd_SO <= 0;
|
315 | CS <= 1;
|
316 | if (cyc_count == 10) begin
|
317 | f_cyc_count <= 0;
|
318 | nextstate <= ST_0;
|
319 | end
|
320 | else begin
|
321 | f_cyc_count <= 1;
|
322 | nextstate <= ST_11;
|
323 | end
|
324 | end
|
325 |
|
326 | default: begin
|
327 | CS <= 0; SI <= 0; SCLK <= 0; f_bit_count <= 0; f_cyc_count <= 0; nextstate <= ST_0;
|
328 | rd_SO <= 0; clear_byte_c <= 0;
|
329 | end
|
330 | endcase
|
331 | end
|
332 |
|
333 | always@(posedge clock_sink_clk or negedge reset_sink_reset) begin
|
334 | if (~reset_sink_reset) begin
|
335 | av_rd7 <= 0; av_rd6 <= 0; av_rd5 <= 0; av_rd4 <= 0;
|
336 | av_rd3 <= 0;av_rd2 <= 0;av_rd1 <= 0;av_rd0 <= 0;
|
337 | end
|
338 | else if (rd_SO) begin
|
339 | av_rd7 <= av_rd7; av_rd6 <= av_rd6; av_rd5 <= av_rd5; av_rd4 <= av_rd4;
|
340 | av_rd3 <= av_rd3; av_rd2 <= av_rd2; av_rd1 <= av_rd1; av_rd0 <= av_rd0;
|
341 | case (bit_count)
|
342 | 0: av_rd7 <= SO;
|
343 | 1: av_rd6 <= SO;
|
344 | 2: av_rd5 <= SO;
|
345 | 3: av_rd4 <= SO;
|
346 | 4: av_rd3 <= SO;
|
347 | 5: av_rd2 <= SO;
|
348 | 6: av_rd1 <= SO;
|
349 | 7: av_rd0 <= SO;
|
350 | default: begin
|
351 | av_rd7 <= av_rd7; av_rd6 <= av_rd6; av_rd5 <= av_rd5; av_rd4 <= av_rd4;
|
352 | av_rd3 <= av_rd3; av_rd2 <= av_rd2; av_rd1 <= av_rd1; av_rd0 <= av_rd0;
|
353 | end
|
354 | endcase
|
355 | end
|
356 | else if (CS && state >= 1) begin
|
357 | av_rd7 <= 0; av_rd6 <= 0; av_rd5 <= 0; av_rd4 <= 0;
|
358 | av_rd3 <= 0;av_rd2 <= 0;av_rd1 <= 0;av_rd0 <= 0;
|
359 | end
|
360 | else begin
|
361 | av_rd7 <= av_rd7; av_rd6 <= av_rd6; av_rd5 <= av_rd5; av_rd4 <= av_rd4;
|
362 | av_rd3 <= av_rd3; av_rd2 <= av_rd2; av_rd1 <= av_rd1; av_rd0 <= av_rd0;
|
363 | end
|
364 |
|
365 | end
|
366 |
|
367 | ////////////////////////////////////////////////////////////////////////////
|
368 |
|
369 | always@(posedge clock_sink_clk or negedge reset_sink_reset) begin // DESASOCIAR BIT_COUNT DE CYCLE COUNTER
|
370 | if (~reset_sink_reset)
|
371 | bit_count <= 0;
|
372 | else if (word_ak)
|
373 | bit_count <= 0;
|
374 | else if (f_bit_count)
|
375 | bit_count <= bit_count + 4'b1;
|
376 | else
|
377 | bit_count <= bit_count;
|
378 | end
|
379 |
|
380 |
|
381 | always@(posedge clock_sink_clk or negedge reset_sink_reset) begin
|
382 | if (~reset_sink_reset)
|
383 | cyc_count <= 0;
|
384 | else if (f_cyc_count)
|
385 | cyc_count <= cyc_count + 4'b1;
|
386 | else
|
387 | cyc_count <= 0;
|
388 | end
|
389 |
|
390 | always@(posedge clock_sink_clk or negedge reset_sink_reset) begin
|
391 | if (~reset_sink_reset)
|
392 | byte_count <= 0;
|
393 | else if (CS && state >= 1)
|
394 | byte_count <= 0;
|
395 | else if (clear_byte_c)
|
396 | byte_count <= 0;
|
397 | else if (word_ak)
|
398 | byte_count <= byte_count + 4'b1;
|
399 | else
|
400 | byte_count <= byte_count;
|
401 | end
|
402 |
|
403 | //////////////// Controls enable from write and read /////////////////////
|
404 |
|
405 | always@(posedge clock_sink_clk or negedge reset_sink_reset) begin
|
406 | if (~reset_sink_reset)
|
407 | enable <= 0;
|
408 | else if (avalon_slave_write || avalon_slave_read)
|
409 | enable <= 1;
|
410 | else
|
411 | enable <= 0;
|
412 | end
|
413 |
|
414 | ////// controls write vs read order, with priority write /////////////////
|
415 |
|
416 | always@ (posedge clock_sink_clk or negedge reset_sink_reset) begin
|
417 | if (~reset_sink_reset)
|
418 | wr_mode <= 0;
|
419 | else if (avalon_slave_write)
|
420 | wr_mode <= 1;
|
421 | else if (CS && state >= 1)
|
422 | wr_mode <= 0;
|
423 | else
|
424 | wr_mode <= wr_mode;
|
425 | end
|
426 | ///////////////////////////////////////////////////////////////////////
|
427 |
|
428 | always@(posedge clock_sink_clk or negedge reset_sink_reset) begin
|
429 | if (~reset_sink_reset)
|
430 | comm_in <= rd_comm;
|
431 | else if (avalon_slave_write)
|
432 | comm_in <= wr_comm;
|
433 | else if (avalon_slave_read)
|
434 | comm_in <= rd_comm;
|
435 | else
|
436 | comm_in <= comm_in;
|
437 | end
|
438 |
|
439 | always@(posedge clock_sink_clk or negedge reset_sink_reset) begin
|
440 | if (~reset_sink_reset)
|
441 | addr_in <= 0;
|
442 | else if (avalon_slave_write || avalon_slave_read )
|
443 | addr_in <= avalon_slave_address;
|
444 | else
|
445 | addr_in <= addr_in;
|
446 | end
|
447 |
|
448 |
|
449 |
|
450 | always@(posedge clock_sink_clk or negedge reset_sink_reset) begin
|
451 | if (~reset_sink_reset)
|
452 | av_wrdata <= 0;
|
453 | else if (avalon_slave_write || avalon_slave_read )
|
454 | av_wrdata <= avalon_slave_writedata;
|
455 | else
|
456 | av_wrdata <= av_wrdata;
|
457 | end
|
458 |
|
459 |
|
460 |
|
461 | always@(posedge clock_sink_clk or negedge reset_sink_reset) begin
|
462 | if (~reset_sink_reset)
|
463 | data_in <= avalon_slave_writedata [7:0];
|
464 | else
|
465 | case (byte_count)
|
466 | 0: data_in <= av_wrdata [7:0];
|
467 | 1: data_in <= av_wrdata[15:8];
|
468 | 2: data_in <= av_wrdata [23:16];
|
469 | 3: data_in <= av_wrdata [31:24];
|
470 | default: data_in <= av_wrdata [7:0];
|
471 | endcase
|
472 |
|
473 | end
|
474 |
|
475 |
|
476 |
|
477 | ///////// Gather all 4 bytes in 1 register ////////////////////////
|
478 |
|
479 | always@(posedge clock_sink_clk or negedge reset_sink_reset) begin
|
480 | if (~reset_sink_reset) begin
|
481 | av_rd_byte1 <= 0; av_rd_byte2 <= 0; av_rd_byte3 <= 0; av_rd_byte4 <= 0;
|
482 | end
|
483 | else if (clear_byte_c && state >= ST_10) begin
|
484 | av_rd_byte1 <= av_rd_byte1; av_rd_byte2 <= av_rd_byte2; av_rd_byte3 <= av_rd_byte3; av_rd_byte4 <= av_rd_byte4;
|
485 | case (byte_count)
|
486 | 0: av_rd_byte1 <= av_rd_buff;
|
487 | 1: av_rd_byte2 <= av_rd_buff;
|
488 | 2: av_rd_byte3 <= av_rd_buff;
|
489 | 3: av_rd_byte4 <= av_rd_buff;
|
490 | default: begin
|
491 | av_rd7 <= av_rd7; av_rd6 <= av_rd6; av_rd5 <= av_rd5; av_rd4 <= av_rd4;
|
492 | av_rd3 <= av_rd3; av_rd2 <= av_rd2; av_rd1 <= av_rd1; av_rd0 <= av_rd0;
|
493 | end
|
494 | endcase
|
495 | end
|
496 | else if (CS && state >= 1) begin
|
497 | av_rd_byte1 <= 0; av_rd_byte2 <= 0; av_rd_byte3 <= 0; av_rd_byte4 <= 0;
|
498 | end
|
499 | end
|
500 |
|
501 |
|
502 | endmodule
|