基本功能:
具有先进后出的堆栈功能。
此LIFO堆栈具有两个按键(write,read),按下write键后,开始输入数据data0-data3;
按下read键后,7段数码管开始倒序显示data3-data0(十进制)。
按下write键,VGA显示“Write”字样,并同时显示输入数据;按下read键,VGA显示“Read”字样,并同时显示输出数据。
大三下学期的实验,贴出代码,仅供参考:
1、分频模块:
library IEEE;
useIEEE.STD_LOGIC_1164.ALL;
entity fenpin is
port
(
clk_fp_in : in std_logic;
reset_fp : in std_logic;
clk_fp_out: out std_logic
);
end fenpin;
architectureBehavioral of fenpin is
signalclk_signal :std_logic;
signal clk_dis :std_logic;
signalcnt:integer range 49999 downto 0 :=0;--移动
begin
process (clk_fp_in,reset_fp)
begin
if(reset_fp='1')then
clk_signal <= '0';
elsif(clk_fp_in'event andclk_fp_in = '1')then
if(clk_signal = '0')then
clk_signal <='1';
else
clk_signal <='0';
end if;
end if;
end process;
clk_fp_out <= clk_signal;
end Behavioral;
2、按键消抖模块:
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
--当高电平持续20ms以上,并且松手后,输出一个clk_key_delay的时钟周期时间的高
entity key_delay is
port( clk_key_delay :in std_logic;
reset_key_delay:instd_logic;
key1_in :in std_logic;
key2_in :in std_logic;
key1_out :outstd_logic;
key2_out :out std_logic
);
end key_delay;
architecture Behavioral of key_delay is
type state is (s0,s1,s2);--状态机类型
type state1 is (s0,s1,s2);--状态机类型
signal current:state;
signal current1:state;
signal iscnt,iscnt2:std_logic;
signal time_20ms:std_logic;
signal cnt:integer range 1000000 downto 0;
begin
process(reset_key_delay,clk_key_delay,key1_in)
begin
if(reset_key_delay= '1') then
time_20ms<='0';
cnt <=0;
elsif(clk_key_delay'eventand clk_key_delay='1')then
if(iscnt='1'or iscnt2='1')then
if(cnt=1000000)then
cnt <=0;
time_20ms<='1';
else
time_20ms<='0';
cnt <=cnt+1;
endif;
else
cnt <=0;
endif;
endif;
endprocess;
process(reset_key_delay,clk_key_delay,key1_in)
begin
if(reset_key_delay= '1') then
key1_out<='0';
iscnt <='0';
current<= s0;
elsif(clk_key_delay'eventand clk_key_delay='1')then
casecurrent is
whens0 =>
key1_out<='0';
if(key1_in='1')then
iscnt <='1';
current<= s1;
else
current<= s0;
iscnt <='0';
endif;
whens1 =>
key1_out<='0';
if(key1_in='1'and time_20ms='1' )then
current<= s2;--电平持续了20ms则跳转到状态s2
elsif(key1_in='1')then
current<= s1;
else
current<= s0;
endif;
whens2 =>
iscnt <='0';
if(key1_in='1')then--此时电平还是高,说明还没松开手
key1_out<='0';
current<= s2;
else
key1_out<='1';
current<= s0;
endif;
whenothers =>
current<= s0;
key1_out<='0';
endcase;
endif;
endprocess;
process(reset_key_delay,clk_key_delay,key2_in)
begin
if(reset_key_delay= '1') then
key2_out<='0';
iscnt2 <='0';
current1<= s0;
elsif(clk_key_delay'eventand clk_key_delay='1')then
casecurrent1 is
whens0 =>
key2_out<='0';
if(key2_in='1')then
iscnt2 <='1';
current1<= s1;
else
current1<= s0;
iscnt2 <='0';
endif;
whens1 =>
key2_out<='0';
if(key2_in='1'and time_20ms='1' )then
current1<= s2;--电平持续了20ms则跳转到状态s2
elsif(key2_in='1')then
current1<= s1;
else
current1<= s0;
endif;
whens2 =>
iscnt2 <='0';
if(key2_in='1')then--此时电平还是高,说明还没松开手
key2_out<='0';
current1<= s2;
else
key2_out<='1';
current1<= s0;
endif;
whenothers =>
current1<= s0;
key2_out<='0';
endcase;
endif;
endprocess;
end Behavioral;
3、VGA控制模块:
library IEEE;
useIEEE.STD_LOGIC_1164.ALL;
USEIEEE.STD_LOGIC_UNSIGNED.ALL;
entity sync is
port( clk_sync :instd_logic;
reset_sync :in std_logic;
V_sync :out std_logic;
H_sync :out std_logic;
Ready_sync :out std_logic;
Lie_Add_sync :out integer range 800 downto 0;
Hang_Add_sync :out integer range 525 downto 0
);
end sync;
architectureBehavioral of sync is
signal count_h:integer range 800 downto 0;
signal count_v:integer range 525 downto 0;
signal isReady :std_logic;
begin
process (clk_sync,reset_sync)
begin
if(reset_sync='1')then
count_h <= 0;
H_sync <= '0';
elsif(clk_sync'event and clk_sync='1')then
if(count_h=799)then
count_h <= 0;
else
count_h <=count_h + 1;
if(count_h <96)then
H_sync <= '0';
else
H_sync <= '1';
end if;
end if;
end if;
end process;
process (clk_sync,reset_sync)
begin
if(reset_sync='1')then
count_v <= 0;
V_sync <= '0';
elsif(clk_sync'event and clk_sync='1')then
if(count_v = 524)then
count_v <= 0;
elsif(count_h=799)then
count_v <=count_v + 1;
else
if(count_v <3)then
V_sync <='0';
else
V_sync <='1';
end if;
end if;
end if;
end process;
process (reset_sync,clk_sync)
begin
if(reset_sync='1')then
isReady <= '0';
Lie_Add_sync<= 0;
Hang_Add_sync<= 0;
elsif(clk_sync'event and clk_sync='1')then
if((count_h >144)and(count_h < 785)and(count_v > 34)and(count_v < 515))then
isReady <= '1';
Lie_Add_sync <=count_h - 145;
Hang_Add_sync<=count_v - 35;
else
isReady <= '0';
Lie_Add_sync <=0;
Hang_Add_sync<=0;
end if;
end if;
end process;
Ready_sync <= isReady;
end Behavioral;
4、VGA显示模块:
library IEEE;
useIEEE.STD_LOGIC_1164.ALL;
USEIEEE.STD_LOGIC_ARITH.ALL;
USE IEEE.STD_LOGIC_UNSIGNED.ALL;
entityvga_display is
port( clk_display :in std_logic;
reset_display :in std_logic;
Ready_display :in std_logic;
Lie_Add_display :in integer range 800 downto 0; --0~640
Hang_Add_display :in integer range 525 downto 0; --0~480
read_en :in std_logic; --写使能,1写0读
wei_in :in std_logic_vector (3 downto 0);--显示位置data_in="1111"是,VGA显示4位数据,0000则不显示
data1_in :in integer range 9 downto 0;
data2_in :in integer range 9 downto 0;
data3_in :in integer range 9 downto 0;
data4_in :in integer range 9 downto 0;
rom_add :out std_logic_vector (8 downto 0);
rom_data :in std_logic_vector (31 downto 0);
RGB_display_out :out std_logic_vector (7 downto 0);
dx_add_display :out STD_LOGIC_VECTOR(5 DOWNTO 0);
dx_out_display :in STD_LOGIC_VECTOR(127 DOWNTO 0)
);
end vga_display;
architectureBehavioral of vga_display is
signal signal_dx :std_logic;--读写图片显示区域(128*32)
signalsignal_kuang :std_logic;--数据框显示区域
signalsignal_kuang_shu :std_logic;--数据框显示区域
signalsignal_kuang_shu1 :std_logic;
signalsignal_kuang_shu2 :std_logic;
signalsignal_kuang_shu3 :std_logic;
signalsignal_kuang_shu4 :std_logic;
signalsignal_kuang_shu5 :std_logic;
signalsignal_kuang_heng :std_logic;--数据框显示区域
signal signal_kuang_heng1 :std_logic;
signalsignal_kuang_heng2 :std_logic;
signalsignal_data1 :std_logic;
signalsignal_data2 :std_logic;
signalsignal_data3 :std_logic;
signalsignal_data4 :std_logic;
begin
----------------------基本显示--------------------
signal_dx <='1' when((Lie_Add_display>255)and(Lie_Add_display<384)and(Hang_Add_display>197)and(Hang_Add_display<230))else '0';
signal_kuang <='1' when (signal_kuang_shu='1' or signal_kuang_heng='1') else'0';
signal_kuang_shu <='1' when (signal_kuang_shu1='1' or signal_kuang_shu2='1' orsignal_kuang_shu3='1' or signal_kuang_shu4='1' or signal_kuang_shu5='1') else'0';
signal_kuang_shu1 <='1' when((Lie_Add_display>214)and(Lie_Add_display<225)and(Hang_Add_display>249)and(Hang_Add_display<290))else '0';
signal_kuang_shu2 <='1' when((Lie_Add_display>264)and(Lie_Add_display<275)and(Hang_Add_display>249)and(Hang_Add_display<290))else '0';
signal_kuang_shu3 <='1' when((Lie_Add_display>314)and(Lie_Add_display<325)and(Hang_Add_display>249)and(Hang_Add_display<290))else '0';
signal_kuang_shu4 <='1' when((Lie_Add_display>364)and(Lie_Add_display<375)and(Hang_Add_display>249)and(Hang_Add_display<290))else '0';
signal_kuang_shu5 <='1' when((Lie_Add_display>414)and(Lie_Add_display<425)and(Hang_Add_display>249)and(Hang_Add_display<290))else '0';
signal_kuang_heng <='1' when (signal_kuang_heng1='1' or signal_kuang_heng2='1')else '0';
signal_kuang_heng1<='1' when((Lie_Add_display>214)and(Lie_Add_display<425)and(Hang_Add_display>239)and(Hang_Add_display<250))else '0';
signal_kuang_heng2<='1' when((Lie_Add_display>214)and(Lie_Add_display<425)and(Hang_Add_display>289)and(Hang_Add_display<300))else '0';
signal_data1 <='1' when ((Lie_Add_display>226)and(Lie_Add_display<259)and(Hang_Add_display>253)and(Hang_Add_display<286))and(wei_in(3)='1')else '0';
signal_data2 <='1' when ((Lie_Add_display>276)and(Lie_Add_display<309)and(Hang_Add_display>253)and(Hang_Add_display<286))and(wei_in(2)='1')else '0';
signal_data3 <='1' when ((Lie_Add_display>326)and(Lie_Add_display<359)and(Hang_Add_display>253)and(Hang_Add_display<286))and(wei_in(1)='1')else '0';
signal_data4 <='1' when ((Lie_Add_display>376)and(Lie_Add_display<409)and(Hang_Add_display>253)and(Hang_Add_display<286))and(wei_in(0)='1')else '0';
process (clk_display,reset_display)
begin
if(reset_display='1')then
rom_add <=(others=>'0');
RGB_display_out<=(others=>'0');
elsif(clk_display'event andclk_display = '1')then
if(Ready_display='1')then
if(signal_dx='1')then --显示读写图片
if(read_en='1')then--
dx_add_display<=conv_std_logic_vector(Hang_Add_display-198,6);
RGB_display_out<=(others=>dx_out_display(Lie_Add_display-256));
else
dx_add_display<=conv_std_logic_vector(32+Hang_Add_display-198,6);
RGB_display_out<=(others=>dx_out_display(Lie_Add_display-256));
end if;
elsif(signal_data1='1')then
rom_add<=conv_std_logic_vector(data1_in*32+(Hang_Add_display-254),9);--存的数据要从0开始
RGB_display_out<=(others=>rom_data(Lie_Add_display-231));
elsif(signal_data2='1')then
rom_add<=conv_std_logic_vector(data2_in*32+(Hang_Add_display-254),9);
RGB_display_out<=(others=>rom_data(Lie_Add_display-281));
elsif(signal_data3='1')then
rom_add<=conv_std_logic_vector(data3_in*32+(Hang_Add_display-254),9);
RGB_display_out<=(others=>rom_data(Lie_Add_display-331));
elsif(signal_data4='1')then
rom_add<=conv_std_logic_vector(data4_in*32+(Hang_Add_display-254),9);
RGB_display_out<=(others=>rom_data(Lie_Add_display-381));
elsif(signal_kuang='1')then
RGB_display_out<="11100000";
else
rom_add <=(others=>'0');
RGB_display_out<=(others=>'0');
end if;
end if;
end if;
end process;
end Behavioral;
5、LIFO模块:
当读信号为1时,执行以下动作:
(1)、wei从0100变为0101:wei的初始状态为0100,表明一开始VGA屏幕中,只有第2为是可以显示的(wei的第2位为1),变为0101表明VGA的第2、4位显示。
(2)、lifo_wea输出一个时钟周期的高电平:这是使写使能信号有效,写入的地址为add
(3)、add由0变1:是写使能地址自增一位
(4)、data1的值始终与add的值一样,不同的是add连接到lifo存储器,datat1连接到VGA用于显示。
(5)、key_in为当前读入的值:10000000,第8位为1,代表数字8.
(6)、data由0000变1000,这是key_in的译码,表示8
(7)、data3与data的值一样,data用于把输入译码为8,data3用于输出给VGA显示。
(8)、写操作同理。
entity LIFO_control2is
port( control_clk :in STD_LOGIC;
control_reset :in STD_LOGIC;
control_write :in STD_LOGIC;
control_read :in STD_LOGIC;
control_key_in:inSTD_LOGIC_VECTOR(7 DOWNTO 0);
control_read_en:outSTD_LOGIC;
control_wei :out STD_LOGIC_vector(3 downto 0);
control_data1 :out integer range 9 downto 0;
control_data2 :out integer range 9 downto 0;
control_data3 :out integer range 9 downto 0;
control_data4 :out integer range 9 downto 0;
lifo_wea :out STD_LOGIC_VECTOR(0 DOWNTO 0);--1写0读
lifo_adda:outSTD_LOGIC_VECTOR(5 DOWNTO 0);
lifo_outb:inSTD_LOGIC_VECTOR(7 DOWNTO 0)
);
endLIFO_control2;
architectureBehavioral of LIFO_control2 is
signaladd:integer range 9 downto 0;
signalvga_data:STD_LOGIC_VECTOR(7 downto 0);
signaldata:integer range 9 downto 0;
type stateis(s0,s1,s2);
signal current:state;
begin
process(control_reset,control_clk)
begin
if(control_reset ='1')then
add <=0;
current <=s0;--此状态什么都不做
elsif(control_clk'event andcontrol_clk ='1')then--检测到上升沿才开始响应
if(control_write='1')then
if(add=9)then
add <=9;
else
add <=add+1;
end if;
current <=s2;
elsif(control_read='1')then
if(add=0)then
add <=0;
else
add <=add-1;
end if;
current <=s1;
else
current <=s0;
end if;
end if;
end process;
process(control_reset,control_clk)
begin
if(control_reset ='1')then
lifo_wea <="1";
control_read_en<='0';
control_wei <="0100";
vga_data <="11111111";
elsif(control_clk'event andcontrol_clk ='1')then--检测到上升沿才开始响应
case current is
when s2 =>
lifo_wea <="1";
vga_data <=control_key_in;
control_read_en<='0';
control_wei <="0101";
when s1 =>
lifo_wea <="0";
vga_data <=lifo_outb;
control_read_en<='1';
control_wei <="1010";
when s0 =>
lifo_wea<="0";
end case;
end if;
end process;
lifo_adda<=conv_std_logic_vector(add,6);
control_data1 <=add;
control_data3 <=data;
control_data2 <=add;
control_data4 <=data;
process(control_reset,control_clk)
begin
if(control_reset='1')then --按键按下为高电平
data <= 0;
elsif(control_clk'event andcontrol_clk='1')then
case vga_data is
when"00000001" => data<=1;
when"00000010" => data<=2;
when"00000100" => data<=3;
when"00001000" => data<=4;
when"00010000" => data<=5;
when"00100000" => data<=6;
when"01000000" => data<=7;
when"10000000" => data<=8;
when others =>
data <=0;
end case;
end if;
end process;
end Behavioral;
6、顶层模块:
library IEEE;
useIEEE.STD_LOGIC_1164.ALL;
entity top is
port( clk :in std_logic;--50M时钟
reset :in std_logic;--复位
key_write :in std_logic;--写按键
key_read :in std_logic;--读按键
data :in std_logic_vector (7 downto 0); --写输入
--VGA输出
V :out std_logic;
H :out std_logic;
vga_out :out std_logic_vector (7 downto 0)
);
end top;
architectureBehavioral of top is
componentkey_delay --声明消抖模块
port( clk_key_delay :in std_logic;
reset_key_delay:in std_logic;
key1_in :in std_logic;
key2_in :in std_logic;
key1_out :out std_logic;
key2_out :out std_logic
);
end component;
component fenpin --分频
port(clk_fp_in : in std_logic;
reset_fp : in std_logic;
clk_fp_out: out std_logic --25M时钟输出
);
end component;
--componentseg_display --数码管显示
--port( clk_seg_in :in std_logic;
-- reset_seg_in :in std_logic;
-- data1_in :in std_logic_vector(3 downto 0);
-- data2_in :in std_logic_vector(3 downto0);
-- data3_in :in std_logic_vector(3 downto0);
-- data4_in :in std_logic_vector(3 downto0);
-- wei: out std_logic_vector(3 downto 0); --位选
-- duan: out std_logic_vector(7 downto 0) --段选
-- );
--end component;
--component LIFO_control--数码管
--port( clk_lifo :instd_logic;
-- reset_lifo :in std_logic;
-- write_lifo :in STD_LOGIC;
-- read_lifo :in STD_LOGIC;
-- data_lifo_in:in STD_LOGIC_VECTOR(7DOWNTO 0);
-- data1_out :out std_logic_vector(3 downto 0);
-- data2_out :out std_logic_vector(3 downto 0);
-- data3_out :out std_logic_vector(3 downto 0);
-- data4_out :out std_logic_vector(3 downto 0);
-- lifo_wea :out STD_LOGIC_VECTOR(0 DOWNTO 0);--0写1读
-- lifo_adda:out STD_LOGIC_VECTOR(5DOWNTO 0);
-- lifo_outb:in STD_LOGIC_VECTOR(7DOWNTO 0)
--);
--end component;
componentvga_display
port( clk_display :in std_logic;
reset_display :in std_logic;
Ready_display :in std_logic;
Lie_Add_display :in integer range 800 downto 0; --0~640
Hang_Add_display :in integer range 525 downto 0; --0~480
read_en :in std_logic; --写使能,1写0读
wei_in :in std_logic_vector (3 downto 0);--显示位置data_in="1111"是,VGA显示4位数据,0000则不显示
data1_in :in integer range 9 downto 0;
data2_in :in integer range 9 downto 0;
data3_in :in integer range 9 downto 0;
data4_in :in integer range 9 downto 0;
rom_add :out std_logic_vector (8 downto 0);
rom_data :in std_logic_vector (31 downto 0);
RGB_display_out :out std_logic_vector (7 downto 0);
dx_add_display :out STD_LOGIC_VECTOR(5 DOWNTO 0);
dx_out_display :in STD_LOGIC_VECTOR(127 DOWNTO 0)
);
end component;
component sync
port( clk_sync :instd_logic;
reset_sync :in std_logic;
V_sync :out std_logic;
H_sync :out std_logic;
Ready_sync :out std_logic;
Lie_Add_sync :out integer range 800 downto 0;
Hang_Add_sync :out integer range 525 downto 0
);
end component;
COMPONENT LIFO
PORT (
clka : IN STD_LOGIC;
wea : IN STD_LOGIC_VECTOR(0 DOWNTO 0);
addra : IN STD_LOGIC_VECTOR(5 DOWNTO 0);
dina : IN STD_LOGIC_VECTOR(7 DOWNTO 0);
douta : OUT STD_LOGIC_VECTOR(7 DOWNTO 0)
);
END COMPONENT;
COMPONENT sz_pic
PORT (
clka : IN STD_LOGIC;
addra : INSTD_LOGIC_VECTOR(8 DOWNTO 0);
douta : OUTSTD_LOGIC_VECTOR(31 DOWNTO 0)
);
END COMPONENT;
COMPONENT dx_pic
PORT (
clka : IN STD_LOGIC;
addra : INSTD_LOGIC_VECTOR(5 DOWNTO 0);
douta : OUTSTD_LOGIC_VECTOR(127 DOWNTO 0)
);
END COMPONENT;
COMPONENTLIFO_control2
port( control_clk :in STD_LOGIC;
control_reset :in STD_LOGIC;
control_write :in STD_LOGIC;
control_read :in STD_LOGIC;
control_key_in:inSTD_LOGIC_VECTOR(7 DOWNTO 0);
control_read_en:outSTD_LOGIC;
control_wei :out STD_LOGIC_vector(3 downto 0);
control_data1 :out integer range 9 downto 0;
control_data2 :out integer range 9 downto 0;
control_data3 :out integer range 9 downto 0;
control_data4 :out integer range 9 downto 0;
lifo_wea :out STD_LOGIC_VECTOR(0 DOWNTO 0);--1写0读
lifo_adda:outSTD_LOGIC_VECTOR(5 DOWNTO 0);
lifo_outb:inSTD_LOGIC_VECTOR(7 DOWNTO 0)
);
END COMPONENT;
signal signal_25M :std_logic;
signalsignal_write :std_logic;
signal signal_read :std_logic;
--signalsignal_data1 :std_logic_vector(3downto 0);
--signalsignal_data2 :std_logic_vector(3downto 0);
--signalsignal_data3 :std_logic_vector(3downto 0);
--signalsignal_data4 :std_logic_vector(3downto 0);
--control接口
signalsignal_read_en:std_logic; --写使能,1写0读
signal signal_wei :STD_LOGIC_VECTOR(3 DOWNTO 0);
signalsignal_data1 :integer range 9 downto 0;
signalsignal_data2 :integer range 9 downto 0;
signalsignal_data3 :integer range 9 downto 0;
signalsignal_data4 :integer range 9 downto 0;
--pic接口
signalsignal_add_pic:STD_LOGIC_VECTOR(8 DOWNTO 0);
signalsignal_dout_pic:STD_LOGIC_VECTOR(31 DOWNTO 0);
--dx图片接口
signalsignal_dx_add:STD_LOGIC_VECTOR(5 DOWNTO 0);
signalsignal_dx_out:STD_LOGIC_VECTOR(127 DOWNTO 0);
--lifo接口
signal signal_wea :STD_LOGIC_VECTOR(0 DOWNTO 0);--0写1读
signalsignal_adda:STD_LOGIC_VECTOR(5 DOWNTO 0);
signal signal_out :STD_LOGIC_VECTOR(7 DOWNTO 0);
--vga接口
signalsignal_Ready :std_logic;
signalsignal_Lie_Add :integer range 800 downto 0; --0~640
signalsignal_Hang_Add:integer range 525 downto 0; --0~480
begin
u1:fenpin
port map ( clk,
reset,
signal_25M
);
u2:key_delay --消抖
port map ( clk,
reset,
key_write,
key_read,
signal_write,
signal_read
);
u5:vga_display
port map( signal_25M,
reset,
signal_Ready,
signal_Lie_Add,
signal_Hang_Add,
signal_read_en,
signal_wei,
signal_data1,
signal_data2,
signal_data3,
signal_data4,
signal_add_pic,
signal_dout_pic,
vga_out,
signal_dx_add,
signal_dx_out
);
u6:sync
port map( signal_25M,
reset,
V,
H,
signal_Ready,
signal_Lie_Add,
signal_Hang_Add
);
u7:sz_pic
port map( signal_25M,
signal_add_pic,
signal_dout_pic
);
u8:LIFO_control2
port map ( clk,
reset,
signal_write,
signal_read,
data,
signal_read_en,
signal_wei,
signal_data1,
signal_data2,
signal_data3,
signal_data4,
signal_wea,
signal_adda,
signal_out
);
u9:dx_pic
PORT map(
signal_25M,
signal_dx_add,
signal_dx_out
);
u10 : LIFO
PORT MAP( clk,
signal_wea,
signal_adda,
data,
signal_out
);
end Behavioral;
FPGA开发板截图:
(1)、初始界面:
(2)、写入8 7 6 54 3 2 1:
(3)、读出为: