一、实验原理
控制LED灯闪烁的用户程序代码很小,可将其固化在片内ROM来执行。变量、堆栈等空间使用片内RAM,不使用任何片外存储器。整个系统框图如图所示。
二、实验设备
硬件:PC 机、DE2-115 FPGA 实验开发平台
软件:Quartus Prime 18.1、Platform Designer、Nios II SBT
三、实验内容
1、硬件设计
(1)创建新项目
芯片的选用:EP4CE115F29C7
(2)Qsys系统设计
进入系统
保存命名文件
双击clk_0,设置为50M
(3)添加Nios II 32-bit CPU
component library标签栏找到Nios II Processor,然后点击add
Nios Core栏中选择Nios II/f选项,其他保持默认选项
重命名为:cpu
cpu的clk和reste_n分别与系统时钟clk_0的clk和reste_n相连
(4)添加jtag uart接口
左侧栏出入jtag找到JTAG UART,然后点击add
保持默认选项,点击finish;
将jtag-uart_0重命名为jtag-uart;
进行clk、reset以及master-slave的连线
(5)添加片上存储器On-Chip Memory(RAM)核
在左侧栏选择On-Chip Memory(RAM or ROM),然后点击add
Size栏中的Total memory size中的窗口输入40960(即片上内存的大小为40KB),其余选项保持默认重命名为onchip_ram;进行时钟、数据端口、指令端口的连接
(6)添加PIO接口
在左侧栏选择PIO,点击add,Width为8bits,Direction选择output,其余选项保持默认
重命名为pio_led,并在export栏处双击,将输出口引出来,并命名为out_led,进行时钟、数据端口、指令端口的连接
(7)添加片System ID Peripheral核
左侧栏输入sys找到System ID Peripheral后点击add,保持默认选项,点击finish,重命名为sysid,进行时钟、数据端口的连接
(8)Qys后续设计
基地址分配:点击system下的Assign Base Address
分配中断号:在IRQ标签栏下选择Avalon_itag_slave和IRQ的连接点就会jtag_uart核添加一个值为0的中断号
点击Qsys主界面菜单栏中的system下的Create Global Reset Network,完成后会自动连接所有复位端口
指定Nios II的复位和异常地址:从system Contents标签栏双击建立好的cpu,进入Nios II Processor的配置界面,配置Reset Vector和Exception Vector为onchip_ram.sl
生成Qsys系统,点选Generate下的Generate
(9)添加Verilog文件
module led1(
input clk,
input reset_n,
output [7:0] led
);
kernel u0 (
.clk_clk (clk), // clk.clk
.reset_reset_n (reset_n), // reset.reset_n
.out_led_export (led), // out_led.export
);
endmodule
(10)添加对应的.qip文件加入项目中
点击Assignments-Settings,添加kernel.qip文件,点击add,选择OK
(11)生成逻辑连接和生成管脚
逻辑连接。开发板晶振为50M,与系统默认一致,不需要修改。
芯片引脚设置选择Assignments-device,然后点击device pin options;
进行unused pin设置,可能会收到外部信号的干扰,将未用引脚设置为As input tri-stated
特殊引脚设置,设置为常规引脚
编译工程
分配物理引脚再编译
2、软件设计
Nios II Software Build Tools for Eclipse来完成项目的软件开发
- 选择Tools-Nios II Software Build Tools for Eclipse,打开Nios II SBT for
Eclipse - 启动Workplace选择当前的项目目录,点击OK
创建工程 - 选择File-New-Nios II Application and BSP from Template
- 在SOPC Information File name窗口中选择kernel.sopcinfo文件,CPU栏中选择cpu,在Project
name输入hello,Project template选择Hello_World,点击finish
系统会自动生成一个打印hello_world的软件工程,在hello_world.c中修改代码
#include "system.h"
#include "altera_avalon_pio_regs.h"
#include "alt_types.h"
const alt_u8
led_data[8]={0x01,0x03,0x07,0x0F,0x1F,0x3F,0x7F,0xFF};
int main()
{
int count=0;
alt_u8 led;
volatile int i;
while(1)
{
if (count==8)
{
count=0;
}else{
count++;
}
led=led_data[count];
IOWR_ALTERA_AVALON_PIO_DATA(PIO_LED_BASE,led);
i=0;
while(i<500000)
i++;
}
return 0;
}
编译程序,右键项目名称,选择Build Project
3、Verilog实现
module v_lsd (
input wire clk ,
input wire rst_n ,
output [7:0] led
);
parameter CNT_MAX = 26'd5000_0000;
reg [25:0] cnt_1s;//1s 计数器,计数最大值 5000_0000 - 1
wire flag_1s;//计数器每计满1s,使能一个时钟周期
reg [7:0] led_reg;//输出信号的寄存信号
//1s计数器
always@(posedge clk or negedge rst_n)begin
if(!rst_n)
cnt_1s <= 26'd0;
else if(cnt_1s >= CNT_MAX - 26'd1) //归零条件
cnt_1s <= 26'd0;
else
cnt_1s <= cnt_1s + 26'd1;
end
assign flag_1s = cnt_1s >= CNT_MAX - 26'd1;
//移位实现流水灯
always@(posedge clk or negedge rst_n)begin
if(!rst_n)
led_reg <= 8'b1111_1111;//全灭
else if(flag_1s)
if(led_reg == 8'b1111_1111)
led_reg <= 8'b0000_0001;
else
led_reg <= {led_reg[6:0],led_reg[7]};//拼接实现循环移位
else
led_reg <= led_reg;
end
assign led = led_reg;
endmodule
四、实验结果
下载:
连接JTAG到开发板
启动Nios II->Quartus Prime Programmer 添加下载文件
然后点击start开始下载
运行/调试程序
选择Run->Run Configurations 配置Run Configurations
转到TargetConnection标签栏,点击右侧的Refresh Connection,将USB-Blaster加入
五、参考与总结
参考:
https://blog.csdn.net/qq_43678923/article/details/116067041
总结:
本次实验了解到nois软核的工作原理,也体会到了与verilog实现方法的不同,体会到nois软核实现的功能强大,高效的利用率。