标题: 我写的PS2键盘控制电子琴(VHDL) [打印本页] 作者: 曾经最美 时间: 2016-4-27 21:39 标题: 我写的PS2键盘控制电子琴(VHDL) 本人新手,还望高手多多指点。
共分为DIV1、DIV2分频模块,PS2键盘控制模块,music发音模块,tone音符分频模块,spk发声模块。
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
---- Uncomment the following library declaration if instantiating
---- any Xilinx primitives in this code.
--library UNISIM;
--use UNISIM.VComponents.all;
entity Div1 is
PORT(clk_50mhz: IN STD_LOGIC; --输入时钟为50MHZ;
c0: OUT STD_LOGIC;
c1: OUT STD_LOGIC);
END Div1;
architecture art of Div1 is
begin
D1: PROCESS(clk_50mhz) --工作进程开始,将50MHZ时钟50分频,=1MHZ;
VARIABLE count6:INTEGER RANGE 0 TO 50;
BEGIN
IF(clk_50mhz 'EVENT AND clk_50mhz ='1')THEN
count6:=count6+1;
IF count6=25 THEN
c0 <='1';
ELSIF count6=50 THEN
c0 <='0'; count6:=0;
END IF;
END IF;
END PROCESS;
D2: PROCESS(clk_50mhz) --将50MHZ时钟100分频,=0.5MHZ;
VARIABLE count7: INTEGER RANGE 0 TO 100;
BEGIN
IF(clk_50mhz 'EVENT AND clk_50mhz ='1')THEN
count7:=count7+1;
IF count7=50 THEN
c1<='1';
ELSIF count7=100 THEN
c1 <='0'; count7:=0;
END IF;
END IF;
END PROCESS;
END art;
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
---- Uncomment the following library declaration if instantiating
---- any Xilinx primitives in this code.
--library UNISIM;
--use UNISIM.VComponents.all;
entity Div2 is
PORT(clk4: IN STD_LOGIC; --输入时钟为1MHZ;
c2: OUT STD_LOGIC; --输出100khz;
c3ut std_logic); --输出时钟为4HZ;
END Div2;
ARCHITECTURE art OF Div2 IS
begin
D1: PROCESS(clk4) --工作进程开始,将1MHZ时钟10分频;
VARIABLE count8:INTEGER RANGE 0 TO 10;
BEGIN
IF(clk4 'EVENT AND clk4 ='1')THEN
count8:=count8+1;
IF count8=5 THEN
c2 <='1';
ELSIF count8=10 THEN
c2 <='0'; count8:=0;
END IF;
END IF;
END PROCESS;
D2: PROCESS(clk4) --250000分频;
VARIABLE count9: INTEGER RANGE 0 TO 250000;
BEGIN
IF(clk4 'EVENT AND clk4 ='1')THEN
count9:=count9+1;
IF count9=125000 THEN
c3<='1';
ELSIF count9=250000 THEN
c3 <='0'; count9:=0;
END IF;
END IF;
END PROCESS;
END art;
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
---- Uncomment the following library declaration if instantiating
---- any Xilinx primitives in this code.
--library UNISIM;
--use UNISIM.VComponents.all;
entity ps2 is
Port ( sysclk: in std_logic;
ps2clk: in std_logic;
ps2data: in std_logic;
reset: in std_logic;
result: out std_logic_vector(7 downto 0));
end ps2;
architecture art of ps2 is
signal ps2clk_r : std_logic_vector(2 downto 0);
signal ps2clkfall : std_logic;
signal q : std_logic_vector(11 downto 0);
signal ps2serialdata : std_logic_vector(10 downto 0) ;
begin
process(sysclk,reset)
begin
if reset='0' then
ps2clk_r <= "000";
elsif rising_edge(sysclk) then
ps2clk_r(2) <= ps2clk_r(1);
ps2clk_r(1) <= ps2clk_r(0);
ps2clk_r(0) <= ps2clk;
end if;
end process;
ps2clkfall<='1' when ps2clk_r="110" else '0';
process(sysclk)
begin
if rising_edge(sysclk) then
if reset='0' then q <= (others =>'0');
elsif ps2clkfall='1' then
if q(0)='0' then
q <= ps2data & "01111111111";
else
q <= ps2data & q(11 downto 1);
end if;
end if;
end if;
end process;
process(q)
begin
if q(0) = '0' then
ps2serialdata <= q(11 downto 1);
result <= not ps2serialdata(8 downto 1);
else
result <="11111111";
end if;
end process;
end art;
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
---- Uncomment the following library declaration if instantiating
---- any Xilinx primitives in this code.
--library UNISIM;
--use UNISIM.VComponents.all;
entity music is
PORT(clk2: IN STD_LOGIC; --4HZ时钟信号
index1: IN STD_LOGIC_VECTOR(7 DOWNTO 0); --键盘输入信号
index2: OUT STD_LOGIC_VECTOR(7 DOWNTO 0)); --音符信号输出
END music;
ARCHITECTURE art OF music IS
SIGNAL count3:INTEGER RANGE 0 TO 31; --定义信号计数器,有32个元素
BEGIN
M1ROCESS(count3,clk2,index1) --music工作进程开始
BEGIN
IF(clk2 'EVENT AND clk2 ='1')THEN --时钟信号2为1
IF(count3=31)THEN --计数器值为31
count3<=0; --计数器清0
ELSE
count3<=count3+1;
END IF;
END IF;
END PROCESS;
M2ROCESS(count3,index1)
BEGIN
IF index1="01001101" THEN 按下P键生效
CASE count3 IS --由计数器从0到31的取??断音符信号?制? WHEN 0=>index2<="00000011"; --3
WHEN 1=> index2<="00000011"; --3
WHEN 2=> index2<="00000011"; --3
WHEN 3=> index2<="00000011"; --3
WHEN 4=> index2<="00000101"; --5
WHEN 5=> index2<="00000101"; --5
WHEN 6=> index2<="00000101"; --5
WHEN 7=> index2<="00000110"; --6
WHEN 8=> index2<="00001000"; --8
WHEN 9=> index2<="00001000"; --8
WHEN 10=> index2<="00001000"; --8
WHEN 11=> index2<="00000011"; --3
WHEN 12=> index2<="00000010"; --2
WHEN 13=> index2<="00000010"; --2
WHEN 14=> index2<="00000001"; --1
WHEN 15=> index2<="00000001"; --1
WHEN 16=> index2<="00000101"; --5
WHEN 17=> index2<="00000101"; --5
WHEN 18=> index2<="00000100"; --4
WHEN 19=> index2<="00000100"; --4
WHEN 20=> index2<="00000100"; --4
WHEN 21=> index2<="00000011"; --3
WHEN 22=> index2<="00000010"; --2
WHEN 23=> index2<="00000010"; --2
WHEN 24=> index2<="00000101"; --5
WHEN 25=> index2<="00000101"; --5
WHEN 26=> index2<="00000100"; --4
WHEN 27=> index2<="00000100"; --4
WHEN 28=> index2<="00000011"; --3
WHEN 29=> index2<="00000011"; --3
WHEN 30=> index2<="00000010"; --2
WHEN 31=> index2<="00000010"; --2
WHEN OTHERS=>NULL;
END CASE;
ELSE --index2<=index1;
case index1 is
when"00010101"=>index2<="00000001";--q
when"00011101"=>index2<="00000010";--w
when"00100100"=>index2<="00000011";--e
when"00101101"=>index2<="00000100";--r
when"00101100"=>index2<="00000101";--t
when"00110101"=>index2<="00000110";--y
when"00111100"=>index2<="00000111";--u
when"00011010"=>index2<="00001111";--z
when"00100010"=>index2<="00010000";--x
when"00100001"=>index2<="00010001";--c
when"00101010"=>index2<="00010010";--v
when"00110010"=>index2<="00010011";--b
when"00110001"=>index2<="00010100";--n
when"00111010"=>index2<="00010101";--m
when others=>index2<="11111111";
end case;
END IF;
END PROCESS;
END art;
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
---- Uncomment the following library declaration if instantiating
---- any Xilinx primitives in this code.
--library UNISIM;
--use UNISIM.VComponents.all;
entity tone is
Port (index3: IN STD_LOGIC_VECTOR(7 DOWNTO 0); --音符输入信号
code1: OUT STD_LOGIC_VECTOR(6 DOWNTO 0); --音符显示信号
high1: OUT STD_LOGIC_VECTOR(2 DOWNTO 0); --高低音显示信号
tone1: OUT INTEGER RANGE 0 TO 2047); --音符的分频系数
end tone;
architecture art of tone is
begin
T1:process(index3)
begin
case index3 is
when"00000001"=> tone1<=1191; code1<="1001111"; high1<="001";
WHEN"00000010"=> tone1<=1702; code1<="0010010"; high1<="001";
WHEN"00000011"=> tone1<=1517; code1<="0000110"; high1<="001";
WHEN"00000100"=> tone1<=1432; code1<="1001100"; high1<="001";
WHEN"00000101"=> tone1<=1276; code1<="0100100"; high1<="001";
WHEN"00000110"=> tone1<=1136; code1<="0100000"; high1<="001";
WHEN"00000111"=> tone1<=1012; code1<="0001111"; high1<="001";
WHEN OTHERS => tone1<=2047; code1<="0000000"; high1<="000";
END CASE;
END PROCESS;
END art;
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
---- Uncomment the following library declaration if instantiating
---- any Xilinx primitives in this code.
--library UNISIM;
--use UNISIM.VComponents.all;
entity speaker is
PORT(clk3: IN STD_LOGIC; --0.5MHZ时钟信号;
tone2: IN INTEGER RANGE 0 TO 2047; --音符分频系数
spk: OUT STD_LOGIC); --驱动扬声器的音频信号
END speaker;
ARCHITECTURE art OF speaker IS
SIGNAL fullclk: STD_LOGIC;
BEGIN
S1ROCESS(clk3,tone2)
VARIABLE count4:INTEGER RANGE 0 TO 2047; --定义变量频率计数器2047Hz
BEGIN
IF(clk3'EVENT AND clk3='1')THEN --clk3脉冲上升沿触发
IF count4<tone2 THEN --若计数器11值小于音符信1
count4:=count4+1;fullclk<='1'; --计数器加1,音频信号为1
ELSE
count4:=0;fullclk<='0';
END IF;
END IF;
END PROCESS;
S2ROCESS(fullclk) --音频信号输出进程开始
VARIABLE count5:STD_LOGIC:='0'; --定义变量计数器2,初值0
BEGIN
IF(fullclk'EVENT AND fullclk='1')THEN --音频信号输出上升沿有效时
count5:=NOT count5;
IF count5='1'THEN
spk<='1';
ELSE
spk<='0';
END IF;
END IF;
END PROCESS;
END art;