|
初学FPGA,跟随特权的视频,这几天正好开始弄特权的那个按键消抖的程序,因为用的不是特权的板子,自己的板子上只有两个按键和两个led显示灯,所以将特权的代码改了下。将代码修改之后烧入芯片中,功能可以实现消抖,因为学习写写testbench,就拿按键消抖的代码在modelsim下进行仿真,发现仿真过不了,以为是自己程序改错了。于是将特权的程序进行modelsim仿真,发现他的程序在modelsim下仿真结果和我的一样。实在不知道什么原因。现贴上特权的verilog程序和我自己写的testbech代码,以及modelsim仿真波形,麻烦帮看看问题出在哪里。在此谢过。
特权的按键检测程序:
01.//说明:当三个独立按键的某一个被按下后,相应的LED被点亮;
02.// 再次按下后,LED熄灭,按键控制LED亮灭
03.
04.module sw_debounce(
05. clk,rst_n,
06. sw1_n,sw2_n,sw3_n,
07. led_d1,led_d2,led_d3
08. );
09.
10.input clk; //主时钟信号,50MHz
11.input rst_n; //复位信号,低有效
12.input sw1_n,sw2_n,sw3_n; //三个独立按键,低表示按下
13.output led_d1,led_d2,led_d3; //发光二极管,分别由按键控制
14.
15.//---------------------------------------------------------------------------
16.reg[2:0] key_rst;
17.
18.always @(posedge clk or negedge rst_n)
19. if (!rst_n) key_rst <= 3'b111;
20. else key_rst <= {sw3_n,sw2_n,sw1_n};
21.
22.reg[2:0] key_rst_r; //每个时钟周期的上升沿将low_sw信号锁存到low_sw_r中
23.
24.always @ ( posedge clk or negedge rst_n )
25. if (!rst_n) key_rst_r <= 3'b111;
26. else key_rst_r <= key_rst;
27.
28.//当寄存器key_rst由1变为0时,led_an的值变为高,维持一个时钟周期
29.wire[2:0] key_an = key_rst_r & ( ~key_rst);
30.
31.//---------------------------------------------------------------------------
32.reg[19:0] cnt; //计数寄存器
33.
34.always @ (posedge clk or negedge rst_n)
35. if (!rst_n) cnt <= 20'd0; //异步复位
36. else if(key_an) cnt <=20'd0;
37. else cnt <= cnt + 1'b1;
38.
39.reg[2:0] low_sw;
40.
41.always @(posedge clk or negedge rst_n)
42. if (!rst_n) low_sw <= 3'b111;
43. else if (cnt == 20'hfffff) //满20ms,将按键值锁存到寄存器low_sw中 cnt == 20'hfffff
44. low_sw <= {sw3_n,sw2_n,sw1_n};
45.
46.//---------------------------------------------------------------------------
47.reg [2:0] low_sw_r; //每个时钟周期的上升沿将low_sw信号锁存到low_sw_r中
48.
49.always @ ( posedge clk or negedge rst_n )
50. if (!rst_n) low_sw_r <= 3'b111;
51. else low_sw_r <= low_sw;
52.
53.//当寄存器low_sw由1变为0时,led_ctrl的值变为高,维持一个时钟周期
54.wire[2:0] led_ctrl = low_sw_r[2:0] & ( ~low_sw[2:0]);
55.
56.reg d1;
57.reg d2;
58.reg d3;
59.
60.always @ (posedge clk or negedge rst_n)
61. if (!rst_n) begin
62. d1 <= 1'b0;
63. d2 <= 1'b0;
64. d3 <= 1'b0;
65. end
66. else begin //某个按键值变化时,LED将做亮灭翻转
67. if ( led_ctrl[0] ) d1 <= ~d1;
68. if ( led_ctrl[1] ) d2 <= ~d2;
69. if ( led_ctrl[2] ) d3 <= ~d3;
70. end
71.
72.assign led_d3 = d1 ? 1'b1 : 1'b0; //LED翻转输出
73.assign led_d2 = d2 ? 1'b1 : 1'b0;
74.assign led_d1 = d3 ? 1'b1 : 1'b0;
75.
76.endmodule
复制代码
自己写的testbench代码
01.`timescale 10 ns/ 1 ps
02.module sw_debounce_vlg_tst();
03.// constants
04.// general purpose registers
05.reg eachvec;
06.// test vector input registers
07.reg clk;
08.reg rst_n;
09.reg sw1_n;
10.reg sw2_n;
11.reg sw3_n;
12.// wires
13.wire led_d1;
14.wire led_d2;
15.wire led_d3;
16.
17.// assign statements (if any)
18.sw_debounce i1 (
19.// port map - connection between master ports and signals/registers
20. .clk(clk),
21. .led_d1(led_d1),
22. .led_d2(led_d2),
23. .led_d3(led_d3),
24. .rst_n(rst_n),
25. .sw1_n(sw1_n),
26. .sw2_n(sw2_n),
27. .sw3_n(sw3_n)
28.);
29.initial
30.begin
31. clk = 1'b0;
32. forever
33. begin
34. #10 clk = ~clk;
35. end
36.end
37.
38. initial
39. begin
40. rst_n = 1'b0;
41. #100;
42. rst_n = 1'b1;
43. end
44.
45. initial
46. begin
47. sw1_n = 1'b1;
48. sw2_n = 1'b1;
49. sw3_n = 1'b1;
50. #1000000
51. sw1_n = 1'b0;
52. sw2_n = 1'b0;
53. sw3_n = 1'b0;
54. #7000000
55. sw1_n = 1'b1;
56. sw2_n = 1'b1;
57. sw3_n = 1'b1;
58. #3000000
59. $stop;
60. end
61.endmodule
复制代码 |
|