本篇实现基于叁芯智能科技的SANXIN -B02 FPGA开发板,如有入手开发板,可以登录官方淘宝店购买,还有配套的学习视频。
& _: B4 K2 _* v3 M- y6 K* D
随机存取存储器(random access memory,RAM)又称作"随机存储器"。存储单元的内容可按需随意取出或存入,且存取的速度与存储单元的位置无关的存储器。这种存储器在断电时将丢失其存储内容,故主要用于存储短时间使用的程序。按照存储单元的工作原理,随机存储器又分为静态随机存储器(Static RAM,SRAM)和动态随机存储器(Dynamic RAM,DRAM)。在FPGA内部的存储块为SRAM。
+ |% U5 [' m) \4 a7 B) l) W& K- H2 k
- 设计要求6 L9 r& g& `" O" h2 l
设计一个深度为256,宽度为8的RAM。不需要初始化内容。
7 O4 r. l, X$ e3 D, a, h
- 设计原理3 T# o) |3 k. w" L% n, u, M) k, n1 G
RAM,此种存储器支持写操作,支持读操作。在存储器建造时,可以进行初始化数据,也可以不进行初始化数据。RAM的初始化文件也是coe文件,原理和ROM类似。
由于设计RAM深度为256,故而地址的宽度为8位。
1 q* l$ Z. I; C' m/ e" b) G9 k
RAM工作原理为,在时钟上升沿采样到rden为1时,将addr所指示的存储空间的数据进行输出;在时钟上升沿采样到wren为1时,将wdata存储到addr所指示的存储空间中去。
/ N. E5 j5 @5 O: h+ r
- 架构设计和信号说明6 R/ X/ G( G3 u a
此模块命名为ram_test。my_ram为ip core。
1 C, e- H( W: A, p! r7 F4 B
/ B E# j1 ^7 r' R' {; W
0 A/ {" \! C/ l, i& S- n0 x% V2 A! k
! ?& W2 O& D1 T0 o+ o
( Y6 w& T" R) \' s
- 调用 ip core 之 RAM; _! c/ ?0 ?4 R- l) R0 Z2 G+ ~) B( @. R
3 _8 I2 a0 A# z+ J( }
建好工程之后,右键点击工程,选择New Source,新建IP核。
4 t6 M: |: n# ?/ q
( u3 |2 @& j, [+ }2 `' x7 E3 R0 y9 v/ P* n
! y. X9 y2 F6 |0 d- T
找到对应路径,命名为my_ram。
" {) i+ i' t( L1 H. |, R% D
* y. Q9 ~7 Q8 b( \- f o打开IP核库之后,搜索Block Memory即可看到我们的RAM。
- D" @- k+ q7 R; h8 L
: t) r' w. k& y+ r& h
. p/ ]2 f r( P' r% k
点击Next。
+ t& i! [6 c$ G& D0 k5 F! g" R$ h
: i9 M) \& m/ q8 o, O' e; G& C4 Q7 O
点击Finish。
& A) ?7 S( Y" O5 K6 x2 j+ b
% ~2 m; J( z; ~, P* B6 ~3 @
% G. k3 m" r1 O" V
点击Next。
; j, P' u+ N- Z5 R9 q" A- P5 d. E/ z
X- b- i; ^) P2 ?
, ~$ R4 u: N9 m. r& G
选择默认的Single Port RAM。点击Next。
; N, ^) I+ Q; M7 U/ V! ~
$ E A- K0 s& `4 n' c+ W& U
2 B V0 y! @/ t
数据位宽为8,数据深度为256。Enable选择Always Enable。点击Next。
3 l# y. J. D; W. D
* w: `, ~; H3 E" Y+ } \) q0 N7 v( ~; r K# E
5 n, i, w0 M% s. E
此界面的数据初始化我们不需要做,因为RAM的数据是我们自己写入的,不是提前固化好的,所以这个界面我们保持默认点击Next。
8 x4 X2 P R9 l* X- \& O" E6 I
8 v+ ]$ U5 y% d& E5 T, y+ a" L8 t# {4 D3 [7 y* Z0 f
: a& `7 C4 J: j) C4 W) p# V' _# X
复位端口同样不使用,如果需要,可以勾选上。我们这里保持默认点击Next。
9 v" W6 Y; Z y% b
% C0 h+ [0 b& Z9 ~7 U1 N
2 W/ I5 N2 [! \6 y% E
点击Generate。
0 g) G4 p1 d) _- F* s: f! R
- 顶层设计
2 i( b L" O5 Z2 c+ C7 C
顶层负责调用my_ram,例化文件在ipcore_dir -> my_ram.veo中。
9 [2 X" {* X6 w) k. f& a: I
设计代码为:
2 P; y2 ~# }; F( q, W
) t! j# E* D) G3 C! ?1 Y
' d# c5 d& g) Z
- RTL仿真
) X2 A* x6 }; f6 X& V* }! G8 C/ E
在某些地址中,写入一些数据,然后读出来。由于写进去后,还需要读出来,所以地址不在使用随机值,固定在0,100,200,255地址写入随机值。
# X S) l6 ^7 c9 ^3 E* y+ |* t仿真代码为:
; u; P- V, g& v/ i1 l2 y# o6 M
2 |) C$ y. c& l* C: O6 \( G( I0 A7 l
% X! ^1 h0 H# Q5 s
经过设置后,进行RTL仿真。
# Z8 u/ t1 k3 L+ h5 Y; e7 ]
- I- ?+ t. B5 w5 q& T. _
通过波形图中,可以看出,在地址为0时,写入数据为36;在地址为100时,写入数据为129;在地址为200时,写入数据为9;在地址为255时,写入数据为99。经过一段时间后,对上述几个地址进行读取,输出的数据与写入数据相同(输出时,输出数据要比地址晚两拍)。