AR# 8856

5.1i XST - XST で ram_style が「Distributed」に設定されているのにブロック RAM が推論される

説明

キーワード : XST, VHDL, Verilog, RAM, Block, distributed, infer, ブロック, 分散, 推論

重要度 : 標準

概要 :
XST で ram_style 命令を「Distributed」に設定しましたが、Block RAM が推論されてしまいます。

ソリューション

1

XST では、RAM のアドレス行にレジスタが付いていると、合成命令に関係なくブロック RAM が推論されてしまいます。

この問題を回避するには、中間にアドレス信号を使用します。

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

回避策 :

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

XST では、RAM のアドレス行にレジスタが付いていると、合成命令に関係なくブロック RAM が推論されてしまいます。

この問題を回避するには、中間にアドレス信号を使用します。

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;

回避策 :

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
日付 10/20/2005
ステータス アーカイブ
種類 一般