---------------------------------------------------------------------------------- -- Company: ISEA RWTH Aachen -- Engineer: Marcel Grigo -- -- Create Date: 07.11.2019 11:14:14 -- Design Name: -- Module Name: async_sram_32bit - Behavioral -- Project Name: -- Target Devices: Artix 7 -- Additional Comments: -- The upper half is read only the lower half is write only (microcontroller view) -- ---------------------------------------------------------------------------------- library IEEE; use IEEE.STD_LOGIC_1164.ALL; use ieee.numeric_std.all; use IEEE.std_logic_unsigned.all; use IEEE.std_logic_arith.all; use work.mem_type.all; entity async_sram_tristate_new_nBit_test is generic ( DAT_WIDTH: natural := 16; -- number of data bits ADDR_WIDTH: natural := 6); -- number of address bits port ( ram_dat : inout std_logic_vector ((DAT_WIDTH - 1) downto 0); -- bidirectional data bus to/from the SRAM device ram_addr: in std_logic_vector ((ADDR_WIDTH - 1) downto 0); -- address bus of the SRAM device nCS : in std_logic := '1'; -- low-active Chip-Enable of the SRAM device; defaults to '1' (inactive) nOE : in std_logic := '1'; -- low-active Output-Enable of the SRAM device; defaults to '1' (inactive) nWE : in std_logic := '1'; -- low-active Write-Enable of the SRAM device; defaults to '1' (inactive) clk : in std_logic; data_fpga_read : out ram_array_16(0 to (2**(ADDR_WIDTH-1) - 1)); data_fpga_write : in ram_array_16(0 to (2**(ADDR_WIDTH-1) - 1)) ); -- ram_wait : out std_logic := '0'); -- wait pin to stretch the strobe period; defaults to '0' (inactive) end async_sram_tristate_new_nBit_test; architecture Behavioral of async_sram_tristate_new_nBit_test is constant ADRR_HALF : natural := 2**(ADDR_WIDTH-1); constant MEM_SIZE : natural := 2**(ADDR_WIDTH)-1; signal ram : ram_array_16(0 to 2**(ADDR_WIDTH) - 1); -- declerates a variable ram of type ram_array // this is the REAL memory signal ram_output_buffer : std_logic_vector ((DAT_WIDTH - 1) downto 0); -- declerates a variable ram of type ram_array to buffer the output signal addr_buffer : natural; begin ------------------------------------------------------------------------- -- TRISTATE BUFFER ------------------------------------------------------------------------- ram_dat <= ram_output_buffer when nWE = '1' and nOE = '0' else (others => 'Z'); -- tristate buffer ------------------------------------------------------------------------- -- ADRESS READ AND BUFFER ------------------------------------------------------------------------- read_addr: process(clk, nCS, nOE, nWE) begin if (nCS = '0') then -- if nCS = '0' the adress is valid but it can change due one write cycle if(falling_edge(nWE) or falling_edge(nOE)) then if (conv_integer(ram_addr) < MEM_SIZE) then -- check if the adress is valid addr_buffer <= conv_integer(ram_addr); end if; end if; end if; end process; ------------------------------------------------------------------------- -- READ PROCESS ------------------------------------------------------------------------- read_ram : process (clk, nOE) begin -- nOE = 0 indicates that the microcontroller wants to read the data if (nWE = '1' and nOE = '0') then if (addr_buffer > ADRR_HALF) then -- checks if the adress is in the "read-only" space ram_output_buffer <= ram(addr_buffer); -- makes the data aviable via the output buffer end if; end if; end process; ------------------------------------------------------------------------- -- WRITE PROCESS ------------------------------------------------------------------------- write_ram : process(clk, nWE, data_fpga_write) begin -- nWE = 0 indicates that the microcontroller wants to write data if (nWE = '0' and nOE = '1') then if (addr_buffer < ADRR_HALF) then ram(addr_buffer) <= ram_dat; end if; end if; ram(2**(ADDR_WIDTH-1) to (2**ADDR_WIDTH)-1) <= data_fpga_write; end process; ------------------------------------------------------------------------- -- INSERTS/OUTSERTS DATA FROM FPGA TO RAM ------------------------------------------------------------------------- -- update the upper half of the ram, with data from the fpga, that is read only to the microcontroller -- mirror the lower half of the ram so the fpga could read the data data_fpga_read <= ram(0 to (2**(ADDR_WIDTH-1)- 1)); end Behavioral;