//-------------------------------------------------------------------
//
//  Filename      : test_GFP.v
//  Author        : Huang Lei Lei
//  Created       : 2015-09-09
//  Description   : fpga test top for GFP_process.v
//
//-------------------------------------------------------------------

`include "GFP_defines.v"

module test_GFP(
  // clk & rst i
  clk                ,
  rstn               ,
  // key & led
  key                ,
  led                ,
  // sdram
  sdram_clk          ,
  sdram_addr         ,
  sdram_dq           ,
  sdram_bank_addr    ,
  sdram_dqm          ,
  sdram_ras_n        ,
  sdram_cas_n        ,
  sdram_cke          ,
  sdram_we_n         ,
  sdram_sel_n
  );


//*** PARAMETER DECLARATION ****************************************************


//*** INPUT/OUTPUT DECLARATION *************************************************

  // clk & rst oI
  input               clk                ;
  input               rstn               ;

  // key & led
  input               key                ;
  output              led                ;

  // sdram
  output              sdram_clk          ;
  output  [12 : 0]    sdram_addr         ;
  inout   [31 : 0]    sdram_dq           ;
  output  [1  : 0]    sdram_bank_addr    ;
  output  [3  : 0]    sdram_dqm          ;
  output              sdram_ras_n        ;
  output              sdram_cas_n        ;
  output              sdram_cke          ;
  output              sdram_we_n         ;
  output              sdram_sel_n        ;


//*** WIRE DECLARATION *********************************************************

  // clk & rst
  wire                sys_clk            ;
  wire                sys_rst            ;
  wire                sys_rstn           ;

  // rd
  wire                rd_ena             ;
  reg     [31 : 0]    rd_adr             ;
  wire    [63 : 0]    rd_dat             ;
  wire                rd_ack             ;

  // wr
  wire                wr_ena             ;
  reg     [31 : 0]    wr_adr             ;
  wire    [7  : 0]    wr_byt             ;
  reg     [63 : 0]    wr_dat             ;
  wire                wr_ack             ;


//*** MAIN BODY ****************************************************************

  assign sys_rstn = !sys_rst ;

  GFP dut(
    // clk & rst i
    .clk                ( clk                ),
    .rstn               ( rstn               ),
    // clk & rst o
    .sys_clk            ( sys_clk            ),
    .sys_rst            ( sys_rst            ),
    // rd
    .rd_ena_i           ( rd_ena             ),
    .rd_adr_i           ( rd_adr             ),
    .rd_dat_o           ( rd_dat             ),
    .rd_ack_o           ( rd_ack             ),
    // wr
    .wr_ena_i           ( wr_ena             ),
    .wr_adr_i           ( wr_adr             ),
    .wr_byt_i           ( wr_byt             ),
    .wr_dat_i           ( wr_dat             ),
    .wr_ack_o           ( wr_ack             ),
    // sdram
    .sdram_clk          ( sdram_clk          ),
    .sdram_addr         ( sdram_addr         ),
    .sdram_dq           ( sdram_dq           ),
    .sdram_bank_addr    ( sdram_bank_addr    ),
    .sdram_dqm          ( sdram_dqm          ),
    .sdram_ras_n        ( sdram_ras_n        ),
    .sdram_cas_n        ( sdram_cas_n        ),
    .sdram_cke          ( sdram_cke          ),
    .sdram_we_n         ( sdram_we_n         ),
    .sdram_sel_n        ( sdram_sel_n        )
    );


//*** TEST LOGIC *********************************

  reg [1 : 0] cur_state ;
  reg [1 : 0] nxt_state ;

  assign led    = cur_state==3 ;
  assign rd_ena = cur_state==1 ;
  assign wr_ena = cur_state==2 ;
  assign wr_byt = 8'hff ;

  always @(posedge sys_clk or negedge sys_rstn ) begin
    if( !sys_rstn )
      rd_adr <= 0 ;
    else if( rd_ack ) begin
      rd_adr <= rd_adr+8 ;
    end
  end

  always @(posedge sys_clk or negedge sys_rstn ) begin
    if( !sys_rstn )
      wr_adr <= 640*480*4 ;
    else if( wr_ack ) begin
      wr_adr <= wr_adr+8 ;
    end
  end

  always @(posedge sys_clk or negedge sys_rstn ) begin
    if( !sys_rstn )
      wr_dat <= 0 ;
    else if( rd_ack ) begin
      wr_dat <= ~rd_dat ;
    end
  end

  always @(posedge sys_clk or negedge sys_rstn ) begin
    if( !sys_rstn )
      cur_state <= 0 ;
    else begin
      cur_state <= nxt_state ;
    end
  end

  always @(*) begin
                                                  nxt_state = 0 ;
    case( cur_state )
      0 : begin    if( !key )                     nxt_state = 1 ;
                   else                           nxt_state = 0 ;
          end
      1 : begin    if( rd_ack )                   nxt_state = 2 ;
                   else                           nxt_state = 1 ;
          end
      2 : begin    if( wr_ack )
                     if( rd_adr==640*480*4-8 )    nxt_state = 3 ;
                     else                         nxt_state = 1 ;
                   else                           nxt_state = 2 ;
          end
      3 : begin                                   nxt_state = 3 ;
          end
    endcase
  end

endmodule