diff options
author | James <james.mckenzie@citrix.com> | 2013-10-13 17:14:59 +0100 |
---|---|---|
committer | James <james.mckenzie@citrix.com> | 2013-10-13 17:14:59 +0100 |
commit | 7d5f96d2e6dd0118226d98b824125d30f0d6e7f3 (patch) | |
tree | 4f108ff72909d62a288b0cb55d8cfc86bf38c455 | |
parent | 66de2329d0a255889f2339c0a8d911fa42d2633d (diff) | |
download | sdram-7d5f96d2e6dd0118226d98b824125d30f0d6e7f3.tar.gz sdram-7d5f96d2e6dd0118226d98b824125d30f0d6e7f3.tar.bz2 sdram-7d5f96d2e6dd0118226d98b824125d30f0d6e7f3.zip |
fish
-rw-r--r-- | Makefile | 2 | ||||
-rw-r--r-- | pllx2.vhd (renamed from pll50125.vhd) | 24 | ||||
-rw-r--r-- | sdram.vhd | 4 | ||||
-rw-r--r-- | sdram_ctrl.vhd | 213 |
4 files changed, 227 insertions, 16 deletions
@@ -18,6 +18,8 @@ default: run run: load_elf.stamp tools/wrap nios2-terminal +build: ${ELF} ${SOF} + #default: load_sof.stamp @@ -4,7 +4,7 @@ -- MODULE: altpll
-- ============================================================
--- File Name: pll50125.vhd
+-- File Name: pllpllx2.vhd
-- Megafunction Name(s):
-- altpll
--
@@ -39,7 +39,7 @@ USE ieee.std_logic_1164.all; LIBRARY altera_mf;
USE altera_mf.all;
-ENTITY pll50125 IS
+ENTITY pllpllx2 IS
PORT
(
areset : IN STD_LOGIC := '0';
@@ -47,10 +47,10 @@ ENTITY pll50125 IS c0 : OUT STD_LOGIC ;
locked : OUT STD_LOGIC
);
-END pll50125;
+END pllpllx2;
-ARCHITECTURE SYN OF pll50125 IS
+ARCHITECTURE SYN OF pllpllx2 IS
SIGNAL sub_wire0 : STD_LOGIC_VECTOR (5 DOWNTO 0);
SIGNAL sub_wire1 : STD_LOGIC ;
@@ -147,7 +147,7 @@ BEGIN inclk0_input_frequency => 41666,
intended_device_family => "Cyclone II",
invalid_lock_multiplier => 5,
- lpm_hint => "CBX_MODULE_PREFIX=pll50125",
+ lpm_hint => "CBX_MODULE_PREFIX=pllpllx2",
lpm_type => "altpll",
operation_mode => "NORMAL",
port_activeclock => "PORT_UNUSED",
@@ -270,7 +270,7 @@ END SYN; -- Retrieval info: PRIVATE: PLL_PFDENA_CHECK STRING "0"
-- Retrieval info: PRIVATE: PLL_TARGET_HARCOPY_CHECK NUMERIC "0"
-- Retrieval info: PRIVATE: PRIMARY_CLK_COMBO STRING "inclk0"
--- Retrieval info: PRIVATE: RECONFIG_FILE STRING "pll50125.mif"
+-- Retrieval info: PRIVATE: RECONFIG_FILE STRING "pllpllx2.mif"
-- Retrieval info: PRIVATE: SACN_INPUTS_CHECK STRING "0"
-- Retrieval info: PRIVATE: SCAN_FEATURE_ENABLED STRING "0"
-- Retrieval info: PRIVATE: SELF_RESET_LOCK_LOSS STRING "0"
@@ -355,11 +355,11 @@ END SYN; -- Retrieval info: CONNECT: c0 0 0 0 0 @clk 0 0 1 0
-- Retrieval info: CONNECT: @inclk 0 0 1 1 GND 0 0 0 0
-- Retrieval info: CONNECT: @areset 0 0 0 0 areset 0 0 0 0
--- Retrieval info: GEN_FILE: TYPE_NORMAL pll50125.vhd TRUE
--- Retrieval info: GEN_FILE: TYPE_NORMAL pll50125.ppf TRUE
--- Retrieval info: GEN_FILE: TYPE_NORMAL pll50125.inc FALSE
--- Retrieval info: GEN_FILE: TYPE_NORMAL pll50125.cmp FALSE
--- Retrieval info: GEN_FILE: TYPE_NORMAL pll50125.bsf FALSE
--- Retrieval info: GEN_FILE: TYPE_NORMAL pll50125_inst.vhd FALSE
+-- Retrieval info: GEN_FILE: TYPE_NORMAL pllpllx2.vhd TRUE
+-- Retrieval info: GEN_FILE: TYPE_NORMAL pllpllx2.ppf TRUE
+-- Retrieval info: GEN_FILE: TYPE_NORMAL pllpllx2.inc FALSE
+-- Retrieval info: GEN_FILE: TYPE_NORMAL pllpllx2.cmp FALSE
+-- Retrieval info: GEN_FILE: TYPE_NORMAL pllpllx2.bsf FALSE
+-- Retrieval info: GEN_FILE: TYPE_NORMAL pllpllx2_inst.vhd FALSE
-- Retrieval info: LIB_FILE: altera_mf
-- Retrieval info: CBX_MODULE_PREFIX: ON
@@ -26,7 +26,7 @@ end entity; architecture rtl of sdram is -component pll50125 IS +component pllx2 IS PORT ( areset : IN STD_LOGIC := '0'; @@ -101,7 +101,7 @@ signal global_reset_n : std_logic; begin - pll: pll50125 port map ( + pll: pllx2 port map ( pll_reset, clock_50, clock_100, diff --git a/sdram_ctrl.vhd b/sdram_ctrl.vhd index 1c93b13..3342726 100644 --- a/sdram_ctrl.vhd +++ b/sdram_ctrl.vhd @@ -5,7 +5,7 @@ use IEEE.NUMERIC_STD.ALL; entity sdram_ctrl is port ( - clock_50 : in std_logic; + clock_100 : in std_logic; reset_n : in std_logic; b_cs_n : in std_logic; @@ -36,10 +36,219 @@ end entity; architecture rtl of sdram_ctrl is +signal clock : std_logic; + + +signal ack_refresh_request : std_logic; +signal refresh_request : std_logic; +subtype uint13_t is integer range 0 to 8191; +signal refresh_counter : uint13_t; +signal init_done : std_logic; + + +signal i_addr : std_logic_vector(12 downto 0); +signal i_cmd : std_logic_vector(3 downto 0); +subtype uint4_t is integer range 0 to 15; +signal i_count : uint4_t; +subtype uint3_t is integer range 0 to 7; +signal i_next : uint3_t; +signal i_refs : uint3_t; +signal i_state :uint3_t; + +constant I_ST_RESET_WAIT : uint3_t:=0; +constant I_ST_PRECHARGE : uint3_t :=1; +constant I_ST_REFRESH : uint3_t :=2; +constant I_ST_WAIT_COUNT : uint3_t :=3; +constant I_ST_SET_MODE : uint3_t :=4; +constant I_ST_DONE : uint3_t :=5; + + +-- CS_N RAS_N CAS_N WE_N + +constant CMD_IGN : std_logic_vector(3 downto 0 ):="1111"; +constant CMD_NOP : std_logic_vector(3 downto 0 ):="0111"; +constant CMD_READ : std_logic_vector(3 downto 0 ):="0101"; +constant CMD_WRIT : std_logic_vector(3 downto 0 ):="0100"; +constant CMD_ACTV : std_logic_vector(3 downto 0 ):="0011"; +constant CMD_PRE : std_logic_vector(3 downto 0 ):="0010"; +constant CMD_REF : std_logic_vector(3 downto 0 ):="0001"; +constant CMD_MRS : std_logic_vector(3 downto 0 ):="0000"; + +signal m_state : std_logic_vector(8 downto 0); + + +function active_high(constant val : in boolean) return std_logic is begin + if val then + return '1'; + else + return '0'; + end if; +end function active_high; + begin -sdram_clk <=clock_50; +clock<=clock_100; + +refresh_counter_process: process(reset_n,clock) begin + if reset_n = '0' then + refresh_counter <= 8000; + elsif rising_edge(clock) then + if refresh_counter = 0 then + refresh_counter <= 624; + else + refresh_counter <= refresh_counter - 1; + end if; + end if; +end process; + + +refresh_request_process: process(reset_n,clock,refresh_counter,refresh_request,init_done,ack_refresh_request) begin + if reset_n = '0' then + refresh_request <= '0'; + elsif rising_edge(clock) then + refresh_request <= (active_high(refresh_counter = 0) or refresh_request) and init_done and not ack_refresh_request; + end if; +end process; + + +init_done_process: process (reset_n,clock,i_state) begin + if reset_n = '0' then + init_done <= '0'; + elsif rising_edge(clock) then + init_done <= init_done or active_high(i_state = I_ST_DONE ); + end if; +end process; + +init_fsm: process (reset_n,clock,i_state,i_count,i_next,refresh_counter) begin + if reset_n = '0' then + i_state <= I_ST_RESET_WAIT; + i_next <= I_ST_RESET_WAIT; + i_cmd <= CMD_IGN; + i_addr <= (others => '1'); + i_count <= 0; + elsif rising_edge(clock) then + + if i_state = I_ST_RESET_WAIT then + -- after reset wait until the refresh_counter ticks over for RAM to stabalize + i_cmd <= CMD_IGN; + i_refs <= 0; + if refresh_counter=0 then + i_state <= I_ST_PRECHARGE; + end if; + elsif i_state = I_ST_PRECHARGE then + -- precharge all banks, wait one clock, then go to refresh + i_cmd <=CMD_PRE; + i_state <= I_ST_WAIT_COUNT; + i_count <= 1; + i_next <= I_ST_REFRESH; + elsif i_state =I_ST_REFRESH then + -- repeat 7 times { refresh, wait 5 counts } + i_cmd <=CMD_REF; + i_refs <= i_refs + 1; + + i_state <= I_ST_WAIT_COUNT; + i_count <= 5; + + if i_refs = 7 then + i_next <= I_ST_SET_MODE; + else + i_next <= I_ST_REFRESH; + end if; + elsif i_state = I_ST_WAIT_COUNT then + -- wait i_count ticks then goto state i_next + i_cmd <= CMD_NOP; + if (i_count > 1) then + i_count <= i_count -1; + else + i_state <= i_next; + end if; + + elsif i_state=I_ST_SET_MODE then + -- set mode, wait 3 ticks then goto done + i_cmd <= CMD_MRS; + + -- reserverd 000 + -- opcode burst read/write 0 + -- reserved 00 + -- cas latency 3 011 + -- sequential burst 0 + -- burst length 1 000 + + i_addr <= "0000000110000"; + i_count <= 3; + i_next <= I_ST_DONE; + + elsif i_state=I_ST_DONE then + i_state <= I_ST_DONE; + else + i_state <= I_ST_RESET_WAIT; + end if; + end if; +end process; + +main_fsm: process (reset_n,clock,m_state,refresh_counter) begin + +end process; + +if reset_n ='0' then +m_state <= M_ST_1; +m_next <= M_ST_1; +m_cmd <= CMD_IGN; +m_bank <= "00"; +m_addr <= "0000000000000"; +m_data <= "0000000000000000"; +m_dqm <= "00"; +m_count <= 0; +ack_refresh_request <= 0; +f_pop <= 0; +oe <= 0; +elsif rising_edge(clock) then +if m_state = M_ST_1 then + if active_high(init_done) then + if active_high(refresh_request) then + m_cmd <= CMD_NOP; + else + m_vmd <= CMD_IGN; + end if; + ack_refresh_request <='1'; + + if active_high(refresh_request) then + m_state <= M_ST_7; + m_next <= M_ST_8; + m_count <= 1; + active_cs_n <= '1'; + elsif (not active_high(f_empty)) then + f_pop <= '1'; + active_cs_n <= f_cs_n; + active_rnw <= f_rnw; + active_addr <= f_addr; + active_data <= f_data; + m_state <= M_ST_2; + end if; + else + m_addr <= i_addr; + m_state <= M_ST_1; + m_next <= M_ST_1; + m_cmd <= i_cmd; + end if; +elsif m_state = M_ST_2 then + m_state <= M_ST_3; + m_cmd(3) <= csn_decode; + m_cmd(2 downto 0)="111"; + m_bank <= active_bank; + m_addr <= active_addr(22 downto 10); + m_data <= active_data; + m_dqm <= active_dqm; + m_count <=2; + if (active_high(active_rnw)) then + m_next <=M_ST_4; + else + m_next <=M_ST_5; + end if; +elsif m_state = M_ST_3 + + end; |