|
|
EDA365欢迎您登录!
您需要 登录 才可以下载或查看,没有帐号?注册
x
最近发现在一些RTL设计中用到了类函数宏定义的方法定义一些参数,在以前的了解中,基于Verilog的开发只能定义常量宏,这是使用system verilog的缘故,因其结合了大部分Verilog 和 C的语法,使得system verilog 在使用时更加灵活,而且可综合的system verilog(sv)是可以替代Verilog的,特别是在简化接口方面。. Y4 [# ^- n: A4 B- I9 f
* @5 x1 O' F. p# O7 w8 t定义常量宏 :`define DEPTH 16
' o' c, y. O' C3 y0 Z2 b: B3 O* f8 Y% m( ~/ K. r* I8 V
定义带参数宏:`define SQUARE(X) (X*X)
^5 k; V( N$ j5 r& G+ c4 s2 I: }7 c& F( i- L5 d
定义带参数宏:`define MIN(a,b) a<b ? a:b
1 j( }! g% D' |1 N1 d# k% e- T t& ]7 |# E4 b4 J
`define LOG2(Z) ((Z<=2)?1:Z<=4)?2:Z<=8)?3:Z<=16)?4:Z<-=32)?5:Z<=64)?6:Z<=128)?7:Z<=256)?8:9)
1 W$ w6 e, y( }. Nmodule sram#(3 m- B* C: k+ E& I2 x7 F3 N! N
parameter RAM_DEPTH =16,//RAM 深度
6 P" ^6 }! t! ^+ K2 R //parameter RAM_ADDR_W= 8 ,//RAM 地址位宽
8 l4 Y% i+ ]4 O( z parameter RAM_WIDTH =8 //RAM 位宽' }$ B6 K; Q" f* z A1 a+ F; J
)& v0 u3 t6 ?) r
(
) W4 R7 U: f, i6 W0 R* u- _+ \, _ input clk,2 h+ t5 K' S9 D& l1 m, e8 ?. U
input wen,
4 y+ H6 {$ U1 `- ~4 Z+ {" V! ] input ren,% z' U4 I4 U4 o( f9 C+ _
input[RAM_WIDTH-1:0] din, 9 i1 G" s% q; {5 I6 p
input[`LOG2(RAM_DEPTH)-1:0] waddr,; T7 D/ y: X3 H% T* H# I, C
input[`LOG2(RAM_DEPTH)-1:0] raddr,
' H! z' a o- k input[RAM_WIDTH-1:0] dout
0 t7 z" R+ l5 C1 z M/ C);
" j3 f9 j5 x3 f% u- k# N0 E6 jreg[RAM_WIDTH-1:0] ram_mem [0:RAM_DEPTH];2 y7 v4 h+ b( ~( ]. c
. L% K) |& b A7 I$ q$ ralways@(posedge clk)begin1 K. R2 h& z; @% \) M
if(wen)+ x% {" I5 M: m; Z' O
ram_mem[waddr]<= din;" L' h! o' `) Z1 [* @
end
& F3 L2 A1 I$ {7 q8 c3 m/ ]always@(posedge clk)begin8 j- a2 ~$ _) S5 f) O# ~( w6 v
if(ren)0 w8 _% p* T l/ U
dout <= ram_mem[raddr];: s' b" Z n, O" F1 Y
end. K) ?1 v5 m( V6 L! ]
endmodule
, A0 j1 J7 ]9 k! p2 H+ \上述代码写的是一个双口RAM,而且RAM的地址和位宽采用parameter 参数化的方式,正常情况下,根据RAM_DEPTH 的不同,我们还需要额外的去定义地址位宽RAM_ADDR_W。' n# x9 [/ r% E& E+ r
4 R% l* g- E2 F% z$ e0 G2 d% X因为两个参数需要匹配一致的,但是手工例化设置时难免会出现一些低级错误,导致RAM的深度和地址位宽不匹配,作者本人曾经也犯过类似的错误,在例化传参时位宽不匹配,不特别注意也不好去定位。还有,在做一些计数CNT时,也容易出现定义位宽与实际CNT位宽不匹配的情况。也可以通过定义带参数的宏来解决,当然实例代码宏定义只写到了256读者可以继续往大的写下去即可。/ b1 d; s) K8 f% W4 {$ S$ T, r
|
|