summaryrefslogtreecommitdiffstats
path: root/misc
diff options
context:
space:
mode:
Diffstat (limited to 'misc')
-rw-r--r--misc/arm7/src/arm7pkg.vhd60
-rw-r--r--misc/arm7/src/arm7wb.vhd472
-rw-r--r--misc/ddrsdram/simsrc/ddr_tb.vhd602
-rw-r--r--misc/ddrsdram/src/ddr_pkg.vhd212
-rw-r--r--misc/ddrsdram/src/ddr_top.vhd1486
-rw-r--r--misc/ddrsdram/src/mt46v16m16.vhd2640
-rw-r--r--misc/wishbone/src/atomic32_access.vhd262
-rw-r--r--misc/wishbone/src/wishbone_pkg.vhd104
8 files changed, 2919 insertions, 2919 deletions
diff --git a/misc/arm7/src/arm7pkg.vhd b/misc/arm7/src/arm7pkg.vhd
index 855fbdb..4dcbb9c 100644
--- a/misc/arm7/src/arm7pkg.vhd
+++ b/misc/arm7/src/arm7pkg.vhd
@@ -1,31 +1,31 @@
-library IEEE;
-use IEEE.STD_LOGIC_1164.all;
-use IEEE.STD_LOGIC_UNSIGNED.ALL;
-library work;
-use work.wishbone_pkg.all;
-
-package arm7 is
-
- component arm7wb
- generic(
- simulate_io_time : boolean := false);
- port ( areset : in std_logic;
- cpu_clk : in std_logic;
- cpu_clk_2x : in std_logic;
- cpu_a_p : in std_logic_vector(23 downto 1);
- cpu_wr_n_p : in std_logic_vector(1 downto 0);
- cpu_cs_n_p : in std_logic_vector(3 downto 1);
- cpu_oe_n_p : in std_logic;
- cpu_d_p : inout std_logic_vector(15 downto 0);
- cpu_wait_n_p : out std_logic;
-
- arm7_debug : out std_logic;
- arm7_debug2 : out std_logic;
-
- wb_o : out wishbone_bus_in;
- wb_i : in wishbone_bus_out);
- end component;
-
-end arm7;
-
+library IEEE;
+use IEEE.STD_LOGIC_1164.all;
+use IEEE.STD_LOGIC_UNSIGNED.ALL;
+library work;
+use work.wishbone_pkg.all;
+
+package arm7 is
+
+ component arm7wb
+ generic(
+ simulate_io_time : boolean := false);
+ port ( areset : in std_logic;
+ cpu_clk : in std_logic;
+ cpu_clk_2x : in std_logic;
+ cpu_a_p : in std_logic_vector(23 downto 1);
+ cpu_wr_n_p : in std_logic_vector(1 downto 0);
+ cpu_cs_n_p : in std_logic_vector(3 downto 1);
+ cpu_oe_n_p : in std_logic;
+ cpu_d_p : inout std_logic_vector(15 downto 0);
+ cpu_wait_n_p : out std_logic;
+
+ arm7_debug : out std_logic;
+ arm7_debug2 : out std_logic;
+
+ wb_o : out wishbone_bus_in;
+ wb_i : in wishbone_bus_out);
+ end component;
+
+end arm7;
+
\ No newline at end of file
diff --git a/misc/arm7/src/arm7wb.vhd b/misc/arm7/src/arm7wb.vhd
index 3366352..85f0ef7 100644
--- a/misc/arm7/src/arm7wb.vhd
+++ b/misc/arm7/src/arm7wb.vhd
@@ -1,236 +1,236 @@
-library IEEE;
-use IEEE.STD_LOGIC_1164.all;
-use IEEE.STD_LOGIC_UNSIGNED.ALL;
-library work;
-use work.phi_config.all;
-use work.wishbone_pkg.all;
-
-entity arm7wb is
- generic(
- simulate_io_time : boolean := false);
- port ( areset : in std_logic;
- cpu_clk : in std_logic;
- cpu_clk_2x : in std_logic;
- cpu_a_p : in std_logic_vector(23 downto 1);
- cpu_wr_n_p : in std_logic_vector(1 downto 0);
- cpu_cs_n_p : in std_logic_vector(3 downto 1);
- cpu_oe_n_p : in std_logic;
- cpu_d_p : inout std_logic_vector(15 downto 0);
- cpu_wait_n_p : out std_logic;
-
- arm7_debug : out std_logic;
- arm7_debug2 : out std_logic;
-
- wb_o : out wishbone_bus_in;
- wb_i : in wishbone_bus_out);
-end arm7wb;
-
-architecture behave of arm7wb is
-
-type cpu_state_type is (cpu_idle, cpu_cs, cpu_end);
-
--- Input simulated delay
-signal cpu_wr_n_p_del : std_logic_vector(1 downto 0);
-signal cpu_a_p_del : std_logic_vector(23 downto 1);
-signal cpu_d_p_del : std_logic_vector(15 downto 0);
-signal cpu_cs_n_p_del : std_logic_vector(3 downto 1);
-signal cpu_oe_n_p_del : std_logic;
-
--- Clock phase detect signals
-signal cpu_clk_toggle : std_logic;
-signal cpu_clk_smp1 : std_logic;
-signal cpu_clk_smp2 : std_logic;
-signal cpu_clk_phase : std_logic;
-
--- Internal version of control signal (for feedback)
-signal arm7_din_int : std_logic_vector(15 downto 0);
-signal arm7_dout_int : std_logic_vector(15 downto 0);
-signal arm7_a_int : std_logic_vector(23 downto 1);
-signal arm7_we_int : std_logic_vector(1 downto 0);
-signal cyc_int : std_logic;
-signal we_int : std_logic;
-signal adr_reg : std_logic_vector(25 downto 24);
-
--- Input sampled
-signal cpu_a_smp : std_logic_vector(23 downto 1);
-signal cpu_d_smp : std_logic_vector(15 downto 0);
-signal cpu_cs_n : std_logic_vector(3 downto 1);
-signal cpu_oe_n : std_logic;
-signal cpu_wr_n : std_logic_vector(1 downto 0);
-
--- Main FSM
-signal cpu_state : cpu_state_type;
-
-constant Clock_2_Out : time := 5.5 ns;
-constant Input_Setup : time := 2.5 ns;
-
-begin
-
- arm7_dout_int <= wb_i.dat(15 downto 0) when (arm7_a_int(1) = '0') else wb_i.dat(31 downto 16);
- arm7_debug <= cpu_oe_n;
- arm7_debug2 <= cpu_wr_n(0);
-
- -- Generate 64 MBytes address based on 3 CS_N signals from CPU
- -- Memory map FPGA internal
- -- 0x00000000 DDR 32 MBytes (CS_N2 and CS_N3)
- -- 0x00200000 FPGA/Ethernet (CS_N1)
- wb_o.adr(31 downto 26) <= "000000";
- wb_o.adr(25 downto 24) <= adr_reg;
- wb_o.adr(23 downto 1) <= arm7_a_int(23 downto 1);
- wb_o.adr(0) <= '0';
-
- wb_o.dat <= (x"0000" & arm7_din_int) when (arm7_a_int(1) = '0') else (arm7_din_int & x"0000");
- wb_o.sel <= ("00" & arm7_we_int) when (arm7_a_int(1) = '0') else (arm7_we_int & "00");
-
- wb_o.cyc <= cyc_int;
- wb_o.stb <= cyc_int;
- wb_o.we <= cpu_oe_n;
-
- iotimingon:
- if simulate_io_time generate
- begin
- cpu_wr_n_p_del <= transport "XX" after 0 ns, cpu_wr_n_p after Input_Setup;
- cpu_a_p_del <= transport "XXXXXXXXXXXXXXXXXXXXXXX" after 0 ns, cpu_a_p after Input_Setup;
- cpu_d_p_del <= transport "XXXXXXXXXXXXXXXX" after 0 ns, cpu_d_p after Input_Setup;
- cpu_cs_n_p_del <= transport "XXX" after 0 ns, cpu_cs_n_p after Input_Setup;
- cpu_oe_n_p_del <= transport 'X' after 0 ns, cpu_oe_n_p after Input_Setup;
- end generate;
-
- iotimingoff:
- if not simulate_io_time generate
- begin
- cpu_wr_n_p_del <= cpu_wr_n_p;
- cpu_a_p_del <= cpu_a_p;
- cpu_d_p_del <= cpu_d_p;
- cpu_cs_n_p_del <= cpu_cs_n_p;
- cpu_oe_n_p_del <= cpu_oe_n_p;
- end generate;
-
- process(cpu_clk, areset) -- Toggle FF with 1x clock to find phase
- begin
- if areset = '1' then
- cpu_clk_toggle <= '0';
- elsif (cpu_clk'event and cpu_clk = '1') then
- cpu_clk_toggle <= not(cpu_clk_toggle);
- end if;
- end process;
-
- process(cpu_clk_2x, areset) -- Find phase relationsship between 1x and 2x clock
- begin
- if areset = '1' then
- cpu_clk_smp1 <= '0';
- cpu_clk_smp2 <= '1';
- cpu_clk_phase <= '0';
- elsif (cpu_clk_2x'event and cpu_clk_2x = '1') then
- cpu_clk_smp1 <= cpu_clk_toggle;
- cpu_clk_smp2 <= cpu_clk_smp1;
- if cpu_clk_smp1 = '1' and cpu_clk_smp2 = '0' then
- cpu_clk_phase <= '0';
- else
- cpu_clk_phase <= not(cpu_clk_phase);
- end if;
- end if;
- end process;
-
- process(cpu_clk_2x, areset) -- Sample input signals on 2x clock
- begin
- if areset = '1' then
- cpu_d_smp <= "0000000000000000";
- cpu_cs_n <= "111";
- elsif (cpu_clk_2x = '1' and cpu_clk_2x'event) then
- cpu_d_smp <= cpu_d_p_del;
- cpu_cs_n <= cpu_cs_n_p_del;
- end if;
- end process;
-
- process(cpu_clk, areset) -- Sample input signals on 1x clock
- begin
- if areset = '1' then
- cpu_a_smp <= "00000000000000000000000";
- cpu_oe_n <= '1';
- cpu_wr_n <= "11";
- elsif (cpu_clk = '1' and cpu_clk'event) then
- cpu_a_smp <= cpu_a_p_del;
- cpu_oe_n <= cpu_oe_n_p_del;
- cpu_wr_n <= cpu_wr_n_p_del;
- end if;
- end process;
-
- arm7_din_int <= cpu_d_smp;
- arm7_a_int <= cpu_a_smp;
- arm7_we_int <= not(cpu_wr_n);
-
- process(cpu_clk, areset)
- begin
- if areset = '1' then
- cpu_state <= cpu_idle;
- cyc_int <= '0';
- we_int <= '0';
- adr_reg <= "00";
- cpu_d_p <= (others => 'Z');
- elsif (cpu_clk'event and cpu_clk = '1') then
-
- cyc_int <= '0';
- we_int <= '0';
- cpu_d_p <= (others => 'Z') after Clock_2_Out;
-
-
- case cpu_state is
-
- when cpu_idle =>
- if cpu_oe_n = '1' then
- we_int <= '1';
- end if;
- if cpu_cs_n(1) = '0' then
- cyc_int <= '1';
- adr_reg <= "10";
- cpu_state <= cpu_cs;
- end if;
- if cpu_cs_n(2) = '0' then
- cyc_int <= '1';
- adr_reg <= "00";
- cpu_state <= cpu_cs;
- end if;
- if cpu_cs_n(3) = '0' then
- cyc_int <= '1';
- adr_reg <= "01";
- cpu_state <= cpu_cs;
- end if;
-
- when cpu_cs =>
- if cpu_oe_n = '0' then
- cpu_d_p <= arm7_dout_int after Clock_2_Out;
- if wb_i.ack = '1' then
- cpu_state <= cpu_end;
- else
- cyc_int <= '1';
- end if;
- else
- if wb_i.ack = '0' then
- cyc_int <= '1';
- we_int <= '1';
- else
- cpu_state <= cpu_end;
- end if;
- end if;
-
- when others =>
- cpu_state <= cpu_idle;
-
- end case;
- end if;
- end process;
-
- process(cpu_clk_2x, areset)
- begin
- if areset = '1' then
- cpu_wait_n_p <= '1';
- elsif (cpu_clk_2x'event and cpu_clk_2x = '1') then
- cpu_wait_n_p <= '1' after Clock_2_Out;
- if (cpu_state = cpu_cs and wb_i.ack = '0') then
- cpu_wait_n_p <= '0' after Clock_2_Out;
- end if;
- end if;
- end process;
-
-end behave;
+library IEEE;
+use IEEE.STD_LOGIC_1164.all;
+use IEEE.STD_LOGIC_UNSIGNED.ALL;
+library work;
+use work.phi_config.all;
+use work.wishbone_pkg.all;
+
+entity arm7wb is
+ generic(
+ simulate_io_time : boolean := false);
+ port ( areset : in std_logic;
+ cpu_clk : in std_logic;
+ cpu_clk_2x : in std_logic;
+ cpu_a_p : in std_logic_vector(23 downto 1);
+ cpu_wr_n_p : in std_logic_vector(1 downto 0);
+ cpu_cs_n_p : in std_logic_vector(3 downto 1);
+ cpu_oe_n_p : in std_logic;
+ cpu_d_p : inout std_logic_vector(15 downto 0);
+ cpu_wait_n_p : out std_logic;
+
+ arm7_debug : out std_logic;
+ arm7_debug2 : out std_logic;
+
+ wb_o : out wishbone_bus_in;
+ wb_i : in wishbone_bus_out);
+end arm7wb;
+
+architecture behave of arm7wb is
+
+type cpu_state_type is (cpu_idle, cpu_cs, cpu_end);
+
+-- Input simulated delay
+signal cpu_wr_n_p_del : std_logic_vector(1 downto 0);
+signal cpu_a_p_del : std_logic_vector(23 downto 1);
+signal cpu_d_p_del : std_logic_vector(15 downto 0);
+signal cpu_cs_n_p_del : std_logic_vector(3 downto 1);
+signal cpu_oe_n_p_del : std_logic;
+
+-- Clock phase detect signals
+signal cpu_clk_toggle : std_logic;
+signal cpu_clk_smp1 : std_logic;
+signal cpu_clk_smp2 : std_logic;
+signal cpu_clk_phase : std_logic;
+
+-- Internal version of control signal (for feedback)
+signal arm7_din_int : std_logic_vector(15 downto 0);
+signal arm7_dout_int : std_logic_vector(15 downto 0);
+signal arm7_a_int : std_logic_vector(23 downto 1);
+signal arm7_we_int : std_logic_vector(1 downto 0);
+signal cyc_int : std_logic;
+signal we_int : std_logic;
+signal adr_reg : std_logic_vector(25 downto 24);
+
+-- Input sampled
+signal cpu_a_smp : std_logic_vector(23 downto 1);
+signal cpu_d_smp : std_logic_vector(15 downto 0);
+signal cpu_cs_n : std_logic_vector(3 downto 1);
+signal cpu_oe_n : std_logic;
+signal cpu_wr_n : std_logic_vector(1 downto 0);
+
+-- Main FSM
+signal cpu_state : cpu_state_type;
+
+constant Clock_2_Out : time := 5.5 ns;
+constant Input_Setup : time := 2.5 ns;
+
+begin
+
+ arm7_dout_int <= wb_i.dat(15 downto 0) when (arm7_a_int(1) = '0') else wb_i.dat(31 downto 16);
+ arm7_debug <= cpu_oe_n;
+ arm7_debug2 <= cpu_wr_n(0);
+
+ -- Generate 64 MBytes address based on 3 CS_N signals from CPU
+ -- Memory map FPGA internal
+ -- 0x00000000 DDR 32 MBytes (CS_N2 and CS_N3)
+ -- 0x00200000 FPGA/Ethernet (CS_N1)
+ wb_o.adr(31 downto 26) <= "000000";
+ wb_o.adr(25 downto 24) <= adr_reg;
+ wb_o.adr(23 downto 1) <= arm7_a_int(23 downto 1);
+ wb_o.adr(0) <= '0';
+
+ wb_o.dat <= (x"0000" & arm7_din_int) when (arm7_a_int(1) = '0') else (arm7_din_int & x"0000");
+ wb_o.sel <= ("00" & arm7_we_int) when (arm7_a_int(1) = '0') else (arm7_we_int & "00");
+
+ wb_o.cyc <= cyc_int;
+ wb_o.stb <= cyc_int;
+ wb_o.we <= cpu_oe_n;
+
+ iotimingon:
+ if simulate_io_time generate
+ begin
+ cpu_wr_n_p_del <= transport "XX" after 0 ns, cpu_wr_n_p after Input_Setup;
+ cpu_a_p_del <= transport "XXXXXXXXXXXXXXXXXXXXXXX" after 0 ns, cpu_a_p after Input_Setup;
+ cpu_d_p_del <= transport "XXXXXXXXXXXXXXXX" after 0 ns, cpu_d_p after Input_Setup;
+ cpu_cs_n_p_del <= transport "XXX" after 0 ns, cpu_cs_n_p after Input_Setup;
+ cpu_oe_n_p_del <= transport 'X' after 0 ns, cpu_oe_n_p after Input_Setup;
+ end generate;
+
+ iotimingoff:
+ if not simulate_io_time generate
+ begin
+ cpu_wr_n_p_del <= cpu_wr_n_p;
+ cpu_a_p_del <= cpu_a_p;
+ cpu_d_p_del <= cpu_d_p;
+ cpu_cs_n_p_del <= cpu_cs_n_p;
+ cpu_oe_n_p_del <= cpu_oe_n_p;
+ end generate;
+
+ process(cpu_clk, areset) -- Toggle FF with 1x clock to find phase
+ begin
+ if areset = '1' then
+ cpu_clk_toggle <= '0';
+ elsif (cpu_clk'event and cpu_clk = '1') then
+ cpu_clk_toggle <= not(cpu_clk_toggle);
+ end if;
+ end process;
+
+ process(cpu_clk_2x, areset) -- Find phase relationsship between 1x and 2x clock
+ begin
+ if areset = '1' then
+ cpu_clk_smp1 <= '0';
+ cpu_clk_smp2 <= '1';
+ cpu_clk_phase <= '0';
+ elsif (cpu_clk_2x'event and cpu_clk_2x = '1') then
+ cpu_clk_smp1 <= cpu_clk_toggle;
+ cpu_clk_smp2 <= cpu_clk_smp1;
+ if cpu_clk_smp1 = '1' and cpu_clk_smp2 = '0' then
+ cpu_clk_phase <= '0';
+ else
+ cpu_clk_phase <= not(cpu_clk_phase);
+ end if;
+ end if;
+ end process;
+
+ process(cpu_clk_2x, areset) -- Sample input signals on 2x clock
+ begin
+ if areset = '1' then
+ cpu_d_smp <= "0000000000000000";
+ cpu_cs_n <= "111";
+ elsif (cpu_clk_2x = '1' and cpu_clk_2x'event) then
+ cpu_d_smp <= cpu_d_p_del;
+ cpu_cs_n <= cpu_cs_n_p_del;
+ end if;
+ end process;
+
+ process(cpu_clk, areset) -- Sample input signals on 1x clock
+ begin
+ if areset = '1' then
+ cpu_a_smp <= "00000000000000000000000";
+ cpu_oe_n <= '1';
+ cpu_wr_n <= "11";
+ elsif (cpu_clk = '1' and cpu_clk'event) then
+ cpu_a_smp <= cpu_a_p_del;
+ cpu_oe_n <= cpu_oe_n_p_del;
+ cpu_wr_n <= cpu_wr_n_p_del;
+ end if;
+ end process;
+
+ arm7_din_int <= cpu_d_smp;
+ arm7_a_int <= cpu_a_smp;
+ arm7_we_int <= not(cpu_wr_n);
+
+ process(cpu_clk, areset)
+ begin
+ if areset = '1' then
+ cpu_state <= cpu_idle;
+ cyc_int <= '0';
+ we_int <= '0';
+ adr_reg <= "00";
+ cpu_d_p <= (others => 'Z');
+ elsif (cpu_clk'event and cpu_clk = '1') then
+
+ cyc_int <= '0';
+ we_int <= '0';
+ cpu_d_p <= (others => 'Z') after Clock_2_Out;
+
+
+ case cpu_state is
+
+ when cpu_idle =>
+ if cpu_oe_n = '1' then
+ we_int <= '1';
+ end if;
+ if cpu_cs_n(1) = '0' then
+ cyc_int <= '1';
+ adr_reg <= "10";
+ cpu_state <= cpu_cs;
+ end if;
+ if cpu_cs_n(2) = '0' then
+ cyc_int <= '1';
+ adr_reg <= "00";
+ cpu_state <= cpu_cs;
+ end if;
+ if cpu_cs_n(3) = '0' then
+ cyc_int <= '1';
+ adr_reg <= "01";
+ cpu_state <= cpu_cs;
+ end if;
+
+ when cpu_cs =>
+ if cpu_oe_n = '0' then
+ cpu_d_p <= arm7_dout_int after Clock_2_Out;
+ if wb_i.ack = '1' then
+ cpu_state <= cpu_end;
+ else
+ cyc_int <= '1';
+ end if;
+ else
+ if wb_i.ack = '0' then
+ cyc_int <= '1';
+ we_int <= '1';
+ else
+ cpu_state <= cpu_end;
+ end if;
+ end if;
+
+ when others =>
+ cpu_state <= cpu_idle;
+
+ end case;
+ end if;
+ end process;
+
+ process(cpu_clk_2x, areset)
+ begin
+ if areset = '1' then
+ cpu_wait_n_p <= '1';
+ elsif (cpu_clk_2x'event and cpu_clk_2x = '1') then
+ cpu_wait_n_p <= '1' after Clock_2_Out;
+ if (cpu_state = cpu_cs and wb_i.ack = '0') then
+ cpu_wait_n_p <= '0' after Clock_2_Out;
+ end if;
+ end if;
+ end process;
+
+end behave;
diff --git a/misc/ddrsdram/simsrc/ddr_tb.vhd b/misc/ddrsdram/simsrc/ddr_tb.vhd
index 249dffb..92d1e4b 100644
--- a/misc/ddrsdram/simsrc/ddr_tb.vhd
+++ b/misc/ddrsdram/simsrc/ddr_tb.vhd
@@ -1,301 +1,301 @@
-library IEEE;
-use IEEE.STD_LOGIC_1164.all;
-use IEEE.STD_LOGIC_UNSIGNED.ALL;
-library work;
-use work.ddr.all;
-
-entity ddr_tb is
- port ( areset : in std_logic;
- break_out : out std_logic);
-end ddr_tb;
-
-architecture behave of ddr_tb is
-
-signal cpu_clk : std_logic;
-signal cpu_clk_2x : std_logic;
-signal cpu_clk_4x : std_logic;
-signal ddr_in_clk : std_logic;
-signal ddr_in_clk_2x : std_logic;
-
-signal ddr_command : std_logic_vector(15 downto 0);
-signal ddr_command_we : std_logic;
-
-signal ddr_data_read : std_logic_vector(31 downto 0); -- Data read from DDR SDRAM
-signal ddr_data_write : std_logic_vector(35 downto 0); -- Data to be written to DDR SDRAM
-signal ddr_req_adr : std_logic_vector(23 downto 1); -- Request address
-signal ddr_req : std_logic; -- Request DDR SDRAM access
-signal ddr_req_ack : std_logic; -- Request acknowledge
-signal ddr_busy : std_logic; -- Request acknowledge
-signal ddr_rd_wr_n : std_logic; -- Access type 1=READ, 0=WRITE
-signal ddr_req_len : std_logic; -- Number of 16-bits words to transfer
-signal ddr_read_en : std_logic; -- Enable signal for read data
-signal ddr_write_en : std_logic; -- Enable (read) signal for data write
-signal refresh_en : std_logic;
-
-signal sdr_clk_p : std_logic; -- ddr_sdram_clock
-signal sdr_clk_n_p : std_logic; -- /ddr_sdram_clock
-signal cke_q_p : std_logic; -- clock enable
-signal cs_qn_p : std_logic; -- /chip select
-signal ras_qn_p : std_logic; -- /ras
-signal cas_qn_p : std_logic; -- /cas
-signal we_qn_p : std_logic; -- /write enable
-signal dm_q_p : std_logic_vector(1 downto 0); -- data mask bits, set to "00"
-signal dqs_q_p : std_logic_vector(1 downto 0); -- data strobe, only for write
-signal ba_q_p : std_logic_vector(1 downto 0); -- bank select
-signal sdr_a_p : std_logic_vector(12 downto 0); -- address bus
-signal sdr_d_p : std_logic_vector(15 downto 0); -- bidir data bus
-
-constant min_time : time := 1.875 ns;
-
-begin
-
- clock1:
- process
- begin
- loop
- cpu_clk_4x <= '1';
- wait for min_time;
- cpu_clk_4x <= '0';
- wait for min_time;
- end loop;
- end process;
-
- clock2:
- process
- begin
- loop
- cpu_clk_2x <= '1' after 100 ps;
- wait until rising_edge(cpu_clk_4x);
- cpu_clk_2x <= '0' after 100 ps;
- wait until rising_edge(cpu_clk_4x);
- end loop;
- end process;
-
- clock3:
- process
- begin
- loop
- cpu_clk <= '1' after 100 ps;
- wait until rising_edge(cpu_clk_2x);
- cpu_clk <= '0' after 100 ps;
- wait until rising_edge(cpu_clk_2x);
- end loop;
- end process;
-
- ddr_in_clk_2x <= cpu_clk_4x after 1 ns;
-
- clock4:
- process
- begin
- loop
- ddr_in_clk <= '0' after 100 ps;
- wait until rising_edge(ddr_in_clk_2x);
- ddr_in_clk <= '1' after 100 ps;
- wait until rising_edge(ddr_in_clk_2x);
- end loop;
- end process;
-
- inputdata:
- process
- begin
- -- Wait until global reset released
- loop
- ddr_command <= x"0000";
- ddr_command_we <= '0';
- ddr_data_write <= x"000000000";
- ddr_req <= '0';
- ddr_req_adr <= "00000000000000000000000";
- ddr_rd_wr_n <= '0';
- ddr_req_len <= '0';
- break_out <= '0';
- refresh_en <= '0';
-
- wait until falling_edge(areset);
-
- -- DDR initialization sequence
- -- Wait more than 200 us
- wait for 201000 ns;
-
- -- Send precharge command
- wait until rising_edge(cpu_clk);
- ddr_command <= x"8000";
- ddr_command_we <= '1';
- wait until rising_edge(cpu_clk);
- ddr_command <= x"0000";
- ddr_command_we <= '0';
-
- -- Wait for 1 us
- wait for 1000 ns;
-
- -- Load extended mode register
- -- Enable DLL
- -- Normal drive strength
- wait until rising_edge(cpu_clk);
- ddr_command <= x"2000";
- ddr_command_we <= '1';
- wait until rising_edge(cpu_clk);
- ddr_command <= x"0000";
- ddr_command_we <= '0';
-
- -- Wait for 1 us
- wait for 1000 ns;
-
- -- Load mode register
- -- Burst length: 2
- -- Burst type: Sequential
- -- Cas latency: 2
- -- Reset DLL
- wait until rising_edge(cpu_clk);
- ddr_command <= x"0121";
- ddr_command_we <= '1';
- wait until rising_edge(cpu_clk);
- ddr_command <= x"0000";
- ddr_command_we <= '0';
-
- -- Wait for 1 us
- wait for 1000 ns;
-
- -- Send precharge command
- wait until rising_edge(cpu_clk);
- ddr_command <= x"8000";
- ddr_command_we <= '1';
- wait until rising_edge(cpu_clk);
- ddr_command <= x"0000";
- ddr_command_we <= '0';
-
- -- Enable refresh
- refresh_en <= '1';
-
- -- Wait 30 us (minimum 2 autorefresh cycles)
- wait for 30000 ns;
-
- -- Load mode register
- -- Burst length: 2
- -- Burst type: Sequential
- -- Cas latency: 2
- -- Deactivate Reset DLL
- wait until rising_edge(cpu_clk);
- ddr_command <= x"0021";
- ddr_command_we <= '1';
- wait until rising_edge(cpu_clk);
- ddr_command <= x"0000";
- ddr_command_we <= '0';
-
- -- Wait for 2 us (DLL stable)
- wait for 2000 ns;
-
- -- Write data to DDR
- wait until rising_edge(cpu_clk_2x);
- ddr_data_write <= x"312345678";
- ddr_req <= '1';
- ddr_req_adr <= "00000000000000000000000";
- ddr_rd_wr_n <= '0';
- ddr_req_len <= '0';
- wait until rising_edge(ddr_write_en);
- wait until rising_edge(cpu_clk_2x);
- ddr_req <= '0';
- ddr_req_adr <= "00000000000000000000000";
- ddr_rd_wr_n <= '0';
- ddr_req_len <= '0';
- ddr_data_write <= x"000000000";
- wait for 100 ns;
-
- -- Read data from DDR
- wait until rising_edge(cpu_clk_2x);
- ddr_req <= '1';
- ddr_req_adr <= "00000000000000000000000";
- ddr_rd_wr_n <= '1';
- ddr_req_len <= '0';
- wait until rising_edge(ddr_req_ack);
- wait until rising_edge(cpu_clk_2x);
- ddr_req <= '0';
- ddr_req_adr <= "00000000000000000000000";
- ddr_rd_wr_n <= '0';
- ddr_req_len <= '0';
- ddr_data_write <= x"000000000";
-
-
-
- wait for 100 ns;
- break_out <= '1';
- wait for 100 ns;
-
- end loop;
-
- end process;
-
- ddr_ctrl:
- ddr_top port map(
- areset => areset,
- cpu_clk => cpu_clk,
- cpu_clk_2x => cpu_clk_2x,
- cpu_clk_4x => cpu_clk_4x,
- ddr_in_clk => ddr_in_clk,
- ddr_in_clk_2x => ddr_in_clk_2x,
-
- -- Command interface
- ddr_command => ddr_command,
- ddr_command_we => ddr_command_we,
- refresh_en => refresh_en,
-
- -- Data interface signals
- ddr_data_read => ddr_data_read,
- ddr_data_write => ddr_data_write,
- ddr_req_adr => ddr_req_adr,
- ddr_req => ddr_req,
- ddr_req_ack => ddr_req_ack,
- ddr_busy => ddr_busy,
- ddr_rd_wr_n => ddr_rd_wr_n,
- ddr_req_len => ddr_req_len,
- ddr_read_en => ddr_read_en,
- ddr_write_en => ddr_write_en,
- -- DDR SDRAM Signals
- sdr_clk_p => sdr_clk_p,
- sdr_clk_n_p => sdr_clk_n_p,
- cke_q_p => cke_q_p,
- cs_qn_p => cs_qn_p,
- ras_qn_p => ras_qn_p,
- cas_qn_p => cas_qn_p,
- we_qn_p => we_qn_p,
- dm_q_p => dm_q_p,
- dqs_q_p => dqs_q_p,
- ba_q_p => ba_q_p,
- sdr_a_p => sdr_a_p,
- sdr_d_p => sdr_d_p);
-
- myram:
- MT46V16M16 generic map(
- tCK => 7.500 ns,
- tCH => 3.375 ns, -- 0.45*tCK
- tCL => 3.375 ns, -- 0.45*tCK
- tDH => 0.500 ns,
- tDS => 0.500 ns,
- tIH => 0.900 ns,
- tIS => 0.900 ns,
- tMRD => 15.000 ns,
- tRAS => 40.000 ns,
- tRAP => 20.000 ns,
- tRC => 65.000 ns,
- tRFC => 75.000 ns,
- tRCD => 20.000 ns,
- tRP => 20.000 ns,
- tRRD => 15.000 ns,
- tWR => 15.000 ns,
- addr_bits => 13,
- data_bits => 16,
- cols_bits => 9)
- port map(
- Dq => sdr_d_p,
- Dqs => dqs_q_p,
- Addr => sdr_a_p,
- Ba => ba_q_p,
- Clk => sdr_clk_p,
- Clk_n => sdr_clk_n_p,
- Cke => cke_q_p,
- Cs_n => cs_qn_p,
- Ras_n => ras_qn_p,
- Cas_n => cas_qn_p,
- We_n => we_qn_p,
- Dm => dm_q_p);
-
-end behave;
+library IEEE;
+use IEEE.STD_LOGIC_1164.all;
+use IEEE.STD_LOGIC_UNSIGNED.ALL;
+library work;
+use work.ddr.all;
+
+entity ddr_tb is
+ port ( areset : in std_logic;
+ break_out : out std_logic);
+end ddr_tb;
+
+architecture behave of ddr_tb is
+
+signal cpu_clk : std_logic;
+signal cpu_clk_2x : std_logic;
+signal cpu_clk_4x : std_logic;
+signal ddr_in_clk : std_logic;
+signal ddr_in_clk_2x : std_logic;
+
+signal ddr_command : std_logic_vector(15 downto 0);
+signal ddr_command_we : std_logic;
+
+signal ddr_data_read : std_logic_vector(31 downto 0); -- Data read from DDR SDRAM
+signal ddr_data_write : std_logic_vector(35 downto 0); -- Data to be written to DDR SDRAM
+signal ddr_req_adr : std_logic_vector(23 downto 1); -- Request address
+signal ddr_req : std_logic; -- Request DDR SDRAM access
+signal ddr_req_ack : std_logic; -- Request acknowledge
+signal ddr_busy : std_logic; -- Request acknowledge
+signal ddr_rd_wr_n : std_logic; -- Access type 1=READ, 0=WRITE
+signal ddr_req_len : std_logic; -- Number of 16-bits words to transfer
+signal ddr_read_en : std_logic; -- Enable signal for read data
+signal ddr_write_en : std_logic; -- Enable (read) signal for data write
+signal refresh_en : std_logic;
+
+signal sdr_clk_p : std_logic; -- ddr_sdram_clock
+signal sdr_clk_n_p : std_logic; -- /ddr_sdram_clock
+signal cke_q_p : std_logic; -- clock enable
+signal cs_qn_p : std_logic; -- /chip select
+signal ras_qn_p : std_logic; -- /ras
+signal cas_qn_p : std_logic; -- /cas
+signal we_qn_p : std_logic; -- /write enable
+signal dm_q_p : std_logic_vector(1 downto 0); -- data mask bits, set to "00"
+signal dqs_q_p : std_logic_vector(1 downto 0); -- data strobe, only for write
+signal ba_q_p : std_logic_vector(1 downto 0); -- bank select
+signal sdr_a_p : std_logic_vector(12 downto 0); -- address bus
+signal sdr_d_p : std_logic_vector(15 downto 0); -- bidir data bus
+
+constant min_time : time := 1.875 ns;
+
+begin
+
+ clock1:
+ process
+ begin
+ loop
+ cpu_clk_4x <= '1';
+ wait for min_time;
+ cpu_clk_4x <= '0';
+ wait for min_time;
+ end loop;
+ end process;
+
+ clock2:
+ process
+ begin
+ loop
+ cpu_clk_2x <= '1' after 100 ps;
+ wait until rising_edge(cpu_clk_4x);
+ cpu_clk_2x <= '0' after 100 ps;
+ wait until rising_edge(cpu_clk_4x);
+ end loop;
+ end process;
+
+ clock3:
+ process
+ begin
+ loop
+ cpu_clk <= '1' after 100 ps;
+ wait until rising_edge(cpu_clk_2x);
+ cpu_clk <= '0' after 100 ps;
+ wait until rising_edge(cpu_clk_2x);
+ end loop;
+ end process;
+
+ ddr_in_clk_2x <= cpu_clk_4x after 1 ns;
+
+ clock4:
+ process
+ begin
+ loop
+ ddr_in_clk <= '0' after 100 ps;
+ wait until rising_edge(ddr_in_clk_2x);
+ ddr_in_clk <= '1' after 100 ps;
+ wait until rising_edge(ddr_in_clk_2x);
+ end loop;
+ end process;
+
+ inputdata:
+ process
+ begin
+ -- Wait until global reset released
+ loop
+ ddr_command <= x"0000";
+ ddr_command_we <= '0';
+ ddr_data_write <= x"000000000";
+ ddr_req <= '0';
+ ddr_req_adr <= "00000000000000000000000";
+ ddr_rd_wr_n <= '0';
+ ddr_req_len <= '0';
+ break_out <= '0';
+ refresh_en <= '0';
+
+ wait until falling_edge(areset);
+
+ -- DDR initialization sequence
+ -- Wait more than 200 us
+ wait for 201000 ns;
+
+ -- Send precharge command
+ wait until rising_edge(cpu_clk);
+ ddr_command <= x"8000";
+ ddr_command_we <= '1';
+ wait until rising_edge(cpu_clk);
+ ddr_command <= x"0000";
+ ddr_command_we <= '0';
+
+ -- Wait for 1 us
+ wait for 1000 ns;
+
+ -- Load extended mode register
+ -- Enable DLL
+ -- Normal drive strength
+ wait until rising_edge(cpu_clk);
+ ddr_command <= x"2000";
+ ddr_command_we <= '1';
+ wait until rising_edge(cpu_clk);
+ ddr_command <= x"0000";
+ ddr_command_we <= '0';
+
+ -- Wait for 1 us
+ wait for 1000 ns;
+
+ -- Load mode register
+ -- Burst length: 2
+ -- Burst type: Sequential
+ -- Cas latency: 2
+ -- Reset DLL
+ wait until rising_edge(cpu_clk);
+ ddr_command <= x"0121";
+ ddr_command_we <= '1';
+ wait until rising_edge(cpu_clk);
+ ddr_command <= x"0000";
+ ddr_command_we <= '0';
+
+ -- Wait for 1 us
+ wait for 1000 ns;
+
+ -- Send precharge command
+ wait until rising_edge(cpu_clk);
+ ddr_command <= x"8000";
+ ddr_command_we <= '1';
+ wait until rising_edge(cpu_clk);
+ ddr_command <= x"0000";
+ ddr_command_we <= '0';
+
+ -- Enable refresh
+ refresh_en <= '1';
+
+ -- Wait 30 us (minimum 2 autorefresh cycles)
+ wait for 30000 ns;
+
+ -- Load mode register
+ -- Burst length: 2
+ -- Burst type: Sequential
+ -- Cas latency: 2
+ -- Deactivate Reset DLL
+ wait until rising_edge(cpu_clk);
+ ddr_command <= x"0021";
+ ddr_command_we <= '1';
+ wait until rising_edge(cpu_clk);
+ ddr_command <= x"0000";
+ ddr_command_we <= '0';
+
+ -- Wait for 2 us (DLL stable)
+ wait for 2000 ns;
+
+ -- Write data to DDR
+ wait until rising_edge(cpu_clk_2x);
+ ddr_data_write <= x"312345678";
+ ddr_req <= '1';
+ ddr_req_adr <= "00000000000000000000000";
+ ddr_rd_wr_n <= '0';
+ ddr_req_len <= '0';
+ wait until rising_edge(ddr_write_en);
+ wait until rising_edge(cpu_clk_2x);
+ ddr_req <= '0';
+ ddr_req_adr <= "00000000000000000000000";
+ ddr_rd_wr_n <= '0';
+ ddr_req_len <= '0';
+ ddr_data_write <= x"000000000";
+ wait for 100 ns;
+
+ -- Read data from DDR
+ wait until rising_edge(cpu_clk_2x);
+ ddr_req <= '1';
+ ddr_req_adr <= "00000000000000000000000";
+ ddr_rd_wr_n <= '1';
+ ddr_req_len <= '0';
+ wait until rising_edge(ddr_req_ack);
+ wait until rising_edge(cpu_clk_2x);
+ ddr_req <= '0';
+ ddr_req_adr <= "00000000000000000000000";
+ ddr_rd_wr_n <= '0';
+ ddr_req_len <= '0';
+ ddr_data_write <= x"000000000";
+
+
+
+ wait for 100 ns;
+ break_out <= '1';
+ wait for 100 ns;
+
+ end loop;
+
+ end process;
+
+ ddr_ctrl:
+ ddr_top port map(
+ areset => areset,
+ cpu_clk => cpu_clk,
+ cpu_clk_2x => cpu_clk_2x,
+ cpu_clk_4x => cpu_clk_4x,
+ ddr_in_clk => ddr_in_clk,
+ ddr_in_clk_2x => ddr_in_clk_2x,
+
+ -- Command interface
+ ddr_command => ddr_command,
+ ddr_command_we => ddr_command_we,
+ refresh_en => refresh_en,
+
+ -- Data interface signals
+ ddr_data_read => ddr_data_read,
+ ddr_data_write => ddr_data_write,
+ ddr_req_adr => ddr_req_adr,
+ ddr_req => ddr_req,
+ ddr_req_ack => ddr_req_ack,
+ ddr_busy => ddr_busy,
+ ddr_rd_wr_n => ddr_rd_wr_n,
+ ddr_req_len => ddr_req_len,
+ ddr_read_en => ddr_read_en,
+ ddr_write_en => ddr_write_en,
+ -- DDR SDRAM Signals
+ sdr_clk_p => sdr_clk_p,
+ sdr_clk_n_p => sdr_clk_n_p,
+ cke_q_p => cke_q_p,
+ cs_qn_p => cs_qn_p,
+ ras_qn_p => ras_qn_p,
+ cas_qn_p => cas_qn_p,
+ we_qn_p => we_qn_p,
+ dm_q_p => dm_q_p,
+ dqs_q_p => dqs_q_p,
+ ba_q_p => ba_q_p,
+ sdr_a_p => sdr_a_p,
+ sdr_d_p => sdr_d_p);
+
+ myram:
+ MT46V16M16 generic map(
+ tCK => 7.500 ns,
+ tCH => 3.375 ns, -- 0.45*tCK
+ tCL => 3.375 ns, -- 0.45*tCK
+ tDH => 0.500 ns,
+ tDS => 0.500 ns,
+ tIH => 0.900 ns,
+ tIS => 0.900 ns,
+ tMRD => 15.000 ns,
+ tRAS => 40.000 ns,
+ tRAP => 20.000 ns,
+ tRC => 65.000 ns,
+ tRFC => 75.000 ns,
+ tRCD => 20.000 ns,
+ tRP => 20.000 ns,
+ tRRD => 15.000 ns,
+ tWR => 15.000 ns,
+ addr_bits => 13,
+ data_bits => 16,
+ cols_bits => 9)
+ port map(
+ Dq => sdr_d_p,
+ Dqs => dqs_q_p,
+ Addr => sdr_a_p,
+ Ba => ba_q_p,
+ Clk => sdr_clk_p,
+ Clk_n => sdr_clk_n_p,
+ Cke => cke_q_p,
+ Cs_n => cs_qn_p,
+ Ras_n => ras_qn_p,
+ Cas_n => cas_qn_p,
+ We_n => we_qn_p,
+ Dm => dm_q_p);
+
+end behave;
diff --git a/misc/ddrsdram/src/ddr_pkg.vhd b/misc/ddrsdram/src/ddr_pkg.vhd
index 0e41a88..af4a705 100644
--- a/misc/ddrsdram/src/ddr_pkg.vhd
+++ b/misc/ddrsdram/src/ddr_pkg.vhd
@@ -1,107 +1,107 @@
-library IEEE;
-use IEEE.STD_LOGIC_1164.all;
-use IEEE.STD_LOGIC_UNSIGNED.ALL;
-
-package ddr is
-
- function mirror_bus32 ( org_sig : std_logic_vector) return std_logic_vector;
- function mirror_bus4 ( org_sig : std_logic_vector) return std_logic_vector;
-
- component ddr_top
- generic(
- simulate_io_time : boolean := false);
- port ( -- Asyncronous reset and clocks
- areset : in std_logic;
- cpu_clk : in std_logic;
- cpu_clk_2x : in std_logic;
- cpu_clk_4x : in std_logic;
- ddr_in_clk : in std_logic;
- ddr_in_clk_2x : in std_logic;
-
- -- Command interface
- ddr_command : in std_logic_vector(15 downto 0);
- ddr_command_we : in std_logic;
- refresh_en : in std_logic;
-
-
- -- Data interface signals
- ddr_data_read : out std_logic_vector(31 downto 0); -- Data read from DDR SDRAM
- ddr_data_write : in std_logic_vector(35 downto 0); -- Data to be written to DDR SDRAM
- ddr_req_adr : in std_logic_vector(25 downto 1); -- Request address
- ddr_req : in std_logic; -- Request DDR SDRAM access
- ddr_busy : out std_logic; -- Request acknowledge
- ddr_rd_wr_n : in std_logic; -- Access type 1=READ, 0=WRITE
- ddr_req_len : in std_logic; -- Number of 16-bits words to transfer (0=2, 1=8)
- ddr_read_en : out std_logic; -- Enable signal for read data
- ddr_write_en : out std_logic; -- Enable (read) signal for data write
-
- -- DDR SDRAM Signals
- sdr_clk_p : out std_logic; -- ddr_sdram_clock
- sdr_clk_n_p : out std_logic; -- /ddr_sdram_clock
- cke_q_p : out std_logic; -- clock enable
- cs_qn_p : out std_logic; -- /chip select
- ras_qn_p : inout std_logic; -- /ras
- cas_qn_p : inout std_logic; -- /cas
- we_qn_p : inout std_logic; -- /write enable
- dm_q_p : out std_logic_vector(1 downto 0); -- data mask bits, set to "00"
- dqs_q_p : out std_logic_vector(1 downto 0); -- data strobe, only for write
- ba_q_p : out std_logic_vector(1 downto 0); -- bank select
- sdr_a_p : out std_logic_vector(12 downto 0); -- address bus
- sdr_d_p : inout std_logic_vector(15 downto 0)); -- bidir data bus
- end component;
-
- component MT46V16M16
- GENERIC ( -- Timing for -75Z CL2
- tCK : TIME := 7.500 ns;
- tCH : TIME := 3.375 ns; -- 0.45*tCK
- tCL : TIME := 3.375 ns; -- 0.45*tCK
- tDH : TIME := 0.500 ns;
- tDS : TIME := 0.500 ns;
- tIH : TIME := 0.900 ns;
- tIS : TIME := 0.900 ns;
- tMRD : TIME := 15.000 ns;
- tRAS : TIME := 40.000 ns;
- tRAP : TIME := 20.000 ns;
- tRC : TIME := 65.000 ns;
- tRFC : TIME := 75.000 ns;
- tRCD : TIME := 20.000 ns;
- tRP : TIME := 20.000 ns;
- tRRD : TIME := 15.000 ns;
- tWR : TIME := 15.000 ns;
- addr_bits : INTEGER := 13;
- data_bits : INTEGER := 16;
- cols_bits : INTEGER := 9
- );
- PORT (
- Dq : INOUT STD_LOGIC_VECTOR (data_bits - 1 DOWNTO 0) := (OTHERS => 'Z');
- Dqs : INOUT STD_LOGIC_VECTOR (1 DOWNTO 0) := "ZZ";
- Addr : IN STD_LOGIC_VECTOR (addr_bits - 1 DOWNTO 0);
- Ba : IN STD_LOGIC_VECTOR (1 DOWNTO 0);
- Clk : IN STD_LOGIC;
- Clk_n : IN STD_LOGIC;
- Cke : IN STD_LOGIC;
- Cs_n : IN STD_LOGIC;
- Ras_n : IN STD_LOGIC;
- Cas_n : IN STD_LOGIC;
- We_n : IN STD_LOGIC;
- Dm : IN STD_LOGIC_VECTOR (1 DOWNTO 0)
- );
- end component;
-
-end;
-
-package body ddr is
-
- function mirror_bus32 ( org_sig : std_logic_vector) return std_logic_vector is
- begin
- return (org_sig(7 downto 0) & org_sig(15 downto 8) & org_sig(23 downto 16) & org_sig(31 downto 24));
- end function mirror_bus32;
-
- function mirror_bus4 ( org_sig : std_logic_vector) return std_logic_vector is
- begin
- return (org_sig(0) & org_sig(1) & org_sig(2) & org_sig(3));
- end function mirror_bus4;
-
-end package body;
-
+library IEEE;
+use IEEE.STD_LOGIC_1164.all;
+use IEEE.STD_LOGIC_UNSIGNED.ALL;
+
+package ddr is
+
+ function mirror_bus32 ( org_sig : std_logic_vector) return std_logic_vector;
+ function mirror_bus4 ( org_sig : std_logic_vector) return std_logic_vector;
+
+ component ddr_top
+ generic(
+ simulate_io_time : boolean := false);
+ port ( -- Asyncronous reset and clocks
+ areset : in std_logic;
+ cpu_clk : in std_logic;
+ cpu_clk_2x : in std_logic;
+ cpu_clk_4x : in std_logic;
+ ddr_in_clk : in std_logic;
+ ddr_in_clk_2x : in std_logic;
+
+ -- Command interface
+ ddr_command : in std_logic_vector(15 downto 0);
+ ddr_command_we : in std_logic;
+ refresh_en : in std_logic;
+
+
+ -- Data interface signals
+ ddr_data_read : out std_logic_vector(31 downto 0); -- Data read from DDR SDRAM
+ ddr_data_write : in std_logic_vector(35 downto 0); -- Data to be written to DDR SDRAM
+ ddr_req_adr : in std_logic_vector(25 downto 1); -- Request address
+ ddr_req : in std_logic; -- Request DDR SDRAM access
+ ddr_busy : out std_logic; -- Request acknowledge
+ ddr_rd_wr_n : in std_logic; -- Access type 1=READ, 0=WRITE
+ ddr_req_len : in std_logic; -- Number of 16-bits words to transfer (0=2, 1=8)
+ ddr_read_en : out std_logic; -- Enable signal for read data
+ ddr_write_en : out std_logic; -- Enable (read) signal for data write
+
+ -- DDR SDRAM Signals
+ sdr_clk_p : out std_logic; -- ddr_sdram_clock
+ sdr_clk_n_p : out std_logic; -- /ddr_sdram_clock
+ cke_q_p : out std_logic; -- clock enable
+ cs_qn_p : out std_logic; -- /chip select
+ ras_qn_p : inout std_logic; -- /ras
+ cas_qn_p : inout std_logic; -- /cas
+ we_qn_p : inout std_logic; -- /write enable
+ dm_q_p : out std_logic_vector(1 downto 0); -- data mask bits, set to "00"
+ dqs_q_p : out std_logic_vector(1 downto 0); -- data strobe, only for write
+ ba_q_p : out std_logic_vector(1 downto 0); -- bank select
+ sdr_a_p : out std_logic_vector(12 downto 0); -- address bus
+ sdr_d_p : inout std_logic_vector(15 downto 0)); -- bidir data bus
+ end component;
+
+ component MT46V16M16
+ GENERIC ( -- Timing for -75Z CL2
+ tCK : TIME := 7.500 ns;
+ tCH : TIME := 3.375 ns; -- 0.45*tCK
+ tCL : TIME := 3.375 ns; -- 0.45*tCK
+ tDH : TIME := 0.500 ns;
+ tDS : TIME := 0.500 ns;
+ tIH : TIME := 0.900 ns;
+ tIS : TIME := 0.900 ns;
+ tMRD : TIME := 15.000 ns;
+ tRAS : TIME := 40.000 ns;
+ tRAP : TIME := 20.000 ns;
+ tRC : TIME := 65.000 ns;
+ tRFC : TIME := 75.000 ns;
+ tRCD : TIME := 20.000 ns;
+ tRP : TIME := 20.000 ns;
+ tRRD : TIME := 15.000 ns;
+ tWR : TIME := 15.000 ns;
+ addr_bits : INTEGER := 13;
+ data_bits : INTEGER := 16;
+ cols_bits : INTEGER := 9
+ );
+ PORT (
+ Dq : INOUT STD_LOGIC_VECTOR (data_bits - 1 DOWNTO 0) := (OTHERS => 'Z');
+ Dqs : INOUT STD_LOGIC_VECTOR (1 DOWNTO 0) := "ZZ";
+ Addr : IN STD_LOGIC_VECTOR (addr_bits - 1 DOWNTO 0);
+ Ba : IN STD_LOGIC_VECTOR (1 DOWNTO 0);
+ Clk : IN STD_LOGIC;
+ Clk_n : IN STD_LOGIC;
+ Cke : IN STD_LOGIC;
+ Cs_n : IN STD_LOGIC;
+ Ras_n : IN STD_LOGIC;
+ Cas_n : IN STD_LOGIC;
+ We_n : IN STD_LOGIC;
+ Dm : IN STD_LOGIC_VECTOR (1 DOWNTO 0)
+ );
+ end component;
+
+end;
+
+package body ddr is
+
+ function mirror_bus32 ( org_sig : std_logic_vector) return std_logic_vector is
+ begin
+ return (org_sig(7 downto 0) & org_sig(15 downto 8) & org_sig(23 downto 16) & org_sig(31 downto 24));
+ end function mirror_bus32;
+
+ function mirror_bus4 ( org_sig : std_logic_vector) return std_logic_vector is
+ begin
+ return (org_sig(0) & org_sig(1) & org_sig(2) & org_sig(3));
+ end function mirror_bus4;
+
+end package body;
+
\ No newline at end of file
diff --git a/misc/ddrsdram/src/ddr_top.vhd b/misc/ddrsdram/src/ddr_top.vhd
index 033e9f8..2aceae9 100644
--- a/misc/ddrsdram/src/ddr_top.vhd
+++ b/misc/ddrsdram/src/ddr_top.vhd
@@ -1,743 +1,743 @@
-library IEEE;
-use IEEE.STD_LOGIC_1164.all;
-use IEEE.STD_LOGIC_UNSIGNED.ALL;
-
-library UNISIM;
-use UNISIM.vcomponents.all;
-
-entity ddr_top is
- generic(
- simulate_io_time : boolean := false);
- port ( -- Asyncronous reset and clocks
- areset : in std_logic;
- cpu_clk : in std_logic;
- cpu_clk_2x : in std_logic;
- cpu_clk_4x : in std_logic;
- ddr_in_clk : in std_logic;
- ddr_in_clk_2x : in std_logic;
-
- -- Command interface
- ddr_command : in std_logic_vector(15 downto 0);
- ddr_command_we : in std_logic;
- refresh_en : in std_logic;
-
- -- Data interface signals
- ddr_data_read : out std_logic_vector(31 downto 0); -- Data read from DDR SDRAM
- ddr_data_write : in std_logic_vector(35 downto 0); -- Data to be written to DDR SDRAM
- ddr_req_adr : in std_logic_vector(25 downto 1); -- Request address
- ddr_req : in std_logic; -- Request DDR SDRAM access
- ddr_busy : out std_logic; -- Request acknowledge
- ddr_rd_wr_n : in std_logic; -- Access type 1=READ, 0=WRITE
- ddr_req_len : in std_logic; -- Number of 16-bits words to transfer (0=2, 1=8)
- ddr_read_en : out std_logic; -- Enable signal for read data
- ddr_write_en : out std_logic; -- Enable (read) signal for data write
-
- -- DDR SDRAM Signals
- sdr_clk_p : out std_logic; -- ddr_sdram_clock
- sdr_clk_n_p : out std_logic; -- /ddr_sdram_clock
- cke_q_p : out std_logic; -- clock enable
- cs_qn_p : out std_logic; -- /chip select
- ras_qn_p : inout std_logic; -- /ras
- cas_qn_p : inout std_logic; -- /cas
- we_qn_p : inout std_logic; -- /write enable
- dm_q_p : out std_logic_vector(1 downto 0); -- data mask bits, set to "00"
- dqs_q_p : out std_logic_vector(1 downto 0); -- data strobe, only for write
- ba_q_p : out std_logic_vector(1 downto 0); -- bank select
- sdr_a_p : out std_logic_vector(12 downto 0); -- address bus
- sdr_d_p : inout std_logic_vector(15 downto 0)); -- bidir data bus
-end ddr_top;
-
-architecture behave of ddr_top is
-
-attribute keep : string;
-
-type clk4_type is array(0 to 15) of std_logic_vector(1 downto 0);
-
-signal cpu_clk_tog : std_logic;
-signal ddr_cmd : std_logic_vector(15 downto 0);
-signal ddr_cmd_we_smp : std_logic;
-signal new_command : std_logic;
-
-signal cpu_clk_2x_smp1 : std_logic;
-signal cpu_clk_2x_smp2 : std_logic;
-signal cpu_clk_4x_smp1 : std_logic;
-signal cpu_clk_4x_smp2 : std_logic;
-
-signal clk2_phase : std_logic;
-signal clk4_phase : std_logic_vector(3 downto 0);
-signal clk4_phase_short : clk4_type;
-attribute keep of clk4_phase_short:signal is "true";
-
-signal ddr_clk_tog : std_logic;
-signal ddr_clk_smp1 : std_logic;
-signal ddr_clk_smp2 : std_logic;
-signal ddr_clk_phase : std_logic;
-
-signal smp_req_adr : std_logic_vector(25 downto 1);
-signal smp_req_type : std_logic;
-signal smp_req_len : std_logic;
-signal ddr_write_en_int : std_logic;
-signal ddr_read_en_int : std_logic;
-
-signal dqs_q : std_logic_vector(1 downto 0);
-signal dqs_oe_n : std_logic_vector(1 downto 0);
-attribute keep of dqs_oe_n:signal is "true";
-signal cas_qn : std_logic;
-signal ras_qn : std_logic;
-signal we_qn : std_logic;
-signal ba_q : std_logic_vector(1 downto 0);
-signal sdr_clk : std_logic;
-signal sdr_clk_n : std_logic;
-signal sdr_a : std_logic_vector(12 downto 0);
-signal sdr_d : std_logic_vector(15 downto 0);
-signal sdr_smp : std_logic_vector(35 downto 0);
-signal sdr_oe_n : std_logic_vector(15 downto 0);
-attribute keep of sdr_oe_n:signal is "true";
-signal sdr_oe_ctrl : std_logic_vector(15 downto 0);
-attribute keep of sdr_oe_ctrl:signal is "true";
-signal sdr_wr_msw : std_logic_vector(17 downto 0);
-attribute keep of sdr_wr_msw:signal is "true";
-signal dm_q : std_logic_vector(1 downto 0);
-
-signal nowin_idle_dqs : std_logic_vector(1 downto 0);
-signal nowin_wr_nop1_d : std_logic_vector(15 downto 0);
-signal nowin_wr_nop1_dqs : std_logic_vector(1 downto 0);
-signal nowin_wr_nop1_dm : std_logic_vector(1 downto 0);
-signal nowin_wr_nop2_dqs : std_logic_vector(1 downto 0);
-signal nowin_wr_nop3_d : std_logic_vector(15 downto 0);
-signal nowin_wr_nop3_dqs : std_logic_vector(1 downto 0);
-attribute keep of nowin_idle_dqs:signal is "true";
-attribute keep of nowin_wr_nop1_d:signal is "true";
-attribute keep of nowin_wr_nop1_dqs:signal is "true";
-attribute keep of nowin_wr_nop1_dm:signal is "true";
-attribute keep of nowin_wr_nop2_dqs:signal is "true";
-attribute keep of nowin_wr_nop3_d:signal is "true";
-attribute keep of nowin_wr_nop3_dqs:signal is "true";
-
-signal cas_n_smp : std_logic;
-signal ras_n_smp : std_logic;
-signal we_n_smp : std_logic;
-signal read_start_sig : std_logic;
-signal sdr_d_in : std_logic_vector(15 downto 0);
-signal read_time_cnt : std_logic_vector(1 downto 0);
-signal read_input_en : std_logic;
-signal read_input_en_del : std_logic;
-signal ddr_data_read_int : std_logic_vector(31 downto 0);
-
-signal refresh_pend : std_logic;
-signal refresh_end : std_logic;
-signal refresh_cnt : std_logic_vector(9 downto 0);
-signal refresh_wait_cnt : std_logic_vector(3 downto 0);
-signal refresh_wait_end : std_logic;
-
-signal cas_qn_p_del : std_logic;
-signal ras_qn_p_del : std_logic;
-signal we_qn_p_del : std_logic;
-signal sdr_d_p_del : std_logic_vector(15 downto 0);
-
-signal saved_row : std_logic_vector(26 downto 11);
-signal operation : std_logic_vector(1 downto 0);
-
-signal ddr_req_adr_int : std_logic_vector(25 downto 1);
-
-type state_type is (idle, act, act_nop1, act_nop2, rd_wr, rd_nop1,
- rd_nop2,rd_nop3,rd_nop4, rd_nop5,pre, pre_nop1, pre_nop2, wr_nop1, wr_nop2,
- wr_nop3, cmd, cpu_pre, refresh, refresh_wait);
-signal ddr_state : state_type;
-
-constant Clk_to_Output : time := 2.2 ns;
-constant Input_Setup : time := 2.5 ns;
-
-constant Refresh_Interval : std_logic_vector(9 downto 0) := "1111100110";
-
-begin
-
- iotimingon:
- if simulate_io_time generate
- begin
- cas_qn_p_del <= 'X' after 0 ns, cas_qn_p after Input_Setup;
- ras_qn_p_del <= 'X' after 0 ns, ras_qn_p after Input_Setup;
- we_qn_p_del <= 'X' after 0 ns, we_qn_p after Input_Setup;
- sdr_d_p_del <= "XXXXXXXXXXXXXXXX" after 0 ns, sdr_d_p after Input_Setup;
- end generate;
-
- iotimingoff:
- if not simulate_io_time generate
- begin
- cas_qn_p_del <= cas_qn_p;
- ras_qn_p_del <= ras_qn_p;
- we_qn_p_del <= we_qn_p;
- sdr_d_p_del <= sdr_d_p;
- end generate;
-
- ddr_write_en <= ddr_write_en_int;
- ddr_read_en <= ddr_read_en_int;
- ddr_data_read <= ddr_data_read_int;
-
- ddr_req_adr_int <= (ddr_req_adr(24 downto 10) & '0' & ddr_req_adr(9 downto 1)) when (simulate_io_time) else ddr_req_adr;
-
- process(cpu_clk, areset) -- Toggle a flip-flop with cpu_clk, in order
- begin -- to find phase relation with 2x and 4x clocks
- if areset = '1' then
- cpu_clk_tog <= '0';
- elsif (cpu_clk'event and cpu_clk = '1') then
- cpu_clk_tog <= not(cpu_clk_tog);
- end if;
- end process;
-
- process(cpu_clk_2x, areset) -- Find phase relation between cpu_clk and cpu_clk_2x
- begin
- if areset = '1' then
- cpu_clk_2x_smp1 <= '0';
- cpu_clk_2x_smp2 <= '0';
- clk2_phase <= '0';
- elsif (cpu_clk_2x'event and cpu_clk_2x = '1') then
- cpu_clk_2x_smp1 <= cpu_clk_tog;
- cpu_clk_2x_smp2 <= cpu_clk_2x_smp1;
- if (cpu_clk_2x_smp1 = '1' and cpu_clk_2x_smp2 = '0') then
- clk2_phase <= '0';
- else
- clk2_phase <= not(clk2_phase);
- end if;
- end if;
- end process;
-
- process(cpu_clk_4x, areset) -- Find phase relation between cpu_clk and cpu_clk_4x
- begin
- if areset = '1' then
- cpu_clk_4x_smp1 <= '0';
- cpu_clk_4x_smp2 <= '0';
- clk4_phase <= "0000";
- clk4_phase_short(0) <= "00";
- clk4_phase_short(1) <= "00";
- clk4_phase_short(2) <= "00";
- clk4_phase_short(3) <= "00";
- clk4_phase_short(4) <= "00";
- clk4_phase_short(5) <= "00";
- clk4_phase_short(6) <= "00";
- clk4_phase_short(7) <= "00";
- clk4_phase_short(8) <= "00";
- clk4_phase_short(9) <= "00";
- clk4_phase_short(10) <= "00";
- clk4_phase_short(11) <= "00";
- clk4_phase_short(12) <= "00";
- clk4_phase_short(13) <= "00";
- clk4_phase_short(14) <= "00";
- clk4_phase_short(15) <= "00";
- elsif (cpu_clk_4x'event and cpu_clk_4x = '1') then
- cpu_clk_4x_smp1 <= cpu_clk_tog;
- cpu_clk_4x_smp2 <= cpu_clk_4x_smp1;
- for i in 0 to 15 loop
- if (cpu_clk_4x_smp1 = '1' and cpu_clk_4x_smp2 = '0') then
- clk4_phase <= "0100";
- clk4_phase_short(i) <= "01";
- else
- clk4_phase <= (clk4_phase(2 downto 0) & clk4_phase(3));
- clk4_phase_short(i) <= clk4_phase_short(i)(0) & clk4_phase_short(i)(1);
- end if;
- end loop;
- end if;
- end process;
-
- process(cpu_clk_4x, areset) --
- begin
- if areset = '1' then
- sdr_clk <= '0';
- sdr_clk_n <= '0';
- elsif (cpu_clk_4x'event and cpu_clk_4x = '1') then
- if clk4_phase_short(0)(0) = '1' then
- sdr_clk <= '1';
- else
- sdr_clk <= '0';
- end if;
- if clk4_phase_short(0)(1) = '1' then
- sdr_clk_n <= '1';
- else
- sdr_clk_n <= '0';
- end if;
- end if;
- end process;
-
- cke_q_p <= '1' after Clk_to_Output;
- cs_qn_p <= '0' after Clk_to_Output;
-
- process(cpu_clk_4x, areset) --
- begin
- if areset = '1' then
- ras_qn_p <= '1';
- cas_qn_p <= '1';
- we_qn_p <= '1';
- dqs_q_p <= "ZZ";
- sdr_a_p <= "0000000000000";
- ba_q_p <= "00";
- sdr_clk_p <= '0';
- sdr_clk_n_p <= '1';
- elsif (cpu_clk_4x'event and cpu_clk_4x = '1') then
- ras_qn_p <= transport ras_qn after Clk_to_Output;
- cas_qn_p <= transport cas_qn after Clk_to_Output;
- we_qn_p <= transport we_qn after Clk_to_Output;
- if dqs_oe_n(0) = '0' then
- dqs_q_p(0) <= transport dqs_q(0) after Clk_to_Output;
- else
- dqs_q_p(0) <= transport 'Z' after Clk_to_Output;
- end if;
- if dqs_oe_n(1) = '0' then
- dqs_q_p(1) <= transport dqs_q(1) after Clk_to_Output;
- else
- dqs_q_p(1) <= transport 'Z' after Clk_to_Output;
- end if;
- sdr_a_p <= transport sdr_a after Clk_to_Output;
- ba_q_p <= transport ba_q after Clk_to_Output;
- sdr_clk_p <= transport sdr_clk after Clk_to_Output;
- sdr_clk_n_p <= transport sdr_clk_n after Clk_to_Output;
- end if;
- end process;
-
- process(cpu_clk_2x, areset) --
- begin
- if areset = '1' then
- ddr_state <= idle;
- ras_qn <= '1';
- cas_qn <= '1';
- we_qn <= '1';
- smp_req_adr <= (others => '0');
- smp_req_type <= '0';
- smp_req_len <= '0';
- sdr_a <= "XXXXXXXXXXXXX";
- ba_q <= "00";
- ddr_busy <= '1';
- saved_row <= "1000000000000000";
- ddr_write_en_int <= '0';
- ddr_read_en_int <= '0';
- nowin_idle_dqs <= "11";
- nowin_wr_nop1_d <= "0000000000000000";
- nowin_wr_nop1_dqs <= "00";
- nowin_wr_nop1_dm <= "00";
- nowin_wr_nop2_dqs <= "00";
- nowin_wr_nop3_d <= "0000000000000000";
- nowin_wr_nop3_dqs <= "00";
- elsif (cpu_clk_2x'event and cpu_clk_2x = '1') then
-
- -- Default values
- ras_qn <= '1';
- cas_qn <= '1';
- we_qn <= '1';
- sdr_a <= "XXXXXXXXXXXXX";
- ddr_busy <= '1';
- ddr_write_en_int <= '0';
- ddr_read_en_int <= '0';
-
- nowin_idle_dqs <= "00";
- nowin_wr_nop1_d <= "0000000000000000";
- nowin_wr_nop1_dqs <= "00";
- nowin_wr_nop1_dm <= "00";
- nowin_wr_nop2_dqs <= "00";
- nowin_wr_nop3_d <= "0000000000000000";
- nowin_wr_nop3_dqs <= "00";
-
- case ddr_state is
- when idle =>
- smp_req_adr <= ddr_req_adr_int;
- smp_req_type <= ddr_rd_wr_n;
- smp_req_len <= ddr_req_len;
- ddr_busy <= '0';
- operation <= "00";
- if refresh_pend = '1' then
- operation <= "01";
- ddr_state <= pre;
- elsif new_command = '1' then
- if ddr_cmd(15) = '1' then
- operation <= "10";
- ddr_state <= cpu_pre;
- else
- ddr_state <= cmd;
- end if;
- elsif (ddr_req = '1' and ddr_req_adr_int(25 downto 11) = saved_row(25 downto 11) and saved_row(26) = '0') then
- operation <= "11";
- ddr_write_en_int <= not(ddr_rd_wr_n);
- ddr_state <= rd_wr;
- elsif ddr_req = '1' then
- operation <= "11";
- ddr_state <= pre;
- else
- ddr_state <= idle;
- nowin_idle_dqs <= "11";
- end if;
- when act =>
- sdr_a <= smp_req_adr(23 downto 11);
- ba_q <= smp_req_adr(25 downto 24);
- ras_qn <= '0';
- ddr_write_en_int <= not(smp_req_type);
- ddr_state <= act_nop1;
- when act_nop1 =>
- ddr_state <= act_nop2;
- when act_nop2 =>
- ddr_state <= rd_wr;
- when rd_wr =>
- sdr_a(10) <= '0'; -- Disable auto precharge
- sdr_a(9 downto 0) <= smp_req_adr(10 downto 1);
- ba_q <= smp_req_adr(25 downto 24);
- saved_row <= '0' & smp_req_adr(25 downto 11);
- cas_qn <= '0';
- we_qn <= smp_req_type;
- if smp_req_type = '1' then
- ddr_state <= rd_nop1;
- else
- ddr_state <= wr_nop1;
- nowin_wr_nop1_d <= "1111111111111111";
- nowin_wr_nop1_dqs <= "11";
- nowin_wr_nop1_dm <= "11";
- end if;
- when wr_nop1 =>
- ddr_state <= wr_nop2;
- nowin_wr_nop2_dqs <= "11";
- when wr_nop2 =>
- ddr_state <= wr_nop3;
- nowin_wr_nop3_d <= "1111111111111111";
- nowin_wr_nop3_dqs <= "11";
- when wr_nop3 =>
- nowin_idle_dqs <= "11";
- ddr_state <= idle;
- when rd_nop1 =>
- ddr_state <= rd_nop2;
- when rd_nop2 =>
- if operation /= "11" then
- nowin_idle_dqs <= "11";
- ddr_state <= idle;
- else
- ddr_state <= rd_nop3;
- end if;
- when rd_nop3 =>
- ddr_state <= rd_nop4;
- when rd_nop4 =>
- ddr_read_en_int <= '1';
- ddr_state <= rd_nop5;
- when rd_nop5 =>
- nowin_idle_dqs <= "11";
- ddr_state <= idle;
- when pre =>
- ras_qn <= '0';
- we_qn <= '0';
- sdr_a(10) <= '1'; -- Precharge all banks
- ba_q <= smp_req_adr(25 downto 24);
- ddr_state <= pre_nop1;
- when pre_nop1 =>
- ddr_state <= pre_nop2;
- when cmd =>
- cas_qn <= '0';
- ras_qn <= '0';
- we_qn <= '0';
- ba_q <= ddr_cmd(14 downto 13);
- sdr_a <= ddr_cmd(12 downto 0);
- nowin_idle_dqs <= "11";
- ddr_state <= idle;
- when cpu_pre =>
- ddr_state <= pre;
- when refresh =>
- cas_qn <= '0';
- ras_qn <= '0';
- saved_row(26) <= '1';
- ddr_state <= refresh_wait;
- when refresh_wait =>
- if refresh_wait_end = '1' then
- ddr_state <= pre_nop2;
- end if;
- when pre_nop2 =>
- if operation = "01" then
- operation <= "10";
- ddr_state <= refresh;
- elsif operation = "10" then
- nowin_idle_dqs <= "11";
- ddr_state <= idle;
- else
- ddr_state <= act;
- end if;
- when others =>
- ddr_state <= idle;
- nowin_idle_dqs <= "11";
- end case;
- end if;
- end process;
-
- process(cpu_clk, areset) --
- begin
- if areset = '1' then
- ddr_cmd <= "0000000000000000";
- elsif (cpu_clk'event and cpu_clk = '1') then
- if ddr_command_we = '1' then
- ddr_cmd <= ddr_command;
- else
- ddr_cmd <= ddr_cmd;
- end if;
- end if;
- end process;
-
- process(cpu_clk_2x, areset) --
- begin
- if areset = '1' then
- ddr_cmd_we_smp <= '0';
- new_command <= '0';
- sdr_smp <= "000000000000000000000000000000000000";
- elsif (cpu_clk_2x'event and cpu_clk_2x = '1') then
- ddr_cmd_we_smp <= ddr_command_we;
- if ddr_command_we = '0' and ddr_cmd_we_smp = '1' then
- new_command <= '1';
- elsif ddr_state = cmd or ddr_state = cpu_pre then
- new_command <= '0';
- else
- new_command <= new_command;
- end if;
-
- if ddr_write_en_int = '1' then
- sdr_smp <= ddr_data_write;
- else
- sdr_smp <= sdr_smp;
- end if;
-
- end if;
- end process;
-
- process(cpu_clk_4x, areset) --
- begin
- if areset = '1' then
- dqs_q <= "00";
- dqs_oe_n <= "11";
- sdr_oe_ctrl <= "1111111111111111";
- sdr_wr_msw <= "000000000000000000";
- elsif (cpu_clk_4x'event and cpu_clk_4x = '1') then
-
- for i in 0 to 15 loop
- if nowin_wr_nop1_d(i) = '1' and clk4_phase_short(i)(0) = '1' then
- sdr_oe_ctrl(i) <= '0';
- elsif nowin_wr_nop3_d(i) = '1' and clk4_phase_short(i)(0) = '1' then
- sdr_oe_ctrl(i) <= '1';
- end if;
- end loop;
-
- for i in 0 to 1 loop
- if nowin_idle_dqs(i) = '1' or nowin_wr_nop3_dqs(i) = '1' then
- dqs_oe_n(i) <= '1';
- elsif nowin_wr_nop1_dqs(i) = '1' then
- dqs_oe_n(i) <= '0';
- end if;
- end loop;
-
- for i in 0 to 1 loop
- if (nowin_wr_nop2_dqs(i) = '1' and clk4_phase_short(i)(0) = '1') then
- dqs_q(i) <= '1';
- else
- dqs_q(i) <= '0';
- end if;
- end loop;
-
- for i in 0 to 15 loop
- if nowin_wr_nop1_d(i) = '1' and clk4_phase_short(i)(1) = '1' then
- sdr_wr_msw(i) <= '1';
- else
- sdr_wr_msw(i) <= '0';
- end if;
- end loop;
-
- for i in 0 to 1 loop
- if nowin_wr_nop1_dm(i) = '1' and clk4_phase_short(i)(1) = '1' then
- sdr_wr_msw(i+16) <= '1';
- else
- sdr_wr_msw(i+16) <= '0';
- end if;
- end loop;
-
- end if;
- end process;
-
- -- NOTE! DATA OUTPUT PATH. CLOCKED ON FALLING 4X CLOCK
- process(cpu_clk_4x, areset) --
- begin
- if areset = '1' then
- sdr_d_p <= "ZZZZZZZZZZZZZZZZ";
- dm_q_p <= "11";
- sdr_oe_n <= "1111111111111111";
- sdr_d <= "0000000000000000";
- dm_q <= "11";
- elsif (cpu_clk_4x'event and cpu_clk_4x = '0') then
-
- for i in 0 to 15 loop
- if sdr_oe_n(i) = '0' then
- sdr_d_p(i) <= transport sdr_d(i) after Clk_to_Output;
- else
- sdr_d_p(i) <= transport 'Z' after Clk_to_Output;
- end if;
- end loop;
-
- dm_q_p <= transport dm_q after Clk_to_Output;
-
- for i in 0 to 15 loop
- if sdr_oe_ctrl(i) = '0' then
- sdr_oe_n(i) <= '0';
- else
- sdr_oe_n(i) <= '1';
- end if;
- end loop;
-
- for i in 0 to 15 loop
- if sdr_wr_msw(i) = '1' then
- sdr_d(i) <= sdr_smp(i);
- else
- sdr_d(i) <= sdr_smp(i+16);
- end if;
- end loop;
-
- for i in 0 to 1 loop
- if sdr_wr_msw(i+16) = '1' then
- dm_q(i) <= sdr_smp(i+32);
- else
- dm_q(i) <= sdr_smp(i+34);
- end if;
- end loop;
-
- end if;
- end process;
-
- process(cpu_clk_2x, areset) --
- begin
- if areset = '1' then
- refresh_cnt <= "0000000000";
- refresh_pend <= '0';
- refresh_end <= '0';
- refresh_wait_cnt <= "0000";
- refresh_wait_end <= '0';
- elsif (cpu_clk_2x'event and cpu_clk_2x = '1') then
-
- if refresh_cnt = Refresh_Interval then
- refresh_end <= '1';
- else
- refresh_end <= '0';
- end if;
-
- if refresh_end = '1' then
- refresh_cnt <= "0000000000";
- else
- refresh_cnt <= refresh_cnt + '1';
- end if;
-
- if refresh_end = '1' and refresh_en = '1' then
- refresh_pend <= '1';
- elsif ddr_state = refresh then
- refresh_pend <= '0';
- else
- refresh_pend <= refresh_pend;
- end if;
-
- if ddr_state = refresh_wait then
- refresh_wait_cnt <= refresh_wait_cnt + '1';
- else
- refresh_wait_cnt <= "0000";
- end if;
-
- if refresh_wait_cnt = "1011" then
- refresh_wait_end <= '1';
- else
- refresh_wait_end <= '0';
- end if;
-
- end if;
- end process;
-
- -- 911. THIS IS A DUMMY FOR FGPA IMPEMENTATION TESTING
-
- process(ddr_in_clk, areset)
- begin
- if areset = '1' then
- ddr_clk_tog <= '0';
- elsif (ddr_in_clk'event and ddr_in_clk = '1') then
- ddr_clk_tog <= not(ddr_clk_tog);
- end if;
- end process;
-
- process(ddr_in_clk_2x, areset)
- begin
- if areset = '1' then
- ddr_clk_smp1 <= '0';
- ddr_clk_smp2 <= '0';
- ddr_clk_phase <= '0';
- elsif (ddr_in_clk_2x'event and ddr_in_clk_2x = '1') then
- ddr_clk_smp1 <= ddr_clk_tog;
- ddr_clk_smp2 <= ddr_clk_smp1;
- if ddr_clk_smp1 = '1' and ddr_clk_smp2 = '0' then
- ddr_clk_phase <= '0';
- else
- ddr_clk_phase <= not(ddr_clk_phase);
- end if;
- end if;
- end process;
-
- process(ddr_in_clk_2x, areset)
- begin
- if areset = '1' then
- cas_n_smp <= '0';
- ras_n_smp <= '0';
- we_n_smp <= '0';
- read_start_sig <= '0';
- elsif (ddr_in_clk_2x'event and ddr_in_clk_2x = '1') then
- cas_n_smp <= cas_qn_p_del;
- ras_n_smp <= ras_qn_p_del;
- we_n_smp <= we_qn_p_del;
- if ras_n_smp = '1' and cas_n_smp = '0' and we_n_smp = '1' and ddr_clk_phase = '1' then
- read_start_sig <= '1';
- else
- read_start_sig <= '0';
- end if;
- end if;
- end process;
-
- process(ddr_in_clk_2x, areset)
- begin
- if areset = '1' then
- sdr_d_in <= "0000000000000000";
- elsif (ddr_in_clk_2x'event and ddr_in_clk_2x = '1') then
- sdr_d_in <= sdr_d_p_del;
- end if;
- end process;
-
- process(ddr_in_clk_2x, areset)
- begin
- if areset = '1' then
- read_time_cnt <= "00";
- read_input_en <= '0';
- elsif (ddr_in_clk_2x'event and ddr_in_clk_2x = '1') then
-
- if read_start_sig = '1' then
- read_time_cnt <= "01";
- elsif read_time_cnt = "00" then
- read_time_cnt <= read_time_cnt;
- else
- read_time_cnt <= read_time_cnt + '1';
- end if;
-
- if read_time_cnt = "11" then
- read_input_en <= '1';
- else
- read_input_en <= '0';
- end if;
-
- read_input_en_del <= read_input_en;
-
- end if;
- end process;
-
- process(ddr_in_clk_2x, areset)
- begin
- if areset = '1' then
- ddr_data_read_int <= "00000000000000000000000000000000";
- elsif (ddr_in_clk_2x'event and ddr_in_clk_2x = '1') then
- if read_input_en = '1' then
- ddr_data_read_int(15 downto 0) <= sdr_d_in;
- end if;
- if read_input_en_del = '1' then
- ddr_data_read_int(31 downto 16) <= sdr_d_in;
- end if;
- end if;
- end process;
-
-end behave;
-
-
+library IEEE;
+use IEEE.STD_LOGIC_1164.all;
+use IEEE.STD_LOGIC_UNSIGNED.ALL;
+
+library UNISIM;
+use UNISIM.vcomponents.all;
+
+entity ddr_top is
+ generic(
+ simulate_io_time : boolean := false);
+ port ( -- Asyncronous reset and clocks
+ areset : in std_logic;
+ cpu_clk : in std_logic;
+ cpu_clk_2x : in std_logic;
+ cpu_clk_4x : in std_logic;
+ ddr_in_clk : in std_logic;
+ ddr_in_clk_2x : in std_logic;
+
+ -- Command interface
+ ddr_command : in std_logic_vector(15 downto 0);
+ ddr_command_we : in std_logic;
+ refresh_en : in std_logic;
+
+ -- Data interface signals
+ ddr_data_read : out std_logic_vector(31 downto 0); -- Data read from DDR SDRAM
+ ddr_data_write : in std_logic_vector(35 downto 0); -- Data to be written to DDR SDRAM
+ ddr_req_adr : in std_logic_vector(25 downto 1); -- Request address
+ ddr_req : in std_logic; -- Request DDR SDRAM access
+ ddr_busy : out std_logic; -- Request acknowledge
+ ddr_rd_wr_n : in std_logic; -- Access type 1=READ, 0=WRITE
+ ddr_req_len : in std_logic; -- Number of 16-bits words to transfer (0=2, 1=8)
+ ddr_read_en : out std_logic; -- Enable signal for read data
+ ddr_write_en : out std_logic; -- Enable (read) signal for data write
+
+ -- DDR SDRAM Signals
+ sdr_clk_p : out std_logic; -- ddr_sdram_clock
+ sdr_clk_n_p : out std_logic; -- /ddr_sdram_clock
+ cke_q_p : out std_logic; -- clock enable
+ cs_qn_p : out std_logic; -- /chip select
+ ras_qn_p : inout std_logic; -- /ras
+ cas_qn_p : inout std_logic; -- /cas
+ we_qn_p : inout std_logic; -- /write enable
+ dm_q_p : out std_logic_vector(1 downto 0); -- data mask bits, set to "00"
+ dqs_q_p : out std_logic_vector(1 downto 0); -- data strobe, only for write
+ ba_q_p : out std_logic_vector(1 downto 0); -- bank select
+ sdr_a_p : out std_logic_vector(12 downto 0); -- address bus
+ sdr_d_p : inout std_logic_vector(15 downto 0)); -- bidir data bus
+end ddr_top;
+
+architecture behave of ddr_top is
+
+attribute keep : string;
+
+type clk4_type is array(0 to 15) of std_logic_vector(1 downto 0);
+
+signal cpu_clk_tog : std_logic;
+signal ddr_cmd : std_logic_vector(15 downto 0);
+signal ddr_cmd_we_smp : std_logic;
+signal new_command : std_logic;
+
+signal cpu_clk_2x_smp1 : std_logic;
+signal cpu_clk_2x_smp2 : std_logic;
+signal cpu_clk_4x_smp1 : std_logic;
+signal cpu_clk_4x_smp2 : std_logic;
+
+signal clk2_phase : std_logic;
+signal clk4_phase : std_logic_vector(3 downto 0);
+signal clk4_phase_short : clk4_type;
+attribute keep of clk4_phase_short:signal is "true";
+
+signal ddr_clk_tog : std_logic;
+signal ddr_clk_smp1 : std_logic;
+signal ddr_clk_smp2 : std_logic;
+signal ddr_clk_phase : std_logic;
+
+signal smp_req_adr : std_logic_vector(25 downto 1);
+signal smp_req_type : std_logic;
+signal smp_req_len : std_logic;
+signal ddr_write_en_int : std_logic;
+signal ddr_read_en_int : std_logic;
+
+signal dqs_q : std_logic_vector(1 downto 0);
+signal dqs_oe_n : std_logic_vector(1 downto 0);
+attribute keep of dqs_oe_n:signal is "true";
+signal cas_qn : std_logic;
+signal ras_qn : std_logic;
+signal we_qn : std_logic;
+signal ba_q : std_logic_vector(1 downto 0);
+signal sdr_clk : std_logic;
+signal sdr_clk_n : std_logic;
+signal sdr_a : std_logic_vector(12 downto 0);
+signal sdr_d : std_logic_vector(15 downto 0);
+signal sdr_smp : std_logic_vector(35 downto 0);
+signal sdr_oe_n : std_logic_vector(15 downto 0);
+attribute keep of sdr_oe_n:signal is "true";
+signal sdr_oe_ctrl : std_logic_vector(15 downto 0);
+attribute keep of sdr_oe_ctrl:signal is "true";
+signal sdr_wr_msw : std_logic_vector(17 downto 0);
+attribute keep of sdr_wr_msw:signal is "true";
+signal dm_q : std_logic_vector(1 downto 0);
+
+signal nowin_idle_dqs : std_logic_vector(1 downto 0);
+signal nowin_wr_nop1_d : std_logic_vector(15 downto 0);
+signal nowin_wr_nop1_dqs : std_logic_vector(1 downto 0);
+signal nowin_wr_nop1_dm : std_logic_vector(1 downto 0);
+signal nowin_wr_nop2_dqs : std_logic_vector(1 downto 0);
+signal nowin_wr_nop3_d : std_logic_vector(15 downto 0);
+signal nowin_wr_nop3_dqs : std_logic_vector(1 downto 0);
+attribute keep of nowin_idle_dqs:signal is "true";
+attribute keep of nowin_wr_nop1_d:signal is "true";
+attribute keep of nowin_wr_nop1_dqs:signal is "true";
+attribute keep of nowin_wr_nop1_dm:signal is "true";
+attribute keep of nowin_wr_nop2_dqs:signal is "true";
+attribute keep of nowin_wr_nop3_d:signal is "true";
+attribute keep of nowin_wr_nop3_dqs:signal is "true";
+
+signal cas_n_smp : std_logic;
+signal ras_n_smp : std_logic;
+signal we_n_smp : std_logic;
+signal read_start_sig : std_logic;
+signal sdr_d_in : std_logic_vector(15 downto 0);
+signal read_time_cnt : std_logic_vector(1 downto 0);
+signal read_input_en : std_logic;
+signal read_input_en_del : std_logic;
+signal ddr_data_read_int : std_logic_vector(31 downto 0);
+
+signal refresh_pend : std_logic;
+signal refresh_end : std_logic;
+signal refresh_cnt : std_logic_vector(9 downto 0);
+signal refresh_wait_cnt : std_logic_vector(3 downto 0);
+signal refresh_wait_end : std_logic;
+
+signal cas_qn_p_del : std_logic;
+signal ras_qn_p_del : std_logic;
+signal we_qn_p_del : std_logic;
+signal sdr_d_p_del : std_logic_vector(15 downto 0);
+
+signal saved_row : std_logic_vector(26 downto 11);
+signal operation : std_logic_vector(1 downto 0);
+
+signal ddr_req_adr_int : std_logic_vector(25 downto 1);
+
+type state_type is (idle, act, act_nop1, act_nop2, rd_wr, rd_nop1,
+ rd_nop2,rd_nop3,rd_nop4, rd_nop5,pre, pre_nop1, pre_nop2, wr_nop1, wr_nop2,
+ wr_nop3, cmd, cpu_pre, refresh, refresh_wait);
+signal ddr_state : state_type;
+
+constant Clk_to_Output : time := 2.2 ns;
+constant Input_Setup : time := 2.5 ns;
+
+constant Refresh_Interval : std_logic_vector(9 downto 0) := "1111100110";
+
+begin
+
+ iotimingon:
+ if simulate_io_time generate
+ begin
+ cas_qn_p_del <= 'X' after 0 ns, cas_qn_p after Input_Setup;
+ ras_qn_p_del <= 'X' after 0 ns, ras_qn_p after Input_Setup;
+ we_qn_p_del <= 'X' after 0 ns, we_qn_p after Input_Setup;
+ sdr_d_p_del <= "XXXXXXXXXXXXXXXX" after 0 ns, sdr_d_p after Input_Setup;
+ end generate;
+
+ iotimingoff:
+ if not simulate_io_time generate
+ begin
+ cas_qn_p_del <= cas_qn_p;
+ ras_qn_p_del <= ras_qn_p;
+ we_qn_p_del <= we_qn_p;
+ sdr_d_p_del <= sdr_d_p;
+ end generate;
+
+ ddr_write_en <= ddr_write_en_int;
+ ddr_read_en <= ddr_read_en_int;
+ ddr_data_read <= ddr_data_read_int;
+
+ ddr_req_adr_int <= (ddr_req_adr(24 downto 10) & '0' & ddr_req_adr(9 downto 1)) when (simulate_io_time) else ddr_req_adr;
+
+ process(cpu_clk, areset) -- Toggle a flip-flop with cpu_clk, in order
+ begin -- to find phase relation with 2x and 4x clocks
+ if areset = '1' then
+ cpu_clk_tog <= '0';
+ elsif (cpu_clk'event and cpu_clk = '1') then
+ cpu_clk_tog <= not(cpu_clk_tog);
+ end if;
+ end process;
+
+ process(cpu_clk_2x, areset) -- Find phase relation between cpu_clk and cpu_clk_2x
+ begin
+ if areset = '1' then
+ cpu_clk_2x_smp1 <= '0';
+ cpu_clk_2x_smp2 <= '0';
+ clk2_phase <= '0';
+ elsif (cpu_clk_2x'event and cpu_clk_2x = '1') then
+ cpu_clk_2x_smp1 <= cpu_clk_tog;
+ cpu_clk_2x_smp2 <= cpu_clk_2x_smp1;
+ if (cpu_clk_2x_smp1 = '1' and cpu_clk_2x_smp2 = '0') then
+ clk2_phase <= '0';
+ else
+ clk2_phase <= not(clk2_phase);
+ end if;
+ end if;
+ end process;
+
+ process(cpu_clk_4x, areset) -- Find phase relation between cpu_clk and cpu_clk_4x
+ begin
+ if areset = '1' then
+ cpu_clk_4x_smp1 <= '0';
+ cpu_clk_4x_smp2 <= '0';
+ clk4_phase <= "0000";
+ clk4_phase_short(0) <= "00";
+ clk4_phase_short(1) <= "00";
+ clk4_phase_short(2) <= "00";
+ clk4_phase_short(3) <= "00";
+ clk4_phase_short(4) <= "00";
+ clk4_phase_short(5) <= "00";
+ clk4_phase_short(6) <= "00";
+ clk4_phase_short(7) <= "00";
+ clk4_phase_short(8) <= "00";
+ clk4_phase_short(9) <= "00";
+ clk4_phase_short(10) <= "00";
+ clk4_phase_short(11) <= "00";
+ clk4_phase_short(12) <= "00";
+ clk4_phase_short(13) <= "00";
+ clk4_phase_short(14) <= "00";
+ clk4_phase_short(15) <= "00";
+ elsif (cpu_clk_4x'event and cpu_clk_4x = '1') then
+ cpu_clk_4x_smp1 <= cpu_clk_tog;
+ cpu_clk_4x_smp2 <= cpu_clk_4x_smp1;
+ for i in 0 to 15 loop
+ if (cpu_clk_4x_smp1 = '1' and cpu_clk_4x_smp2 = '0') then
+ clk4_phase <= "0100";
+ clk4_phase_short(i) <= "01";
+ else
+ clk4_phase <= (clk4_phase(2 downto 0) & clk4_phase(3));
+ clk4_phase_short(i) <= clk4_phase_short(i)(0) & clk4_phase_short(i)(1);
+ end if;
+ end loop;
+ end if;
+ end process;
+
+ process(cpu_clk_4x, areset) --
+ begin
+ if areset = '1' then
+ sdr_clk <= '0';
+ sdr_clk_n <= '0';
+ elsif (cpu_clk_4x'event and cpu_clk_4x = '1') then
+ if clk4_phase_short(0)(0) = '1' then
+ sdr_clk <= '1';
+ else
+ sdr_clk <= '0';
+ end if;
+ if clk4_phase_short(0)(1) = '1' then
+ sdr_clk_n <= '1';
+ else
+ sdr_clk_n <= '0';
+ end if;
+ end if;
+ end process;
+
+ cke_q_p <= '1' after Clk_to_Output;
+ cs_qn_p <= '0' after Clk_to_Output;
+
+ process(cpu_clk_4x, areset) --
+ begin
+ if areset = '1' then
+ ras_qn_p <= '1';
+ cas_qn_p <= '1';
+ we_qn_p <= '1';
+ dqs_q_p <= "ZZ";
+ sdr_a_p <= "0000000000000";
+ ba_q_p <= "00";
+ sdr_clk_p <= '0';
+ sdr_clk_n_p <= '1';
+ elsif (cpu_clk_4x'event and cpu_clk_4x = '1') then
+ ras_qn_p <= transport ras_qn after Clk_to_Output;
+ cas_qn_p <= transport cas_qn after Clk_to_Output;
+ we_qn_p <= transport we_qn after Clk_to_Output;
+ if dqs_oe_n(0) = '0' then
+ dqs_q_p(0) <= transport dqs_q(0) after Clk_to_Output;
+ else
+ dqs_q_p(0) <= transport 'Z' after Clk_to_Output;
+ end if;
+ if dqs_oe_n(1) = '0' then
+ dqs_q_p(1) <= transport dqs_q(1) after Clk_to_Output;
+ else
+ dqs_q_p(1) <= transport 'Z' after Clk_to_Output;
+ end if;
+ sdr_a_p <= transport sdr_a after Clk_to_Output;
+ ba_q_p <= transport ba_q after Clk_to_Output;
+ sdr_clk_p <= transport sdr_clk after Clk_to_Output;
+ sdr_clk_n_p <= transport sdr_clk_n after Clk_to_Output;
+ end if;
+ end process;
+
+ process(cpu_clk_2x, areset) --
+ begin
+ if areset = '1' then
+ ddr_state <= idle;
+ ras_qn <= '1';
+ cas_qn <= '1';
+ we_qn <= '1';
+ smp_req_adr <= (others => '0');
+ smp_req_type <= '0';
+ smp_req_len <= '0';
+ sdr_a <= "XXXXXXXXXXXXX";
+ ba_q <= "00";
+ ddr_busy <= '1';
+ saved_row <= "1000000000000000";
+ ddr_write_en_int <= '0';
+ ddr_read_en_int <= '0';
+ nowin_idle_dqs <= "11";
+ nowin_wr_nop1_d <= "0000000000000000";
+ nowin_wr_nop1_dqs <= "00";
+ nowin_wr_nop1_dm <= "00";
+ nowin_wr_nop2_dqs <= "00";
+ nowin_wr_nop3_d <= "0000000000000000";
+ nowin_wr_nop3_dqs <= "00";
+ elsif (cpu_clk_2x'event and cpu_clk_2x = '1') then
+
+ -- Default values
+ ras_qn <= '1';
+ cas_qn <= '1';
+ we_qn <= '1';
+ sdr_a <= "XXXXXXXXXXXXX";
+ ddr_busy <= '1';
+ ddr_write_en_int <= '0';
+ ddr_read_en_int <= '0';
+
+ nowin_idle_dqs <= "00";
+ nowin_wr_nop1_d <= "0000000000000000";
+ nowin_wr_nop1_dqs <= "00";
+ nowin_wr_nop1_dm <= "00";
+ nowin_wr_nop2_dqs <= "00";
+ nowin_wr_nop3_d <= "0000000000000000";
+ nowin_wr_nop3_dqs <= "00";
+
+ case ddr_state is
+ when idle =>
+ smp_req_adr <= ddr_req_adr_int;
+ smp_req_type <= ddr_rd_wr_n;
+ smp_req_len <= ddr_req_len;
+ ddr_busy <= '0';
+ operation <= "00";
+ if refresh_pend = '1' then
+ operation <= "01";
+ ddr_state <= pre;
+ elsif new_command = '1' then
+ if ddr_cmd(15) = '1' then
+ operation <= "10";
+ ddr_state <= cpu_pre;
+ else
+ ddr_state <= cmd;
+ end if;
+ elsif (ddr_req = '1' and ddr_req_adr_int(25 downto 11) = saved_row(25 downto 11) and saved_row(26) = '0') then
+ operation <= "11";
+ ddr_write_en_int <= not(ddr_rd_wr_n);
+ ddr_state <= rd_wr;
+ elsif ddr_req = '1' then
+ operation <= "11";
+ ddr_state <= pre;
+ else
+ ddr_state <= idle;
+ nowin_idle_dqs <= "11";
+ end if;
+ when act =>
+ sdr_a <= smp_req_adr(23 downto 11);
+ ba_q <= smp_req_adr(25 downto 24);
+ ras_qn <= '0';
+ ddr_write_en_int <= not(smp_req_type);
+ ddr_state <= act_nop1;
+ when act_nop1 =>
+ ddr_state <= act_nop2;
+ when act_nop2 =>
+ ddr_state <= rd_wr;
+ when rd_wr =>
+ sdr_a(10) <= '0'; -- Disable auto precharge
+ sdr_a(9 downto 0) <= smp_req_adr(10 downto 1);
+ ba_q <= smp_req_adr(25 downto 24);
+ saved_row <= '0' & smp_req_adr(25 downto 11);
+ cas_qn <= '0';
+ we_qn <= smp_req_type;
+ if smp_req_type = '1' then
+ ddr_state <= rd_nop1;
+ else
+ ddr_state <= wr_nop1;
+ nowin_wr_nop1_d <= "1111111111111111";
+ nowin_wr_nop1_dqs <= "11";
+ nowin_wr_nop1_dm <= "11";
+ end if;
+ when wr_nop1 =>
+ ddr_state <= wr_nop2;
+ nowin_wr_nop2_dqs <= "11";
+ when wr_nop2 =>
+ ddr_state <= wr_nop3;
+ nowin_wr_nop3_d <= "1111111111111111";
+ nowin_wr_nop3_dqs <= "11";
+ when wr_nop3 =>
+ nowin_idle_dqs <= "11";
+ ddr_state <= idle;
+ when rd_nop1 =>
+ ddr_state <= rd_nop2;
+ when rd_nop2 =>
+ if operation /= "11" then
+ nowin_idle_dqs <= "11";
+ ddr_state <= idle;
+ else
+ ddr_state <= rd_nop3;
+ end if;
+ when rd_nop3 =>
+ ddr_state <= rd_nop4;
+ when rd_nop4 =>
+ ddr_read_en_int <= '1';
+ ddr_state <= rd_nop5;
+ when rd_nop5 =>
+ nowin_idle_dqs <= "11";
+ ddr_state <= idle;
+ when pre =>
+ ras_qn <= '0';
+ we_qn <= '0';
+ sdr_a(10) <= '1'; -- Precharge all banks
+ ba_q <= smp_req_adr(25 downto 24);
+ ddr_state <= pre_nop1;
+ when pre_nop1 =>
+ ddr_state <= pre_nop2;
+ when cmd =>
+ cas_qn <= '0';
+ ras_qn <= '0';
+ we_qn <= '0';
+ ba_q <= ddr_cmd(14 downto 13);
+ sdr_a <= ddr_cmd(12 downto 0);
+ nowin_idle_dqs <= "11";
+ ddr_state <= idle;
+ when cpu_pre =>
+ ddr_state <= pre;
+ when refresh =>
+ cas_qn <= '0';
+ ras_qn <= '0';
+ saved_row(26) <= '1';
+ ddr_state <= refresh_wait;
+ when refresh_wait =>
+ if refresh_wait_end = '1' then
+ ddr_state <= pre_nop2;
+ end if;
+ when pre_nop2 =>
+ if operation = "01" then
+ operation <= "10";
+ ddr_state <= refresh;
+ elsif operation = "10" then
+ nowin_idle_dqs <= "11";
+ ddr_state <= idle;
+ else
+ ddr_state <= act;
+ end if;
+ when others =>
+ ddr_state <= idle;
+ nowin_idle_dqs <= "11";
+ end case;
+ end if;
+ end process;
+
+ process(cpu_clk, areset) --
+ begin
+ if areset = '1' then
+ ddr_cmd <= "0000000000000000";
+ elsif (cpu_clk'event and cpu_clk = '1') then
+ if ddr_command_we = '1' then
+ ddr_cmd <= ddr_command;
+ else
+ ddr_cmd <= ddr_cmd;
+ end if;
+ end if;
+ end process;
+
+ process(cpu_clk_2x, areset) --
+ begin
+ if areset = '1' then
+ ddr_cmd_we_smp <= '0';
+ new_command <= '0';
+ sdr_smp <= "000000000000000000000000000000000000";
+ elsif (cpu_clk_2x'event and cpu_clk_2x = '1') then
+ ddr_cmd_we_smp <= ddr_command_we;
+ if ddr_command_we = '0' and ddr_cmd_we_smp = '1' then
+ new_command <= '1';
+ elsif ddr_state = cmd or ddr_state = cpu_pre then
+ new_command <= '0';
+ else
+ new_command <= new_command;
+ end if;
+
+ if ddr_write_en_int = '1' then
+ sdr_smp <= ddr_data_write;
+ else
+ sdr_smp <= sdr_smp;
+ end if;
+
+ end if;
+ end process;
+
+ process(cpu_clk_4x, areset) --
+ begin
+ if areset = '1' then
+ dqs_q <= "00";
+ dqs_oe_n <= "11";
+ sdr_oe_ctrl <= "1111111111111111";
+ sdr_wr_msw <= "000000000000000000";
+ elsif (cpu_clk_4x'event and cpu_clk_4x = '1') then
+
+ for i in 0 to 15 loop
+ if nowin_wr_nop1_d(i) = '1' and clk4_phase_short(i)(0) = '1' then
+ sdr_oe_ctrl(i) <= '0';
+ elsif nowin_wr_nop3_d(i) = '1' and clk4_phase_short(i)(0) = '1' then
+ sdr_oe_ctrl(i) <= '1';
+ end if;
+ end loop;
+
+ for i in 0 to 1 loop
+ if nowin_idle_dqs(i) = '1' or nowin_wr_nop3_dqs(i) = '1' then
+ dqs_oe_n(i) <= '1';
+ elsif nowin_wr_nop1_dqs(i) = '1' then
+ dqs_oe_n(i) <= '0';
+ end if;
+ end loop;
+
+ for i in 0 to 1 loop
+ if (nowin_wr_nop2_dqs(i) = '1' and clk4_phase_short(i)(0) = '1') then
+ dqs_q(i) <= '1';
+ else
+ dqs_q(i) <= '0';
+ end if;
+ end loop;
+
+ for i in 0 to 15 loop
+ if nowin_wr_nop1_d(i) = '1' and clk4_phase_short(i)(1) = '1' then
+ sdr_wr_msw(i) <= '1';
+ else
+ sdr_wr_msw(i) <= '0';
+ end if;
+ end loop;
+
+ for i in 0 to 1 loop
+ if nowin_wr_nop1_dm(i) = '1' and clk4_phase_short(i)(1) = '1' then
+ sdr_wr_msw(i+16) <= '1';
+ else
+ sdr_wr_msw(i+16) <= '0';
+ end if;
+ end loop;
+
+ end if;
+ end process;
+
+ -- NOTE! DATA OUTPUT PATH. CLOCKED ON FALLING 4X CLOCK
+ process(cpu_clk_4x, areset) --
+ begin
+ if areset = '1' then
+ sdr_d_p <= "ZZZZZZZZZZZZZZZZ";
+ dm_q_p <= "11";
+ sdr_oe_n <= "1111111111111111";
+ sdr_d <= "0000000000000000";
+ dm_q <= "11";
+ elsif (cpu_clk_4x'event and cpu_clk_4x = '0') then
+
+ for i in 0 to 15 loop
+ if sdr_oe_n(i) = '0' then
+ sdr_d_p(i) <= transport sdr_d(i) after Clk_to_Output;
+ else
+ sdr_d_p(i) <= transport 'Z' after Clk_to_Output;
+ end if;
+ end loop;
+
+ dm_q_p <= transport dm_q after Clk_to_Output;
+
+ for i in 0 to 15 loop
+ if sdr_oe_ctrl(i) = '0' then
+ sdr_oe_n(i) <= '0';
+ else
+ sdr_oe_n(i) <= '1';
+ end if;
+ end loop;
+
+ for i in 0 to 15 loop
+ if sdr_wr_msw(i) = '1' then
+ sdr_d(i) <= sdr_smp(i);
+ else
+ sdr_d(i) <= sdr_smp(i+16);
+ end if;
+ end loop;
+
+ for i in 0 to 1 loop
+ if sdr_wr_msw(i+16) = '1' then
+ dm_q(i) <= sdr_smp(i+32);
+ else
+ dm_q(i) <= sdr_smp(i+34);
+ end if;
+ end loop;
+
+ end if;
+ end process;
+
+ process(cpu_clk_2x, areset) --
+ begin
+ if areset = '1' then
+ refresh_cnt <= "0000000000";
+ refresh_pend <= '0';
+ refresh_end <= '0';
+ refresh_wait_cnt <= "0000";
+ refresh_wait_end <= '0';
+ elsif (cpu_clk_2x'event and cpu_clk_2x = '1') then
+
+ if refresh_cnt = Refresh_Interval then
+ refresh_end <= '1';
+ else
+ refresh_end <= '0';
+ end if;
+
+ if refresh_end = '1' then
+ refresh_cnt <= "0000000000";
+ else
+ refresh_cnt <= refresh_cnt + '1';
+ end if;
+
+ if refresh_end = '1' and refresh_en = '1' then
+ refresh_pend <= '1';
+ elsif ddr_state = refresh then
+ refresh_pend <= '0';
+ else
+ refresh_pend <= refresh_pend;
+ end if;
+
+ if ddr_state = refresh_wait then
+ refresh_wait_cnt <= refresh_wait_cnt + '1';
+ else
+ refresh_wait_cnt <= "0000";
+ end if;
+
+ if refresh_wait_cnt = "1011" then
+ refresh_wait_end <= '1';
+ else
+ refresh_wait_end <= '0';
+ end if;
+
+ end if;
+ end process;
+
+ -- 911. THIS IS A DUMMY FOR FGPA IMPEMENTATION TESTING
+
+ process(ddr_in_clk, areset)
+ begin
+ if areset = '1' then
+ ddr_clk_tog <= '0';
+ elsif (ddr_in_clk'event and ddr_in_clk = '1') then
+ ddr_clk_tog <= not(ddr_clk_tog);
+ end if;
+ end process;
+
+ process(ddr_in_clk_2x, areset)
+ begin
+ if areset = '1' then
+ ddr_clk_smp1 <= '0';
+ ddr_clk_smp2 <= '0';
+ ddr_clk_phase <= '0';
+ elsif (ddr_in_clk_2x'event and ddr_in_clk_2x = '1') then
+ ddr_clk_smp1 <= ddr_clk_tog;
+ ddr_clk_smp2 <= ddr_clk_smp1;
+ if ddr_clk_smp1 = '1' and ddr_clk_smp2 = '0' then
+ ddr_clk_phase <= '0';
+ else
+ ddr_clk_phase <= not(ddr_clk_phase);
+ end if;
+ end if;
+ end process;
+
+ process(ddr_in_clk_2x, areset)
+ begin
+ if areset = '1' then
+ cas_n_smp <= '0';
+ ras_n_smp <= '0';
+ we_n_smp <= '0';
+ read_start_sig <= '0';
+ elsif (ddr_in_clk_2x'event and ddr_in_clk_2x = '1') then
+ cas_n_smp <= cas_qn_p_del;
+ ras_n_smp <= ras_qn_p_del;
+ we_n_smp <= we_qn_p_del;
+ if ras_n_smp = '1' and cas_n_smp = '0' and we_n_smp = '1' and ddr_clk_phase = '1' then
+ read_start_sig <= '1';
+ else
+ read_start_sig <= '0';
+ end if;
+ end if;
+ end process;
+
+ process(ddr_in_clk_2x, areset)
+ begin
+ if areset = '1' then
+ sdr_d_in <= "0000000000000000";
+ elsif (ddr_in_clk_2x'event and ddr_in_clk_2x = '1') then
+ sdr_d_in <= sdr_d_p_del;
+ end if;
+ end process;
+
+ process(ddr_in_clk_2x, areset)
+ begin
+ if areset = '1' then
+ read_time_cnt <= "00";
+ read_input_en <= '0';
+ elsif (ddr_in_clk_2x'event and ddr_in_clk_2x = '1') then
+
+ if read_start_sig = '1' then
+ read_time_cnt <= "01";
+ elsif read_time_cnt = "00" then
+ read_time_cnt <= read_time_cnt;
+ else
+ read_time_cnt <= read_time_cnt + '1';
+ end if;
+
+ if read_time_cnt = "11" then
+ read_input_en <= '1';
+ else
+ read_input_en <= '0';
+ end if;
+
+ read_input_en_del <= read_input_en;
+
+ end if;
+ end process;
+
+ process(ddr_in_clk_2x, areset)
+ begin
+ if areset = '1' then
+ ddr_data_read_int <= "00000000000000000000000000000000";
+ elsif (ddr_in_clk_2x'event and ddr_in_clk_2x = '1') then
+ if read_input_en = '1' then
+ ddr_data_read_int(15 downto 0) <= sdr_d_in;
+ end if;
+ if read_input_en_del = '1' then
+ ddr_data_read_int(31 downto 16) <= sdr_d_in;
+ end if;
+ end if;
+ end process;
+
+end behave;
+
+
diff --git a/misc/ddrsdram/src/mt46v16m16.vhd b/misc/ddrsdram/src/mt46v16m16.vhd
index 6b89345..356bb28 100644
--- a/misc/ddrsdram/src/mt46v16m16.vhd
+++ b/misc/ddrsdram/src/mt46v16m16.vhd
@@ -1,1320 +1,1320 @@
------------------------------------------------------------------------------------------
---
--- File Name: MT46V16M16.VHD
--- Version: 2.1
--- Date: January 14th, 2002
--- Model: Behavioral
--- Simulator: NCDesktop - http://www.cadence.com
--- ModelSim PE - http://www.model.com
---
--- Dependencies: None
---
--- Author: Son P. Huynh
--- Email: sphuynh@micron.com
--- Phone: (208) 368-3825
--- Company: Micron Technology, Inc.
--- Part Number: MT46V16M16 (4 Mb x 16 x 4 Banks)
---
--- Description: Micron 256 Mb SDRAM DDR (Double Data Rate)
---
--- Limitation: Doesn't model internal refresh counter
---
--- Note:
---
--- Disclaimer: THESE DESIGNS ARE PROVIDED "AS IS" WITH NO WARRANTY
--- WHATSOEVER AND MICRON SPECIFICALLY DISCLAIMS ANY
--- IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR
--- A PARTICULAR PURPOSE, OR AGAINST INFRINGEMENT.
---
--- Copyright (c) 1998 Micron Semiconductor Products, Inc.
--- All rights researved
---
--- Rev Author Date Changes
--- --- ---------------------------- ---------- -------------------------------------
--- 2.1 Son P. Huynh 01/14/2002 - Fix Burst_counter
--- Micron Technology, Inc.
---
--- 2.0 Son P. Huynh 11/08/2001 - Second release
--- Micron Technology, Inc. - Rewrote and remove SHARED VARIABLE
---
------------------------------------------------------------------------------------------
-
-LIBRARY IEEE;
- USE IEEE.STD_LOGIC_1164.ALL;
- USE IEEE.STD_LOGIC_UNSIGNED.ALL;
- USE IEEE.STD_LOGIC_ARITH.ALL;
-
-ENTITY MT46V16M16 IS
- GENERIC ( -- Timing for -75Z CL2
- tCK : TIME := 7.500 ns;
- tCH : TIME := 3.375 ns; -- 0.45*tCK
- tCL : TIME := 3.375 ns; -- 0.45*tCK
- tDH : TIME := 0.500 ns;
- tDS : TIME := 0.500 ns;
- tIH : TIME := 0.900 ns;
- tIS : TIME := 0.900 ns;
- tMRD : TIME := 15.000 ns;
- tRAS : TIME := 40.000 ns;
- tRAP : TIME := 20.000 ns;
- tRC : TIME := 65.000 ns;
- tRFC : TIME := 75.000 ns;
- tRCD : TIME := 20.000 ns;
- tRP : TIME := 20.000 ns;
- tRRD : TIME := 15.000 ns;
- tWR : TIME := 15.000 ns;
- addr_bits : INTEGER := 13;
- data_bits : INTEGER := 16;
- cols_bits : INTEGER := 9
- );
- PORT (
- Dq : INOUT STD_LOGIC_VECTOR (data_bits - 1 DOWNTO 0) := (OTHERS => 'Z');
- Dqs : INOUT STD_LOGIC_VECTOR (1 DOWNTO 0) := "ZZ";
- Addr : IN STD_LOGIC_VECTOR (addr_bits - 1 DOWNTO 0);
- Ba : IN STD_LOGIC_VECTOR (1 DOWNTO 0);
- Clk : IN STD_LOGIC;
- Clk_n : IN STD_LOGIC;
- Cke : IN STD_LOGIC;
- Cs_n : IN STD_LOGIC;
- Ras_n : IN STD_LOGIC;
- Cas_n : IN STD_LOGIC;
- We_n : IN STD_LOGIC;
- Dm : IN STD_LOGIC_VECTOR (1 DOWNTO 0)
- );
-END MT46V16M16;
-
-ARCHITECTURE behave OF MT46V16M16 IS
- -- Array for Read pipeline
- TYPE Array_Read_cmnd IS ARRAY (8 DOWNTO 0) OF STD_LOGIC;
- TYPE Array_Read_bank IS ARRAY (8 DOWNTO 0) OF STD_LOGIC_VECTOR (1 DOWNTO 0);
- TYPE Array_Read_cols IS ARRAY (8 DOWNTO 0) OF STD_LOGIC_VECTOR (cols_bits - 1 DOWNTO 0);
-
- -- Array for Write pipeline
- TYPE Array_Write_cmnd IS ARRAY (2 DOWNTO 0) OF STD_LOGIC;
- TYPE Array_Write_bank IS ARRAY (2 DOWNTO 0) OF STD_LOGIC_VECTOR (1 DOWNTO 0);
- TYPE Array_Write_cols IS ARRAY (2 DOWNTO 0) OF STD_LOGIC_VECTOR (cols_bits - 1 DOWNTO 0);
-
- -- Array for Auto Precharge
- TYPE Array_Read_precharge IS ARRAY (3 DOWNTO 0) OF STD_LOGIC;
- TYPE Array_Write_precharge IS ARRAY (3 DOWNTO 0) OF STD_LOGIC;
- TYPE Array_Count_precharge IS ARRAY (3 DOWNTO 0) OF INTEGER;
-
- -- Array for Manual Precharge
- TYPE Array_A10_precharge IS ARRAY (8 DOWNTO 0) OF STD_LOGIC;
- TYPE Array_Bank_precharge IS ARRAY (8 DOWNTO 0) OF STD_LOGIC_VECTOR (1 DOWNTO 0);
- TYPE Array_Cmnd_precharge IS ARRAY (8 DOWNTO 0) OF STD_LOGIC;
-
- -- Array for Burst Terminate
- TYPE Array_Cmnd_bst IS ARRAY (8 DOWNTO 0) OF STD_LOGIC;
-
- -- Array for Memory Access
- TYPE Array_ram_type IS ARRAY (2**cols_bits - 1 DOWNTO 0) OF STD_LOGIC_VECTOR (data_bits - 1 DOWNTO 0);
- TYPE Array_ram_pntr IS ACCESS Array_ram_type;
- TYPE Array_ram_stor IS ARRAY (2**addr_bits - 1 DOWNTO 0) OF Array_ram_pntr;
-
- -- Data pair
- SIGNAL Dq_pair : STD_LOGIC_VECTOR (2 * data_bits - 1 DOWNTO 0);
- SIGNAL Dm_pair : STD_LOGIC_VECTOR (3 DOWNTO 0);
-
- -- Mode Register
- SIGNAL Mode_reg : STD_LOGIC_VECTOR (addr_bits - 1 DOWNTO 0) := (OTHERS => '0');
-
- -- Command Decode Variables
- SIGNAL Active_enable, Aref_enable, Burst_term, Ext_mode_enable : STD_LOGIC := '0';
- SIGNAL Mode_reg_enable, Prech_enable, Read_enable, Write_enable : STD_LOGIC := '0';
-
- -- Burst Length Decode Variables
- SIGNAL Burst_length_2, Burst_length_4, Burst_length_8, Burst_length_f : STD_LOGIC := '0';
-
- -- Cas Latency Decode Variables
- SIGNAL Cas_latency_15, Cas_latency_2, Cas_latency_25, Cas_latency_3, Cas_latency_4 : STD_LOGIC := '0';
-
- -- Internal Control Signals
- SIGNAL Cs_in, Ras_in, Cas_in, We_in : STD_LOGIC := '0';
-
- -- System Clock
- SIGNAL Sys_clk : STD_LOGIC := '0';
-
- -- Dqs buffer
- SIGNAL Dqs_out : STD_LOGIC_VECTOR (1 DOWNTO 0) := "ZZ";
-
-BEGIN
- -- Strip the strength
- Cs_in <= To_X01 (Cs_n);
- Ras_in <= To_X01 (Ras_n);
- Cas_in <= To_X01 (Cas_n);
- We_in <= To_X01 (We_n);
-
- -- Commands Decode
- Active_enable <= NOT(Cs_in) AND NOT(Ras_in) AND Cas_in AND We_in;
- Aref_enable <= NOT(Cs_in) AND NOT(Ras_in) AND NOT(Cas_in) AND We_in;
- Burst_term <= NOT(Cs_in) AND Ras_in AND Cas_in AND NOT(We_in);
- Ext_mode_enable <= NOT(Cs_in) AND NOT(Ras_in) AND NOT(Cas_in) AND NOT(We_in) AND Ba(0) AND NOT(Ba(1));
- Mode_reg_enable <= NOT(Cs_in) AND NOT(Ras_in) AND NOT(Cas_in) AND NOT(We_in) AND NOT(Ba(0)) AND NOT(Ba(1));
- Prech_enable <= NOT(Cs_in) AND NOT(Ras_in) AND Cas_in AND NOT(We_in);
- Read_enable <= NOT(Cs_in) AND Ras_in AND NOT(Cas_in) AND We_in;
- Write_enable <= NOT(Cs_in) AND Ras_in AND NOT(Cas_in) AND NOT(We_in);
-
- -- Burst Length Decode
- Burst_length_2 <= NOT(Mode_reg(2)) AND NOT(Mode_reg(1)) AND Mode_reg(0);
- Burst_length_4 <= NOT(Mode_reg(2)) AND Mode_reg(1) AND NOT(Mode_reg(0));
- Burst_length_8 <= NOT(Mode_reg(2)) AND Mode_reg(1) AND Mode_reg(0);
- Burst_length_f <= (Mode_reg(2)) AND Mode_reg(1) AND Mode_reg(0);
-
- -- CAS Latency Decode
- Cas_latency_15 <= Mode_reg(6) AND NOT(Mode_reg(5)) AND (Mode_reg(4));
- Cas_latency_2 <= NOT(Mode_reg(6)) AND Mode_reg(5) AND NOT(Mode_reg(4));
- Cas_latency_25 <= Mode_reg(6) AND Mode_reg(5) AND NOT(Mode_reg(4));
- Cas_latency_3 <= NOT(Mode_reg(6)) AND Mode_reg(5) AND Mode_reg(4);
- Cas_latency_4 <= (Mode_reg(6)) AND NOT(Mode_reg(5)) AND NOT(Mode_reg(4));
-
- -- Dqs buffer
- Dqs <= Dqs_out;
-
- --
- -- System Clock
- --
- int_clk : PROCESS (Clk, Clk_n)
- VARIABLE ClkZ, CkeZ : STD_LOGIC := '0';
- begin
- IF Clk = '1' AND Clk_n = '0' THEN
- ClkZ := '1';
- CkeZ := Cke;
- ELSIF Clk = '0' AND Clk_n = '1' THEN
- ClkZ := '0';
- END IF;
- Sys_clk <= CkeZ AND ClkZ;
- END PROCESS;
-
- --
- -- Main Process
- --
- state_register : PROCESS
- -- Precharge Variables
- VARIABLE Pc_b0, Pc_b1, Pc_b2, Pc_b3 : STD_LOGIC := '0';
-
- -- Activate Variables
- VARIABLE Act_b0, Act_b1, Act_b2, Act_b3 : STD_LOGIC := '1';
-
- -- Data IO variables
- VARIABLE Data_in_enable, Data_out_enable : STD_LOGIC := '0';
-
- -- Internal address mux variables
- VARIABLE Cols_brst : STD_LOGIC_VECTOR (2 DOWNTO 0);
- VARIABLE Prev_bank : STD_LOGIC_VECTOR (1 DOWNTO 0) := "00";
- VARIABLE Bank_addr : STD_LOGIC_VECTOR (1 DOWNTO 0) := "00";
- VARIABLE Cols_addr : STD_LOGIC_VECTOR (cols_bits - 1 DOWNTO 0);
- VARIABLE Rows_addr : STD_LOGIC_VECTOR (addr_bits - 1 DOWNTO 0);
- VARIABLE B0_row_addr : STD_LOGIC_VECTOR (addr_bits - 1 DOWNTO 0);
- VARIABLE B1_row_addr : STD_LOGIC_VECTOR (addr_bits - 1 DOWNTO 0);
- VARIABLE B2_row_addr : STD_LOGIC_VECTOR (addr_bits - 1 DOWNTO 0);
- VARIABLE B3_row_addr : STD_LOGIC_VECTOR (addr_bits - 1 DOWNTO 0);
-
- -- DLL Reset variables
- VARIABLE DLL_enable : STD_LOGIC := '0';
- VARIABLE DLL_reset : STD_LOGIC := '0';
- VARIABLE DLL_done : STD_LOGIC := '0';
- VARIABLE DLL_count : INTEGER := 0;
-
- -- Timing Check
- VARIABLE MRD_chk : TIME := 0 ns;
- VARIABLE RFC_chk : TIME := 0 ns;
- VARIABLE RRD_chk : TIME := 0 ns;
- VARIABLE RAS_chk0, RAS_chk1, RAS_chk2, RAS_chk3 : TIME := 0 ns;
- VARIABLE RAP_chk0, RAP_chk1, RAP_chk2, RAP_chk3 : TIME := 0 ns;
- VARIABLE RC_chk0, RC_chk1, RC_chk2, RC_chk3 : TIME := 0 ns;
- VARIABLE RCD_chk0, RCD_chk1, RCD_chk2, RCD_chk3 : TIME := 0 ns;
- VARIABLE RP_chk0, RP_chk1, RP_chk2, RP_chk3 : TIME := 0 ns;
- VARIABLE WR_chk0, WR_chk1, WR_chk2, WR_chk3 : TIME := 0 ns;
-
- -- Read pipeline variables
- VARIABLE Read_cmnd : Array_Read_cmnd;
- VARIABLE Read_bank : Array_Read_bank;
- VARIABLE Read_cols : Array_Read_cols;
-
- -- Write pipeline variables
- VARIABLE Write_cmnd : Array_Write_cmnd;
- VARIABLE Write_bank : Array_Write_bank;
- VARIABLE Write_cols : Array_Write_cols;
-
- -- Auto Precharge variables
- VARIABLE Read_precharge : Array_Read_precharge := ('0' & '0' & '0' & '0');
- VARIABLE Write_precharge : Array_Write_precharge := ('0' & '0' & '0' & '0');
- VARIABLE Count_precharge : Array_Count_precharge := ( 0 & 0 & 0 & 0 );
-
- -- Manual Precharge variables
- VARIABLE A10_precharge : Array_A10_precharge;
- VARIABLE Bank_precharge : Array_Bank_precharge;
- VARIABLE Cmnd_precharge : Array_Cmnd_precharge;
-
- -- Burst Terminate variable
- VARIABLE Cmnd_bst : Array_Cmnd_bst;
-
- -- Memory Banks
- VARIABLE Bank0 : Array_ram_stor;
- VARIABLE Bank1 : Array_ram_stor;
- VARIABLE Bank2 : Array_ram_stor;
- VARIABLE Bank3 : Array_ram_stor;
-
- -- Burst Counter
- VARIABLE Burst_counter : STD_LOGIC_VECTOR (cols_bits - 1 DOWNTO 0);
-
- -- Internal Dqs initialize
- VARIABLE Dqs_int : STD_LOGIC := '0';
-
- -- Data buffer for DM Mask
- VARIABLE Data_buf : STD_LOGIC_VECTOR (data_bits - 1 DOWNTO 0) := (OTHERS => 'Z');
-
- --
- -- Initialize empty rows
- --
- PROCEDURE Init_mem (Bank : STD_LOGIC_VECTOR; Row_index : INTEGER) IS
- VARIABLE i, j : INTEGER := 0;
- BEGIN
- IF Bank = "00" THEN
- IF Bank0 (Row_index) = NULL THEN -- Check to see if row empty
- Bank0 (Row_index) := NEW Array_ram_type; -- Open new row for access
- FOR i IN (2**cols_bits - 1) DOWNTO 0 LOOP -- Filled row with zeros
- FOR j IN (data_bits - 1) DOWNTO 0 LOOP
- Bank0 (Row_index) (i) (j) := '0';
- END LOOP;
- END LOOP;
- END IF;
- ELSIF Bank = "01" THEN
- IF Bank1 (Row_index) = NULL THEN
- Bank1 (Row_index) := NEW Array_ram_type;
- FOR i IN (2**cols_bits - 1) DOWNTO 0 LOOP
- FOR j IN (data_bits - 1) DOWNTO 0 LOOP
- Bank1 (Row_index) (i) (j) := '0';
- END LOOP;
- END LOOP;
- END IF;
- ELSIF Bank = "10" THEN
- IF Bank2 (Row_index) = NULL THEN
- Bank2 (Row_index) := NEW Array_ram_type;
- FOR i IN (2**cols_bits - 1) DOWNTO 0 LOOP
- FOR j IN (data_bits - 1) DOWNTO 0 LOOP
- Bank2 (Row_index) (i) (j) := '0';
- END LOOP;
- END LOOP;
- END IF;
- ELSIF Bank = "11" THEN
- IF Bank3 (Row_index) = NULL THEN
- Bank3 (Row_index) := NEW Array_ram_type;
- FOR i IN (2**cols_bits - 1) DOWNTO 0 LOOP
- FOR j IN (data_bits - 1) DOWNTO 0 LOOP
- Bank3 (Row_index) (i) (j) := '0';
- END LOOP;
- END LOOP;
- END IF;
- END IF;
- END;
-
- --
- -- Burst Counter
- --
- PROCEDURE Burst_decode IS
- VARIABLE Cols_temp : STD_LOGIC_VECTOR (cols_bits - 1 DOWNTO 0) := (OTHERS => '0');
- BEGIN
- -- Advance burst counter
- Burst_counter := Burst_counter + 1;
-
- -- Burst Type
- IF Mode_reg (3) = '0' THEN
- Cols_temp := Cols_addr + 1;
- ELSIF Mode_reg (3) = '1' THEN
- Cols_temp (2) := Burst_counter (2) XOR Cols_brst (2);
- Cols_temp (1) := Burst_counter (1) XOR Cols_brst (1);
- Cols_temp (0) := Burst_counter (0) XOR Cols_brst (0);
- END IF;
-
- -- Burst Length
- IF Burst_length_2 = '1' THEN
- 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;
- IF Read_precharge (2) = '1' OR Write_precharge (2) = '1' THEN
- Count_precharge (2) := Count_precharge (2) + 1;
- END IF;
- IF Read_precharge (3) = '1' OR Write_precharge (3) = '1' THEN
- Count_precharge (3) := Count_precharge (3) + 1;
- END IF;
-
- -- Read with AutoPrecharge Calculation
- -- The device start internal precharge when:
- -- 1. Meet tRAS requirement
- -- 2. BL/2 cycles after command
- IF ((Read_precharge(0) = '1') AND (NOW - RAS_chk0 >= tRAS)) THEN
- IF ((Burst_length_2 = '1' AND Count_precharge(0) >= 1) OR
- (Burst_length_4 = '1' AND Count_precharge(0) >= 2) OR
- (Burst_length_8 = '1' AND Count_precharge(0) >= 4)) THEN
- Pc_b0 := '1';
- Act_b0 := '0';
- RP_chk0 := NOW;
- Read_precharge(0) := '0';
- END IF;
- END IF;
- IF ((Read_precharge(1) = '1') AND (NOW - RAS_chk1 >= tRAS)) THEN
- IF ((Burst_length_2 = '1' AND Count_precharge(1) >= 1) OR
- (Burst_length_4 = '1' AND Count_precharge(1) >= 2) OR
- (Burst_length_8 = '1' AND Count_precharge(1) >= 4)) THEN
- Pc_b1 := '1';
- Act_b1 := '0';
- RP_chk1 := NOW;
- Read_precharge(1) := '0';
- END IF;
- END IF;
- IF ((Read_precharge(2) = '1') AND (NOW - RAS_chk2 >= tRAS)) THEN
- IF ((Burst_length_2 = '1' AND Count_precharge(2) >= 1) OR
- (Burst_length_4 = '1' AND Count_precharge(2) >= 2) OR
- (Burst_length_8 = '1' AND Count_precharge(2) >= 4)) THEN
- Pc_b2 := '1';
- Act_b2 := '0';
- RP_chk2 := NOW;
- Read_precharge(2) := '0';
- END IF;
- END IF;
- IF ((Read_precharge(3) = '1') AND (NOW - RAS_chk3 >= tRAS)) THEN
- IF ((Burst_length_2 = '1' AND Count_precharge(3) >= 1) OR
- (Burst_length_4 = '1' AND Count_precharge(3) >= 2) OR
- (Burst_length_8 = '1' AND Count_precharge(3) >= 4)) THEN
- Pc_b3 := '1';
- Act_b3 := '0';
- RP_chk3 := NOW;
- Read_precharge(3) := '0';
- END IF;
- END IF;
-
- -- Write with AutoPrecharge Calculation
- -- The device start internal precharge when:
- -- 1. Meet tRAS requirement
- -- 2. Two clock after last burst
- -- Since tWR is time base, the model will compensate tRP
- IF ((Write_precharge(0) = '1') AND (NOW - RAS_chk0 >= tRAS)) THEN
- IF ((Burst_length_2 = '1' AND Count_precharge (0) >= 4) OR
- (Burst_length_4 = '1' AND Count_precharge (0) >= 5) OR
- (Burst_length_8 = '1' AND Count_precharge (0) >= 7)) THEN
- Pc_b0 := '1';
- Act_b0 := '0';
- RP_chk0 := NOW - ((2 * tCK) - tWR);
- Write_precharge(0) := '0';
- END IF;
- END IF;
- IF ((Write_precharge(1) = '1') AND (NOW - RAS_chk1 >= tRAS)) THEN
- IF ((Burst_length_2 = '1' AND Count_precharge (1) >= 4) OR
- (Burst_length_4 = '1' AND Count_precharge (1) >= 5) OR
- (Burst_length_8 = '1' AND Count_precharge (1) >= 7)) THEN
- Pc_b1 := '1';
- Act_b1 := '0';
- RP_chk1 := NOW - ((2 * tCK) - tWR);
- Write_precharge(1) := '0';
- END IF;
- END IF;
- IF ((Write_precharge(2) = '1') AND (NOW - RAS_chk2 >= tRAS)) THEN
- IF ((Burst_length_2 = '1' AND Count_precharge (2) >= 4) OR
- (Burst_length_4 = '1' AND Count_precharge (2) >= 5) OR
- (Burst_length_8 = '1' AND Count_precharge (2) >= 7)) THEN
- Pc_b2 := '1';
- Act_b2 := '0';
- RP_chk2 := NOW - ((2 * tCK) - tWR);
- Write_precharge(2) := '0';
- END IF;
- END IF;
- IF ((Write_precharge(3) = '1') AND (NOW - RAS_chk3 >= tRAS)) THEN
- IF ((Burst_length_2 = '1' AND Count_precharge (3) >= 4) OR
- (Burst_length_4 = '1' AND Count_precharge (3) >= 5) OR
- (Burst_length_8 = '1' AND Count_precharge (3) >= 7)) THEN
- Pc_b3 := '1';
- Act_b3 := '0';
- RP_chk3 := NOW - ((2 * tCK) - tWR);
- Write_precharge(3) := '0';
- END IF;
- END IF;
- END IF;
-
- --
- -- DLL Counter
- --
- IF Sys_clk'EVENT AND Sys_clk = '1' THEN
- IF (DLL_Reset = '1' AND DLL_done = '0') THEN
- DLL_count := DLL_count + 1;
- IF (DLL_count >= 200) THEN
- DLL_done := '1';
- END IF;
- END IF;
- END IF;
-
- --
- -- Control Logic
- --
- IF Sys_clk'EVENT AND Sys_clk = '1' THEN
- -- Auto Refresh
- IF Aref_enable = '1' THEN
- -- Auto Refresh to Auto Refresh
- ASSERT (NOW - RFC_chk >= tRFC)
- REPORT "tRFC violation during Auto Refresh"
- SEVERITY WARNING;
-
- -- Precharge to Auto Refresh
- ASSERT ((NOW - RP_chk0 >= tRP) AND (NOW - RP_chk1 >= tRP) AND
- (NOW - RP_chk2 >= tRP) AND (NOW - RP_chk3 >= tRP))
- REPORT "tRP violation during Auto Refresh"
- SEVERITY WARNING;
-
- -- Precharge to Auto Refresh
- ASSERT (Pc_b0 = '1' AND Pc_b1 = '1' AND Pc_b2 = '1' AND Pc_b3 = '1')
- REPORT "All banks must be Precharge before Auto Refresh"
- SEVERITY WARNING;
-
- -- Record current tRFC time
- RFC_chk := NOW;
- END IF;
-
- -- Extended Load Mode Register
- IF Ext_mode_enable = '1' THEN
- IF (Pc_b0 = '1' AND Pc_b1 = '1' AND Pc_b2 = '1' AND Pc_b3 = '1') THEN
- IF (Addr (0) = '0') THEN
- DLL_enable := '1';
- ELSE
- DLL_enable := '0';
- END IF;
- END IF;
-
- -- Precharge to EMR
- ASSERT (Pc_b0 = '1' AND Pc_b1 = '1' AND Pc_b2 = '1' AND Pc_b3 = '1')
- REPORT "All bank must be Precharged before Extended Mode Register"
- SEVERITY WARNING;
-
- -- Precharge to EMR
- ASSERT ((NOW - RP_chk0 >= tRP) AND (NOW - RP_chk1 >= tRP) AND
- (NOW - RP_chk2 >= tRP) AND (NOW - RP_chk3 >= tRP))
- REPORT "tRP violation during Extended Load Register"
- SEVERITY WARNING;
-
- -- LMR/EMR to EMR
- ASSERT (NOW - MRD_chk >= tMRD)
- REPORT "tMRD violation during Extended Mode Register"
- SEVERITY WARNING;
-
- -- Record current tMRD time
- MRD_chk := NOW;
- END IF;
-
- -- Load Mode Register
- IF Mode_reg_enable = '1' THEN
- -- Register mode
- Mode_reg <= Addr;
-
- -- DLL Reset
- IF (DLL_enable = '1' AND Addr (8) = '1') THEN
- DLL_reset := '1';
- DLL_done := '0';
- DLL_count := 0;
- ELSIF (DLL_enable = '1' AND DLL_reset = '0' AND Addr (8) = '0') THEN
- ASSERT (FALSE)
- REPORT "DLL is ENABLE: DLL RESET is require"
- SEVERITY WARNING;
- ELSIF (DLL_enable = '0' AND Addr (8) = '1') THEN
- ASSERT (FALSE)
- REPORT "DLL is DISABLE: DLL RESET will be ignored"
- SEVERITY WARNING;
- END IF;
-
- -- Precharge to LMR
- ASSERT (Pc_b0 = '1' AND Pc_b1 = '1' AND Pc_b2 = '1' AND Pc_b3 = '1')
- REPORT "All bank must be Precharged before Load Mode Register"
- SEVERITY WARNING;
-
- -- Precharge to EMR
- ASSERT ((NOW - RP_chk0 >= tRP) AND (NOW - RP_chk1 >= tRP) AND
- (NOW - RP_chk2 >= tRP) AND (NOW - RP_chk3 >= tRP))
- REPORT "tRP violation during Load Mode Register"
- SEVERITY WARNING;
-
- -- LMR/ELMR to LMR
- ASSERT (NOW - MRD_chk >= tMRD)
- REPORT "tMRD violation during Load Mode Register"
- SEVERITY WARNING;
-
- -- Check for invalid Burst Length
- ASSERT ((Addr (2 DOWNTO 0) = "001") OR -- BL = 2
- (Addr (2 DOWNTO 0) = "010") OR -- BL = 4
- (Addr (2 DOWNTO 0) = "011")) -- BL = 8
- REPORT "Invalid Burst Length during Load Mode Register"
- SEVERITY WARNING;
-
- -- Check for invalid CAS Latency
- ASSERT ((Addr (6 DOWNTO 4) = "010") OR -- CL = 2.0
- (Addr (6 DOWNTO 4) = "110")) -- CL = 2.5
- REPORT "Invalid CAS Latency during Load Mode Register"
- SEVERITY WARNING;
-
- -- Record current tMRD time
- MRD_chk := NOW;
- END IF;
-
- -- Active Block (latch Bank and Row Address)
- IF Active_enable = '1' THEN
- -- Activate an OPEN bank can corrupt data
- ASSERT ((Ba = "00" AND Act_b0 = '0') OR
- (Ba = "01" AND Act_b1 = '0') OR
- (Ba = "10" AND Act_b2 = '0') OR
- (Ba = "11" AND Act_b3 = '0'))
- REPORT "Bank is already activated - data can be corrupted"
- SEVERITY WARNING;
-
- -- Activate Bank 0
- IF Ba = "00" AND Pc_b0 = '1' THEN
- -- Activate to Activate (same bank)
- ASSERT (NOW - RC_chk0 >= tRC)
- REPORT "tRC violation during Activate Bank 0"
- SEVERITY WARNING;
-
- -- Precharge to Active
- ASSERT (NOW - RP_chk0 >= tRP)
- REPORT "tRP violation during Activate Bank 0"
- SEVERITY WARNING;
-
- -- Record Variables for checking violation
- Act_b0 := '1';
- Pc_b0 := '0';
- B0_row_addr := Addr;
- RC_chk0 := NOW;
- RCD_chk0 := NOW;
- RAS_chk0 := NOW;
- RAP_chk0 := NOW;
- END IF;
-
- -- Activate Bank 1
- IF Ba = "01" AND Pc_b1 = '1' THEN
- -- Activate to Activate (same bank)
- ASSERT (NOW - RC_chk1 >= tRC)
- REPORT "tRC violation during Activate Bank 1"
- SEVERITY WARNING;
-
- -- Precharge to Active
- ASSERT (NOW - RP_chk1 >= tRP)
- REPORT "tRP violation during Activate Bank 1"
- SEVERITY WARNING;
-
- -- Record Variables for checking violation
- Act_b1 := '1';
- Pc_b1 := '0';
- B1_row_addr := Addr;
- RC_chk1 := NOW;
- RCD_chk1 := NOW;
- RAS_chk1 := NOW;
- RAP_chk1 := NOW;
- END IF;
-
- -- Activate Bank 2
- IF Ba = "10" AND Pc_b2 = '1' THEN
- -- Activate to Activate (same bank)
- ASSERT (NOW - RC_chk2 >= tRC)
- REPORT "tRC violation during Activate Bank 2"
- SEVERITY WARNING;
-
- -- Precharge to Active
- ASSERT (NOW - RP_chk2 >= tRP)
- REPORT "tRP violation during Activate Bank 2"
- SEVERITY WARNING;
-
- -- Record Variables for checking violation
- Act_b2 := '1';
- Pc_b2 := '0';
- B2_row_addr := Addr;
- RC_chk2 := NOW;
- RCD_chk2 := NOW;
- RAS_chk2 := NOW;
- RAP_chk2 := NOW;
- END IF;
-
- -- Activate Bank 3
- IF Ba = "11" AND Pc_b3 = '1' THEN
- -- Activate to Activate (same bank)
- ASSERT (NOW - RC_chk3 >= tRC)
- REPORT "tRC violation during Activate Bank 3"
- SEVERITY WARNING;
-
- -- Precharge to Active
- ASSERT (NOW - RP_chk3 >= tRP)
- REPORT "tRP violation during Activate Bank 3"
- SEVERITY WARNING;
-
- -- Record Variables for checking violation
- Act_b3 := '1';
- Pc_b3 := '0';
- B3_row_addr := Addr;
- RC_chk3 := NOW;
- RCD_chk3 := NOW;
- RAS_chk3 := NOW;
- RAP_chk3 := NOW;
- END IF;
-
- -- Activate Bank A to Activate Bank B
- IF (Prev_bank /= Ba) THEN
- ASSERT (NOW - RRD_chk >= tRRD)
- REPORT "tRRD violation during Activate"
- SEVERITY WARNING;
- END IF;
-
- -- AutoRefresh to Activate
- ASSERT (NOW - RFC_chk >= tRFC)
- REPORT "tRFC violation during Activate"
- SEVERITY WARNING;
-
- -- Record Variables for Checking Violation
- RRD_chk := NOW;
- Prev_bank := Ba;
- END IF;
-
- -- Precharge Block - Consider NOP if bank already precharged or in process of precharging
- IF Prech_enable = '1' THEN
- -- EMR or LMR to Precharge
- ASSERT (NOW - MRD_chk >= tMRD)
- REPORT "tMRD violation during Precharge"
- SEVERITY WARNING;
-
- -- Precharge Bank 0
- IF ((Addr (10) = '1' OR (Addr (10) = '0' AND Ba = "00")) AND Act_b0 = '1') THEN
- Act_b0 := '0';
- Pc_b0 := '1';
- RP_chk0 := NOW;
-
- -- Activate to Precharge bank 0
- ASSERT (NOW - RAS_chk0 >= tRAS)
- REPORT "tRAS violation during Precharge"
- SEVERITY WARNING;
-
- -- tWR violation check for Write
- ASSERT (NOW - WR_chk0 >= tWR)
- REPORT "tWR violation during Precharge"
- SEVERITY WARNING;
- END IF;
-
- -- Precharge Bank 1
- IF ((Addr (10) = '1' OR (Addr (10) = '0' AND Ba = "01")) AND Act_b1 = '1') THEN
- Act_b1 := '0';
- Pc_b1 := '1';
- RP_chk1 := NOW;
-
- -- Activate to Precharge
- ASSERT (NOW - RAS_chk1 >= tRAS)
- REPORT "tRAS violation during Precharge"
- SEVERITY WARNING;
-
- -- tWR violation check for Write
- ASSERT (NOW - WR_chk1 >= tWR)
- REPORT "tWR violation during Precharge"
- SEVERITY WARNING;
- END IF;
-
- -- Precharge Bank 2
- IF ((Addr (10) = '1' OR (Addr (10) = '0' AND Ba = "10")) AND Act_b2 = '1') THEN
- Act_b2 := '0';
- Pc_b2 := '1';
- RP_chk2 := NOW;
-
- -- Activate to Precharge
- ASSERT (NOW - RAS_chk2 >= tRAS)
- REPORT "tRAS violation during Precharge"
- SEVERITY WARNING;
-
- -- tWR violation check for Write
- ASSERT (NOW - WR_chk2 >= tWR)
- REPORT "tWR violation during Precharge"
- SEVERITY WARNING;
- END IF;
-
- -- Precharge Bank 3
- IF ((Addr (10) = '1' OR (Addr (10) = '0' AND Ba = "11")) AND Act_b3 = '1') THEN
- Act_b3 := '0';
- Pc_b3 := '1';
- RP_chk3 := NOW;
-
- -- Activate to Precharge
- ASSERT (NOW - RAS_chk3 >= tRAS)
- REPORT "tRAS violation during Precharge"
- SEVERITY WARNING;
-
- -- tWR violation check for Write
- ASSERT (NOW - WR_chk3 >= tWR)
- REPORT "tWR violation during Precharge"
- SEVERITY WARNING;
- END IF;
-
- -- Pipeline for READ
- IF CAS_latency_15 = '1' THEN
- A10_precharge (3) := Addr(10);
- Bank_precharge (3) := Ba;
- Cmnd_precharge (3) := '1';
- ELSIF CAS_latency_2 = '1' THEN
- A10_precharge (4) := Addr(10);
- Bank_precharge (4) := Ba;
- Cmnd_precharge (4) := '1';
- ELSIF CAS_latency_25 = '1' THEN
- A10_precharge (5) := Addr(10);
- Bank_precharge (5) := Ba;
- Cmnd_precharge (5) := '1';
- ELSIF CAS_latency_3 = '1' THEN
- A10_precharge (6) := Addr(10);
- Bank_precharge (6) := Ba;
- Cmnd_precharge (6) := '1';
- ELSIF CAS_latency_4 = '1' THEN
- A10_precharge (8) := Addr(10);
- Bank_precharge (8) := Ba;
- Cmnd_precharge (8) := '1';
- END IF;
- END IF;
-
- -- Burst Terminate
- IF Burst_term = '1' THEN
- -- Pipeline for Read
- IF CAS_latency_15 = '1' THEN
- Cmnd_bst (3) := '1';
- ELSIF CAS_latency_2 = '1' THEN
- Cmnd_bst (4) := '1';
- ELSIF CAS_latency_25 = '1' THEN
- Cmnd_bst (5) := '1';
- ELSIF CAS_latency_3 = '1' THEN
- Cmnd_bst (6) := '1';
- ELSIF CAS_latency_4 = '1' THEN
- Cmnd_bst (8) := '1';
- END IF;
-
- -- Terminate Write
- ASSERT (Data_in_enable = '0')
- REPORT "It's illegal to Burst Terminate a Write"
- SEVERITY WARNING;
-
- -- Terminate Read with Auto Precharge
- ASSERT (Read_precharge (0) = '0' AND Read_precharge (1) = '0' AND
- Read_precharge (2) = '0' AND Read_precharge (3) = '0')
- REPORT "It's illegal to Burst Terminate a Read with Auto Precharge"
- SEVERITY WARNING;
- END IF;
-
- -- Read Command
- IF Read_enable = '1' THEN
- -- CAS Latency Pipeline
- IF Cas_latency_15 = '1' THEN
- Read_cmnd (3) := '1';
- Read_bank (3) := Ba;
- Read_cols (3) := Addr (8 DOWNTO 0);
- ELSIF Cas_latency_2 = '1' THEN
- Read_cmnd (4) := '1';
- Read_bank (4) := Ba;
- Read_cols (4) := Addr (8 DOWNTO 0);
- ELSIF Cas_latency_25 = '1' THEN
- Read_cmnd (5) := '1';
- Read_bank (5) := Ba;
- Read_cols (5) := Addr (8 DOWNTO 0);
- ELSIF Cas_latency_3 = '1' THEN
- Read_cmnd (6) := '1';
- Read_bank (6) := Ba;
- Read_cols (6) := Addr (8 DOWNTO 0);
- ELSIF Cas_latency_4 = '1' THEN
- Read_cmnd (8) := '1';
- Read_bank (8) := Ba;
- Read_cols (8) := Addr (8 DOWNTO 0);
- END IF;
-
- -- Write to Read: Terminate Write Immediately
- IF Data_in_enable = '1' THEN
- Data_in_enable := '0';
- END IF;
-
- -- Interrupting a Read with Auto Precharge (same bank only)
- ASSERT (Read_precharge(CONV_INTEGER(Ba)) = '0')
- REPORT "It's illegal to interrupt a Read with Auto Precharge"
- SEVERITY WARNING;
-
- -- Activate to Read
- ASSERT ((Ba = "00" AND Act_b0 = '1') OR
- (Ba = "01" AND Act_b1 = '1') OR
- (Ba = "10" AND Act_b2 = '1') OR
- (Ba = "11" AND Act_b3 = '1'))
- REPORT "Bank is not Activated for Read"
- SEVERITY WARNING;
-
- -- Activate to Read without Auto Precharge
- IF Addr (10) = '0' THEN
- ASSERT ((Ba = "00" AND NOW - RCD_chk0 >= tRCD) OR
- (Ba = "01" AND NOW - RCD_chk1 >= tRCD) OR
- (Ba = "10" AND NOW - RCD_chk2 >= tRCD) OR
- (Ba = "11" AND NOW - RCD_chk3 >= tRCD))
- REPORT "tRCD violation during Read"
- SEVERITY WARNING;
- END IF;
-
- -- Activate to Read with Auto Precharge
- IF Addr (10) = '1' THEN
- ASSERT ((Ba = "00" AND NOW - RAP_chk0 >= tRAP) OR
- (Ba = "01" AND NOW - RAP_chk1 >= tRAP) OR
- (Ba = "10" AND NOW - RAP_chk2 >= tRAP) OR
- (Ba = "11" AND NOW - RAP_chk3 >= tRAP))
- REPORT "tRAP violation during Read"
- SEVERITY WARNING;
- END IF;
-
- -- Auto precharge
- IF Addr (10) = '1' THEN
- Read_precharge (Conv_INTEGER(Ba)) := '1';
- Count_precharge (Conv_INTEGER(Ba)) := 0;
- END IF;
-
- -- DLL Check
- IF (DLL_reset = '1') THEN
- ASSERT (DLL_done = '1')
- REPORT "DLL RESET not complete"
- SEVERITY WARNING;
- END IF;
- END IF;
-
- -- Write Command
- IF Write_enable = '1' THEN
- -- Pipeline for Write
- Write_cmnd (2) := '1';
- Write_bank (2) := Ba;
- Write_cols (2) := Addr (8 DOWNTO 0);
-
- -- Interrupting a Write with Auto Precharge (same bank only)
- ASSERT (Write_precharge(CONV_INTEGER(Ba)) = '0')
- REPORT "It's illegal to interrupt a Write with Auto Precharge"
- SEVERITY WARNING;
-
- -- Activate to Write
- ASSERT ((Ba = "00" AND Act_b0 = '1') OR
- (Ba = "01" AND Act_b1 = '1') OR
- (Ba = "10" AND Act_b2 = '1') OR
- (Ba = "11" AND Act_b3 = '1'))
- REPORT "Bank is not Activated for Write"
- SEVERITY WARNING;
-
- -- Activate to Write
- ASSERT ((Ba = "00" AND NOW - RCD_chk0 >= tRCD) OR
- (Ba = "01" AND NOW - RCD_chk1 >= tRCD) OR
- (Ba = "10" AND NOW - RCD_chk2 >= tRCD) OR
- (Ba = "11" AND NOW - RCD_chk3 >= tRCD))
- REPORT "tRCD violation during Write"
- SEVERITY WARNING;
-
- -- Auto precharge
- IF Addr (10) = '1' THEN
- Write_precharge (Conv_INTEGER(Ba)) := '1';
- Count_precharge (Conv_INTEGER(Ba)) := 0;
- END IF;
- END IF;
- END IF;
- END PROCESS;
-
- --
- -- Dqs Receiver
- --
- dqs_rcvrs : PROCESS
- VARIABLE Dm_temp : STD_LOGIC_VECTOR (1 DOWNTO 0);
- VARIABLE Dq_temp : STD_LOGIC_VECTOR (data_bits - 1 DOWNTO 0);
- BEGIN
- WAIT ON Dqs;
- -- Latch data at posedge Dqs
- IF Dqs'EVENT AND Dqs (1) = '1' AND Dqs (0) = '1' THEN
- Dq_temp := Dq;
- Dm_temp := Dm;
- END IF;
- -- Latch data at negedge Dqs
- IF Dqs'EVENT AND Dqs (1) = '0' AND Dqs (0) = '0' THEN
- Dq_pair <= (Dq & Dq_temp);
- Dm_pair <= (Dm & Dm_temp);
- END IF;
- END PROCESS;
-
- --
- -- Setup timing checks
- --
- Setup_check : PROCESS
- BEGIN
- WAIT ON Sys_clk;
- IF Sys_clk'EVENT AND Sys_clk = '1' THEN
- ASSERT(Cke'LAST_EVENT >= tIS)
- REPORT "CKE Setup time violation -- tIS"
- SEVERITY WARNING;
- ASSERT(Cs_n'LAST_EVENT >= tIS)
- REPORT "CS# Setup time violation -- tIS"
- SEVERITY WARNING;
- ASSERT(Cas_n'LAST_EVENT >= tIS)
- REPORT "CAS# Setup time violation -- tIS"
- SEVERITY WARNING;
- ASSERT(Ras_n'LAST_EVENT >= tIS)
- REPORT "RAS# Setup time violation -- tIS"
- SEVERITY WARNING;
- ASSERT(We_n'LAST_EVENT >= tIS)
- REPORT "WE# Setup time violation -- tIS"
- SEVERITY WARNING;
- ASSERT(Addr'LAST_EVENT >= tIS)
- REPORT "ADDR Setup time violation -- tIS"
- SEVERITY WARNING;
- ASSERT(Ba'LAST_EVENT >= tIS)
- REPORT "BA Setup time violation -- tIS"
- SEVERITY WARNING;
- END IF;
- END PROCESS;
-
- --
- -- Hold timing checks
- --
- Hold_check : PROCESS
- BEGIN
- WAIT ON Sys_clk'DELAYED (tIH);
- IF Sys_clk'DELAYED (tIH) = '1' THEN
- ASSERT(Cke'LAST_EVENT >= tIH)
- REPORT "CKE Hold time violation -- tIH"
- SEVERITY WARNING;
- ASSERT(Cs_n'LAST_EVENT >= tIH)
- REPORT "CS# Hold time violation -- tIH"
- SEVERITY WARNING;
- ASSERT(Cas_n'LAST_EVENT >= tIH)
- REPORT "CAS# Hold time violation -- tIH"
- SEVERITY WARNING;
- ASSERT(Ras_n'LAST_EVENT >= tIH)
- REPORT "RAS# Hold time violation -- tIH"
- SEVERITY WARNING;
- ASSERT(We_n'LAST_EVENT >= tIH)
- REPORT "WE# Hold time violation -- tIH"
- SEVERITY WARNING;
- ASSERT(Addr'LAST_EVENT >= tIH)
- REPORT "ADDR Hold time violation -- tIH"
- SEVERITY WARNING;
- ASSERT(Ba'LAST_EVENT >= tIH)
- REPORT "BA Hold time violation -- tIH"
- SEVERITY WARNING;
- END IF;
- END PROCESS;
-
-END behave;
+-----------------------------------------------------------------------------------------
+--
+-- File Name: MT46V16M16.VHD
+-- Version: 2.1
+-- Date: January 14th, 2002
+-- Model: Behavioral
+-- Simulator: NCDesktop - http://www.cadence.com
+-- ModelSim PE - http://www.model.com
+--
+-- Dependencies: None
+--
+-- Author: Son P. Huynh
+-- Email: sphuynh@micron.com
+-- Phone: (208) 368-3825
+-- Company: Micron Technology, Inc.
+-- Part Number: MT46V16M16 (4 Mb x 16 x 4 Banks)
+--
+-- Description: Micron 256 Mb SDRAM DDR (Double Data Rate)
+--
+-- Limitation: Doesn't model internal refresh counter
+--
+-- Note:
+--
+-- Disclaimer: THESE DESIGNS ARE PROVIDED "AS IS" WITH NO WARRANTY
+-- WHATSOEVER AND MICRON SPECIFICALLY DISCLAIMS ANY
+-- IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR
+-- A PARTICULAR PURPOSE, OR AGAINST INFRINGEMENT.
+--
+-- Copyright (c) 1998 Micron Semiconductor Products, Inc.
+-- All rights researved
+--
+-- Rev Author Date Changes
+-- --- ---------------------------- ---------- -------------------------------------
+-- 2.1 Son P. Huynh 01/14/2002 - Fix Burst_counter
+-- Micron Technology, Inc.
+--
+-- 2.0 Son P. Huynh 11/08/2001 - Second release
+-- Micron Technology, Inc. - Rewrote and remove SHARED VARIABLE
+--
+-----------------------------------------------------------------------------------------
+
+LIBRARY IEEE;
+ USE IEEE.STD_LOGIC_1164.ALL;
+ USE IEEE.STD_LOGIC_UNSIGNED.ALL;
+ USE IEEE.STD_LOGIC_ARITH.ALL;
+
+ENTITY MT46V16M16 IS
+ GENERIC ( -- Timing for -75Z CL2
+ tCK : TIME := 7.500 ns;
+ tCH : TIME := 3.375 ns; -- 0.45*tCK
+ tCL : TIME := 3.375 ns; -- 0.45*tCK
+ tDH : TIME := 0.500 ns;
+ tDS : TIME := 0.500 ns;
+ tIH : TIME := 0.900 ns;
+ tIS : TIME := 0.900 ns;
+ tMRD : TIME := 15.000 ns;
+ tRAS : TIME := 40.000 ns;
+ tRAP : TIME := 20.000 ns;
+ tRC : TIME := 65.000 ns;
+ tRFC : TIME := 75.000 ns;
+ tRCD : TIME := 20.000 ns;
+ tRP : TIME := 20.000 ns;
+ tRRD : TIME := 15.000 ns;
+ tWR : TIME := 15.000 ns;
+ addr_bits : INTEGER := 13;
+ data_bits : INTEGER := 16;
+ cols_bits : INTEGER := 9
+ );
+ PORT (
+ Dq : INOUT STD_LOGIC_VECTOR (data_bits - 1 DOWNTO 0) := (OTHERS => 'Z');
+ Dqs : INOUT STD_LOGIC_VECTOR (1 DOWNTO 0) := "ZZ";
+ Addr : IN STD_LOGIC_VECTOR (addr_bits - 1 DOWNTO 0);
+ Ba : IN STD_LOGIC_VECTOR (1 DOWNTO 0);
+ Clk : IN STD_LOGIC;
+ Clk_n : IN STD_LOGIC;
+ Cke : IN STD_LOGIC;
+ Cs_n : IN STD_LOGIC;
+ Ras_n : IN STD_LOGIC;
+ Cas_n : IN STD_LOGIC;
+ We_n : IN STD_LOGIC;
+ Dm : IN STD_LOGIC_VECTOR (1 DOWNTO 0)
+ );
+END MT46V16M16;
+
+ARCHITECTURE behave OF MT46V16M16 IS
+ -- Array for Read pipeline
+ TYPE Array_Read_cmnd IS ARRAY (8 DOWNTO 0) OF STD_LOGIC;
+ TYPE Array_Read_bank IS ARRAY (8 DOWNTO 0) OF STD_LOGIC_VECTOR (1 DOWNTO 0);
+ TYPE Array_Read_cols IS ARRAY (8 DOWNTO 0) OF STD_LOGIC_VECTOR (cols_bits - 1 DOWNTO 0);
+
+ -- Array for Write pipeline
+ TYPE Array_Write_cmnd IS ARRAY (2 DOWNTO 0) OF STD_LOGIC;
+ TYPE Array_Write_bank IS ARRAY (2 DOWNTO 0) OF STD_LOGIC_VECTOR (1 DOWNTO 0);
+ TYPE Array_Write_cols IS ARRAY (2 DOWNTO 0) OF STD_LOGIC_VECTOR (cols_bits - 1 DOWNTO 0);
+
+ -- Array for Auto Precharge
+ TYPE Array_Read_precharge IS ARRAY (3 DOWNTO 0) OF STD_LOGIC;
+ TYPE Array_Write_precharge IS ARRAY (3 DOWNTO 0) OF STD_LOGIC;
+ TYPE Array_Count_precharge IS ARRAY (3 DOWNTO 0) OF INTEGER;
+
+ -- Array for Manual Precharge
+ TYPE Array_A10_precharge IS ARRAY (8 DOWNTO 0) OF STD_LOGIC;
+ TYPE Array_Bank_precharge IS ARRAY (8 DOWNTO 0) OF STD_LOGIC_VECTOR (1 DOWNTO 0);
+ TYPE Array_Cmnd_precharge IS ARRAY (8 DOWNTO 0) OF STD_LOGIC;
+
+ -- Array for Burst Terminate
+ TYPE Array_Cmnd_bst IS ARRAY (8 DOWNTO 0) OF STD_LOGIC;
+
+ -- Array for Memory Access
+ TYPE Array_ram_type IS ARRAY (2**cols_bits - 1 DOWNTO 0) OF STD_LOGIC_VECTOR (data_bits - 1 DOWNTO 0);
+ TYPE Array_ram_pntr IS ACCESS Array_ram_type;
+ TYPE Array_ram_stor IS ARRAY (2**addr_bits - 1 DOWNTO 0) OF Array_ram_pntr;
+
+ -- Data pair
+ SIGNAL Dq_pair : STD_LOGIC_VECTOR (2 * data_bits - 1 DOWNTO 0);
+ SIGNAL Dm_pair : STD_LOGIC_VECTOR (3 DOWNTO 0);
+
+ -- Mode Register
+ SIGNAL Mode_reg : STD_LOGIC_VECTOR (addr_bits - 1 DOWNTO 0) := (OTHERS => '0');
+
+ -- Command Decode Variables
+ SIGNAL Active_enable, Aref_enable, Burst_term, Ext_mode_enable : STD_LOGIC := '0';
+ SIGNAL Mode_reg_enable, Prech_enable, Read_enable, Write_enable : STD_LOGIC := '0';
+
+ -- Burst Length Decode Variables
+ SIGNAL Burst_length_2, Burst_length_4, Burst_length_8, Burst_length_f : STD_LOGIC := '0';
+
+ -- Cas Latency Decode Variables
+ SIGNAL Cas_latency_15, Cas_latency_2, Cas_latency_25, Cas_latency_3, Cas_latency_4 : STD_LOGIC := '0';
+
+ -- Internal Control Signals
+ SIGNAL Cs_in, Ras_in, Cas_in, We_in : STD_LOGIC := '0';
+
+ -- System Clock
+ SIGNAL Sys_clk : STD_LOGIC := '0';
+
+ -- Dqs buffer
+ SIGNAL Dqs_out : STD_LOGIC_VECTOR (1 DOWNTO 0) := "ZZ";
+
+BEGIN
+ -- Strip the strength
+ Cs_in <= To_X01 (Cs_n);
+ Ras_in <= To_X01 (Ras_n);
+ Cas_in <= To_X01 (Cas_n);
+ We_in <= To_X01 (We_n);
+
+ -- Commands Decode
+ Active_enable <= NOT(Cs_in) AND NOT(Ras_in) AND Cas_in AND We_in;
+ Aref_enable <= NOT(Cs_in) AND NOT(Ras_in) AND NOT(Cas_in) AND We_in;
+ Burst_term <= NOT(Cs_in) AND Ras_in AND Cas_in AND NOT(We_in);
+ Ext_mode_enable <= NOT(Cs_in) AND NOT(Ras_in) AND NOT(Cas_in) AND NOT(We_in) AND Ba(0) AND NOT(Ba(1));
+ Mode_reg_enable <= NOT(Cs_in) AND NOT(Ras_in) AND NOT(Cas_in) AND NOT(We_in) AND NOT(Ba(0)) AND NOT(Ba(1));
+ Prech_enable <= NOT(Cs_in) AND NOT(Ras_in) AND Cas_in AND NOT(We_in);
+ Read_enable <= NOT(Cs_in) AND Ras_in AND NOT(Cas_in) AND We_in;
+ Write_enable <= NOT(Cs_in) AND Ras_in AND NOT(Cas_in) AND NOT(We_in);
+
+ -- Burst Length Decode
+ Burst_length_2 <= NOT(Mode_reg(2)) AND NOT(Mode_reg(1)) AND Mode_reg(0);
+ Burst_length_4 <= NOT(Mode_reg(2)) AND Mode_reg(1) AND NOT(Mode_reg(0));
+ Burst_length_8 <= NOT(Mode_reg(2)) AND Mode_reg(1) AND Mode_reg(0);
+ Burst_length_f <= (Mode_reg(2)) AND Mode_reg(1) AND Mode_reg(0);
+
+ -- CAS Latency Decode
+ Cas_latency_15 <= Mode_reg(6) AND NOT(Mode_reg(5)) AND (Mode_reg(4));
+ Cas_latency_2 <= NOT(Mode_reg(6)) AND Mode_reg(5) AND NOT(Mode_reg(4));
+ Cas_latency_25 <= Mode_reg(6) AND Mode_reg(5) AND NOT(Mode_reg(4));
+ Cas_latency_3 <= NOT(Mode_reg(6)) AND Mode_reg(5) AND Mode_reg(4);
+ Cas_latency_4 <= (Mode_reg(6)) AND NOT(Mode_reg(5)) AND NOT(Mode_reg(4));
+
+ -- Dqs buffer
+ Dqs <= Dqs_out;
+
+ --
+ -- System Clock
+ --
+ int_clk : PROCESS (Clk, Clk_n)
+ VARIABLE ClkZ, CkeZ : STD_LOGIC := '0';
+ begin
+ IF Clk = '1' AND Clk_n = '0' THEN
+ ClkZ := '1';
+ CkeZ := Cke;
+ ELSIF Clk = '0' AND Clk_n = '1' THEN
+ ClkZ := '0';
+ END IF;
+ Sys_clk <= CkeZ AND ClkZ;
+ END PROCESS;
+
+ --
+ -- Main Process
+ --
+ state_register : PROCESS
+ -- Precharge Variables
+ VARIABLE Pc_b0, Pc_b1, Pc_b2, Pc_b3 : STD_LOGIC := '0';
+
+ -- Activate Variables
+ VARIABLE Act_b0, Act_b1, Act_b2, Act_b3 : STD_LOGIC := '1';
+
+ -- Data IO variables
+ VARIABLE Data_in_enable, Data_out_enable : STD_LOGIC := '0';
+
+ -- Internal address mux variables
+ VARIABLE Cols_brst : STD_LOGIC_VECTOR (2 DOWNTO 0);
+ VARIABLE Prev_bank : STD_LOGIC_VECTOR (1 DOWNTO 0) := "00";
+ VARIABLE Bank_addr : STD_LOGIC_VECTOR (1 DOWNTO 0) := "00";
+ VARIABLE Cols_addr : STD_LOGIC_VECTOR (cols_bits - 1 DOWNTO 0);
+ VARIABLE Rows_addr : STD_LOGIC_VECTOR (addr_bits - 1 DOWNTO 0);
+ VARIABLE B0_row_addr : STD_LOGIC_VECTOR (addr_bits - 1 DOWNTO 0);
+ VARIABLE B1_row_addr : STD_LOGIC_VECTOR (addr_bits - 1 DOWNTO 0);
+ VARIABLE B2_row_addr : STD_LOGIC_VECTOR (addr_bits - 1 DOWNTO 0);
+ VARIABLE B3_row_addr : STD_LOGIC_VECTOR (addr_bits - 1 DOWNTO 0);
+
+ -- DLL Reset variables
+ VARIABLE DLL_enable : STD_LOGIC := '0';
+ VARIABLE DLL_reset : STD_LOGIC := '0';
+ VARIABLE DLL_done : STD_LOGIC := '0';
+ VARIABLE DLL_count : INTEGER := 0;
+
+ -- Timing Check
+ VARIABLE MRD_chk : TIME := 0 ns;
+ VARIABLE RFC_chk : TIME := 0 ns;
+ VARIABLE RRD_chk : TIME := 0 ns;
+ VARIABLE RAS_chk0, RAS_chk1, RAS_chk2, RAS_chk3 : TIME := 0 ns;
+ VARIABLE RAP_chk0, RAP_chk1, RAP_chk2, RAP_chk3 : TIME := 0 ns;
+ VARIABLE RC_chk0, RC_chk1, RC_chk2, RC_chk3 : TIME := 0 ns;
+ VARIABLE RCD_chk0, RCD_chk1, RCD_chk2, RCD_chk3 : TIME := 0 ns;
+ VARIABLE RP_chk0, RP_chk1, RP_chk2, RP_chk3 : TIME := 0 ns;
+ VARIABLE WR_chk0, WR_chk1, WR_chk2, WR_chk3 : TIME := 0 ns;
+
+ -- Read pipeline variables
+ VARIABLE Read_cmnd : Array_Read_cmnd;
+ VARIABLE Read_bank : Array_Read_bank;
+ VARIABLE Read_cols : Array_Read_cols;
+
+ -- Write pipeline variables
+ VARIABLE Write_cmnd : Array_Write_cmnd;
+ VARIABLE Write_bank : Array_Write_bank;
+ VARIABLE Write_cols : Array_Write_cols;
+
+ -- Auto Precharge variables
+ VARIABLE Read_precharge : Array_Read_precharge := ('0' & '0' & '0' & '0');
+ VARIABLE Write_precharge : Array_Write_precharge := ('0' & '0' & '0' & '0');
+ VARIABLE Count_precharge : Array_Count_precharge := ( 0 & 0 & 0 & 0 );
+
+ -- Manual Precharge variables
+ VARIABLE A10_precharge : Array_A10_precharge;
+ VARIABLE Bank_precharge : Array_Bank_precharge;
+ VARIABLE Cmnd_precharge : Array_Cmnd_precharge;
+
+ -- Burst Terminate variable
+ VARIABLE Cmnd_bst : Array_Cmnd_bst;
+
+ -- Memory Banks
+ VARIABLE Bank0 : Array_ram_stor;
+ VARIABLE Bank1 : Array_ram_stor;
+ VARIABLE Bank2 : Array_ram_stor;
+ VARIABLE Bank3 : Array_ram_stor;
+
+ -- Burst Counter
+ VARIABLE Burst_counter : STD_LOGIC_VECTOR (cols_bits - 1 DOWNTO 0);
+
+ -- Internal Dqs initialize
+ VARIABLE Dqs_int : STD_LOGIC := '0';
+
+ -- Data buffer for DM Mask
+ VARIABLE Data_buf : STD_LOGIC_VECTOR (data_bits - 1 DOWNTO 0) := (OTHERS => 'Z');
+
+ --
+ -- Initialize empty rows
+ --
+ PROCEDURE Init_mem (Bank : STD_LOGIC_VECTOR; Row_index : INTEGER) IS
+ VARIABLE i, j : INTEGER := 0;
+ BEGIN
+ IF Bank = "00" THEN
+ IF Bank0 (Row_index) = NULL THEN -- Check to see if row empty
+ Bank0 (Row_index) := NEW Array_ram_type; -- Open new row for access
+ FOR i IN (2**cols_bits - 1) DOWNTO 0 LOOP -- Filled row with zeros
+ FOR j IN (data_bits - 1) DOWNTO 0 LOOP
+ Bank0 (Row_index) (i) (j) := '0';
+ END LOOP;
+ END LOOP;
+ END IF;
+ ELSIF Bank = "01" THEN
+ IF Bank1 (Row_index) = NULL THEN
+ Bank1 (Row_index) := NEW Array_ram_type;
+ FOR i IN (2**cols_bits - 1) DOWNTO 0 LOOP
+ FOR j IN (data_bits - 1) DOWNTO 0 LOOP
+ Bank1 (Row_index) (i) (j) := '0';
+ END LOOP;
+ END LOOP;
+ END IF;
+ ELSIF Bank = "10" THEN
+ IF Bank2 (Row_index) = NULL THEN
+ Bank2 (Row_index) := NEW Array_ram_type;
+ FOR i IN (2**cols_bits - 1) DOWNTO 0 LOOP
+ FOR j IN (data_bits - 1) DOWNTO 0 LOOP
+ Bank2 (Row_index) (i) (j) := '0';
+ END LOOP;
+ END LOOP;
+ END IF;
+ ELSIF Bank = "11" THEN
+ IF Bank3 (Row_index) = NULL THEN
+ Bank3 (Row_index) := NEW Array_ram_type;
+ FOR i IN (2**cols_bits - 1) DOWNTO 0 LOOP
+ FOR j IN (data_bits - 1) DOWNTO 0 LOOP
+ Bank3 (Row_index) (i) (j) := '0';
+ END LOOP;
+ END LOOP;
+ END IF;
+ END IF;
+ END;
+
+ --
+ -- Burst Counter
+ --
+ PROCEDURE Burst_decode IS
+ VARIABLE Cols_temp : STD_LOGIC_VECTOR (cols_bits - 1 DOWNTO 0) := (OTHERS => '0');
+ BEGIN
+ -- Advance burst counter
+ Burst_counter := Burst_counter + 1;
+
+ -- Burst Type
+ IF Mode_reg (3) = '0' THEN
+ Cols_temp := Cols_addr + 1;
+ ELSIF Mode_reg (3) = '1' THEN
+ Cols_temp (2) := Burst_counter (2) XOR Cols_brst (2);
+ Cols_temp (1) := Burst_counter (1) XOR Cols_brst (1);
+ Cols_temp (0) := Burst_counter (0) XOR Cols_brst (0);
+ END IF;
+
+ -- Burst Length
+ IF Burst_length_2 = '1' THEN
+ 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;
+ IF Read_precharge (2) = '1' OR Write_precharge (2) = '1' THEN
+ Count_precharge (2) := Count_precharge (2) + 1;
+ END IF;
+ IF Read_precharge (3) = '1' OR Write_precharge (3) = '1' THEN
+ Count_precharge (3) := Count_precharge (3) + 1;
+ END IF;
+
+ -- Read with AutoPrecharge Calculation
+ -- The device start internal precharge when:
+ -- 1. Meet tRAS requirement
+ -- 2. BL/2 cycles after command
+ IF ((Read_precharge(0) = '1') AND (NOW - RAS_chk0 >= tRAS)) THEN
+ IF ((Burst_length_2 = '1' AND Count_precharge(0) >= 1) OR
+ (Burst_length_4 = '1' AND Count_precharge(0) >= 2) OR
+ (Burst_length_8 = '1' AND Count_precharge(0) >= 4)) THEN
+ Pc_b0 := '1';
+ Act_b0 := '0';
+ RP_chk0 := NOW;
+ Read_precharge(0) := '0';
+ END IF;
+ END IF;
+ IF ((Read_precharge(1) = '1') AND (NOW - RAS_chk1 >= tRAS)) THEN
+ IF ((Burst_length_2 = '1' AND Count_precharge(1) >= 1) OR
+ (Burst_length_4 = '1' AND Count_precharge(1) >= 2) OR
+ (Burst_length_8 = '1' AND Count_precharge(1) >= 4)) THEN
+ Pc_b1 := '1';
+ Act_b1 := '0';
+ RP_chk1 := NOW;
+ Read_precharge(1) := '0';
+ END IF;
+ END IF;
+ IF ((Read_precharge(2) = '1') AND (NOW - RAS_chk2 >= tRAS)) THEN
+ IF ((Burst_length_2 = '1' AND Count_precharge(2) >= 1) OR
+ (Burst_length_4 = '1' AND Count_precharge(2) >= 2) OR
+ (Burst_length_8 = '1' AND Count_precharge(2) >= 4)) THEN
+ Pc_b2 := '1';
+ Act_b2 := '0';
+ RP_chk2 := NOW;
+ Read_precharge(2) := '0';
+ END IF;
+ END IF;
+ IF ((Read_precharge(3) = '1') AND (NOW - RAS_chk3 >= tRAS)) THEN
+ IF ((Burst_length_2 = '1' AND Count_precharge(3) >= 1) OR
+ (Burst_length_4 = '1' AND Count_precharge(3) >= 2) OR
+ (Burst_length_8 = '1' AND Count_precharge(3) >= 4)) THEN
+ Pc_b3 := '1';
+ Act_b3 := '0';
+ RP_chk3 := NOW;
+ Read_precharge(3) := '0';
+ END IF;
+ END IF;
+
+ -- Write with AutoPrecharge Calculation
+ -- The device start internal precharge when:
+ -- 1. Meet tRAS requirement
+ -- 2. Two clock after last burst
+ -- Since tWR is time base, the model will compensate tRP
+ IF ((Write_precharge(0) = '1') AND (NOW - RAS_chk0 >= tRAS)) THEN
+ IF ((Burst_length_2 = '1' AND Count_precharge (0) >= 4) OR
+ (Burst_length_4 = '1' AND Count_precharge (0) >= 5) OR
+ (Burst_length_8 = '1' AND Count_precharge (0) >= 7)) THEN
+ Pc_b0 := '1';
+ Act_b0 := '0';
+ RP_chk0 := NOW - ((2 * tCK) - tWR);
+ Write_precharge(0) := '0';
+ END IF;
+ END IF;
+ IF ((Write_precharge(1) = '1') AND (NOW - RAS_chk1 >= tRAS)) THEN
+ IF ((Burst_length_2 = '1' AND Count_precharge (1) >= 4) OR
+ (Burst_length_4 = '1' AND Count_precharge (1) >= 5) OR
+ (Burst_length_8 = '1' AND Count_precharge (1) >= 7)) THEN
+ Pc_b1 := '1';
+ Act_b1 := '0';
+ RP_chk1 := NOW - ((2 * tCK) - tWR);
+ Write_precharge(1) := '0';
+ END IF;
+ END IF;
+ IF ((Write_precharge(2) = '1') AND (NOW - RAS_chk2 >= tRAS)) THEN
+ IF ((Burst_length_2 = '1' AND Count_precharge (2) >= 4) OR
+ (Burst_length_4 = '1' AND Count_precharge (2) >= 5) OR
+ (Burst_length_8 = '1' AND Count_precharge (2) >= 7)) THEN
+ Pc_b2 := '1';
+ Act_b2 := '0';
+ RP_chk2 := NOW - ((2 * tCK) - tWR);
+ Write_precharge(2) := '0';
+ END IF;
+ END IF;
+ IF ((Write_precharge(3) = '1') AND (NOW - RAS_chk3 >= tRAS)) THEN
+ IF ((Burst_length_2 = '1' AND Count_precharge (3) >= 4) OR
+ (Burst_length_4 = '1' AND Count_precharge (3) >= 5) OR
+ (Burst_length_8 = '1' AND Count_precharge (3) >= 7)) THEN
+ Pc_b3 := '1';
+ Act_b3 := '0';
+ RP_chk3 := NOW - ((2 * tCK) - tWR);
+ Write_precharge(3) := '0';
+ END IF;
+ END IF;
+ END IF;
+
+ --
+ -- DLL Counter
+ --
+ IF Sys_clk'EVENT AND Sys_clk = '1' THEN
+ IF (DLL_Reset = '1' AND DLL_done = '0') THEN
+ DLL_count := DLL_count + 1;
+ IF (DLL_count >= 200) THEN
+ DLL_done := '1';
+ END IF;
+ END IF;
+ END IF;
+
+ --
+ -- Control Logic
+ --
+ IF Sys_clk'EVENT AND Sys_clk = '1' THEN
+ -- Auto Refresh
+ IF Aref_enable = '1' THEN
+ -- Auto Refresh to Auto Refresh
+ ASSERT (NOW - RFC_chk >= tRFC)
+ REPORT "tRFC violation during Auto Refresh"
+ SEVERITY WARNING;
+
+ -- Precharge to Auto Refresh
+ ASSERT ((NOW - RP_chk0 >= tRP) AND (NOW - RP_chk1 >= tRP) AND
+ (NOW - RP_chk2 >= tRP) AND (NOW - RP_chk3 >= tRP))
+ REPORT "tRP violation during Auto Refresh"
+ SEVERITY WARNING;
+
+ -- Precharge to Auto Refresh
+ ASSERT (Pc_b0 = '1' AND Pc_b1 = '1' AND Pc_b2 = '1' AND Pc_b3 = '1')
+ REPORT "All banks must be Precharge before Auto Refresh"
+ SEVERITY WARNING;
+
+ -- Record current tRFC time
+ RFC_chk := NOW;
+ END IF;
+
+ -- Extended Load Mode Register
+ IF Ext_mode_enable = '1' THEN
+ IF (Pc_b0 = '1' AND Pc_b1 = '1' AND Pc_b2 = '1' AND Pc_b3 = '1') THEN
+ IF (Addr (0) = '0') THEN
+ DLL_enable := '1';
+ ELSE
+ DLL_enable := '0';
+ END IF;
+ END IF;
+
+ -- Precharge to EMR
+ ASSERT (Pc_b0 = '1' AND Pc_b1 = '1' AND Pc_b2 = '1' AND Pc_b3 = '1')
+ REPORT "All bank must be Precharged before Extended Mode Register"
+ SEVERITY WARNING;
+
+ -- Precharge to EMR
+ ASSERT ((NOW - RP_chk0 >= tRP) AND (NOW - RP_chk1 >= tRP) AND
+ (NOW - RP_chk2 >= tRP) AND (NOW - RP_chk3 >= tRP))
+ REPORT "tRP violation during Extended Load Register"
+ SEVERITY WARNING;
+
+ -- LMR/EMR to EMR
+ ASSERT (NOW - MRD_chk >= tMRD)
+ REPORT "tMRD violation during Extended Mode Register"
+ SEVERITY WARNING;
+
+ -- Record current tMRD time
+ MRD_chk := NOW;
+ END IF;
+
+ -- Load Mode Register
+ IF Mode_reg_enable = '1' THEN
+ -- Register mode
+ Mode_reg <= Addr;
+
+ -- DLL Reset
+ IF (DLL_enable = '1' AND Addr (8) = '1') THEN
+ DLL_reset := '1';
+ DLL_done := '0';
+ DLL_count := 0;
+ ELSIF (DLL_enable = '1' AND DLL_reset = '0' AND Addr (8) = '0') THEN
+ ASSERT (FALSE)
+ REPORT "DLL is ENABLE: DLL RESET is require"
+ SEVERITY WARNING;
+ ELSIF (DLL_enable = '0' AND Addr (8) = '1') THEN
+ ASSERT (FALSE)
+ REPORT "DLL is DISABLE: DLL RESET will be ignored"
+ SEVERITY WARNING;
+ END IF;
+
+ -- Precharge to LMR
+ ASSERT (Pc_b0 = '1' AND Pc_b1 = '1' AND Pc_b2 = '1' AND Pc_b3 = '1')
+ REPORT "All bank must be Precharged before Load Mode Register"
+ SEVERITY WARNING;
+
+ -- Precharge to EMR
+ ASSERT ((NOW - RP_chk0 >= tRP) AND (NOW - RP_chk1 >= tRP) AND
+ (NOW - RP_chk2 >= tRP) AND (NOW - RP_chk3 >= tRP))
+ REPORT "tRP violation during Load Mode Register"
+ SEVERITY WARNING;
+
+ -- LMR/ELMR to LMR
+ ASSERT (NOW - MRD_chk >= tMRD)
+ REPORT "tMRD violation during Load Mode Register"
+ SEVERITY WARNING;
+
+ -- Check for invalid Burst Length
+ ASSERT ((Addr (2 DOWNTO 0) = "001") OR -- BL = 2
+ (Addr (2 DOWNTO 0) = "010") OR -- BL = 4
+ (Addr (2 DOWNTO 0) = "011")) -- BL = 8
+ REPORT "Invalid Burst Length during Load Mode Register"
+ SEVERITY WARNING;
+
+ -- Check for invalid CAS Latency
+ ASSERT ((Addr (6 DOWNTO 4) = "010") OR -- CL = 2.0
+ (Addr (6 DOWNTO 4) = "110")) -- CL = 2.5
+ REPORT "Invalid CAS Latency during Load Mode Register"
+ SEVERITY WARNING;
+
+ -- Record current tMRD time
+ MRD_chk := NOW;
+ END IF;
+
+ -- Active Block (latch Bank and Row Address)
+ IF Active_enable = '1' THEN
+ -- Activate an OPEN bank can corrupt data
+ ASSERT ((Ba = "00" AND Act_b0 = '0') OR
+ (Ba = "01" AND Act_b1 = '0') OR
+ (Ba = "10" AND Act_b2 = '0') OR
+ (Ba = "11" AND Act_b3 = '0'))
+ REPORT "Bank is already activated - data can be corrupted"
+ SEVERITY WARNING;
+
+ -- Activate Bank 0
+ IF Ba = "00" AND Pc_b0 = '1' THEN
+ -- Activate to Activate (same bank)
+ ASSERT (NOW - RC_chk0 >= tRC)
+ REPORT "tRC violation during Activate Bank 0"
+ SEVERITY WARNING;
+
+ -- Precharge to Active
+ ASSERT (NOW - RP_chk0 >= tRP)
+ REPORT "tRP violation during Activate Bank 0"
+ SEVERITY WARNING;
+
+ -- Record Variables for checking violation
+ Act_b0 := '1';
+ Pc_b0 := '0';
+ B0_row_addr := Addr;
+ RC_chk0 := NOW;
+ RCD_chk0 := NOW;
+ RAS_chk0 := NOW;
+ RAP_chk0 := NOW;
+ END IF;
+
+ -- Activate Bank 1
+ IF Ba = "01" AND Pc_b1 = '1' THEN
+ -- Activate to Activate (same bank)
+ ASSERT (NOW - RC_chk1 >= tRC)
+ REPORT "tRC violation during Activate Bank 1"
+ SEVERITY WARNING;
+
+ -- Precharge to Active
+ ASSERT (NOW - RP_chk1 >= tRP)
+ REPORT "tRP violation during Activate Bank 1"
+ SEVERITY WARNING;
+
+ -- Record Variables for checking violation
+ Act_b1 := '1';
+ Pc_b1 := '0';
+ B1_row_addr := Addr;
+ RC_chk1 := NOW;
+ RCD_chk1 := NOW;
+ RAS_chk1 := NOW;
+ RAP_chk1 := NOW;
+ END IF;
+
+ -- Activate Bank 2
+ IF Ba = "10" AND Pc_b2 = '1' THEN
+ -- Activate to Activate (same bank)
+ ASSERT (NOW - RC_chk2 >= tRC)
+ REPORT "tRC violation during Activate Bank 2"
+ SEVERITY WARNING;
+
+ -- Precharge to Active
+ ASSERT (NOW - RP_chk2 >= tRP)
+ REPORT "tRP violation during Activate Bank 2"
+ SEVERITY WARNING;
+
+ -- Record Variables for checking violation
+ Act_b2 := '1';
+ Pc_b2 := '0';
+ B2_row_addr := Addr;
+ RC_chk2 := NOW;
+ RCD_chk2 := NOW;
+ RAS_chk2 := NOW;
+ RAP_chk2 := NOW;
+ END IF;
+
+ -- Activate Bank 3
+ IF Ba = "11" AND Pc_b3 = '1' THEN
+ -- Activate to Activate (same bank)
+ ASSERT (NOW - RC_chk3 >= tRC)
+ REPORT "tRC violation during Activate Bank 3"
+ SEVERITY WARNING;
+
+ -- Precharge to Active
+ ASSERT (NOW - RP_chk3 >= tRP)
+ REPORT "tRP violation during Activate Bank 3"
+ SEVERITY WARNING;
+
+ -- Record Variables for checking violation
+ Act_b3 := '1';
+ Pc_b3 := '0';
+ B3_row_addr := Addr;
+ RC_chk3 := NOW;
+ RCD_chk3 := NOW;
+ RAS_chk3 := NOW;
+ RAP_chk3 := NOW;
+ END IF;
+
+ -- Activate Bank A to Activate Bank B
+ IF (Prev_bank /= Ba) THEN
+ ASSERT (NOW - RRD_chk >= tRRD)
+ REPORT "tRRD violation during Activate"
+ SEVERITY WARNING;
+ END IF;
+
+ -- AutoRefresh to Activate
+ ASSERT (NOW - RFC_chk >= tRFC)
+ REPORT "tRFC violation during Activate"
+ SEVERITY WARNING;
+
+ -- Record Variables for Checking Violation
+ RRD_chk := NOW;
+ Prev_bank := Ba;
+ END IF;
+
+ -- Precharge Block - Consider NOP if bank already precharged or in process of precharging
+ IF Prech_enable = '1' THEN
+ -- EMR or LMR to Precharge
+ ASSERT (NOW - MRD_chk >= tMRD)
+ REPORT "tMRD violation during Precharge"
+ SEVERITY WARNING;
+
+ -- Precharge Bank 0
+ IF ((Addr (10) = '1' OR (Addr (10) = '0' AND Ba = "00")) AND Act_b0 = '1') THEN
+ Act_b0 := '0';
+ Pc_b0 := '1';
+ RP_chk0 := NOW;
+
+ -- Activate to Precharge bank 0
+ ASSERT (NOW - RAS_chk0 >= tRAS)
+ REPORT "tRAS violation during Precharge"
+ SEVERITY WARNING;
+
+ -- tWR violation check for Write
+ ASSERT (NOW - WR_chk0 >= tWR)
+ REPORT "tWR violation during Precharge"
+ SEVERITY WARNING;
+ END IF;
+
+ -- Precharge Bank 1
+ IF ((Addr (10) = '1' OR (Addr (10) = '0' AND Ba = "01")) AND Act_b1 = '1') THEN
+ Act_b1 := '0';
+ Pc_b1 := '1';
+ RP_chk1 := NOW;
+
+ -- Activate to Precharge
+ ASSERT (NOW - RAS_chk1 >= tRAS)
+ REPORT "tRAS violation during Precharge"
+ SEVERITY WARNING;
+
+ -- tWR violation check for Write
+ ASSERT (NOW - WR_chk1 >= tWR)
+ REPORT "tWR violation during Precharge"
+ SEVERITY WARNING;
+ END IF;
+
+ -- Precharge Bank 2
+ IF ((Addr (10) = '1' OR (Addr (10) = '0' AND Ba = "10")) AND Act_b2 = '1') THEN
+ Act_b2 := '0';
+ Pc_b2 := '1';
+ RP_chk2 := NOW;
+
+ -- Activate to Precharge
+ ASSERT (NOW - RAS_chk2 >= tRAS)
+ REPORT "tRAS violation during Precharge"
+ SEVERITY WARNING;
+
+ -- tWR violation check for Write
+ ASSERT (NOW - WR_chk2 >= tWR)
+ REPORT "tWR violation during Precharge"
+ SEVERITY WARNING;
+ END IF;
+
+ -- Precharge Bank 3
+ IF ((Addr (10) = '1' OR (Addr (10) = '0' AND Ba = "11")) AND Act_b3 = '1') THEN
+ Act_b3 := '0';
+ Pc_b3 := '1';
+ RP_chk3 := NOW;
+
+ -- Activate to Precharge
+ ASSERT (NOW - RAS_chk3 >= tRAS)
+ REPORT "tRAS violation during Precharge"
+ SEVERITY WARNING;
+
+ -- tWR violation check for Write
+ ASSERT (NOW - WR_chk3 >= tWR)
+ REPORT "tWR violation during Precharge"
+ SEVERITY WARNING;
+ END IF;
+
+ -- Pipeline for READ
+ IF CAS_latency_15 = '1' THEN
+ A10_precharge (3) := Addr(10);
+ Bank_precharge (3) := Ba;
+ Cmnd_precharge (3) := '1';
+ ELSIF CAS_latency_2 = '1' THEN
+ A10_precharge (4) := Addr(10);
+ Bank_precharge (4) := Ba;
+ Cmnd_precharge (4) := '1';
+ ELSIF CAS_latency_25 = '1' THEN
+ A10_precharge (5) := Addr(10);
+ Bank_precharge (5) := Ba;
+ Cmnd_precharge (5) := '1';
+ ELSIF CAS_latency_3 = '1' THEN
+ A10_precharge (6) := Addr(10);
+ Bank_precharge (6) := Ba;
+ Cmnd_precharge (6) := '1';
+ ELSIF CAS_latency_4 = '1' THEN
+ A10_precharge (8) := Addr(10);
+ Bank_precharge (8) := Ba;
+ Cmnd_precharge (8) := '1';
+ END IF;
+ END IF;
+
+ -- Burst Terminate
+ IF Burst_term = '1' THEN
+ -- Pipeline for Read
+ IF CAS_latency_15 = '1' THEN
+ Cmnd_bst (3) := '1';
+ ELSIF CAS_latency_2 = '1' THEN
+ Cmnd_bst (4) := '1';
+ ELSIF CAS_latency_25 = '1' THEN
+ Cmnd_bst (5) := '1';
+ ELSIF CAS_latency_3 = '1' THEN
+ Cmnd_bst (6) := '1';
+ ELSIF CAS_latency_4 = '1' THEN
+ Cmnd_bst (8) := '1';
+ END IF;
+
+ -- Terminate Write
+ ASSERT (Data_in_enable = '0')
+ REPORT "It's illegal to Burst Terminate a Write"
+ SEVERITY WARNING;
+
+ -- Terminate Read with Auto Precharge
+ ASSERT (Read_precharge (0) = '0' AND Read_precharge (1) = '0' AND
+ Read_precharge (2) = '0' AND Read_precharge (3) = '0')
+ REPORT "It's illegal to Burst Terminate a Read with Auto Precharge"
+ SEVERITY WARNING;
+ END IF;
+
+ -- Read Command
+ IF Read_enable = '1' THEN
+ -- CAS Latency Pipeline
+ IF Cas_latency_15 = '1' THEN
+ Read_cmnd (3) := '1';
+ Read_bank (3) := Ba;
+ Read_cols (3) := Addr (8 DOWNTO 0);
+ ELSIF Cas_latency_2 = '1' THEN
+ Read_cmnd (4) := '1';
+ Read_bank (4) := Ba;
+ Read_cols (4) := Addr (8 DOWNTO 0);
+ ELSIF Cas_latency_25 = '1' THEN
+ Read_cmnd (5) := '1';
+ Read_bank (5) := Ba;
+ Read_cols (5) := Addr (8 DOWNTO 0);
+ ELSIF Cas_latency_3 = '1' THEN
+ Read_cmnd (6) := '1';
+ Read_bank (6) := Ba;
+ Read_cols (6) := Addr (8 DOWNTO 0);
+ ELSIF Cas_latency_4 = '1' THEN
+ Read_cmnd (8) := '1';
+ Read_bank (8) := Ba;
+ Read_cols (8) := Addr (8 DOWNTO 0);
+ END IF;
+
+ -- Write to Read: Terminate Write Immediately
+ IF Data_in_enable = '1' THEN
+ Data_in_enable := '0';
+ END IF;
+
+ -- Interrupting a Read with Auto Precharge (same bank only)
+ ASSERT (Read_precharge(CONV_INTEGER(Ba)) = '0')
+ REPORT "It's illegal to interrupt a Read with Auto Precharge"
+ SEVERITY WARNING;
+
+ -- Activate to Read
+ ASSERT ((Ba = "00" AND Act_b0 = '1') OR
+ (Ba = "01" AND Act_b1 = '1') OR
+ (Ba = "10" AND Act_b2 = '1') OR
+ (Ba = "11" AND Act_b3 = '1'))
+ REPORT "Bank is not Activated for Read"
+ SEVERITY WARNING;
+
+ -- Activate to Read without Auto Precharge
+ IF Addr (10) = '0' THEN
+ ASSERT ((Ba = "00" AND NOW - RCD_chk0 >= tRCD) OR
+ (Ba = "01" AND NOW - RCD_chk1 >= tRCD) OR
+ (Ba = "10" AND NOW - RCD_chk2 >= tRCD) OR
+ (Ba = "11" AND NOW - RCD_chk3 >= tRCD))
+ REPORT "tRCD violation during Read"
+ SEVERITY WARNING;
+ END IF;
+
+ -- Activate to Read with Auto Precharge
+ IF Addr (10) = '1' THEN
+ ASSERT ((Ba = "00" AND NOW - RAP_chk0 >= tRAP) OR
+ (Ba = "01" AND NOW - RAP_chk1 >= tRAP) OR
+ (Ba = "10" AND NOW - RAP_chk2 >= tRAP) OR
+ (Ba = "11" AND NOW - RAP_chk3 >= tRAP))
+ REPORT "tRAP violation during Read"
+ SEVERITY WARNING;
+ END IF;
+
+ -- Auto precharge
+ IF Addr (10) = '1' THEN
+ Read_precharge (Conv_INTEGER(Ba)) := '1';
+ Count_precharge (Conv_INTEGER(Ba)) := 0;
+ END IF;
+
+ -- DLL Check
+ IF (DLL_reset = '1') THEN
+ ASSERT (DLL_done = '1')
+ REPORT "DLL RESET not complete"
+ SEVERITY WARNING;
+ END IF;
+ END IF;
+
+ -- Write Command
+ IF Write_enable = '1' THEN
+ -- Pipeline for Write
+ Write_cmnd (2) := '1';
+ Write_bank (2) := Ba;
+ Write_cols (2) := Addr (8 DOWNTO 0);
+
+ -- Interrupting a Write with Auto Precharge (same bank only)
+ ASSERT (Write_precharge(CONV_INTEGER(Ba)) = '0')
+ REPORT "It's illegal to interrupt a Write with Auto Precharge"
+ SEVERITY WARNING;
+
+ -- Activate to Write
+ ASSERT ((Ba = "00" AND Act_b0 = '1') OR
+ (Ba = "01" AND Act_b1 = '1') OR
+ (Ba = "10" AND Act_b2 = '1') OR
+ (Ba = "11" AND Act_b3 = '1'))
+ REPORT "Bank is not Activated for Write"
+ SEVERITY WARNING;
+
+ -- Activate to Write
+ ASSERT ((Ba = "00" AND NOW - RCD_chk0 >= tRCD) OR
+ (Ba = "01" AND NOW - RCD_chk1 >= tRCD) OR
+ (Ba = "10" AND NOW - RCD_chk2 >= tRCD) OR
+ (Ba = "11" AND NOW - RCD_chk3 >= tRCD))
+ REPORT "tRCD violation during Write"
+ SEVERITY WARNING;
+
+ -- Auto precharge
+ IF Addr (10) = '1' THEN
+ Write_precharge (Conv_INTEGER(Ba)) := '1';
+ Count_precharge (Conv_INTEGER(Ba)) := 0;
+ END IF;
+ END IF;
+ END IF;
+ END PROCESS;
+
+ --
+ -- Dqs Receiver
+ --
+ dqs_rcvrs : PROCESS
+ VARIABLE Dm_temp : STD_LOGIC_VECTOR (1 DOWNTO 0);
+ VARIABLE Dq_temp : STD_LOGIC_VECTOR (data_bits - 1 DOWNTO 0);
+ BEGIN
+ WAIT ON Dqs;
+ -- Latch data at posedge Dqs
+ IF Dqs'EVENT AND Dqs (1) = '1' AND Dqs (0) = '1' THEN
+ Dq_temp := Dq;
+ Dm_temp := Dm;
+ END IF;
+ -- Latch data at negedge Dqs
+ IF Dqs'EVENT AND Dqs (1) = '0' AND Dqs (0) = '0' THEN
+ Dq_pair <= (Dq & Dq_temp);
+ Dm_pair <= (Dm & Dm_temp);
+ END IF;
+ END PROCESS;
+
+ --
+ -- Setup timing checks
+ --
+ Setup_check : PROCESS
+ BEGIN
+ WAIT ON Sys_clk;
+ IF Sys_clk'EVENT AND Sys_clk = '1' THEN
+ ASSERT(Cke'LAST_EVENT >= tIS)
+ REPORT "CKE Setup time violation -- tIS"
+ SEVERITY WARNING;
+ ASSERT(Cs_n'LAST_EVENT >= tIS)
+ REPORT "CS# Setup time violation -- tIS"
+ SEVERITY WARNING;
+ ASSERT(Cas_n'LAST_EVENT >= tIS)
+ REPORT "CAS# Setup time violation -- tIS"
+ SEVERITY WARNING;
+ ASSERT(Ras_n'LAST_EVENT >= tIS)
+ REPORT "RAS# Setup time violation -- tIS"
+ SEVERITY WARNING;
+ ASSERT(We_n'LAST_EVENT >= tIS)
+ REPORT "WE# Setup time violation -- tIS"
+ SEVERITY WARNING;
+ ASSERT(Addr'LAST_EVENT >= tIS)
+ REPORT "ADDR Setup time violation -- tIS"
+ SEVERITY WARNING;
+ ASSERT(Ba'LAST_EVENT >= tIS)
+ REPORT "BA Setup time violation -- tIS"
+ SEVERITY WARNING;
+ END IF;
+ END PROCESS;
+
+ --
+ -- Hold timing checks
+ --
+ Hold_check : PROCESS
+ BEGIN
+ WAIT ON Sys_clk'DELAYED (tIH);
+ IF Sys_clk'DELAYED (tIH) = '1' THEN
+ ASSERT(Cke'LAST_EVENT >= tIH)
+ REPORT "CKE Hold time violation -- tIH"
+ SEVERITY WARNING;
+ ASSERT(Cs_n'LAST_EVENT >= tIH)
+ REPORT "CS# Hold time violation -- tIH"
+ SEVERITY WARNING;
+ ASSERT(Cas_n'LAST_EVENT >= tIH)
+ REPORT "CAS# Hold time violation -- tIH"
+ SEVERITY WARNING;
+ ASSERT(Ras_n'LAST_EVENT >= tIH)
+ REPORT "RAS# Hold time violation -- tIH"
+ SEVERITY WARNING;
+ ASSERT(We_n'LAST_EVENT >= tIH)
+ REPORT "WE# Hold time violation -- tIH"
+ SEVERITY WARNING;
+ ASSERT(Addr'LAST_EVENT >= tIH)
+ REPORT "ADDR Hold time violation -- tIH"
+ SEVERITY WARNING;
+ ASSERT(Ba'LAST_EVENT >= tIH)
+ REPORT "BA Hold time violation -- tIH"
+ SEVERITY WARNING;
+ END IF;
+ END PROCESS;
+
+END behave;
diff --git a/misc/wishbone/src/atomic32_access.vhd b/misc/wishbone/src/atomic32_access.vhd
index b062f98..9bc9825 100644
--- a/misc/wishbone/src/atomic32_access.vhd
+++ b/misc/wishbone/src/atomic32_access.vhd
@@ -1,132 +1,132 @@
-library IEEE;
-use IEEE.STD_LOGIC_1164.ALL;
-use IEEE.STD_LOGIC_UNSIGNED.ALL;
-
-library work;
---use work.phi_config.all;
-use work.wishbone_pkg.all;
-
-entity atomic32_access is
- port ( cpu_clk : in std_logic;
- areset : in std_logic;
-
- -- Wishbone from CPU interface
- wb_16_i : in wishbone_bus_in;
- wb_16_o : out wishbone_bus_out;
-
- -- Wishbone to FPGA registers and ethernet core
- wb_32_i : in wishbone_bus_out;
- wb_32_o : out wishbone_bus_in);
-end atomic32_access;
-
-architecture behave of atomic32_access is
-
-type eth_state_wr_type is (idle, lsb_msb, lsb, msb, write, ack, wait_st);
-signal eth_state_wr : eth_state_wr_type;
-type eth_state_rd_type is (idle, lsb_msb, lsb_read, lsb, wait_st2, msb);
-signal eth_state_rd : eth_state_rd_type;
-signal core_data : std_logic_vector(31 downto 0);
-signal core_addr : std_logic_vector(31 downto 0);
-
-begin
- process(cpu_clk, areset)
- begin
- if areset = '1' then
- eth_state_wr <= idle;
- eth_state_rd <= idle;
- wb_32_o.stb <= '0';
- wb_32_o.cyc <= '0';
- wb_16_o.ack <= '0';
- core_data <= (others => '0');
- core_addr <= (others => '0');
- elsif (rising_edge(cpu_clk)) then
-
- case eth_state_wr is --write cycle
- when idle =>
- if wb_16_i.cyc = '1' and wb_16_i.we = '1' then
- eth_state_wr <= lsb_msb;
- end if;
- when lsb_msb =>
- if wb_16_i.adr(1) = '0' then
- eth_state_wr <= lsb;
- end if;
- if wb_16_i.adr(1) = '1' then
- eth_state_wr <= msb;
- end if;
- when lsb =>
- core_data(15 downto 0) <= wb_16_i.dat(15 downto 0);
- wb_16_o.ack <= '1';
- eth_state_wr <= wait_st;
- when msb =>
- core_data(31 downto 16) <= wb_16_i.dat(31 downto 16);
- core_addr <= wb_16_i.adr(31 downto 2) & "00";
- eth_state_wr <= write;
- when write =>
- wb_32_o.dat <= core_data;
- wb_32_o.adr <= core_addr;
- wb_32_o.sel <= "1111";
- wb_32_o.we <= '1';
- wb_32_o.stb <= '1';
- wb_32_o.cyc <= '1';
- eth_state_wr <= ack;
- when ack =>
- if wb_32_i.ack = '1' then
- wb_16_o.ack <= '1';
- eth_state_wr <= wait_st;
- wb_32_o.stb <= '0';
- wb_32_o.cyc <= '0';
- wb_32_o.sel <= "0000";
- wb_32_o.we <= '0';
- end if;
- when wait_st =>
- wb_16_o.ack <= '0';
- eth_state_wr <= idle;
- when others =>
- eth_state_wr <= idle;
- end case;
-
- case eth_state_rd is --read cycle
- when idle =>
- if wb_16_i.cyc = '1' and wb_16_i.we = '0' then
- core_addr <= wb_16_i.adr(31 downto 2) & "00";
- eth_state_rd <= lsb_msb;
- end if;
- when lsb_msb =>
- if wb_16_i.adr(1) = '0' then
- wb_32_o.adr <= core_addr;
- eth_state_rd <= lsb_read;
- end if;
- if wb_16_i.adr(1) = '1' then
- wb_32_o.adr <= core_addr;
- eth_state_rd <= msb;
- end if;
- when lsb_read =>
- wb_32_o.sel <= "1111";
- wb_32_o.we <= '0';
- wb_32_o.stb <= '1';
- wb_32_o.cyc <= '1';
- eth_state_rd <= lsb;
- when lsb =>
- if wb_32_i.ack = '1' then
- wb_32_o.sel <= "0000";
- wb_32_o.stb <= '0';
- wb_32_o.cyc <= '0';
- core_data <= wb_32_i.dat;
- wb_16_o.dat <= x"0000" & wb_32_i.dat(15 downto 0);
- wb_16_o.ack <= '1';
- eth_state_rd <= wait_st2;
- end if;
- when wait_st2 =>
- wb_16_o.ack <= '0';
- eth_state_rd <= idle;
- when msb =>
- wb_16_o.ack <= '1';
- wb_16_o.dat <= core_data(31 downto 16) & x"0000";
- eth_state_rd <= wait_st2;
- when others =>
- eth_state_rd <= idle;
- end case;
- end if;
- end process;
-
+library IEEE;
+use IEEE.STD_LOGIC_1164.ALL;
+use IEEE.STD_LOGIC_UNSIGNED.ALL;
+
+library work;
+--use work.phi_config.all;
+use work.wishbone_pkg.all;
+
+entity atomic32_access is
+ port ( cpu_clk : in std_logic;
+ areset : in std_logic;
+
+ -- Wishbone from CPU interface
+ wb_16_i : in wishbone_bus_in;
+ wb_16_o : out wishbone_bus_out;
+
+ -- Wishbone to FPGA registers and ethernet core
+ wb_32_i : in wishbone_bus_out;
+ wb_32_o : out wishbone_bus_in);
+end atomic32_access;
+
+architecture behave of atomic32_access is
+
+type eth_state_wr_type is (idle, lsb_msb, lsb, msb, write, ack, wait_st);
+signal eth_state_wr : eth_state_wr_type;
+type eth_state_rd_type is (idle, lsb_msb, lsb_read, lsb, wait_st2, msb);
+signal eth_state_rd : eth_state_rd_type;
+signal core_data : std_logic_vector(31 downto 0);
+signal core_addr : std_logic_vector(31 downto 0);
+
+begin
+ process(cpu_clk, areset)
+ begin
+ if areset = '1' then
+ eth_state_wr <= idle;
+ eth_state_rd <= idle;
+ wb_32_o.stb <= '0';
+ wb_32_o.cyc <= '0';
+ wb_16_o.ack <= '0';
+ core_data <= (others => '0');
+ core_addr <= (others => '0');
+ elsif (rising_edge(cpu_clk)) then
+
+ case eth_state_wr is --write cycle
+ when idle =>
+ if wb_16_i.cyc = '1' and wb_16_i.we = '1' then
+ eth_state_wr <= lsb_msb;
+ end if;
+ when lsb_msb =>
+ if wb_16_i.adr(1) = '0' then
+ eth_state_wr <= lsb;
+ end if;
+ if wb_16_i.adr(1) = '1' then
+ eth_state_wr <= msb;
+ end if;
+ when lsb =>
+ core_data(15 downto 0) <= wb_16_i.dat(15 downto 0);
+ wb_16_o.ack <= '1';
+ eth_state_wr <= wait_st;
+ when msb =>
+ core_data(31 downto 16) <= wb_16_i.dat(31 downto 16);
+ core_addr <= wb_16_i.adr(31 downto 2) & "00";
+ eth_state_wr <= write;
+ when write =>
+ wb_32_o.dat <= core_data;
+ wb_32_o.adr <= core_addr;
+ wb_32_o.sel <= "1111";
+ wb_32_o.we <= '1';
+ wb_32_o.stb <= '1';
+ wb_32_o.cyc <= '1';
+ eth_state_wr <= ack;
+ when ack =>
+ if wb_32_i.ack = '1' then
+ wb_16_o.ack <= '1';
+ eth_state_wr <= wait_st;
+ wb_32_o.stb <= '0';
+ wb_32_o.cyc <= '0';
+ wb_32_o.sel <= "0000";
+ wb_32_o.we <= '0';
+ end if;
+ when wait_st =>
+ wb_16_o.ack <= '0';
+ eth_state_wr <= idle;
+ when others =>
+ eth_state_wr <= idle;
+ end case;
+
+ case eth_state_rd is --read cycle
+ when idle =>
+ if wb_16_i.cyc = '1' and wb_16_i.we = '0' then
+ core_addr <= wb_16_i.adr(31 downto 2) & "00";
+ eth_state_rd <= lsb_msb;
+ end if;
+ when lsb_msb =>
+ if wb_16_i.adr(1) = '0' then
+ wb_32_o.adr <= core_addr;
+ eth_state_rd <= lsb_read;
+ end if;
+ if wb_16_i.adr(1) = '1' then
+ wb_32_o.adr <= core_addr;
+ eth_state_rd <= msb;
+ end if;
+ when lsb_read =>
+ wb_32_o.sel <= "1111";
+ wb_32_o.we <= '0';
+ wb_32_o.stb <= '1';
+ wb_32_o.cyc <= '1';
+ eth_state_rd <= lsb;
+ when lsb =>
+ if wb_32_i.ack = '1' then
+ wb_32_o.sel <= "0000";
+ wb_32_o.stb <= '0';
+ wb_32_o.cyc <= '0';
+ core_data <= wb_32_i.dat;
+ wb_16_o.dat <= x"0000" & wb_32_i.dat(15 downto 0);
+ wb_16_o.ack <= '1';
+ eth_state_rd <= wait_st2;
+ end if;
+ when wait_st2 =>
+ wb_16_o.ack <= '0';
+ eth_state_rd <= idle;
+ when msb =>
+ wb_16_o.ack <= '1';
+ wb_16_o.dat <= core_data(31 downto 16) & x"0000";
+ eth_state_rd <= wait_st2;
+ when others =>
+ eth_state_rd <= idle;
+ end case;
+ end if;
+ end process;
+
end behave; \ No newline at end of file
diff --git a/misc/wishbone/src/wishbone_pkg.vhd b/misc/wishbone/src/wishbone_pkg.vhd
index c3b0d9b..359a33f 100644
--- a/misc/wishbone/src/wishbone_pkg.vhd
+++ b/misc/wishbone/src/wishbone_pkg.vhd
@@ -1,52 +1,52 @@
-library IEEE;
-use IEEE.STD_LOGIC_1164.all;
-use IEEE.STD_LOGIC_UNSIGNED.ALL;
-
-package wishbone_pkg is
-
- type wishbone_bus_in is record
- adr : std_logic_vector(31 downto 0);
- sel : std_logic_vector(3 downto 0);
- we : std_logic;
- dat : std_logic_vector(31 downto 0); -- Note! Data written with 'we'
- cyc : std_logic;
- stb : std_logic;
- end record;
-
- type wishbone_bus_out is record
- dat : std_logic_vector(31 downto 0);
- ack : std_logic;
- end record;
-
- type wishbone_bus is record
- insig : wishbone_bus_in;
- outsig : wishbone_bus_out;
- end record;
-
- component atomic32_access is
- port ( cpu_clk : in std_logic;
- areset : in std_logic;
-
- -- Wishbone from CPU interface
- wb_16_i : in wishbone_bus_in;
- wb_16_o : out wishbone_bus_out;
- -- Wishbone to FPGA registers and ethernet core
- wb_32_i : in wishbone_bus_out;
- wb_32_o : out wishbone_bus_in);
- end component;
-
- component eth_access_corr is
- port ( cpu_clk : in std_logic;
- areset : in std_logic;
-
- -- Wishbone from Wishbone MUX
- eth_raw_o : out wishbone_bus_out;
- eth_raw_i : in wishbone_bus_in;
-
- -- Wishbone ethernet core
- eth_slave_i : in wishbone_bus_out;
- eth_slave_o : out wishbone_bus_in);
- end component;
-
-
-end wishbone_pkg;
+library IEEE;
+use IEEE.STD_LOGIC_1164.all;
+use IEEE.STD_LOGIC_UNSIGNED.ALL;
+
+package wishbone_pkg is
+
+ type wishbone_bus_in is record
+ adr : std_logic_vector(31 downto 0);
+ sel : std_logic_vector(3 downto 0);
+ we : std_logic;
+ dat : std_logic_vector(31 downto 0); -- Note! Data written with 'we'
+ cyc : std_logic;
+ stb : std_logic;
+ end record;
+
+ type wishbone_bus_out is record
+ dat : std_logic_vector(31 downto 0);
+ ack : std_logic;
+ end record;
+
+ type wishbone_bus is record
+ insig : wishbone_bus_in;
+ outsig : wishbone_bus_out;
+ end record;
+
+ component atomic32_access is
+ port ( cpu_clk : in std_logic;
+ areset : in std_logic;
+
+ -- Wishbone from CPU interface
+ wb_16_i : in wishbone_bus_in;
+ wb_16_o : out wishbone_bus_out;
+ -- Wishbone to FPGA registers and ethernet core
+ wb_32_i : in wishbone_bus_out;
+ wb_32_o : out wishbone_bus_in);
+ end component;
+
+ component eth_access_corr is
+ port ( cpu_clk : in std_logic;
+ areset : in std_logic;
+
+ -- Wishbone from Wishbone MUX
+ eth_raw_o : out wishbone_bus_out;
+ eth_raw_i : in wishbone_bus_in;
+
+ -- Wishbone ethernet core
+ eth_slave_i : in wishbone_bus_out;
+ eth_slave_o : out wishbone_bus_in);
+ end component;
+
+
+end wishbone_pkg;
OpenPOWER on IntegriCloud