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

📄 data_statemachine.vhd

📁 xilinx ddr3最新VHDL代码,通过调试
💻 VHD
📖 第 1 页 / 共 3 页
字号:
--------------------------------------------------------------------------------
    -- Combinational process
DATASM_CMB: process (Pend_write, Pend_read, DDR_brst_end, datasm_cs, Tcaslat_end,
                     Twr_end,
                     Bus2IP_Burst, Comb_Bus2IP_CS,
                     read_cnt,
                     Rdack,
                     Read_pause)
begin
-- Set default values
wrdata_ack <= '0';
write_data_en_cmb <= '0';
read_data_en_cmb <= '0';
read_data_done_cmb <= '0';
datasm_ns <= datasm_cs;
Tbrst_cnt_en <= '0';
Tbrst_load <= '0';
Tcaslat_load <= '0';
Tcaslat_cnt_en <= '0';
Twr_load <= '0';
Twr_cnten <= '0';
data_mask <= '1';
rdack_rst_i <= '0';

case datasm_cs is
-------------------------- IDLE --------------------------
    when IDLE =>
        -- idle state
        -- wait in this state for pending read or write       
        rdack_rst_i <= '1';
        
        if Pend_write = '1' then
            datasm_ns <= WR_DATA;
            wrdata_ack <= '1';
            Tbrst_load <= '1';
            write_data_en_cmb <= '1';
            data_mask <= '0';
        end if;
        if Pend_read = '1' then
            datasm_ns <= WAIT_CASLAT;
            Tcaslat_load <= '1';
        end if;
        
-------------------------- WAIT_CASLAT --------------------------
    when WAIT_CASLAT => 
        -- wait in this state for cas latency timer to expire
        Tcaslat_cnt_en <= '1';
        -- since this is a state only accessable from READ,
        -- assert read data enable a clock before caslatency expires
        read_data_en_cmb <= '1';
        rdack_rst_i <= '1';
        if Tcaslat_end = '1' then
            datasm_ns <= RD_DATA;
            Tbrst_load <= '1';
        end if;
-------------------------- WR_DATA --------------------------
    when WR_DATA =>
        -- write data in this state
        -- stay in this state while pend_wr is asserted
        -- check to see if the DDR burst cycle is complete
        Tbrst_cnt_en <= '1';
        write_data_en_cmb <= '1';
        if Pend_write = '0' then
            -- single transaction or burst has finished
            if DDR_brst_end = '1' then
                -- DDR is done, wait for Twr
                -- kill the data enable for writes
                Twr_load <= '1';
                datasm_ns <= WAIT_TWR;
            else
                -- DDR is not done with burst, stay in this state and keep the data enable asserted
                data_mask <= '0';
            end if;
        else
            wrdata_ack <= '1';
            -- still transferring data
            if DDR_brst_end = '1' then
                --stay in this state, need to reset pending command and reload burst counter
                Tbrst_load <= '1';
                Tbrst_cnt_en <= '0';
                data_mask <= '0';
            else
                -- DDR is not done with burst, stay in this state and keep the data enable asserted
                data_mask <= '0';
            end if;
        end if;

-------------------------- RD_DATA --------------------------
    when RD_DATA =>
        -- read data in this state
        -- stay in this state while pend_rd is asserted
        -- check to see if the DDR burst cycle is complete
        Tbrst_cnt_en <= '1';
        read_data_en_cmb <= '1';

        -- If bursting supported
        if C_INCLUDE_BURSTS = 1 then

            -- If burst is finished while waiting to service a refresh
            if Comb_Bus2IP_CS = '0' then
                -- go to DONE, no need to wait for more RdAcks
                datasm_ns <= DONE;
                read_data_done_cmb <= '1';
                rdack_rst_i <= '1';

            elsif Bus2IP_Burst = '0' and Read_pause = '0' and C_INCLUDE_ECC_SUPPORT = 0 then 
                       
                -- single transaction or burst has finished
                if Rdack = '1' then
                -- DDR is done with burst, go to DONE
                    datasm_ns <= DONE;
                    read_data_done_cmb <= '1';
                    rdack_rst_i <= '1';
                else
                    -- wait for read data ack
                    datasm_ns <= WAIT_RDACK;
                end if;
            
            elsif read_cnt = READ_CNTR_ZEROS then
                -- read transaction has been interrupted and
                -- all read acks have been received
                datasm_ns <= DONE;
                read_data_done_cmb <= '1';
                rdack_rst_i <= '1';
            else
                -- still transferring data
                if DDR_brst_end = '1' then
                    --stay in this state, need to reset pending command and reload burst counter
                    Tbrst_load <= '1';
                    Tbrst_cnt_en <= '0';
                end if;
            end if;
            
        else
            -- No bursting supported
            if Rdack = '1' then
                datasm_ns <= DONE;
                read_data_done_cmb <= '1';
                rdack_rst_i <= '1';
            else
                -- wait for read data ack
                datasm_ns <= WAIT_RDACK;
            end if;
        
        end if; -- if bursts supported
  
-------------------------- WAIT_TWR --------------------------
    when WAIT_TWR => 
        -- wait in this state for write recovery timer to expire
        Twr_cnten <= '1';
        if Twr_end = '1' then
           datasm_ns <= DONE;
           write_data_en_cmb <= '0'; 
        end if;
-------------------------- WAIT_RDACK --------------------------
    when WAIT_RDACK => 
        read_data_en_cmb <= '1';
        -- wait in this state for read data ack to assert
        if Rdack = '1' then
            -- DDR is done with burst, go to DONE
            datasm_ns <= DONE;
            read_data_done_cmb <= '1';
            rdack_rst_i <= '1';
        end if;
-------------------------- DONE --------------------------
    when DONE =>
        -- Read_data_done is asserted in this state
        -- if pend_op asserts, go to XFER_DATA, otherwise
        -- go back to IDLE
        rdack_rst_i <= '1';
        if Pend_write = '1' then
            datasm_ns <= WR_DATA;
            Tbrst_load <= '1';
            write_data_en_cmb <= '1';
            data_mask <= '0';
        elsif Pend_read = '1' then
            datasm_ns <= WAIT_CASLAT;
            Tcaslat_load <= '1';
        else
            datasm_ns <= IDLE;
        end if;
        
-------------------------- DEFAULT --------------------------
    when others => 
        datasm_ns <= IDLE;
end case;
end process DATASM_CMB;
    
DATASM_REG: process (Clk)
begin

    if (Clk'event and Clk = '1') then
        if (Rst = RESET_ACTIVE) then
            datasm_cs <= IDLE;
        else
            datasm_cs <= datasm_ns;
        end if;
    end if;
end process DATASM_REG;    

DATADONE_REG: process (Clk)
begin

    if (Clk'event and Clk = '1') then
        if (Rst = RESET_ACTIVE or Read_data_done_rst='1') then
            read_data_done_reg <= '0';
        elsif read_data_done_cmb = '1' then
            read_data_done_reg <= '1';
        end if;
    end if;
end process DATADONE_REG;    

-- Only generate this read_cnt if bursting is supported
W_BURST: if C_INCLUDE_BURSTS = 1 generate

    -- reset RdAck when the read transaction has been interrupted and the last
    -- read ack has been received and during all states of the read side of the
    -- data state machine except RD_DATA
    RdAck_rst <= '1' 
                when ((read_cnt = READ_CNTR_ONE and RdAck = '1' and Read_pause='1')
                       or rdack_rst_i = '1')
                else '0';

    -- Read counter
    -- Counts up when there is a pending read command, counts
    -- down everytime a read acknowledge is received
    -- Reset whenever read data is finished
    read_cntr_ce <= Pend_read xor RdAck;
    read_cntr_rst <= read_data_done_cmb or Rst;
    
    READCNTR_I:  entity proc_common_v2_00_a.Counter(imp)
        generic map (C_NUM_BITS => READ_CNTR_WIDTH)
        port map
            (
                Clk           => Clk,
                Rst           => read_cntr_rst,  
                Load_In       => READ_CNTR_ZEROS,
                Count_Enable  => read_cntr_ce,
                Count_Load    => '0',
                Count_Down    => RdAck,
                Count_Out     => read_cnt,
                Carry_Out     => open
            );
            
end generate W_BURST;

WO_BURST: if C_INCLUDE_BURSTS = 0 generate
    -- For NO burst support Read_pause is tied to 0
    RdAck_rst <= rdack_rst_i;
end generate WO_BURST;
        
end imp;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -