NIOS Ⅱ系统实例,参考自特权同学《勇敢的芯-伴你玩转NIOS Ⅱ》
一些基础操作就不再赘述
目录
1.2 进入Platform Designer添加组件并设置
1.2.4 设置Nios Ⅱ复位向量与异常向量地址,使其指向RAM
1.创建Quartus项目
1.2 进入Platform Designer添加组件并设置
1.2.1 设置时钟频率50MHz;
1.2.2 添加Nios Ⅱ组件
选择Nios II/f模式;
1.2.3 添加RAM组件
设置Data width为32,Total memory size为22528,其他设置为默认
1.2.4 设置Nios Ⅱ复位向量与异常向量地址,使其指向RAM
1.2.5 添加System ID组件
设置32 bit System ID为0x01223344
1.2.6 添加JTAG UART组件
设置Write FIFO和Read FIFO得存储量为16,勾选Construct using registers instead of memory blocks,其他为默认
1.2.7 添加Timer组件
设置模式为Full-featured,周期Period为1,单位为s,其他默认
1.2.8 添加UART组件
设置校验位(Parity)为NONE、8个数据位(Data bits)、1个停止位(Stop bits)、同步周期(Synchronizer stages)为 2、波特率(Baud rate)为9600、不勾选Fixed baud rate(即波特率为Nios Ⅱ处理器软件可更改)
1.2.9 添加蜂鸣器PIO组件
设置位宽(Width)为1、方向(Direction)Output、默认值(Output Port Reset Value)为0x0,其他默认。
1.2.10 添加拨码开关PIO组件
设置位宽(Width)为4、方向(Direction)为Input、勾选Edge capture register-Synchronously capture选项,同时选中边沿类型(Edge Type)为 ANY、勾选InterruptGenerate IRQ选项,中断类型(IRQ Type)为 EDGE
1.2.11 数码管组件
数码管组件通过Avalon-MM总线从机接口实现 Nios Ⅱ处理器将4位数字显示到数码管上。该组件定时进行数码管显示驱动刷新,将 Nios Ⅱ处理器发送到数据寄存器的32位数据显示到数码管上。
将source_code/digital_tube_controller下三个.v文件添加自定义数码管组件并设置信号相应参数,然后添加数码管组件
Parameters中可以设置组件源码中定义的参数是否在用户加载组件时可配置
这里ADDR_SIZE为固定值,因此不勾选
注意dtube_cs_n和dtube_data的export名字不能相同
1.2.12 ADC组件
ADC组件通过Avalon-MM总线机接口实现Nios Ⅱ处理器与ADC芯片TLC549之间的数据传输。该组件产生TLC549芯片数据读取所需的接口时序,定时读取ADC芯片的采样数据存储到Avalon-MM 总线可访问的数据寄存器中,供Nios Ⅱ处理器读取。
将source_code/adc_controller下三个.v文件添加自定义ADC组件并设置信号相应参数,然后添加ADC组件
1.2.13 DAC组件
DAC组件通过Avalon-MM总线从机接口实现 Nios Ⅱ处理器与DAC芯片DAC5571之间的数据传输。该组件产生DAC5571芯片读写访问的IIC总线接口所需的时序,在Avalon-MM总线可访问的数据寄存器值发生变化时,执行DAC5571芯片DAC转换数据的写入。
将source_code/dac_controller下三个.v文件添加自定义DAC组件并设置信号相应参数,然后添加DAC组件
1.2.14 超声波测距组件
ultrasound_controller组件通过Avalon-MM总线从机接口实现 Nios Ⅱ处理器对超声波模块获取的最新距离数据信息的采集。该组件定时产生超声波测距模块所需的触发脉冲信号,回采反馈脉冲,并且对反馈脉冲进行中值滤波和距离值换算,最终获得以毫米为单位的距离信息。该距离信息存储到 Avalon-MM总线可访问的数据寄存器中,供 Nios Ⅱ处理器读取。
将source_code/ultrasound_controller下六个.v文件以及mult文件夹(乘法器IP核)下mul.qip文件添加自定义超声波测距组件并设置信号相应参数,然后添加超声波测距组件
1.215 RTC组件
RTC组件通过Avalon-MM总线从机接口实现Nios Ⅱ处理器对RTC芯片PCF8563T的时间和日期数据进行读写操作。该组件定时读取最新的RTC数据,存储到Avalon-MM总线可访问的数据寄存器中,Nios Ⅱ处理器随时可以读取最新的RTC数据也可以写人修改的数据更新到RTC芯片中。
将source_code/rtc_controller下五个.v文件添加自定义RTC组件并设置信号相应参数,然后添加RTC组件
1.2.16 矩阵按键组件
矩阵按键组件通过Avalon-MM总线从机接口实现 Nios Ⅱ处理器对4X4矩阵按键值的采集。该组件定时产生矩阵按键扫描所需的各种电平变换,采集到按键扫描值存储到Avalon-MM总线可访问的数据寄存器中并且产生可配置开关状态的中断信号给Nios Ⅱ处理器,Nios Ⅱ处理器可通过中断状态实时读取按键值。
将source_code/Button_controller下四个.v文件添加自定义RTC组件并设置信号相应参数,然后添加矩阵按键组件
1.3 信号连接
将各个组件的时钟、复位信号连接到Clock组件的相应信号上
为了Nios Ⅱ处理器能够访问到各个组件,实现对组件数据的读取、传输等功能,则需要将Nios Ⅱ处理器的数据总线(data_master)连接到各个组件(s1、control_slave、avalon_jtag_slave)上
要把Onchip_men作为Nios Ⅱ处理器的程序存储和程序运行的存储器,需要把Nios Ⅱ的指令总线(instruction_master)和数据总线(data_master)连接到Onchip_men的s1上
数据主端口与所有的外设 IP 核连接,而指令主端口只连接存储器 IP 核
此外UART外设接口(RX和TX信号)需要引出到QSYS系统外部连接到FPGA的引脚上,因此需要双击UART外设external_connection一行的Double-click to,当出现接口符号,说明该接口已引出
PIO和自定义组件同理
1.4 中断连接
在IRQ一列中与Nios Ⅱ处理器相连接中断信号有timer、pio_switch、jtag_uart、uart 和 ButtonController组件。
点击这些IRQ和 NiosⅡ处理器的空心圆连接点进行连接,连接后出现的数字表示中断号,数字越低优先级越高。
1.5 地址分配
在Address Map窗口列出了所有外设的地址范围。目前地址还未分配,默认都是从0x0000开始作为基地址,所以各个外设间出现了地址冲突
在菜单栏中选择System一Assign Base Address让工具自动进行地址分配,以8bit为单位进行寻址
这这里应该所有报错都解决了
1.6 系统生成并例化模板
菜单栏Generate->Genarate HDL...
在Quartus的工具栏Assignments->Settings->Files->File name中找到生成的.qip文件并添加
添加成功后会在Project Navigator窗口中看到添加的qip文件
1.7 完成Quartus工程
最后建立工程的顶层模块,在Platform Designer中点击Generate->Show Instantiation Template生成例化代码
将例化代码复制到顶层文件cy4.v中并连接好端口
//Qsys系统
module cy4(
input ext_clk_25m, //外部输入25MHz时钟信号
input ext_rst_n, //外部输入复位信号,低电平有效
input uart_rx, //UART接收数据信号
output uart_tx, //UART发送数据信号
input[3:0] switch, //拨码开关SW3输入,ON-低电平、OFF-高电平
output beep, //蜂鸣器控制信号,1-响、0-不响
output[3:0] dtube_cs_n, //7段数码管位选信号
output[7:0] dtube_data, //7段数码管段选信号(包括小数点为8段)
input adc_data, //ADC芯片TLC549的SPI数据信号
output adc_cs_n, //ADC芯片TLC549的SPI片选信号,低电平有效
output adc_clk, //ADC芯片TLC549的SPI时钟信号
output dac_iic_sck, //DAC5571的IIC接口SCL
inout dac_iic_sda, //DAC5571的IIC接口SDA
output ultrasound_trig, //超声波测距模块脉冲激励信号,10us的高脉冲
input ultrasound_echo, //超声波测距模块回响信号
output rtc_iic_sck, //RTC芯片的IIC时钟信号
inout rtc_iic_sda, //RTC芯片的IIC数据信号
input[3:0] key_v, //4个列按键输入,未按下为高电平,按下后为低电平
output[3:0] key_h //4个行按键输入
);
wire clk_12m5; //PLL输出12.5MHz时钟
wire clk_25m; //PLL输出 25 MHz时钟
wire clk_50m; //PLL输出 50 MHz时钟
wire clk_100m; //PLL输出100 MHz时钟
wire sys_rst_n; //PLL输出的locked信号作为FPGA内部的复位信号,低电平复位,高电平正常工作
//-------------------------------------
//PLL例化
pll_controller pll_controller_inst (
.rst ( !ext_rst_n ),
.refclk ( ext_clk_25m ),
.outclk_0 ( clk_12m5 ),
.outclk_1 ( clk_25m ),
.outclk_2 ( clk_50m ),
.outclk_3 ( clk_100m ),
.locked ( sys_rst_n )
);
//-------------------------------------
//Qsys系统例化
cy4_qsys uun_cy4_qsys (
.adc_controller_1_conduit_end_export_clk (adc_clk), //adc_controller_1_conduit_end.export_clk
.adc_controller_1_conduit_end_export_cs_n (adc_cs_n), //.export_cs_n
.adc_controller_1_conduit_end_export_data (adc_data), //.export_data
.buttoncontroller_0_conduit_end_1_export_v (key_v), //buttoncontroller_0_conduit_end_1.export_v
.buttoncontroller_0_conduit_end_1_export_h (key_h), //.export_h
.clk_clk (clk_50m), //clk.clk
.dac_controller_0_conduit_end_export_scl (dac_iic_sck), //dac_controller_0_conduit_end.export_scl
.dac_controller_0_conduit_end_export_sda (dac_iic_sda), //.export_sda
.digital_tube_controller_conduit_end_export_cs_n (dtube_cs_n), //digital_tube_controller_conduit_end.export_cs_n
.digital_tube_controller_conduit_end_export_data (dtube_data), //.export_data
.pio_beep_external_connection_export (beep), //pio_beep_external_connection.export
.pio_switch_external_connection_export (switch), //pio_switch_external_connection.export
.reset_reset_n (sys_rst_n), //reset.reset_n
.rtc_controller_0_conduit_end_export_rtcsda (rtc_iic_sda), //rtc_controller_0_conduit_end.export_rtcsda
.rtc_controller_0_conduit_end_export_rtcsck (rtc_iic_sck), //.export_rtcsck
.uart_external_connection_rxd (uart_rx), //uart_external_connection.rxd
.uart_external_connection_txd (uart_tx), //.txd
.ultrasound_controller_0_conduit_end_export_trig (ultrasound_trig), //ultrasound_controller_0_conduit_end.export_trig
.ultrasound_controller_0_conduit_end_export_echo (ultrasound_echo) //.export_echo
);
endmodule
添加一个PLL IP核
进行语法分析,引脚分配,系统编译,完成Quartus Ⅱ工程