当前位置: 首页 > news >正文

NIOS2随笔——自定义IP(DPRAM)

  1. AVALON总线分类

在QSYS下,一个简单的组件包含了许多接口,它们实现了不同的功能,大致有下面几种:

Avalon-MM

Avalon-ST

Avalon Conduit

Avalon-TC

Avalon Interrupt

Avalon Clock.

这些标准是开源的,不需要license就可以开发使用。下图是一个总线应用的示意图:

wKioL1e0Gm3izts1AADLRaaI9b4776.jpg


2. AVALON MM总线

这里以AVALON MM为例,设计一个用户自定义的DPRAM组件,并用DMA方式将DPRAM PORTB中的数据搬移到内存SDRAM/DDR2中。下面接口定义是AVALON MM SLAVE总线的信号,具体时序在Avalon Interface Specifications中有详细描述。

1
2
3
4
5
6
7
8
9
10
11
//avalon MM slave
input avs_clk,
input avs_reset_n,
input avs_chipselect_n,
input [7:0] avs_address,
input [3:0] avs_byteenable,
input avs_write,
input [31 :0] avs_writedata,
input avs_read,
output avs_readdatavalid,
output [31 :0] avs_readdata


3. Qsys中添加自定义组件

1) 新建组件

wKioL1e0HgKxVwZ9AAB_gS4gy2M556.jpg

2)添加文件

wKioL1e0HmrjMx98AACHdhdzvHY121.jpg

3) 信号设置

wKiom1e0Hu7iMPy7AAC72yJKk4w782.jpg

4) 接口时序

wKioL1e0H2yzN8TvAACgJ_Ytcdw970.jpg


4. FPGA逻辑代码

下面是用户自定义的DPRAM的Verilog代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
//file name:       vid_dpram.v
//author:           shugen.yin
//date:             2016.8.15
//function:         user dpram for Qsys
//log: 
 
module vid_dpram(
     //user port
     input inclock,
     input [7:0] data,
     input data_valid,
     input vid_vsync,
     
     //avalon MM slave
     input avs_clk,
     input avs_reset_n,
     input avs_chipselect_n,
     input [7:0] avs_address,
     input [3:0] avs_byteenable,
     input avs_write,
     input [31 :0] avs_writedata,
     input avs_read,
     output avs_readdatavalid,
     output [31 :0] avs_readdata
);
 
parameter VID_WIDTH = 640;
 
 
reg avs_readdatavalid_r0;
reg avs_readdatavalid_r1;
 
reg [9:0] wraddress_0;
reg [9:0] wraddress_1;
 
reg rdaddress_high_bit;
reg wraddress_high_bit;
 
wire [10:0] wraddress;
 
wire [8:0] rdaddress;
assign rdaddress = (avs_chipselect_n==1 'b0)?{1' b0,avs_address[7:0]}:0;
     
 
wire rden;
assign rden = avs_read & ~avs_chipselect_n;   
     
dpram_01    dpram_01_inst (
     .data ( data ),
     .wrclock ( inclock ),
     .rdclock ( avs_clk ),
     .rden   (rden),
     .rdaddress ( rdaddress ),         //input [8:0]  rdaddress;
     .wraddress ( wraddress ),         //input [10:0]  wraddress;
     .wren (1'b0 ),
     .q ( avs_readdata )
     );
 
 
endmodule

dpram的PORT B端用HEX文件初始化(511~0循环递减):

wKioL1e0I2qxQE2bAABXOWoPIyQ715.jpg


5. NIOS2 源代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
#include <stdio.h>
#include <sys/unistd.h>
#include <string.h>
#include <sys/alt_irq.h>
#include "system.h"
#include "alt_types.h"
#include "altera_avalon_dma_regs.h"
#include "sys/alt_dma.h"
#include <sys/alt_cache.h>
 
 
#define DAT_LEN 640
 
unsigned  int  buffer0[DAT_LEN/4];
unsigned  int  *point=VID_DPRAM_0_BASE;
 
static  void  DMA_Init( void );  //初始化DMA
unsigned  int  dma_end_flag = 0;
 
alt_dma_txchan tx;
alt_dma_rxchan rx;
 
void  dma_done()
{
     dma_end_flag++;
}
 
static  void  DMA_Init( void )
{
     tx = alt_dma_txchan_open( "/dev/dma_0" );
 
     if (tx != NULL)
     {
         printf ( "DMA transition start\n" );
     }
 
     alt_dma_txchan_ioctl(tx,ALT_DMA_SET_MODE_32,NULL);
 
     //point是源地址、传输数据块长度是DAT_LEN
     alt_dma_txchan_send(tx, point, DAT_LEN, NULL, NULL);
 
     rx = alt_dma_rxchan_open( "/dev/dma_0" );
 
     alt_dma_rxchan_ioctl(rx,ALT_DMA_SET_MODE_32,NULL);
 
     //buffer0是目标地址、传输数据块长度是DAT_LEN、dma_done()是DMA完成后被调用的回调函数
     alt_dma_rxchan_prepare(rx, buffer0 , DAT_LEN, dma_done, NULL);
}
 
 
int  main()
{
     int  i;
 
     for (i=0;i<DAT_LEN/4;i++)
         buffer0[i] = 0;
 
//  alt_dcache_flush_all(); //if the nios2 core uses the cache
 
     DMA_Init();
     //等待中断结束,说明传输完成
     while (dma_end_flag == 0);
 
     alt_dma_txchan_close(tx);
     alt_dma_rxchan_close(rx);
 
     printf ( "\n============start===========\n" );
     
     //打印接收地址的数据
     for (i=0;i<DAT_LEN/4;i++)
     {
         printf ( "buffer0[%d]=%d\t" ,i,buffer0[i]);
     }
 
     printf ( "\n=============end===========\n" );
 
     return  0;
}


6. 运行结果

wKiom1e0JHHSssrhAADYzcNDodA880.jpg



本文转自 shugenyin 51CTO博客,原文链接:http://blog.51cto.com/shugenyin/1839613

相关文章:

  • Webpack入门教程十五
  • IPv6, DAD 工作原理详解
  • 解决configure: error: Please reinstall the libcurl distribution
  • tweak 支持第三方库
  • 第十一章 持有对象
  • 条件变量的接口函数和使用原则
  • C# DataGridView中DataGridViewComboBoxCell列,下拉框事件的处理【完美解决】
  • C# 中的枚举类型 enum (属于值类型)
  • jQuery选择器之表单对象属性过滤选择器Demo
  • Cloudera Mountable HDFS (hadoop-fuse-dfs).
  • linux reiserfs文件系统损坏后的数据恢复过程记录
  • 把一个用户的相关权限赋予另外一个用户
  • gets函数的不安性详解
  • Silverlight知识链接整理(11月-12月)
  • ORACLE 分区与索引
  • Create React App 使用
  • ES6系列(二)变量的解构赋值
  • golang中接口赋值与方法集
  • HTTP传输编码增加了传输量,只为解决这一个问题 | 实用 HTTP
  • input实现文字超出省略号功能
  • JavaScript工作原理(五):深入了解WebSockets,HTTP/2和SSE,以及如何选择
  • JDK 6和JDK 7中的substring()方法
  • JSONP原理
  • Laravel Mix运行时关于es2015报错解决方案
  • open-falcon 开发笔记(一):从零开始搭建虚拟服务器和监测环境
  • Python语法速览与机器学习开发环境搭建
  • Redux系列x:源码分析
  • SegmentFault 2015 Top Rank
  • spring + angular 实现导出excel
  • Spring思维导图,让Spring不再难懂(mvc篇)
  • Sublime Text 2/3 绑定Eclipse快捷键
  • 第2章 网络文档
  • 服务器从安装到部署全过程(二)
  • 经典排序算法及其 Java 实现
  • 入口文件开始,分析Vue源码实现
  • 算法---两个栈实现一个队列
  • 小程序开发之路(一)
  • 国内开源镜像站点
  • ​​​​​​​​​​​​​​Γ函数
  • ​软考-高级-系统架构设计师教程(清华第2版)【第15章 面向服务架构设计理论与实践(P527~554)-思维导图】​
  • ###C语言程序设计-----C语言学习(6)#
  • #HarmonyOS:软件安装window和mac预览Hello World
  • (10)工业界推荐系统-小红书推荐场景及内部实践【排序模型的特征】
  • (C语言)球球大作战
  • (html转换)StringEscapeUtils类的转义与反转义方法
  • (ZT)北大教授朱青生给学生的一封信:大学,更是一个科学的保证
  • (待修改)PyG安装步骤
  • (二)JAVA使用POI操作excel
  • (二开)Flink 修改源码拓展 SQL 语法
  • (附源码)springboot学生选课系统 毕业设计 612555
  • (十八)SpringBoot之发送QQ邮件
  • (十一)手动添加用户和文件的特殊权限
  • (转)总结使用Unity 3D优化游戏运行性能的经验
  • .net 4.0发布后不能正常显示图片问题
  • .NET 8 中引入新的 IHostedLifecycleService 接口 实现定时任务