-------------------------------------------------------------------------------
-- Title      : SWCore - RAM model read-after-write
-- Project    : WhiteRabbit switch
-------------------------------------------------------------------------------
-- File       : swc_rd_wr_ram.vhd
-- Author     : Tomasz Wlostowski
-- Company    : CERN BE-CO-HT
-- Created    : 2012-03-18
-- Last update: 2012-03-18
-- Platform   : FPGA-generic
-- Standard   : VHDL
-------------------------------------------------------------------------------
--
-- Copyright (c) 2012 CERN / BE-CO-HT
--
-- 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
--
-------------------------------------------------------------------------------

library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;

use work.genram_pkg.all;

library UNISIM;
use UNISIM.vcomponents.all;

Library xpm;
use xpm.vcomponents.all;

entity swc_rd_wr_ram is

  generic(
    g_data_width : integer;
    g_size       : integer;
    g_use_native : boolean := false);
  port(
    clk_i   : in std_logic;
    rst_n_i : in std_logic := '1';
    we_i    : in std_logic;
    wa_i    : in std_logic_vector(f_log2_size(g_size)-1 downto 0);
    wd_i    : in std_logic_vector(g_data_width-1 downto 0);

    ra_i : in  std_logic_vector(f_log2_size(g_size)-1 downto 0);
    rd_o : out std_logic_vector(g_data_width-1 downto 0)
    );

end swc_rd_wr_ram;


architecture rtl of swc_rd_wr_ram is

  signal rstb   : std_logic;
  signal wen    : std_logic_vector(g_data_width/8-1 downto 0);

begin  -- rtl
  
  wen     <= (others => we_i);
  
-- xpm_memory_sdpram: Simple Dual Port RAM
-- Xilinx Parameterized Macro, Version 2017.4
  xpm_memory_sdpram_inst : xpm_memory_sdpram
  generic map (

    -- Common module generics
    MEMORY_SIZE             => g_size*g_data_width,   --positive integer
    MEMORY_PRIMITIVE        => "auto",         --string; "auto", "distributed", "block" or "ultra" ;
    CLOCKING_MODE           => "common_clock", --string; "common_clock", "independent_clock" 
    MEMORY_INIT_FILE        => "none",         --string; "none" or "<filename>.mem" 
    MEMORY_INIT_PARAM       => "",             --string;
    USE_MEM_INIT            => 0,              --integer; 0,1
    WAKEUP_TIME             => "disable_sleep",--string; "disable_sleep" or "use_sleep_pin" 
    MESSAGE_CONTROL         => 1,              --integer; 0,1
    ECC_MODE                => "no_ecc",       --string; "no_ecc", "encode_only", "decode_only" or "both_encode_and_decode" 
    AUTO_SLEEP_TIME         => 0,              --Do not Change
-- +---------------------------------------------------------------------------------------------------------------------+
-- | USE_EMBEDDED_CONSTRAINT | Integer            | Must be 0 or 1                                                       |
-- |---------------------------------------------------------------------------------------------------------------------|
-- | Specify 1 to enable the set_false_path constraint addition between clka of Distributed RAM and doutb_reg on clkb    |
-- +---------------------------------------------------------------------------------------------------------------------+
    USE_EMBEDDED_CONSTRAINT => 0,              --integer: 0,1
    MEMORY_OPTIMIZATION     => "true",          --string; "true", "false" 

    -- Port A module generics
    WRITE_DATA_WIDTH_A      => g_data_width,        --positive integer
    BYTE_WRITE_WIDTH_A      => g_data_width,        --integer; 8, 9, or WRITE_DATA_WIDTH_A value
    ADDR_WIDTH_A            => f_log2_size(g_size), --positive integer

    -- Port B module generics
    READ_DATA_WIDTH_B       => g_data_width,        --positive integer
    ADDR_WIDTH_B            => f_log2_size(g_size), --positive integer
    READ_RESET_VALUE_B      => "0",            --string
    READ_LATENCY_B          => 1,              --non-negative integer
    WRITE_MODE_B            => "write_first"     --string; "write_first", "read_first", "no_change" 
  )
  port map (

    -- Common module ports
    sleep                   => '0',

    -- Port A module ports
    clka                    => clk_i,
    ena                     => '1',
    wea                     => wen,
    addra                   => wa_i,
    dina                    => wd_i,
    injectsbiterra          => '0',
    injectdbiterra          => '0',

    -- Port B module ports
    clkb                    => clk_i,
    rstb                    => rstb,
    enb                     => '1',
    regceb                  => '1',
    addrb                   => ra_i,
    doutb                   => rd_o,
    sbiterrb                => open,
    dbiterrb                => open
  );

rstb  <= not rst_n_i;

end rtl;
