安德鲁

[原创].怎样定制SRAM的Avalon接口IP,以供Nios II使用.[Memory][Nios II][Quartus II][SOPC Builder]

0
阅读(19852)

测试环境

硬件:艾米电子EP2C8核心板

软件:Quartus II 10.0 + Nios II 10.0 Software Build Tools for Eclipse

 

内容

1 定制SRAM的Avalon接口IP

关于SRAM的特性,请参考相关手册,此处不赘述。

 

1.1 使用HDL描述接口

代码1.1 Amy_S_sram.v

	module Amy_S_sram

	#(
parameter DATA_LEN = 16,
 parameter ADDR_LEN = 18
(
 input                     csi_clk,
input                     csi_reset_n,
 //
 input  [(ADDR_LEN-1)  :0] avs_address,
 input  [(DATA_LEN/8-1):0] avs_byteenable_n,
 input                     avs_write_n,
 input  [(DATA_LEN-1)  :0] avs_writedata,
 input                     avs_read_n,
 output [(DATA_LEN-1)  :0] avs_readdata, 
//                         
 inout  [(DATA_LEN-1)  :0] coe_SRAM_DQ,      // SRAM Data bus 16 Bits
output [(ADDR_LEN-1)  :0] coe_SRAM_ADDR,    // SRAM Address bus 18 Bits
output                    coe_SRAM_LB_N,    // SRAM Low-byte Data Mask
output                    coe_SRAM_UB_N,    // SRAM High-byte Data Mask
 output                    coe_SRAM_CE_N,    // SRAM Chip chipselect
 output                    coe_SRAM_OE_N,    // SRAM Output chipselect
output                    coe_SRAM_WE_N     // SRAM Write chipselect
);
	 
assign coe_SRAM_DQ   = coe_SRAM_WE_N ? 'hz : avs_writedata;
assign avs_readdata  = coe_SRAM_DQ;
assign coe_SRAM_ADDR = avs_address;
assign coe_SRAM_WE_N = avs_write_n;
assign coe_SRAM_OE_N = avs_read_n;
assign coe_SRAM_CE_N = avs_read_n & avs_write_n;
assign {coe_SRAM_UB_N, coe_SRAM_LB_N} = avs_byteenable_n;
 
endmodule
   

第2~5行,参数化数据总线和地址总线的宽度。我所测试的板子,板载SRAM配置如下;读者,若是使用其他的SRAM,可在SOPC Builder中例化的时候,自行填下参数即可。

1 #(
2   parameter DATA_LEN = 16,
3   parameter ADDR_LEN = 18
4 )

 

第26~27行,此处为处理双向口的惯用做法。当coe_SRAM_WE_N为低时,coe_SRAM_DQ输入avs_writedata,否则则输入高阻。

1 assign coe_SRAM_DQ   = coe_SRAM_WE_N ? 'hz : avs_writedata;
2 assign avs_readdata  = coe_SRAM_DQ;

 

第31行,关于片选信号chipselect,在Avalon接口规范9.1之后,这个信号被拿掉了。那现在如何描述呢,我们根据表1.1和1.2,推出如何使用write(write_n)和read(read_n)来描述。

 

表1.1 低电平有效的情况

read_n write_n 片选_n
0 0 有效
0 1 有效
1 0 有效
1 1 无效

 

由表1.1,(片选_n == 0)= read_n & write_n。因此当片选是低电平有效时,使用下面的语句描述。

1 assign coe_SRAM_CE_N = avs_read_n & avs_write_n;

 

表1.2 高电平有效的情况

read write 片选
0 0 无效
0 1 有效
1 0 有效
1 1 有效

 

由表1.2,(片选 == 1)= read | write。

 

第32行,将SRAM的高位使能和低位使能拼接到一起(注意顺序),接受avs_byteenable_n的赋值。一般情况下,Avalon-MM 默认的writedata(readdata与之一致)数据位宽是32位。其他情况下,则需要使用byteenable来限定字节,以分段传输。关于 byteenable的属性,请参考Avalon Interface Specification。

1 assign {coe_SRAM_UB_N, coe_SRAM_LB_N} = avs_byteenable_n;

 

关于Avalon信号的命名规范,请参考表1.3。按照规范命名,会减少许多不必要的麻烦。

 

表1.3 Avalon信号的命名规范

 

 

1.2 添加到SOPC Builder的组件库中

 

打开SOPC Builder,选择File>New Component,打开组件编辑器。选择HDL Files>Add,添加Avalon接口文件和逻辑文件(此处仅有接口文件)。


图1.1 添加HDL文件

 

观察信号是否正确;若不正确,适当修改HDL文件。由于我所写的HDL文件,信号是严格按照规范来命名的,因此其Interface选项内的接口是自动生成的,不必在手动编辑。


图1.2 Avalon接口信号

 

选择Interfaces>avalon_slave_0>Deprecated,因为SRAM是 易失型存储器,因此需要选中Memory Device,其他选项全部默认。如果Memory Device不被选中的话,在cpu的选项中,将无法选择此SRAM。我估计,Altera之所以将此选项命名为Deprecated,实际上是提醒我们 谨慎使用。在没有这种GUI的情况下,使用tcl语言手动描述也是可以的。


图1.3 Memory device选项

 

Library Info主要用于管理和区分IP。


图1.4 Library Info

 

单击Finish后,该IP就会出现在SOPC Builder左面的组件库中,即可供以后使用。

 

 

2 在SRAM上运行Nios II软核

2.1 硬件部分

2.1.1 在SOPC Builder自定义Nios II软核系统

定制含以下组件的Nios II软核系统,命名为nios_core。其中sysid和timer虽然不是必须,但是加入后,可在Nios II EDS中的下载配置时,减少麻烦;其功用暂时不再赘述。由于使用的SRAM是256Kx16位,因此其数据总线宽度为16,地址总线宽度为18。配置完组 件后,如图2.6,分别选择System>Auto assign base addressesSystem>Auto assign IRQs,来自动分配虚拟地址和中断号。

 


图2.1 组件一览


图2.2 cpu选项的配置


图2.3 timer的配置


图2.4 SRAM的配置


图2.5 配置PIO,测试板载LED


图2.6 自动分配虚拟地址和中断号

 

点击Generate,生成Nios II软核系统。

 

2.1.2 在Quartus II综合

2.1.2.1 描述顶层模块

打开nios_core_inst.v,根据该Nios II软核系统例化模板文件,编辑顶层文件nios_sram.v。

代码2.1 nios_core_inst.v(Nios II软核系统例化模板文件)

01 //Example instantiation for system 'nios_core'
02 nios_core nios_core_inst
03   (
04     .clk_50                           (clk_50),
05     .coe_SRAM_ADDR_from_the_sram      (coe_SRAM_ADDR_from_the_sram),
06     .coe_SRAM_CE_N_from_the_sram      (coe_SRAM_CE_N_from_the_sram),
07     .coe_SRAM_DQ_to_and_from_the_sram (coe_SRAM_DQ_to_and_from_the_sram),
08     .coe_SRAM_LB_N_from_the_sram      (coe_SRAM_LB_N_from_the_sram),
09     .coe_SRAM_OE_N_from_the_sram      (coe_SRAM_OE_N_from_the_sram),
10     .coe_SRAM_UB_N_from_the_sram      (coe_SRAM_UB_N_from_the_sram),
11     .coe_SRAM_WE_N_from_the_sram      (coe_SRAM_WE_N_from_the_sram),
12     .out_port_from_the_pio            (out_port_from_the_pio),
13     .reset_n                          (reset_n)
14   );

 

代码2.2 nios_sram.v(Quartus II顶层模块)

01 module nios_sram(
02   input         CLOCK_50,
03   input         Q_KEY,
04   output        Q_LED,
05   //
06   output [17:0] SRAM_ADDR,
07   output        SRAM_CE_N,
08   inout  [15:0] SRAM_DQ,
09   output        SRAM_LB_N,
10   output        SRAM_OE_N,
11   output        SRAM_UB_N,
12   output        SRAM_WE_N
13 );
14  
15 nios_core nios_core_inst
16 (
17   .clk_50                           (CLOCK_50),
18   //
19   .coe_SRAM_ADDR_from_the_sram      (SRAM_ADDR),
20   .coe_SRAM_CE_N_from_the_sram      (SRAM_CE_N),
21   .coe_SRAM_DQ_to_and_from_the_sram (SRAM_DQ),
22   .coe_SRAM_LB_N_from_the_sram      (SRAM_LB_N),
23   .coe_SRAM_OE_N_from_the_sram      (SRAM_OE_N),
24   .coe_SRAM_UB_N_from_the_sram      (SRAM_UB_N),
25   .coe_SRAM_WE_N_from_the_sram      (SRAM_WE_N),
26   //
27   .out_port_from_the_pio            (Q_LED),
28   .reset_n                          (Q_KEY)
29 );
30  
31 endmodule

 

2.1.2.2 配置引脚相关

在Quartus II中,打开Assignments>Device>Device and Pin Options>Unused Pins选项,配置未用引脚为三态输入。


图2.7 配置未用管脚

 

打开Assignments>Device>Device and Pin Options>Configuration选项,选择配置芯片为EPCS4。


图2.8 选择配置芯片

 

使用文本编辑软件(如Notepad++),按以下格式,编写待分配引脚的映射文件,保存为pins’ list.txt。

01 To,                 Location
02  
03 // 板载50MHz时钟
04 CLOCK_50,           PIN_23
05  
06 // 板载按键RST(亦可不做复位用)
07 Q_KEY,              PIN_129
08  
09 // 板载LED
10 Q_LED,              PIN_199
11  
12 // SRAM
13 SRAM_DQ[0],         PIN_82
14 SRAM_DQ[1],         PIN_84
15 SRAM_DQ[2],         PIN_80
16 SRAM_DQ[3],         PIN_81
17 SRAM_DQ[4],         PIN_76
18 SRAM_DQ[5],         PIN_77
19 SRAM_DQ[6],         PIN_74
20 SRAM_DQ[7],         PIN_75
21 SRAM_DQ[8],         PIN_188
22 SRAM_DQ[9],         PIN_189
23 SRAM_DQ[10],        PIN_185
24 SRAM_DQ[11],        PIN_187
25 SRAM_DQ[12],        PIN_181
26 SRAM_DQ[13],        PIN_182
27 SRAM_DQ[14],        PIN_179
28 SRAM_DQ[15],        PIN_180
29 SRAM_ADDR[0],       PIN_92
30 SRAM_ADDR[1],       PIN_90
31 SRAM_ADDR[2],       PIN_88
32 SRAM_ADDR[3],       PIN_89
33 SRAM_ADDR[4],       PIN_86
34 SRAM_ADDR[5],       PIN_72
35 SRAM_ADDR[6],       PIN_68
36 SRAM_ADDR[7],       PIN_69
37 SRAM_ADDR[8],       PIN_64
38 SRAM_ADDR[9],       PIN_67
39 SRAM_ADDR[10],      PIN_197
40 SRAM_ADDR[11],      PIN_198
41 SRAM_ADDR[12],      PIN_193
42 SRAM_ADDR[13],      PIN_195
43 SRAM_ADDR[14],      PIN_191
44 SRAM_ADDR[15],      PIN_173
45 SRAM_ADDR[16],      PIN_169
46 SRAM_ADDR[17],      PIN_170
47 SRAM_WE_N,          PIN_70
48 SRAM_CE_N,          PIN_87
49 SRAM_OE_N,          PIN_171
50 SRAM_UB_N,          PIN_176
51 SRAM_LB_N,          PIN_175

 

打开Assignments>import Assignments选项,导入引脚映射文件。


图2.9 导入引脚映射文件

2.1.2.3 编译下载

编译及调试。编程与配置FPGA目标芯片。

 

2.2软件部分

2.2.1 在Nios II 10.0 Software Build Tools for Eclipse,打开New>Nios II Application and BSP from Template选项,使用模板新建软件工程。此处选择hello_world作为软件测试模板,命名工程为hello_world。


图2.10 选择Hello World模板

 

右键hello_world工程,选择Build Project,编译此工程。

 

编译完毕后,右键hello_world工程,选择Run as>Nios II Hardware,运行此C程序。

 

如果以上各步都正确,则会出现下面的效果。


图2.11 打印hello world

 

参考

1. [原创].怎样制作一个简单ip,以方便在Quartus II和Nios II中使用?.[Nios II][Quartus II][SOPC Builder]

2. Altera.Avalon Interface Specifications