[原创].怎样定制SRAM的Avalon接口IP,以供Nios II使用.[Memory][Nios II][Quartus II][SOPC Builder]
0赞测试环境
硬件:艾米电子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 addresses和System>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