-------------------------------------------------------------------------
-- Project: SDRAM controller
-- This file: Top-level put all together
--
-- Copyright (C) 2007 J. Ahrensfeld
--
-- This program is free software: you can redistribute it and/or modify
-- it under the terms of the GNU General Public License as published by
-- the Free Software Foundation, either version 3 of the License, or
-- (at your option) any later version.
--
-- This program 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 General Public License for more details.
--
-- You should have received a copy of the GNU General Public License
-- along with this program.  If not, see <http://www.gnu.org/licenses/>.
--
-- For questions and ideas, please contact the author at jens@jayfield.org
--
--------------------------------------------------------------------------

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.numeric_std.ALL;

use work.sdram_const.all;
use work.sdram_config.all;
use work.sdram_types.all;

entity sdram_ctrl_top is
	Generic
	(
		F_SYSCLK		: real		:= 100.0;
		F_SDRCLK		: real		:= 100.0;
		FIFO_DEPTH		: natural := 3
	);
	Port
	(
		sys_rst_in			: in  STD_LOGIC;
		sys_clk_in			: in  STD_LOGIC;
		
		sdram_clk0			: in  STD_LOGIC;
		sdram_rst0			: in  STD_LOGIC;
		
		-- User interface
		u_busy				: out STD_LOGIC;
		u_cmd				: in  user_cmd_t;
		u_cmd_we			: in  STD_LOGIC;
		u_addr				: in  user_addr_t;
		u_tag				: in  user_tag_t;
		
		-- Phy interface
		phy_ctrl			: out phy_ctrl_t
	
	);
end sdram_ctrl_top;

architecture rtl of sdram_ctrl_top is

	signal sd_cmd_in		: sdr_cmd_t;
	signal sd_cmd			: sdr_cmd_t;
	signal sd_cmd_we		: std_logic;
	signal cke				: std_logic;

	-- SD command FIFO
	constant CMD_FIFO_DATA_WIDTH	: positive := user_tag_t'length + 4 + mode_word_t'length + col_addr_t'length;
	signal cmd_fifo_din				: unsigned(CMD_FIFO_DATA_WIDTH-1 downto 0);
	signal cmd_fifo_dout			: unsigned(CMD_FIFO_DATA_WIDTH-1 downto 0);
	signal cmd_fifo_re				: std_logic;
	signal cmd_fifo_we				: std_logic;
	signal cmd_fifo_full			: std_logic;
	signal cmd_fifo_empty			: std_logic;

	alias tag_fifo_in is cmd_fifo_din(CMD_FIFO_DATA_WIDTH-1 downto CMD_FIFO_DATA_WIDTH-user_tag_t'length);
	alias cmd_fifo_in is cmd_fifo_din(CMD_FIFO_DATA_WIDTH-user_tag_t'length-1 downto CMD_FIFO_DATA_WIDTH-user_tag_t'length-4);
	alias mode_fifo_in is cmd_fifo_din(CMD_FIFO_DATA_WIDTH-user_tag_t'length-4-1 downto CMD_FIFO_DATA_WIDTH-user_tag_t'length-4-mode_word_t'length);
	alias col_fifo_in is cmd_fifo_din(CMD_FIFO_DATA_WIDTH-user_tag_t'length-4-mode_word_t'length-1 downto 0);

	alias sd_tag_fifo_out is cmd_fifo_dout(CMD_FIFO_DATA_WIDTH-1 downto CMD_FIFO_DATA_WIDTH-user_tag_t'length);
	alias sd_cmd_fifo_out is cmd_fifo_dout(CMD_FIFO_DATA_WIDTH-user_tag_t'length-1 downto CMD_FIFO_DATA_WIDTH-user_tag_t'length-4);
	alias sd_mode_fifo_out is cmd_fifo_dout(CMD_FIFO_DATA_WIDTH-user_tag_t'length-4-1 downto CMD_FIFO_DATA_WIDTH-user_tag_t'length-4-mode_word_t'length);
	alias sd_col_fifo_out is cmd_fifo_dout(CMD_FIFO_DATA_WIDTH-user_tag_t'length-4-mode_word_t'length-1 downto 0);

begin 
    
	---------------------------------
	sd_cmd_we		<= not cmd_fifo_empty;
	cmd_fifo_in		<= to_unsigned(sd_cmd_in, 4);
	sd_cmd			<= sdr_cmd_t(to_integer(sd_cmd_fifo_out));

	---------------------------------

	-- Main controller
	inst_sdram_ctrl : entity work.sdram_ctrl
	Generic map 
	(
		F_SYSCLK		=> F_SYSCLK
	)
	Port map 
	(
		rst				=> sys_rst_in,
		clk				=> sys_clk_in,
		u_busy			=> u_busy,
		u_tag_in		=> u_tag,
		u_tag_out		=> tag_fifo_in,
		u_cmd			=> u_cmd,
		u_cmd_we		=> u_cmd_we,
		u_addr			=> u_addr,
		sdr_cmd_busy	=> cmd_fifo_full,
		sdr_cmd			=> sd_cmd_in,
		sdr_cmd_we		=> cmd_fifo_we,
		col_addr		=> col_fifo_in,
		sdr_mode		=> mode_fifo_in
	);
   
	-- Instantiate synchronous FIFO
	inst_sd_cmd_fifo: entity work.fifo_async
	GENERIC MAP
	(
		addr_width			=> FIFO_DEPTH,
		data_width			=> CMD_FIFO_DATA_WIDTH
	)
	PORT MAP
	(
		rst			=>	sdram_rst0,
		clk_w		=>	sys_clk_in,
		clk_r		=>	sdram_clk0,
		we			=>	cmd_fifo_we,
		re			=>	cmd_fifo_re,
		fifo_full	=>	cmd_fifo_full,
		fifo_empty	=>	cmd_fifo_empty,
		fifo_afull	=>	open,
		fifo_aempty	=>	open,
		data_w		=>  cmd_fifo_din,
		data_r		=>  cmd_fifo_dout
	);

	-- DDR SDRAM command fsm
	inst_sdram_cmd : entity work.sdram_cmd
	Generic map
	(
		F_SDRCLK		=> F_SDRCLK
	)
	Port map
	(
		rst				=> sdram_rst0,
		clk				=> sdram_clk0,
		tag				=> sd_tag_fifo_out,
		col_addr		=> sd_col_fifo_out,
		mode_word		=> sd_mode_fifo_out,
		cmd				=> sd_cmd,
		cmd_we			=> sd_cmd_we,
		cmd_ack			=> cmd_fifo_re,
		phy_ctrl		=> phy_ctrl
	);
   
  
end architecture rtl;

