array
) of vectors. The width of the vector is determined by the bit depth of the memory cell, and the number of vectors is determined by the number of cells in the memory module.
type mem is array (0 to 31) of std_logic_vector (7 downto 0);
std_logic_vector (7 downto 0)
.
data_in: in std_logic_vector (7 downto 0); data_out: out std_logic_vector (7 downto 0);
integer
or types based on it. The integer
type is necessary because the address is used as an index of the memory array.
addr: in integer range 0 to 31;
addr_width
and data_width
are used to describe the memory module, which specify the width of the address and data buses, respectively. The number of cells in the memory block in this case is defined as 2**addr_width
, and their width is equal to data_width
.
generic (addr_width: natural:= 5; data_width: natural:=8); port ( addr: in integer range 0 to 2**addr_width - 1; data_in: in std_logic_vector (data_width-1 downto 0); data_out: out std_logic_vector (data_width-1 downto 0) ); type mem is array (2**addr_width-1 downto 0) of std_logic_vector (7 downto 0);
case
; type ROM is array (0 to 7) of std_logic_vector (7 downto 0); constant Content: ROM := ( 0 => "00000001", 1 => "00000010", 2 => "00000011", 3 => "00000100", 4 => "00000101", 5 => "00000110", 6 => "00000111", 7 => "00001000", );
Data_out
must be of type std_logic_vector (7 downto 0)
. Access to the contents of the memory will look like this:
Data_out <= Content (Addr);
clk
, cs
- clock and chip selection, respectively. If the signal cs
equals one, the original ROM lines go to the Z-state (lines 27 and 28). If the signal cs
is equal to zero, then the outputs go to the working state and the operation of the chip occurs.
clk
.
rd
equals one, then the information is allowed to read, if it equals zero, the original lines go to the Z-state (line 32). To access a specific cell in the memory module, line 30 is used. The content constant has the data type of the std_logic_vector
cell, which corresponds to the type of the original data_out
signal. The address signal in the memory module is also of the std_logic_vector
type, so for addressing the cell in the content array, the necessary conversion is of the std_logic_vector
type to the integer
type, which is done using the to_integer (unsigned (address)
structure. only later - to the integer
type. More clearly about the type conversion here .
1 library ieee; 2 use ieee.std_logic_1164.all; 3 use ieee.numeric_std.all; 4 entity ROM is 5 port (clk : in std_logic; 6 cs : in std_logic; 7 rd : in std_logic; 8 address : in std_logic_vector(4 downto 0); 9 data_out: out std_logic_vector(7 downto 0)); 10 end ROM; 11 architecture behav of ROM is 12 type ROM_array is array (0 to 31) 13 of std_logic_vector(7 downto 0); 14 constant content: ROM_array := ( 15 0 => "00000001", 16 1 => "00000010", 17 2 => "00000011", 18 . . . 19 12 => "00001101", 20 13 => "00001110", 21 14 => "00001111", 22 others => "11111111"); 23 begin 24 process(clk, cs) 25 begin 26 if(cs = '1' ) then 27 data_out <= "ZZZZZZZZ"; 28 elsif (clk'event and clk = '1') then 29 if rd = '1' then 30 data_out <= content(to_integer (unsigned (address))); 31 else 32 data_out <= "ZZZZZZZZ"; 33 end if; 34 end if; 35 end process; 36 end behav;
case
. when => _ <= _;
std_logic
, the data output is described by a six-bit vector of type std_logic
. With the help of the case statement, the contents of the first ten cells of the memory block are separately determined, all others are defined together with the help of when others
operators.
library ieee; use ieee.std_logic_1164.all; entity mem is port ( clock : in std_logic; address : in std_logic_vector (7 downto 0); data_out : out std_logic_vector (5 downto 0)); end mem; architecture rtl of mem is begin process (clock) begin if rising_edge (clock) then case address is when "00000000" => data_out <= "000111"; when "00000001" => data_out <= "000110"; when "00000010" => data_out <= "000010"; when "00000011" => data_out <= "100000"; when "00000100" => data_out <= "100010"; when "00000101" => data_out <= "001110"; when "00000110" => data_out <= "111100"; when "00000111" => data_out <= "110111"; when "00001000" => data_out <= "111000"; when "00001001" => data_out <= "100110"; when others => data_out <= "101111"; end case; end if; end process; end rtl;
altera_syn_attributes
synthesis attribute library of the company and use the ram_init_file
attribute. By default, the library is located in the folder _quartus\libraries\vhdl\altera
. This attribute specifies a mif file that contains information about the contents of the memory.
attribute ram_init_file : string;
ram_init_file
attribute and a signal that describes a block of memory. The attribute value must match the * .mif file name:
attribute ram_init_file of rom : signal is "mem.mif";
mem_t
type and the rom
signal of this type are entered, which describe the memory module.
ram_init_file
attribute of the string type is specified, and in line 14 this attribute links to the rom
signal and a link is made to the mem.mif file, in which the contents of the memory module are listed.
1 library ieee, altera; 2 use ieee.std_logic_1164.all; 3 use ieee.numeric_std.all; 4 use altera.altera_syn_attributes.all; 5 entity mem is 6 port (clk: in std_logic; 7 addr: in natural range 0 to 255; 8 q: out std_logic_vector (7 downto 0)); 9 end entity; 10 architecture rtl of mem is 11 type mem_t is array (255 downto 0) of std_logic_vector(7 downto 0); 12 signal rom: mem_t; 13 attribute ram_init_file: string; 14 attribute ram_init_file of rom: signal is "mem.mif"; 15 begin 16 process(clk) 17 begin 18 if(rising_edge(clk)) then 19 q <= rom(addr); 20 end if; 21 end process; 22 end rtl;
Wn_R | CSn | Do [3..0] | Operation mode |
---|---|---|---|
0 | 0 | Zzzzz | Record |
one | 0 | Initial data | Reading |
Γ | one | Zzzzz | Saving information |
library ieee; use ieee.std_logic_1164.all; use ieee.std_logic_unsigned.all; use ieee.numeric_std.all; entity mem is port (clk : in std_logic; Wn_R : in std_logic; CSn : in std_logic; addr : in std_logic_vector(4 downto 0); Di : in std_logic_vector(3 downto 0); Do : out std_logic_vector(3 downto 0)); end mem; architecture syn of mem is type ram_type is array (31 downto 0) of std_logic_vector (3 downto 0); signal RAM : ram_type; begin process (clk, CSn) begin if CSn = '0' then if (clk'event and clk = '1') then if (Wn_R = '0') then RAM(to_integer(unsigned(addr))) <= Di; Do <= "ZZZZ"; else Do <= RAM(to_integer(unsigned(addr))); end if; end if; else Do <= "ZZZZ"; end if; end process; end syn;
Source: https://habr.com/ru/post/197750/