思考空间
给定列表{RAMB18 RAMB36 LUTRAM RAMB},要求从中找出RAMB18和RAMB36。
如下图所示。
单端口RAM支持BWE(Byte Write Enable),同样地,双端口RAM也支持BWE。结合RAM的三种工作模式(读优先、写优先和保持模式,关于三种工作模式可看这里write_first/read_first/no_change什么区别)可形成不同的组合。例如:双端口RAM读优先,双端口RAM写优先。这里我们看一个支持BWE功能的真双端口读优先RAM,通过这个案例了解一下SystemVerilog的几个知识点。
先看代码的第一部分,如下图所示。从端口声明部分不难看出,该RAM有两个独立的端口:端口A和端口B。之所以认为两者独立是因为它们有各自的时钟端口、数据端口、地址端口和BWE端口。代码第22行声明了一个数组,数组的深度为DEPTH,这种写法类似于C语言声明数组的方法,这种方法仅在SystemVerilog中可用,Verilog并不支持。同时,在该行使用了ram_style的综合属性。该属性用于指导Vivado将该RAM采用何种资源实现,可用的值包括block、distributed、registers和ultra(ram_style的具体使用方法可以看这里Vivado综合属性:RAM_STYLE和ROM_STYLE)。这里我们将其值设置为block,那么Vivado会将其采用Block RAM实现。
代码的第二部分如下图所示。核心部分是两个for generate语句。两个for generate语句描述的功能是一致的,只是一个针对A端口,一个针对B端口。需要注意的是genvar也就是循环变量不能是同一个变量,在这里分别为i和k。不同于之前单端口BWE的描述方式,这里使用了符号“+:”,该符号的左边为基地址,右边为位宽,从而确定哪些bit被选中。除了“+:”还有“-:”,两者被称为indexed part-select。
关于indexed part-select,我们再来看一个具体案例,如下图所示。
思考空间
如果b_vect采用如下声明方式:
logic [0 : 31] b_vect;
那么b_vect[0 +: 8]和b_vect[15 -:8]分别选取b_vect的哪些位?