诗人的眼YI

2、FPGA学习之模式LED

0
阅读(2106)

模式LED灯,设置了三个按键,每次按下一个按键后,LED灯呈现对应的状态。一个左移,一个右移,一个当前状态翻转。

module key_led
(
	clk,
	rst_n,
	key,
	
	led
);
	
	input clk;             //时钟,50MHz
	input rst_n;           //复位,低电平有效
	input [3:1]key;        //定义三个按键
	
	output reg[7:0]led;    //后面可以看到,led在赋值的左边,需要定义为reg型
	
	reg [19:0]cnt;         //定义一个20位计数器,来得到计数1_000_000次,即20ms(20ns*1_000_000)
	
	//
	always@(posedge clk or negedge rst_n)
		if(!rst_n)
			cnt <= 20'd0;
		else if(cnt < 20'd999_999)
			cnt <= cnt + 1'b1;
		else	
			cnt <= 1'b0;
			
	//key[1]按下(为低电平时),灯左移;key[2]按下(为低电平时),灯右移;key[3]按下(为低电平时),当前灯状态翻转
	always@(posedge clk or negedge rst_n)
		if(!rst_n)
		led <= 8'b11111110;        //初始8个灯的状态和每次按下复位键的状态
		else if(cnt == 20'd999_999)//当你按住按键的时候,每计数20ms,这里为了在仿真中运行时间短点,计数较小,实际中想要观察明显点,可以把计数次数修改大点
			if(!key[1])
				led <= {led[6:0],led[7]}; //左移
			else if(!key[2])
				led <= {led[0],led[7:1]}; //右移
			else if(!key[3])
				led <= ~led;              //状态翻转


endmodule


下面为测试文件

`timescale 1ns/1ns
`define clk_period 20

module key_led_tb;
	
	reg clk;                    //将.v文件中的端口复制过来,input修改为reg,output修改为wire
	reg rst_n;
	reg [3:1]key;
	
	wire [7:0]led;
	
	
	key_led key_led             //将.v文件中的端口复制过来,加个例化名字,加个.,加个例化的端口
	(
		.clk(clk),
		.rst_n(rst_n),
		.key(key),
		
		.led(led)
	);
	 
	initial clk =1; 
	always #(`clk_period/2) clk = ~clk; //初始化时钟,开始为高电平,每隔10ns翻转一次,一个周期20ns
	
	initial begin
		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

QQ截图20160427211229.jpg

话说图怎么插啊,看不清啊!有知道的大大麻烦告知一下!感激不尽!