vivado Byte Write Enable (Block RAM)

这篇文章介绍了AMD支持在块RAM中启用字节写入功能,允许对内存进行高级控制,特别提到了基于列的写入方式。Vivado工具允许利用这种特性,但有特定的写入列宽要求。给出了用VHDL和Verilog编写的True-Dual-PortRAM模块实例。
摘要由CSDN通过智能技术生成

AMD支持在块RAM中启用字节写入功能。使用块RAM中的字节写入功能可以:

•对将数据写入RAM进行高级控制

•单独指定寻址存储器的8位的可写部分

从HDL建模和推理的角度来看,该概念最好描述为基于列的写入:

•RAM被视为大小相等的列的集合

•在写入周期中,您可以分别控制写入这些列中的每一列

Vivado综合推理使您能够利用块RAM字节写入启用功能。所描述的RAM是在块RAM资源上实现的,使用字节写入使能能力,前提是满足以下要求:

•写入宽度相等的列

•允许的写入列宽:8位、9位、16位、18位(8位或9位的倍数)

对于其他写入列宽,例如5位或12位(8位或9位的非倍数),Vivado合成对每列使用单独的RAM:

•写入列数:任意

•支持读写同步:先读、先写,无更改

字节写入启用—具有字节宽写入启用的真双端口(Verilog)

Filename: bytewrite_tdp_ram_rf.v
// True-Dual-Port BRAM with Byte-wide Write Enable
// Read-First mode
// bytewrite_tdp_ram_rf.v
//
module bytewrite_tdp_ram_rf
#(
//--------------------------------------------------------------------------
parameter NUM_COL = 4,
parameter COL_WIDTH = 8,
parameter ADDR_WIDTH = 10,
// Addr Width in bits : 2 *ADDR_WIDTH = RAM Depth
parameter DATA_WIDTH = NUM_COL*COL_WIDTH // Data Width in bits
//----------------------------------------------------------------------
) (
input clkA,
input enaA,
input [NUM_COL-1:0] weA,
input [ADDR_WIDTH-1:0] addrA,
input [DATA_WIDTH-1:0] dinA,
output reg [DATA_WIDTH-1:0] doutA,
input clkB,
input enaB,
input [NUM_COL-1:0] weB,
input [ADDR_WIDTH-1:0] addrB,
input [DATA_WIDTH-1:0] dinB,
output reg [DATA_WIDTH-1:0] doutB
);
// Core Memory
reg [DATA_WIDTH-1:0] ram_block [(2**ADDR_WIDTH)-1:0];
integer i;
// Port-A Operation
always @ (posedge clkA) begin
if(enaA) begin
for(i=0;i<NUM_COL;i=i+1) begin
if(weA[i]) begin
ram_block[addrA][i*COL_WIDTH +: COL_WIDTH] <= dinA[i*COL_WIDTH +:
COL_WIDTH];
end
end
doutA <= ram_block[addrA];
end
end
// Port-B Operation:
always @ (posedge clkB) begin
if(enaB) begin
for(i=0;i<NUM_COL;i=i+1) begin
if(weB[i]) begin
ram_block[addrB][i*COL_WIDTH +: COL_WIDTH] <= dinB[i*COL_WIDTH +:
COL_WIDTH];
end
end
doutB <= ram_block[addrB];
end
end
endmodule // bytewrite_tdp_ram_rf
Byte Write Enable—True Dual Port READ_FIRST Mode (VHDL)
Filename: bytewrite_tdp_ram_rf.vhd
-- True-Dual-Port BRAM with Byte-wide Write Enable
-- Read First mode
--
-- bytewrite_tdp_ram_rf.vhd
--
-- READ_FIRST ByteWide WriteEnable Block RAM Template
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
entity bytewrite_tdp_ram_rf is
generic(
SIZE : integer := 1024;
ADDR_WIDTH : integer := 10;
COL_WIDTH : integer := 9;
NB_COL : integer := 4
);
port(
clka : in std_logic;
ena : in std_logic;
wea : in std_logic_vector(NB_COL - 1 downto 0);
addra : in std_logic_vector(ADDR_WIDTH - 1 downto 0);
dia : in std_logic_vector(NB_COL * COL_WIDTH - 1 downto 0);
doa : out std_logic_vector(NB_COL * COL_WIDTH - 1 downto 0);
clkb : in std_logic;
enb : in std_logic;
web : in std_logic_vector(NB_COL - 1 downto 0);
addrb : in std_logic_vector(ADDR_WIDTH - 1 downto 0);
dib : in std_logic_vector(NB_COL * COL_WIDTH - 1 downto 0);
dob : out std_logic_vector(NB_COL * COL_WIDTH - 1 downto 0)
);
end bytewrite_tdp_ram_rf;
architecture byte_wr_ram_rf of bytewrite_tdp_ram_rf is
type ram_type is array (0 to SIZE - 1) of std_logic_vector(NB_COL *
COL_WIDTH - 1 downto 0);
shared variable RAM : ram_type := (others => (others => '0'));
begin
------- Port A -------
process(clka)
begin
if rising_edge(clka) then
if ena = '1' then
doa <= RAM(conv_integer(addra));
for i in 0 to NB_COL - 1 loop
if wea(i) = '1' then
RAM(conv_integer(addra))((i + 1) * COL_WIDTH - 1 downto i * COL_WIDTH) :=
dia((i + 1) * COL_WIDTH - 1 downto i * COL_WIDTH);
end if;
end loop;
end if;
end if;
end process;
------- Port B -------
process(clkb)
begin
if rising_edge(clkb) then
if enb = '1' then
dob <= RAM(conv_integer(addrb));
for i in 0 to NB_COL - 1 loop
if web(i) = '1' then
RAM(conv_integer(addrb))((i + 1) * COL_WIDTH - 1 downto i * COL_WIDTH) :=
dib((i + 1) * COL_WIDTH - 1 downto i * COL_WIDTH);
end if;
end loop;
end if;
end if;
end process;
end byte_wr_ram_rf;
Byte Write Enable—WRITE_FIRST Mode (VHDL)
Filename: bytewrite_tdp_ram_wf.vhd
-- True-Dual-Port BRAM with Byte-wide Write Enable
-- Write First mode
--
-- bytewrite_tdp_ram_wf.vhd
-- WRITE_FIRST ByteWide WriteEnable Block RAM Template
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
entity bytewrite_tdp_ram_wf is
generic(
SIZE : integer := 1024;
ADDR_WIDTH : integer := 10;
COL_WIDTH : integer := 9;
NB_COL : integer := 4
);
port(
clka : in std_logic;
ena : in std_logic;
wea : in std_logic_vector(NB_COL - 1 downto 0);
addra : in std_logic_vector(ADDR_WIDTH - 1 downto 0);
dia : in std_logic_vector(NB_COL * COL_WIDTH - 1 downto 0);
doa : out std_logic_vector(NB_COL * COL_WIDTH - 1 downto 0);
clkb : in std_logic;
enb : in std_logic;
web : in std_logic_vector(NB_COL - 1 downto 0);
addrb : in std_logic_vector(ADDR_WIDTH - 1 downto 0);
dib : in std_logic_vector(NB_COL * COL_WIDTH - 1 downto 0);
dob : out std_logic_vector(NB_COL * COL_WIDTH - 1 downto 0)
);
end bytewrite_tdp_ram_wf;
architecture byte_wr_ram_wf of bytewrite_tdp_ram_wf is
type ram_type is array (0 to SIZE - 1) of std_logic_vector(NB_COL *
COL_WIDTH - 1 downto 0);
shared variable RAM : ram_type := (others => (others => '0'));
begin
------- Port A -------
process(clka)
begin
if rising_edge(clka) then
if ena = '1' then
for i in 0 to NB_COL - 1 loop
if wea(i) = '1' then
RAM(conv_integer(addra))((i + 1) * COL_WIDTH - 1 downto i * COL_WIDTH) :=
dia((i + 1) * COL_WIDTH - 1 downto i * COL_WIDTH);
end if;
end loop;
doa <= RAM(conv_integer(addra));
end if;
end if;
end process;
------- Port B -------
process(clkb)
begin
if rising_edge(clkb) then
if enb = '1' then
for i in 0 to NB_COL - 1 loop
if web(i) = '1' then
RAM(conv_integer(addrb))((i + 1) * COL_WIDTH - 1 downto i * COL_WIDTH) :=
dib((i + 1) * COL_WIDTH - 1 downto i * COL_WIDTH);
end if;
end loop;
dob <= RAM(conv_integer(addrb));
end if;
end if;
end process;
end byte_wr_ram_wf;
Byte-Wide Write Enable—NO_CHANGE Mode (Verilog)
Filename: bytewrite_tdp_ram_nc.v
//
// True-Dual-Port BRAM with Byte-wide Write Enable
// No-Change mode
//
// bytewrite_tdp_ram_nc.v
//
// ByteWide Write Enable, - NO_CHANGE mode template - Vivado recomended
module bytewrite_tdp_ram_nc
#(
//---------------------------------------------------------------
parameter NUM_COL = 4,
parameter COL_WIDTH = 8,
parameter ADDR_WIDTH = 10, // Addr Width in bits : 2**ADDR_WIDTH = RAM Depth
parameter DATA_WIDTH = NUM_COL*COL_WIDTH // Data Width in bits
//---------------------------------------------------------------
) (
input clkA,
input enaA,
input [NUM_COL-1:0] weA,
input [ADDR_WIDTH-1:0] addrA,
input [DATA_WIDTH-1:0] dinA,
output reg [DATA_WIDTH-1:0] doutA,
input clkB,
input enaB,
input [NUM_COL-1:0] weB,
input [ADDR_WIDTH-1:0] addrB,
input [DATA_WIDTH-1:0] dinB,
output reg [DATA_WIDTH-1:0] doutB
);
// Core Memory
reg [DATA_WIDTH-1:0] ram_block [(2**ADDR_WIDTH)-1:0];
// Port-A Operation
generate
genvar i;
for(i=0;i<NUM_COL;i=i+1) begin
always @ (posedge clkA) begin
if(enaA) begin
if(weA[i]) begin
ram_block[addrA][i*COL_WIDTH +: COL_WIDTH] <= dinA[i*COL_WIDTH +:
COL_WIDTH];
end
end
end
end
endgenerate
always @ (posedge clkA) begin
if(enaA) begin
if (~|weA)
doutA <= ram_block[addrA];
end
end
// Port-B Operation:
generate
for(i=0;i<NUM_COL;i=i+1) begin
always @ (posedge clkB) begin
if(enaB) begin
if(weB[i]) begin
ram_block[addrB][i*COL_WIDTH +: COL_WIDTH] <= dinB[i*COL_WIDTH +:
COL_WIDTH];
end
end
end
end
endgenerate
always @ (posedge clkB) begin
if(enaB) begin
if (~|weB)
doutB <= ram_block[addrB];
end
end
endmodule // bytewrite_tdp_ram_nc
Byte-Wide Write Enable—NO_CHANGE Mode (VHDL)
Filename: bytewrite_tdp_ram_nc.vhd
--
-- True-Dual-Port BRAM with Byte-wide Write Enable
-- No change mode
--
-- bytewrite_tdp_ram_nc.vhd
--
-- NO_CHANGE ByteWide WriteEnable Block RAM Template
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
entity bytewrite_tdp_ram_nc is
generic(
SIZE : integer := 1024;
ADDR_WIDTH : integer := 10;
COL_WIDTH : integer := 9;
NB_COL : integer := 4
);
port(
clka : in std_logic;
ena : in std_logic;
wea : in std_logic_vector(NB_COL - 1 downto 0);
addra : in std_logic_vector(ADDR_WIDTH - 1 downto 0);
dia : in std_logic_vector(NB_COL * COL_WIDTH - 1 downto 0);
doa : out std_logic_vector(NB_COL * COL_WIDTH - 1 downto 0);
clkb : in std_logic;
enb : in std_logic;
web : in std_logic_vector(NB_COL - 1 downto 0);
addrb : in std_logic_vector(ADDR_WIDTH - 1 downto 0);
dib : in std_logic_vector(NB_COL * COL_WIDTH - 1 downto 0);
dob : out std_logic_vector(NB_COL * COL_WIDTH - 1 downto 0)
);
end bytewrite_tdp_ram_nc;
architecture byte_wr_ram_nc of bytewrite_tdp_ram_nc is
type ram_type is array (0 to SIZE - 1) of std_logic_vector(NB_COL *
COL_WIDTH - 1 downto 0);
shared variable RAM : ram_type := (others => (others => '0'));
begin
------- Port A -------
process(clka)
begin
if rising_edge(clka) then
if ena = '1' then
if (wea = (wea'range => '0')) then
doa <= RAM(conv_integer(addra));
end if;
for i in 0 to NB_COL - 1 loop
if wea(i) = '1' then
RAM(conv_integer(addra))((i + 1) * COL_WIDTH - 1 downto i * COL_WIDTH) :=
dia((i + 1) * COL_WIDTH - 1 downto i * COL_WIDTH);
end if;
end loop;
end if;
end if;
end process;
------- Port B -------
process(clkb)
begin
if rising_edge(clkb) then
if enb = '1' then
if (web = (web'range => '0')) then
dob <= RAM(conv_integer(addrb));
end if;
for i in 0 to NB_COL - 1 loop
if web(i) = '1' then
RAM(conv_integer(addrb))((i + 1) * COL_WIDTH - 1 downto i * COL_WIDTH) :=
dib((i + 1) * COL_WIDTH - 1 downto i * COL_WIDTH);
end if;
end loop;
end if;
end if;
end process;
end byte_wr_ram_nc;
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

cckkppll

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值