LED灯多种方式闪烁的FPGA实现

10 篇文章 7 订阅
3 篇文章 1 订阅

一、Quartus开发工具简介

Quartus Prime是inter FPGA(Altera FPGA在2015年被inter收购)的开发套件,到inter FPGA的官网可下载软件的安装包。在下载时,除了要下载基本的软件安装包以外,还要根据自己的需求下载相应的器件支持包。安装完毕后可将支持包导入到软件中,而后便可进行开发。

官方软件下载地址:https://www.intel.cn/content/www/cn/zh/programmable/downloads/download-center.html#

二、FPGA开发流程简介

FPGA 的设计流程就是利用 EDA 开发软件和编程工具对 FPGA 芯片进行开发的过程。典型 FPGA 的开发流程一般如下图所示,包括功能定义/器件选型、设计输入、功能仿真、综合优化、综合后仿真、实现、布线后仿真、板级仿真以及芯片编程与调试等主要步骤。

上图描述的开发过程与ASIC 的开发过程极为相似,只是FPGA的开发很大程度上实现了自动化,布局布线基本上不需要人为干预。在实际的FPGA开发过程中,流程并没有那么复杂,上图描述的是一个完整的开发流程。如果开发的项目比较简单,只需要进行代码编写-功能仿真-综合-芯片编程这几个简单的流程。本文要介绍的LED灯的项目只进行了代码编写、综合、芯片编程这三个步骤,并不是一个完整的开发过程,旨在介绍Quartus Prime的开发基本操作。

三、项目介绍

功能描述:在三十个时间间隔中(每个时间间隔的长度可通过编程实现),前十个时间间隔,LED灯在亮、暗两种状态下进行切换,每个状态持续一个时间间隔;中间十个时间间隔中,实现LED流水灯功能;后十个时间间隔中,前五个时间间隔,LED由暗逐渐变亮,后五个时间间隔,LED由亮逐渐变暗。而后LED按这三十个时间间隔的变化规律一直运行下去。

开发环境:Quartus Prime17.1;Cyclone IV E EP4CE15F23C8芯片

四、开发过程

1.新建项目

可通过如下几种方式新建项目:

或者 :

或者  :

                                     

而后选择工程存放目录并设置工程名,注意设计顶层实体名要与代码中的保持一致,即要与代码中的module名一致(以Verilog为例):

选择建立空项目还是采用项目模板,这次笔者选择空项目:

选择是否添加已存在文件: 

选择目标器件: 

是否指定开发工具(可使用第三方的工具:如综合、仿真软件):

 完成工程建立:

 2.编写代码

建立新文件的方法有两种:

                                                     

或者:

                                                                  

编写好代码以后要确保将代码添加到工程中。 

3.编译

代码编写好以后就可进行编译工作了,编译的目的是检查代码语法错误、将代码翻译成标准符号表示的电路、而后再将电路映射为芯片内部具体电路的连接。

编译的方法:

或者:

若编译过程中报错,则需要根据错误信息修正代码。  

编译完成后可查看设计的RTL级电路图:

还可在主界面左侧查看编译报告,其中包括资源消耗情况:

4.指定引脚

编译完成后可根据需求约束起器件管脚,即指定设计中的输入输出在芯片上的具体位置:

或者:

而后根据实际需求指定:

  约束完之后直接关闭约束界面即可,软件自动保存结果。

5.再次编译

指定完管脚以后,需要再次进行编译。

6.器件编程

将芯片用USB-Blaster与电脑连接起来,打开编程工具:

或者

而后进行相关设置,最后点击Start进行编程:

五、代码解读

本设计代码采用《至简设计法》计数器架构法进行设计,感兴趣的读者可去查阅。

module test_led(
clk    ,
rst_n  ,
led
);

//参数定义
parameter      cnt_10ms_w =19;
parameter      cnt_1s_w =  7;
parameter      cnt_30c_w = 5;

//输入信号定义
input               clk    ;
input               rst_n  ;

//输出信号定义
output[7:0] led;

//输出信号reg定义
reg[7:0] led;

//中间信号定义
reg[cnt_10ms_w-1:0]               cnt_10ms;
reg[cnt_1s_w-1:0]                 cnt_1s;
reg[cnt_30c_w-1:0]                cnt_30c;
reg[cnt_10ms_w-1:0]               x;

//wire定义
wire add_cnt_10ms;
wire end_cnt_10ms;

wire add_cnt_1s;
wire end_cnt_1s;

wire add_cnt_30c;
wire end_cnt_30c;

//计数器cnt_10ms
always @(posedge clk or negedge rst_n)begin
    if(!rst_n)begin
        cnt_10ms <= 0;
    end
    else if(add_cnt_10ms)begin
        if(end_cnt_10ms)
            cnt_10ms <= 0;
        else
            cnt_10ms <= cnt_10ms + 1;
    end
end

assign add_cnt_10ms =1 ;       
assign end_cnt_10ms = add_cnt_10ms && cnt_10ms==500_000-1 ;   

//计数器cnt_1s
always @(posedge clk or negedge rst_n)begin
    if(!rst_n)begin
        cnt_1s <= 0;
    end
    else if(add_cnt_1s)begin
        if(end_cnt_1s)
            cnt_1s <= 0;
        else
            cnt_1s <= cnt_1s + 1;
    end
end

assign add_cnt_1s =end_cnt_10ms ;       
assign end_cnt_1s = add_cnt_1s && cnt_1s==10-1 ;   

//计数器cnt_30c
always @(posedge clk or negedge rst_n)begin
    if(!rst_n)begin
        cnt_30c <= 0;
    end
    else if(add_cnt_30c)begin
        if(end_cnt_30c)
            cnt_30c <= 0;
        else
            cnt_30c <= cnt_30c + 1;
    end
end

assign add_cnt_30c =end_cnt_1s ;       
assign end_cnt_30c = add_cnt_30c && cnt_30c==30-1 ;   

//LED功能设置
always@(posedge clk or negedge rst_n)begin
if(rst_n==1'b0)begin
    led<=8'b1111_1111;
end
else if(cnt_30c>=0&&cnt_30c<10)begin
	if(add_cnt_1s && cnt_1s==5-1 )begin
		led<=8'b0000_0000;
	end
	else if(end_cnt_1s)begin
		led<=8'b1111_1111;
	end
end
else if(cnt_30c>=10&&cnt_30c<20)begin
	case(cnt_30c)
	    5'd10:led=8'b1111_1110;
        5'd11:led=8'b1111_1101;
        5'd12:led=8'b1111_1011;
        5'd13:led=8'b1111_0111;
        5'd14:led=8'b1110_1111;
        5'd15:led=8'b1101_1111;
        5'd16:led=8'b1011_1111;
        5'd17:led=8'b0111_1111;
        5'd18:led=8'b0011_1100;
        5'd19:led=8'b0101_1010;
      default:led=8'b1111_1111;
	endcase
end
else if(cnt_30c>=20&&cnt_30c<30)begin
	if(add_cnt_10ms&&cnt_10ms==x-1)begin
		led=8'b0000_0000;
	end
	else if(end_cnt_10ms)begin
		led=8'b1111_1111;
	end	
end
end

//x的设定
always@(*)begin
    case(cnt_30c)
        5'd20:x=475_000;
        5'd21:x=425_000;
        5'd22:x=350_000;
        5'd23:x=250_000;
        5'd24:x=100_000;
        5'd25:x=100_000;
        5'd26:x=250_000;
        5'd27:x=350_000;
        4'd28:x=425_000;
        4'd29:x=475_000;
     default:x=500_000;
    endcase
end

endmodule

六、总结

本设计以“LED灯多种方式闪烁的FPGA实现”项目为例,介绍了Quartus Prime的简单开发流程。

七、参考文献

1.《至简设计法》潘文明 易文兵

2.明德扬 FPGA 至简设计与应用实验手册

八、相关下载

1.“LED灯多种方式闪烁的FPGA实现”工程文件:https://download.csdn.net/download/qq_26379299/11548857

2.英文版Quartus Prime开发简介:https://download.csdn.net/download/qq_26379299/11548859

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值