目录
- [一、 内容概要](#一、 内容概要)
- [二、 实现](#二、 实现)
-
- [2.1 基于Nios II软核的流水灯](#2.1 基于Nios II软核的流水灯)
-
- [2.1.1 准备工作](#2.1.1 准备工作)
- [2.1.2 工程搭建](#2.1.2 工程搭建)
- [2.1.3 硬件代码设计](#2.1.3 硬件代码设计)
-
- [Ⅰ 连接IP核](#Ⅰ 连接IP核)
- [Ⅱ 编写代码](#Ⅱ 编写代码)
- [Ⅲ 各种配置](#Ⅲ 各种配置)
- [2.1.4 软件代码设计](#2.1.4 软件代码设计)
-
- [Ⅰ 环境构建](#Ⅰ 环境构建)
- [Ⅱ 编写代码](#Ⅱ 编写代码)
- [2.1.5 代码下载](#2.1.5 代码下载)
-
- [Ⅰ 硬件下载](#Ⅰ 硬件下载)
- [Ⅱ 软件下载](#Ⅱ 软件下载)
- [2.1.6 运行结果](#2.1.6 运行结果)
- [2.2 Verilog流水灯](#2.2 Verilog流水灯)
- [三、 心得体会](#三、 心得体会)
- [四、 参考链接](#四、 参考链接)
一、 内容概要
在DE2-115开发板上分别用 Verilog和 Nios软件编程两种方式完成LED流水灯显示,理解两种方式的差异
二、 实现
2.1 基于Nios II软核的流水灯
2.1.1 准备工作
- Quartus II
- DE2-115开发板
2.1.2 工程搭建
- 打开Quartus,新建一个工程
按照图片进行如下选择
选择芯片
finish
2.1.3 硬件代码设计
Ⅰ 连接IP核
类似于以可视化界面的方式进行verilog里面的通过顶层文件连接各模块操作
找到platform Designer ,某些版本可能是 Qsys
首先设置时钟
默认即为50MHZ,设置好后点右下角finish
左侧通过搜索栏进行搜索,添加以下模块:
Nios Ⅱ Processor
(nios软核处理器)
On-Chip Memory
(储存器)
JTAG UART
(JTAG、UART)
System ID Peripheral
(为Nios II生成一个ID号)
pio
(流水灯管脚)
先全部点Finish保持默认
三连击Name标签下的属性可以修改名称:
略微修改了一下名字
连接模块:
clk,reset,datamaster需要和其他所有IP核连接,nios ii的指令端口(instruction_master)只与存储器进行连接,nios ii中的jtag_debug_model_reset与外部IP核进行连接 。jtag端口的中断信号的连接,其中0表示中断的优先级(可以进行设置)
接下来进行参数配置(右键模块点击edit)
- On-chip Memory
设置为10k(10240)
- nios
- PIO
将width设置为4表示4个Led灯
把管教名设置为led
然后系统分配地址
完成后就不报错了
最后点击右下角Generate生成
然后等待
完成后一路finish
Ⅱ 编写代码
回到Quartus,新建一个verilog文件
写入代码
c
module led_ctrl(
input clk,
input reset_n,
output [3:0] led
);
Ⅲ 各种配置
找到生成的文件添加
找到这个总文件,根据管脚信息在之前写的代码里面加入:
c
demo2_waterled u0 (
.clk_clk (clk), // clk.clk
.reset_reset_n (reset_n), // reset.reset_n
.led_export (led) // led.export
);
这样完整的代码即为:
c
module led_ctrl(
input clk,
input reset_n,
output [3:0] led
);
demo2_waterled u0 (
.clk_clk (clk), // clk.clk
.reset_reset_n (reset_n), // reset.reset_n
.led_export (led) // led.export
);
endmodule
配置一下管脚
然后进入Dual-purpose Pins,全部设置为Use as regular I/O
然后编译一下
然后分配一下管脚
重新编译
2.1.4 软件代码设计
Ⅰ 环境构建
通过此处打开eclipse
自己选定一个工作空间(不一定是当前项目目录)
进入初始界面后创建文件
点击NEXT
点击Finish
完成后找到这个文件
Ⅱ 编写代码
把hello_world.c的代码修改为:
c
#include <stdio.h>
#include "system.h"
#include "altera_avalon_pio_regs.h"
#include "alt_types.h"
const alt_u8
led_data[4]={0x01,0x03,0x07,0x0F};
int main (void) {
int count=0;
alt_u8 led;
volatile int i;
while (1)
{
if (count==4)
{
count=0;
}
else
{
count++;
}
led=led_data[count];
IOWR_ALTERA_AVALON_PIO_DATA(LED_BASE, led);
//延时的设置
i = 0;
while (i<5000000)
i++;
}
return 0;
}
保存
而后右键waterled_bsp,再Nios II 中选择BSP Editor进行如下配置:
选择Generate BSP
然后右键waterled,选择build project
完成
2.1.5 代码下载
Ⅰ 硬件下载
Ⅱ 软件下载
回到eclipse,右键waterled,选择Run As中的Nios II Hardware
刷新一下
然后先apply再run
2.1.6 运行结果
2.2 Verilog流水灯
直接编写Verilog代码
c
module led_ctrl(input En,input CP,input Dn,output reg [0:7] Out);//匹配8个灯,故宽度为8
reg [25:0] cnt;
reg cnt1;
reg Cn;
parameter cnt_max = 26'd49_999_999;//时钟的频率是50mhz,要实现几秒钟变一次就调到//相应时间,例子为1s每次
always@(posedge CP or negedge En)//该always循环实现的是一秒钟的计数
if(En==1'b0)
cnt<=26'd0;
else if(cnt == cnt_max)
cnt<=26'd0;
else
cnt<=cnt + 1'b1;
always @(posedge CP or negedge En) //cnt每次为1代表到了一秒钟
if(En==1'b0)
cnt1<=1'b0;
else if(cnt == cnt_max-1'd1)
cnt1<=1'b1;
else
cnt1<=1'b0;
always @(posedge CP or negedge En)
if(En==1'b0) begin
if(Dn==1'b1) //用 Dn来判断赋不同的值,1为亮,也就可以实现两个灯一起移动的选择
Out <=8'b00000001;
else
Out <=8'b00000011;
end
else begin
if (Out[0]==1'b1)//不用判断整个Out,只需要判断最边上的1,为1则表示需要改变方向,方向由Cn判断
Cn<=1'b1;
else if(Out[7]==1'b1)
Cn<=1'b0;
if (cnt1==1'b1) begin
if(Cn==1'b1)
Out<={1'b0,Out[0:6]};//右移
else
Out<={Out[1:7],1'b0};//左移
end
end
endmodule
管脚配置
正常编译烧录就行
结果:
三、 心得体会
·理解硬件与软件编程的差异:通过实践,我更深入地理解了硬件描述语言(如Verilog)和软件编程(如C语言)在FPGA设计中的应用差异。
·硬件编程的直观性:使用Verilog直接编程,可以直观地控制硬件行为,如LED的亮灭顺序,这种方式更接近底层硬件,对FPGA的资源利用和性能优化有更直接的控制。
·软件编程的便利性:Nios II软核提供了一个类似于通用处理器的环境,可以使用高级语言(如C语言)进行编程,这使得开发过程更加简便,代码更易于理解和维护。
·综合工具的重要性:无论是硬件还是软件编程,都需要依赖于综合工具(如Quartus II)来将设计部署到FPGA上。这些工具提供了图形界面和自动化流程,极大地提高了开发效率。
·学习曲线:Verilog编程可能对初学者来说有一定的难度,因为它需要对硬件电路有一定的理解。而Nios II软核编程则更容易上手,因为它使用的是更熟悉的编程语言和概念。
对比
·开发速度:使用Nios II软核进行软件编程通常开发速度更快,因为它允许开发者使用高级语言和现有的库函数。
·资源消耗:硬件编程(Verilog)通常对FPGA资源的消耗更少,因为它直接控制硬件,而软件编程可能需要更多的资源来运行软核处理器。
·性能:硬件编程可以实现更高的性能,因为它可以精细控制时序和并行操作,而软件编程可能受限于软核处理器的性能。
·灵活性与可移植性:软件编程在灵活性和可移植性方面具有优势,因为编写的软件可以在不同的硬件平台上运行,而硬件编程则更依赖于特定的FPGA架构。
·调试与测试:硬件编程的调试可能更复杂,需要使用仿真和硬件测试工具。软件编程则可以使用标准的调试工具,如Eclipse的调试器。
·应用场景:对于需要高性能和低延迟的应用,硬件编程可能更合适。而对于复杂的算法和数据处理任务,软件编程可能更加高效。