diff --git a/src/sdram.vhd b/src/sdram.vhd index f846192..6bbecc6 100644 --- a/src/sdram.vhd +++ b/src/sdram.vhd @@ -13,77 +13,48 @@ use IEEE.std_logic_1164.all; use IEEE.numeric_std.all; entity sdram is - port( - CLK : in std_logic; - clk_28MHz : in std_logic; - c0 : in std_logic; - c1 : in std_logic; - c2 : in std_logic; - c3 : in std_logic; - curr_cpu : in std_logic; - -- Memory port - loader : in std_logic; - bsel : in std_logic_vector(1 downto 0); -- Active HI - A : in std_logic_vector(23 downto 0); - DI : in std_logic_vector(15 downto 0); - DO : out std_logic_vector(15 downto 0); - DO_cpu : out std_logic_vector(15 downto 0); - dram_stb : out std_logic; - ---------------------------- - REQ : in std_logic; - RNW : in std_logic; - RFSH : in std_logic; --< REFRESH command NOT USED - RFSHREQ : out std_logic; --> request for refresh - IDLE : out std_logic; --> - -- SDRAM Pin - CK : out std_logic; - CKE : out std_logic; - RAS_n : out std_logic; - CAS_n : out std_logic; - WE_n : out std_logic; - BA1 : out std_logic; - BA0 : out std_logic; - MA : out std_logic_vector(12 downto 0); - DQ : inout std_logic_vector(15 downto 0); - DQML : out std_logic; - DQMH : out std_logic; - -- - TST : out std_logic_vector(3 downto 0) - ); +port( + CLK : in std_logic; + clk_28MHz: in std_logic; + c0 : in std_logic; + c3 : in std_logic; + + -- Memory port + loader : in std_logic; + bsel : in std_logic_vector(1 downto 0); -- Active HI + A : in std_logic_vector(23 downto 0); + DI : in std_logic_vector(15 downto 0); + DO : out std_logic_vector(15 downto 0); + curr_cpu : in std_logic; + DO_cpu : out std_logic_vector(15 downto 0); + REQ : in std_logic; + RNW : in std_logic; + + -- SDRAM Pin + CKE : out std_logic; + RAS_n : out std_logic; + CAS_n : out std_logic; + WE_n : out std_logic; + CS_n : out std_logic; + BA : out std_logic_vector(1 downto 0); + MA : out std_logic_vector(12 downto 0); + DQ : inout std_logic_vector(15 downto 0); + DQML : out std_logic; + DQMH : out std_logic +); end sdram; architecture rtl of sdram is signal state : unsigned(4 downto 0) := "00000"; - signal addr_in : std_logic_vector(23 downto 0); - signal address : std_logic_vector(23 downto 0); - signal bsel_int : std_logic_vector(1 downto 0); - signal rfsh_cnt : unsigned(9 downto 0) := "0000000000"; - signal rfsh_req : std_logic := '0'; - signal data_reg : std_logic_vector(15 downto 0); - signal cpu_reg : std_logic_vector(15 downto 0); - signal data_in : std_logic_vector(15 downto 0); - signal idle1 : std_logic; - signal st_rfsh : std_logic; - signal req_dis : std_logic; - ------------------------------ + signal col : std_logic_vector(7 downto 0); + signal WR_in : std_logic; - signal WR_in1 : std_logic; --- signal WR_r : std_logic; signal RD_in : std_logic; - signal RD_in1 : std_logic; --- signal RD_r : std_logic; signal REQ_in : std_logic; signal RNW_in : std_logic; signal rd_op : std_logic; signal RFSH_in : std_logic; - -- SD-RAM control signals signal sdr_cmd : std_logic_vector(2 downto 0); - signal sdr_ba0 : std_logic; - signal sdr_ba1 : std_logic; - signal sdr_dqml : std_logic; - signal sdr_dqmh : std_logic; - signal sdr_a : std_logic_vector(12 downto 0); - signal sdr_dq : std_logic_vector(15 downto 0); constant SdrCmd_xx : std_logic_vector(2 downto 0) := "111"; -- no operation constant SdrCmd_ac : std_logic_vector(2 downto 0) := "011"; -- activate @@ -99,156 +70,96 @@ architecture rtl of sdram is begin - TST(0) <= WR_in; --idle1; --RD_in; - TST(1) <= data_in(0); --idle1; -- - TST(2) <= idle1; -- - TST(3) <= st_rfsh; - - process (clk_28MHz, c3, DI, A, c0) + process (clk_28MHz) begin - if rising_edge (clk_28MHz) and (c3 = '1') then --next_cycle - if (REQ = '1' and RNW = '1') then - RD_in <= '1'; - elsif (REQ = '1' and RNW = '0') then - WR_in <= '1'; - else - RFSH_in <= '1'; + if rising_edge (clk_28MHz) then + if c3 = '1' then --next_cycle + RD_in <= REQ and RNW; + WR_in <= REQ and not RNW; + RFSH_in <= not REQ; + end if; + + if c0 = '1' then --NOT WORK + RD_in <= '0'; + WR_in <= '0'; + RFSH_in <= '0'; end if; - end if; - data_in <= DI; - addr_in <= A; - if rising_edge (clk_28MHz) and (c0 = '1') then --NOT WORK - RD_in <= '0'; - WR_in <= '0'; - RFSH_in <= '0'; end if; end process; process (CLK) begin - if CLK'event and CLK = '0' then + if rising_edge(CLK) then --------------------------------------------------------- case state is -- Init - when "00000" => -- s00 - sdr_cmd <= SdrCmd_pr; -- PRECHARGE - sdr_a <= "1111111111111"; - sdr_ba1 <= '0'; - sdr_ba0 <= '0'; - sdr_dqml <= '1'; - sdr_dqmh <= '1'; + when "00000" => -- s00 + sdr_cmd <= SdrCmd_pr; -- PRECHARGE + DQ <= (others => 'Z'); + MA <= (others => '1'); + BA <= "00"; + DQML <= '1'; + DQMH <= '1'; state <= state + 1; - when "00011" | "01010" => -- s03 s0A - sdr_cmd <= SdrCmd_re; -- REFRESH + + when "00011" | "01010" => -- s03 s0A + sdr_cmd <= SdrCmd_re; -- REFRESH state <= state + 1; - when "10001" => -- s11 - sdr_cmd <= SdrCmd_ms; -- LOAD MODE REGISTER - sdr_a <= "000" & "1" & "00" & "010" & "0" & "000"; + + when "10001" => -- s11 + sdr_cmd <= SdrCmd_ms; -- LOAD MODE REGISTER + MA <= "000" & "1" & "00" & "010" & "0" & "000"; state <= state + 1; -- Idle - when "11000" => -- s18 - sdr_dq <= (others => 'Z'); - if RD_in = '1' then - idle1 <= '0'; - bsel_int <= bsel; - address <= addr_in; -- LOCK ADDR - sdr_cmd <= SdrCmd_ac; -- ACTIVE - sdr_ba1 <= addr_in(10); -- A(11) - sdr_ba0 <= addr_in(9); -- A(10) --- sdr_a <= addr_in(23 downto 11); -- RAW_ADDR(12..0) - sdr_a <= "0"&addr_in(23)&addr_in(20 downto 11)&addr_in(8); -- RAW_ADDR(12..0) - state <= "11001"; -- s19 Read = when "11010" - elsif WR_in = '1' and (loader = '1' or addr_in(23) = '0') then --Rising UP - idle1 <= '0'; - rd_op <= '0'; - bsel_int <= bsel; - address <= addr_in; - sdr_cmd <= SdrCmd_ac; -- ACTIVE - sdr_ba1 <= addr_in(10); - sdr_ba0 <= addr_in(9); --- sdr_a <= addr_in(23 downto 11); - sdr_a <= "0"&addr_in(23)&addr_in(20 downto 11)&addr_in(8); -- RAW_ADDR(12..0) - state <= "11011"; -- s1B Write + when "11000" => -- s18 + rd_op <= '0'; + if rd_op = '1' then + DO <= DQ; + if curr_cpu = '1' then + DO_cpu <= DQ; + end if; + end if; + if RD_in = '1' or (WR_in = '1' and (loader = '1' or A(23) = '0')) then + col <= A(7 downto 0); -- LOCK COL + sdr_cmd <= SdrCmd_ac; -- ACTIVE + BA <= A(10 downto 9); + MA <= "0"&A(23)&A(20 downto 11)&A(8); -- RAW_ADDR(12..0) + DQML <= not (bsel(0) or RD_in); + DQMH <= not (bsel(1) or RD_in); + rd_op <= RD_in; + state <= state + 1; elsif RFSH_in = '1' then - idle1 <= '0'; - rd_op <= '0'; - st_rfsh <= '1'; - rfsh_req <= '0'; sdr_cmd <= SdrCmd_re; -- REFRESH state <= "10011"; -- s13 - else - sdr_cmd <= SdrCmd_xx; -- NOP - idle1 <= '1'; - rd_op <= '0'; - st_rfsh <= '0'; end if; -- A24 A23 A22 A21 A20 A19 A18 A17 A16 A15 A14 A13 A12 A11 A10 A9 A8 A7 A6 A5 A4 A3 A2 A1 A0 -- -----------------------ROW------------------------- BA1 BA0 -----------COLUMN------------ - -- Single read - with auto precharge - when "11010" => -- s1A - sdr_cmd <= SdrCmd_rd; -- READ (A10 = 1 enable auto precharge; A9..0 = column) --- sdr_a <= "0010" & address(8 downto 0); - sdr_a <= "00100" & address(7 downto 0); - sdr_dqml <= '0'; - sdr_dqmh <= '0'; - state <= "10110"; -- s16 - rd_op <= '1'; - -- Single write - with auto precharge - when "11100" => -- s1C - sdr_cmd <= SdrCmd_wr; -- WRITE (A10 = 1 enable auto precharge; A9..0 = column) --- sdr_a <= "0010" & address(8 downto 0); - sdr_a <= "00100" & address(7 downto 0); - sdr_dqml <= not bsel_int(0); - sdr_dqmh <= not bsel_int(1); - sdr_dq <= data_in; + + -- Single read/write - with auto precharge + when "11010" => -- s1A + MA <= "00100" & col; -- A10 = 1 enable auto precharge; A9..0 = column state <= "10110"; -- s16 + if rd_op = '1' then + sdr_cmd <= SdrCmd_rd; -- READ + else + sdr_cmd <= SdrCmd_wr; -- WRITE + DQ <= DI; + end if; when others => - sdr_dq <= (others => 'Z'); - sdr_cmd <= SdrCmd_xx; -- NOP + DQ <= (others => 'Z'); + sdr_cmd <= SdrCmd_xx; -- NOP state <= state + 1; end case; + end if; + end process; - -- Providing a distributed AUTO REFRESH command every 7.81us - if rfsh_cnt = "1010010001" then -- (84MHz * 1000 * 64 / 8192) = 657 %10 1001 0001 - rfsh_cnt <= (others => '0'); - rfsh_req <= '1'; - else - rfsh_cnt <= rfsh_cnt + 1; - end if; - - end if; - end process; - - process (CLK, rd_op) - begin --------------CLK = '0'------OK------------ - if CLK'event and CLK = '1' and rd_op = '1' then ---idle1 = '0' then - if state = "11000" then -- s18 - data_reg <= DQ; - if curr_cpu = '1' then - cpu_reg <= DQ; - end if; - end if; - end if; - end process; - - IDLE <= idle1; - DO <= data_reg; - DO_cpu <= cpu_reg; - RFSHREQ <= rfsh_req; - CK <= CLK; - CKE <= '1'; - RAS_n <= sdr_cmd(2); - CAS_n <= sdr_cmd(1); + CKE <= '1'; + CS_n <= '0'; + RAS_n <= sdr_cmd(2); + CAS_n <= sdr_cmd(1); WE_n <= sdr_cmd(0); - DQML <= sdr_dqml; - DQMH <= sdr_dqmh; - BA1 <= sdr_ba1; - BA0 <= sdr_ba0; - MA <= sdr_a; - DQ <= sdr_dq; - dram_stb <= rd_op; end rtl; \ No newline at end of file