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

📄 mt46v16m16.vhd

📁 ddr verilog代码,实现DDR内存控制
💻 VHD
📖 第 1 页 / 共 4 页
字号:
                Cols_addr (0) := Cols_temp (0);
            ELSIF Burst_length_4 = '1' THEN
                Cols_addr (1 DOWNTO 0) := Cols_temp (1 DOWNTO 0);
            ELSIF Burst_length_8 = '1' THEN
                Cols_addr (2 DOWNTO 0) := Cols_temp (2 DOWNTO 0);
            ELSE
                Cols_addr := Cols_temp;
            END IF;

            -- Data counter
            IF Burst_length_2 = '1' THEN
                IF Burst_counter >= 2 THEN
                    IF Data_in_enable = '1' THEN
                        Data_in_enable := '0';
                    ELSIF Data_out_enable = '1' THEN
                        Data_out_enable := '0';
                    END IF;
                END IF;
            ELSIF Burst_length_4 = '1' THEN
                IF Burst_counter >= 4 THEN
                    IF Data_in_enable = '1' THEN
                        Data_in_enable := '0';
                    ELSIF Data_out_enable = '1' THEN
                        Data_out_enable := '0';
                    END IF;
                END IF;
            ELSIF Burst_length_8 = '1' THEN
                IF Burst_counter >= 8 THEN
                    IF Data_in_enable = '1' THEN
                        Data_in_enable := '0';
                    ELSIF Data_out_enable = '1' THEN
                        Data_out_enable := '0';
                    END IF;
                END IF;
            END IF;
        END;

    BEGIN
        WAIT ON Sys_clk;

        --
        -- Manual Precharge Pipeline
        --
        IF ((Sys_clk'EVENT AND Sys_clk = '0') OR (Sys_clk'EVENT AND Sys_clk = '1')) THEN
            -- A10 Precharge Pipeline
            A10_precharge(0) := A10_precharge(1);
            A10_precharge(1) := A10_precharge(2);
            A10_precharge(2) := A10_precharge(3);
            A10_precharge(3) := A10_precharge(4);
            A10_precharge(4) := A10_precharge(5);
            A10_precharge(5) := A10_precharge(6);
            A10_precharge(6) := A10_precharge(7);
            A10_precharge(7) := A10_precharge(8);
            A10_precharge(8) := '0';

            -- Bank Precharge Pipeline
            Bank_precharge(0) := Bank_precharge(1);
            Bank_precharge(1) := Bank_precharge(2);
            Bank_precharge(2) := Bank_precharge(3);
            Bank_precharge(3) := Bank_precharge(4);
            Bank_precharge(4) := Bank_precharge(5);
            Bank_precharge(5) := Bank_precharge(6);
            Bank_precharge(6) := Bank_precharge(7);
            Bank_precharge(7) := Bank_precharge(8);
            Bank_precharge(8) := "00";

            -- Command Precharge Pipeline
            Cmnd_precharge(0) := Cmnd_precharge(1);
            Cmnd_precharge(1) := Cmnd_precharge(2);
            Cmnd_precharge(2) := Cmnd_precharge(3);
            Cmnd_precharge(3) := Cmnd_precharge(4);
            Cmnd_precharge(4) := Cmnd_precharge(5);
            Cmnd_precharge(5) := Cmnd_precharge(6);
            Cmnd_precharge(6) := Cmnd_precharge(7);
            Cmnd_precharge(7) := Cmnd_precharge(8);
            Cmnd_precharge(8) := '0';

            -- Terminate Read if same bank or all banks
            IF ((Cmnd_precharge (0) = '1') AND
                (Bank_precharge (0) = Bank_addr OR A10_precharge (0) = '1') AND
                (Data_out_enable = '1')) THEN
                Data_out_enable := '0';
            END IF;
        END IF;

        --
        -- Burst Terminate Pipeline
        --
        IF ((Sys_clk'EVENT AND Sys_clk = '0') OR (Sys_clk'EVENT AND Sys_clk = '1')) THEN
            -- Burst Terminate pipeline
            Cmnd_bst (0) := Cmnd_bst (1);
            Cmnd_bst (1) := Cmnd_bst (2);
            Cmnd_bst (2) := Cmnd_bst (3);
            Cmnd_bst (3) := Cmnd_bst (4);
            Cmnd_bst (4) := Cmnd_bst (5);
            Cmnd_bst (5) := Cmnd_bst (6);
            Cmnd_bst (6) := Cmnd_bst (7);
            Cmnd_bst (7) := Cmnd_bst (8);
            Cmnd_bst (8) := '0';

            -- Terminate current Read
            IF ((Cmnd_bst  (0) = '1') AND (Data_out_enable = '1')) THEN
                Data_out_enable := '0';
            END IF;
        END IF;

        --
        -- Dq and Dqs Drivers
        --
        IF ((Sys_clk'EVENT AND Sys_clk = '0') OR (Sys_clk'EVENT AND Sys_clk = '1')) THEN
            -- Read Command Pipeline
            Read_cmnd (0) := Read_cmnd (1);
            Read_cmnd (1) := Read_cmnd (2);
            Read_cmnd (2) := Read_cmnd (3);
            Read_cmnd (3) := Read_cmnd (4);
            Read_cmnd (4) := Read_cmnd (5);
            Read_cmnd (5) := Read_cmnd (6);
            Read_cmnd (6) := Read_cmnd (7);
            Read_cmnd (7) := Read_cmnd (8);
            Read_cmnd (8) := '0';

            -- Read Bank Pipeline
            Read_bank (0) := Read_bank (1);
            Read_bank (1) := Read_bank (2);
            Read_bank (2) := Read_bank (3);
            Read_bank (3) := Read_bank (4);
            Read_bank (4) := Read_bank (5);
            Read_bank (5) := Read_bank (6);
            Read_bank (6) := Read_bank (7);
            Read_bank (7) := Read_bank (8);
            Read_bank (8) := "00";

            -- Read Column Pipeline
            Read_cols (0) := Read_cols (1);
            Read_cols (1) := Read_cols (2);
            Read_cols (2) := Read_cols (3);
            Read_cols (3) := Read_cols (4);
            Read_cols (4) := Read_cols (5);
            Read_cols (5) := Read_cols (6);
            Read_cols (6) := Read_cols (7);
            Read_cols (7) := Read_cols (8);
            Read_cols (8) := (OTHERS => '0');

            -- Initialize Read command
            IF Read_cmnd (0) = '1' THEN
                Data_out_enable := '1';
                Bank_addr := Read_bank (0);
                Cols_addr := Read_cols (0);
                Cols_brst := Cols_addr (2 DOWNTO 0);
                Burst_counter := (OTHERS => '0');

                -- Row address mux
                CASE Bank_addr IS
                    WHEN "00"   => Rows_addr := B0_row_addr;
                    WHEN "01"   => Rows_addr := B1_row_addr;
                    WHEN "10"   => Rows_addr := B2_row_addr;
                    WHEN OTHERS => Rows_addr := B3_row_addr;
                END CASE;
            END IF;

            -- Toggle Dqs during Read command
            IF Data_out_enable = '1' THEN
                Dqs_int := '0';
                IF Dqs_out = "00" THEN
                    Dqs_out <= "11";
                ELSIF Dqs_out = "11" THEN
                    Dqs_out <= "00";
                ELSE
                    Dqs_out <= "00";
                END IF;
            ELSIF Data_out_enable = '0' AND Dqs_int = '0' THEN
                Dqs_out <= "ZZ";
            END IF;

            -- Initialize Dqs for Read command
            IF Read_cmnd (2) = '1' THEN
                IF Data_out_enable = '0' THEN
                    Dqs_int := '1';
                    Dqs_out <= "00";
                END IF;
            END IF;

            -- Read Latch
            IF Data_out_enable = '1' THEN
                -- Initialize Memory
                Init_mem (Bank_addr, CONV_INTEGER(Rows_addr));
                
                -- Output Data
                CASE Bank_addr IS
                    WHEN "00"   => Dq <= Bank0 (CONV_INTEGER(Rows_addr)) (CONV_INTEGER(Cols_addr));
                    WHEN "01"   => Dq <= Bank1 (CONV_INTEGER(Rows_addr)) (CONV_INTEGER(Cols_addr));
                    WHEN "10"   => Dq <= Bank2 (CONV_INTEGER(Rows_addr)) (CONV_INTEGER(Cols_addr));
                    WHEN OTHERS => Dq <= Bank3 (CONV_INTEGER(Rows_addr)) (CONV_INTEGER(Cols_addr));
                END CASE;

                --  Increase Burst Counter
                Burst_decode;
            ELSE
                Dq <= (OTHERS => 'Z');
            END IF;
        END IF;

        --
        -- Write FIFO and DM Mask Logic
        --
        IF Sys_clk'EVENT AND Sys_clk = '1' THEN
            -- Write command pipeline
            Write_cmnd (0) := Write_cmnd (1);
            Write_cmnd (1) := Write_cmnd (2);
            Write_cmnd (2) := '0';

            -- Write command pipeline
            Write_bank (0) := Write_bank (1);
            Write_bank (1) := Write_bank (2);
            Write_bank (2) := "00";

            -- Write column pipeline
            Write_cols (0) := Write_cols (1);
            Write_cols (1) := Write_cols (2);
            Write_cols (2) := (OTHERS => '0');

            -- Initialize Write command
            IF Write_cmnd (0) = '1' THEN
                Data_in_enable := '1';
                Bank_addr := Write_bank (0);
                Cols_addr := Write_cols (0);
                Cols_brst := Cols_addr (2 DOWNTO 0);
                Burst_counter := (OTHERS => '0');

                -- Row address mux
                CASE Bank_addr IS
                    WHEN "00"   => Rows_addr := B0_row_addr;
                    WHEN "01"   => Rows_addr := B1_row_addr;
                    WHEN "10"   => Rows_addr := B2_row_addr;
                    WHEN OTHERS => Rows_addr := B3_row_addr;
                END CASE;
            END IF;

            -- Write data
            IF Data_in_enable = '1' THEN
                -- Initialize memory
                Init_mem (Bank_addr, CONV_INTEGER(Rows_addr));
                
                -- Write first data
                IF Dm_pair (1) = '0' OR Dm_pair (0) = '0' THEN
                    -- Data Buffer
                    CASE Bank_addr IS
                        WHEN "00"   => Data_buf := Bank0 (CONV_INTEGER(Rows_addr)) (CONV_INTEGER(Cols_addr));
                        WHEN "01"   => Data_buf := Bank1 (CONV_INTEGER(Rows_addr)) (CONV_INTEGER(Cols_addr));
                        WHEN "10"   => Data_buf := Bank2 (CONV_INTEGER(Rows_addr)) (CONV_INTEGER(Cols_addr));
                        WHEN OTHERS => Data_buf := Bank3 (CONV_INTEGER(Rows_addr)) (CONV_INTEGER(Cols_addr));
                    END CASE;

                    -- Perform DM Mask
                    IF Dm_pair (0) = '0' THEN
                        Data_buf ( 7 DOWNTO 0) := Dq_pair ( 7 DOWNTO 0);
                    END IF;
                    IF Dm_pair (1) = '0' THEN
                        Data_buf (15 DOWNTO 8) := Dq_pair (15 DOWNTO 8);
                    END IF;

                    -- Write Data
                    CASE Bank_addr IS
                        WHEN "00"   => Bank0 (CONV_INTEGER(Rows_addr)) (CONV_INTEGER(Cols_addr)) := Data_buf;
                        WHEN "01"   => Bank1 (CONV_INTEGER(Rows_addr)) (CONV_INTEGER(Cols_addr)) := Data_buf;
                        WHEN "10"   => Bank2 (CONV_INTEGER(Rows_addr)) (CONV_INTEGER(Cols_addr)) := Data_buf;
                        WHEN OTHERS => Bank3 (CONV_INTEGER(Rows_addr)) (CONV_INTEGER(Cols_addr)) := Data_buf;
                    END CASE;
                END IF;

                --  Increase Burst Counter
                Burst_decode;

                -- Write second data
                IF Dm_pair (3) = '0' OR Dm_pair (2) = '0' THEN
                    -- Data Buffer
                    CASE Bank_addr IS
                        WHEN "00"   => Data_buf := Bank0 (CONV_INTEGER(Rows_addr)) (CONV_INTEGER(Cols_addr));
                        WHEN "01"   => Data_buf := Bank1 (CONV_INTEGER(Rows_addr)) (CONV_INTEGER(Cols_addr));
                        WHEN "10"   => Data_buf := Bank2 (CONV_INTEGER(Rows_addr)) (CONV_INTEGER(Cols_addr));
                        WHEN OTHERS => Data_buf := Bank3 (CONV_INTEGER(Rows_addr)) (CONV_INTEGER(Cols_addr));
                    END CASE;

                    -- Perform DM Mask
                    IF Dm_pair (2) = '0' THEN
                        Data_buf ( 7 DOWNTO 0) := Dq_pair (23 DOWNTO 16);
                    END IF;
                    IF Dm_pair (3) = '0' THEN
                        Data_buf (15 DOWNTO 8) := Dq_pair (31 DOWNTO 24);
                    END IF;

                    -- Write Data
                    CASE Bank_addr IS
                        WHEN "00"   => Bank0 (CONV_INTEGER(Rows_addr)) (CONV_INTEGER(Cols_addr)) := Data_buf;
                        WHEN "01"   => Bank1 (CONV_INTEGER(Rows_addr)) (CONV_INTEGER(Cols_addr)) := Data_buf;
                        WHEN "10"   => Bank2 (CONV_INTEGER(Rows_addr)) (CONV_INTEGER(Cols_addr)) := Data_buf;
                        WHEN OTHERS => Bank3 (CONV_INTEGER(Rows_addr)) (CONV_INTEGER(Cols_addr)) := Data_buf;
                    END CASE;
                END IF;
                
                -- Increase Burst Counter
                Burst_decode;

                -- tWR start and tWTR check
                IF Dm_pair (3 DOWNTO 2) = "00" OR Dm_pair (1 DOWNTO 0) = "00" THEN
                    CASE Bank_addr IS
                        WHEN "00"   => WR_chk0 := NOW;
                        WHEN "01"   => WR_chk1 := NOW;
                        WHEN "10"   => WR_chk2 := NOW;
                        WHEN OTHERS => WR_chk3 := NOW;
                    END CASE;

                    -- tWTR check
                    ASSERT (Read_enable = '0')
                        REPORT "tWTR violation during Read"
                        SEVERITY WARNING;
                END IF;
            END IF;
        END IF;

        --
        -- Auto Precharge Calculation
        --
        IF Sys_clk'EVENT AND Sys_clk = '1' THEN
            -- Precharge counter
            IF Read_precharge (0) = '1' OR Write_precharge (0) = '1' THEN
                Count_precharge (0) := Count_precharge (0) + 1;
            END IF;
            IF Read_precharge (1) = '1' OR Write_precharge (1) = '1' THEN
                Count_precharge (1) := Count_precharge (1) + 1;
            END IF;

⌨️ 快捷键说明

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