RAM之VHDL描述
现在的FPGA基本上都提供了Block RAM供用户使用,所以在自己的工程怎么用VHDL来使用这些Block RAM就非常重要。当然,还是推荐使用开发商提供的软件来生成一个RAM模块,但是这样的RAM块不论移植性还是灵活性都降低了。所以这里采用VHDL来描述一个RAM,对于不同的综合工具和约束条件,综合出的结果可能有所不同,尽管这样,其移植性和灵活性还是要比使用工具生成的RAM块好。使用不同的综合工具,只要稍加修改就可以满足自己设计的要求。' j! F2 Q, j: C- k1 \# S1 i
- q% D- E" I4 M: y
下面的VHDL代码使用ISE的XST综合,综合结果使用了Block RAM,这是我们期望的。当然有时对于用到的容量很小的RAM,我们并不需要其使用Block RAM,那么只要稍微修改一下就可以综合成Distribute RAM。具体如何修改后面再做介绍。
& ^6 d& w# t7 z" Y0 e* N8 o: {; v" H+ F4 \% s' q& s: k
--------------------------------------------------------------------------------
3 O: f7 g" j$ ?1 ~; `- X* P% ^-- Engineer: skycanny% f: I1 T+ \" l- y4 X
-- Module Name: ram - Behavioral0 e. p: E' L& r; O5 B
-- Tool versions: ISE 7.1
' ^$ f8 y% [- K, g2 R3 ?' N) L-- Description: This module is designed to generate a RAM
# R+ Y$ a% ^% B% m- G( ^! F* Z--------------------------------------------------------------------------------3 E8 R8 b* h: L, R& w* ^! Y' E
library IEEE;
* M7 N8 O F+ b' xuse IEEE.STD_LOGIC_1164.ALL;8 u# E3 o* i5 j: R2 [
use IEEE.STD_LOGIC_ARITH.ALL;
* `2 U' v6 X8 g: [" \% ]use IEEE.STD_LOGIC_UNSIGNED.ALL;
. ]2 L1 i: j* y( D1 c H$ c" i; M# G- A* x
entity ram is; s' B; X4 B3 t2 \/ k+ {: {( X
generic(width: integer := 16; -- used to change the memory data's width
% {! t4 ^; x4 j3 z2 q depth: integer := 8); -- used to change the memery address' width during( u$ V' Q" ]: m% c, J; T t5 V
-- instantiation.
7 u) w# |0 j7 V* I1 j port(; a% R7 A$ e( M9 o2 d C8 ?
clk : in std_logic; --clock
, t+ I" T1 t7 `" F, Z addr : in std_logic_vector(depth - 1 downto 0); --address bus, c1 Q6 M% B. _
cs : in std_logic; --chip select2 d& W# u$ e" N4 r7 A
oe : in std_logic; --output enable/ P& p+ g) x0 F8 I7 v
--high for write4 j# F' j1 |0 ]* }4 h
--low for read+ K! K' g2 \+ {9 o$ k
data_i: in std_logic_vector(width - 1 downto 0); --write data bus* P7 m" ?2 J! v% @4 p1 i9 i; J+ X
data_o: out std_logic_vector(width - 1 downto 0) --read data bus, C2 b ]3 V2 C. f
);
/ l5 }+ e* F6 Q; Gend ram;/ O6 F/ @: P6 K7 x9 i
; R- n, X I: karchitecture Behavioral of ram is( v" M' @. T W. C" K
' \# i6 a3 }. w" \type ram is array(2 ** depth - 1 downto 0) of std_logic_vector(width - 1 downto 0);
. M- s! b G) U( t+ O) ssignal ram1 : ram;
+ H; V7 r+ U1 A" I' Z$ f# i1 ~0 H+ ^3 U, C
begin5 ~* q1 T- P+ u7 u8 A9 F
process(clk)
: C% R) \3 _$ W7 v. m begin
- g9 f3 n i, n* \9 Q if(clk'event and clk = '1') then
8 W0 L/ Y* a) v% ^0 ~( m b if(cs = '0') then ) V/ t) r3 L7 W l
if(oe = '0') then8 b$ l: ^& s8 G$ Z) e, u( S, ~
data_o <= ram1(conv_integer(addr));
9 b2 G1 ?0 P$ l1 a4 z, R3 L) Z else; } o4 {9 m) \/ G- a, n7 f/ Q( m2 p
ram1(conv_integer(addr)) <= data_i;, m2 ?1 J z% D- o7 M: w
end if;
% m7 f8 ?7 C T( o- N7 | end if;
8 a/ b C7 f) I: S' @; O, ]& p end if;0 G1 ~8 L# k3 i* |5 w7 [: O9 t
end process;0 o( p" @4 i" h8 R
end Behavioral;, u9 Y, V) p( G3 v: E+ g
----------------------------------------------------------------------------------------------------
7 F) d4 X/ P! D4 s& _- m/ C2 d, k4 F0 u
$ F- U% B% ~4 Q- j* d( ?0 h我们看一下综合报告:( G4 | Z# S3 r$ M5 E: h
- F5 H& g1 i' j+ q; @# f( V
=========================================================================/ \- h+ C# E6 P* ]# Y5 P& {$ K/ h
* HDL Synthesis *
$ c ]0 `9 E W+ G=========================================================================
7 O/ A( g" q5 b) d$ ~* a7 V( F m! {, r# n9 _
Synthesizing Unit <ram>.
@4 o* h$ P& P4 d. i Related source file is "G:/vhdl/ram/ram.vhd"., s. f( D& d$ W
Found 256x16-bit single-port block RAM for signal <ram1>.' |$ v$ F$ E2 K# O% u3 \
-----------------------------------------------------------------------* i: H4 `" D' F' Y
| mode | no-change | |/ \( k9 x$ r* i5 [7 z5 ^! _& y% s1 z
| aspect ratio | 256-word x 16-bit | |
3 a# Y( e7 ?4 ?( ^ | clock | connected to signal <clk> | rise |4 F7 U8 |% m$ p' b X) e4 W
| enable | connected to signal <cs> | low |
, s- l( T8 \$ G4 q | write enable | connected to signal <oe> | high |
, A0 K7 t2 o* R8 ]( \8 k | address | connected to signal <addr> | |
5 [) p9 t: w8 }6 { | data in | connected to signal <data_i> | |
7 r7 B2 A+ x" _" r4 G& l# T | data out | connected to signal <data_o> | |9 L+ z: _( d0 t
| ram_style | Auto | |% o4 R) r. L6 z% `7 I9 v
-----------------------------------------------------------------------+ q* Y* @# \* K1 `# m' u4 u
Summary:& T( M) c1 F2 E) a v/ A
inferred 1 RAM(s).
8 E' W7 E3 p7 \$ |$ i' rUnit <ram> synthesized.
" H- n7 A& o9 _# x
/ F! c% Z, i) u7 e9 i( g1 ~: t; U可见确实综合成了Block RAM。并且只要改变Width和Depth,就可以改变生成RAM的宽度和容量 。
6 o3 x3 |+ J! N0 Z: O. l
`# O+ h& n4 P y5 R# g下面是把上面的代码稍做修改后生成Distribute RAM的代码和其综合报告,可见改动是非常小的。
6 P5 B9 @5 S! I2 m$ Y
; r# }' @8 |4 {( o' h3 R4 s8 ?entity ram is
' {3 y; h6 a& f4 q generic(width: integer := 16; -- used to change the memory data's width
$ F3 Q8 R6 q' L- C" M* K& ~ depth: integer := 8); -- used to change the memery address' width during, N0 q6 C: A; T4 a& b& Y4 E: ]+ d& G; t) Q
-- instantiation.
" Q5 }; y" U8 a4 Y$ f% ]; C port(, h( x0 W- ?0 }3 u) H* z
clk : in std_logic; --clock
8 J# `7 l: ]$ d- }/ C$ }. A addr : in std_logic_vector(depth - 1 downto 0); --address bus2 K3 c. h k5 J5 w' U3 R
cs : in std_logic; --chip select$ ?, T# b1 _1 L, O7 p
oe : in std_logic; --output enable7 Z7 C6 N5 @4 p* r' n
--low for read3 Y/ M9 u$ F/ ^! Z
wr : in std_logic; --low for write --add for distribute ram
: H2 ~. w0 Z; N/ N; H1 d5 p data_i: in std_logic_vector(width - 1 downto 0); --write data bus( X1 E) \! }, l7 Y6 |- l9 @2 [
data_o: out std_logic_vector(width - 1 downto 0) --read data bus2 h9 D3 X- D3 o- B
);
v8 m5 r9 s5 V! ~% r- Uend ram;6 g4 U' `5 v3 c/ J) W, S
6 }9 e4 C$ N7 Y& X2 e7 m7 f& G, i1 p
architecture Behavioral of ram is9 ]) I% C8 y7 Y
+ y5 R5 d6 f% s, Vtype ram is array(2 ** depth - 1 downto 0) of std_logic_vector(width - 1 downto 0);5 `9 p( W* g! E
signal ram1 : ram;
5 n: i) \0 G O- X' l0 x( I3 s" h/ M; c+ _, \' q0 {9 Z9 j
begin
% a, i) L; j; Z* V |# M ~' r6 m process(clk)% o% U* f# J& \0 k, u1 I, l, d" T0 }
begin
/ m! B! ?# V9 j9 n5 N) V$ U if(clk'event and clk = '1') then/ u, C- d! v: X
if(cs = '0') then
( `8 j4 D* x/ y if(oe = '0') then . i* C' G" O5 p! p7 G
data_o <= ram1(conv_integer(addr)); + A3 I& b' a' V) r9 [) Z6 I
elsif(wr = '0') then --change for distribute ram
$ t6 G8 ]" L' D. X ram1(conv_integer(addr)) <= data_i;: @3 F% t( V7 \
end if;
9 a/ y9 S9 b. w( ? end if;
' V; V& g1 A' ^( C8 u: b ? end if;
) b8 Z0 K+ A7 B; |' i/ D- ? end process;% O! U ?! e! j9 l# ?* L
end Behavioral;
4 l5 |( K% v* I3 N9 H: Y, D
; `! P# V# i1 J* y7 E) i% U/ V9 L=========================================================================
" Z: t5 M, P, f* HDL Synthesis *
) H' b9 `9 J5 ? m0 b=========================================================================2 g* I6 g) O4 N) `( m4 F5 ^' n
( }9 u+ }9 z+ w4 Z- K! USynthesizing Unit <ram>.) C6 x3 z* G8 z8 p( b, U) F
Related source file is "G:/vhdl/ram/ram.vhd".
7 R! y# Z( {) @" |8 f: e) w5 L5 j8 O7 L Found 256x16-bit single-port distributed RAM for signal <ram1>.% J6 u& O/ h1 y) a) e' G
-----------------------------------------------------------------------5 r, b9 L" [8 {3 I0 X9 P
| aspect ratio | 256-word x 16-bit | |8 z4 H2 L5 T# F( n: y
| clock | connected to signal <clk> | rise |4 n2 G' M6 f$ f" a# P) K: d
| write enable | connected to internal node | high |1 e- `$ m9 s+ [! z; W
| address | connected to signal <addr> | |8 }) \' n( I( h8 z
| data in | connected to signal <data_i> | |8 X& }9 q! L. R8 M6 E! s9 o
| data out | connected to internal node | |, B! |* i: p. T a$ g( x
| ram_style | Auto | |
* p0 v. O; z* W0 P/ ? -----------------------------------------------------------------------
$ |5 t5 `; _) r" l9 _3 m8 ^ Found 16-bit register for signal <data_o>.$ L) \% R. N x0 N/ ?7 N& v
Summary:; ^4 o% Y: k& V( |1 k6 R
inferred 1 RAM(s)./ J6 W: A: A6 Q# F8 j; R
inferred 16 D-type flip-flop(s).
9 \* H& o8 N+ x* w; H, p, sUnit <ram> synthesized.1 Z* h# n7 k+ P9 u) x& s0 E
& d* H' Y" Q+ g. f) N* ^
由以上的讨论我们可以看出,用VHDL来描述RAM其实是非常方便,更加重要的这种方法在移植是时候有着更加优越的特点。 H$ L# ]" [9 u7 V) A
& w5 k* i, j0 W# V9 S5 _[ 本帖最后由 vfdff 于 2007-12-18 00:56 编辑 ]
搜索更多相关主题的帖子:
RAM VHDL 描述