典型的存储器模块有:
寻址存储器,ROM RAM
顺序存储器,FIFO Stack (LIFO)
存储器模块的 VHDL设计
ROM和 RAM属于通用大规模器件,一般不需要自行设计 ;但是在数字系统中,有时也需要设计一些小型的存储器件,用于特定的用途,l
例如临时存放数据,构成查表运算等。
此类器件的特点为地址与存储内容直接对应,
设计时将输入地址作为给出输出内容的条件,
采用条件赋值方式进行设计。
寻址存储器的 VHDL设计设计思想:
将每个 8位数组作为一个字( word);
总共存储 16个字;
将 ram作为由 16个字构成的数组,以地址为下标;
通过读写控制模式实现对特定地址上字的读出或写入;
寻址存储器设计,16x8位 RAM
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
entity kram is
port ( clk,wr,cs,in std_logic;
d,inout std_logic_vector(7 downto 0);
adr,in std_logic_vector(3 downto 0));
end kram;
寻址存储器设计,16x8位 RAM
architecture beh of kram is
subtype word is std_logic_vector(7 downto 0);
type memory is array (0 to 15) of word;
signal adr_in:integer range 0 to 15;
signal sram:memory;
begin
adr_in<=conv_integer (adr);
--将地址转换为数组下标
process(clk)
begin
寻址存储器设计,16x8位 RAM
if(clk'event and clk='1') then
if (cs='1'and wr='1') then --片选、写
sram (adr_in)<=d;
end if;
if (cs='1'and wr='0' ) then --片选、读
d<=sram (adr_in);
end if;
end if;
end process;
end beh;
寻址存储器设计,16x8位 RAM
ROM的内容是初始设计电路时就写入到内部的,
通常采用电路的固定结构来实现存储; ROM只需设置数据输出端口和地址输入端口;
设计思想,采用二进制译码器的设计方式,
将每个输入组态对应的输出与一组存储数据对应起来;
寻址存储器设计,16x8位 ROM
library ieee;
use ieee.std_logic_1164.all;
entity rom is
port(dataout,out std_logic_vector(7 downto 0);
addr,in std_logic_vector(3 downto 0);
ce,in std_logic);
end rom;
寻址存储器设计,16x8位 ROM
architecture d of rom is
signal id,std_logic_vector(4 downto 0);
begin
id <= addr & ce;
dataout <= "00001111" when id ="00000" else
"11110000" when id ="00010" else
"11001100" when id ="00100" else
"00110011" when id ="00110" else
"10101010" when id ="01000" else
"01010101" when id ="01010" else
"10011001" when id ="01100" else
寻址存储器设计,16x8位 ROM
"01100110" when id ="01110" else
"00000000" when id ="10000" else
"11111111" when id ="10010" else
"00010001" when id ="10100" else
"10001000" when id ="10110" else
"10011001" when id ="11000" else
"01100110" when id ="11010" else
"10100110" when id ="11100" else
"01100111" when id ="11110" else
"XXXXXXXX";
end d;
寻址存储器设计,16x8位 ROM
顺序存储器的特点是不设置地址,所有数据的写入和读出都按顺序进行;
数据写入或读出时通常采用移位操作设计;
在设计时必须考虑各存储单元的存储状态;
顺序存储器(堆栈和 FIFO)的设计设计要求:
存入数据按顺序排放;
存储器全满时给出信号并拒绝继续存入;
数据读出时按后进先出原则;
存储数据一旦读出就从存储器中消失;
堆栈(后进先出存储器)的设计设计思想:
将每个存储单元设置为字( word);存储器整体作为由字构成的数组;为每个字设置一个标记( flag),用以表达该存储单元是否已经存放了数据;每写入或读出一个数据时,字的数组内容进行相应的移动,
标记也做相应的变化;
堆栈(后进先出存储器)的设计
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_arith.all;
use ieee.std_logic_signed.all;
entity stack is
port(datain,in std_logic_vector(7 downto 0);
push,pop,reset,clk:in std_logic;
stackfull:out std_logic;
dataout,buffer std_logic_vector(7 downto 0));
end stack;
堆栈设计:移位寄存器方式
architecture b of stack is
type arraylogic is array(15 downto 0) of
std_logic_vector(7 downto 0);
signal data,arraylogic;
signal stackflag:std_logic_vector(15 downto 0);
begin
stackfull<=stackflag(0);
process(clk,reset,pop,push)
variable selfunction,std_logic_vector(1 downto 0);
begin
selfunction:=push & pop;
堆栈设计:移位寄存器方式
if reset='1' then
stackflag<=(others=>'0'); dataout<=(others=>'0');
for i in 0 to 15 loop
data(i)<="00000000“; end loop;
elsif clk'event and clk='1' then
case selfunction is
when "10" =>
if stackflag(0)=’0’ then
data(15)<=datain;
stackflag<='1'&stackflag(15 downto 1);
for i in 0 to 14 loop
data(i)<=data(i+1); end loop;
end if;
堆栈设计:移位寄存器方式
when "01" =>
dataout<=data(15);
stackflag<=stackflag(14 downto 0)&'0';
for i in 15 downto 1 loop
data(i)<=data(i-1);
end loop;
when others=>null;
end case;
end if;
end process;
end b;
堆栈设计:移位寄存器方式
architecture b of stack is
type arraylogic is array(15 downto 0) of
std_logic_vector(7 downto 0);
signal data,arraylogic;
begin
process(clk,reset,pop,push)
variable p:natural range 0 to 15;
variable selfunction,std_logic_vector(1 downto
0);
variable s:std_logic;
begin
堆栈设计:地址指针方式
stackfull<=s;
selfunction:=push & pop;
if reset='1' then
p:=0;dataout<=(others=>'0');s:='0';
for i in 0 to 15 loop
data(i)<="00000000";
end loop;
elsif clk'event and clk='1' then
if p<15 and selfunction="10" then
data(p)<=datain; p:=p+1;
end if;
堆栈设计:地址指针方式
if p=15 and selfunction="10" and s='0' then
data(p)<=datain; s:='1';
end if;
if p>0 and selfunction="01" and s='0' then
p:=p-1; dataout<=data(p);
end if;
if p=15 and selfunction="01" and s='1' then
dataout<=data(p); s:='0';
end if;
end if;
end process;
end b;
堆栈设计:地址指针方式设计要求:
存入数据按顺序排放;
存储器全满时给出信号并拒绝继续存入;
全空时也给出信号并拒绝读出;
读出时按先进先出原则;
存储数据一旦读出就从存储器中消失;
FIFO(先进先出存储器)的设计设计思想:
结合堆栈指针的设计思想,采用环行寄存器方式进行设计;分别设置写入指针 wp和读出指针 rp,标记下一个写入地址和读出地址;地址随写入或读出过程顺序变动;
设计时需要注意处理好从地址最高位到地址最地位的变化;
FIFO(先进先出存储器)的设计
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_arith.all;
use ieee.std_logic_signed.all;
entity kfifo is
port(datain,in std_logic_vector(7 downto 0);
push,pop,reset,clk:in std_logic;
full,empty:out std_logic;
dataout,out std_logic_vector(7 downto 0));
end kfifo;
FIFO设计:地址指针方式
architecture b of kfifo is
type arraylogic is array(15 downto 0) of
std_logic_vector(7 downto 0);
signal data,arraylogic;
signal fi,ei:std_logic;
--为全满全空设置内部信号,以便内部调用 ;
signal wp,rp:natural range 0 to 15;
--写入指针和读出指针 ;
begin
FIFO设计:地址指针方式
process(clk,reset,pop,push)
variable selfunction,std_logic_vector(1 downto
0);
begin
full<=fi;empty<=ei;
selfunction:=push & pop;
if reset='1' then
wp<=0;rp<=0;fi<='0';ei<='1'; --初始指针处于 0位 ;
dataout<=(others=>'0');
for i in 0 to 15 loop
data(i)<="00000000";
end loop;
FIFO设计:地址指针方式
elsif clk‘event and clk=’1‘ then
if fi='0' and selfunction="10" and wp<15 then
data(wp)<=datain; --写入数据 ;
wp<=wp+1;
if wp=rp then fi<='1';end if;
if ei='1' then ei<='0';end if;
end if;
if fi='0' and selfunction="10" and wp=15 then
data(wp)<=datain;
wp<=0;
if wp=rp then fi<='1';end if;
if ei='1' then ei<='0';end if;
end if;
FIFO设计:地址指针方式
if ei='0' and selfunction="01" and rp<15 then
dataout<=data(rp); --读出数据 ;
rp<=rp+1;
if wp=rp then ei<='1';end if;
if fi='1' then fi<='0';end if;
end if;
if ei='0' and selfunction="01" and rp=15 then
dataout<=data(rp);
rp<=0;
if wp=rp then ei<='1';end if;
if fi='1' then fi<='0';end if;
end if;
end if;end process;end b;
library ieee;
use ieee.std_logic_1164.all;
library lpm;
use lpm.lpm_components.all;
entity fifo2 is
port(data,in std_logic_vector(7 downto 0);
wrreq,rdreq,clock,aclr:in std_logic;
q,out std_logic_vector(7 downto 0);
full,empty,out std_logic;
usedw,out std_logic_vector(3 downto 0));
end fifo2;
FIFO设计:利用参数化模块
architecture str of fifo2 is
signal sub_wire0:std_logic_vector(3 downto 0);
signal sub_wire1:std_logic;
signal sub_wire2:std_logic_vector(7 downto 0);
signal sub_wire3:std_logic;
begin
usedw<=sub_wire0(3 downto 0);
empty<=sub_wire1;
q<=sub_wire2(7 downto 0);
full<=sub_wire3;
FIFO设计:利用参数化模块
lpm_fifo_component:lpm_fifo
generic map(
lpm_width =>8,
lpm_numwords =>16,
lpm_widthu=>4,
lpm_showahead => "off",
lpm_hint=>
"use_eab=on,maximize_speed=5")
FIFO设计:利用参数化模块
port map(
rdreq=>rdreq,aclr=>aclr,clock=>clock,
wrreq=>wrreq,data=>data,
usedw=>sub_wire0,
empty=>sub_wire1,
q =>sub_wire2,
full=>sub_wire3);
end str;
FIFO设计:利用参数化模块
寻址存储器,ROM RAM
顺序存储器,FIFO Stack (LIFO)
存储器模块的 VHDL设计
ROM和 RAM属于通用大规模器件,一般不需要自行设计 ;但是在数字系统中,有时也需要设计一些小型的存储器件,用于特定的用途,l
例如临时存放数据,构成查表运算等。
此类器件的特点为地址与存储内容直接对应,
设计时将输入地址作为给出输出内容的条件,
采用条件赋值方式进行设计。
寻址存储器的 VHDL设计设计思想:
将每个 8位数组作为一个字( word);
总共存储 16个字;
将 ram作为由 16个字构成的数组,以地址为下标;
通过读写控制模式实现对特定地址上字的读出或写入;
寻址存储器设计,16x8位 RAM
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
entity kram is
port ( clk,wr,cs,in std_logic;
d,inout std_logic_vector(7 downto 0);
adr,in std_logic_vector(3 downto 0));
end kram;
寻址存储器设计,16x8位 RAM
architecture beh of kram is
subtype word is std_logic_vector(7 downto 0);
type memory is array (0 to 15) of word;
signal adr_in:integer range 0 to 15;
signal sram:memory;
begin
adr_in<=conv_integer (adr);
--将地址转换为数组下标
process(clk)
begin
寻址存储器设计,16x8位 RAM
if(clk'event and clk='1') then
if (cs='1'and wr='1') then --片选、写
sram (adr_in)<=d;
end if;
if (cs='1'and wr='0' ) then --片选、读
d<=sram (adr_in);
end if;
end if;
end process;
end beh;
寻址存储器设计,16x8位 RAM
ROM的内容是初始设计电路时就写入到内部的,
通常采用电路的固定结构来实现存储; ROM只需设置数据输出端口和地址输入端口;
设计思想,采用二进制译码器的设计方式,
将每个输入组态对应的输出与一组存储数据对应起来;
寻址存储器设计,16x8位 ROM
library ieee;
use ieee.std_logic_1164.all;
entity rom is
port(dataout,out std_logic_vector(7 downto 0);
addr,in std_logic_vector(3 downto 0);
ce,in std_logic);
end rom;
寻址存储器设计,16x8位 ROM
architecture d of rom is
signal id,std_logic_vector(4 downto 0);
begin
id <= addr & ce;
dataout <= "00001111" when id ="00000" else
"11110000" when id ="00010" else
"11001100" when id ="00100" else
"00110011" when id ="00110" else
"10101010" when id ="01000" else
"01010101" when id ="01010" else
"10011001" when id ="01100" else
寻址存储器设计,16x8位 ROM
"01100110" when id ="01110" else
"00000000" when id ="10000" else
"11111111" when id ="10010" else
"00010001" when id ="10100" else
"10001000" when id ="10110" else
"10011001" when id ="11000" else
"01100110" when id ="11010" else
"10100110" when id ="11100" else
"01100111" when id ="11110" else
"XXXXXXXX";
end d;
寻址存储器设计,16x8位 ROM
顺序存储器的特点是不设置地址,所有数据的写入和读出都按顺序进行;
数据写入或读出时通常采用移位操作设计;
在设计时必须考虑各存储单元的存储状态;
顺序存储器(堆栈和 FIFO)的设计设计要求:
存入数据按顺序排放;
存储器全满时给出信号并拒绝继续存入;
数据读出时按后进先出原则;
存储数据一旦读出就从存储器中消失;
堆栈(后进先出存储器)的设计设计思想:
将每个存储单元设置为字( word);存储器整体作为由字构成的数组;为每个字设置一个标记( flag),用以表达该存储单元是否已经存放了数据;每写入或读出一个数据时,字的数组内容进行相应的移动,
标记也做相应的变化;
堆栈(后进先出存储器)的设计
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_arith.all;
use ieee.std_logic_signed.all;
entity stack is
port(datain,in std_logic_vector(7 downto 0);
push,pop,reset,clk:in std_logic;
stackfull:out std_logic;
dataout,buffer std_logic_vector(7 downto 0));
end stack;
堆栈设计:移位寄存器方式
architecture b of stack is
type arraylogic is array(15 downto 0) of
std_logic_vector(7 downto 0);
signal data,arraylogic;
signal stackflag:std_logic_vector(15 downto 0);
begin
stackfull<=stackflag(0);
process(clk,reset,pop,push)
variable selfunction,std_logic_vector(1 downto 0);
begin
selfunction:=push & pop;
堆栈设计:移位寄存器方式
if reset='1' then
stackflag<=(others=>'0'); dataout<=(others=>'0');
for i in 0 to 15 loop
data(i)<="00000000“; end loop;
elsif clk'event and clk='1' then
case selfunction is
when "10" =>
if stackflag(0)=’0’ then
data(15)<=datain;
stackflag<='1'&stackflag(15 downto 1);
for i in 0 to 14 loop
data(i)<=data(i+1); end loop;
end if;
堆栈设计:移位寄存器方式
when "01" =>
dataout<=data(15);
stackflag<=stackflag(14 downto 0)&'0';
for i in 15 downto 1 loop
data(i)<=data(i-1);
end loop;
when others=>null;
end case;
end if;
end process;
end b;
堆栈设计:移位寄存器方式
architecture b of stack is
type arraylogic is array(15 downto 0) of
std_logic_vector(7 downto 0);
signal data,arraylogic;
begin
process(clk,reset,pop,push)
variable p:natural range 0 to 15;
variable selfunction,std_logic_vector(1 downto
0);
variable s:std_logic;
begin
堆栈设计:地址指针方式
stackfull<=s;
selfunction:=push & pop;
if reset='1' then
p:=0;dataout<=(others=>'0');s:='0';
for i in 0 to 15 loop
data(i)<="00000000";
end loop;
elsif clk'event and clk='1' then
if p<15 and selfunction="10" then
data(p)<=datain; p:=p+1;
end if;
堆栈设计:地址指针方式
if p=15 and selfunction="10" and s='0' then
data(p)<=datain; s:='1';
end if;
if p>0 and selfunction="01" and s='0' then
p:=p-1; dataout<=data(p);
end if;
if p=15 and selfunction="01" and s='1' then
dataout<=data(p); s:='0';
end if;
end if;
end process;
end b;
堆栈设计:地址指针方式设计要求:
存入数据按顺序排放;
存储器全满时给出信号并拒绝继续存入;
全空时也给出信号并拒绝读出;
读出时按先进先出原则;
存储数据一旦读出就从存储器中消失;
FIFO(先进先出存储器)的设计设计思想:
结合堆栈指针的设计思想,采用环行寄存器方式进行设计;分别设置写入指针 wp和读出指针 rp,标记下一个写入地址和读出地址;地址随写入或读出过程顺序变动;
设计时需要注意处理好从地址最高位到地址最地位的变化;
FIFO(先进先出存储器)的设计
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_arith.all;
use ieee.std_logic_signed.all;
entity kfifo is
port(datain,in std_logic_vector(7 downto 0);
push,pop,reset,clk:in std_logic;
full,empty:out std_logic;
dataout,out std_logic_vector(7 downto 0));
end kfifo;
FIFO设计:地址指针方式
architecture b of kfifo is
type arraylogic is array(15 downto 0) of
std_logic_vector(7 downto 0);
signal data,arraylogic;
signal fi,ei:std_logic;
--为全满全空设置内部信号,以便内部调用 ;
signal wp,rp:natural range 0 to 15;
--写入指针和读出指针 ;
begin
FIFO设计:地址指针方式
process(clk,reset,pop,push)
variable selfunction,std_logic_vector(1 downto
0);
begin
full<=fi;empty<=ei;
selfunction:=push & pop;
if reset='1' then
wp<=0;rp<=0;fi<='0';ei<='1'; --初始指针处于 0位 ;
dataout<=(others=>'0');
for i in 0 to 15 loop
data(i)<="00000000";
end loop;
FIFO设计:地址指针方式
elsif clk‘event and clk=’1‘ then
if fi='0' and selfunction="10" and wp<15 then
data(wp)<=datain; --写入数据 ;
wp<=wp+1;
if wp=rp then fi<='1';end if;
if ei='1' then ei<='0';end if;
end if;
if fi='0' and selfunction="10" and wp=15 then
data(wp)<=datain;
wp<=0;
if wp=rp then fi<='1';end if;
if ei='1' then ei<='0';end if;
end if;
FIFO设计:地址指针方式
if ei='0' and selfunction="01" and rp<15 then
dataout<=data(rp); --读出数据 ;
rp<=rp+1;
if wp=rp then ei<='1';end if;
if fi='1' then fi<='0';end if;
end if;
if ei='0' and selfunction="01" and rp=15 then
dataout<=data(rp);
rp<=0;
if wp=rp then ei<='1';end if;
if fi='1' then fi<='0';end if;
end if;
end if;end process;end b;
library ieee;
use ieee.std_logic_1164.all;
library lpm;
use lpm.lpm_components.all;
entity fifo2 is
port(data,in std_logic_vector(7 downto 0);
wrreq,rdreq,clock,aclr:in std_logic;
q,out std_logic_vector(7 downto 0);
full,empty,out std_logic;
usedw,out std_logic_vector(3 downto 0));
end fifo2;
FIFO设计:利用参数化模块
architecture str of fifo2 is
signal sub_wire0:std_logic_vector(3 downto 0);
signal sub_wire1:std_logic;
signal sub_wire2:std_logic_vector(7 downto 0);
signal sub_wire3:std_logic;
begin
usedw<=sub_wire0(3 downto 0);
empty<=sub_wire1;
q<=sub_wire2(7 downto 0);
full<=sub_wire3;
FIFO设计:利用参数化模块
lpm_fifo_component:lpm_fifo
generic map(
lpm_width =>8,
lpm_numwords =>16,
lpm_widthu=>4,
lpm_showahead => "off",
lpm_hint=>
"use_eab=on,maximize_speed=5")
FIFO设计:利用参数化模块
port map(
rdreq=>rdreq,aclr=>aclr,clock=>clock,
wrreq=>wrreq,data=>data,
usedw=>sub_wire0,
empty=>sub_wire1,
q =>sub_wire2,
full=>sub_wire3);
end str;
FIFO设计:利用参数化模块