407
阿里云
技术社区[云栖]
怎样制作一个简单ip,以方便在Quartus II和Nios II中使用?.[Nios II][上]
概述:此处,我以Lcd12864(ST7920)作为范例,进行粗浅讲解,望各位网友踊跃拍砖。
0 软硬件环境
软件:Altera Quartus II 9.1 + Nios II 9.1 Software Build Tools for Eclipse
硬件:艾米电子EP2C8开发板(EP2C8Q208C8 + 16 bit SDRAM 64MB + EPCS4)
1 硬件部分
1.1 Avalon-MM接口(读作:阿窝龙妹妹接口)
Avalon Memory-Mapped接口,简称为 Avalon-MM接口,用于在存储映射系统中描述主从元件(component)的读/写接口。

图1.1 Amy_S_lcd12864 IP与System Interconnect Fabric的连线框图

图1.2 某带有Amy_S_lcd12864 IP的Avalon系统框图
1.2 从设备读写时序
请参考手册《Avalon Interface Specification》,此处略去。
1.3 HDL模块及说明
1.3.1 模块介绍
表1.1 Amy_S_lcd12864 IP的HDL源代码模块介绍
文件名称 |
功能描述 |
Amy_S_lcd12864_avalon_interface.v |
Amy_S_lcd12864 Avalon接口文件 |
1.3.2 源代码
注:本文所涉及verilog代码,是按照Verilog 2001规范编写的。Avalon信号类型命名参考图1.3。

图1.3 Naming Convention for Avalon Signal Type
1.3.2.1 Amy_S_lcd12864_avalon_interface.v
005
|
*
QQ(邮箱):amy-studio@qq.com
|
007
|
*
文件名称:Amy_S_lcd12864_avalon_interface.v
|
009
|
*
描述:Lcd12864的Avalon接口描述文件
|
023
|
module Amy_S_lcd12864_avalon_interface(
|
028
|
input avs_chipselect,
|
029
|
input [1:0]
avs_address,
|
031
|
input [31:0]
avs_writedata,
|
033
|
output [31:0]
avs_readdata,
|
035
|
//
lcd12864 interface
|
039
|
inout [7:0]
coe_data_io
|
042
|
//++++++++++++++++++++++++++++++++++++++
|
044
|
//++++++++++++++++++++++++++++++++++++++
|
045
|
reg [7:0]
coe_data_o;
|
047
|
always @( posedge csi_clk, negedge csi_reset_n)
|
056
|
else if (avs_chipselect
& avs_write)
|
059
|
0:
coe_e <= avs_writedata[0];
|
060
|
1:
coe_rw <= avs_writedata[0];
|
061
|
2:
coe_rs <= avs_writedata[0];
|
062
|
3:
coe_data_o <= avs_writedata[7:0];
|
066
|
//--------------------------------------
|
068
|
//--------------------------------------
|
070
|
//++++++++++++++++++++++++++++++++++++++
|
072
|
//++++++++++++++++++++++++++++++++++++++
|
073
|
reg [7:0]
readdata_r;
|
074
|
wire [7:0]
coe_data_i;
|
076
|
always @( posedge csi_clk)
|
077
|
if (avs_chipselect
& avs_read)
|
079
|
if (avs_address
== 3)
|
080
|
readdata_r
<= coe_data_i;
|
087
|
assign avs_readdata
= { 24'b0 ,
readdata_r};
|
088
|
//--------------------------------------
|
090
|
//--------------------------------------
|
093
|
//++++++++++++++++++++++++++++++++++++++
|
095
|
//++++++++++++++++++++++++++++++++++++++
|
098
|
always @( posedge csi_clk)
|
099
|
if (avs_chipselect
& avs_write)
|
100
|
coe_data_o_en
<= 1'b0 ;
|
101
|
else if (avs_chipselect
& avs_read)
|
102
|
coe_data_o_en
<= 1'b1 ;
|
104
|
assign coe_data_i
= coe_data_io;
|
105
|
assign coe_data_io
= coe_data_o_en ? 8'bz :
coe_data_o;
|
106
|
//--------------------------------------
|
108
|
//--------------------------------------
|
1.3.3 一些说明
ST7920的E、RW和RS都是单向的,而DATA总线是双向的;故在此处nios既需要写数据给ST7920,又需要从ST7920读数据。
从42行到68行,即nios向ST7920写数据。注意,谁给nios写数据呢?请看图1.4。

图1.4 NII、nios cpu和ST7920通信框图
从70行到90行,是nios从ST7920读数据。由于只有DATA总线需要读,其他的管脚就不写了,呵呵。
从93行到108行,是对DATA双向总线的处理。读或写只是简单由Avalon的读、写信号来控制的。这个技巧是我从open-cores里面的基于wishbone总线的IIC从设备的IP上学到的。注意:ST7920是低速设备,此处只做简单处理;高速设备请大家自行斟酌。
还有一点需要说明,chipselect在Nios II 9.0之后就不是必须的信号,此处加上,只为和以前的版本兼容。
最后更新:2017-04-04 02:25:10