------------------------------------------------------------------------------- -- Title : Dual-port RAM for WR core -- Project : WhiteRabbit ------------------------------------------------------------------------------- -- File : wrc_dpram.vhd -- Author : Grzegorz Daniluk -- Company : CERN -- Created : 2011-02-15 -- Last update: 2018-03-08 -- Platform : FPGA-generics -- Standard : VHDL '93 ------------------------------------------------------------------------------- -- Description: -- -- Dual port RAM with wishbone interface ------------------------------------------------------------------------------- -- Copyright (c) 2011-2017 CERN -- -- This source file is free software; you can redistribute it -- and/or modify it under the terms of the GNU Lesser General -- Public License as published by the Free Software Foundation; -- either version 2.1 of the License, or (at your option) any -- later version. -- -- This source is distributed in the hope that it will be -- useful, but WITHOUT ANY WARRANTY; without even the implied -- warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR -- PURPOSE. See the GNU Lesser General Public License for more -- details. -- -- You should have received a copy of the GNU Lesser General -- Public License along with this source; if not, download it -- from http://www.gnu.org/licenses/lgpl-2.1.html ------------------------------------------------------------------------------- -- Revisions : -- Date Version Author Description -- 2011-02-15 1.0 greg.d Created -- 2011-06-09 1.01 twlostow Removed unnecessary generics -- 2011-21-09 1.02 twlostow Struct-ized version ------------------------------------------------------------------------------- library ieee; use ieee.std_logic_1164.all; use ieee.numeric_std.all; library work; use work.genram_pkg.all; use work.wishbone_pkg.all; entity xwb_dpram is generic( g_size : natural := 16384; g_init_file : string := ""; g_must_have_init_file : boolean := true; g_slave1_interface_mode : t_wishbone_interface_mode; g_slave2_interface_mode : t_wishbone_interface_mode; g_slave1_granularity : t_wishbone_address_granularity; g_slave2_granularity : t_wishbone_address_granularity ); port( clk_sys_i : in std_logic; rst_n_i : in std_logic; slave1_i : in t_wishbone_slave_in; slave1_o : out t_wishbone_slave_out; slave2_i : in t_wishbone_slave_in; slave2_o : out t_wishbone_slave_out ); end xwb_dpram; architecture struct of xwb_dpram is signal s_wea : std_logic; signal s_web : std_logic; signal s_bwea : std_logic_vector(3 downto 0); signal s_bweb : std_logic_vector(3 downto 0); signal slave1_in : t_wishbone_slave_in; signal slave1_out : t_wishbone_slave_out; signal slave2_in : t_wishbone_slave_in; signal slave2_out : t_wishbone_slave_out; begin U_Adapter1 : wb_slave_adapter generic map ( g_master_use_struct => true, g_master_mode => g_slave1_interface_mode, g_master_granularity => WORD, g_slave_use_struct => true, g_slave_mode => g_slave1_interface_mode, g_slave_granularity => g_slave1_granularity) port map ( clk_sys_i => clk_sys_i, rst_n_i => rst_n_i, slave_i => slave1_i, slave_o => slave1_o, master_i => slave1_out, master_o => slave1_in); U_Adapter2 : wb_slave_adapter generic map ( g_master_use_struct => true, g_master_mode => g_slave2_interface_mode, g_master_granularity => WORD, g_slave_use_struct => true, g_slave_mode => g_slave2_interface_mode, g_slave_granularity => g_slave2_granularity) port map ( clk_sys_i => clk_sys_i, rst_n_i => rst_n_i, slave_i => slave2_i, slave_o => slave2_o, master_i => slave2_out, master_o => slave2_in); U_DPRAM : generic_dpram generic map( -- standard parameters g_data_width => 32, g_size => g_size, g_with_byte_enable => true, g_addr_conflict_resolution => "dont_care", g_init_file => g_init_file, g_dual_clock => false ) port map( rst_n_i => rst_n_i, -- Port A clka_i => clk_sys_i, bwea_i => s_bwea, wea_i => s_wea, aa_i => slave1_in.adr(f_log2_size(g_size)-1 downto 0), da_i => slave1_in.dat, qa_o => slave1_out.dat, -- Port B clkb_i => clk_sys_i, bweb_i => s_bweb, web_i => s_web, ab_i => slave2_in.adr(f_log2_size(g_size)-1 downto 0), db_i => slave2_in.dat, qb_o => slave2_out.dat ); -- I know this looks weird, but otherwise ISE generates distributed RAM instead of block -- RAM s_bwea <= slave1_in.sel when s_wea = '1' else f_zeros(c_wishbone_data_width/8); s_bweb <= slave2_in.sel when s_web = '1' else f_zeros(c_wishbone_data_width/8); s_wea <= slave1_in.we and slave1_in.stb and slave1_in.cyc; s_web <= slave2_in.we and slave2_in.stb and slave2_in.cyc; process(clk_sys_i) begin if(rising_edge(clk_sys_i)) then if(rst_n_i = '0') then slave1_out.ack <= '0'; slave2_out.ack <= '0'; else if(slave1_out.ack = '1' and g_slave1_interface_mode = CLASSIC) then slave1_out.ack <= '0'; else slave1_out.ack <= slave1_in.cyc and slave1_in.stb; end if; if(slave2_out.ack = '1' and g_slave2_interface_mode = CLASSIC) then slave2_out.ack <= '0'; else slave2_out.ack <= slave2_in.cyc and slave2_in.stb; end if; end if; end if; end process; slave1_out.stall <= '0'; slave2_out.stall <= '0'; slave1_out.err <= '0'; slave2_out.err <= '0'; slave1_out.rty <= '0'; slave2_out.rty <= '0'; end struct;