实验名称 电子琴设计—任务2
(仅供学习使用,引用请注明出处)
一、实验电路图、状态图、流程图、程序代码、仿真代码、仿真波形图(可以只写出核心功能代码,代码要有注释)
1.设计思路
选曲:
基于任务1的设计,只需要在再设计控制音符的持续时间的部分即可。阅读此曲的简 谱,知最短的音符为8分音符,四分音符为一拍,每小节四拍,每拍60s/108≈0.5s。只需要一个4hz的时钟产生8分音符的时长,其他音符都是0.25s(此曲中一个八分音符的时长)的整数倍,只需要在记谱的时候记相应的次数即可。例如一个四分音符,则需要记音名两次。
记谱的实现采用实验要求中的思路:“自动播放功能需要在代码中编写一个“数据表”(可以是寄存器数组,也可以用 case 语句实现),数据表中存储着乐谱每个音符对应的分频系数。”,采用case语句实现。
为了实现循环播放,需要在设计一个计数器,记到对应的数时,把对应的分频系数送到分频器中,当记到最后一个音符时,重新从0计数,则可以达到循环播放的目标。
2.程序代码
module lyj_3501_7(mode_change,clk_in,clr,key,clk_out,clk_out_1,seg,codeout,beat);
//预置分频比
parameter O=14'd0;//休止符
parameter DO_=14'd11468;//中音1
parameter RE_=14'd10215;//中音2
parameter MI_=14'd9102;//中音3
parameter FA_=14'd8591;//中音4
parameter SO_=14'd7653;//中音5
parameter LA_=14'd6818;//中音6
parameter SI_=14'd6073;//中音7
parameter DO=14'd5736;//高音1
parameter RE=14'd5111;//高音2
parameter MI=14'd4552;//高音3
parameter FA=14'd4289;//高音4
parameter SO=14'd3827;//高音5
parameter LA=14'd3409;//高音6
parameter SI=14'd3037;//高音7
//输入
input mode_change;
input [13:0]key;//14个琴键输入
input clk_in;//时钟为6Mhz
input clr;//复位信号
//方便仿真的测试信号
output beat;
//输出
output reg clk_out;//分频器信号输出
output clk_out_1;//与clk_out一致
output [7:0] codeout;//八段数码管
output seg;//数码管位选选信号
//内部变量
reg [13:0]divider;//分频系数
reg [13:0]cnt;//计数器
reg flag;
//任务2内部变量
reg [19:0] cnt_clk_4hz;//4hz的计数器
reg clk_4hz;//半拍0.25s 一拍0.5s
reg [7:0] beat;//计时,循环播放
reg [13:0]divider_;//分频系数
assign clk_out_1=clk_out;//与clk_out一致
//得到4hz的时钟
always@(posedge clk_in or posedge clr)
begin
if(clr)
begin
clk_4hz<=0;
cnt_clk_4hz<=0;
end
else
begin
if(cnt_clk_4hz<750_000)
cnt_clk_4hz<=cnt_clk_4hz+1'b1;
else
begin
clk_4hz<=~clk_4hz;
cnt_clk_4hz<=0;
end
end
end
//分频器
always@(posedge clk_in or posedge clr)
begin
if(clr)//异步复位,高电平有效
begin
flag<=1;
cnt<=0;
end
else
begin
if(mode_change==0)
begin
if(cnt<divider)
begin
cnt<=cnt+1'b1;
flag<=1'b0;
end
else
begin
flag<=1'b1;
cnt<=1'b0;
end
end
else
begin
if(cnt<divider_)
begin
cnt<=cnt+1'b1;
flag<=1'b0;
end
else
begin
flag<=1'b1;
cnt<=1'b0;
end
end
end
end
//波形产生
always@(posedge flag)
begin//flag==1表示计数满,则波形反转
if(clr)
begin
clk_out<=0;
end
else
begin
if(key!=0||mode_change==1)
clk_out<=~clk_out;//得到50%占空比的方波信号
else
clk_out<=1'd0;
end
end
always@(key)
begin
case(key)//根据不同的音符,预置分频比
14'b0000_000_0000_000:divider<=0;
14'b1000_000_0000_000:divider<=14'd11468;
14'b0100_000_0000_000:divider<=14'd10215;
14'b0010_000_0000_000:divider<=14'd9102;
14'b0001_000_0000_000:divider<=14'd8591;
14'b0000_100_0000_000:divider<=14'd7653;
14'b0000_010_0000_000:divider<=14'd6818;
14'b0000_001_0000_000:divider<=14'd6073;
14'b0000_000_1000_000:divider<=14'd5736;
14'b0000_000_0100_000:divider<=14'd5111;
14'b0000_000_0010_000:divider<=14'd4552;
14'b0000_000_0001_000:divider<=14'd4289;
14'b0000_000_0000_100:divider<=14'd3827;
14'b0000_000_0000_010:divider<=14'd3409;
14'b0000_000_0000_001:divider<=14'd3037;
default:divider<=0;
endcase
end
always@(posedge clk_4hz)
begin
if(mode_change==1)
begin
if(beat==8'd72)
beat<=8'd0;
else
beat<=beat+1'b1;
end
else
begin
beat<=0;
end
case(beat)//记谱(小叮当)
0 :divider_<=O; //休止符
1 :divider_<=SO_; 41 :divider_<=SO_;
2 :divider_<=DO; 42 :divider_<=DO;
3 :divider_<=DO; 43 :divider_<=DO;
4 :divider_<=MI; 44 :divider_<=MI;
5 :divider_<=LA; 45 :divider_<=LA;
6 :divider_<=MI; 46 :divider_<=MI;
7 :divider_<=SO; 47 :divider_<=SO;
8 :divider_<=SO; 48 :divider_<=SO;
//第一节 //第六节
9 :divider_<=SO; 49 :divider_<=SO;
10 :divider_<=LA; 50 :divider_<=LA;
11 :divider_<=SO; 51 :divider_<=SO;
12 :divider_<=MI; 52 :divider_<=MI;
13 :divider_<=FA; 53 :divider_<=FA;
14 :divider_<=MI; 54 :divider_<=MI;
15 :divider_<=RE; 55 :divider_<=RE;
16 :divider_<=RE; 56 :divider_<=RE;
//第二节 //第七节
17 :divider_<=LA_; 57 :divider_<=LA_;
18 :divider_<=RE; 58 :divider_<=RE;
19 :divider_<=RE; 59 :divider_<=RE;
20 :divider_<=FA; 60 :divider_<=FA;
21 :divider_<=SI; 61 :divider_<=SI;
22 :divider_<=SI; 62 :divider_<=SI;
23 :divider_<=LA; 63 :divider_<=LA;
24 :divider_<=SO; 64 :divider_<=SO;
// 第三节 //第八节
25 :divider_<=SO; 65 :divider_<=FA;
26 :divider_<=SO; 66 :divider_<=FA;
27 :divider_<=FA; 67 :divider_<=FA;
28 :divider_<=MI; 68 :divider_<=MI;
29 :divider_<=LA_; 69 :divider_<=SI_;
30 :divider_<=SI_; 70 :divider_<=SI_;
31 :divider_<=SI_; 71 :divider_<=RE;
32 :divider_<=DO; 72 :divider_<=RE;
// 第五节 //第九节
33 :divider_<=RE;
34 :divider_<=RE;
35 :divider_<=RE;
36 :divider_<=RE;
37 :divider_<=RE;
38 :divider_<=O ;
39 :divider_<=O ;
40 :divider_<=O ;
//第六节
default:divider_<=O;//休止符
endcase
end
lyj_3501_6_b u1(key,codeout,seg);
endmodule
module lyj_3501_6_b(key,codeout,seg);//译码器模块
input [13:0] key;
output reg[7:0] codeout;
output seg;
assign seg=1'b1;//数码管位选信号
always@ (key)
begin
case(key)
14'b1000_000_0000_000:codeout=8'b0_0000110;//中音1
14'b0100_000_0000_000:codeout=8'b0_1011011;//中音2
14'b0010_000_0000_000:codeout=8'b0_1001111;//中音3
14'b0001_000_0000_000:codeout=8'b0_1100110;//中音4
14'b0000_100_0000_000:codeout=8'b0_1101101;//中音5
14'b0000_010_0000_000:codeout=8'b0_1111101;//中音6
14'b0000_001_0000_000:codeout=8'b0_0000111;//中音7
14'b0000_000_1000_000:codeout=8'b1_0000110;//高音1
14'b0000_000_0100_000:codeout=8'b1_1011011;//高音2
14'b0000_000_0010_000:codeout=8'b1_1001111;//高音3
14'b0000_000_0001_000:codeout=8'b1_1100110;//高音4
14'b0000_000_0000_100:codeout=8'b1_1101101;//高音5
14'b0000_000_0000_010:codeout=8'b1_1111101;//高音6
14'b0000_000_0000_001:codeout=8'b1_0000111;//高音7
14'b0000_000_0000_000:codeout=8'b1_1111111;//休止符
default:codeout=8'b1_0111111;//0
endcase
end
endmodule
//测试文件
`timescale 1ns / 1ns//时间单位/时间精度
module test_lyj_3501_7;
reg clk_in,clr;
reg [13:0]key;
reg mode_change;
wire [7:0]beat;//方便观察仿真结果
wire seg;
wire [7:0]codeout;
wire clk_out_1,clk_out;
lyj_3501_7 test_a(.mode_change(mode_change),.clk_in(clk_in),.clr(clr),.key(key),.clk_out(clk_out),.clk_out_1(clk_out_1),.seg(seg),.codeout(codeout),.beat(beat));
always #83 clk_in=~clk_in;//近似为6Mhz的时钟
initial
begin
clk_in=1'b0;
clr=1'b1;
key=14'd0;
#1000
clr=1'b0;
#1000
mode_change=0;
#1_000_000_000
mode_change=1;
end
endmodule
3.仿真波形图
数据过多,且任务1已经做过误差分析,同时随机抽检结果也符合要求
二、引脚分配表(电路中的信号名称->主板器件名称->引脚号PIN)
信号名 主板器件 PIN 信号名 主板器件 PIN
key[13] Key13 PIN_7 codeout[0] a PIN_112
key[12] Key12 PIN_8 codeout[1] b PIN_100
key[11] Key11 PIN_144 codeout[2] c PIN_104
key[10] Key10 PIN_6 codeout[3] d PIN_111
key[9] Key9 PIN_13 codeout[4] e PIN_106
key[8] Key8 PIN_43 codeout[5] f PIN_110
key[7] Key7 PIN_44 codeout[6] g PIN_103
key[6] Key6 PIN_39 codeout[7] h PIN_105
key[5] Key5 PIN_42 seg SEG0 PIN_119
key[4] Key4 PIN_32 clk_out 扬声器 PIN_128
key[3] Key3 PIN_33 clk_out_1 LED0/IO0 PIN_46
key[2] Key2 PIN_30 mode_change Key16 PIN_142
key[1] Key1 PIN_31
key[0] Key0 PIN_24
clk_in Clk0 PIN_88
clr Key17 PIN_137
三、实验现象及原始数据记录
Top-level Entity name Family Device
lyj_3501_7 Cyclone IV E EP4CE6E22C8
Total logic elements Total registers Total pins
265 45 37
Total memory bits Embedded Multiplier 9-bit elements Total PLLs
0 0 0
波形图、真值表
参考资料:
王金明,徐志军,苏勇.《EDA技术与Verilog HDL设计》[M]:电子工业出版社,2013