//////////////////////////////////////////////////////////////////////////////// // // Create Date: 10/07/06 // Design Name: NOR FLASH memory driver // Module Name: nor_flash // Description: NOR FLASH memory driver for INtel TE28F128J3 used on S3E // board // // Revision: // Revision 0.01 - File Created // Additional Comments: // // File format: This file has been formated to use tabstop of 4 // // Development platform: Spartan-3E Starter kit // // Copyright (C) 2006, Rick Huang // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public // License as published by the Free Software Foundation; either // version 2.1 of the License, or (at your option) any later version. // // This library is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU // Lesser General Public License for more details. // // You should have received a copy of the GNU Lesser General Public // License along with this library; if not, write to the Free Software // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA // // //////////////////////////////////////////////////////////////////////////////// module nor_flash(sf_oe_O, sf_ce_O, sf_we_O, sf_D_IO, sf_A_O, main_clk, /* Main system clock */ wADR_I, wSTB_I, wDAT_I, wDAT_O, /* Wishbone bus */ wACK_O, wWE_I); // Connection to flash memory output sf_oe_O; output sf_ce_O; output sf_we_O; inout [15:0] sf_D_IO; output [24:0] sf_A_O; // Main system clock input main_clk; // Wishbone bus signal input [24:0] wADR_I; input wSTB_I; input [7:0] wDAT_I; output [7:0] wDAT_O; output wACK_O; input wWE_I; // Local data storage reg [4:0] sf_state; reg [4:0] wait_count; reg [24:0] sf_A_O; reg sf_oe_O; reg sf_ce_O; reg sf_we_O; reg data_sample_en; reg wACK_O; /*************************************************** * Data bus flow direction control ***************************************************/ assign wDAT_O = (data_sample_en ? sf_D_IO[7:0] : 8'b00000000); assign sf_D_IO[15:8] = (sf_oe_O ? 8'b00000000 : 8'bz); assign sf_D_IO[7:0] = (sf_oe_O ? wDAT_I : 8'bz); /* Control the data flow */ /*************************************************** * Main tx/rx state machine ***************************************************/ parameter WAIT_TIME = 5'd5; parameter SF_IDLE = 0, /* Declear bit states */ SF_RD_WAIT = 2, SF_RD_END = 3, SF_WR_WAIT = 6, SF_WR_END = 7; always @ (posedge main_clk) begin case (sf_state) SF_IDLE: begin if(wSTB_I == 1) begin if(wWE_I == 0) begin sf_A_O <= wADR_I; sf_oe_O <= 0; // Enable output sf_ce_O <= 0; // Enable SF sf_we_O <= 1; // No write sf_state <= SF_RD_WAIT; data_sample_en <= 0; // Data not ready yet wait_count <= 0; end else begin sf_A_O <= wADR_I; sf_oe_O <= 1; // SF IN, FPGA OUT sf_ce_O <= 0; // Enable SF sf_we_O <= 0; // write start sf_state <= SF_WR_WAIT; data_sample_en <= 0; // No read wait_count <= 0; end end end SF_RD_WAIT: begin wait_count <= wait_count + 1; if(wait_count == WAIT_TIME) begin data_sample_en <= 1; // Data ready wACK_O <= 1; sf_state <= SF_RD_END; end end SF_RD_END: begin wACK_O <= 0; sf_oe_O <= 0; sf_ce_O <= 1; // Disable SF sf_we_O <= 1; // No write sf_state <= SF_IDLE; data_sample_en <= 0; // Data done end SF_WR_WAIT: begin wait_count <= wait_count + 1; if(wait_count == WAIT_TIME) begin wACK_O <= 1; sf_we_O <= 1; // write end sf_state <= SF_WR_END; end end SF_WR_END: begin wACK_O <= 0; sf_oe_O <= 0; sf_ce_O <= 1; // Disable SF sf_we_O <= 1; // No write sf_state <= SF_IDLE; end default: sf_state <= SF_IDLE; endcase end endmodule