我先看的正点原子nios视频笔记,后看的小梅哥,这篇笔记就不怎么记太基础的了
讲课口头禅、音量忽大忽小、语速忽快忽慢也让人头疼,但是讲的比较细致、透彻,还讲了很多正点原子没讲过的东西,值得一听,有收获,很多时候看视频标题没兴趣看,看的过程中发现有意外收获。多看看他的视频,加深认识,调试时可以少走很多弯路。
IP硬核:外设固定 无法修改,增加成本和功耗、依赖具体FPGA器件。性能较高。
IP软核:低成本、灵活裁剪、可集成多个处理器、支持TCP/IP。
基于ASIC与FPGA区别
quartus15.0以上版本,有nios II GEN2
nios内核类型
32位对应4G寻址空间。最高位用于指令缓存屏蔽位、所以只有2G寻址空间
FPGA大大简化设计
qsys配置生成的是Verilog代码。
软件工具及开发流程
软件实现容易修改、增删、差错、不增加逻辑资源占用,但性能较低。一般优先使用软件实现。
led闪烁系统框图
软核一般不进行仿真
如果在nios跑linux,nios设置需要include MMU。使用SDRAM时为提高速度,利用片上ram实现cache。注意有cache时不要使用指针操作外设,容易出问题。
on-chip ROM,不要勾选 Enable non-default initialization file,否则niosIDE报错
统一编址
注意:quartus工程添加*.qsys文件后再编译。
添加时钟的时序约束
注意去掉优化,否则LED不闪烁
quartus正常破解qsys才能generate
bsp包含硬件信息
system.h中的SYSID_ID是十进制,qsys中设置的是16进制
将elf转化为hex初始化文件
工程右键-->Make Targets-->Build-->mem_init_generate-->build 。quartus工程添加生成的qip(就是hex的路径)文件。重新编译,下载sof(同时包含软硬件)led闪烁。烧写jic即可固化软硬件。
EPCS实际是SPI接口的FLASH,几块钱。
Flash Loader实际上也是一段代码,实现将jtag传过来的配置数据写入epcs
PIO设置修改。Bidir只有1个信号引出,可用于IIC的信号。InOut有2个信号引出,一般用于FPGA内部逻辑。
直接双击Assembler可避免时序分析,节约时间。
查看pio源码发现双向IO口默认是输入
视频把PIO核8页说明全部简单讲了1遍
作业
注意时钟输入引脚可以作为按键输入,但不可以作为输出或三态引脚
完成上个视频作业
键盘无上拉电阻,需要在quartus中设置上拉电阻
字体从默认的西欧改为中欧
查询PIO数据方式:设置PIO方向、关中断、读PIO
查询PIO边沿捕获寄存器方式:设置PIO方向、关中断、清捕获位、读捕获寄存器、清捕获位
拷贝的工程若不做任何修改,直接改c文件,更改的实际是原路径下的c文件。
更改路径后,先删除工程(非删除文件),后右键 import-->general-->existing projects into workspace ,修改 settings.bsp 的两个路径。
2个常用操作:右键工程 Refresh 或 Index-->Freshen ALL Files
位设置与位清零
#include sys/alt_irq.h
IOWR_ALTERA_AVALON_PIO_IRQ_MASK 打开中断
alt_ic_isr_register注册中断(ic指器件)
使用 Outline当目录用也不错
查看工程与bsp是否关联,如下图
debug时需要关掉优化
若debug时有gdb进程在运行(debug时异常退出),会导致debug异常,需要去任务管理器中关掉gdb。
只保留.v文件和.sys文件共2个文件,新建quartus工程,添加2个文件
Altera 16550 Compatible UART是收费IP,功能较全
JTAG UART示意图如下,nios写入JTAG 的FIFO(等待PC通过blaster主动读FIFO),若FIFO满则无法写入,nios等待、挂起、软件死机
UART(RS-232 Serial Port)性能最弱,简单可靠,本视频使用该UART核。
若端口较多,可从IP核源码中复制到用户工程源文件,如下图
在引脚分配窗口也可以直接复制Location,另外优先使用3.3-V LVTTL
新建hello world small,例程代码无需修改,直接从串口打印字符串,代码如下
alt_main函数调用alt_sys_init调用串口初始化代码,若在Drivers中取消Enable,则无对应设备的初始化代码,如下图
多个串口时选择某个串口作为标准输入、输出、错误设备,如下
花了大量时间看文档UART相关内容
注意:若用户直接操作寄存器收发数据,一定记得关掉bsp的驱动,否则会导致bsp与用户抢数据。
关bsp的uart驱动
C代码:关uart中断、清status、读空rxdata、设波特率(使用系统频率宏定义),txdata为空则发送。
用户工程优化选项为size,导致边沿捕获读取不到数值,始终为0。
用搜索的方式改代码字体,快多了
编译完看不到过程中的Console信息,选中用户工程就能看到了
回环发送代码如下
中断接收代码如下
调试时在memory中查看全局变量,Monitors中点击+,输入全局变量名
新建用户工程,使用现有bsp(允许多个用户工程使用同一个bsp)工程
新的用户工程只复制1个c文件即可编译,编译前后如下图
UART收发中断使用同1个函数,如下
选中工程,alt+enter快速打开属性设置
根据开发板硬件设置SDRAM参数,timing使用默认值,只修改位宽+column
添加Avalon ALTPLL为SDRAM提供时钟,-90°相移
PLL取代系统时钟为所有IP核提供时钟,
sdram引脚默认2.5V,可直接复制粘贴成3.3V
引脚分配也可以直接从excel中复制
引脚分配也可以通过预先写好的tcl文件一键分配
从ram改到sdram后需要刷新,否则sdram实际未使用,刷新后interrupt_stack_memory_region_name随之改变
添加qsys核(背光需要自己写代码),printf可直接打印在屏幕上
添加时序约束
没加约束,clk[0]只能跑到68.79MHz,设计100M,可能无法下载
sdc约束文件添加到工程中,指导布局布线,达到设计要求。
添加约束后,频率几乎翻番,满足要求
3个任务的3种实现方式
操作系统必须有定时器
定时时间太短,切换太快,切换相关资源消耗较高。视频中为10ms。
视频中有3个定时器,1个用于操作系统+1个用于通用定时器+1个看门狗 。看门狗一般固定时间、不可停止,否则有warning,看门狗设置如下
见下图,看门狗复位除clk外所有IP核
若使用同步复位,添加reset核。即看门狗复位reset核,reset核复位其他IP核(含看门狗),连接如下
若不了解IP核,可查阅文档Embedded Peripherals IP User Guide。
视频中printf打印到串口,而不是通过jtag打印到niosIDE
若不想bsp自动驱动某些外设,可以关掉,如下图
若添加了任意定时器,但是没有使用操作系统,也没有使用定时器,建议关掉,否则可能出现各种奇葩问题
使用uCos,必须注意上图系统时钟设置正确。
实现上个视频提到的多任务
LED IO设为输出,关IO中断
使用全局变量实现任务间通信
任务1 2代码如下
任务3,按键按下则改变led闪烁方式,led++
按键优先级调整为最高,另外led闪烁和串口打印任务优先级无所谓。
任务4,启动看门狗、喂狗
修改printf输出设备,打印到lcd屏幕
Epcs中断是为了作为通用存储器时提高读写速度
分配引脚也可以手动输入,而不是必须要综合1遍
更换主内存后注意执行2次restore defaults
复位地址为epcs,却想用ram调试,需取消allow_code_at_reset、enable_alt_load,但烧写时必须勾选(在13.1实测,勾选则无法调试。不勾选即可在线调试也可固化)
使用sh tcl脚本生成hex jic实现固化:1、eclipse中运行sh脚本;2、quartus中运行tcl脚本;3、烧写jic
开发板使用的通用SPIFLASH W25Q16(ID=EF4015),非altera官方。
官方EPCS16 ID
保存nios烧写配置文件,方便下次烧写
解决No EPCS layout data --- looking for section [EPCS-xxxxx]_subkiller的博客-CSDN博客
SOC的核心是软硬件协同
nios采集AD数据低效率的2个方案如下:1、使用PIO模拟SPI时序读取ADC;2、使用PIO控制Verilog写的ADC驱动。
查看PIO核对应的.c .h .v文件,根据.v文件理解avalon总线时序,时钟 复位 片选 地址 写请求 写数据
quartus自动扫描工程目录下名为IP的文件夹
数据寄存器一般放在地址0
自定义IP核操作
小写字母命名比较规范,基本自动识别成功。大写字母全部识别错误,手动修改后如下图
指定复位信号、remove interfaces with no signals、指定中断信号绑定as总线
修改tcl文件所在路径为.v文件路径,修改tcl文件中的.v文件路径,删除选中部分后即为相对路径(tcl文件与v文件在同一路径下)。直接复制文件夹即可复制IP
注意nios中地址以字节为单位,nios中地址偏移是ADC IP核地址(以16bit为单位)的2倍
上述代码有误,将按位与~替换为逻辑非!即可在串口打印AD采样值
关于chipselect的作用说明:如下图,PIO只连接低4位地址线,若nios访问UART或ADC,若没有chipselect,PIO会误以为被访问。
封装IP的操作步骤总结
__builtin_stwio:内建汇编指令,其中w指word 32bit
SYSTEM_BUS_WIDTH为32
有下图中的一句话,IP按照静态地址对齐,可以使用IORD IOWR。若没有NATIVE这句话,默认动态地址对齐,
更改为静态地址对齐后,软件代码如下(注意地址偏移)。图中有误,0x0a应改为5
下图路径为系统IP源文件保存位置
地址对齐总结
上节复习
parameter生成IP(必须在顶层文件中)时会展示在GUI界面上,localparam不会。
DAC寄存器
C语言操作时注意
底层驱动独立为单独函数,如dac_init()。
为提高可移植性,建议不使用alt_types.h,使用跨平台通用的C99标准的stdint.h中定义的数据类型
自定义IP核建议写寄存器说明文档,编写类似altera_avalon_pio_regs.h的头文件
参考bsp,新建文件夹.c .h,按功能区分文件,而不是都在mian.c一个文件中
注意包含新建的h文件路径
有时还需要下述操作(修改的文件在硬盘,软件运行在内存,Freshen ALL Files保持硬盘和内存一致)
需求:nios占用SDRAM,显示器也想主动从SDRAM读取数据;摄像头主动将数据写入SDRAM,等待nios或其他外设读取;
讲文档《Avalon-MM Master Templates》及相关文件
将文件拷贝到相应路径,qsys出现 master_template IP核
master_template 的avalon_master只连接到SDRAM。因为用户接口同步于内部的clk,需要将clk引出。但clk要么内部连线,要么引出到外部,不可同时使用,借助Clock Bridge核实现。因为原fifo为sc同步fifo,不方便使用,小梅哥改写为dc异步fifo,使用用户提供的时钟,注意控制端口仍然是同步的。
使用ucgui库实现图形界面,液晶屏直接读SDRAM,大概35帧显示波形。相当于SDRAM既做nios的内存,也做屏幕的显存。
码农只需要关心3控制逻辑、4fifo
高速数据传输一般都需要avalon mm master。
位宽与SDRAM保持一致;SDRAM地址宽度23,选择32也能用;SDRAM不支持突发;M9K只要用1点,整体都不能用作其他用处,干脆直接用完,fifo深度512(512*16=8192bit=M9K)。若使用logic,深度别太大;
建议将SDRAM地址固定为0开始,方便用户逻辑访问。
非固定地址、从SDRAM中间位置开始访问、读4096*2字节(与C代码4096*16bits保持一致)。
调试时使用下述工具。另外注意控制端口仍然是同步的
注意:control_done指全部4098*2个字节读完,user_read_buffer才是用户读数据需要考虑的,只要有效就可以读数据。
软件C代码和硬件逻辑分工如下
verilog实现udp协议数据带宽高,但不适用于广域网、路由器传输。下述方案OV7670+W5500实现TCP/IP协议,也方便转换为其他协议,但带宽相对较低。
master写IP也将fifo 改写为双时钟,需要修改下图后4个文件
master核配置类似读master配置
quartus中端口
使用第3方IIC IP核
硬件上需要通信扩展(貌似板级通过50MSPI传输)板卡(ETH CAN 485)
SPI IP核 连线及配置
最终效果,帧率只有0.7,非常卡,有很大优化空间
SGDMA比master更加复杂,资源占用很多,效率比avalon MM接口的DMA更高,可支持千兆以太网
Memory to Memory使用avalon MM总线,Memory to Stream数据输出方为avalon ST,Stream to Memory数据输入方为avalon ST。
视频示例的数据流
VGA_SINK为第三方开源IP,友晶科技提供。
latency指该信号需要打几拍。很多信号小梅哥也没有彻底明白。
双时钟fifo设置,注意为ST接口,非MM接口
IP核连接如下
VGA_SINK模块默认设置即可
IP连线完成
需要增加硬件板卡
右键代码注释
显示图片
上图颜色变化较大时,花纹明显,修改VGA_CLK为反相后显示正常。