一 信号
框图:
其中 key_filter seg_595_dynamic均为已有模块,直接例化即可使用,rom_8*256模块,调用rom ip实现。Rom_ctrl模块需要重新编写。
波形图:
二 代码
module key_fliter
#(
parameter CNT_MAX =24'd9_999_999
(
input wire sys_clk,
input wire sys_rst_n,
input wire key1,
input wire key2,
output wire [7:0] addr
);
reg [2:0] cnt_200ms;//定义中间变量。
reg key1_en;
reg key2_en;
always@(posedge sys_clk or negedge sys_rst_n)
if(sys_rst_n==1'b0)//异步复位。
cnt_200ms<=24'd0;//赋初值。
else if(cnt_200ms ==CNT_MAX || key1_en ==1'b1 || key2_en == 1'b1)
cnt_200ms<= 24'd0;//清零。
else
cnt_200ms <= cnt_200ms + 1'b1;//计数。
always@(posedge sys_clk or negedge sys_rst_n)
if(sys_rst_n==1'b0)//异步复位。
key1_en_<=1'b0;//赋初值。
else if(key2 == 1'b1)
key1_en<=1'b0;//取低电平。
else if(key1 ==1'b1)
key1_en<=~key1_en;//取反。
else
key1_en<=~key1_en;//保持。
always@(posedge sys_clk or negedge sys_rst_n)
if(sys_rst_n==1'b0)//异步复位。
key2_en_<=1'b0;//赋初值。
else if(key1 == 1'b1)
key2_en<=1'b0;//取低电平。
else if(key2 ==1'b1)
key2_en<=~key2_en;//取反。
else
key2_en<=~key2_en;//保持。
always@(posedge sys_clk or negedge sys_rst_n)
if(sys_rst_n==1'b0)//异步复位。
addr <= 8'd0;//赋初值。
else if(addr == 8'd255 && cnt_200ms ==CNT_MAX)
addr <= 8'd0;
else if(key1 == 1'b1)
addr <= 8'd99;
else if(key2 == 1'b1)
addr <= 8'd199;
else if(cnt_200ms ==CNT_MAX)
addr <= addr + 1'b1;
endmodule
module rom//工程顶层文件。
(
input wire sys_clk,
input wire key1,
input wire sys_rst_n,
input wire key2,
output wire ds,
output wire oe,
output wire shcp,
output wire stcp
);
wire key2_flag ;
wire key1_flag ;
wire [7:0] addr ;
wire [7:0] data ;
key_filter
#(
.CNT_MAX (20'd9)
)
key_filter_inst1
(
.sys_clk (sys_clk),
.sys_rst_n (sys_rst_n),
.key_in (key1),
.key_flag (key1_flag)
);//按键消抖模块实例化。
key_filter
#(
.CNT_MAX (20'd9)
)
key_filter_inst1
(
.sys_clk (sys_clk),
.sys_rst_n (sys_rst_n),
.key_in (key2),
.key_flag (key2_flag)
);//按键消抖模块实例化。
rom_ctrl_inst
(
.sys_clk (sys_clk),
.sys_rst_n (sys_rst_n),
.key1 (key1_flag),
.key2 (key2_flag),
.addr (addr)
);//rom_ctrl模块实例化。
rom_8x236 rom_8x236_inst
(
.address (addr),
.clock (sys_clk),
.q (data)
);//rom ip核实例化。
seg_595_dynamic seg_595_dynamic
(
.sys_clk (sys_clk),
.sys_rst_n (sys_rst_n),
.data ({12'b0,data}),
.point (6'b000_000),
.sign (1'b0),
.seg_en (1'b1),
.ds (ds ),
.oe (oe ),
.shcp (shcp),
);//数码管显示模块,实例化。
代码编译通过,对顶层文件进行仿真验证。
'timescale 1ns/1ns
module tb_rom()
reg sys_clk;
reg sys_rst_n;
reg key1;
reg key2;
wire ds;
wire oe;
wire shcp;
wire stcp;
initial
begin
sys_clk =1'b1;
sys_rst_n <= 1'b0;
key1 <= 1'b1;
key2 <= 1'b1;
#20
sys_rst_n <= 1'b1;
#700000
//key1
key1 <= 1'b0;
#20
key1 <= 1'b1;
#20
key1 <= 1'b0;
#20
key1 <= 1'b1;
#20
key1 <= 1'b0;
#20
key1 <= 1'b1;
#20
key1 <= 1'b0;
#20
key1 <= 1'b1;
#20
key1 <= 1'b0;
#20
key1 <= 1'b0;
//key2
#20000
key2 <= 1'b0;
#20
key2 <= 1'b1;
#20
key2 <= 1'b0;
#20
key2 <= 1'b1;
#20
key2 <= 1'b0;
#200
key2 <= 1'b1;
#20
key2 <= 1'b0;
#20
key2 <= 1'b1;
#20
key2 <= 1'b0;
#20
key2 <= 1'b0;
end
always #10 sys_clk = ~sys_clk;
rom rom_inst
(
.sys_clk (sys_clk),
.sys_rst_n (sys_rst_n),
.key1 (key1),
.key2 (key2),
.ds (ds),
.oe (oe),
.shcp (shcp),
.stcp (stcp)
);