📄 xsasdramcntl.vhd
字号:
--------------------------------------------------------------------
-- Company : XESS Corp.
-- Engineer : Dave Vanden Bout
-- Creation Date : 05/17/2005
-- Copyright : 2005, XESS Corp
-- Tool Versions : WebPACK 6.3.03i
--
-- Description:
-- Customizes the generic SDRAM controller module for the XSA Board.
--
-- Revision:
-- 1.1.0
--
-- Additional Comments:
-- 1.1.0:
-- Added CLK_DIV generic parameter to allow stepping-down the clock frequency.
-- Added MULTIPLE_ACTIVE_ROWS generic parameter to enable/disable keeping an active row in each bank.
-- 1.0.0:
-- Initial release.
--
-- License:
-- This code can be freely distributed and modified as long as
-- this header is not removed.
--------------------------------------------------------------------
library IEEE, UNISIM;
use IEEE.std_logic_1164.all;
use IEEE.numeric_std.all;
use UNISIM.VComponents.all;
use WORK.common.all;
use WORK.sdram.all;
package XSASDRAM is
component XSASDRAMCntl
generic(
FREQ : natural := 50_000; -- operating frequency in KHz
CLK_DIV : real := 1.0; -- divisor for FREQ (can only be 1.0, 1.5, 2.0, 2.5, 3.0, 4.0, 5.0, 8.0 or 16.0)
PIPE_EN : boolean := false; -- if true, enable pipelined read operations
MAX_NOP : natural := 10000; -- number of NOPs before entering self-refresh
MULTIPLE_ACTIVE_ROWS : boolean := false; -- if true, allow an active row in each bank
DATA_WIDTH : natural := 16; -- host & SDRAM data width
NROWS : natural := 4096; -- number of rows in SDRAM array
NCOLS : natural := 512; -- number of columns in SDRAM array
HADDR_WIDTH : natural := 23; -- host-side address width
SADDR_WIDTH : natural := 12 -- SDRAM-side address width
);
port(
-- host side
clk : in std_logic; -- master clock
bufclk : out std_logic; -- buffered master clock
clk1x : out std_logic; -- host clock sync'ed to master clock (and divided if CLK_DIV>1)
clk2x : out std_logic; -- double-speed host clock
lock : out std_logic; -- true when host clock is locked to master clock
rst : in std_logic; -- reset
rd : in std_logic; -- initiate read operation
wr : in std_logic; -- initiate write operation
earlyOpBegun : out std_logic; -- read/write/self-refresh op begun (async)
opBegun : out std_logic; -- read/write/self-refresh op begun (clocked)
rdPending : out std_logic; -- read operation(s) are still in the pipeline
done : out std_logic; -- read or write operation is done
rdDone : out std_logic; -- read done and data is available
hAddr : in std_logic_vector(HADDR_WIDTH-1 downto 0); -- address from host
hDIn : in std_logic_vector(DATA_WIDTH-1 downto 0); -- data from host
hDOut : out std_logic_vector(DATA_WIDTH-1 downto 0); -- data to host
status : out std_logic_vector(3 downto 0); -- diagnostic status of the FSM
-- SDRAM side
sclkfb : in std_logic; -- clock from SDRAM after PCB delays
sclk : out std_logic; -- SDRAM clock sync'ed to master clock
cke : out std_logic; -- clock-enable to SDRAM
cs_n : out std_logic; -- chip-select to SDRAM
ras_n : out std_logic; -- SDRAM row address strobe
cas_n : out std_logic; -- SDRAM column address strobe
we_n : out std_logic; -- SDRAM write enable
ba : out std_logic_vector(1 downto 0); -- SDRAM bank address bits
sAddr : out std_logic_vector(SADDR_WIDTH-1 downto 0); -- SDRAM row/column address
sData : inout std_logic_vector(DATA_WIDTH-1 downto 0); -- SDRAM in/out databus
dqmh : out std_logic; -- high databits I/O mask
dqml : out std_logic -- low databits I/O mask
);
end component;
end package XSASDRAM;
library IEEE, UNISIM;
use IEEE.std_logic_1164.all;
use IEEE.numeric_std.all;
use UNISIM.VComponents.all;
use WORK.common.all;
use WORK.sdram.all;
entity XSASDRAMCntl is
generic(
FREQ : natural := 50_000; -- operating frequency in KHz
CLK_DIV : real := 1.0; -- divisor for FREQ (can only be 1.0, 1.5, 2.0, 2.5, 3.0, 4.0, 5.0, 8.0 or 16.0)
PIPE_EN : boolean := false; -- if true, enable pipelined read operations
MAX_NOP : natural := 10000; -- number of NOPs before entering self-refresh
MULTIPLE_ACTIVE_ROWS : boolean := false; -- if true, allow an active row in each bank
DATA_WIDTH : natural := 16; -- host & SDRAM data width
NROWS : natural := 4096; -- number of rows in SDRAM array
NCOLS : natural := 512; -- number of columns in SDRAM array
HADDR_WIDTH : natural := 23; -- host-side address width
SADDR_WIDTH : natural := 12 -- SDRAM-side address width
);
port(
-- host side
clk : in std_logic; -- master clock
bufclk : out std_logic; -- buffered master clock
clk1x : out std_logic; -- host clock sync'ed to master clock (and divided if CLK_DIV>1)
clk2x : out std_logic; -- double-speed host clock
lock : out std_logic; -- true when host clock is locked to master clock
rst : in std_logic; -- reset
rd : in std_logic; -- initiate read operation
wr : in std_logic; -- initiate write operation
earlyOpBegun : out std_logic; -- read/write/self-refresh op begun (async)
opBegun : out std_logic; -- read/write/self-refresh op begun (clocked)
rdPending : out std_logic; -- read operation(s) are still in the pipeline
done : out std_logic; -- read or write operation is done
rdDone : out std_logic; -- read done and data is available
hAddr : in std_logic_vector(HADDR_WIDTH-1 downto 0); -- address from host
hDIn : in std_logic_vector(DATA_WIDTH-1 downto 0); -- data from host
hDOut : out std_logic_vector(DATA_WIDTH-1 downto 0); -- data to host
status : out std_logic_vector(3 downto 0); -- diagnostic status of the FSM
-- SDRAM side
sclkfb : in std_logic; -- clock from SDRAM after PCB delays
sclk : out std_logic; -- SDRAM clock sync'ed to master clock
cke : out std_logic; -- clock-enable to SDRAM
cs_n : out std_logic; -- chip-select to SDRAM
ras_n : out std_logic; -- SDRAM row address strobe
cas_n : out std_logic; -- SDRAM column address strobe
we_n : out std_logic; -- SDRAM write enable
ba : out std_logic_vector(1 downto 0); -- SDRAM bank address bits
sAddr : out std_logic_vector(SADDR_WIDTH-1 downto 0); -- SDRAM row/column address
sData : inout std_logic_vector(DATA_WIDTH-1 downto 0); -- SDRAM in/out databus
dqmh : out std_logic; -- high databits I/O mask
dqml : out std_logic -- low databits I/O mask
);
end XSASDRAMCntl;
architecture arch of XSASDRAMCntl is
-- The SDRAM controller and external SDRAM chip will clock on the same edge
-- if the frequency and divided frequency are both greater than the minimum DLL lock frequency.
-- Otherwise the DLLs cannot be used so the SDRAM controller and external SDRAM clock on opposite edges
-- to try and mitigate the clock skew between the internal FPGA logic and the external SDRAM.
constant MIN_LOCK_FREQ : real := 25_000.0;
constant IN_PHASE : boolean := real(FREQ)/CLK_DIV >= MIN_LOCK_FREQ;
-- Calculate the frequency of the clock for the SDRAM.
constant SDRAM_FREQ : natural := int_select(IN_PHASE, (FREQ*integer(2.0*CLK_DIV))/2, FREQ);
-- Compute the CLKDV_DIVIDE generic paramter for the DLL modules. It defaults to 2 when CLK_DIV=1
-- because the DLL does not support a divisor of 1 on the CLKDV output. We use the CLK0 output
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -