- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi, I am trying to interact with a 16 Mbit Flash RAM (S29AL016M10TAI020) in Verilog, but I have some problems. This flash supports byte or word mode,
I have studied the datasheet and I have tried to implement a flash controller in byte mode. Question: is it necessary to do the Word/Byte Program Command Sequence first (a four cycle operation)? Also, what is the Program Address and the Program Data that I must specify (4th clock cycle of command sequence)? Also i need some help with the code. I want to read data from the flash so i execute the Word/Byte Program Command Sequence first and then start reading. Am i doing sth wrong?
module flash_controller(clock, reset_n, mem_mode, mem_ce_n, mem_rst_n, mem_oe_n, mem_we_n, address, data, flash_data);
// Controller inputs: clock of 10Mhz and negedge reset
input clock, reset_n;
// Flash Signals
output mem_mode, mem_ce_n, mem_rst_n, mem_oe_n, mem_we_n; // in flash they are inputs
output address; // in flash it is input
inout data; // in flash it is inout
// Controller output to check the read data
output flash_data;
wire nclock;
reg cycles;
reg write_data;
reg read_data;
reg mem_rst_n, mem_oe_n, mem_we_n;
reg address;
assign mem_mode = 1'b0; // to select byte mode
assign mem_ce_n = 1'b0; // always at 0 so the chip is enabled
// if mem_oe_n == H then write data else Z
assign data = (mem_oe_n) ? write_data : 8'bZ;
assign flash_data = read_data;
// ADDRESSES are latched on the NEGEDGE of mem_we_n
// DATA are latched on the POSEDGE of mem_we_n
assign nclock = !clock;
// clock cycles 1-4: flash programming at byte mode (is it necessary??):
// cc1: write AA at AAA
// cc2: write 55 at 555
// cc3: write A0 at AAA
// cc4: write Program Data at Program Address (whats this?)
// clock cycles >= 5: flash reading and showing the data at the output via flash data
always @ (posedge clock or posedge nclock or negedge reset_n)
begin
if (!reset_n) // RESET
begin
cycles = 3'd0;
mem_rst_n = 1'b0;
address = 21'd0;
end
else if (clock) // CLOCK POSEDGE
begin
if (cycles < 3'd4) // clock cycles 1-4: flash programming
begin
mem_we_n = 1'b0; // do the negedge of mem_we_n to latch the address
mem_oe_n = 1'b1; // output disable
mem_rst_n = 1'b1; // no reset
case (cycles)
3'd0: begin
address = 21'b000000000101010101010; // AAA
write_data = 8'b10101010; // AA
end
3'd1: begin
address = 21'b000000000010101010101; // 555
write_data = 8'b01010101; // 55
end
3'd2: begin
address = 21'b000000000101010101010; // AAA
write_data = 8'b10100000; // A0
end
3'd3: begin
address = 21'd0; // ??? what should I put here, it says the program address
write_data = 8'd10; // ??? what should I put here, it says the program data
end
endcase
cycles = cycles + 1;
end
else // clock cycles >= 5: flash reading
begin
mem_we_n = 1'b0; // do the negedge of mem_we_n to latch the address
mem_oe_n = 1'b0; // output enable
address = address + 1;
read_data = data;
end
end
else // CLOCK NEGEDGE
begin
mem_we_n = 1'b1; // do the posedge of mem_we_n to latch the data (write or read)
end
end
endmodule
Thanks very much in advance. Any help is appreciated :)
Link Copied
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
You need to Program code 1st to 4th bus cycle. You can specify data, addr in 4th cycle.
1st: Addr:AAA, Data:AA 2nd:Addr:555, Data:55 3rd:Addr:AAA, Data:A0 4th: Addr, Data For read sequence, just use Addr,Data. I don't think you need to add write command.- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
You only need to issue the 3 (or more) cycle 'unlock' sequence when you're writing/erasing a FLASH device but not when you're reading from it. Any operation that changes the contents must be preceded by the unlock sequence (unless you've already activated the unlock bypass - I suggest you get something working before experimenting with that). There are some other special commands that require unlock codes. However, you don't need to unlock the device to read from it, just present the address and assert CE# & OE# (WE# de-asserted).
If you haven't already, I suggest you start by looking to implement a command like 'Manufacturer ID' to prove your basic code sequence. This should return you a known, fixed value which, I hope, should help consolidate the basic timings your code generates. Cheers, Alex- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Thank you very much for your response. I have tried to implement a smal FSM to do the reading operation. Actually, in my system I only need to read from the flash and not to write.
I have attached the code in the next reply.- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Am 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
- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page