UPGRADE YOUR BROWSER

We have detected your current browser version is not the latest one. Xilinx.com uses the latest web technologies to bring you the best online experience possible. Please upgrade to a Xilinx.com supported browser:Chrome, Firefox, Internet Explorer 11, Safari. Thank you!

AR# 8856

5.1i XST - XST is inferring Block RAM even though the ram_style is set to "Distributed"

Description

Keywords: XST, VHDL, Verilog, RAM, Block, distributed, infer

Urgency: Standard

General Description:
When I set the ram_style XST directive to "Distributed", Block RAM is still inferred.

解决方案

1

Due to a problem with XST, if the address lines for the RAM is registered, XST will infer Block RAM regardless of the synthesis directive.

To work around this problem, use an intermediate address signal:

Verilog:

module infer_ram (doa, dob, di, addra, addrb, clka, clkb, write);
output [31:0] doa, dob;
input [31:0] di;
input [3:0] addra, addrb;
input clka, clkb, write;

//Synthesis attribute ram_style of RAM is distributed
reg [31:0] ram [0:15];
reg [3:0] addra_reg;

always @ (posedge clka)
addra_reg <= addra;

always @ (posedge clkb) begin
if (write)
ram[addrb] <= di;
end

assign dob = ram[addrb];
assign doa = ram[addra_reg];

endmodule

Work-around:

module infer_ram (doa, dob, di, addra, addrb, clka, clkb, write);
output [31:0] doa;
output [31:0] dob;
input [31:0] di;
input [3:0] addra, addrb;
input clka, clkb, write;

//Synthesis attribute ram_style of RAM is distributed
reg [31:0] ram[0:15];
reg [3:0] addra_reg;
wire [3:0] addra_temp; //Added temporary address signal

always @ (posedge clka)
addra_reg <= addra;

always @ (posedge clkb) begin
if (write)
ram[addrb] <= di;
end

assign dob = ram[addrb];
assign doa = ram[addra_temp]; //Using temporary address signal for the RAM

assign addra_temp = addra_reg;
//Assigning the registered address signal to the temporary address signal

endmodule

2

Due to a problem with XST, if the address lines for the RAM is registered, XST will infer Block RAM regardless of the synthesis directive.

To work around this problem, use an intermediate address signal:

VHDL:

library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;

entity infer_ram is
port (doa, dob : out std_logic_vector (31 downto 0);
di : in std_logic_vector (31 downto 0);
addra, addrb : in std_logic_vector (3 downto 0);
clka, clkb, write : in std_logic);
end entity;

architecture infer_ram_arch of infer_ram is

type ram_type is array (0 to 15) of std_logic_vector (31 downto 0);
signal ram : ram_type;
signal addra_reg : std_logic_vector (3 downto 0);

begin

process (clka) is begin
if clka'event and clka = '1' then
addra_reg <= addra;
end if;
end process;

process (clkb) is begin
if clkb'event and clkb = '1' then
if (write = '1') then
ram(conv_integer(addrb)) <= di;
end if;
end if;
end process;

dob <= ram(conv_integer(addrb));
doa <= ram(conv_integer(addra_reg));

end architecture;

Work-around:

library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;

entity infer_ram is
port (doa, dob : out std_logic_vector (31 downto 0);
di : in std_logic_vector (31 downto 0);
addra, addrb : in std_logic_vector (3 downto 0);
clka, clkb, write : in std_logic);
end entity;

architecture infer_ram_arch of infer_ram is

type ram_type is array (0 to 15) of std_logic_vector (31 downto 0);
signal ram : ram_type;
signal addra_reg : std_logic_vector (3 downto 0);
signal addra_temp : std_logic_vector (3 downto 0); --Added temporary address signal

begin

process (clka) is begin
if clka'event and clka = '1' then
addra_reg <= addra;
end if;
end process;

process (clkb) is begin
if clkb'event and clkb = '1' then
if (write = '1') then
ram(conv_integer(addrb)) <= di;
end if;
end if;
end process;

dob <= ram(conv_integer(addrb));
doa <= ram(conv_integer(addra_temp)); --Using temporary address signal for the RAM

addra_temp <= addra_reg;
--Assigning the registered address signal to the temporary address signal

end architecture;
AR# 8856
创建日期 03/20/2000
Last Updated 10/20/2005
状态 Archive
Type 综合文章