Forum Discussion
Altera_Forum
Honored Contributor
9 years agoAm I doing something wrong? Thnx again :)
module Flash_Ctrl(clock, reset_n, read, data_out, BYTEn, RESETn, CEn, WEn, OEn, A, D);
// System Signals
input clock; // posedge clock: 100 MHz
input reset_n; // negative reset
input read; // read flag: 1 -> read, 0 -> idle
output data_out; // data read from Flash
/* Flash Memory Operations
----------------------------------------------------------------------------
|Operation | BYTEn | RESETn | CEn | WEn | OEn | A | D |
----------------------------------------------------------------------------
| Read | 0 | 1 | 0 | 1 | 0 | <address> | <mem> |
| Inactive | 0 | 1 | 0 | 1 | 1 | XX...X | ZZ...Z |
| Reset | 0 | 0 | X | X | X | XX...X | ZZ...Z |
----------------------------------------------------------------------------
*/
// Flash Signals
output BYTEn, RESETn, CEn, WEn, OEn;
output A;
input D;
// Registers
reg CEn, OEn;
reg A;
reg data_out;
// ================================================================
// ----------------------- Flash Controller -----------------------
// ================================================================
// Flash States
reg flash_state;
parameter IDLE = 0,
READ_START = 1,
READ_1 = 2,
READ_2 = 3,
READ_3 = 4,
READ_END = 5;
// Wire Flash Signals
assign RESETn = reset_n; // reset according to system reset
assign BYTEn = 1'b0; // byte mode
assign WEn = 1'b1; // always read mode
// Address Access Time
wire tAA;
// Address to read from
reg address;
// Flash State Machine
always @(posedge clock or negedge reset_n)
begin
if (!reset_n) // Reset
begin
CEn <= 1'b1;
OEn <= 1'b1;
A <= 21'b0;
flash_state <= IDLE;
data_out <= 8'bF0;
address <= 21'b0;
end
else // Clock
begin
CEn <= 1'b1;
OEn <= 1'b1;
A <= A;
address <= address;
// Examining flash states
case (flash_state)
// Flash = IDLE
IDLE:
begin
if (read) // read operation should start
flash_state <= READ_START;
else
flash_state <= IDLE;
end
// Flash = READ_START
READ_START:
begin
CEn <= 1'b0;
A <= address;
flash_state <= READ_1; // tAS = 0 ns
end
// Flash = READ_1
READ_1:
begin
CEn <= 1'b0;
OEn <= 1'b0;
A <= inner_A;
if (tAA) // tAA = 100 ns
flash_state <= READ_2;
else
flash_state <= READ_1;
end
// Flash = READ_2
READ_2:
begin
data_out <= D; // read the data
flash_state <= READ_3;
end
// Flash = READ_3
READ_3:
begin
flash_state <= READ_END;
address <= address + 1; // next address to read from
end
// Flash = READ_END
READ_END:
begin
flash_state <= IDLE;
end
// Flash = DEFAULT
default:
begin
flash_state <= IDLE;
end
endcase
end
// tAA = 100 ns time generation
reg tAA_cnt;
assign tAA = (tAA_cnt == 10);
always @(posedge clock or negedge reset_n)
begin
if (!reset_n)
tAA_cnt <= 0;
else
begin
if (time_is_tAA)
tAA_cnt <= 0;
else if (flash_state == READ_START_1)
tAA_cnt <= tAA_cnt + 1;
end
end
endmodule