Forum Discussion

Altera_Forum's avatar
Altera_Forum
Icon for Honored Contributor rankHonored Contributor
9 years ago

Reading/Writing from/to 16 Mbit Flash RAM (S29AL016M10TAI020)

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 :)

4 Replies

  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    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.
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    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
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    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.
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    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