izhou0517 发表于 2011-1-30 23:40:50

我写的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;
          c3:out 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

M1:PROCESS(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;
M2:PROCESS(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";

WHENOTHERS=> 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
S1:PROCESS(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;
S2:PROCESS(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;

redbat_228 发表于 2011-1-31 09:13:54

mark

sky5566 发表于 2012-9-19 17:33:18

请问是否影 PS2 支持方向键长按的控制
页: [1]
查看完整版本: 我写的PS2键盘控制电子琴(VHDL)