| 
 | 
 
初学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 
复制代码 |   
 
 
 
 |