SOPC之NiosⅡ系统(三)

常用NIOS Ⅱ组件概括

目录

1.定时器Timer

1.1 预定义硬件配置

1.2 超时周期Timeout poriod

1.3 计数器大小Timer counter Size

1.4 寄存器Registers

2.串口UART

2.1 基础设置Basic settings

2.1.1 奇偶校验Parity

2.1.2 数据为Data bits

2.1.3 停止位Stop bits

2.1.4 其他

2.2 波特率设置Baud rate

3.SDRAM

3.1 Memory Profile

3.2 Timing

4. 自定义IP核


1.定时器Timer

Interval timer核的基础特性:
1.Niosll 处理器的Avalon-MM主设备可以通过写控制寄存器 (control register) 来完成:(1)启动和停止定时器;(2)使能/禁止IRQ;(3)明确累减计数一次或重复性累减计数

2.处理器通过读状态寄存器 (status register) ,能够得知定时器所处的状态

3.处理器可以通过给周期寄存器 (period registers) 写数值来指定定时器的周期

4.内部计数器累减到 0,然后会从周期寄存器 (period registers) 获取数值,继续累减计数

5.处理器可以通过一些操作来获取当前计数器 (counter) 的值:先给其中一个捕获寄存器 (snap registers)写数据,然后读捕获寄存器 (snap registers) 来获得完整的值。

6.当计数器计数到 0 的时候,可能会触发:(1)如果IRQ被使能,此时会触发 IRQ;(2)可选的一个时钟周期的脉冲输出;(3)可选的看门狗输出,复位系统

 在IP Catalog中搜索Timer添加Interval Timer Intel FPGA IP组件

1.1 预定义硬件配置

Library中提供了预定义的硬件配置:
Simple periodic interrupt (简单周期中断)一一用于只需要周期性地触发 RQ 的系统,固定周期,定时器无法被停止,但IRQ可以被禁止。
Full-featured (全功能) 一一用于要求定时器能被处理器启动或停止,但能禁止IRQ的嵌入式处理器系统
Watchdog(看门狗)一一用于需要“看门狗”定时器去复位停止响应的系统

1.2 超时周期Timeout poriod

超时周期(Timeout Period) 是定时器频率 (Timer Frequency)的整数倍。定时器频率固定为系统时钟的频率。定时器频率设置的单位可以是μs、ms、seconds或者clocks (系统时钟周期个数)


Period定时器周期,没有选中 Fixed period 选项的话,可以在软件中修改。若软件中没有修改操作,period 中的值就会作为超时周期 (Timeout Period)
Units: 周期的单位,可以是μs、ms、seconds、clocks。

1.3 计数器大小Timer counter Size

Counter Size设置决定了定时器的位宽,可以设置成32位或 64 位。

32位的定时器拥有2个16位的period registers (周期寄存器)

64位的定时器拥有4个16位的period registers (周期寄存器)

1.4 寄存器Registers


No Start/Stop controlbits:没有选中该选项时,主设备可以通过写control寄存器中的START和 STOP位来启动或者停止定时器。当选中该选项后,定时器会一直运行。当硬件中使能了“watchdog功能后,无论No Start/Stop control bits选项如何,control寄存器中 START 位有效。

Fixed period:选中该选项后,就无法在软件中更改定时器周期,且定时器周期为Timeout Period处设置的结果;若没有选中该选项,可以通过在软件中给 period registers 赋值来更改定时器周期(timeout Period )

Readable snapshot: 选中该选项后,主设备可以读取当前的计数值。没有选中该选项时,硬件中将不会存在 snap 寄存器,且读 snap 寄存器会返回未定义的值。在这种配置下,计数器 (counter)的状态只能通过status寄存器或IRQ信号之类的来观测

2.串口UART

在IP Catalog中搜索uart添加UART(RS-232 Serial Port) Intel FPGA IP组件

2.1 基础设置Basic settings

2.1.1 奇偶校验Parity

Partity有None (无)、Even (偶)、Odd (奇) 三个选项

用来确定UART是否发送有奇偶校验的字符,以及它是否期望接收到的有奇偶校验的字符。 

2.1.2 数据为Data bits

Data bits有7、8、9三个可设置选项,这个设置决定了txdata、rxdata、endofpacket三个寄存器的位宽。

2.1.3 停止位Stop bits

Stop bits有 1、2两个选项,决定了IP 核在传输每一个字符时,是有一个还是两个停止位。

UART IP 核总是在接收到第一个停止位的时候,就停止接收操作,忽略掉附带的停止位,无论什么设置。

2.1.4 其他

Synchronizer Stages与寄存器的长度以及亚稳态事件相关,一般使用默认设置。

Include CTSRTS选择是否使用串口的“流控”功能,一般很少使用

Include end-of-packet选择是否设置数据流的结束标志 (end-of-packet),一般很少使用

2.2 波特率设置Baud rate

UART 内核可实现RS-232标准中的任意波特率。

波特率可配置为:

固定的波特率一一波特率在系统生成时被确定,且不能通过 Avalon 从控制器端口改变它的值。
可变的波特率一一基于divisor寄存器中存储的时钟分频值,波特率是可变的。主控制器通过向divisor寄存器中写入新值来改变波特率。

波特率的计算依赖于 Avalon-MM 接口提供的时钟频率。在硬件改变系统时钟频率,却没有重新生成UART IP 核会导致错误的信号。

Baud Rate设置决定了复位后的波特率。Baud Rate选项提供了标准的预设值。也允许用户输入任何非标准波特率。为了实现所需要的波特率,通常根据波特率计算时钟分频系数。

波特率与分频系数的关系如下.
除数=int ( (时钟频率) / (波特) + 0.5 )
波特率=(时钟频)/(除 + 1 )

选择Fixed baud rate时,UART 硬件中不再包括divisor寄存器。UART硬件使用固定的波特率分频系数,且在系统生成后无法改变。

不选择Fixed baud rate时,硬件中会在地址偏移值4生成一个 16 位的divisor寄存器。divisor寄存器是可写的,可以通过向分频寄存器写入新值来改变波特率。

3.SDRAM

在IP Catalog中搜索sdram添加SDRAM Controller Intel FPGA IP组件

 

SDRAM 控制器 IP核产生于 FPGA 内部,它带有接口引脚、控制逻辑、以及Avalon从机接口

接口引脚用来连接外部 SDRAM 芯片管脚,这些接口引脚通过Altera FPGA上的I/0 引脚连接到 SDRAM芯片管脚上。

控制逻辑用来实现SDRAM操作,比如SDRAM 初始化,自刷新,突发读写等,这些全都是控制逻辑来完成的,当生成 SDRAM 控制器 IP 核之后,控制逻辑会自动生成。

Avalon从机接口用来连接CPU,Avalon从机接口是SDRAM控制器IP核中仅为用户可见的部分。从控制器端口提供一个线性存储器空间。Avalon接口作为存储器接口操作,SDRAM芯片必须和Avalon接口一样以相同的时钟来驱动,片内锁相环(PLL)就是用来调整 SDRAM 控制器与SDRAM 芯片之间的时钟相位差。

在较低的时钟频率下,可能不需要 PLL。在较高的时钟频率下,当信号在引脚上有效时,需要 PLL 来调整SDRAM时钟相位。PLI并没有包括在 SDRAM 控制器内。如果需要PLL,设计者必须在生成Qsys系统模块以外手动添加 PLL。

Presets列表提供几个预定义的SDRAM配置。如果实际使用的SDRAM芯片型号与列表中的一致,可直接选用而不用设置其他选项。选择不同的预配置,SDRAM IP核将自动改变Memory Profile和 Timing 选项卡上的值来匹配指定的配置。如果实际使用的 SDRAM 芯片与列表中的不相同,则可以根据 SDRAM芯片数据手册的参数来设置 Memory Profile 和 Timing标签上的值。

3.1 Memory Profile

数据宽度Data Width,有8、16、32、64四个可选项(SDRAM数据总线宽度),确定dq(数据)总线和dqm总线的宽度。

体系结构Architecture:

片选chip select,有1、2、4、8四个可选项(SDRAM 芯片的数目),通过使用多个片选信号,SDRAM控制器可组合多个SDRAM芯片为一个存储器子系统。

Banks,有2、4两个可选项(Bank 的数量),该值确定连接到SDRAM的 ba (Bank 地址) 总线宽度。

地址宽度Address Width:

行row,有11、12、13、14四个可选项,行地址线的宽度,该值确定addr总线的宽度

列column,≥8且小于行值,列地址线的宽度

Generic Memory model,当打开选项时,Qsys创建SDRAM芯片的功能仿真模型,仅用于仿真。

上述参数值可参照使用的 SDRAM 手册来设置,设置完毕后会显示SDRAM预期的内存容量。

3.2 Timing

设置 SDRAM 芯片的时序规范

 

4. 自定义IP核

自定义seg_decoder

首先要使用硬件描述语言描述硬件逻辑,一个典型的IP核的硬件逻辑一般由三个功能模块组成:

接口文件:作为顶层文件,定义总线接口信号;

寄存器文件:完成该IP核与外部信号进行通信,有了寄存器文件,用户就可以通过Avalon接口采用基地址+地址偏移量的方式来访问组件内部各寄存器;

硬件逻辑文件:实现IP核的硬件功能。

4.1自定义IP核实现动态数码管显示

4.1.1 创建工程及功能文件

创建Quartus工程,创建三个功能文件

顶层文件segled_controller.v

module segled_controller(
input clk, // 时钟信号
input rst_n, // 复位信号//Avalon-MM 接口
input [ 1:0] avs_address, // Avalon 地址总线
input avs_write, // Avalon 写请求
input [31:0] avs_writedata, // Avalon 写数据//数码管接口
output [ 5:0] sel, // 数码管位选
output [ 7:0] seg_led // 数码管段选
);//wire define
wire [19:0] data; // 6 个数码管要显示的数值
wire [ 5:0] point; // 小数点显示的位置,从高(左)到低(右),高电平有效
wire sign; // 显示符号位(高电平显示负号)
wire en; // 数码管使能信号//*****************************************************
//** main code
//*****************************************************//数码管寄存器文件
segled_register u_segled_register(
.clk (clk),
.rst_n (rst_n),//Avalon-MM 接口 
.avs_address (avs_address),
.avs_write (avs_write),
.avs_writedata (avs_writedata),//用户接口
.data (data),
.point (point),
.sign (sign),
.en (en),
);//数码管逻辑功能文件
segled_logic u_segled_logic(
.clk (clk), 
.rst_n (rst_n),//用户接口
.data (data), 
.point (point),
.sign (sign),
.en (en), //数码管接口
.sel (sel), 
.seg_led (seg_led) 
);endmodule

硬件逻辑文件segled_logic.v 

module segled_logic(
//module clockinput clk , // 时钟信号input rst_n , // 复位信号(低有效)//seg_led interfaceoutput reg [5:0] sel , // 数码管位选端(选择的数码管)output reg [7:0] seg_led, // 数码管段选端(数码管数值显示的段)//user interfaceinput [19:0] data , // 6 个数码管要显示的数值input [ 5:0] point , // 小数点显示的位置,从左到右,高电平有效input sign , // 显示符号位(高电平显示“-”号)input en // 数码管使能信号
);//parameter define
localparam MAX_NUM = 13'd5000 ; // 1ms 计数值
localparam CLK_DIVIDE = 4'd10 ; // 时钟分频//reg define
reg [12:0] cnt0 ; // 1ms 计数
reg 		  flag ; // 1ms 计满标志信号
reg [2:0]  cnt ; // 切换显示数码管用
reg [3:0]  num1 ; // 送给要显示的数码管,要亮的灯
reg 		  point1 ; // 要显示的小数点
reg [23:0] num ; // 24 位 bcd 码用寄存器
reg [ 3:0] clk_cnt ; // 时钟计数
reg 		  dri_clk ; // 驱动数码管操作的驱动时钟//wire define
wire [3:0] data0 ; // 十万位数
wire [3:0] data1 ; // 万位数
wire [3:0] data2 ; // 千位数
wire [3:0] data3 ; // 百位数
wire [3:0] data4 ; // 十位数
wire [3:0] data5 ; // 个位数//*****************************************************
//** main code
//*****************************************************assign data5 = data[19:0] / 17'd100000;        // 十万位数
assign data4 = data[19:0] / 14'd10000 % 4'd10; // 万位数
assign data3 = data[19:0] / 10'd1000 % 4'd10 ; // 千位数
assign data2 = data[19:0] / 7'd100 % 4'd10 ;   // 百位数
assign data1 = data[19:0] / 4'd10 % 4'd10 ;    // 十位数
assign data0 = data[19:0] % 4'd10; 				  // 个位数//生成数码管的驱动时钟用于驱动数码管的操作
always @(posedge clk or negedge rst_n) beginif(!rst_n) begindri_clk <= 1'b1;clk_cnt <= 4'd0;endelse if(clk_cnt == CLK_DIVIDE/2 - 1'd1) beginclk_cnt <= 4'd0;dri_clk <= ~dri_clk;endelseclk_cnt <= clk_cnt + 1'b1;
end//将 20 位 2 进制数转换为 8421bcd 码
always @ (posedge dri_clk or negedge rst_n) beginif (!rst_n)num <= 24'b0;else beginif (data5 || point[5]) beginnum[23:20] <= data5;num[19:16] <= data4;num[15:12] <= data3;num[11:8] <= data2;num[ 7:4] <= data1;num[ 3:0] <= data0;endelse beginif (data4 || point[4]) beginnum[19:0] <= {data4,data3,data2,data1,data0};if(sign)num[23:20] <= 4'd11;elsenum[23:20] <= 4'd10;endelse beginif (data3 || point[3]) beginnum[15: 0] <= {data3,data2,data1,data0};num[23:20] <= 4'd10;if(sign)num[19:16] <= 4'd11;elsenum[19:16] <= 4'd10;endelse beginif (data2 || point[2]) beginnum[11: 0] <= {data2,data1,data0};num[23:16] <= {2{4'd10}};if(sign)num[15:12] <= 4'd11;elsenum[15:12] <= 4'd10;endelse beginif (data1 || point[1]) beginnum[ 7: 0] <= {data1,data0};num[23:12] <= {3{4'd10}};if(sign)num[11:8] <= 4'd11;elsenum[11:8] <= 4'd10;endelse beginnum[3:0] <= data0;if(sign)num[23:4] <= {{4{4'd10}},4'd11};elsenum[23:4] <= {5{4'd10}};endendendendendend
end//计数 1ms
always @ (posedge dri_clk or negedge rst_n) beginif (rst_n == 1'b0) beginflag <= 1'b0;cnt0 <= 13'b0;endelse if (cnt0 < MAX_NUM - 1'b1) beginflag <= 1'b0;cnt0 <= cnt0 + 1'b1;endelse beginflag <= 1'b1;cnt0 <= 13'b0;end
end//计数器,用来计数 6 个状态(因为有 6 个灯)
always @ (posedge dri_clk or negedge rst_n) beginif (rst_n == 1'b0)cnt <= 3'b0;else if(flag) beginif(cnt < 3'd5)cnt <= cnt + 1'b1;elsecnt <= 3'b0;end
end//6 个数码管轮流显示,完成刷新( 从右到左)
always @ (posedge dri_clk or negedge rst_n) beginif(!rst_n) beginsel <= 6'b000000;num1 <= 4'b0;endelse beginif(en) begincase (cnt)3'd0: beginsel <= 6'b111110;num1 <= num[3:0] ;point1 <= ~point[0] ;end3'd1: beginsel <= 6'b111101;num1 <= num[7:4] ;point1 <= ~point[1] ;end3'd2: beginsel <= 6'b111011;num1 <= num[11:8];point1 <= ~point[2] ;end3'd3: beginsel <= 6'b110111;num1 <= num[15:12];point1 <= ~point[3] ;end3'd4: beginsel <= 6'b101111;num1 <= num[19:16];point1 <= ~point[4];end3'd5: beginsel <= 6'b011111;num1 <= num[23:20];point1 <= ~point[5];enddefault: beginsel <= 6'b000000;num1 <= 4'b0;point1 <= 1'b1;endendcaseendelsesel <= 6'b111111;end
end//数码管显示数据
always @ (posedge dri_clk or negedge rst_n) beginif (!rst_n)seg_led <= 7'h40;else begincase (num1)4'd0 : seg_led <= {point1,7'b1000000};4'd1 : seg_led <= {point1,7'b1111001};4'd2 : seg_led <= {point1,7'b0100100};4'd3 : seg_led <= {point1,7'b0110000};4'd4 : seg_led <= {point1,7'b0011001};4'd5 : seg_led <= {point1,7'b0010010};4'd6 : seg_led <= {point1,7'b0000010};4'd7 : seg_led <= {point1,7'b1111000};4'd8 : seg_led <= {point1,7'b0000000};4'd9 : seg_led <= {point1,7'b0010000};4'd10: seg_led <= 8'b11111111;4'd11: seg_led <= 8'b10111111;default : seg_led <= {point1,7'b1000000};endcaseend
endendmodule

寄存器文件segled register.v 

module segled_register(input clk, // 时钟信号input rst_n, // 复位信号(低有效)//Avalon-MM 接口input [ 1:0] avs_address, // Avalon 地址input avs_write, // Avalon 写请求input [31:0] avs_writedata, // Avalon 写数据//用户接口output reg [19:0] data, // 6 个数码管要显示的数值output reg [ 5:0] point, // 小数点显示的位置,从左到右,高电平有效output reg sign, // 显示符号位(高电平显示“-”号)output reg en // 数码管使能信号
);//*****************************************************
//** main code
//*****************************************************//用于给进行赋值
always @(posedge clk or negedge rst_n) beginif(!rst_n) begindata <= 20'd0; //显示数值寄存器point <= 6'd0; //小数点位置寄存器sign <= 1'b0; //符号使能寄存器en <= 1'b0; //显示使能寄存器endelse if(avs_write) begincase(avs_address)2'd0: //地址 0:显示数值寄存器data <= avs_writedata[19:0]; 2'd1: //地址 1:小数点位置寄存器point <= avs_writedata[5:0]; 2'd2: //地址 2:符号使能寄存器sign <= avs_writedata[0]; 2'd3: //地址 3:显示使能寄存器en <= avs_writedata[0];endcaseend
endendmodule

 4.1.2 使用IP核编辑器封装硬件逻辑

打开Platform Designer,选择New Component

Component Type中填入相关信息

Name(名称) 、Display name(显示名称)、Version(版本号) 、Group(分组) 、Description(描述) 、Created by(创建者) 、Icon(组件图标)、Documentation(组件文档连接)

 在Files中

首先点击Add File..将三个功能文件添加进来,如果没有选择顶层顶层文件还要在Attributesno attributes的设置顶层文件,然后点击Analyze Synthesis Files对三个文件进行分析

如果代码没有问题就会分析成功

但还是会报错,这些错误后悔会进行解决

 在 在Parameters页面中可以设置组件源码中定义的参数是否用户加载组件时可配置

在Signals&Interfaces中,

avalon_slave_0是Avalon-MM 总线的信号接口,Signals Type中要指定各个信号对应的类型

conduit_end是输出到Qsys系统外部的接口,是Qsys系统和外部接口的信号,通常是连接到FPGA引脚上的信号,它的 Signal Type 固定为 *(export)

clock_sink 为时钟信号,reset_sink 为复位信号

rst_n信号出现在了avalon_slave_0的interface中,这样就不能设置其Sign Type

 因此添加Reset Input,然后把rst_n拖动到该Interface中,然后将Sign Type选择为reset

 

 

同理添加Conduit Interface,将sel和sel_led拖入,点击conduit_end,设置其Associated Reset为reset_sink,然后再设置seg_led和sel的Sign Type为export

这里会有一个export信号类型问题,expert信号需要自定义名字,每个名字只能对应一个端口,需要给每个export分配不同名字

 同理设置avalon_slave的Associated Reset为reset_sink,至此就没有报错,点击下方finish生成自定义IP核

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/22475.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

CANOE 操作详情

canoe 手把手教你如何操作canoe工具&#xff1a; 1&#xff1a;创建test文件夹&#xff0c; 并在文件夹下创建3 文件夹 2&#xff1a;创建canoe工程&#xff0c;选择500波特率 3: 双击后进入 4&#xff1a;创建DBC文件 5 创建网络节点&#xff1a; 两个节点创建好之后&#x…

【力扣刷题 | 第十九天】

目录 前言&#xff1a; 135. 分发糖果 - 力扣&#xff08;LeetCode&#xff09; 860. 柠檬水找零 - 力扣&#xff08;LeetCode&#xff09; 总结&#xff1a; 前言&#xff1a; 今天着重刷贪心算法的题目 135. 分发糖果 - 力扣&#xff08;LeetCode&#xff09; n 个孩子…

SQL语法与数据库快速入门(1)

目录 数据库简介数据库分类常用数据库简介使用场景MySql 的安装与配置数据库客户端工具MySql 介绍SQL 简介DDL 数据库操作-创建DDL 数据库操作-查看DDL 数据库操作-修改DDL 数据库操作-删除DDL 数据库表操作简介DDL 数据库表操作-创建DDL 数据库表操作-查看DDL 数据库表操作-修…

explain 是干嘛的

explain 是干嘛的 1.explain的作用 在MySQL中&#xff0c;EXPLAIN是一个用于查询优化的关键字。它可以用于分析查询语句的执行计划&#xff0c;帮助开发人员和数据库管理员理解查询的执行方式、查询涉及的表和索引、连接类型、查询优化器的决策等信息。 通过使用EXPLAIN关键…

【基于FPGA的芯片设计】RISC-V的20条指令CPU设计

实验板卡&#xff1a;xc7a100tlc sg324-2L&#xff0c;共20个开关 实验要求&#xff1a;

psutil库使用详解

一、背景 在Python的世界里&#xff0c;有一些库因其强大的功能和易用性而备受开发者们的喜爱。今天&#xff0c;我们要介绍的就是其中的一员——psutil库。psutil(python system and process utilities)是一个跨平台的第三方库&#xff0c;用于获取系统运行时的进程和系统利用…

【数据结构】搜索二叉树/map/set

二叉搜索树&#xff08;搜索二叉树&#xff09; 1.1.二叉搜索树概念 二叉搜索树又称二叉排序树&#xff0c;它或者是一棵空树&#xff0c;或者是具有以下性质的二叉树: 若它的左子树不为空&#xff0c;则左子树上所有节点的值都小于根节点的值 若它的右子树不为空&#xff0c;则…

决策树(Decision Tree)

文章目录 一、决策树 一、决策树 决策树在机器学习中也是比较常见的一种算法&#xff0c;属于监督学习中的一种。看字面意思应该也比较容易理解&#xff0c;相比其他算法比如支持向量机(SVM)或神经网络&#xff0c;似乎决策树感觉“亲切”许多。 优点&#xff1a;计算复杂度不…

Web3与物联网行业:实现安全、可信与智能的连接

随着物联网技术的快速发展&#xff0c;我们正迎来一个高度互联、智能化的未来。而Web3作为互联网的下一次演进&#xff0c;将为物联网行业带来重要的变革。 本文将探讨Web3在物联网行业中的应用前景和优势&#xff0c;以及如何实现安全、可信和智能的连接。 第一部分&#xff…

QT Quick初学笔记---第一篇

链接: QML Book中文版(QML Book In Chinese) 1、对Qt Quick的初步认识 Qt Quick是Qt5界面开发技术的统称&#xff0c;是以下几种技术的集合&#xff1a; QML&#xff1a;界面标记语言JavaScript&#xff1a;动态脚本语言QT C&#xff1a;跨平台C封装库 QML是与HTML类似的一…

OpenCV 入门教程:中值滤波和双边滤波

OpenCV 入门教程&#xff1a;中值滤波和双边滤波 导语一、中值滤波二、双边滤波三、示例应用3.1 图像去噪3.2 图像平滑 总结 导语 在图像处理和计算机视觉领域&#xff0c;中值滤波和双边滤波是两种常见的滤波方法&#xff0c;用于平滑图像、去除噪声等。 OpenCV 提供了中值滤…

抖音seo矩阵系统源码|需求文档编译说明(技术)

1.抖音seo矩阵系统文档开发流程 抖音SEO矩阵指的是一系列通过搜索引擎优化&#xff08;SEO&#xff09;技术和策略来提升抖音账号在搜索结果中排名的方法和工具。在抖音上&#xff0c;用户可以通过搜索关键词来查找与其相关的视频和账号。因此&#xff0c;抖音SEO矩阵的主要目…