|
EDA365欢迎您登录!
您需要 登录 才可以下载或查看,没有帐号?注册
x
最近发现在一些RTL设计中用到了类函数宏定义的方法定义一些参数,在以前的了解中,基于Verilog的开发只能定义常量宏,这是使用system verilog的缘故,因其结合了大部分Verilog 和 C的语法,使得system verilog 在使用时更加灵活,而且可综合的system verilog(sv)是可以替代Verilog的,特别是在简化接口方面。
4 ?0 g; W z' w4 c+ ~5 k& K
% G' j, K5 z( O3 q% j定义常量宏 :`define DEPTH 16
% S; P+ [ X9 G% D7 v4 m& d
* n. d) X% E' l定义带参数宏:`define SQUARE(X) (X*X)
4 d4 B# K' [: c) F+ M7 E& ^0 r& N. b
定义带参数宏:`define MIN(a,b) a<b ? a:b
: ~5 i, G- u8 E6 m& E% B+ r3 Z1 r& I0 p0 j; w
`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)
4 n+ }8 R9 m ~. o% x' X8 Jmodule sram#(
2 D8 h: g! x L3 o6 j* {+ S& ]* { parameter RAM_DEPTH =16,//RAM 深度8 {8 E6 w5 n( j9 X2 [& J& x
//parameter RAM_ADDR_W= 8 ,//RAM 地址位宽
5 N' I% ^2 x1 T% G; J9 X i parameter RAM_WIDTH =8 //RAM 位宽
4 M2 C! H/ ^# d5 _)( }7 B* A* U; j8 {! |
(0 `5 a1 z k" K7 `
input clk,+ |0 O( y% B+ s( C
input wen,1 K6 ~+ T1 K6 H# D2 k0 }
input ren,5 {+ j. X6 C$ ]" ?! }
input[RAM_WIDTH-1:0] din, % W+ a- M& i0 d' _5 W2 t
input[`LOG2(RAM_DEPTH)-1:0] waddr,; E2 w' L# A- M6 ?& }
input[`LOG2(RAM_DEPTH)-1:0] raddr,4 H; V+ z: r0 u- d# Z. M
input[RAM_WIDTH-1:0] dout$ S: Y) u5 A- i, g
);
9 b9 g$ @" e, F+ {reg[RAM_WIDTH-1:0] ram_mem [0:RAM_DEPTH];) s( b9 J' @5 ?0 S+ ?$ T! F! W* L, M
7 K( j9 G' T- U: c7 Ralways@(posedge clk)begin, c5 j8 `& Z, F% Y2 b
if(wen)3 ^& @( h* l6 ]9 z4 z( u' k6 P
ram_mem[waddr]<= din;
2 t$ U% G8 e" ^. V) F" dend" S/ F8 K2 J3 _/ k; c3 D- v$ J# {/ Z
always@(posedge clk)begin
+ s, _/ q+ \. `7 j1 k if(ren)1 v, M7 _& c5 b3 s4 {, ~/ Q# {; m* P
dout <= ram_mem[raddr];) ^- n9 i$ f. c
end5 a* b6 j; G0 M, V: C9 t+ t" ]: N
endmodule
. s0 |% d. W5 P9 K7 o8 K, P' z上述代码写的是一个双口RAM,而且RAM的地址和位宽采用parameter 参数化的方式,正常情况下,根据RAM_DEPTH 的不同,我们还需要额外的去定义地址位宽RAM_ADDR_W。
9 h3 W- V; `( g; f
6 Z- U5 ]! ], _9 p因为两个参数需要匹配一致的,但是手工例化设置时难免会出现一些低级错误,导致RAM的深度和地址位宽不匹配,作者本人曾经也犯过类似的错误,在例化传参时位宽不匹配,不特别注意也不好去定位。还有,在做一些计数CNT时,也容易出现定义位宽与实际CNT位宽不匹配的情况。也可以通过定义带参数的宏来解决,当然实例代码宏定义只写到了256读者可以继续往大的写下去即可。6 d3 f: V& k. U O3 S, u# c5 O
|
|