当前位置:   article > 正文

FPGA复杂数字系统设计1(数字电子琴)_数字逻辑电路课程设计简易电子琴设计

数字逻辑电路课程设计简易电子琴设计

做的是一个简陋的按键电子琴模块,并且用的笨办法,很笨蛋,但有效。

一、来看看实验要求:

通过按键控制蜂鸣器鸣响,编写Verilog程序,对基本时钟源(20MHz)进行分频,以产生如表1所示的各个频率信号。表1中列出的频率共有21个,分别与低音、中音、高音3个频段下的不同音调相对应(每个频段下有7个音调)。通过按键产生相应的序列频率信号,并发送到蜂鸣器,可演奏出音乐。

使用主板上的8个白色独立按键(1”~“8”)模拟琴键。通过“键8”来选择高、中、低音三个频段,并由其余7个按键选择该频段下7个不同的音阶。按下“按键8”实现频段由频段1到频段3的循环切换。数码管“数码8”即时显示当前频段值(1,2或3)。当按下不同的音阶时,7个数码管“数码1”至“数码7”也即时显示当前的音阶值。

 二、在编写程序前需要明确的事情:

1.本次的代码实现用了分模块的思路,虽然分得很烂且分了跟分得太散,但是也算是分模块吧。

 2.本次实际分了6个模块,分别是顶层模块piano,分模块5个,每个分模块的作用在下面有注释,且所有代码都注释标好了,纯傻瓜式注释,看不懂打我(bushi)。

3,分模块中有需要注意的一个点就是PLL锁相环模块,需要读者自己使用IP核进行设置,需要把核心板时钟20MHZ分频成5MHZ引出来作为音阶频率的计算基准源,分频的21个系数如下:

  1. //算出高中低音对应7个音阶各自的分频系数,
  2. parameter MIN_DO = 15'd19080,//(5_000_000/262)
  3. MIN_RE = 15'd17006,//(5_000_000/294)
  4. MIN_MI = 15'd15150,//(5_000_000/330)
  5. MIN_FA = 15'd14326,//(5_000_000/349)
  6. MIN_SO = 15'd12756,//(5_000_000/392)
  7. MIN_LA = 15'd11360,//(5_000_000/440)
  8. MIN_XI = 15'd10120;//(5_000_000/494)
  9. //中音
  10. parameter MID_DO = 15'd9560,//(5_000_000/523)
  11. MID_RE = 15'd8516,//(5_000_000/587)
  12. MID_MI = 15'd7586,//(5_000_000/659)
  13. MID_FA = 15'd7160,//(5_000_000/698)
  14. MID_SO = 15'd6376,//(5_000_000/784)
  15. MID_LA = 15'd5680,//(5_000_000/880)
  16. MID_XI = 15'd5060;//(5_000_000/988)
  17. //高音
  18. parameter MAX_DO = 15'd4776,//(5_000_000/1047)
  19. MAX_RE = 15'd4256,//(5_000_000/1175)
  20. MAX_MI = 15'd3790,//(5_000_000/1319)
  21. MAX_FA = 15'd3580,//(5_000_000/1397)
  22. MAX_SO = 15'd3190,//(5_000_000/1568)
  23. MAX_LA = 15'd2842,//(5_000_000/1760)
  24. MAX_XI = 15'd2542;//(5_000_000/1967)

4.分模块中音阶频率的实现我使用了傻瓜式代码操作,就是重复了21次同个分频模块,浪费了21个寄存器计数的笨方法。

  1. clk_5m_o就是锁相环输出的5mhz频率计算基准源
  2. always@(posedge clk_5m_o or negedge rst)
  3. begin
  4. if(!rst)//复位信号,预置0
  5. begin
  6. count1<=0;
  7. //count1是第一个用来计数的寄存器,同样作用的寄存器还有20个,
  8. clk_h0<=0; //clk_h0是最低音的第一个音阶频率输出;
  9. //(本来以h命名该是最高音的,但我不小心一开始编程的时候就把h和l搞反了
  10. end
  11. else begin //MIN_DO是低音第一个音阶的分频系数,
  12. if(count1==((MIN_DO>>1)-1'b1))begin count1<=0;clk_h0<=~clk_h0;end
  13. else count1 <=count1+1;//
  14. end
  15. end
  16. //同样的模块还有20个,每次要把count1和clk_h0,还有MIN_DO都替换成对应的正确内容

三、以下是全部代码:

注:引脚绑定看用什么板,需要自己查阅试验箱说明书。

  1. /*
  2. 时间:2023/5/14
  3. 作者:黄
  4. 作用:制作一个电子琴,通过按键输入演奏谱曲;
  5. */
  6. module piano(//顶层模块
  7. clk_i,
  8. rst,
  9. p8_i,
  10. ps_i,//输入
  11. speaker_o,
  12. bt1,
  13. bt2,
  14. led8,
  15. seg
  16. );
  17. input clk_i,//时钟信号
  18. rst,//复位信号
  19. p8_i;//第八个按键输入
  20. input[6:0] ps_i;//7个按键输入
  21. //需要注意的是,按键输入都是上升沿触发,
  22. output speaker_o;//蜂鸣器输出
  23. output [6:0] bt2;
  24. output bt1;
  25. output [3:0]led8;//duanxuan
  26. output[27:0] seg;
  27. wire[1:0] to_o;//第八个数码管显示显示高中低音
  28. wire clk_5m_o;
  29. wire clk_h0,//h代表高音,m代表中音,l代表低音,0-7代表音阶
  30. clk_h1,//要注意的是,我一开始编程的时候搞反了,所以代码实际实现的时候h代表低音,l代表高音
  31. clk_h2,
  32. clk_h3,
  33. clk_h4,
  34. clk_h5,
  35. clk_h6,
  36. clk_m0,
  37. clk_m1,
  38. clk_m2,
  39. clk_m3,
  40. clk_m4,
  41. clk_m5,
  42. clk_m6,
  43. clk_l0,
  44. clk_l1,
  45. clk_l2,
  46. clk_l3,
  47. clk_l4,
  48. clk_l5,
  49. clk_l6;
  50. clk_div clk_div(
  51. .clk_i(clk_i),
  52. .rst(rst),
  53. .clk_h0(clk_h0),//h代表高音,m代表中音,l代表低音,0-7代表音阶
  54. .clk_h1(clk_h1),//要注意的是,我一开始编程的时候搞反了,所以代码实际实现的时候h代表低音,l代表高音
  55. .clk_h2(clk_h2),
  56. .clk_h3(clk_h3),
  57. .clk_h4(clk_h4),
  58. .clk_h5(clk_h5),
  59. .clk_h6(clk_h6),
  60. .clk_m0(clk_m0),
  61. .clk_m1(clk_m1),
  62. .clk_m2(clk_m2),
  63. .clk_m3(clk_m3),
  64. .clk_m4(clk_m4),
  65. .clk_m5(clk_m5),
  66. .clk_m6(clk_m6),
  67. .clk_l0(clk_l0),
  68. .clk_l1(clk_l1),
  69. .clk_l2(clk_l2),
  70. .clk_l3(clk_l3),
  71. .clk_l4(clk_l4),
  72. .clk_l5(clk_l5),
  73. .clk_l6(clk_l6),
  74. .clk_5m_o(clk_5m_o)
  75. );
  76. //第二个模块,获取第八个按键输入,并输出
  77. board_input board_input(
  78. .rst(rst),//复位
  79. .p8_i(p8_i),//第八个按键,用来制作选择高中低
  80. .to_o(to_o),//输出数据
  81. );
  82. //第三个模块,输出8个数码管的内容并显示在实验板上
  83. seg_display seg_display(
  84. .to_o(to_o),//数码管八的内容
  85. .ps_i(ps_i),//七个按键输入
  86. .led8(led8),//单独输出第八个数码管内容
  87. .bt1(bt1),//bt1 bt2是位选,选择输出哪个数码管
  88. .bt2(bt2),//
  89. .seg(seg)//同步输出七个数码管内容,同一时间只能按一个
  90. );
  91. selct_speaker selct_speaker_U5(
  92. .clk_5m_o(clk_5m_o),//5m时钟信号输入,来源于第一个时钟模块
  93. .rst(rst),
  94. .to_o(to_o),//输入高中低音选择
  95. .ps_i(ps_i),//循环扫描p1-p7这7个按键;
  96. .clk_h0(clk_h0),//输入所有音阶分频频率,h代表高音,m代表中音,l代表低音,0-7代表音阶
  97. .clk_h1(clk_h1),//要注意的是,我一开始编程的时候搞反了,所以代码实际实现的时候h代表低音,l代表高音
  98. .clk_h2(clk_h2),
  99. .clk_h3(clk_h3),
  100. .clk_h4(clk_h4),
  101. .clk_h5(clk_h5),
  102. .clk_h6(clk_h6),
  103. .clk_m0(clk_m0),
  104. .clk_m1(clk_m1),
  105. .clk_m2(clk_m2),
  106. .clk_m3(clk_m3),
  107. .clk_m4(clk_m4),
  108. .clk_m5(clk_m5),
  109. .clk_m6(clk_m6),
  110. .clk_l0(clk_l0),
  111. .clk_l1(clk_l1),
  112. .clk_l2(clk_l2),
  113. .clk_l3(clk_l3),
  114. .clk_l4(clk_l4),
  115. .clk_l5(clk_l5),
  116. .clk_l6(clk_l6),
  117. .speaker_o(speaker_o)//蜂鸣器输出
  118. );
  119. endmodule
  120. module clk_div(
  121. clk_i,
  122. rst,
  123. clk_h0,//h代表高音,m代表中音,l代表低音,0-7代表音阶
  124. clk_h1,//要注意的是,我一开始编程的时候搞反了,所以代码实际实现的时候h代表低音,l代表高音
  125. clk_h2,
  126. clk_h3,
  127. clk_h4,
  128. clk_h5,
  129. clk_h6,
  130. clk_m0,
  131. clk_m1,
  132. clk_m2,
  133. clk_m3,
  134. clk_m4,
  135. clk_m5,
  136. clk_m6,
  137. clk_l0,
  138. clk_l1,
  139. clk_l2,
  140. clk_l3,
  141. clk_l4,
  142. clk_l5,
  143. clk_l6,
  144. clk_5m_o//5m输出
  145. );
  146. input clk_i,rst;
  147. output clk_5m_o;
  148. output reg clk_h0,//h代表高音,m代表中音,l代表低音,0-7代表音阶
  149. clk_h1,//要注意的是,我一开始编程的时候搞反了,所以代码实际实现的时候h代表低音,l代表高音
  150. clk_h3,
  151. clk_h4,
  152. clk_h5,
  153. clk_h6,
  154. clk_m0,
  155. clk_m1,
  156. clk_m2,
  157. clk_m3,
  158. clk_m4,
  159. clk_m5,
  160. clk_m6,
  161. clk_l0,
  162. clk_l1,
  163. clk_l2,
  164. clk_l3,
  165. clk_l4,
  166. clk_l5,
  167. clk_l6;
  168. //算出高中低音对应7个音阶各自的分频系数,
  169. parameter MIN_DO = 15'd19080,//(5_000_000/262)
  170. MIN_RE = 15'd17006,//(5_000_000/294)
  171. MIN_MI = 15'd15150,//(5_000_000/330)
  172. MIN_FA = 15'd14326,//(5_000_000/349)
  173. MIN_SO = 15'd12756,//(5_000_000/392)
  174. MIN_LA = 15'd11360,//(5_000_000/440)
  175. MIN_XI = 15'd10120;//(5_000_000/494)
  176. //中音
  177. parameter MID_DO = 15'd9560,//(5_000_000/523)
  178. MID_RE = 15'd8516,//(5_000_000/587)
  179. MID_MI = 15'd7586,//(5_000_000/659)
  180. MID_FA = 15'd7160,//(5_000_000/698)
  181. MID_SO = 15'd6376,//(5_000_000/784)
  182. MID_LA = 15'd5680,//(5_000_000/880)
  183. MID_XI = 15'd5060;//(5_000_000/988)
  184. //高音
  185. parameter MAX_DO = 15'd4776,//(5_000_000/1047)
  186. MAX_RE = 15'd4256,//(5_000_000/1175)
  187. MAX_MI = 15'd3790,//(5_000_000/1319)
  188. MAX_FA = 15'd3580,//(5_000_000/1397)
  189. MAX_SO = 15'd3190,//(5_000_000/1568)
  190. MAX_LA = 15'd2842,//(5_000_000/1760)
  191. MAX_XI = 15'd2542;//(5_000_000/1967)
  192. //使用21个寄存器计数
  193. reg [14:0]count1;
  194. reg [14:0]count2;
  195. reg [14:0]count3 ;
  196. reg [14:0]count4 ;
  197. reg [14:0]count5 ;
  198. reg [14:0]count6 ;
  199. reg [14:0]count7 ;
  200. reg [14:0]count11 ;
  201. reg [14:0]count12;
  202. reg [14:0]count13;
  203. reg [14:0]count14 ;
  204. reg [14:0]count15 ;
  205. reg [14:0]count16 ;
  206. reg [14:0]count17 ;
  207. reg [14:0]count21 ;
  208. reg [14:0]count22 ;
  209. reg [14:0]count23 ;
  210. reg [14:0]count24 ;
  211. reg [14:0]count25 ;
  212. reg [14:0]count26 ;
  213. reg [14:0]count27 ;
  214. //引用锁相环模块,做出5mhz输出
  215. PLL PLL_U1(
  216. .inclk0 (clk_i),
  217. .c0 ( clk_5m_o),
  218. .locked ( locked_sig )
  219. );
  220. //分频模块,重复21次,替换上每个模块对应的分频系数和计数寄存器count
  221. always@(posedge clk_5m_o or negedge rst)
  222. begin
  223. if(!rst)
  224. begin
  225. count1<=0;
  226. clk_h0<=0;
  227. end
  228. else begin
  229. if(count1==((MIN_DO>>1)-1'b1))begin count1<=0;clk_h0<=~clk_h0;end
  230. else count1 <=count1+1;
  231. end
  232. end
  233. always@(posedge clk_5m_o or negedge rst)
  234. begin
  235. if(!rst)
  236. begin
  237. count2<=0;
  238. clk_h1<=0;
  239. end
  240. else begin
  241. if(count2==((MIN_RE>>1)-1'b1))begin count2<=0;clk_h1<=~clk_h1;end
  242. else count2 <=count2+1;
  243. end
  244. end
  245. always@(posedge clk_5m_o or negedge rst)
  246. begin
  247. if(!rst)
  248. begin
  249. count3<=0;
  250. clk_h2<=0;
  251. end
  252. else begin
  253. if(count3==((MIN_MI>>1)-1'b1))begin count3<=0;clk_h2=~clk_h2;end
  254. else count3 <=count3+1;
  255. end
  256. end
  257. always@(posedge clk_5m_o or negedge rst)
  258. begin
  259. if(!rst)
  260. begin
  261. count4<=0;
  262. clk_h3<=0;
  263. end
  264. else begin
  265. if(count4==((MIN_FA>>1)-1'b1))begin count4<=0;clk_h3=~clk_h3;end
  266. else count4 <=count4+1;
  267. end
  268. end
  269. always@(posedge clk_5m_o or negedge rst)
  270. begin
  271. if(!rst)
  272. begin
  273. count5<=0;
  274. clk_h4<=0;
  275. end
  276. else begin
  277. if(count5==((MIN_SO>>1)-1'b1))begin count5<=0;clk_h4=~clk_h4;end
  278. else count5 <=count5+1;
  279. end
  280. end
  281. always@(posedge clk_5m_o or negedge rst)
  282. begin
  283. if(!rst)
  284. begin
  285. count6<=0;
  286. clk_h5<=0;
  287. end
  288. else begin
  289. if(count6==((MIN_LA>>1)-1'b1))begin count6<=0;clk_h5=~clk_h5;end
  290. else count6 <=count6+1;
  291. end
  292. end
  293. always@(posedge clk_5m_o or negedge rst)
  294. begin
  295. if(!rst)
  296. begin
  297. count7<=0;
  298. clk_h6<=0;
  299. end
  300. else begin
  301. if(count7==((MIN_XI>>1)-1'b1))begin count7<=0;clk_h6=~clk_h6;end
  302. else count7 <=count7+1;
  303. end
  304. end
  305. always@(posedge clk_5m_o or negedge rst)
  306. begin
  307. if(!rst)
  308. begin
  309. count11<=0;
  310. clk_m0<=0;
  311. end
  312. else begin
  313. if(count11==((MID_DO>>1)-1'b1))begin count11<=0;clk_m0=~clk_m0;end
  314. else count11 <=count11+1;
  315. end
  316. end
  317. always@(posedge clk_5m_o or negedge rst)
  318. begin
  319. if(!rst)
  320. begin
  321. count12<=0;
  322. clk_m1<=0;
  323. end
  324. else begin
  325. if(count12==((MID_RE>>1)-1'b1))begin count12<=0;clk_m1=~clk_m1;end
  326. else count12 <=count12+1;
  327. end
  328. end
  329. always@(posedge clk_5m_o or negedge rst)
  330. begin
  331. if(!rst)
  332. begin
  333. count13<=0;
  334. clk_m2<=0;
  335. end
  336. else begin
  337. if(count13==((MID_MI>>1)-1'b1))begin count13<=0;clk_m2=~clk_m2;end
  338. else count13 <=count13+1;
  339. end
  340. end
  341. always@(posedge clk_5m_o or negedge rst)
  342. begin
  343. if(!rst)
  344. begin
  345. count14<=0;
  346. clk_m3<=0;
  347. end
  348. else begin
  349. if(count14==((MID_FA>>1)-1'b1))begin count14<=0;clk_m3=~clk_m3;end
  350. else count14 <=count14+1;
  351. end
  352. end
  353. always@(posedge clk_5m_o or negedge rst)
  354. begin
  355. if(!rst)
  356. begin
  357. count15<=0;
  358. clk_m4<=0;
  359. end
  360. else begin
  361. if(count15==((MID_SO>>1)-1'b1))begin count15<=0;clk_m4=~clk_m4;end
  362. else count15 <=count15+1;
  363. end
  364. end
  365. always@(posedge clk_5m_o or negedge rst)
  366. begin
  367. if(!rst)
  368. begin
  369. count16<=0;
  370. clk_m5<=0;
  371. end
  372. else begin
  373. if(count16==((MID_LA>>1)-1'b1))begin count16<=0;clk_m5=~clk_m5;end
  374. else count16 <=count16+1;
  375. end
  376. end
  377. always@(posedge clk_5m_o or negedge rst)
  378. begin
  379. if(!rst)
  380. begin
  381. count17<=0;
  382. clk_m6<=0;
  383. end
  384. else begin
  385. if(count17==((MID_XI>>1)-1'b1))begin count17<=0;clk_m6=~clk_m6;end
  386. else count17 <=count17+1;
  387. end
  388. end
  389. always@(posedge clk_5m_o or negedge rst)
  390. begin
  391. if(!rst)
  392. begin
  393. count21<=0;
  394. clk_l0<=0;
  395. end
  396. else begin
  397. if(count21==((MAX_DO>>1)-1'b1))begin count21<=0;clk_l0=~clk_l0;end
  398. else count21 <=count21+1;
  399. end
  400. end
  401. always@(posedge clk_5m_o or negedge rst)
  402. begin
  403. if(!rst)
  404. begin
  405. count22<=0;
  406. clk_l1<=0;
  407. end
  408. else begin
  409. if(count22==((MAX_RE>>1)-1'b1))begin count22<=0;clk_l1=~clk_l1;end
  410. else count22 <=count22+1;
  411. end
  412. end
  413. always@(posedge clk_5m_o or negedge rst)
  414. begin
  415. if(!rst)
  416. begin
  417. count23<=0;
  418. clk_l2<=0;
  419. end
  420. else begin
  421. if(count23==((MAX_MI>>1)-1'b1))begin count23<=0;clk_l2=~clk_l2;end
  422. else count23 <=count23+1;
  423. end
  424. end
  425. always@(posedge clk_5m_o or negedge rst)
  426. begin
  427. if(!rst)
  428. begin
  429. count24<=0;
  430. clk_l3<=0;
  431. end
  432. else begin
  433. if(count24==((MAX_FA>>1)-1'b1))begin count24<=0;clk_l3=~clk_l3;end
  434. else count24 <=count24+1;
  435. end
  436. end
  437. always@(posedge clk_5m_o or negedge rst)
  438. begin
  439. if(!rst)
  440. begin
  441. count25<=0;
  442. clk_l4<=0;
  443. end
  444. else begin
  445. if(count25==((MAX_SO>>1)-1'b1))begin count25<=0;clk_l4=~clk_l4;end
  446. else count25 <=count25+1;
  447. end
  448. end
  449. always@(posedge clk_5m_o or negedge rst)
  450. begin
  451. if(!rst)
  452. begin
  453. count26<=0;
  454. clk_l5<=0;
  455. end
  456. else begin
  457. if(count26==((MAX_LA>>1)-1'b1))begin count26<=0;clk_l5=~clk_l5;end
  458. else count26 <=count26+1;
  459. end
  460. end
  461. always@(posedge clk_5m_o or negedge rst)
  462. begin
  463. if(!rst)
  464. begin
  465. count27<=0;
  466. clk_l6<=0;
  467. end
  468. else begin
  469. if(count27==((MAX_XI>>1)-1'b1))begin count27<=0;clk_l6=~clk_l6;end
  470. else count27 <=count27+1;
  471. end
  472. end
  473. endmodule
  474. module board_input(
  475. rst,//复位
  476. p8_i,//第八个按键,用来制作选择高中低
  477. to_o,//输出第八位的数据
  478. );
  479. //
  480. parameter s1=2'b01,//1
  481. s2=2'b10,//2
  482. s3=2'b11;//3
  483. //input rst;
  484. input rst;
  485. input p8_i;
  486. output reg [1:0] to_o;
  487. always@(posedge p8_i or negedge rst)
  488. begin
  489. if(!rst)begin
  490. to_o<=s1;
  491. end
  492. else
  493. begin
  494. if(to_o==s1)to_o<=s2;
  495. else if(to_o==s2)to_o<=s3;
  496. else to_o=s1;
  497. end
  498. end
  499. endmodule
  500. module seg_display(
  501. rst,//复位
  502. to_o,//第八个数码管显示内容
  503. ps_i,//七个按键输入
  504. led8,//单独输出第八个数码管内容
  505. bt1,
  506. bt2,//wei xuan
  507. seg//同步输出七个数码管内容,同一时间只能按一个
  508. );
  509. //parameter定义s1-s3三个状态,转换成十进制是1 2 3,
  510. parameter s0=2'b00,//0
  511. s1=2'b01,//1
  512. s2=2'b10,//2
  513. s3=2'b11;
  514. input rst;
  515. input[1:0] to_o;
  516. input[6:0] ps_i;
  517. output reg [6:0] bt2;
  518. output reg bt1;
  519. output reg [3:0]led8;//duanxuan
  520. output reg [27:0]seg;//duanxuan
  521. //对七个数码管通过七个按键输入控制需要显示的数码管
  522. always@(posedge ps_i or posedge rst )//always模块,同步复位
  523. begin
  524. if(rst)
  525. begin
  526. bt2<=7'b0000000;
  527. bt1<=0;
  528. end
  529. else
  530. begin
  531. bt1<=1;
  532. case(ps_i)
  533. 7'b0000001:begin bt2<=7'b0000001;end
  534. 7'b0000010:begin bt2<=7'b0000010;end
  535. 7'b0000100:begin bt2<=7'b0000100;end
  536. 7'b0001000:begin bt2<=7'b0001000;end
  537. 7'b0010000:begin bt2<=7'b0010000;end
  538. 7'b0100000:begin bt2<=7'b0100000;end
  539. 7'b1000000:begin bt2<=7'b1000000;end
  540. default:begin bt2<=bt2;end
  541. endcase
  542. end
  543. end
  544. //对七个数码管通过七个按键输入控制需要显示的数码管的对应内容
  545. always@(posedge ps_i or negedge rst )
  546. begin
  547. case(ps_i)
  548. 7'b0000001:begin seg[3:0]<=4'b0001;end
  549. 7'b0000010:begin seg[7:4]<=4'b0010;end
  550. 7'b0000100:begin seg[11:8]<=4'b0011;end
  551. 7'b0001000:begin seg[15:12]<=4'b0100;end
  552. 7'b0010000:begin seg[19:16]<=4'b0101;end
  553. 7'b0100000:begin seg[23:20]<=4'b0110;end
  554. 7'b1000000:begin seg[27:24]<=4'b0111;end
  555. default:begin seg[27:0]<=0;end
  556. endcase
  557. end
  558. //需要额外申明的是,数码管已经有了译码器,只需要输入4位二进制就能显示0-f的全部数字
  559. //通过对to_o的判断,判断第八个数码管要输出什么内容
  560. always@(posedge to_o or negedge rst)
  561. begin
  562. case(to_o)
  563. s1:led8=4'b0001;
  564. s2:led8=4'b0010;
  565. s3:led8=4'b0011;
  566. default :led8=4'b0001;
  567. endcase
  568. end
  569. endmodule
  570. module selct_speaker
  571. (
  572. clk_5m_o,
  573. rst,
  574. to_o,
  575. ps_i,
  576. clk_h0,//h代表高音,m代表中音,l代表低音,0-7代表音阶
  577. clk_h1,//要注意的是,我一开始编程的时候搞反了,所以代码实际实现的时候h代表低音,l代表高音
  578. clk_h2,
  579. clk_h3,
  580. clk_h4,
  581. clk_h5,
  582. clk_h6,
  583. clk_m0,
  584. clk_m1,
  585. clk_m2,
  586. clk_m3,
  587. clk_m4,
  588. clk_m5,
  589. clk_m6,
  590. clk_l0,
  591. clk_l1,
  592. clk_l2,
  593. clk_l3,
  594. clk_l4,
  595. clk_l5,
  596. clk_l6,
  597. speaker_o//蜂鸣器输出
  598. );
  599. input clk_5m_o,rst;
  600. input[1:0] to_o;
  601. input[6:0] ps_i;
  602. reg [6:0]be_o;
  603. input clk_h0,//h代表高音,m代表中音,l代表低音,0-7代表音阶
  604. clk_h1,//要注意的是,我一开始编程的时候搞反了,所以代码实际实现的时候h代表低音,l代表高音
  605. clk_h2,
  606. clk_h3,
  607. clk_h4,
  608. clk_h5,
  609. clk_h6,
  610. clk_m0,
  611. clk_m1,
  612. clk_m2,
  613. clk_m3,
  614. clk_m4,
  615. clk_m5,
  616. clk_m6,
  617. clk_l0,
  618. clk_l1,
  619. clk_l2,
  620. clk_l3,
  621. clk_l4,
  622. clk_l5,
  623. clk_l6;
  624. output reg speaker_o;
  625. parameter s0=2'b00,//0
  626. s1=2'b01,//1
  627. s2=2'b10,//2
  628. s3=2'b11;
  629. //always模块通过判断to_o判断高中低音,再通过每个case判断选择输出什么频率
  630. always@(posedge ps_i or posedge rst)
  631. begin
  632. if(rst)speaker_o<=0;
  633. else begin
  634. if(to_o==s1)begin
  635. case(ps_i)
  636. 7'b0000001:speaker_o<=clk_h0;
  637. 7'b0000010:speaker_o<=clk_h1;
  638. 7'b0000100:speaker_o<=clk_h2;
  639. 7'b0001000:speaker_o<=clk_h3;
  640. 7'b0010000:speaker_o<=clk_h4;
  641. 7'b0100000:speaker_o<=clk_h5;
  642. 7'b1000000:speaker_o<=clk_h6;
  643. default:speaker_o<=speaker_o;
  644. endcase
  645. end
  646. else if(to_o==s2)begin
  647. case(ps_i)
  648. 7'b0000001:speaker_o<=clk_m0;
  649. 7'b0000010:speaker_o<=clk_m1;
  650. 7'b0000100:speaker_o<=clk_m2;
  651. 7'b0001000:speaker_o<=clk_m3;
  652. 7'b0010000:speaker_o<=clk_m4;
  653. 7'b0100000:speaker_o<=clk_m5;
  654. 7'b1000000:speaker_o<=clk_m6;
  655. default:speaker_o<=speaker_o;
  656. endcase
  657. end
  658. else if(to_o==s3)begin
  659. case(ps_i)
  660. 7'b0000001:speaker_o<=clk_l0;
  661. 7'b0000010:speaker_o<=clk_l1;
  662. 7'b0000100:speaker_o<=clk_l2;
  663. 7'b0001000:speaker_o<=clk_l3;
  664. 7'b0010000:speaker_o<=clk_l4;
  665. 7'b0100000:speaker_o<=clk_l5;
  666. 7'b1000000:speaker_o<=clk_l6;
  667. default:speaker_o<=speaker_o;
  668. endcase
  669. end
  670. end
  671. end
  672. endmodule

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/不正经/article/detail/710766
推荐阅读
相关标签
  

闽ICP备14008679号