//-------------------------------------------------------------------
//
//  Filename      : GFP.v
//  Author        : Huang Lei Lei
//  Created       : 2015-09-09
//  Description   : module general fpga platform
//
//-------------------------------------------------------------------

`include "GFP_defines.v"

module GFP(
  // global
  clk                   ,
  rstn                  ,
  // control
  proc_en               ,
  vga_en                ,
  // 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           ,
  // vga
  vga_clk               ,
  vga_r                 ,
  vga_g                 ,
  vga_b                 ,
  vga_hs                ,
  vga_vs                ,
  vga_sync_n            ,
  vga_blank_n           ,
  // dbg
  DBG_PROC_FIFO_ERR     ,
  DBG_VGA_FIFO_ERR      ,
  );


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

  parameter    AXI_DW       = 64                ,
               AXI_AW       = 32                ,
               AXI_MIDW     = 4                 ,
               AXI_SIDW     = 8                 ;

  parameter    PROC_WID     = 0                 ,
               VGA_RID      = 0                 ;


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

  // global
  input                     clk                 ;
  input                     rstn                ;
  
  // control
  input                     proc_en             ;
  input                     vga_en              ;

  // 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         ;

  // vga
  output                    vga_clk             ;
  output  [7        : 0]    vga_r               ;
  output  [7        : 0]    vga_g               ;
  output  [7        : 0]    vga_b               ;
  output                    vga_hs              ;
  output                    vga_vs              ;
  output                    vga_sync_n          ;
  output                    vga_blank_n         ;

  // dbg
  output  [1        : 0]    DBG_PROC_FIFO_ERR   ;
  output  [1        : 0]    DBG_VGA_FIFO_ERR    ;


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

  // clk & rst
  wire                      sys_clk             ;
  wire                      sys_rst             ;
  wire                      vga_clk             ;
  wire                      vga_ctrl_clk        ;
  wire                      vga_ctrl_rst        ;

  // gen_m
  wire  [AXI_AW-1   : 0]    gen_m_wr_maddr      , gen_m_rd_maddr      ;
  wire  [1          : 0]    gen_m_wr_mburst     , gen_m_rd_mburst     ;
  wire  [3          : 0]    gen_m_wr_mcache     , gen_m_rd_mcache     ;
  wire  [AXI_DW-1   : 0]    gen_m_wr_mdata      , gen_m_rd_mdata      ;
  wire  [AXI_MIDW-1 : 0]    gen_m_wr_mid        , gen_m_rd_mid        ;
  wire  [3          : 0]    gen_m_wr_mlen       , gen_m_rd_mlen       ;
  wire                      gen_m_wr_mlock      , gen_m_rd_mlock      ;
  wire  [2          : 0]    gen_m_wr_mprot      , gen_m_rd_mprot      ;
  wire                      gen_m_wr_mread      , gen_m_rd_mread      ;
  wire                      gen_m_wr_mready     , gen_m_rd_mready     ;
  wire  [2          : 0]    gen_m_wr_msize      , gen_m_rd_msize      ;
  wire                      gen_m_wr_mwrite     , gen_m_rd_mwrite     ;
  wire  [AXI_DW/8-1 : 0]    gen_m_wr_mwstrb     , gen_m_rd_mwstrb     ;
  wire                      gen_m_wr_saccept    , gen_m_rd_saccept    ;
  wire  [AXI_DW-1   : 0]    gen_m_wr_sdata      , gen_m_rd_sdata      ;
  wire  [AXI_MIDW-1 : 0]    gen_m_wr_sid        , gen_m_rd_sid        ;
  wire                      gen_m_wr_slast      , gen_m_rd_slast      ;
  wire  [2          : 0]    gen_m_wr_sresp      , gen_m_rd_sresp      ;
  wire                      gen_m_wr_svalid     , gen_m_rd_svalid     ;

  // sdram ctrl_line
  wire  [3          : 0]    sdram_dout_valid    ;
  wire  [31         : 0]    sdram_rd_data       ;
  wire  [31         : 0]    sdram_wr_data       ;


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

//*** WIRE ASSIGNMENT ****************************

//*** AXI BUS ************************************

  axi u_axi_bus(
    // clk & rstn
    .ACLK_aclk                ( sys_clk             ),
    .ARESETn_aresetn          (!sys_rst             ),
    .HCLK_hclk                ( sys_clk             ),
    .HRESETn_hresetn          (!sys_rst             ),
    // remap
    .i_axi_remap_n            ( 1                   ),
    // clk enable
    .gm_rd_gclken             ( 1                   ),
    .gm_wr_gclken             ( 1                   ),
    // gen master
    .gen_m_rd_maddr           ( gen_m_rd_maddr      ),
    .gen_m_rd_mburst          ( gen_m_rd_mburst     ),
    .gen_m_rd_mcache          ( gen_m_rd_mcache     ),
    .gen_m_rd_mdata           ( gen_m_rd_mdata      ),
    .gen_m_rd_mid             ( gen_m_rd_mid        ),
    .gen_m_rd_mlen            ( gen_m_rd_mlen       ),
    .gen_m_rd_mlock           ( gen_m_rd_mlock      ),
    .gen_m_rd_mprot           ( gen_m_rd_mprot      ),
    .gen_m_rd_mread           ( gen_m_rd_mread      ),
    .gen_m_rd_mready          ( gen_m_rd_mready     ),
    .gen_m_rd_msize           ( gen_m_rd_msize      ),
    .gen_m_rd_mwrite          ( gen_m_rd_mwrite     ),
    .gen_m_rd_mwstrb          ( gen_m_rd_mwstrb     ),
    .gen_m_rd_saccept         ( gen_m_rd_saccept    ),
    .gen_m_rd_sdata           ( gen_m_rd_sdata      ),
    .gen_m_rd_sid             ( gen_m_rd_sid        ),
    .gen_m_rd_slast           ( gen_m_rd_slast      ),
    .gen_m_rd_sresp           ( gen_m_rd_sresp      ),
    .gen_m_rd_svalid          ( gen_m_rd_svalid     ),
    // gen master
    .gen_m_wr_maddr           ( gen_m_wr_maddr      ),
    .gen_m_wr_mburst          ( gen_m_wr_mburst     ),
    .gen_m_wr_mcache          ( gen_m_wr_mcache     ),
    .gen_m_wr_mdata           ( gen_m_wr_mdata      ),
    .gen_m_wr_mid             ( gen_m_wr_mid        ),
    .gen_m_wr_mlen            ( gen_m_wr_mlen       ),
    .gen_m_wr_mlock           ( gen_m_wr_mlock      ),
    .gen_m_wr_mprot           ( gen_m_wr_mprot      ),
    .gen_m_wr_mread           ( gen_m_wr_mread      ),
    .gen_m_wr_mready          ( gen_m_wr_mready     ),
    .gen_m_wr_msize           ( gen_m_wr_msize      ),
    .gen_m_wr_mwrite          ( gen_m_wr_mwrite     ),
    .gen_m_wr_mwstrb          ( gen_m_wr_mwstrb     ),
    .gen_m_wr_saccept         ( gen_m_wr_saccept    ),
    .gen_m_wr_sdata           ( gen_m_wr_sdata      ),
    .gen_m_wr_sid             ( gen_m_wr_sid        ),
    .gen_m_wr_slast           ( gen_m_wr_slast      ),
    .gen_m_wr_sresp           ( gen_m_wr_sresp      ),
    .gen_m_wr_svalid          ( gen_m_wr_svalid     ),
    // sdram ports from memctl
    .i_memctl_clear_sr_dp     ( 1'b0                ),
    .i_memctl_gpi             ( 8'b0                ),
    .i_memctl_power_down      ( 1'b0                ),
    .i_memctl_remap           ( 1'b0                ),
    .i_memctl_s_rd_data       ( sdram_rd_data       ),
    .i_memctl_s_rd_ready      ( 1'b0                ),
    .i_memctl_s_sda_in        ( 1'b0                ),
    .i_memctl_s_cas_n         ( sdram_cas_n         ),
    .i_memctl_s_cke           ( sdram_cke           ),
    .i_memctl_s_dout_valid    ( sdram_dout_valid    ),
    .i_memctl_s_dqm           ( sdram_dqm           ),
    .i_memctl_s_ras_n         ( sdram_ras_n         ),
    .i_memctl_s_addr          ( sdram_addr          ),
    .i_memctl_s_bank_addr     ( sdram_bank_addr     ),
    .i_memctl_s_sel_n         ( sdram_sel_n         ),
    .i_memctl_s_we_n          ( sdram_we_n          ),
    .i_memctl_s_wr_data       ( sdram_wr_data       )
    );


//*** PROC ***************************************

  proc_axi_top #(
    .AXI_DW                   ( AXI_DW              ),
    .AXI_AW                   ( AXI_AW              ),
    .AXI_WID                  ( PROC_WID            )
  ) proc_axi_top0(
    // global
    .axi_clk                  ( sys_clk             ),
    .axi_rstn                 (!sys_rst             ),
    .proc_clk                 ( sys_clk             ),
    .proc_rstn                (!sys_rst             ),
    // control
    .proc_en                  ( proc_en             ),
    // gm
    .gm_maddr                 ( gen_m_wr_maddr      ),
    .gm_mburst                ( gen_m_wr_mburst     ),
    .gm_mcache                ( gen_m_wr_mcache     ),
    .gm_mdata                 ( gen_m_wr_mdata      ),
    .gm_mid                   ( gen_m_wr_mid        ),
    .gm_mlen                  ( gen_m_wr_mlen       ),
    .gm_mlock                 ( gen_m_wr_mlock      ),
    .gm_mprot                 ( gen_m_wr_mprot      ),
    .gm_mread                 ( gen_m_wr_mread      ),
    .gm_mready                ( gen_m_wr_mready     ),
    .gm_msize                 ( gen_m_wr_msize      ),
    .gm_mwrite                ( gen_m_wr_mwrite     ),
    .gm_mwstrb                ( gen_m_wr_mwstrb     ),
    .gm_saccept               ( gen_m_wr_saccept    ),
    .gm_sdata                 ( gen_m_wr_sdata      ),
    .gm_sid                   ( gen_m_wr_sid        ),
    .gm_slast                 ( gen_m_wr_slast      ),
    .gm_sresp                 ( gen_m_wr_sresp      ),
    .gm_svalid                ( gen_m_wr_svalid     ),
    // fifo err
    .proc_fifo_err            ( DBG_PROC_FIFO_ERR   )
    );


//*** VGA ****************************************

  vga_axi_top #(
    .AXI_DW                   ( AXI_DW              ),
    .AXI_AW                   ( AXI_AW              ),
    .AXI_RID                  ( VGA_RID             )
  ) vga_axi_top0(
    // global
    .axi_clk                  ( sys_clk             ),
    .axi_rstn                 (!sys_rst             ),
    .vga_ctrl_clk             ( vga_ctrl_clk        ),
    .vga_ctrl_rstn            (!vga_ctrl_rst        ),
    // control
    .vga_en                   ( vga_en              ),
    // gm
    .gm_maddr                 ( gen_m_rd_maddr      ),
    .gm_mburst                ( gen_m_rd_mburst     ),
    .gm_mcache                ( gen_m_rd_mcache     ),
    .gm_mdata                 ( gen_m_rd_mdata      ),
    .gm_mid                   ( gen_m_rd_mid        ),
    .gm_mlen                  ( gen_m_rd_mlen       ),
    .gm_mlock                 ( gen_m_rd_mlock      ),
    .gm_mprot                 ( gen_m_rd_mprot      ),
    .gm_mread                 ( gen_m_rd_mread      ),
    .gm_mready                ( gen_m_rd_mready     ),
    .gm_msize                 ( gen_m_rd_msize      ),
    .gm_mwrite                ( gen_m_rd_mwrite     ),
    .gm_mwstrb                ( gen_m_rd_mwstrb     ),
    .gm_saccept               ( gen_m_rd_saccept    ),
    .gm_sdata                 ( gen_m_rd_sdata      ),
    .gm_sid                   ( gen_m_rd_sid        ),
    .gm_slast                 ( gen_m_rd_slast      ),
    .gm_sresp                 ( gen_m_rd_sresp      ),
    .gm_svalid                ( gen_m_rd_svalid     ),
    // vga
    .oVGA_R                   ( vga_r               ),
    .oVGA_G                   ( vga_g               ),
    .oVGA_B                   ( vga_b               ),
    .oVGA_H_SYNC              ( vga_hs              ),
    .oVGA_V_SYNC              ( vga_vs              ),
    .oVGA_SYNC                ( vga_sync_n          ),
    .oVGA_BLANK               ( vga_blank_n         ),
    // fifo err
    .vga_fifo_err             ( DBG_VGA_FIFO_ERR    )
    );


//*** CLKGEN *************************************

  GFP_clkgen GFP_clkgen0(
    // clk&rst in
    .board_clk              ( clk                 ),
    .board_rst              (!rstn                ),
    // clk&rst out
    .sys_clk                ( sys_clk             ),
    .sys_rst                ( sys_rst             ),
    .vga_ctrl_clk           ( vga_ctrl_clk        ),
    .vga_ctrl_rst           ( vga_ctrl_rst        )
    );

  assign vga_clk   = !vga_ctrl_clk ;
  assign sdram_clk =  sys_clk      ;

//*** I/O PAD ************************************

  // for sdram
  sdram_data_ctrl sdram_data_ctrl0(
    .datain         ( sdram_wr_data                 ),
    .oe             ( { {8{sdram_dout_valid[3]}},
                        {8{sdram_dout_valid[2]}},
                        {8{sdram_dout_valid[1]}},
                        {8{sdram_dout_valid[0]}}  } ),
    .dataio         ( sdram_dq                      ),
    .dataout        ( sdram_rd_data                 )
    );


endmodule