在NIOS中自定义Component对SRAM进行访问

 模块架构:

 自定义Component:

(1)点击new component

 (2)在"Component Type"中为自己的component定义Group;

 (3)在"Files"中添加自己的.v文件,然后点击"Aanlyze Synthesis Files";

(4) 定义.v文件中的接口的类型以及接口参数;1、2、3、4分别为Avalon Slave端口,时钟接口,外部信号接口,复位接口;紫色框中需要将时钟和复位信号关联;Parameters设置需要注意Adress units;

(5)至此,Component所有参数全部设置完成,点击Finish,等待Component生成

系统各模块添加 :

如图,红色框中为自己定义的Component;该模块需要通过Avalon-MM连接到NIOS II(cpu);pio_irq用来检测ram写满信号上升沿以产生中断

 Verilog部分代码:

module	avs_sram_ctrl
(
	//sram port
	input		wire			user_rd_clk,
	output		wire			user_rd_req,
	output		wire	[15:0]	user_rd_addr,
	input		wire	[15:0]	user_rd_data,
	input		wire			user_rd_valid,
	
	//avalon-MM slave
	input		wire			avs_clk,
	input		wire			avs_rst_n,
	input		wire			avs_chipselect_n,	
	input		wire	[8:0]	avs_address,
	input		wire	[3:0]	avs_byteenable,
	input		wire			avs_read_req,
	output		wire			avs_read_valid,
	output		wire	[32:0]	avs_read_data,
	input		wire			avs_write_req,
	input		wire	[32:0]	avs_write_data	
);

assign	user_rd_req = (avs_chipselect_n==1'b0) ? avs_read_req : 1'b0;
assign	user_rd_addr = (avs_chipselect_n==1'b0) ? {7'd0,avs_address} : 16'd0;

assign	avs_read_valid = user_rd_valid;
assign	avs_read_data = user_rd_data;
endmodule

 软核部分代码:

在软核代码中,地址以4递增,是因为在自定义Component部分,Address units设置的为WORDS;内部地址每次递增4,自定义Component部分输出的user_rd_addr才会每次递增1

//该部分代码使用基地址+4进行访问

#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_pio_regs.h"
#include "sys/alt_dma.h"
#include <sys/alt_cache.h>

#define DATA_LEN 288 //读取数据数量

void irq_init();
void irq_execute();

unsigned int buffer[DATA_LEN];

int main()
{
  printf("Hello from Nios II!\n");

  int m=0;

  while(m<6)
  {
	  irq_init();
	  printf("1");
	  usleep(1*1000*100);
	  m++;
	  printf("%d\n",m);
  }
  printf("OK");
  return 0;
}

void irq_init(void)
{
	IOWR_ALTERA_AVALON_PIO_IRQ_MASK(PIO_IRQ_BASE,0x01);//使能中断
	alt_ic_isr_register(PIO_IRQ_IRQ_INTERRUPT_CONTROLLER_ID, PIO_IRQ_IRQ, irq_execute,NULL,0x00);
}

void irq_execute(void)
{
	int i;
	int j;
	int n=0;
	unsigned int base_addr=AVS_SRAM_CTRL_BASE;//读取地址
//  unsigned int * base_addr=AVS_SRAM_CTRL_BASE;//此处将base_addr定义为指针类型
	for(j=0;j<DATA_LEN;j++)
	{
		buffer[j]=IORD_16DIRECT(base_addr,0);//IORD_16DIRECT()读取sram中的数据;
		base_addr = base_addr + 4; //当base_addr为unsigned时每次递增4
//      base_addr = base_addr + 1; //当base_addr为指针时,每次递增1
	}

	printf("\n====Start print data====\n");

	for(i=0;i<DATA_LEN;i++)
	{
		printf("buffer[%d]=%d\t",i,buffer[i]);
	}

	printf("\n====End print data====\n");
	IOWR_ALTERA_AVALON_PIO_EDGE_CAP(PIO_IRQ_BASE,0x00);//清中断边沿寄存器
}

//该部分代码使用偏移地址+4进行访问

#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_pio_regs.h"
#include "sys/alt_dma.h"
#include <sys/alt_cache.h>

#define DATA_LEN 288 //读取数据数量

void irq_init();
void irq_execute();

unsigned int buffer[DATA_LEN];

int main()
{
  printf("Hello from Nios II!\n");

  int m=0;

  while(m<6)
  {
	  irq_init();
	  printf("1");
	  usleep(1*1000*100);
	  m++;
	  printf("%d\n",m);
  }
  printf("OK");
  return 0;
}

void irq_init(void)
{
	IOWR_ALTERA_AVALON_PIO_IRQ_MASK(PIO_IRQ_BASE,0x01);//使能中断
	alt_ic_isr_register(PIO_IRQ_IRQ_INTERRUPT_CONTROLLER_ID, PIO_IRQ_IRQ, irq_execute,NULL,0x00);
}

void irq_execute(void)
{
	int i;
	int j=0;
	int n=0;
    unsigned int base_addr = AVS_SRAM_CTRL_BASE;

    for(j=0;j<DATA_LEN;j++)
	{
		buffer[j]=IORD_16DIRECT(base_addr ,n);//IORD_16DIRECT()读取sram中的数据;
		n=n+4;
	}

	printf("\n====Start print data====\n");

	for(i=0;i<DATA_LEN;i++)
	{
		printf("buffer[%d]=%d\t",i,buffer[i]);
	}

	printf("\n====End print data====\n");

	IOWR_ALTERA_AVALON_PIO_EDGE_CAP(PIO_IRQ_BASE,0x00);//清中断边沿寄存器
}

 数据打印:

 使用singal tap进行数据抓取:

(1)软核中,如果IORD_16DIRECT()地址以2递增,波形如下,可以发现:输出的user_rd_addr前后两次都是19

(2)软核代码中,读取地址如果以4递增,波形如下,可以发现:输出的user_rd_addr递增1

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值