|
EDA365欢迎您登录!
您需要 登录 才可以下载或查看,没有帐号?注册
x
最近发现在一些RTL设计中用到了类函数宏定义的方法定义一些参数,在以前的了解中,基于Verilog的开发只能定义常量宏,这是使用system verilog的缘故,因其结合了大部分Verilog 和 C的语法,使得system verilog 在使用时更加灵活,而且可综合的system verilog(sv)是可以替代Verilog的,特别是在简化接口方面。. x3 b, n, A! ]- s& e8 Q1 `
8 p1 [4 ^& V$ ]6 |0 ?: c+ j- k
定义常量宏 :`define DEPTH 16: P- I) Y$ H; x2 g
" J2 ~9 V' `( N: b/ \
定义带参数宏:`define SQUARE(X) (X*X)
8 B! @& Q0 F1 o7 w8 ^! u' g& k" U, H, X; P5 \6 Q8 E
定义带参数宏:`define MIN(a,b) a<b ? a:b; d# B" ]0 T! a* W# R0 ?2 Y9 R
z& W% B- \$ c! s; X
`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)
# B+ b5 w4 K4 o' X+ R L* lmodule sram#(
& o5 B8 U% y5 ~* _ parameter RAM_DEPTH =16,//RAM 深度% W! l! ], y# D: J; @5 J
//parameter RAM_ADDR_W= 8 ,//RAM 地址位宽, T. \& c+ a: Q2 }$ I+ M
parameter RAM_WIDTH =8 //RAM 位宽- h- y" `# }4 f6 f
)" z( `) u2 ]# P- l L' K4 X
(
4 A& r' Q! G: ]5 G6 A, a- [ input clk,
' g/ A; G+ q( r) }- w. e" L input wen,
+ U9 O8 S8 w% d; l5 I! Q5 o input ren,
& M# V5 Y A3 ^6 B) ^ input[RAM_WIDTH-1:0] din,
$ N! W) N3 G- D- z9 p input[`LOG2(RAM_DEPTH)-1:0] waddr,1 H: O0 \" g* u6 w# D, L& g0 f7 R& c
input[`LOG2(RAM_DEPTH)-1:0] raddr,
# B9 i& [% H5 e0 W, X' ~& n% s input[RAM_WIDTH-1:0] dout
u4 G7 J: `' q2 K);
. c& |* `5 t6 P: y( yreg[RAM_WIDTH-1:0] ram_mem [0:RAM_DEPTH];) _2 L! _. n! H' O( y) `: H4 ?1 \+ @
8 J1 P9 R( B" \( ]. c o
always@(posedge clk)begin* S6 j/ ]: q3 l1 o
if(wen)& T3 C' \9 H& N; p5 t5 Z
ram_mem[waddr]<= din;4 _; W4 L3 R+ O5 Q) _4 U
end, W) d: w' t5 e$ A1 X3 O5 X7 Q
always@(posedge clk)begin6 N8 s0 |, C; p" ]8 N9 C4 a
if(ren)- ~6 z8 Q. z/ h
dout <= ram_mem[raddr];( e* v( h! u0 P$ d4 C0 o- \% [
end
: {! x0 h3 C/ U" o" r4 @' ^4 rendmodule
; f2 b$ x" g2 P* Z! f上述代码写的是一个双口RAM,而且RAM的地址和位宽采用parameter 参数化的方式,正常情况下,根据RAM_DEPTH 的不同,我们还需要额外的去定义地址位宽RAM_ADDR_W。
9 h E5 ?) Q: l: b6 _# p
+ b3 S1 a [2 N/ M因为两个参数需要匹配一致的,但是手工例化设置时难免会出现一些低级错误,导致RAM的深度和地址位宽不匹配,作者本人曾经也犯过类似的错误,在例化传参时位宽不匹配,不特别注意也不好去定位。还有,在做一些计数CNT时,也容易出现定义位宽与实际CNT位宽不匹配的情况。也可以通过定义带参数的宏来解决,当然实例代码宏定义只写到了256读者可以继续往大的写下去即可。$ z! ` ~9 s t6 m! K, s7 O
|
|