?? ddr1_controller.vhd
字號:
-------------------------------------------------------------------------------
-- Copyright (c) 2006 Xilinx, Inc.
-- This design is confidential and proprietary of Xilinx, All Rights Reserved.
-------------------------------------------------------------------------------
-- ____ ____
-- / /\/ /
-- /___/ \ / Vendor: Xilinx
-- \ \ \/ Version: 1.1
-- \ \ Filename: ddr1_controller.vhd
-- / / Date Last Modified: 5/11/06
-- /___/ /\ Date Created:
-- \ \ / \
-- \___\/\___\
--
--Device: Virtex-5
--Purpose: Main DDR1 transaction control state machine. Handles all SDRAM
-- commands, except power-up initialization (initialization is done in
-- the PHY layer).
--Reference:
-- XAPP851
--Revision History:
-- Rev 1.0 - Internal release. Author: Toshihiko Moriyama. 4/29/06.
-- Rev 1.1 - External release. Added header. Deleted unused signal
-- chip_cnt(1:0). Changed ctrl_ddr_cke, ddr_cke_r to single bit.
-- 5/11/06
-- Rev 1.2 - Fixed bug with CL=2.5 read-write spacing. rchiu. 6/28/06
-------------------------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
library UNISIM;
use UNISIM.vcomponents.all;
use work.ddr1_parameters.all;
entity ddr1_controller is
port(
clk0 : in std_logic;
refresh_clk : in std_logic;
rst : in std_logic;
af_addr : in std_logic_vector(35 downto 0);
af_empty : in std_logic;
phy_Dly_Slct_Done : in std_logic;
burst_length : out std_logic_vector(2 downto 0);
ctrl_af_RdEn : out std_logic;
ctrl_Wdf_RdEn : out std_logic;
ctrl_Dqs_Rst : out std_logic;
ctrl_Dqs_En : out std_logic;
ctrl_WrEn : out std_logic;
ctrl_RdEn : out std_logic;
ctrl_ddr_address : out std_logic_vector((row_address -1) downto 0);
ctrl_ddr_ba : out std_logic_vector((bank_address -1) downto 0);
ctrl_ddr_ras_L : out std_logic;
ctrl_ddr_cas_L : out std_logic;
ctrl_ddr_we_L : out std_logic;
ctrl_ddr_cs_L : out std_logic_vector((no_of_cs -1) downto 0);
ctrl_ddr_cke : out std_logic
);
end ddr1_controller;
architecture arch of ddr1_controller is
constant IDLE : std_logic_vector(4 downto 0) := "00000";
constant LOAD_MODE_REG_ST : std_logic_vector(4 downto 0) := "00001";
constant MODE_REGISTER_WAIT : std_logic_vector(4 downto 0) := "00010";
constant PRECHARGE : std_logic_vector(4 downto 0) := "00011";
constant PRECHARGE_WAIT : std_logic_vector(4 downto 0) := "00100";
constant AUTO_REFRESH : std_logic_vector(4 downto 0) := "00101";
constant AUTO_REFRESH_WAIT : std_logic_vector(4 downto 0) := "00110";
constant ACTIVE : std_logic_vector(4 downto 0) := "00111";
constant ACTIVE_WAIT : std_logic_vector(4 downto 0) := "01000";
constant FIRST_READ : std_logic_vector(4 downto 0) := "01001";
constant BURST_READ : std_logic_vector(4 downto 0) := "01010";
constant READ_WAIT : std_logic_vector(4 downto 0) := "01011";
constant FIRST_WRITE : std_logic_vector(4 downto 0) := "01100";
constant BURST_WRITE : std_logic_vector(4 downto 0) := "01101";
constant WRITE_WAIT : std_logic_vector(4 downto 0) := "01110";
constant WRITE_READ : std_logic_vector(4 downto 0) := "01111";
constant READ_WRITE : std_logic_vector(4 downto 0) := "10000";
constant cs_h0 : std_logic_vector(3 downto 0) := "0000";
constant cs_h1 : std_logic_vector(3 downto 0) := "0001";
constant cs_h2 : std_logic_vector(3 downto 0) := "0010";
constant cs_h3 : std_logic_vector(3 downto 0) := "0011";
constant cs_h5 : std_logic_vector(3 downto 0) := "0101";
constant cs_h6 : std_logic_vector(3 downto 0) := "0110";
constant cs_h7 : std_logic_vector(3 downto 0) := "0111";
constant cs_hA : std_logic_vector(3 downto 0) := "1010";
constant cs_hB : std_logic_vector(3 downto 0) := "1011";
constant cs_hD : std_logic_vector(3 downto 0) := "1101";
constant cs_hE : std_logic_vector(3 downto 0) := "1110";
constant cs_hF : std_logic_vector(3 downto 0) := "1111";
signal ref_flag : std_logic;
signal ref_flag_266 : std_logic;
signal ref_flag_266_r : std_logic;
signal auto_ref : std_logic;
signal next_state : std_logic_vector(4 downto 0);
signal state : std_logic_vector(4 downto 0);
signal state_r2 : std_logic_vector(4 downto 0);
signal state_r3 : std_logic_vector(4 downto 0);
signal row_addr_r : std_logic_vector((row_address - 1) downto 0);
signal ddr_address_r1 : std_logic_vector((row_address - 1) downto 0);
signal ddr_ba_r1 : std_logic_vector((bank_address - 1) downto 0);
signal mrd_count : std_logic;
signal rp_count : std_logic_vector(2 downto 0);
signal rfc_count : std_logic_vector(5 downto 0);
signal rcd_count : std_logic_vector(2 downto 0);
signal ras_count : std_logic_vector(3 downto 0);
signal wr_to_rd_count : std_logic_vector(3 downto 0);
signal rd_to_wr_count : std_logic_vector(3 downto 0);
signal rtp_count : std_logic_vector(3 downto 0);
signal wtp_count : std_logic_vector(3 downto 0);
signal refi_count : std_logic_vector((max_ref_width - 1) downto 0);
--signal cas_count : std_logic_vector(2 downto 0);
signal cas_check_count : std_logic_vector(3 downto 0);
signal wrburst_cnt : std_logic_vector(2 downto 0);
signal read_burst_cnt : std_logic_vector(2 downto 0);
signal ctrl_WrEn_cnt : std_logic_vector(2 downto 0);
signal rdburst_cnt : std_logic_vector(2 downto 0);
--signal rc_count : std_logic_vector(3 downto 0);
signal af_addr_r : std_logic_vector(35 downto 0);
signal af_addr_r1 : std_logic_vector(35 downto 0);
signal wdf_rden_r : std_logic;
signal wdf_rden_r2 : std_logic;
signal wdf_rden_r3 : std_logic;
signal wdf_rden_r4 : std_logic;
signal af_rden : std_logic;
signal ddr_ras_r2 : std_logic;
signal ddr_cas_r2 : std_logic;
signal ddr_we_r2 : std_logic;
signal ddr_ras_r : std_logic;
signal ddr_cas_r : std_logic;
signal ddr_we_r : std_logic;
signal ddr_ras_r3 : std_logic;
signal ddr_cas_r3 : std_logic;
signal ddr_we_r3 : std_logic;
signal idle_cnt : std_logic_vector(3 downto 0);
signal conflict_resolved_r : std_logic;
signal ddr_cs_r1 : std_logic_vector((no_of_cs - 1) downto 0);
signal ddr_cs_r : std_logic_vector((no_of_cs - 1) downto 0);
signal ddr_cke_r : std_logic;
signal burst_cnt : std_logic_vector(3 downto 0);
signal burst_cnt_by2 : std_logic_vector(2 downto 0);
signal conflict_detect : std_logic;
signal conflict_detect_r : std_logic;
signal load_mode_reg : std_logic_vector((row_address - 1) downto 0);
signal ext_mode_reg : std_logic_vector((row_address - 1) downto 0);
signal CAS_LATENCY_VALUE : std_logic_vector(3 downto 0);
signal BURST_LENGTH_VALUE : std_logic_vector(2 downto 0);
signal REGISTERED_VALUE : std_logic;
signal ECC_VALUE : std_logic;
signal WR : std_logic;
signal RD : std_logic;
signal LMR : std_logic;
signal PRE : std_logic;
signal REF : std_logic;
signal ACT : std_logic;
signal WR_r : std_logic;
signal RD_r : std_logic;
signal LMR_r : std_logic;
signal PRE_r : std_logic;
signal REF_r : std_logic;
signal ACT_r : std_logic;
signal af_empty_r : std_logic;
signal LMR_PRE_REF_ACT_cmd_r : std_logic;
signal command_address : std_logic_vector(2 downto 0);
signal zeroes : std_logic_vector((row_address - col_ap_width) downto 0);
signal done_200us : std_logic;
signal write_state : std_logic;
signal read_state : std_logic;
signal read_write_state : std_logic;
signal burst_write_state : std_logic;
signal first_write_state : std_logic;
signal burst_read_state : std_logic;
signal first_read_state : std_logic;
signal burst_read_state_r2 : std_logic;
signal burst_read_state_r3 : std_logic;
signal first_read_state_r2 : std_logic;
signal read_write_state_r2 : std_logic;
signal read_write_state_r3 : std_logic;
signal ctrl_WrEn_r : std_logic;
signal ctrl_WrEn_r1 : std_logic;
signal ctrl_Dqs_Rst_r : std_logic;
signal ctrl_Dqs_Rst_r1 : std_logic;
signal ctrl_Dqs_En_r : std_logic;
signal ctrl_Dqs_En_r1 : std_logic;
signal ctrl_RdEn_r : std_logic;
signal ctrl_RdEn_r1 : std_logic;
signal ctrl_Wdf_RdEn_r : std_logic;
signal ctrl_Wdf_RdEn_r1 : std_logic;
signal rd_to_wr_cas_delay : std_logic;
begin
REGISTERED_VALUE <= '0';
CAS_LATENCY_VALUE <= "0010" when (load_mode_reg(6 downto 4) = "110") else
'0' & load_mode_reg(6 downto 4) ;
BURST_LENGTH_VALUE <= load_mode_reg(2 downto 0);
burst_length <= burst_cnt(2 downto 0);
command_address <= af_addr(34 downto 32);
zeroes <= (others => '0');
ECC_VALUE <= ecc_enable;
-- ADDED, RCHIU, 06/28/06
-- Fix for CL=2.5 read-write spacing. CL=2.5 has the same spacing from read
-- to write as for CL=3 (and not same spacing as CL=2). This signal is an
-- additive factor tacked on to an internal counter for forcing minimum delay
-- between reads and writes. =0 for CL=2, =1 for CL=2.5,3
rd_to_wr_cas_delay <= '0' when (load_mode_reg(6 downto 4) = "010") else
'1';
burst_read_state <= '1' when ((conflict_detect = '0') or (conflict_resolved_r = '1')) and (state = BURST_READ) and (RD = '1') else '0';
first_read_state <= '1' when ((conflict_detect = '0') or (conflict_resolved_r = '1')) and (state = FIRST_READ) and (RD = '1') else '0';
read_state <= burst_read_state or first_read_state;
read_write_state <= write_state or read_state;
burst_write_state <= '1' when ((conflict_detect = '0') or (conflict_resolved_r = '1')) and (state = BURST_WRITE) and (WR = '1') else '0';
first_write_state <= '1' when ((conflict_detect = '0') or (conflict_resolved_r = '1')) and (state = FIRST_WRITE) and (WR = '1') else '0';
write_state <= burst_write_state or first_write_state;
-- fifo control signals
ctrl_af_RdEn <= af_rden;
conflict_detect <= af_addr(35) and phy_Dly_Slct_Done and (not af_empty);
process(command_address, phy_Dly_Slct_Done, af_empty)
begin
WR <= '0';
RD <= '0';
LMR <= '0';
PRE <= '0';
REF <= '0';
ACT <= '0';
if((phy_Dly_Slct_Done = '1') and (af_empty = '0')) then
case command_address is
when "000" => LMR <= '1';
when "001" => REF <= '1';
when "010" => PRE <= '1';
when "011" => ACT <= '1';
when "100" => WR <= '1';
when "101" => RD <= '1';
when others => null;
end case;
end if;
end process;
-- register address outputs
process (clk0)
begin
if(clk0'event and clk0 = '1') then
if(rst = '1') then
WR_r <= '0';
RD_r <= '0';
LMR_r <= '0';
PRE_r <= '0';
REF_r <= '0';
ACT_r <= '0';
af_empty_r <= '0';
LMR_PRE_REF_ACT_cmd_r <= '0';
else
WR_r <= WR;
RD_r <= RD;
LMR_r <= LMR;
PRE_r <= PRE;
REF_r <= REF;
ACT_r <= ACT;
LMR_PRE_REF_ACT_cmd_r <= LMR or PRE or REF or ACT;
af_empty_r <= af_empty;
end if;
end if;
end process;
-- register address outputs
process (clk0)
begin
if(clk0'event and clk0 = '1') then
if(rst = '1') then
af_addr_r <= (others => '0');
af_addr_r1 <= (others => '0');
conflict_detect_r <= '0';
read_write_state_r2 <= '0';
read_write_state_r3 <= '0';
first_read_state_r2 <= '0';
burst_read_state_r2 <= '0';
burst_read_state_r3 <= '0';
else
af_addr_r <= af_addr;
af_addr_r1 <= af_addr_r;
conflict_detect_r <= conflict_detect;
read_write_state_r2 <= read_write_state;
read_write_state_r3 <= read_write_state_r2;
first_read_state_r2 <= first_read_state;
burst_read_state_r2 <= burst_read_state;
burst_read_state_r3 <= burst_read_state_r2;
end if;
end if;
end process;
process (clk0)
begin
if(clk0'event and clk0 = '1') then
if(rst = '1') then
load_mode_reg <= load_mode_register((row_address-1) downto 0);
elsif((state = LOAD_MODE_REG_ST) and (LMR_r = '1') and (af_addr_r((bank_address+row_address + col_ap_width -1) downto (col_ap_width + row_address))="00")) then
load_mode_reg <= af_addr ((row_address-1) downto 0);
end if;
end if;
end process;
process (clk0)
begin
if(clk0'event and clk0 = '1') then
if(rst = '1') then
ext_mode_reg <= ext_load_mode_register((row_address-1) downto 0);
elsif((state = LOAD_MODE_REG_ST) and (LMR_r = '1') and (af_addr_r((bank_address+row_address + col_ap_width -1) downto (col_ap_width + row_address))= "01")) then
ext_mode_reg <= af_addr (row_address-1 downto 0);
end if;
end if;
end process;
-- mrd count
process (clk0)
begin
if(clk0'event and clk0 = '1') then
if(rst = '1') then
mrd_count <= '0';
elsif (state = LOAD_MODE_REG_ST) then
mrd_count <= mrd_count_value;
elsif (mrd_count /= '0') then
mrd_count <= '0';
else
mrd_count <= '0';
end if;
end if;
end process;
-- rp count
process (clk0)
begin
if(clk0'event and clk0 = '1') then
if(rst = '1') then
rp_count(2 downto 0) <= "000";
elsif (state = PRECHARGE) then
rp_count(2 downto 0) <= rp_count_value;
elsif (rp_count(2 downto 0) /= "000") then
rp_count(2 downto 0) <= rp_count(2 downto 0) - 1;
else
rp_count(2 downto 0) <= "000";
end if;
end if;
end process;
-- rfc count
process (clk0)
begin
if(clk0'event and clk0 = '1') then
if(rst = '1') then
rfc_count(5 downto 0) <= "000000";
elsif (state = AUTO_REFRESH) then
rfc_count(5 downto 0) <= rfc_count_value;
elsif (rfc_count(5 downto 0) /= "000000") then
rfc_count(5 downto 0) <= rfc_count(5 downto 0) - 1;
else
rfc_count(5 downto 0) <= "000000";
end if;
end if;
end process;
-- rcd count - 20ns
process (clk0)
begin
if(clk0'event and clk0 = '1') then
if(rst = '1') then
rcd_count(2 downto 0) <= "000";
elsif (state = ACTIVE) then
rcd_count(2 downto 0) <= rcd_count_value;
elsif (rcd_count(2 downto 0) /= "000") then
rcd_count(2 downto 0) <= rcd_count(2 downto 0) - 1;
else
rcd_count(2 downto 0) <= "000";
end if;
end if;
end process;
-- ras count - active to precharge
process (clk0)
begin
if(clk0'event and clk0 = '1') then
if(rst = '1') then
ras_count(3 downto 0) <= "0000";
elsif (state = ACTIVE) then
ras_count(3 downto 0) <= ras_count_value;
elsif (ras_count(3 downto 1) = "000") then
if (ras_count(0) /= '0') then
ras_count(0) <= '0';
end if;
else
ras_count(3 downto 0) <= ras_count(3 downto 0) - 1;
end if;
end if;
end process;
--AL+BL/2+TRTP-2
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -