查看: 985|回复: 0
打印 上一主题 下一主题

我写的PS2键盘控制电子琴(VHDL)

[复制链接]
跳转到指定楼层
沙发
发表于 2016-4-27 21:39:21 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
本人新手,还望高手多多指点。
共分为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"00011100"=>index2<="00001000";--a
when"00011011"=>index2<="00001001";--s
when"00100011"=>index2<="00001010";--d
when"00101011"=>index2<="00001011";--f
when"00110100"=>index2<="00001100";--g
when"00110011"=>index2<="00001101";--h
when"00111011"=>index2<="00001110";--j

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"00001000"=> tone1<=955;  code1<="1001111"; high1<="010";
WHEN"00001001"=> tone1<=851;  code1<="0010010"; high1<="010";  
WHEN"00001010"=> tone1<=758;  code1<="0000110"; high1<="010";
WHEN"00001011"=> tone1<=716;  code1<="1001100"; high1<="010";
WHEN"00001100"=> tone1<=638;  code1<="0100100"; high1<="010";
WHEN"00001101"=> tone1<=568;  code1<="0100000"; high1<="010";
WHEN"00001110"=> tone1<=506;  code1<="0001111"; high1<="010";

WHEN"00001111"=> tone1<=478;  code1<="1001111"; high1<="100";
WHEN"00010000"=> tone1<=426;  code1<="0010010"; high1<="100";
WHEN"00010001"=> tone1<=379;  code1<="0000110"; high1<="100";
WHEN"00010010"=> tone1<=358;  code1<="1001100"; high1<="100";
WHEN"00010011"=> tone1<=319;  code1<="0100100"; high1<="100";
WHEN"00010100"=> tone1<=284;  code1<="0100000"; high1<="100";
WHEN"00010101"=> tone1<=253;  code1<="0001111"; high1<="100";

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;
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 加入因仑

本版积分规则

快速回复 返回顶部 返回列表