|
初学FPGA,跟随特权的视频,这几天正好开始弄特权的那个按键消抖的程序,因为用的不是特权的板子,自己的板子上只有两个按键和两个led显示灯,所以将特权的代码改了下。将代码修改之后烧入芯片中,功能可以实现消抖,因为学习写写testbench,就拿按键消抖的代码在modelsim下进行仿真,发现仿真过不了,以为是自己程序改错了。于是将特权的程序进行modelsim仿真,发现他的程序在modelsim下仿真结果和我的一样。实在不知道什么原因。现贴上特权的verilog程序和我自己写的testbech代码,以及modelsim仿真波形,麻烦帮看看问题出在哪里。在此谢过。
特权的按键检测程序:
- //说明:当三个独立按键的某一个被按下后,相应的LED被点亮;
- // 再次按下后,LED熄灭,按键控制LED亮灭
- module sw_debounce(
- clk,rst_n,
- sw1_n,sw2_n,sw3_n,
- led_d1,led_d2,led_d3
- );
- input clk; //主时钟信号,50MHz
- input rst_n; //复位信号,低有效
- input sw1_n,sw2_n,sw3_n; //三个独立按键,低表示按下
- output led_d1,led_d2,led_d3; //发光二极管,分别由按键控制
- //---------------------------------------------------------------------------
- reg[2:0] key_rst;
- always @(posedge clk or negedge rst_n)
- if (!rst_n) key_rst <= 3'b111;
- else key_rst <= {sw3_n,sw2_n,sw1_n};
- reg[2:0] key_rst_r; //每个时钟周期的上升沿将low_sw信号锁存到low_sw_r中
- always @ ( posedge clk or negedge rst_n )
- if (!rst_n) key_rst_r <= 3'b111;
- else key_rst_r <= key_rst;
-
- //当寄存器key_rst由1变为0时,led_an的值变为高,维持一个时钟周期
- wire[2:0] key_an = key_rst_r & ( ~key_rst);
- //---------------------------------------------------------------------------
- reg[19:0] cnt; //计数寄存器
- always @ (posedge clk or negedge rst_n)
- if (!rst_n) cnt <= 20'd0; //异步复位
- else if(key_an) cnt <=20'd0;
- else cnt <= cnt + 1'b1;
-
- reg[2:0] low_sw;
- always @(posedge clk or negedge rst_n)
- if (!rst_n) low_sw <= 3'b111;
- else if (cnt == 20'hfffff) //满20ms,将按键值锁存到寄存器low_sw中 cnt == 20'hfffff
- low_sw <= {sw3_n,sw2_n,sw1_n};
-
- //---------------------------------------------------------------------------
- reg [2:0] low_sw_r; //每个时钟周期的上升沿将low_sw信号锁存到low_sw_r中
- always @ ( posedge clk or negedge rst_n )
- if (!rst_n) low_sw_r <= 3'b111;
- else low_sw_r <= low_sw;
-
- //当寄存器low_sw由1变为0时,led_ctrl的值变为高,维持一个时钟周期
- wire[2:0] led_ctrl = low_sw_r[2:0] & ( ~low_sw[2:0]);
- reg d1;
- reg d2;
- reg d3;
-
- always @ (posedge clk or negedge rst_n)
- if (!rst_n) begin
- d1 <= 1'b0;
- d2 <= 1'b0;
- d3 <= 1'b0;
- end
- else begin //某个按键值变化时,LED将做亮灭翻转
- if ( led_ctrl[0] ) d1 <= ~d1;
- if ( led_ctrl[1] ) d2 <= ~d2;
- if ( led_ctrl[2] ) d3 <= ~d3;
- end
- assign led_d3 = d1 ? 1'b1 : 1'b0; //LED翻转输出
- assign led_d2 = d2 ? 1'b1 : 1'b0;
- assign led_d1 = d3 ? 1'b1 : 1'b0;
-
- endmodule
复制代码
自己写的testbench代码
- `timescale 10 ns/ 1 ps
- module sw_debounce_vlg_tst();
- // constants
- // general purpose registers
- reg eachvec;
- // test vector input registers
- reg clk;
- reg rst_n;
- reg sw1_n;
- reg sw2_n;
- reg sw3_n;
- // wires
- wire led_d1;
- wire led_d2;
- wire led_d3;
- // assign statements (if any)
- sw_debounce i1 (
- // port map - connection between master ports and signals/registers
- .clk(clk),
- .led_d1(led_d1),
- .led_d2(led_d2),
- .led_d3(led_d3),
- .rst_n(rst_n),
- .sw1_n(sw1_n),
- .sw2_n(sw2_n),
- .sw3_n(sw3_n)
- );
- initial
- begin
- clk = 1'b0;
- forever
- begin
- #10 clk = ~clk;
- end
- end
- initial
- begin
- rst_n = 1'b0;
- #100;
- rst_n = 1'b1;
- end
-
- initial
- begin
- sw1_n = 1'b1;
- sw2_n = 1'b1;
- sw3_n = 1'b1;
- #1000000
- sw1_n = 1'b0;
- sw2_n = 1'b0;
- sw3_n = 1'b0;
- #7000000
- sw1_n = 1'b1;
- sw2_n = 1'b1;
- sw3_n = 1'b1;
- #3000000
- $stop;
- end
- endmodule
复制代码
下面是特权的代码的仿真波形,模拟一下按键的按下,有30mS的按下延时
|
本帖子中包含更多资源
您需要 登录 才可以下载或查看,没有帐号?注册
x
阿莫论坛20周年了!感谢大家的支持与爱护!!
知道什么是神吗?其实神本来也是人,只不过神做了人做不到的事情 所以才成了神。 (头文字D, 杜汶泽)
|