Files
firmware_vhdl_evr320/hdl/evr320_buffer.vhd

151 lines
6.3 KiB
VHDL

--------------------------------------------------------------------------------
-- Paul Scherrer Institute (PSI)
--------------------------------------------------------------------------------
-- Unit : evr320_buffer.vhd
-- Author : Waldemar Koprek, Section Diagnostic
-- Goran Marinkovic, Section Diagnostic
--------------------------------------------------------------------------------
-- Copyright© PSI, Section Diagnostic
--------------------------------------------------------------------------------
-- Comment :
--------------------------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
use ieee.math_real.all;
entity evr320_buffer is
generic
(
MEM_SIZE_BYTE : integer := 2048;
MEM_DOB_WIDTH : integer := 32
);
port
(
-- port a
clka : in std_logic;
ena : in std_logic;
wea : in std_logic;
addra : in std_logic_vector(integer(ceil(log2(real(MEM_SIZE_BYTE))))-1 downto 0);
dia : in std_logic_vector( 7 downto 0);
page : in std_logic;
-- port b
clkb : in std_logic;
enb : in std_logic;
addrb : in std_logic_vector(integer(ceil(log2(real(MEM_SIZE_BYTE/(MEM_DOB_WIDTH/8)))))-1 downto 0);
dob : out std_logic_vector(MEM_DOB_WIDTH-1 downto 0)
);
attribute ram_style : string;
attribute ram_style of evr320_buffer : entity is "block";
end evr320_buffer;
architecture behavioral of evr320_buffer is
type ram_type_d32 is array ((2*MEM_SIZE_BYTE)-1 downto 0) of std_logic_vector( 7 downto 0);
shared variable RAM : ram_type_d32;
type ram_type_d64 is array (MEM_SIZE_BYTE-1 downto 0) of std_logic_vector(7 downto 0);
shared variable RAM_ODD : ram_type_d64;
shared variable RAM_EVEN : ram_type_d64;
signal page_d : std_logic := '0';
signal page_addr_clka : std_logic := '0';
signal page_addr_clkb : std_logic_vector( 3 downto 0) := (others => '0');
attribute ASYNC_REG : string;
attribute ASYNC_REG of page_addr_clkb : signal is "TRUE";
attribute DONT_TOUCH : string;
attribute DONT_TOUCH of page_addr_clkb : signal is "TRUE";
begin
-- Page switch command clka side
process (clka)
begin
if rising_edge(clka) then
page_d <= page;
if (page_d = '0' and page = '1') then
page_addr_clka <= not page_addr_clka;
end if;
end if;
end process;
-- Page switch command clkb side
process (clkb)
begin
if rising_edge(clkb) then
page_addr_clkb <= page_addr_clkb( 2 downto 0) & not page_addr_clka;
end if;
end process;
-----------------------------------------------------------------------------
dob_32bit: if MEM_DOB_WIDTH = 32 generate
-----------------------------------------------------------------------------
process (clka)
begin
if rising_edge(clka) then
if (ena = '1') then
if (wea = '1') then
RAM(to_integer(unsigned(std_logic_vector'(page_addr_clka & addra)))) := dia;
end if;
end if;
end if;
end process;
process (clkb)
begin
if rising_edge(clkb) then
if (enb = '1') then
dob( 7 downto 0) <= RAM(to_integer(unsigned(std_logic_vector'(page_addr_clkb( 3) & addrb & "00"))));
dob(15 downto 8) <= RAM(to_integer(unsigned(std_logic_vector'(page_addr_clkb( 3) & addrb & "01"))));
dob(23 downto 16) <= RAM(to_integer(unsigned(std_logic_vector'(page_addr_clkb( 3) & addrb & "10"))));
dob(31 downto 24) <= RAM(to_integer(unsigned(std_logic_vector'(page_addr_clkb( 3) & addrb & "11"))));
end if;
end if;
end process;
end generate dob_32bit;
-----------------------------------------------------------------------------
dob_64bit: if MEM_DOB_WIDTH = 64 generate
-----------------------------------------------------------------------------
process (clka)
begin
if rising_edge(clka) then
if (ena = '1') then
if (wea = '1') then
if (addra(0) = '1') then
RAM_ODD (to_integer(unsigned(std_logic_vector'(page_addr_clka & addra(addra'high downto 1))))) := dia;
else
RAM_EVEN(to_integer(unsigned(std_logic_vector'(page_addr_clka & addra(addra'high downto 1))))) := dia;
end if;
end if;
end if;
end if;
end process;
process (clkb)
begin
if rising_edge(clkb) then
if (enb = '1') then
dob( 7 downto 0) <= RAM_EVEN(to_integer(unsigned(std_logic_vector'(page_addr_clkb( 3) & addrb & "00"))));
dob(15 downto 8) <= RAM_ODD (to_integer(unsigned(std_logic_vector'(page_addr_clkb( 3) & addrb & "00"))));
dob(23 downto 16) <= RAM_EVEN(to_integer(unsigned(std_logic_vector'(page_addr_clkb( 3) & addrb & "01"))));
dob(31 downto 24) <= RAM_ODD (to_integer(unsigned(std_logic_vector'(page_addr_clkb( 3) & addrb & "01"))));
dob(39 downto 32) <= RAM_EVEN(to_integer(unsigned(std_logic_vector'(page_addr_clkb( 3) & addrb & "10"))));
dob(47 downto 40) <= RAM_ODD (to_integer(unsigned(std_logic_vector'(page_addr_clkb( 3) & addrb & "10"))));
dob(55 downto 48) <= RAM_EVEN(to_integer(unsigned(std_logic_vector'(page_addr_clkb( 3) & addrb & "11"))));
dob(63 downto 56) <= RAM_ODD (to_integer(unsigned(std_logic_vector'(page_addr_clkb( 3) & addrb & "11"))));
end if;
end if;
end process;
end generate dob_64bit;
end behavioral;
--------------------------------------------------------------------------------
-- End of file
--------------------------------------------------------------------------------