OpenCores
URL https://opencores.org/ocsvn/sdram_controller/sdram_controller/trunk

Subversion Repositories sdram_controller

[/] [sdram_controller/] [trunk/] [sdram.vhd] - Diff between revs 9 and 10

Go to most recent revision | Show entire file | Details | Blame | View Log

Rev 9 Rev 10
Line 38... Line 38...
--  the mt46v32m16 chip. Dunno if it will work anywhere else.
--  the mt46v32m16 chip. Dunno if it will work anywhere else.
-- Uses the ODDR2 and DCM Xilinx primitives, for other FPGAs, you'll need to
-- Uses the ODDR2 and DCM Xilinx primitives, for other FPGAs, you'll need to
--  patch in equivalents. See sdram_support for the details.
--  patch in equivalents. See sdram_support for the details.
-- I'd strongly recommend running it through a post-PAR simulation if you're
-- I'd strongly recommend running it through a post-PAR simulation if you're
--  porting to any other FPGA, as the timings will probably change on you.
--  porting to any other FPGA, as the timings will probably change on you.
-- Consumes two DCMs, runs off of the main 50mhz board clock. Could possibly
-- Consumes one DCM, needs a 100mhz clock or an external DCM to supply it.
--  consume one DCM if you want to feed it the 100mhz clock directly.
 
-- Has an 8bit wide datapath, moderate changes could support 16bits, 32 bits
-- Has an 8bit wide datapath, moderate changes could support 16bits, 32 bits
--  you'll have to work some. You want more than that, you'll be doing brain
--  you'll have to work some. You want more than that, you'll be doing brain
--  surgery on the FSMs - good luck.
--  surgery on the FSMs - good luck.
 
 
-- This design has been tested with the testbench only. There may be glitches
-- This design has now been tested with a t80 soft cpu, however, it hasn't been
--  hidden in here somewhere still. Consider this to be an alpha release.
--  exhaustively tested with the rest of the system. Glitches may still exist.
-- Did I mention that you shouldn't put this in anything mission critical? 
-- Did I mention that you shouldn't put this in anything mission critical? 
 
 
-- Be careful with the synthesizer settings too. Do not let the FSM extractor
-- Be careful with the synthesizer settings too. Do not let the FSM extractor
--  choose something other than one-hot. Be careful with equivalent register
--  choose something other than one-hot. Be careful with equivalent register
--  removal. I've rolled all synthesizer settings back to default and things
--  removal. I've rolled all synthesizer settings back to default and things
Line 219... Line 218...
                        addr_out : out std_logic_vector(12 downto 0)
                        addr_out : out std_logic_vector(12 downto 0)
                );
                );
        end component;
        end component;
        -- component decls end here
        -- component decls end here
 
 
        -- DRAM commands - <we,cas,ras>
        -- DRAM commands - <we_n,cas_n,ras_n>
        constant CMD_NOP        : std_logic_vector(2 downto 0)  := "111";
        constant CMD_NOP        : std_logic_vector(2 downto 0)  := "111";
        constant CMD_ACTIVE     : std_logic_vector(2 downto 0)  := "110"; -- opens a row within a bank
        constant CMD_ACTIVE     : std_logic_vector(2 downto 0)  := "110"; -- opens a row within a bank
        constant CMD_READ       : std_logic_vector(2 downto 0)  := "101";
        constant CMD_READ       : std_logic_vector(2 downto 0)  := "101";
        constant CMD_WRITE      : std_logic_vector(2 downto 0)  := "001";
        constant CMD_WRITE      : std_logic_vector(2 downto 0)  := "001";
        constant CMD_BURST_TERM : std_logic_vector(2 downto 0)  := "011";
        constant CMD_BURST_TERM : std_logic_vector(2 downto 0)  := "011";
Line 231... Line 230...
        constant CMD_AUTO_REFR  : std_logic_vector(2 downto 0)  := "100";
        constant CMD_AUTO_REFR  : std_logic_vector(2 downto 0)  := "100";
        constant CMD_LOAD_MR    : std_logic_vector(2 downto 0)  := "000";
        constant CMD_LOAD_MR    : std_logic_vector(2 downto 0)  := "000";
 
 
        -- various wait counter values
        -- various wait counter values
        constant AUTO_REFRESH_CLKS  : integer := 700; -- spec says 7.8us, which is 780 clocks @ 100Mhz, I'm setting it to 700
        constant AUTO_REFRESH_CLKS  : integer := 700; -- spec says 7.8us, which is 780 clocks @ 100Mhz, I'm setting it to 700
        constant WRITE_RECOVER_CLKS : integer := 5;   -- these are fudged a bit, you *might* be able to shave a clock or two off
        constant WRITE_RECOVER_CLKS : integer := 6;   -- these are fudged a bit, you *might* be able to shave a clock or two off
        constant READ_DONE_CLKS     : integer := 5;
        constant READ_DONE_CLKS     : integer := 5;
 
 
        type CMD_STATES is ( STATE_START, STATE_INIT, STATE_WAIT_INIT, STATE_IDLE, STATE_IDLE_AUTO_REFRESH, STATE_IDLE_WAIT_AR_CTR,
        type CMD_STATES is ( STATE_START, STATE_INIT, STATE_WAIT_INIT, STATE_IDLE, STATE_IDLE_AUTO_REFRESH,
                                                                STATE_IDLE_WAIT_AUTO_REFRESH, STATE_WRITE_ROW_OPEN, STATE_WRITE_WAIT_ROW_OPEN, STATE_WRITE_ISSUE_CMD,
                             STATE_IDLE_CHECK_OP_PENDING, STATE_IDLE_WAIT_AR_CTR, STATE_IDLE_WAIT_AUTO_REFRESH,
                                                                STATE_WRITE_WAIT_RECOVER, STATE_READ_ROW_OPEN, STATE_READ_WAIT_ROW_OPEN, STATE_READ_ISSUE_CMD,
                                                                STATE_WRITE_ROW_OPEN, STATE_WRITE_WAIT_ROW_OPEN, STATE_WRITE_ISSUE_CMD, STATE_WRITE_WAIT_RECOVER,
                                                                STATE_READ_WAIT_CAPTURE );
                                                                STATE_READ_ROW_OPEN, STATE_READ_WAIT_ROW_OPEN, STATE_READ_ISSUE_CMD, STATE_READ_WAIT_CAPTURE );
 
 
        signal cmd_state : CMD_STATES := STATE_START;
        signal cmd_state : CMD_STATES := STATE_START;
 
 
        signal cmd_oddr2_rising   : std_logic_vector(2 downto 0) := CMD_NOP;
        signal cmd_oddr2_rising   : std_logic_vector(2 downto 0) := CMD_NOP;
        signal bank_oddr2_rising  : std_logic_vector(1 downto 0) := "00";
        signal bank_oddr2_rising  : std_logic_vector(1 downto 0) := "00";
Line 290... Line 289...
        signal read_wait_done : std_logic;
        signal read_wait_done : std_logic;
 
 
        signal data0_o : std_logic_vector(7 downto 0);
        signal data0_o : std_logic_vector(7 downto 0);
        signal data1_o : std_logic_vector(7 downto 0);
        signal data1_o : std_logic_vector(7 downto 0);
 
 
        --
        -- capture signals
        signal cap_en     : std_logic;
        signal cap_en     : std_logic;
 
        signal op_save    : std_logic_vector(1 downto 0);
        signal addr_save  : std_logic_vector(25 downto 0);
        signal addr_save  : std_logic_vector(25 downto 0);
        signal datai_save : std_logic_vector(7 downto 0);
        signal datai_save : std_logic_vector(7 downto 0);
 
 
begin
begin
 
 
Line 456... Line 456...
 
 
        debug_reg <= x"00";
        debug_reg <= x"00";
        dram_cs <= '0';
        dram_cs <= '0';
        data_o <= data1_o when addr_save(0) = '1' else data0_o;
        data_o <= data1_o when addr_save(0) = '1' else data0_o;
 
 
 
        -- capture the addr when op is captured by cmd fsm
        process (clk_000)
        process (clk_000)
        begin
        begin
                if (rising_edge(clk_000)) then
                if (rising_edge(clk_000)) then
                        if (cap_en = '1') then
                        if (cap_en = '1') then
                                addr_save <= addr;
                                addr_save <= addr;
 
                        end if;
 
                end if;
 
        end process;
 
 
 
        -- capture data_i when op is captured by cmd fsm
 
        process (clk_000)
 
        begin
 
                if (rising_edge(clk_000)) then
 
                        if (cap_en = '1') then
                                datai_save <= data_i;
                                datai_save <= data_i;
                        end if;
                        end if;
                end if;
                end if;
        end process;
        end process;
 
 
 
        process (clk_000)
 
        begin
 
                if (rising_edge(clk_000)) then
 
                        if (cap_en = '1') then
 
                                op_save <= op;
 
                        end if;
 
                end if;
 
        end process;
 
 
        -- command state machine
        -- command state machine
        process (clk_000)
        process (clk_000)
        begin
        begin
                if (rising_edge(clk_000)) then
                if (rising_edge(clk_000)) then
                        if (dcm_locked = '1') then
                        if (dcm_locked = '1') then
Line 500... Line 519...
                                        when STATE_IDLE =>
                                        when STATE_IDLE =>
                                                -- this is the main hub state
                                                -- this is the main hub state
                                                -- this is where reads and writes return to after being completed
                                                -- this is where reads and writes return to after being completed
                                                busy_n <= '1';
                                                busy_n <= '1';
                                                op_ack <= '0';
                                                op_ack <= '0';
 
                                                cap_en <= '0';
                                                need_ar_rst <= '0';
                                                need_ar_rst <= '0';
                                                cap_en <= '1';
 
                                                main_sel <= '1';
                                                main_sel <= '1';
                                                writer_rst <= '1';
                                                writer_rst <= '1';
                                                reader_rst <= '1';
                                                reader_rst <= '1';
 
                                                cap_en <= '1';
                                                if (need_ar = '1') then
                                                if (need_ar = '1') then
                                                        busy_n <= '0';
                                                        busy_n <= '0';
                                                        cmd_state <= STATE_IDLE_AUTO_REFRESH;
                                                        cmd_state <= STATE_IDLE_AUTO_REFRESH;
                                                elsif (op = "01" and en = '1') then
                                                elsif (op = "01") then
                                                        busy_n <= '0';
                                                        busy_n <= '0';
 
                                                        op_ack <= '1';
                                                        cmd_state <= STATE_READ_ROW_OPEN;
                                                        cmd_state <= STATE_READ_ROW_OPEN;
                                                elsif (op = "10" and en = '1') then
                                                elsif (op = "10") then
                                                        busy_n <= '0';
                                                        busy_n <= '0';
 
                                                        op_ack <= '1';
                                                        cmd_state <= STATE_WRITE_ROW_OPEN;
                                                        cmd_state <= STATE_WRITE_ROW_OPEN;
                                                else
                                                else
                                                        cmd_state <= cmd_state;
                                                        cmd_state <= cmd_state;
                                                end if;
                                                end if;
 
 
                                        when STATE_IDLE_AUTO_REFRESH =>
                                        when STATE_IDLE_AUTO_REFRESH =>
 
                                                if (op = "01" or op = "10") then
 
                                                        cap_en <= '0';
 
                                                end if;
                                                need_ar_rst <= '1';
                                                need_ar_rst <= '1';
                                                wait_ar_rst <= '1';
                                                wait_ar_rst <= '1';
                                                main_cmd <= CMD_AUTO_REFR;
                                                main_cmd <= CMD_AUTO_REFR;
                                                main_bank <= "00";
                                                main_bank <= "00";
                                                main_addr <= "0000000000000";
                                                main_addr <= "0000000000000";
                                                cmd_state <= STATE_IDLE_WAIT_AR_CTR;
                                                cmd_state <= STATE_IDLE_WAIT_AR_CTR;
 
 
                                        when STATE_IDLE_WAIT_AR_CTR =>
                                        when STATE_IDLE_WAIT_AR_CTR =>
 
                                                if (op = "01" or op = "10") then
 
                                                        cap_en <= '0';
 
                                                end if;
                                                wait_ar_rst <= '0';
                                                wait_ar_rst <= '0';
                                                main_cmd <= CMD_NOP;
                                                main_cmd <= CMD_NOP;
                                                main_bank <= "00";
                                                main_bank <= "00";
                                                main_addr <= "0000000000000";
                                                main_addr <= "0000000000000";
                                                cmd_state <= STATE_IDLE_WAIT_AUTO_REFRESH;
                                                cmd_state <= STATE_IDLE_WAIT_AUTO_REFRESH;
 
 
                                        when STATE_IDLE_WAIT_AUTO_REFRESH =>
                                        when STATE_IDLE_WAIT_AUTO_REFRESH =>
 
                                                if (op = "01" or op = "10") then
 
                                                        cap_en <= '0';
 
                                                end if;
                                                main_cmd <= CMD_NOP;
                                                main_cmd <= CMD_NOP;
                                                main_bank <= "00";
                                                main_bank <= "00";
                                                main_addr <= "0000000000000";
                                                main_addr <= "0000000000000";
                                                if (wait_ar_done = '1') then
                                                if (wait_ar_done = '1') then
                                                        cmd_state <= STATE_IDLE;
                                                        cmd_state <= STATE_IDLE_CHECK_OP_PENDING;
                                                else
                                                else
                                                        cmd_state <= cmd_state;
                                                        cmd_state <= cmd_state;
                                                end if;
                                                end if;
 
 
                                        when STATE_WRITE_ROW_OPEN =>
                                        when STATE_IDLE_CHECK_OP_PENDING =>
 
                                                if (op_save = "01") then
                                                op_ack <= '1';
                                                op_ack <= '1';
 
                                                        cmd_state <= STATE_READ_ROW_OPEN;
 
                                                elsif (op_save = "10") then
 
                                                        op_ack <= '1';
 
                                                        cmd_state <= STATE_WRITE_ROW_OPEN;
 
                                                else
 
                                                        cmd_state <= STATE_IDLE;
 
                                                end if;
 
 
 
                                        when STATE_WRITE_ROW_OPEN =>
 
                                                cap_en <= '0';
                                                dqs_dir <= '1';
                                                dqs_dir <= '1';
                                                dq_dir <= '1';
                                                dq_dir <= '1';
                                                cap_en <= '0';
 
                                                main_cmd <= CMD_ACTIVE;
                                                main_cmd <= CMD_ACTIVE;
                                                main_bank <= addr_save(25 downto 24);
                                                main_bank <= addr_save(25 downto 24);
                                                main_addr <= addr_save(23 downto 11);
                                                main_addr <= addr_save(23 downto 11);
                                                cmd_state <= STATE_WRITE_WAIT_ROW_OPEN;
                                                cmd_state <= STATE_WRITE_WAIT_ROW_OPEN;
 
 
Line 579... Line 620...
                                                else
                                                else
                                                        cmd_state <= cmd_state;
                                                        cmd_state <= cmd_state;
                                                end if;
                                                end if;
 
 
                                        when STATE_READ_ROW_OPEN =>
                                        when STATE_READ_ROW_OPEN =>
                                                op_ack <= '1';
                                                cap_en <= '0';
                                                dqs_dir <= '0';
                                                dqs_dir <= '0';
                                                dq_dir <= '0';
                                                dq_dir <= '0';
                                                cap_en <= '0';
 
                                                main_cmd <= CMD_ACTIVE;
                                                main_cmd <= CMD_ACTIVE;
                                                main_bank <= addr_save(25 downto 24);
                                                main_bank <= addr_save(25 downto 24);
                                                main_addr <= addr_save(23 downto 11);
                                                main_addr <= addr_save(23 downto 11);
                                                cmd_state <= STATE_READ_WAIT_ROW_OPEN;
                                                cmd_state <= STATE_READ_WAIT_ROW_OPEN;
 
 

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.