----------------------------------------------------------------------------------
-- Company: 
-- Engineer: 
-- 
-- Create Date:    15:02:12 02/25/2014 
-- Design Name: 
-- Module Name:    ram_wrap - Behavioral 
-- Project Name: 
-- Target Devices: 
-- Tool versions: 
-- Description: 
--
-- Dependencies: 
--
-- Revision: 
-- Revision 0.01 - File Created
-- Additional Comments: 
--
----------------------------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;

-- Uncomment the following library declaration if using
-- arithmetic functions with Signed or Unsigned values
--use IEEE.NUMERIC_STD.ALL;
use ieee.std_logic_unsigned.all;
use IEEE.STD_LOGIC_ARITH.ALL;

-- Uncomment the following library declaration if instantiating
-- any Xilinx primitives in this code.
--library UNISIM;
--use UNISIM.VComponents.all;

entity ram_wrap is
	port (
			clk : in std_logic;
			
			--Primary port :  (pcie)			                             opisi klele spodej so zamenjani:
			addr_wr1 		: in std_logic_vector(3 downto 0);				--6 bitni addres iz kompresorja (5 downto 2)-tapravi address za v ram;(1 downto 0) dejansko kater blok 16 bitov rabimo
			write_en1 		: in std_logic;										--write enable (primary) - kompresor core
			write_data1 	: in std_logic_vector(63 downto 0);				--16 data input iz kompresor core-a
			addr_rd1 		: in std_logic_vector(3 downto 0);
			out1 				: out std_logic_vector(63 downto 0);			--16 bitni out do kompresor core-a	
			busy1				: out std_logic;
			
			--Dual port :   (iz kompresor core)	
			addr_wr2 		: in std_logic_vector(5 downto 0);				--4 bitni addres iz pcie 
			write_en2		: in std_logic;										--write enable (dual) - pcie
			write_data2 	: in std_logic_vector(15 downto 0);				--64 data input iz pcie
			addr_rd2 		: in std_logic_vector(5 downto 0);	
			out2 				: out std_logic_vector(15 downto 0); 			--64 bitni out do pcie
			busy2				: out std_logic
);
end ram_wrap;

-- BRAM, 16 x 64 bitov
architecture Behavioral of ram_wrap is
component rams_11 
   port( 
	     clk         : in std_logic;
		  
		  --primary (pcie)
        addr1       : in std_logic_vector(3 downto 0);
        out1A       : out std_logic_vector(63 downto 0);
		  write_en1   : in std_logic;
        write_data1 : in std_logic_vector(63 downto 0);

		  --dual (kompresor core)
		  addr2       : in std_logic_vector(3 downto 0);
        out2A       : out std_logic_vector(63 downto 0);
        write_en2   : in std_logic;
        write_data2 : in std_logic_vector(63 downto 0)
        );
end component;

signal dout2	: std_logic_vector (63 downto 0);	--prebrano iz rama(za kompresor), 
signal din2		: std_logic_vector (63 downto 0); 	--v ta signal zlepimo za zapis iz kompresorja
signal addr1	: std_logic_vector(3 downto 0);
signal addr2  	: std_logic_vector(5 downto 0);

--	mux signals
signal mux_addr1, mux_addr2 : std_logic_vector (3 downto 0);
signal mux_write_data1, mux_write_data2, mux_out1, mux_out2 : std_logic_vector (63 downto 0);
signal mux_write_en1, mux_write_en2 : std_logic;



begin
ram: rams_11 port map (
	clk=>clk,
	
	addr1=>mux_addr1,
	out1A=>mux_out1,
	write_en1=>mux_write_en1,
	write_data1=>mux_write_data1,
	
	addr2=>mux_addr2,
	out2A=>mux_out2,
	write_en2=>mux_write_en2,
	write_data2=>mux_write_data2

);

busy1<=write_en1;
busy2<=write_en2;

--	address mux glede na write			
addr1<=addr_wr1 when write_en1='1' else addr_rd1;
addr2<=addr_wr2 when write_en2='1' else addr_rd2;

--	16-64 bit adaptation - dual read
out2 <= 	dout2(15 downto 0) when addr2(1 downto 0)="00" else
			dout2(31 downto 16) when addr2(1 downto 0)="01" else
			dout2(47 downto 32) when addr2(1 downto 0)="10" else
			dout2(63 downto 48);
--	16-64 bit adaptation - dual write
din2 <= 	(dout2(63 downto 16) & write_data2) 							when addr2(1 downto 0)="00" else
			(dout2(63 downto 32) & write_data2 & dout2(15 downto 0)) when addr2(1 downto 0)="01" else
			(dout2(63 downto 48) & write_data2 & dout2(31 downto 0)) when addr2(1 downto 0)="10" else
			(write_data2 & dout2(47 downto 0));

-- bram input mux
mux_addr1 <= addr2(5 downto 2) when write_en2='1' else addr1;
mux_addr2 <= addr1 when write_en2='1' else addr2(5 downto 2);
mux_write_data1 <= din2 when write_en2='1' else write_data1;
mux_write_en1 <= write_en1 or write_en2;

--bram output mux
dout2 <= mux_out1 when write_en2='1' else mux_out2;
out1 <= mux_out2 when write_en2='1' else mux_out1;


end Behavioral;

