📄 data_statemachine.vhd
字号:
-- Architecture section
-----------------------------------------------------------------------------
architecture imp of data_statemachine is
-----------------------------------------------------------------------------
-- Constant declarations
-----------------------------------------------------------------------------
constant DATA_MASK_ONES : std_logic_vector(0 to C_DDR_DWIDTH/8-1)
:= (others => '1');
constant READ_CNTR_WIDTH : integer := 4;
constant READ_CNTR_ZEROS : std_logic_vector(0 to READ_CNTR_WIDTH-1)
:= (others => '0');
constant READ_CNTR_ONE : std_logic_vector(0 to READ_CNTR_WIDTH-1)
:= conv_std_logic_vector(1, READ_CNTR_WIDTH);
-----------------------------------------------------------------------------
-- Signal declarations
-----------------------------------------------------------------------------
type DATA_STATE_TYPE is (IDLE, WAIT_CASLAT, WR_DATA, WAIT_TWR,
RD_DATA, WAIT_RDACK, DONE);
signal datasm_ns : DATA_STATE_TYPE;
signal datasm_cs : DATA_STATE_TYPE;
signal write_data_en_cmb: std_logic;
signal read_data_en_cmb : std_logic;
signal wrdata_ack : std_logic;
signal read_data_done_cmb : std_logic;
signal read_data_done_reg : std_logic;
signal data_mask : std_logic;
signal ipic_wrdata_d1 : std_logic_vector(0 to C_DDR_DWIDTH-1);
signal ipic_be_d1 : std_logic_vector(0 to C_DDR_DWIDTH/8-1);
signal write_data_en_i : std_logic;
signal write_dqs_en_i : std_logic_vector(0 to C_DDR_DWIDTH/8-1);
signal write_data_i : std_logic_vector(0 to C_IPIF_DWIDTH-1);
signal write_data_mask_i: std_logic_vector(0 to C_IPIF_DWIDTH/8-1);
signal rdack_rst_i : std_logic;
signal read_cntr_ce : std_logic;
signal read_cntr_rst : std_logic;
signal read_cnt : std_logic_vector(0 to READ_CNTR_WIDTH-1);
-----------------------------------------------------------------------------
-- Component declarations
-----------------------------------------------------------------------------
-----------------------------------------------------------------------------
-- Begin architecture
-----------------------------------------------------------------------------
begin -- architecture imp
-- assign output signals
WrAck <= wrdata_ack;
Read_data_done <= read_data_done_reg;
-- generate the read data en
RD_DATAEN_PROCESS: process(Clk)
begin
if Clk'event and Clk = '1' then
if Rst = RESET_ACTIVE then
Read_data_en <= '0';
else
Read_data_en <= read_data_en_cmb;
end if;
end if;
end process RD_DATAEN_PROCESS;
WR_DATAEN_PROCESS: process (Clk)
begin
-- register write_data_en on falling edge of clock
if Clk'event and Clk = '0' then
if Rst = RESET_ACTIVE then
write_data_en_i <= '0';
else
write_data_en_i <= write_data_en_cmb;
end if;
end if;
end process;
WRITE_DQS_EN_GEN: for i in 0 to C_DDR_DWIDTH/8 -1 generate
WR_DQS_REG: FDR
port map (
Q => write_dqs_en_i(i), --[out]
C => Clk, --[in]
D => write_data_en_cmb, --[in]
R => Rst --[in]
);
end generate WRITE_DQS_EN_GEN;
-- generate write data and write data mask
-- need to register the lower half of the bus
BUS2IPDATA_REG: process (Clk)
begin
if Clk'event and Clk='1' then
if Rst = RESET_ACTIVE then
ipic_wrdata_d1 <= (others => '0');
ipic_be_d1 <= (others => '0');
else
ipic_wrdata_d1 <= IPIC_wrdata(C_DDR_DWIDTH to C_DDR_DWIDTH*2-1);
if data_mask = '0' then
ipic_be_d1 <= IPIC_be(C_DDR_DWIDTH/8 to C_DDR_DWIDTH*2/8-1);
else
ipic_be_d1 <= (others => '0');
end if;
end if;
end if;
end process BUS2IPDATA_REG;
-- generate the data mask
write_data_mask_i <= not(IPIC_be(0 to C_DDR_DWIDTH/8-1)) & not(ipic_be_d1)
when data_mask = '0'
else DATA_MASK_ONES & not(ipic_be_d1);
write_data_i <= IPIC_wrdata(0 to C_DDR_DWIDTH-1) & ipic_wrdata_d1;
-- Determine whether REG_DIMM - if so, register delay all associated write signals
-- by one clock to account for the registering of control/address signals in the DIMM
-- if not REG_DIMM, output write signals
WRITE_PIPE_GEN: if C_REG_DIMM = 1 generate
WRITE_RE_REG: process(Clk)
begin
if Clk'event and Clk='1' then
if Rst=RESET_ACTIVE then
Write_data <= (others => '0');
Write_data_mask <= (others => '1');
Write_dqs_en <= (others => '0');
else
Write_data <= write_data_i;
Write_data_mask <= write_data_mask_i;
Write_dqs_en <= write_dqs_en_i;
end if;
end if;
end process WRITE_RE_REG;
WRITE_FE_REG: process(Clk)
begin
if Clk'event and Clk='0' then
if Rst=RESET_ACTIVE then
Write_data_en <= '0';
else
Write_data_en <= write_data_en_i after 1 ns;
end if;
end if;
end process WRITE_FE_REG;
end generate WRITE_PIPE_GEN;
NOWRITE_PIPE_GEN: if C_REG_DIMM = 0 generate
Write_data <= write_data_i;
Write_data_mask <= write_data_mask_i;
Write_dqs_en <= write_dqs_en_i;
Write_data_en <= write_data_en_i after 1 ns;
end generate NOWRITE_PIPE_GEN;
-- If ECC logic is enabled, add registers for ecc_chk_bits_wr
W_ECC_DATA_REG : if C_INCLUDE_ECC_SUPPORT = 1 generate
signal ecc_chk_bits_wr_d1 : std_logic_vector(0 to NUM_ECC_BITS-1);
signal ecc_chk_bits_wr_i : std_logic_vector(0 to NUM_ECC_BITS*2-1);
signal write_data_ecc_en_i : std_logic;
signal write_data_ecc_mask_i : std_logic_vector (0 to C_IPIF_DWIDTH/32-1);
signal write_dqs_ecc_en_i : std_logic;
begin
-- Generate write data ecc enable process
WR_DATA_ECC_EN_PROCESS: process (Clk)
begin
-- register write_data_en on falling edge of clock
if Clk'event and Clk = '0' then
if Rst = RESET_ACTIVE then
write_data_ecc_en_i <= '0';
else
write_data_ecc_en_i <= write_data_en_cmb;
end if;
end if;
end process WR_DATA_ECC_EN_PROCESS;
-- Generate write DQS ecc enable
WR_DQS_ECC_REG: FDR
port map (
Q => write_dqs_ecc_en_i, --[out]
C => Clk, --[in]
D => write_data_en_cmb, --[in]
R => Rst --[in]
);
-- Generate write data and write data mask
-- need to register the lower half of the check bit bus
BUS2IP_ECC_DATA_REG: process (Clk)
begin
if Clk'event and Clk='1' then
if Rst = RESET_ACTIVE then
ecc_chk_bits_wr_d1 <= (others => '0');
else
ecc_chk_bits_wr_d1 <= ECC_chk_bits_wr (NUM_ECC_BITS to NUM_ECC_BITS*2-1);
end if;
end if;
end process BUS2IP_ECC_DATA_REG;
-- generate the ecc data mask (condensed write_data_mask)
write_data_ecc_mask_i <= (write_data_mask_i(0) and write_data_mask_i(1) and
write_data_mask_i(2) and write_data_mask_i(3)) &
(write_data_mask_i(4) and write_data_mask_i(5) and
write_data_mask_i(6) and write_data_mask_i(7))
when data_mask = '0'
else "1" & (write_data_mask_i(4) and write_data_mask_i(5) and
write_data_mask_i(6) and write_data_mask_i(7));
ecc_chk_bits_wr_i <= ECC_chk_bits_wr (0 to NUM_ECC_BITS-1) & ecc_chk_bits_wr_d1;
-- Determine whether REG_DIMM - if so, register delay all associated write signals
-- by one clock to account for the registering of control/address signals in the DIMM
-- if not REG_DIMM, output write signals
WRITE_PIPE_GEN: if C_REG_DIMM = 1 generate
WRITE_RE_REG: process (Clk)
begin
if Clk'event and Clk='1' then
if Rst=RESET_ACTIVE then
Write_data_ecc <= (others => '0');
Write_data_ecc_mask <= "11";
Write_dqs_ecc_en <= '0';
else
Write_data_ecc <= ecc_chk_bits_wr_i;
Write_data_ecc_mask <= write_data_ecc_mask_i;
Write_dqs_ecc_en <= write_dqs_ecc_en_i;
end if;
end if;
end process WRITE_RE_REG;
WRITE_FE_REG: process(Clk)
begin
if Clk'event and Clk='0' then
if Rst=RESET_ACTIVE then
Write_data_ecc_en <= '0';
else
Write_data_ecc_en <= write_data_ecc_en_i after 1 ns;
end if;
end if;
end process WRITE_FE_REG;
end generate WRITE_PIPE_GEN;
NOWRITE_PIPE_GEN: if C_REG_DIMM = 0 generate
Write_data_ecc <= ecc_chk_bits_wr_i;
Write_data_ecc_mask <= write_data_ecc_mask_i;
Write_dqs_ecc_en <= write_dqs_ecc_en_i;
Write_data_ecc_en <= write_data_ecc_en_i after 1 ns;
end generate NOWRITE_PIPE_GEN;
end generate W_ECC_DATA_REG;
--------------------------------------------------------------------------------
-- Data State Machine
-- DATASM_CMB: combinational process for determining next state
-- DATASM_REG: state machine registers
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -