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

📄 command_statemachine.vhd

📁 xilinx ddr3最新VHDL代码,通过调试
💻 VHD
📖 第 1 页 / 共 4 页
字号:
Trefi_load <= '0';
Trc_load <= '0';
Trrd_load <= '0';
Tras_load <= '0';
GPcnt_en <= '0';
GPcnt_load <= '0';
GPcnt_data <= (others => '1');
cmdsm_ns <= cmdsm_cs;
Retry <= '0';
reset_pendrdreq_cmb <= '0';
reset_pendwrreq_cmb <= '0';
dq_oe_cmb_i <= '1';
dq_ecc_oe_cmb_i <= '1';
dqs_oe_cmb  <= '1';
dqs_ecc_oe_cmb  <= '1';
dqs_setrst_cmb <= '0';
dqs_ecc_setrst_cmb <= '0';
dqs_rst_cmb <= '0';
dqs_ecc_rst_cmb <= '0';
rst_read_state <= '0';
read_state_cmb <= read_state;
Rd_AddrAck <= '0';
Wr_AddrAck <= '0';
Twr_rst <= '0';
read_data_done_rst_cmb <= '0';
ToutSup <= '0';
read_pause_cmb <= read_pause_i;
read_dqs_ce_i <= '1';

case cmdsm_cs is
-------------------------- IDLE --------------------------
    when IDLE =>
        -- reset state
        Twr_rst <= '1';
        rst_read_state <= '1';
        -- while in IDLE, drive the DQS lines to the pullup/pulldown value
        dqs_oe_cmb <= '1';
        dqs_ecc_oe_cmb <= '1';
        dqs_setrst_cmb <= '1';
        dqs_ecc_setrst_cmb <= '1';
        -- setup the command so that once its registered,
        -- it'll line up with the state
        if Refresh='1' or 
            (init_done = '1' and Trefi_end='1') then
            cmdsm_ns <= REFRESH_CMD;
            RCW_cmd <= REFRESH_RCW;
            csn_cmd <= (others => '0'); -- Assert CS of all memory banks during refresh
            -- reload the refresh interval timer
            Trefi_load <= '1';
            -- load the general purpose counter to time refresh
            -- command to another command delay
            GPcnt_load <= '1';
            GPcnt_data <= C_RFCCNT;
            -- assert Retry
            Retry <= '1'; 
        elsif Comb_Bus2IP_CS = '1' and Init_done = '1' then
            -- prepare for ACTIVE command
            cmdsm_ns <= ACT_CMD;
            RCW_cmd <= ACTIVE_RCW;
            csn_cmd <= not (Bus2IP_CS);
            DDR_Addr <= Row_addr;
            DDR_BankAddr <= Bank_addr;
            -- load the general purpose counter to time Trcd
            GPcnt_load <= '1';
            GPcnt_data <= C_RCDCNT;
            -- load the RAS counter to time Tras
            Tras_load <= '1';
            -- load the RRD counter to time Trrd
            Trrd_load <= '1';
            -- load the RC counter to time Trc
            Trc_load <= '1';
        elsif Load_mr = '1' then
            cmdsm_ns <= LOAD_MR_CMD;
            RCW_cmd <= LOAD_MR_RCW;
            csn_cmd <= (others => '0');     -- Assert all CS during load mode register
            DDR_Addr <= Register_data;
            DDR_BankAddr <= Register_sel;
            GPcnt_load <= '1';
            GPcnt_data <= C_MRDCNT;
        elsif Precharge = '1' then
            cmdsm_ns <= PRECHARGE_CMD;
            RCW_cmd <= PRECHARGE_RCW;            
            if (init_done = '0') then
                csn_cmd <= (others => '0');     -- Precharge all banks during initialization
            else    csn_cmd <= not (Bus2IP_CS);   -- Else precharge specific memory bank
            end if;            
            DDR_Addr <= PRECHARGE_DATA;
            GPcnt_load <= '1';
            GPcnt_data <= C_RPCNT;
        end if;        
-------------------------- REFRESH_CMD --------------------------
    when REFRESH_CMD =>
        -- start timing refresh command cycle. 
        GPcnt_en <= '1';
        
        -- assert Retry
        Retry <= '1'; 
               
        -- assert ToutSup
        ToutSup <= '1';
        
        if C_OPB_BUS = 1 then
            -- When timer expires 
            -- return to IDLE state if write transaction
            -- because write buffer is controlling Bus2IP_CS
            -- if read, must wait for Bus2IP_CS to negate so that the bus
            -- has reacted to the retry
            if GPcnt_end = '1' then
                if read_state= '1' or Bus2IP_RdReq = '1' then 
                    if Comb_Bus2IP_CS = '0' then
                        cmd_done_cmb <= '1';
                        cmdsm_ns <= IDLE;
                    end if;
                else
                    cmd_done_cmb <= '1';
                    cmdsm_ns <= IDLE;
                end if;    
            end if;
        end if;
        if C_PLB_BUS = 1 then
            -- when timer expires, return to IDLE state if CS is negated
            -- Data phase can't abort on PLB, so if CS is still valid
            -- go to ACT state
            if GPcnt_end = '1'then
                cmd_done_cmb <= '1';
                
                if Comb_Bus2IP_CS = '1' then
                    cmdsm_ns <= ACT_CMD;
                    RCW_cmd <= ACTIVE_RCW;
                    csn_cmd <= not (Bus2IP_CS);   -- Assert CS of active memory bank
                    DDR_Addr <= Row_addr;
                    DDR_BankAddr <= Bank_addr;
                    -- load the general purpose counter to time Trcd
                    GPcnt_load <= '1';
                    GPcnt_data <= C_RCDCNT;
                    -- load the RAS counter to time Tras
                    Tras_load <= '1';
                    -- load the RRD counter to time Trrd
                    Trrd_load <= '1';
                    -- load the RC counter to time Trc
                    Trc_load <= '1';
                else
                    cmdsm_ns <= IDLE;
                end if;
            end if;
        end if;

-------------------------- LOAD_MR_CMD --------------------------
    when LOAD_MR_CMD =>
        -- assert the count enable to start timing LOAD_MR command
        -- cycle.
        GPcnt_en <= '1';
        Retry <= '1';
        -- assert ToutSup
        ToutSup <= '1';
        
        if C_OPB_BUS = 1 then
            -- When timer expires and Comb_Bus2IP_CS=0, 
            -- return to IDLE state 
            -- must wait for Comb_Bus2IP_CS to negate so that the bus
            -- has reacted to the retry
            if GPcnt_end = '1' and Comb_Bus2IP_CS = '0' then
                cmd_done_cmb <= '1';
                cmdsm_ns <= IDLE;
            end if;
        end if;
        if C_PLB_BUS = 1 then
            -- when timer expires, return to IDLE state
            -- Data phase can't abort on PLB, so CS is still valid
            if GPcnt_end = '1'then
                cmd_done_cmb <= '1';
                cmdsm_ns <= IDLE;
            end if;
        end if;
           
-------------------------- ACT_CMD --------------------------
    when ACT_CMD =>
        -- assert general purpose counter enable to start timing Trcd
        GPcnt_en <= '1';
        
        -- assert reset to DQS registers to insure 1 clock of DQS=0
        -- DQS output enable will only output this if write cycle
        dqs_rst_cmb <= '1';
        dqs_ecc_rst_cmb <= '1';

        -- assert ToutSup
        ToutSup <= '1';
                
        if Trefi_end='1' then
            -- refresh, assert Retry
            Retry <= '1'; 
            -- must go to to precharge to close row                
            if Tras_end = '1' then
                 cmdsm_ns <= PRECHARGE_CMD;
                 RCW_cmd <= PRECHARGE_RCW;
                 DDR_Addr <= PRECHARGE_DATA;
                 GPcnt_load <= '1';
                 GPcnt_data <= C_RPCNT;
            else
                 cmdsm_ns <= WAIT_TRAS;
            end if;
        elsif Comb_Bus2IP_CS = '0' then
            -- CS has negated (master abort)
            -- must go to to precharge to close row                
            if Tras_end = '1' then
                 cmdsm_ns <= PRECHARGE_CMD;
                 RCW_cmd <= PRECHARGE_RCW;
                 DDR_Addr <= PRECHARGE_DATA;
                 GPcnt_load <= '1';
                 GPcnt_data <= C_RPCNT;
            else
                 cmdsm_ns <= WAIT_TRAS;
            end if;
        elsif GPcnt_end = '1' then
            -- Trcd is complete
            -- load the command counter
            Tcmd_load <= '1';
            if read_state = '1' then
                -- need to continue an interrupted read transaction
                -- wait for data to be completed
                if read_data_done = '1' then
                    -- prepare for READ_CMD state
                    RCW_cmd <= READ_RCW;
                    DDR_Addr <= Col_addr;
                    DDR_BankAddr <= bank_addr;
                    cmdsm_ns <= READ_CMD;
                    pend_read_cmb <= '1';
                    reset_pendrdreq_cmb <= '1';
                    Rd_addrAck <= '1';
                    -- release read data done reset
                    read_data_done_rst_cmb <= '1';
                end if;
            elsif Pend_rdreq ='1' or  Bus2IP_RdReq = '1' then
                -- prepare for READ_CMD state
                RCW_cmd <= READ_RCW;
                DDR_Addr <= Col_addr;
                DDR_BankAddr <= bank_addr;
                cmdsm_ns <= READ_CMD;
                pend_read_cmb <= '1';
                reset_pendrdreq_cmb <= '1';
                Rd_addrAck <= '1';
             elsif Pend_wrreq = '1' or Bus2IP_WrReq = '1'then
               -- check for new write request or if need to finish write burst
                -- prepare for WRITE_CMD state
                RCW_cmd <= WRITE_RCW;
                DDR_Addr <= Col_addr;
                DDR_BankAddr <= bank_addr;
                cmdsm_ns <= WRITE_CMD;
                pend_write_cmb <= '1';
                reset_pendwrreq_cmb <= '1';
                Wr_addrAck <= '1';    -- start IPIC address counters
                dq_oe_cmb_i <= '0';   -- assert output enable
                dqs_oe_cmb  <= '0';
                dq_ecc_oe_cmb_i <= '0';  
                dqs_ecc_oe_cmb  <= '0';
            end if;
        end if;
-------------------------- READ_CMD --------------------------
    when READ_CMD =>
        -- when command timer ends, see if this is a burst
        -- so that a new command can be issued
        read_state_cmb <= '1';
        
        -- assert ToutSup
        ToutSup <= '1';

        if Tcmd_end = '1' then
        
            if Trefi_end = '1' then
                -- go handle refresh
                -- have to PRECHARGE
                -- assert read_pause
                read_pause_cmb <= '1';
                if Tras_end = '1' then
                     cmdsm_ns <= PRECHARGE_CMD;
                     RCW_cmd <= PRECHARGE_RCW;
                     DDR_Addr <= PRECHARGE_DATA;
                     GPcnt_load <= '1';
                     GPcnt_data <= C_RPCNT;
                else
                     cmdsm_ns <= WAIT_TRAS;
                end if;
            else
                if Bus2IP_RdReq = '1' then
                    if Same_row = '1' then
                        -- access is to the same row, can repeat read command
                        RCW_cmd <= READ_RCW;
                        DDR_Addr <= Col_addr;
                        DDR_BankAddr <= bank_addr;
                        cmdsm_ns <= READ_CMD;
                        Tcmd_load <= '1';
                        Tcmd_cnt_en <= '0';
                        pend_read_cmb <= '1';
                        Rd_addrAck <= '1';
                    else
                        -- access is to a different row
                        -- if same bank, have to precharge
                        -- assert read_pause
                        read_pause_cmb <= '1';
                        if Same_bank = '1' then
                            if Tras_end = '1' then
                                 cmdsm_ns <= PRECHARGE_CMD;
                                 RCW_cmd <= PRECHARGE_RCW;
                                 DDR_Addr <= PRECHARGE_DATA;
                                 GPcnt_load <= '1';
                                 GPcnt_data <= C_RPCNT;
                            else
                                 cmdsm_ns <= WAIT_TRAS;
                            end if;
                        else
                            -- different bank - can go to ACTIVE
                            -- if Trrd has expired, prepare for ACTIVE cmd, else
                            -- wait for Trrd to expire
                            if Trrd_end = '1'  then
                                RCW_cmd <= ACTIVE_RCW;
                                csn_cmd <= not (Bus2IP_CS);   -- Assert CS of active memory bank
                                DDR_Addr <= Row_addr;
                                DDR_BankAddr <= Bank_addr;
                                -- load the general purpose counter to time Trcd
                                GPcnt_load <= '1';
                                GPcnt_data <= C_RCDCNT;
                                -- load the RAS counter to time Tras
                                Tras_load <= '1';
                                -- load the RC counter to time Trc
                                Trc_load <= '1';
                                -- reset read_data_done
                                read_data_done_rst_cmb <= '1';                                    
                                cmdsm_ns <= ACT_CMD;
                            else
                                cmdsm_ns <= WAIT_TRRD;
                            end if;
                        end if;  
                    end if; -- if same bank, different row
                else
                    -- not a burst                    

                    -- if Tras has expired, go to PRECHARGE, 

⌨️ 快捷键说明

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