FPGA:流水灯设计

本次基于FPGA实现流水灯,即让LED[0:7]从左到右依次电量,每个LED灯频闪周期为1s钟,在这里,给出下面三种实现思路:

1、实验思路

1、使用位运算符
在复位时令LED灯为LED=8’b0000_0001,然后每过一秒钟,左移一位,如果LED灯状态为LED=8’b1000_0000,下一次再让LED=8’b0000_0001即可实现流水灯。
2、使用循环位移
使用循环位移和位拼接符,复位时如果我们令led=1000_0000,然后开始计时,我们让led[6:0]和led[7]进行拼接,得到0000_0001,再过一秒,同样进行拼接,得到0000_0010,使用这个方法无需考虑上面的末尾情况。
3、使用3-8译码器
再加入一个计数器,作为状态输入端,我们有8个输出,所以需要三个输入端口,复位令计数器为0,每过一秒状态计数器的值加1,最后状态计数器的值作为3-8译码器的输入端口即可。

2、代码编写

下面给出上面三种思路对应设计文件的verilog代码:
1、使用位运算符

module led_run1(
	clk,Reset_n,led
);
input clk;
input Reset_n;
output reg[7:0] led; 
reg [24:0] counter;
always@(posedge clk or negedge Reset_n)
if (!Reset_n)
	counter<=0;
else if(counter == 24999999)
//else if(counter == 24999)   //节约仿真时间
	counter <=0;
else 
	counter <= counter+1;
always@(posedge clk or negedge Reset_n)
if (!Reset_n)
	led <= 8'b0000_0001;
else if(counter == 24999999)
//else if(counter == 24999)  //节约仿真时间
	begin
	if(led == 8'b1000_0000)   //如果是最后一个灯亮,则再回去
		led <= 8'b0000_0001;
	else
		led <= (led<<1); //如果是其他情况,则左移一位即可
	end

endmodule

2、使用循环位移

module led_run2(
	clk,Reset_n,led
);
input clk;
input Reset_n;
output reg[7:0] led;
reg [24:0] counter;
always@(posedge clk or negedge Reset_n)
if (!Reset_n)
	counter<=0;
else if(counter ==24999999)
//else if(counter == 24999)   //节约仿真时间
    counter<=0;
else 
	counter <= counter+1;
always@(posedge clk or negedge Reset_n)
if (!Reset_n)
	led<=8'b0000_0001;
else if(counter==24999999)
//else if(counter == 24999)   //节约仿真时间
	led <= {led[6:0],led[7]};  //使用拼接符,循环左移
endmodule

3、外接3-8译码器

module led_run3(
	clk,Reset_n,led
);
input clk;
input Reset_n;
output [7:0] led;  //此处led是由底层三八译码器驱动,不需要reg类型,已经在decoder中定义out为reg了 
reg [25:0] counter;   //为了和前面区分,这里设为1秒的速率
always@(posedge clk or negedge Reset_n)
if (!Reset_n)
	counter<=0;
else if(counter == 49999999)
//else if(counter == 24999)   //节约仿真时间
	counter <=0;
else 
	counter <= counter+1;
//使用三八译码器,八个输出刚好对应八个LED灯,三个输入利用重新产生一个变量即可
reg [2:0] counter2;  //产生三位输出作为三八译码器输出
always@(posedge clk or negedge Reset_n)
if (!Reset_n)
	counter2 <= 3'b000;
//else if(counter == 24999) 
else if(counter == 49999999)
	counter2 <= counter2+1'b1;
//例化3-8译码器模块
decoder_3_8 decoder_3_8(
	.a(counter2[2]),
	.b(counter2[1]),
	.c(counter2[0]),
	.out(led)
);
endmodule

编写测试文件,不同的设计文件更改对应的模块名即可

`timescale 1ns/1ps
module led_run_tb();
reg clk;
reg Reset_n;
wire [7:0] led;
led_run3 led_run(    //例化led_run1修改对应的前面的标签即可
	.clk(clk),
	.Reset_n(Reset_n),
	.led(led)
);
initial clk=1; //时钟初始值设为1
always #10 clk=!clk;   //每延时10ns,时钟翻转一次,这样一个周期就是20ns
initial begin
Reset_n = 0;  //复位
#201  
Reset_n = 1;  // 复位接高电平
#40000000;
$stop;
end
endmodule

3、仿真测试

在这里插入图片描述

4、板级验证

生成比特流,烧到开发板即可。

  • 12
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值