模式LED灯,设置了三个按键,每次按下一个按键后,LED灯呈现对应的状态。一个左移,一个右移,一个当前状态翻转。
modulekey_led
(
clk,
rst_n,
key,
led
);
inputclk;//时钟,50MHz
inputrst_n;//复位,低电平有效
input[3:1]key;//定义三个按键
outputreg[7:0]led;//后面可以看到,led在赋值的左边,需要定义为reg型
reg[19:0]cnt;//定义一个20位计数器,来得到计数1_000_000次,即20ms(20ns*1_000_000)
//
always@(posedgeclkornegedgerst_n)
if(!rst_n)
cnt<=20'd0;
elseif(cnt<20'd999_999)
cnt<=cnt+1'b1;
else
cnt<=1'b0;
//key[1]按下(为低电平时),灯左移;key[2]按下(为低电平时),灯右移;key[3]按下(为低电平时),当前灯状态翻转
always@(posedgeclkornegedgerst_n)
if(!rst_n)
led<=8'b11111110;//初始8个灯的状态和每次按下复位键的状态
elseif(cnt==20'd999_999)//当你按住按键的时候,每计数20ms,这里为了在仿真中运行时间短点,计数较小,实际中想要观察明显点,可以把计数次数修改大点
if(!key[1])
led<={led[6:0],led[7]};//左移
elseif(!key[2])
led<={led[0],led[7:1]};//右移
elseif(!key[3])
led<=~led;//状态翻转
endmodule
下面为测试文件
`timescale1ns/1ns
`defineclk_period20
modulekey_led_tb;
regclk;//将.v文件中的端口复制过来,input修改为reg,output修改为wire
regrst_n;
reg[3:1]key;
wire[7:0]led;
key_ledkey_led//将.v文件中的端口复制过来,加个例化名字,加个.,加个例化的端口
(
.clk(clk),
.rst_n(rst_n),
.key(key),
.led(led)
);
initialclk=1;
always#(`clk_period/2)clk=~clk;//初始化时钟,开始为高电平,每隔10ns翻转一次,一个周期20ns
initialbegin
rst_n=1'b0;
key[1]=1;
key[2]=1;
key[3]=1;
#(`clk_period*200)//这里加2使下面的rst_n复位与时钟的上升沿不同步了,间隔了50个时钟周期后key三个数每隔50个时钟周期变化一次,自然也就不和上升沿同步了,但是led的值是随着时钟上升沿变化的,自然跟上升沿同步
rst_n=1'b1;
#(`clk_period*50)
key[1]=0;
key[2]=1;
key[3]=1;
#(`clk_period*2000000)//此段的时间至少要有顶层文件中技术周期的两倍,否则不容易看出led的变化
key[1]=1;
key[2]=1;
key[3]=1;
#(`clk_period*50)
key[1]=1;
key[2]=0;
key[3]=1;
#(`clk_period*2000000)//此段的时间至少要有顶层文件中技术周期的两倍,否则不容易看出led的变化
key[1]=1;
key[2]=1;
key[3]=1;
#(`clk_period*50)
key[1]=1;
key[2]=1;
key[3]=0;
#(`clk_period*2000000)//此段的时间至少要有顶层文件中技术周期的两倍,否则不容易看出led的变化
key[1]=1;
key[2]=1;
key[3]=1;
#(`clk_period*50)
$stop;
end
endmodule
话说图怎么插啊,看不清啊!有知道的大大麻烦告知一下!感激不尽!