------------------------------------------------------------------------------- -- -- Project : ATEP -- File name : memory.vhd -- Title : Memory Component -- Description : Model a memory which is initialized by a file. -- Memory Operation: Memory is initialized at startup from -- file "memdata.txt. -- -- READ <- write at this edge -- -- RdWrF --------+ +------ -- +______+ -- -- CeF ---+ +---+ +------ -- +--+ +-------+ ------------------------------------------------------------------------------- -- Revisions : -- Date Author Revision Comments -- Sun Dec 11 12:24:46 1994 cohen Rev A Creation ------------------------------------------------------------------------------- library IEEE; use IEEE.Std_Logic_1164.all; package Mem_Pkg is constant DataWidth_c : natural; -- Data width constant AddrWidth_c : natural; -- Address width constant MaxDepth_c : natural; function CharToStd(Char_v : character) return Std_Logic; end Mem_Pkg; package body Mem_Pkg is constant DataWidth_c : natural := 8; -- deferred constant constant AddrWidth_c : natural := 16; -- Address width constant MaxDepth_c : natural := 2 ** AddrWidth_c; -- 64K function CharToStd(Char_v : character) return Std_Logic is begin case Char_v is when '1' => return '1'; when '0' => return '0'; when others => return '0'; assert false report "Input Character is NOT a 1 or 0" severity warning; end case; -- Char_v end CharToStd; end Mem_Pkg; library IEEE; -- used because Std_Logic use IEEE.Std_Logic_1164.all; -- signals are resolved library ATEP_Lib; use ATEP_Lib.Mem_Pkg.all; use ATEP_Lib.Mem_Pkg; entity Memory_Nty is generic (FileName_g : String(1 to 12):= "memdata_.txt"); port( MemAddr : in natural; MemData : inout Std_Logic_Vector(Mem_Pkg.DataWidth_c - 1 downto 0); RdWrF : in Std_Logic; CeF : in Std_Logic); -- Chip Select end Memory_Nty; architecture Memory_a of Memory_Nty is begin -- Memory_a Memory_Lbl : process(MemAddr, MemData, RdWrF, CeF) use Std.TextIO.all; -- localize TextIO to this process use Std.TextIO; subtype Data_Typ is Std_Logic_Vector(Mem_Pkg.DataWidth_c - 1 downto 0); subtype MemSize_Typ is integer range 0 to Mem_Pkg.MaxDepth_c - 1; type Mem_Typ is array(MemSize_Typ) of Data_Typ; variable Memory_v : Mem_Typ; variable Initialization_v : boolean := true; file MemData_f : TextIO.text is in FileName_g; procedure MemoryData -- Preload memory from a file, VHDL'87 (variable FileName_v : in TextIO.text; variable Memory_v : inout Mem_Typ) is variable InLine_v : TextIO.line; variable MemAddress_v : MemSize_Typ := 0; -- 0 to 64k variable Word_v : Data_Typ; variable WordIndex_v : natural; begin File_Lbl : while not TextIO.Endfile(MemData_f) loop -- Read 1 line from the input file TextIO.ReadLine(MemData_f, InLine_v); -- Test if InLine_v is an empty line, next File_Lbl when InLine_v'length = 0; -- null line if InLine_v'length < DataWidth_c then -- error assert false report "Data width in file is less than defined width" severity warning; next File_Lbl; -- detect lines of 80 characters with spaces elsif InLine_v(DataWidth_c) = ' ' then -- error assert false report "Data width in file is less than defined width" severity warning; next File_Lbl; end if; -- Read a data word WordIndex_v := InLine_v'left; -- Convert characters to Std_Logic and fill a data word LoadWord_Lbl : for W_i in Mem_Pkg.DataWidth_c - 1 downto 0 loop Word_v(W_i) := Mem_Pkg.CharToStd(InLine_v(WordIndex_v)); WordIndex_v := WordIndex_v + 1; end loop LoadWord_Lbl; -- Store word in memory and increment address index Memory_v(MemAddress_v) := Word_v; MemAddress_v := MemAddress_v + 1; end loop File_Lbl; end MemoryData; begin -- process Memory_Lbl -- Load memory if in initialization if Initialization_v then MemoryData(FileName_v => MemData_f, Memory_v => Memory_v); Initialization_v := false; end if; -- Normal operation if CeF = '0' then -- memory transaction if RdWrF'event and RdWrF'last_value = '0'and -- positive transition RdWrF = '1' then -- of RdWrF Memory_v(MemAddr) := MemData; -- WRITE OPERATION elsif RdWrF = '1' then -- memory read MemData <= Memory_v(MemAddr); end if; else MemData <= (others => 'Z'); end if; end process Memory_Lbl; end Memory_a;