Intel® Hyperflex™ 体系结构高性能设计手册

ID 683353
日期 10/04/2021
Public
文档目录

2.4.2.9.4. 存储器混合端口宽度比率限制

Intel® Hyperflex™ 体系结构FPGA器件模块RAM支持高达1GHz的时钟速度。相对于混合端口数据宽度的使用,新的RAM模块设计更具限制性。 Intel® Hyperflex™ 体系结构FPGA器件模块RAM不支持1/32,1/16和1/8混合端口比率。有效的比率为1,½和¼混合端口比率。Compiler会对无效的混合端口比率的实现生成错误消息。

当移植一个对 Intel® Hyperflex™ 体系结构FPGA使用无效端口宽度比率的设计时,需要修改RTL来创建所需的比率。

图 75. 无效的1/8混合端口比率的双端口存储器

要创建一个在功能上等效的设计,请创建并合并具有有效混合端口宽度比率的较小存储器。例如,以下步骤实现了一个混合端口宽度比率:

  1. 通过从IP Catalog例化2-Ports存储器IP Core来创建两个具有¼混合端口宽度比率的存储器。
  2. 定义写使能逻辑来对两个存储器进行交替写操作。
  3. 交错存储器的输出来重构一个1/8比率输出。
图 76. 1/8宽度比率实例

此实例显示了两个存储器的写逻辑的交错。所选择的写逻辑使用写地址的最低有效位来决定要写入的存储器。偶数地址写入到存储器mem_A中,奇数地址写入到存储器mem_B中。

由于用于控制写入到存储器的方案,在写操作期间谨慎地构建完整的64-bit输出。您必须要考虑到在两个存储器中的单独8-bit字的交错。

图 77. 存储器输出解扰实例

此实例显示了当试图在地址0h0上进行读操作时的已解扰输出。

下面的RTL实例实现了额外的阶段来对读一侧的存储器进行数据解扰。

顶层解扰RTL代码

module test 
#(	parameter WR_DATA_WIDTH = 8,
		parameter RD_DATA_WIDTH = 64,
		parameter WR_DEPTH = 64,
		parameter RD_DEPTH = 4,
		parameter WR_ADDR_WIDTH = 6,
		parameter RD_ADDR_WIDTH = 4
)(
	data, wraddress, rdaddress,	wren,
	wrclock, rdclock,	q
);

input	[WR_DATA_WIDTH-1:0]	data;
input	[WR_ADDR_WIDTH-1:0]	wraddress;
input	[RD_ADDR_WIDTH-1:0]	rdaddress;
input		wren;
input		wrclock;
input		rdclock;
output	[RD_DATA_WIDTH-1:0]	q;

wire wrena, wrenb;
wire [(RD_DATA_WIDTH/2)-1:0] q_A, q_B;

memorySelect memWriteSelect (
	.wraddress_lsb(wraddress[0]),
	.wren(wren),
	.wrena(wrena),
	.wrenb(wrenb)
);

myMemory mem_A (
	.data(data),
	.wraddress(wraddress),
	.rdaddress(rdaddress),
	.wren(wrena),
	.wrclock(wrclock),
	.rdclock(rdclock),
	.q(q_A)
);

myMemory mem_B (
	.data(data),
	.wraddress(wraddress),
	.rdaddress(rdaddress),
	.wren(wrenb),
	.wrclock(wrclock),
	.rdclock(rdclock),
	.q(q_B)
);

descrambler #(
	.WR_WIDTH(WR_DATA_WIDTH),
	.RD_WIDTH(RD_DATA_WIDTH)
) outputDescrambler (
	.qA(q_A),
	.qB(q_B),
	.qDescrambled(q)
);

endmodule

支持的RTL代码

module memorySelect (wraddress_lsb, wren, wrena, wrenb);
	input wraddress_lsb;
	input wren;
	output wrena, wrenb;

	assign wrena = !wraddress_lsb && wren;
	assign wrenb = wraddress_lsb && wren;
endmodule

module descrambler #(
	parameter WR_WIDTH = 8,
	parameter RD_WIDTH = 64
) (
	input [(RD_WIDTH/2)-1 : 0] qA,
	input [(RD_WIDTH/2)-1 : 0] qB,
	output [RD_WIDTH:0] qDescrambled
);

	genvar i;
	generate
  	for (i=WR_WIDTH*2; i<=RD_WIDTH; i += WR_WIDTH*2) begin: descramble
   	  assign qDescrambled[i-WR_WIDTH-1:i-(WR_WIDTH*2)] = qA[(i/2)-1:(i/2)-WR_WIDTH];
      assign qDescrambled[i-1:i-WR_WIDTH] = qB[(i/2)-1:(i/2)-WR_WIDTH];
    end
  endgenerate

endmodule