⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 data_statemachine.vhd

📁 xilinx ddr3最新VHDL代码,通过调试
💻 VHD
📖 第 1 页 / 共 3 页
字号:
-- 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 + -