FPGA实现Avalon-MM接口通信

news2025/1/21 3:02:14

        在Avalon总线协议(一)和Avalon总线协议(二)中大概了解Avalon总线的几种类型,目前比较常用到的就是Avalon-MM接口了,虽然在概念中有那么多的属性,但是具体使用起来还是非常简单的。

一、Avalon-MM

        前面提到过Avalon总线常用于 用户自定义的逻辑 与 NIOS Ⅱ处理器 之间进行通信,再通俗一点的理解就是硬件(Verilog代码)和软件(Nios Ⅱ处理器)进行数据交互。Nios Ⅱ作为主端口(Master),而Verilog代码模块实现了从端口(Slave),比如在Verilog代码中写了一个计数器,而Nios想要知道这个计数器的值,那么就可以在Verilog代码中定义一个寄存器,该寄存器具有与之相对应的地址,Nios Ⅱ可以根据地址对这个寄存器的值进行读取或者写入,这就是Avalon-MM协议。

如图,Verilog代码中定义了三个寄存器,分别是REG1、REG2、REG3,偏移量分别是OFFSET1、OFFSET2、OFFSET3;

当这一部分Verilog代码作为自定义组件加入到NIOS中并进行编译后,会自动产生BASE;

这时候寄存器的地址和偏移量就都有了,那么NIOS就可以对寄存器中的数据进行读写,从而实现通信!

二、NIOS常用函数

在NIOS中有一些已经定义好的函数方便去对数据进行操作

最常用的肯定是IORD()、IOWR()以及对PIO操作的IORD_ALTERA_AVALON_PIO_DATA()、IOWR_ALTERA_AVALON_PIO_DATA()

其实都一样>-<,IORD_ALTERA_AVALON_PIO_DATA()还是调用的IORD()

IORD(BASE, OFFSET)
//BASE为寄存器的基地址,OFFSET为寄存器的偏移量
//从基地址为BASE的设备中读取寄存器中偏移量为OFFSET的单元里面的值

IOWR(BASE, OFFSET, DATA)
//BASE为寄存器的基地址,OFFSET为寄存器的偏移量,DATA为要写入的数据
//向基地址为BASE的设备偏移量为OFFSET寄存器中写入数据DATA

IORD_ALTERA_AVALON_PIO_DATA(BASE)
//BASE为寄存器的基地址
//向基地址为BASE的设备中读取数

IOWR_ALTERA_AVALON_PIO_DATA(BASE, DATA)
//BASE为寄存器的基地址,DATA为要写入的数据
//向基地址为BASE的设备中写入数据DATA

其他NIOS函数可以参考:NIOS常用函数详解-CSDN博客

三、Avalon-MM实现

其实已经在前面的文章中实现过了,只不过没有较为详细的解释:

SOPC之NIOS Ⅱ实现电机转速PID控制_STATEABC的博客-CSDN博客

就用其中的电机PWM控制模块作为例子

3.1 硬件部分

module MOTOR_PWM(
	input						clk,
	input						reset_n,
	//Avalon-MM输入输出
	input						avalon_cs,			// 片选信号,进行数据操作时自动置为1
	input		[2:0]			avalon_address,		// 基地址,位宽根据要定义的寄存器个数
	input						avalon_write,		// 写入信号
	input		[31:0]			avalon_writedata,	// 写入数据
	input						avalon_read,		// 读取信号
	output  reg	[31:0]			avalon_readdata,	// 读取数据
	
	input	signed [31:0]		Speed,
	output	reg					PWM,
	output	reg					IN1,
	output	reg					IN2
);

reg            pwm_tem;
reg     [31:0] total;       // 总时间
reg     [31:0] high;        // 高位时间
reg     [31:0] count;            // 计数器

/
// 定义寄存器的偏移量,两种写法都可以
localparam REGISTER_TOTAL_DUR	= 0;

`define REGISTER_HIGH_DUR      2'd1


/
// Avalon-MM通信
always @(posedge clock or negedge reset_n)
begin
    if (~reset_n)
    begin
        high <= 0;
        total <= 0;
    end
    // 当片选信号和写入信号有效,反映在软件上就是执行了IOWR()
    else if (avalon_cs & avalon_write)
    begin
        if (avalon_address == REGISTER_TOTAL_DUR)			// 当地址等于0,即REGISTER_TOTAL_DUR
            total <= avalon_writedata;						// avalon_writedata为IOWR()写入的DATA值
        else if (avalon_address == `REGISTER_HIGH_DUR)
            high <= avalon_writedata;
    end
    // 当片选信号和读取信号有效,反映在软件上就是执行了IORD()
    else if (select_cs & select_read)
    begin
        if (avalon_address == `REGISTER_TOTAL_DUR)			// 当地址等于0,即REGISTER_TOTAL_DUR
            select_readdata <= total;						// avalon_writedata为IORD()的返回值
        else if (avalon_address == `REGISTER_HIGH_DUR)
            select_readdata <= high;
    end    
end
 
/
// 进行PWM输出
always @(*)
begin
    if (Speed>0) begin
    	{IN1, IN2, PWM} <= {1'b1, 1'b0, pwm_tem};
    end
    else begin
    	{IN1, IN2, PWM} <= {1'b1, 1'b0, pwm_tem};
    end
end
 
always @(posedge clock or negedge reset_n)
begin
    if (~reset_n)
    begin
        count <= 1;
    end
    else if (count >= total)
    begin
        count <= 1;
    end
    else
        count <= count + 1;
end
 
always @(posedge clock)
begin
    pwm_tem <= (count <= high) ? 1'b1 : 1'b0;
end
 
endmodule

将其作为自定义组件加入NIOS系统中并进行编译

3.2 软件部分

硬件部分进行全编译后,生成的systm.h文件中会包含其BASE信息

然后就可以根据BASE和OFFSET进行数据的读取

#include <stdio.h>
#include <stdlib.h>
#include "system.h"
#include "altera_avalon_pio_regs.h" //IOWR_ALTERA_AVALON_PIO_DATA

int main()
{    
    int high,total;
    //写入数据
    IOWR(MOTOR_PWM_BASE,0,2000);
    IOWR(MOTOR_PWM_BASE,1,1000);
    //读取数据
    total = IORD(MOTOR_PWM_BASE,0);
    high  = IORD(MOTOR_PWM_BASE,1);

    printf("total= %d\r\n", total);
    printf("high = %d\r\n", hight);
   
    return 0;
}

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

《QT从基础到进阶·三十二》Q指针和D指针用法

二进制兼容&#xff1a; 如果程序从一个以前版本的库动态链接到新版本的库之后&#xff0c;能够继续正常运行&#xff0c;而不需要重新编译&#xff0c;那么我们就说这个库是二进制兼容的。&#xff08;通常只要dll的头文件总字节数不变基本满足二进制兼容&#xff0c;pimpl设计…

前端js面试题 (四)

文章目录 ES6新增的proxy手写&#xff0c;proxy访问某对象输出别的数字深度拷贝&#xff0c;为啥无法使用JSON.parse(JSON.stringify(obj))异步编程有哪些&#xff0c;async await来由&#xff0c;本质原理是什么事件队列输出题第一题第二题第三题 粘性布局的原理&#xff0c;以…

2023 年 数维杯(D题)国际大学生数学建模挑战赛 |数学建模完整代码+建模过程全解全析

大家面临着复杂的数学建模问题时&#xff0c;你是否曾经感到茫然无措&#xff1f;作为2022年美国大学生数学建模比赛的O奖得主&#xff0c;我为大家提供了一套优秀的解题思路&#xff0c;让你轻松应对各种难题。 让我们来看看数维杯D题&#xff01; 问题一&#xff1a;最佳清…

软件外包开发设计文档的编写

编写软件设计文档是软件开发过程中至关重要的一步&#xff0c;下面是一些在编写软件设计文档时需要注意的问题&#xff0c;通过注意这些问题&#xff0c;可以确保软件设计文档是清晰、完整且易于理解的&#xff0c;为整个开发团队提供有力的指导。北京木奇移动技术有限公司&…

candence出现no connect property onpin,,,,错误,该怎么办?

原因是上面有引脚添加了 属性no connect&#xff0c;但依然连接了网络&#xff0c;这个时候需要把线剪切&#xff0c;然后看到引脚上有个X, 解决方法&#xff1a; 工具栏&#xff02;place >no connect "X 再连上线&#xff0c;再生成网标的时候&#xff0c; 就不报错了…

【实施】Sentry-self-hosted部署

Sentry-self-hosted部署 介绍 Sentry 是一个开源的错误追踪&#xff08;error tracking&#xff09;平台。它主要用于监控和追踪应用程序中的错误、异常和崩溃。Sentry允许开发人员实时地收集和分析错误&#xff0c;并提供了强大的工具来排查和修复问题&#xff0c;研发最近是…

MCTS蒙特卡洛树搜索(The Monte Carlo Tree Search)

1、简介 蒙特卡罗树搜索是一类树搜索算法的统称&#xff0c;简称MCTS。它是一种用于某些决策过程的启发式搜索算法&#xff0c;且在搜索空间巨大的游戏中会比较有效。从全局来看&#xff0c;蒙特卡洛树搜索的主要目标是&#xff1a;给定一个游戏状态来选择最佳的下一步。等常见…

AD教程 (十六)常用PCB封装的直接调用

AD教程 &#xff08;十六&#xff09;常用PCB封装的直接调用 打开已经做好的PCB文件 点击设计&#xff0c;生成PCB库&#xff0c;会自动把PCB里所用到的所有封装&#xff0c;全部自动生成 CtrlA 将所有元器件的封装全部选中&#xff08;或者只选中所需要的&#xff09;&#x…

Java相关编程思想

少用继承多用“组合”——在现有类的基础上组织一个新类。 2.继承要用“is”来检验&#xff0c;如果继承者is被继承者&#xff0c;说明这是一个比较好的继承。 3.向上造型&#xff0c;把实现方法留给继承者去实现。&#xff08;动态绑定&#xff09; 4.把接口理解为抽象类的进一…

windows安装gdal库

提示&#xff1a;在windows上使用pip在cmd终端安装gdal 文章目录 前言一、pandas是什么&#xff1f;二、使用步骤 1.引入库2.读入数据总结 前言 提示&#xff1a;这里可以添加本文要记录的大概内容&#xff1a; 原因是由于丹丹安装使用pip安装gdal时报错Microsoft visual C 1…

编码器脉冲信号测量2路DI高速计数器PNP/NPN转RS-485数据采集模块 解码转换成标准Modbus RTU协议 YL150-485

特点&#xff1a; ● 编码器解码转换成标准Modbus RTU协议 ● 可用作编码器计数器或者转速测量 ● 支持编码器计数&#xff0c;可识别正反转 ● 也可以设置作为2路独立DI高速计数器 ● 计数值支持断电自动保存 ● DI输入支持PNP和NPN输入 ● 继电器和机械开关输入时可以…

几个测试接口的好工具,效率加倍~

作为一名后端程序员&#xff0c;一定要对自己写的接口负责&#xff0c;保证接口的正确和稳定性。因此&#xff0c;接口测试也是后端开发中的关键环节。 但我相信&#xff0c;很多朋友是懒得测试接口的&#xff0c;觉得这很麻烦。一般自己写的接口自己都不调用&#xff0c;而是…

【博客系统】 二

本文主要介绍了linux和如何在云服务器上部署一个简单的servlet程序. 一.云服务器 真正搞一个网站,是希望这个网站被其他人访问到 , 所以需要一个云服务器(具有外网ip)来让别人也可以访问 云服务器 操作系统是Linux(一般都是通过命令行来操作) 当前市面上常见的系统: 1.windo…

共享WiFi贴项目商业新模式,到底能不能做

共享WiFi贴的模式&#xff0c;已经在众多商业圈和线下商家门店中引起关注&#xff0c;创造出了一种新的共享互联网商业模式。然而这种共享模式到底能不能做&#xff0c;从中创业者可以获得多少的商业价值呢&#xff1f;让我们一文深度解析一下。 共享WiFi贴&#xff0c;简单来说…

052-第三代软件开发-系统监测

第三代软件开发-系统监测 文章目录 第三代软件开发-系统监测项目介绍系统监测 关键字&#xff1a; Qt、 Qml、 cpu、 内存、memory 项目介绍 欢迎来到我们的 QML & C 项目&#xff01;这个项目结合了 QML&#xff08;Qt Meta-Object Language&#xff09;和 C 的强大功…

智能制造中后期:深挖成本、提升效率的关键——标准工时

在智能制造的背景下&#xff0c;企业面临着持续的成本压力和效率提升的需求。特别是在智能制造的中后期&#xff0c;要想进一步深挖成本、提升效率&#xff0c;必须考虑标准工时这一重要因素。标准工时作为一种基础而富有价值的管理工具&#xff0c;对于建立领先的标准工时系统…

PPP协议_基础知识

ppp协议 点对点协议PPP(Point-to-Point Protocol)是目前使用最广泛的点对点数据链路层协议。 一.ppp协议的组成 PPP协议为在点对点链路传输各种协议数据报提供了一个标准方法&#xff0c;主要由以下三部分构成: 对各种协议数据报的封装方法(封装成帧)链路控制协议LCP    …

【机器学习】 特征工程:特征预处理,归一化、标准化、处理缺失值

特征预处理采用的是特定的统计方法&#xff08;数学方法&#xff09;将数据转化为算法要求的数字 1. 数值型数据 归一化&#xff0c;将原始数据变换到[0,1]之间 标准化&#xff0c;数据转化到均值为0&#xff0c;方差为1的范围内 缺失值&#xff0c;缺失值处理成均值、中…

前后端联调时JS数据精度问题的解决

在JavaScript中&#xff0c;Number类型范围 -2^53 1 到 2^53 - 1&#xff0c;而在Java中Long类型的取值范围是 -2^63 1 到 2^63 - 1, 比JavaScript中大很多&#xff0c;所以后端能正常处理。 其实 ES6 引入了 Number.MAX_SAFE_INTEGER 和 Number.MIN_SAFE_INTEGER 这两个常量…

开源与闭源:驾驭大模型未来的关键决断

在数字化的时代洪流中&#xff0c;开源与闭源的选择不断成为技术界的重要分水岭。随着特斯拉CEO埃隆马斯克的言论及其决策&#xff0c;公开支持开源&#xff0c;并糅合商业理念与技术革新&#xff0c;使得这场辩论再次成为公众关注的焦点。那么&#xff0c;在这场关乎技术发展脉…