library ieee; use ieee.std_logic_1164.all; use ieee.numeric_std.all; use std.textio.all; library work; use work.wishbone_types.all; use work.sim_console.all; entity litedram_wrapper is generic ( DRAM_ABITS : positive; DRAM_ALINES : positive ); port( -- LiteDRAM generates the system clock and reset -- from the input clkin clk_in : in std_ulogic; rst : in std_ulogic; system_clk : out std_ulogic; system_reset : out std_ulogic; core_alt_reset : out std_ulogic; pll_locked : out std_ulogic; -- Wishbone ports: wb_in : in wishbone_master_out; wb_out : out wishbone_slave_out; wb_is_csr : in std_ulogic; wb_is_init : in std_ulogic; -- Init core serial debug serial_tx : out std_ulogic; serial_rx : in std_ulogic; -- Misc init_done : out std_ulogic; init_error : out std_ulogic; -- DRAM wires ddram_a : out std_ulogic_vector(DRAM_ALINES-1 downto 0); ddram_ba : out std_ulogic_vector(2 downto 0); ddram_ras_n : out std_ulogic; ddram_cas_n : out std_ulogic; ddram_we_n : out std_ulogic; ddram_cs_n : out std_ulogic; ddram_dm : out std_ulogic_vector(1 downto 0); ddram_dq : inout std_ulogic_vector(15 downto 0); ddram_dqs_p : inout std_ulogic_vector(1 downto 0); ddram_dqs_n : inout std_ulogic_vector(1 downto 0); ddram_clk_p : out std_ulogic; ddram_clk_n : out std_ulogic; ddram_cke : out std_ulogic; ddram_odt : out std_ulogic; ddram_reset_n : out std_ulogic ); end entity litedram_wrapper; architecture behaviour of litedram_wrapper is component litedram_core port ( clk : in std_ulogic; rst : in std_ulogic; serial_tx : out std_ulogic; serial_rx : in std_ulogic; pll_locked : out std_ulogic; ddram_a : out std_ulogic_vector(DRAM_ALINES-1 downto 0); ddram_ba : out std_ulogic_vector(2 downto 0); ddram_ras_n : out std_ulogic; ddram_cas_n : out std_ulogic; ddram_we_n : out std_ulogic; ddram_cs_n : out std_ulogic; ddram_dm : out std_ulogic_vector(1 downto 0); ddram_dq : inout std_ulogic_vector(15 downto 0); ddram_dqs_p : inout std_ulogic_vector(1 downto 0); ddram_dqs_n : inout std_ulogic_vector(1 downto 0); ddram_clk_p : out std_ulogic; ddram_clk_n : out std_ulogic; ddram_cke : out std_ulogic; ddram_odt : out std_ulogic; ddram_reset_n : out std_ulogic; init_done : out std_ulogic; init_error : out std_ulogic; user_clk : out std_ulogic; user_rst : out std_ulogic; user_port_native_0_cmd_valid : in std_ulogic; user_port_native_0_cmd_ready : out std_ulogic; user_port_native_0_cmd_we : in std_ulogic; user_port_native_0_cmd_addr : in std_ulogic_vector(DRAM_ABITS-1 downto 0); user_port_native_0_wdata_valid : in std_ulogic; user_port_native_0_wdata_ready : out std_ulogic; user_port_native_0_wdata_we : in std_ulogic_vector(15 downto 0); user_port_native_0_wdata_data : in std_ulogic_vector(127 downto 0); user_port_native_0_rdata_valid : out std_ulogic; user_port_native_0_rdata_ready : in std_ulogic; user_port_native_0_rdata_data : out std_ulogic_vector(127 downto 0) ); end component; signal user_port0_cmd_valid : std_ulogic; signal user_port0_cmd_ready : std_ulogic; signal user_port0_cmd_we : std_ulogic; signal user_port0_cmd_addr : std_ulogic_vector(DRAM_ABITS-1 downto 0); signal user_port0_wdata_valid : std_ulogic; signal user_port0_wdata_ready : std_ulogic; signal user_port0_wdata_we : std_ulogic_vector(15 downto 0); signal user_port0_wdata_data : std_ulogic_vector(127 downto 0); signal user_port0_rdata_valid : std_ulogic; signal user_port0_rdata_ready : std_ulogic; signal user_port0_rdata_data : std_ulogic_vector(127 downto 0); signal ad3 : std_ulogic; signal dram_user_reset : std_ulogic; type state_t is (CMD, MWRITE, MREAD); signal state : state_t; begin -- Address bit 3 selects the top or bottom half of the data -- bus (64-bit wishbone vs. 128-bit DRAM interface) -- ad3 <= wb_in.adr(3); -- DRAM interface signals user_port0_cmd_valid <= (wb_in.cyc and wb_in.stb and not wb_is_csr and not wb_is_init) when state = CMD else '0'; user_port0_cmd_we <= wb_in.we when state = CMD else '0'; user_port0_wdata_valid <= '1' when state = MWRITE else '0'; user_port0_rdata_ready <= '1' when state = MREAD else '0'; user_port0_cmd_addr <= wb_in.adr(DRAM_ABITS+3 downto 4); user_port0_wdata_data <= wb_in.dat & wb_in.dat; user_port0_wdata_we <= wb_in.sel & "00000000" when ad3 = '1' else "00000000" & wb_in.sel; -- Wishbone out signals. CSR and init memory do nothing, just ack wb_out.ack <= '1' when (wb_is_csr = '1' or wb_is_init = '1') else user_port0_wdata_ready when state = MWRITE else user_port0_rdata_valid when state = MREAD else '0'; wb_out.dat <= (others => '0') when (wb_is_csr = '1' or wb_is_init = '1') else user_port0_rdata_data(127 downto 64) when ad3 = '1' else user_port0_rdata_data(63 downto 0); wb_out.stall <= '0' when wb_in.cyc = '0' else not wb_out.ack; -- Reset, lift it when init done, no alt core reset system_reset <= dram_user_reset or not init_done; core_alt_reset <= '0'; -- State machine sm: process(system_clk) begin if rising_edge(system_clk) then if dram_user_reset = '1' then state <= CMD; else case state is when CMD => if (user_port0_cmd_ready and user_port0_cmd_valid) = '1' then state <= MWRITE when wb_in.we = '1' else MREAD; end if; when MWRITE => if user_port0_wdata_ready = '1' then state <= CMD; end if; when MREAD => if user_port0_rdata_valid = '1' then state <= CMD; end if; end case; end if; end if; end process; litedram: litedram_core port map( clk => clk_in, rst => rst, serial_tx => serial_tx, serial_rx => serial_rx, pll_locked => pll_locked, ddram_a => ddram_a, ddram_ba => ddram_ba, ddram_ras_n => ddram_ras_n, ddram_cas_n => ddram_cas_n, ddram_we_n => ddram_we_n, ddram_cs_n => ddram_cs_n, ddram_dm => ddram_dm, ddram_dq => ddram_dq, ddram_dqs_p => ddram_dqs_p, ddram_dqs_n => ddram_dqs_n, ddram_clk_p => ddram_clk_p, ddram_clk_n => ddram_clk_n, ddram_cke => ddram_cke, ddram_odt => ddram_odt, ddram_reset_n => ddram_reset_n, init_done => init_done, init_error => init_error, user_clk => system_clk, user_rst => dram_user_reset, user_port_native_0_cmd_valid => user_port0_cmd_valid, user_port_native_0_cmd_ready => user_port0_cmd_ready, user_port_native_0_cmd_we => user_port0_cmd_we, user_port_native_0_cmd_addr => user_port0_cmd_addr, user_port_native_0_wdata_valid => user_port0_wdata_valid, user_port_native_0_wdata_ready => user_port0_wdata_ready, user_port_native_0_wdata_we => user_port0_wdata_we, user_port_native_0_wdata_data => user_port0_wdata_data, user_port_native_0_rdata_valid => user_port0_rdata_valid, user_port_native_0_rdata_ready => user_port0_rdata_ready, user_port_native_0_rdata_data => user_port0_rdata_data ); end architecture behaviour;