顶层文件telphone.vhd
LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
USE IEEE.STD_LOGIC_UNSIGNED.ALL;
ENTITY telphone IS
PORT(DIN1: IN STD_LOGIC_VECTOR(6 DOWNTO 0);
clk3:in std_logic;
CLK1,CLEAR,DIAL,RE_DIAL,delete:IN STD_LOGIC;
KEYOUT:OUT STD_LOGIC;
SEG71:OUT STD_LOGIC_VECTOR(7 DOWNTO 0);
SEG8:OUT STD_LOGIC_VECTOR(7 DOWNTO 0);
timebegin:in std_logic;
botong:out std_logic;
reset1:in std_logic
);
END ENTITY;
ARCHITECTURE ART OF telphone IS
COMPONENT SET_NUM IS
PORT(DIN:IN STD_LOGIC_VECTOR(6 DOWNTO 0);
clk3:in std_logic;
CLK,CLEAR,DIAL,RE_DIAL,delete:IN STD_LOGIC;
KEYOUT:OUT STD_LOGIC;
SET:OUT STD_LOGIC_VECTOR(3 DOWNTO 0);
SEG8:OUT STD_LOGIC_VECTOR(7 DOWNTO 0);
timebegin:in std_logic;
botong:out std_logic;
reset1:in std_logic
);
END COMPONENT;
COMPONENT DISPLAY IS
PORT(BCD1:IN STD_LOGIC_VECTOR(3 DOWNTO 0);
SEG7:OUT STD_LOGIC_VECTOR(7 DOWNTO 0));
END COMPONENT;
SIGNAL SET_1:STD_LOGIC_VECTOR(3 DOWNTO 0);
BEGIN
U1:SET_NUM PORT MAP(DIN1,clk3,CLK1,CLEAR,DIAL,RE_DIAL,delete,KEYOUT,SET_1,SEG8,timebegin,botong,reset1);
U2:DISPLAY PORT MAP(SET_1,SEG71);
END ART;
DISPLAY.vhd
LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
USE IEEE.STD_LOGIC_UNSIGNED.ALL;
ENTITY DISPLAY IS
PORT(
BCD1:IN STD_LOGIC_VECTOR(3 DOWNTO 0);
SEG7:OUT STD_LOGIC_VECTOR(7 DOWNTO 0));
END ENTITY;
ARCHITECTURE ONE OF DISPLAY IS
BEGIN
PROCESS(BCD1) IS
BEGIN
CASE BCD1 IS
WHEN"0000"=>SEG7<="00111111";
WHEN"0001"=>SEG7<="00000110";
WHEN"0010"=>SEG7<="01011011";
WHEN"0011"=>SEG7<="01001111";
WHEN"0100"=>SEG7<="01100110";
WHEN"0101"=>SEG7<="01101101";
WHEN"0110"=>SEG7<="01111101";
WHEN"0111"=>SEG7<="00000111";
WHEN"1000"=>SEG7<="01111111";
WHEN"1001"=>SEG7<="01101111";
when"1010"=>seg7<="10000000";--小数点
when"1011"=>seg7<="00000000";--全灭
WHEN OTHERS=>SEG7<="00000000";
END CASE;
END PROCESS;
END ONE;
SET_NUM.vhd
LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
USE IEEE.STD_LOGIC_ARITH.ALL;
USE IEEE.STD_LOGIC_UNSIGNED.ALL;
ENTITY SET_NUM IS
PORT(DIN:IN STD_LOGIC_VECTOR(6 DOWNTO 0);
clk3:in std_logic;
CLK,CLEAR,DIAL,RE_DIAL,delete:IN STD_LOGIC;
KEYOUT:OUT STD_LOGIC;
SET:OUT STD_LOGIC_VECTOR(3 DOWNTO 0);
SEG8:OUT STD_LOGIC_VECTOR(7 DOWNTO 0);
testpins:out std_logic;
timebegin:in std_logic;
botong:out std_logic;
reset1:in std_logic
);
END SET_NUM;
ARCHITECTURE ONE OF SET_NUM IS
SUBTYPE TEN IS STD_LOGIC_VECTOR(3 DOWNTO 0);
SIGNAL BCD:TEN;
TYPE NUMBER1 IS ARRAY(7 DOWNTO 0)OF STD_LOGIC_VECTOR(3 DOWNTO 0);
SIGNAL NUMBER:STD_LOGIC_VECTOR(31 DOWNTO 0):="00000000000000000000000000000000";
SIGNAL KEY,KEY1,KEY2,CLK1,DIAL1,RE_DIAL1:STD_LOGIC:='0';
SIGNAL COUNT:STD_LOGIC_VECTOR(3 DOWNTO 0):="0000";
SIGNAL COUNT1:STD_LOGIC_VECTOR(3 DOWNTO 0);
SIGNAL COUNT2:STD_LOGIC_VECTOR(2 DOWNTO 0);
SIGNAL DIN1:STD_LOGIC_VECTOR(6 DOWNTO 0);
SIGNAL LOCK:STD_LOGIC_VECTOR(31 DOWNTO 0);
signal count3,count4,count5,count6,count7,count8,count9,count10,count11:integer;
signal clktimes:STD_LOGIC_VECTOR(22 DOWNTO 0):="00000000000000000000000";
signal second,min:integer range 0 to 59:=0;
signal hour:integer range 0 to 24:=0;
signal storage:std_logic:='0';
signal botong1:std_logic:='0';
signal wanbi:std_logic:='0';
signal shanshuo:std_logic;
signal jieshu:std_logic:='0';
signal count12:std_logic_vector(3 downto 0):="1010";
signal weijieting:std_logic:='0';
BEGIN
process(clk3)--clk3连接pin125 频率为100000HZ
begin
if (clk3'event and clk3='1') then--拨通信号灯的判断
if wanbi='1' and jieshu='0' then
botong1<='1';
elsif dial='1' and wanbi='1' and shanshuo='0' and jieshu='0' then
botong1<='0';
elsif jieshu='1' and shanshuo='0' and wanbi='1' then--10s内未接通自动挂断
botong1<='0';
elsif wanbi='0' then
botong1<='0';
elsif timebegin='0' and dial='1' and jieshu='1' then--对方挂断
botong1<='0';
elsif timebegin='1' and dial='0' and jieshu='1' then--我方挂断
botong1<='0';
elsif timebegin='0' and dial='0' and jieshu='1' then
botong1<='0';
elsif jieshu='1' and shanshuo='1' and wanbi='1' then--10s内接通指示灯闪烁
if count3<100000 then
count3<=count3+1;
else
count3<=0;
botong1<=not botong1;
end if;
end if;
end if;
if (clk3'event and clk3='1') then--双方都挂断重置
if reset1='1' then
shanshuo<='0';
end if;
end if;
if (clk3'event and clk3='1') then--判断对方是否应答
if jieshu='1' then
if weijieting='1' then
shanshuo<='0';--
else
shanshuo<='1';
end if;
end if;
end if;
--以下为7个按键消抖
if(clk3'event and clk3='1') then
if(DIN(0)='0') then
count4<=count4+1;
if(count4=2000) then
DIN1(0)<='1';
else
DIN1(0)<='0';
end if;
else
count4<=0;
end if;
end if;
if(clk3'event and clk3='1') then
if(DIN(1)='0') then
count5<=count5+1;
if(count5=2000) then
DIN1(1)<='1';
else
DIN1(1)<='0';
end if;
else
count5<=0;
end if;
end if;
if(clk3'event and clk3='1') then
if(DIN(2)='0') then
count6<=count6+1;
if(count6=2000) then
DIN1(2)<='1';
else
DIN1(2)<='0';
end if;
else
count6<=0;
end if;
end if;
if(clk3'event and clk3='1') then
if(DIN(3)='0') then
count7<=count7+1;
if(count7=2000) then
DIN1(3)<='1';
else
DIN1(3)<='0';
end if;
else
count7<=0;
end if;
end if;
if(clk3'event and clk3='1') then
if(DIN(4)='0') then
count8<=count8+1;
if(count8=2000) then
DIN1(4)<='1';
else
DIN1(4)<='0';
end if;
else
count8<=0;
end if;
end if;
if(clk3'event and clk3='1') then
if(DIN(5)='0') then
count9<=count9+1;
if(count9=2000) then
DIN1(5)<='1';
else
DIN1(5)<='0';
end if;
else
count9<=0;
end if;
end if;
if(clk3'event and clk3='1') then
if(DIN(6)='0') then
count10<=count10+1;
if(count10=2000) then
DIN1(6)<='1';
else
DIN1(6)<='0';
end if;
else
count10<=0;
end if;
end if;
if(clk3'event and clk3='1') then
if(RE_DIAL='0') then
count11<=count11+1;
if(count11=2000) then
RE_DIAL1<='1';
else
RE_DIAL1<='0';
end if;
else
count11<=0;
end if;
end if;
end process;
PROCESS(CLK) IS
BEGIN
IF RISING_EDGE(CLK) THEN--上升沿触发
DIAL1<=DIAL;--拨号键赋值给DIAL1
botong<=botong1;--botong1赋值给拨通指示灯
END IF;
END PROCESS;
KEY<=(DIN1(0) OR DIN1(1) OR DIN1(2) OR DIN1(3) OR DIN1(4) OR DIN1(5) OR DIN1(6));--一旦有键按下则KEY为1
PROCESS(CLK,wanbi) IS --clk连接pin55 频率为6000000HZ
variable count1:integer range 0 to 20000;
variable count2:integer range 0 to 2000;
variable suo:boolean:=false;
BEGIN
IF FALLING_EDGE(CLK) THEN --下降沿有效\十秒倒计时
if reset1='1' then--双方都挂断重置
jieshu<='0';
count12<="1010";
weijieting<='0';
end if;
if timebegin='0' then
if wanbi='1' then
if (not suo) then
if count12="0000" then
suo:=true;
jieshu<='1';
weijieting<='1';
else
count1:=count1+1;
if count1=20000 then
count1:=0;
count2:=count2+1;
if count2=300 then --300为1秒
count2:=0;
count12<=count12-1;
end if;
end if;
end if;
end if;
end if;
else
jieshu<='1';
end if;
if CLEAR='0' AND RE_DIAL1='0' and timebegin='0' and delete='0'and dial='0' then--初始状态
KEY1<='1';
min<=0;
second<=0;
elsif CLEAR='0' AND RE_DIAL1='0' and timebegin='0' and delete='0'and dial='1' THEN--拨号键按下,数字输入,从低位向高位显示
KEY1<=KEY;
KEY2<='0';
min<=0;
second<=0;
ELSIF CLEAR='1' AND RE_DIAL1='0' and timebegin='0'and delete='0' and dial='1'THEN--删除键按下,数字从低位删除
KEY1<=CLEAR;
KEY2<=clear;
ELSIF CLEAR='0' AND RE_DIAL1='0' and timebegin='0'and delete='1' and dial='1'THEN--清除键按下,清楚数码管显示
KEY1<=delete;
KEY2<=delete;
elsif CLEAR='0' AND RE_DIAL1='0' and timebegin='1' and delete='0' and dial='1' then--对方应答,开始计时
if clktimes="10110111000110110000000" then
key1<='1';
clktimes<="00000000000000000000000";
if second=59 then
if min<60 then
min<=min+1;
end if;
second<=0;
else
second<=second+1;
end if;
else
key1<='0';
clktimes<=clktimes+1;
end if;
ELSif clear='0' and RE_DIAL1='1' and timebegin='0' and delete='0' and dial='1' then --拿起话筒,重拨键按下
KEY1<=RE_DIAL1;
END IF;
end if;
END PROCESS;
PROCESS(DIN1) IS--如果按键有变化
BEGIN
IF DIN1(6)='1' THEN BCD<="0110";
ELSIF DIN1(5)='1' THEN BCD<="0101";
ELSIF DIN1(4)='1' THEN BCD<="0100";
ELSIF DIN1(3)='1' THEN BCD<="0011";
ELSIF DIN1(2)='1' THEN BCD<="0010";
ELSIF DIN1(1)='1' THEN BCD<="0001";
ELSIF DIN1(0)='1' THEN BCD<="0000";
ELSE BCD<="0000";--0123456对应的BCD码
END IF;
END PROCESS;
KEYOUT<=KEY2;--删除键或清除键按下指示灯亮灭
PROCESS(KEY1)IS
variable m,m2:integer;
BEGIN
if RISING_EDGE(KEY1) THEN--key1上升沿检测
if reset1='1' then--双方都挂断重置
wanbi<='0';
elsif CLEAR='0' AND RE_DIAL1='0' and timebegin='0' and delete='0'and dial='0' THEN--初始状态
NUMBER(31 DOWNTO 0)<="10111011101110111011101110111011";
elsif CLEAR='0' AND RE_DIAL1='0' and timebegin='0' and delete='0'and dial='1' THEN--输入数字,实现数字从低位向高位移动
NUMBER(31 DOWNTO 28)<=NUMBER(27 DOWNTO 24);
NUMBER(27 DOWNTO 24)<=NUMBER(23 DOWNTO 20);
NUMBER(23 DOWNTO 20)<=NUMBER(19 DOWNTO 16);
NUMBER(19 DOWNTO 16)<=NUMBER(15 DOWNTO 12);
NUMBER(15 DOWNTO 12)<=NUMBER(11 DOWNTO 8);
NUMBER(11 DOWNTO 8)<=NUMBER(7 DOWNTO 4);
NUMBER(7 DOWNTO 4)<=NUMBER(3 DOWNTO 0);
NUMBER(3 DOWNTO 0)<=BCD;
if number(27 downto 24)/="1011" then--判断八位数字是否输入完毕
LOCK(31 DOWNTO 28)<=NUMBER(31 DOWNTO 28);
LOCK(27 DOWNTO 24)<=NUMBER(27 DOWNTO 24);
LOCK(23 DOWNTO 20)<=NUMBER(23 DOWNTO 20);
LOCK(19 DOWNTO 16)<=NUMBER(19 DOWNTO 16);
LOCK(15 DOWNTO 12)<=NUMBER(15 DOWNTO 12);
LOCK(11 DOWNTO 8)<=NUMBER(11 DOWNTO 8);
LOCK(7 DOWNTO 4)<=NUMBER(7 DOWNTO 4);
LOCK(3 DOWNTO 0)<=NUMBER(3 DOWNTO 0);
wanbi<='1';
end if;
ELSIF CLEAR='1' AND RE_DIAL1='0' and timebegin='0' and delete='0' and dial='1'THEN --按下删除键,数字从高位向低位移动
NUMBER(31 DOWNTO 28)<="1011";
NUMBER(27 DOWNTO 24)<=NUMBER(31 DOWNTO 28);
NUMBER(23 DOWNTO 20)<=NUMBER(27 DOWNTO 24);
NUMBER(19 DOWNTO 16)<=NUMBER(23 DOWNTO 20);
NUMBER(15 DOWNTO 12)<=NUMBER(19 DOWNTO 16);
NUMBER(11 DOWNTO 8)<=NUMBER(15 DOWNTO 12);
NUMBER(7 DOWNTO 4)<=NUMBER(11 DOWNTO 8);
NUMBER(3 DOWNTO 0)<=NUMBER(7 DOWNTO 4);
ELSIF CLEAR='0' AND RE_DIAL1='0' and timebegin='0' and delete='1' and dial='1' THEN--清除键按下,清楚数码管显示
number(31 downto 0)<="10111011101110111011101110111011";
elsif CLEAR='0' AND RE_DIAL1='0' and timebegin='1' and delete='0' and dial='1' then----对方应答,开始计时
number(31 downto 24)<="00000000";
number(23 downto 20)<="1010";
m:=min rem 10;
number(19 downto 16)<=conv_std_logic_vector((min-m)/10,4);
number(15 downto 12)<=conv_std_logic_vector(m,4);
number(11 downto 8)<="1010";
m2:=second rem 10;
NUMBER(7 DOWNTO 4)<=conv_std_logic_vector((second-m2)/10,4);
NUMBER(3 DOWNTO 0)<=conv_std_logic_vector(m2,4);
ELSif clear='0' and RE_DIAL1='1' and timebegin='0' and delete='0'and dial='1' then ----重拨键按下
NUMBER(31 DOWNTO 28)<=LOCK(31 DOWNTO 28);
NUMBER(27 DOWNTO 24)<=LOCK(27 DOWNTO 24);
NUMBER(23 DOWNTO 20)<=LOCK(23 DOWNTO 20);
NUMBER(19 DOWNTO 16)<=LOCK(19 DOWNTO 16);
NUMBER(15 DOWNTO 12)<=LOCK(15 DOWNTO 12);
NUMBER(11 DOWNTO 8)<=LOCK(11 DOWNTO 8);
NUMBER(7 DOWNTO 4)<=LOCK(7 DOWNTO 4);
NUMBER(3 DOWNTO 0)<=LOCK(3 DOWNTO 0);
wanbi<='1';
end if;
end if;
END PROCESS;
PROCESS(CLK) IS--为动态扫描数码管提供频率
BEGIN
IF RISING_EDGE(CLK) THEN
COUNT<=COUNT+1;
END IF;
END PROCESS;
PROCESS(COUNT)IS--动态扫描数码管
BEGIN
CASE COUNT IS--片选,选择数码管
WHEN"0001"=>SET<=NUMBER(31 DOWNTO 28);SEG8<="01111111";
WHEN"0011"=>SET<=NUMBER(27 DOWNTO 24);SEG8<="10111111";
WHEN"0101"=>SET<=NUMBER(23 DOWNTO 20);SEG8<="11011111" ;
WHEN"0111"=>SET<=NUMBER(19 DOWNTO 16);SEG8<="11101111" ;
WHEN"1001"=>SET<=NUMBER(15 DOWNTO 12);SEG8<="11110111" ;
WHEN"1011"=>SET<=NUMBER(11 DOWNTO 8);SEG8<="11111011" ;
WHEN"1101"=>SET<=NUMBER(7 DOWNTO 4);SEG8<="11111101" ;
WHEN"1111"=>SET<=NUMBER(3 DOWNTO 0);SEG8<="11111110" ;
WHEN OTHERS=>NULL;
END CASE;
END PROCESS;
END ONE;
板载为EPF10K20TC144-3
pins:
bug:
1.重置需要拨动reset1开关,置于1,再拨动dial置为1,在置为0,关闭reset即可拨动dial按键拨打电话
2.重置后10s倒计时失效
3.重拨键少一位