📄 command_statemachine.vhd
字号:
Register_sel : in std_logic_vector(0 to C_DDR_BANK_AWIDTH-1);
Init_done : in std_logic;
Cmd_done : out std_logic;
-- Data SM interface
Read_data_done : in std_logic;
Read_data_done_rst : out std_logic;
Pend_write : out std_logic;
Pend_read : out std_logic;
Read_pause : out std_logic;
-- Counters interface
Trefi_end : in std_logic;
Trc_end : in std_logic;
Trrd_end : in std_logic;
Tras_end : in std_logic;
Twr_end : in std_logic;
GPcnt_end : in std_logic;
Tcmd_end : in std_logic;
Twr_rst : out std_logic;
Tcmd_load : out std_logic;
Tcmd_cnt_en : out std_logic;
Trefi_load : out std_logic;
Trc_load : out std_logic;
Trrd_load : out std_logic;
Tras_load : out std_logic;
GPcnt_load : out std_logic;
GPcnt_en : out std_logic;
GPcnt_data : out std_logic_vector(0 to C_GP_CNTR_WIDTH-1);
-- IOB Register interface
DDR_CSn : out std_logic_vector(0 to C_NUM_BANKS_MEM-1);
DDR_RASn : out std_logic;
DDR_CASn : out std_logic;
DDR_WEn : out std_logic;
DDR_Addr : out std_logic_vector(0 to C_DDR_AWIDTH-1);
DDR_BankAddr : out std_logic_vector(0 to C_DDR_BANK_AWIDTH-1);
DQ_oe_cmb : out std_logic;
DQS_oe : out std_logic_vector(0 to C_DDR_DWIDTH/8-1);
DQS_rst : out std_logic_vector(0 to C_DDR_DWIDTH/8-1);
DQS_setrst : out std_logic_vector(0 to C_DDR_DWIDTH/8-1);
DQ_ECC_oe_cmb : out std_logic;
DQS_ECC_oe : out std_logic;
DQS_ECC_rst : out std_logic;
DQS_ECC_setrst : out std_logic;
-- Clocks and reset
Clk : in std_logic;
Rst : in std_logic
);
end entity command_statemachine;
-----------------------------------------------------------------------------
-- Architecture section
-----------------------------------------------------------------------------
architecture imp of command_statemachine is
-----------------------------------------------------------------------------
-- Constant declarations
-----------------------------------------------------------------------------
-- setup constants for the DDR command (RCW = Ras, Cas, Wen)
-- RAS = bit 0
-- CAS = bit 1
-- WEN = bit 2
constant NOP_RCW : std_logic_vector(0 to 2) := "111";
constant ACTIVE_RCW : std_logic_vector(0 to 2) := "011";
constant READ_RCW : std_logic_vector(0 to 2) := "101";
constant WRITE_RCW : std_logic_vector(0 to 2) := "100";
constant PRECHARGE_RCW : std_logic_vector(0 to 2) := "010";
constant REFRESH_RCW : std_logic_vector(0 to 2) := "001";
constant LOAD_MR_RCW : std_logic_vector(0 to 2) := "000";
-- Precharge command has data value
constant PRECHARGE_DATA : std_logic_vector(0 to C_DDR_AWIDTH-1) := (others => '1');
-----------------------------------------------------------------------------
-- Signal declarations
-----------------------------------------------------------------------------
type COMMAND_STATE_TYPE is (IDLE, LOAD_MR_CMD, REFRESH_CMD, ACT_CMD, READ_CMD,
WRITE_CMD, WAIT_TWR, WAIT_TRAS, PRECHARGE_CMD, WAIT_TRRD);
signal cmdsm_ns : COMMAND_STATE_TYPE;
signal cmdsm_cs : COMMAND_STATE_TYPE;
-- combinational versions of registered outputs
-- other needed signals
signal pend_read_cmb : std_logic;
signal pend_write_cmb : std_logic;
signal pend_write_reg : std_logic;
signal RCW_cmd : std_logic_vector(0 to 2);
signal csn_cmd, csn_cmd_reg : std_logic_vector(0 to C_NUM_BANKS_MEM-1);
signal cmd_done_cmb : std_logic;
signal reset_pendwrreq_cmb : std_logic;
signal reset_pendrdreq_cmb : std_logic;
signal read_data_done_rst_cmb : std_logic;
signal read_pause_cmb : std_logic;
signal read_pause_i : std_logic;
signal dq_oe_cmb_i : std_logic;
signal dqs_oe_cmb : std_logic;
signal dqs_oe_reg : std_logic_vector(0 to C_DDR_DWIDTH/8-1);
signal dqs_rst_cmb : std_logic;
signal dqs_rst_reg : std_logic_vector(0 to C_DDR_DWIDTH/8-1);
signal dqs_setrst_cmb : std_logic;
signal dqs_setrst_reg : std_logic_vector(0 to C_DDR_DWIDTH/8-1);
signal dq_ecc_oe_cmb_i : std_logic;
signal dqs_ecc_oe_cmb : std_logic;
signal dqs_ecc_oe_reg : std_logic;
signal dqs_ecc_rst_cmb : std_logic;
signal dqs_ecc_rst_reg : std_logic;
signal dqs_ecc_setrst_cmb : std_logic;
signal dqs_ecc_setrst_reg : std_logic;
signal rst_read_state : std_logic;
signal read_state_cmb : std_logic;
signal read_state : std_logic;
signal read_dqs_ce_i : std_logic;
-----------------------------------------------------------------------------
-- Component declarations
-----------------------------------------------------------------------------
-----------------------------------------------------------------------------
-- Begin architecture
-----------------------------------------------------------------------------
begin -- architecture imp
-- assign outputs
-- Optimize CS logic if only one memory bank is utilized
ONE_CS: if C_NUM_BANKS_MEM = 1 generate
DDR_CSn(0) <= '0';
end generate ONE_CS;
MULT_CS: if C_NUM_BANKS_MEM /= 1 generate
DDR_CSn <= csn_cmd after 1 ns;
end generate MULT_CS;
DDR_RASn <= RCW_cmd(0) after 1 ns;
DDR_CASn <= RCW_cmd(1) after 1 ns;
DDR_WEn <= RCW_cmd(2) after 1 ns;
Pend_read <= pend_read_cmb;
Pend_write <= pend_write_reg;
Read_pause <= read_pause_i;
-- use falling edge to clock dqs_oe, dqs_rst, and dqs_setrst
-- 1 bit for each DQS
DQS_OE_SETRST_GEN: for i in 0 to C_DDR_DWIDTH/8-1 generate
begin
DQS_OE_REG_I: FDS_1
port map (
Q => DQS_oe_reg(i), --[out]
C => Clk, --[in]
D => dqs_oe_cmb, --[in]
S => Rst --[in]
);
DQS_RST_I: FDR_1
port map (
Q => DQS_rst_reg(i), --[out]
C => Clk, --[in]
D => dqs_rst_cmb, --[in]
R => Rst --[in]
);
DQS_SETRST_I: FDS_1
port map (
Q => DQS_setrst_reg(i), --[out]
C => Clk, --[in]
D => dqs_setrst_cmb, --[in]
S => Rst --[in]
);
end generate DQS_OE_SETRST_GEN;
-- Determine whether REG_DIMM - if so, register delay all associated output enable signals
-- by one clock to account for the registering of control/address signals in the DIMM
-- if not REG_DIMM, output signals
OE_PIPE_GEN: if C_REG_DIMM = 1 generate
OE_REG: process(Clk)
begin
if Clk'event and Clk='1' then
if Rst=RESET_ACTIVE then
DQ_OE_cmb <= '1';
else
DQ_OE_cmb <= dq_oe_cmb_i;
end if;
end if;
end process OE_REG;
-- use falling edge to clock dqs_oe, dqs_rst, and dqs_setrst
-- 1 bit for each DQS
DQS_OE_SETRST_REG_GEN: for i in 0 to C_DDR_DWIDTH/8-1 generate
begin
DQS_OE_REG_I: FDS_1
port map (
Q => DQS_oe(i), --[out]
C => Clk, --[in]
D => dqs_oe_reg(i), --[in]
S => Rst --[in]
);
DQS_RST_I: FDR_1
port map (
Q => DQS_rst(i), --[out]
C => Clk, --[in]
D => dqs_rst_reg(i),--[in]
R => Rst --[in]
);
DQS_SETRST_I: FDS_1
port map (
Q => DQS_setrst(i), --[out]
C => Clk, --[in]
D => dqs_setrst_reg(i), --[in]
S => Rst --[in]
);
end generate DQS_OE_SETRST_REG_GEN;
end generate OE_PIPE_GEN;
OE_NOPIPE_GEN: if C_REG_DIMM=0 generate
DQ_oe_cmb <= dq_oe_cmb_i;
DQS_oe <= dqs_oe_reg;
DQS_rst <= dqs_rst_reg;
DQS_setrst <= dqs_setrst_reg;
end generate OE_NOPIPE_GEN;
-- Generate the following signals:
-- DQ_ECC_oe_cmb
-- DQS_ECC_oe
-- DQS_ECC_rst
-- DQS_ECC_setrst
W_ECC: if C_INCLUDE_ECC_SUPPORT = 1 generate
begin
-- use falling edge to clock dqs_oe, dqs_rst, and dqs_setrst
DQS_ECC_OE_REG_I: FDS_1
port map (
Q => DQS_ECC_oe_reg, --[out]
C => Clk, --[in]
D => dqs_ecc_oe_cmb, --[in]
S => Rst --[in]
);
DQS_ECC_RST_I: FDR_1
port map (
Q => DQS_ECC_rst_reg, --[out]
C => Clk, --[in]
D => dqs_ecc_rst_cmb, --[in]
R => Rst --[in]
);
DQS_ECC_SETRST_I: FDS_1
port map (
Q => DQS_ECC_setrst_reg, --[out]
C => Clk, --[in]
D => dqs_ecc_setrst_cmb, --[in]
S => Rst --[in]
);
-- Determine whether REG_DIMM - if so, register delay all associated output enable signals
-- by one clock to account for the registering of control/address signals in the DIMM
-- if not REG_DIMM, output signals
OE_PIPE_GEN: if C_REG_DIMM = 1 generate
OE_REG: process(Clk)
begin
if Clk'event and Clk='1' then
if Rst=RESET_ACTIVE then
DQ_ECC_OE_cmb <= '1';
else
DQ_ECC_OE_cmb <= dq_ecc_oe_cmb_i;
end if;
end if;
end process OE_REG;
-- use falling edge to clock dqs_oe, dqs_rst, and dqs_setrst
DQS_ECC_OE_REG_I: FDS_1
port map (
Q => DQS_ECC_oe, --[out]
C => Clk, --[in]
D => dqs_ecc_oe_reg, --[in]
S => Rst --[in]
);
DQS_ECC_RST_I: FDR_1
port map (
Q => DQS_ECC_rst, --[out]
C => Clk, --[in]
D => dqs_ecc_rst_reg, --[in]
R => Rst --[in]
);
DQS_ECC_SETRST_I: FDS_1
port map (
Q => DQS_ECC_setrst, --[out]
C => Clk, --[in]
D => dqs_ecc_setrst_reg, --[in]
S => Rst --[in]
);
end generate OE_PIPE_GEN;
OE_NOPIPE_GEN: if C_REG_DIMM=0 generate
DQ_ECC_OE_cmb <= dq_ecc_oe_cmb_i;
DQS_ECC_oe <= dqs_ecc_oe_reg;
DQS_ECC_rst <= dqs_ecc_rst_reg;
DQS_ECC_setrst <= dqs_ecc_setrst_reg;
end generate OE_NOPIPE_GEN;
end generate W_ECC;
--------------------------------------------------------------------------------
-- Command State Machine
-- CMDSM_CMB: combinational process for determining next state
-- CMDSM_REG: state machine registers
--------------------------------------------------------------------------------
-- Combinational process
CMDSM_CMB: process (Bus2IP_CS, Comb_Bus2IP_CS, Row_addr,
Col_addr, Bank_addr, Refresh, Precharge, Load_mr,
Register_data, Register_sel, Read_data_done, Trefi_end, Trrd_end,
Tras_end, Twr_end, GPcnt_end,
Pend_rdreq,
Pend_wrreq, Bus2IP_WrReq, Same_row, Same_bank, Tcmd_end, Trc_end,
pend_write_reg, cmdsm_cs,
read_state, Init_done,
Bus2IP_RdReq, read_pause_i,
csn_cmd_reg)
begin
-- Set default values
-- Note: the DDR interface signals will be registered in IOB registers for better timing
csn_cmd <= csn_cmd_reg;
RCW_cmd <= (others => '1');
DDR_Addr <= (others => '0');
DDR_BankAddr <= (others => '0');
cmd_done_cmb <= '0';
pend_write_cmb <= '0';
pend_read_cmb <= '0';
Tcmd_load <= '0';
Tcmd_cnt_en <= '0';
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -