Continue to Site

Welcome to EDAboard.com

Welcome to our site! EDAboard.com is an international Electronics Discussion Forum focused on EDA software, circuits, schematics, books, theory, papers, asic, pld, 8051, DSP, Network, RF, Analog Design, PCB, Service Manuals... and a whole lot more! To participate you need to register. Registration is free. Click here to register now.

small memory is taking 47% of a 1.8MillionGates Xilinx chip!

Status
Not open for further replies.

omara007

Advanced Member level 4
Joined
Jan 6, 2003
Messages
1,237
Helped
50
Reputation
102
Reaction score
16
Trophy points
1,318
Location
Cairo/Egypt
Activity points
9,716
Hi folks

I am trying to map my vhdl coded memory into Xilinx distributed RAM .. I'm using Xilinx Spartan-3A DSP chip (XC3SD1800A-4fg676) and Xilinx ISE 11.3.

I'm facing 2 problem:
1. Synthesis using XST is taking too long .. approximately 5.5 hours.
2. The chip utilization of just the memory is 47% of 1.8 million-gate equivalent chip.

The RAM is intended to have 8 synchronous write ports and 8 asynchronous read ports.

The code is shown here:
Code:
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;

-- Entity Declaration --------------------------------------------------------
entity rregfile_dp is
port (
clk : in std_logic;
rst_n : in std_logic;
-- Write Port -------------------------------------
-- Port-0
wr_en0 : in std_logic; -- Write Enable
addrs0_wr : in unsigned (rg_addrs_width-1 downto 0); -- Write Addresses
data0_wr : in signed (rg_data_width-1 downto 0); -- Write Data
-- Port-1
wr_en1 : in std_logic; -- Write Enable
addrs1_wr : in unsigned (rg_addrs_width-1 downto 0); -- Write Addresses
data1_wr : in signed (rg_data_width-1 downto 0); -- Write Data
-- Port-2
wr_en2 : in std_logic; -- Write Enable
addrs2_wr : in unsigned (rg_addrs_width-1 downto 0); -- Write Addresses
data2_wr : in signed (rg_data_width-1 downto 0); -- Write Data
-- Port-3
wr_en3 : in std_logic; -- Write Enable
addrs3_wr : in unsigned (rg_addrs_width-1 downto 0); -- Write Addresses
data3_wr : in signed (rg_data_width-1 downto 0); -- Write Data
-- Port-4
wr_en4 : in std_logic; -- Write Enable
addrs4_wr : in unsigned (rg_addrs_width-1 downto 0); -- Write Addresses
data4_wr : in signed (rg_data_width-1 downto 0); -- Write Data
-- Port-5
wr_en5 : in std_logic; -- Write Enable
addrs5_wr : in unsigned (rg_addrs_width-1 downto 0); -- Write Addresses
data5_wr : in signed (rg_data_width-1 downto 0); -- Write Data
-- Port-6
wr_en6 : in std_logic; -- Write Enable
addrs6_wr : in unsigned (rg_addrs_width-1 downto 0); -- Write Addresses
data6_wr : in signed (rg_data_width-1 downto 0); -- Write Data
-- Port-7
wr_en7 : in std_logic; -- Write Enable
addrs7_wr : in unsigned (rg_addrs_width-1 downto 0); -- Write Addresses
data7_wr : in signed (rg_data_width-1 downto 0); -- Write Data

-- Read Ports --------------------------------------
-- Port-0
addrs0_rd : in unsigned (rg_addrs_width-1 downto 0); -- Read Address
data0_rd : out signed (rg_data_width-1 downto 0); -- Read Data
-- Port-1
addrs1_rd : in unsigned (rg_addrs_width-1 downto 0); -- Read Address
data1_rd : out signed (rg_data_width-1 downto 0); -- Read Data
-- Port-2
addrs2_rd : in unsigned (rg_addrs_width-1 downto 0); -- Read Address
data2_rd : out signed (rg_data_width-1 downto 0); -- Read Data
-- Port-3
addrs3_rd : in unsigned (rg_addrs_width-1 downto 0); -- Read Address
data3_rd : out signed (rg_data_width-1 downto 0); -- Read Data
-- Port-4
addrs4_rd : in unsigned (rg_addrs_width-1 downto 0); -- Read Address
data4_rd : out signed (rg_data_width-1 downto 0); -- Read Data
-- Port-5
addrs5_rd : in unsigned (rg_addrs_width-1 downto 0); -- Read Address
data5_rd : out signed (rg_data_width-1 downto 0); -- Read Data
-- Port-6
addrs6_rd : in unsigned (rg_addrs_width-1 downto 0); -- Read Address
data6_rd : out signed (rg_data_width-1 downto 0); -- Read Data
-- Port-7
addrs7_rd : in unsigned (rg_addrs_width-1 downto 0); -- Read Address
data7_rd : out signed (rg_data_width-1 downto 0)); -- Read Data


end entity rregfile_dp;
-- End of Entity Declaration -------------------------------------------------

-- Architecture Declaration --------------------------------------------------
architecture rtl of rregfile_dp is

type regfile_type is array (natural range <>) of signed (rg_data_width-1 downto 0);
signal raccum_reg : regfile_type (0 to (2**rg_addrs_width)-1);

begin -- architecture rtl

----------------------------------------------------------
-- Write Process
----------------------------------------------------------
proc_wraccum: process (clk, rst_n) is
begin -- process proc_wraccum
if rst_n = '0' then -- asynchronous reset (active low)
raccum_reg <= (others => (others =>'0'));
elsif clk'event and clk = '1' then -- rising clock edge
if wr_en0 = '1' then
raccum_reg(to_integer(addrs0_wr)) <= data0_wr;
end if;

if wr_en1 = '1' then
raccum_reg(to_integer(addrs1_wr)) <= data1_wr;
end if;

if wr_en2 = '1' then
raccum_reg(to_integer(addrs2_wr)) <= data2_wr;
end if;

if wr_en3 = '1' then
raccum_reg(to_integer(addrs3_wr)) <= data3_wr;
end if;

if wr_en4 = '1' then
raccum_reg(to_integer(addrs4_wr)) <= data4_wr;
end if;

if wr_en5 = '1' then
raccum_reg(to_integer(addrs5_wr)) <= data5_wr;
end if;

if wr_en6 = '1' then
raccum_reg(to_integer(addrs6_wr)) <= data6_wr;
end if;

if wr_en7 = '1' then
raccum_reg(to_integer(addrs7_wr)) <= data7_wr;
end if;
end if;
end process proc_wraccum;
----------------------------------------------------------

----------------------------------------------------------
-- Read Process
----------------------------------------------------------
data0_rd <= raccum_reg(to_integer(addrs0_rd));
data1_rd <= raccum_reg(to_integer(addrs1_rd));
data2_rd <= raccum_reg(to_integer(addrs2_rd));
data3_rd <= raccum_reg(to_integer(addrs3_rd));
data4_rd <= raccum_reg(to_integer(addrs4_rd));
data5_rd <= raccum_reg(to_integer(addrs5_rd));
data6_rd <= raccum_reg(to_integer(addrs6_rd));
data7_rd <= raccum_reg(to_integer(addrs7_rd));
----------------------------------------------------------

end architecture rtl;
-- End of Architecture Declaration -------------------------------------------




Any suggestion on how to reduce this high utilization to its normal range ? .. also reducing the synthesis time ..



Regards
 

Re: small memory is taking 47% of a 1.8MillionGates Xilinx c

omara007 said:
I am trying to map my vhdl coded memory into Xilinx distributed RAM .. I'm using Xilinx Spartan-3A DSP chip (XC3SD1800A-4fg676) and Xilinx ISE 11.3.

I'm facing 2 problem:
1. Synthesis using XST is taking too long .. approximately 5.5 hours.
2. The chip utilization of just the memory is 47% of 1.8 million-gate equivalent chip.

Hi,

Long before I came across same problem for RAM code in ACTEL environment.

I had written code of SRAM in verilog using two dimensional array, and this way for small RAM code synthesis time and core utilization was too much, for me also!!

The proble with two dimensional array for me in Actel tool, I change code and it was working fine for me and problem solved.

In your case, although i have not much experience about VHDL but problem seems to be similar.

HTH
--
Shitansh Vaghela
 

Re: small memory is taking 47% of a 1.8MillionGates Xilinx c

shitansh said:
I had written code of SRAM in verilog using two dimensional array, and this way for small RAM code synthesis time and core utilization was too much, for me also!!

The proble with two dimensional array for me in Actel tool, I change code and it was working fine for me and problem solved.

I would appreciate if you elaborate more about your Verilog approach .. I'm bilingual .. so, please tell me how did you manage to solve it (with code examples if possible) ..
 

whats the value of "rg_data_width" & "rg_data_width"?
 

Re: small memory is taking 47% of a 1.8MillionGates Xilinx c

omara007 said:
how did you manage to solve it (with code examples if possible) ..

Please find two files in attachment.
Please note that these files are provided just to give reference to you.

while synthesizing SramCtrl.v core utilization and syntesis time are too much.

And while synthesizing SramCtrl_modified.v, there is less syntesis time and also core utilization is also reduced.

For me problem was due to two dimensional array and seperate clock for read and write.

Just try to syntesis these files in your tool

HTH
--
Shitansh Vaghela
 

Re: small memory is taking 47% of a 1.8MillionGates Xilinx c

palai_santosh said:
whats the value of "rg_data_width" & "rg_data_width"?

rg_data_width = 42
rg_addrs_width = 5

i.e. the memory size is 32deep X 42bit wide.

Added after 2 minutes:

shitansh said:
omara007 said:
how did you manage to solve it (with code examples if possible) ..

Please find two files in attachment.
Please note that these files are provided just to give reference to you.

while synthesizing SramCtrl.v core utilization and syntesis time are too much.

And while synthesizing SramCtrl_modified.v, there is less syntesis time and also core utilization is also reduced.

For me problem was due to two dimensional array and seperate clock for read and write.

Just try to syntesis these files in your tool

HTH
--
Shitansh Vaghela


Thanks .. I will try them .. yet, I only have one clock for write .. and I'm reading asynchronously .. I guess if I was to read synchronously, I would have gone for Block RAMs rather than Distributed RAMs ..

Let me get back to you after I use your files
 

I think you are well aware of the problem of using Distributed Memories.
looks like a coding issue. Is if statements are intentional?? Imagine the case when two or more write ports want to write.
Its trying to infer 1K+ flops to make this reg file...

Added after 1 hours 9 minutes:

Just to add..
From the look of your design , Its not the memory which is giving you high synthesis time. Its the no of ports for a particular reg.
You are using 8 read ports and 8 write ports . This code is trying to realize a big mux
42-bit 32-to-1 multiplexer and eight of them.

Added after 10 minutes:

Try this... Hope this will solve your problem.
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;

-- Entity Declaration --------------------------------------------------------
entity rregfile_dp is
generic (
rg_addrs_width : integer := 5;
rg_data_width : integer := 42 );
port (
clk : in std_logic;
rst_n : in std_logic;
-- Write Port -------------------------------------
-- Port-0
wr_en0 : in std_logic; -- Write Enable
addrs0_wr : in unsigned (rg_addrs_width-1 downto 0); -- Write Addresses
data0_wr : in signed (rg_data_width-1 downto 0); -- Write Data
-- Port-1
wr_en1 : in std_logic; -- Write Enable
addrs1_wr : in unsigned (rg_addrs_width-1 downto 0); -- Write Addresses
data1_wr : in signed (rg_data_width-1 downto 0); -- Write Data
-- Port-2
wr_en2 : in std_logic; -- Write Enable
addrs2_wr : in unsigned (rg_addrs_width-1 downto 0); -- Write Addresses
data2_wr : in signed (rg_data_width-1 downto 0); -- Write Data
-- Port-3
wr_en3 : in std_logic; -- Write Enable
addrs3_wr : in unsigned (rg_addrs_width-1 downto 0); -- Write Addresses
data3_wr : in signed (rg_data_width-1 downto 0); -- Write Data
-- Port-4
wr_en4 : in std_logic; -- Write Enable
addrs4_wr : in unsigned (rg_addrs_width-1 downto 0); -- Write Addresses
data4_wr : in signed (rg_data_width-1 downto 0); -- Write Data
-- Port-5
wr_en5 : in std_logic; -- Write Enable
addrs5_wr : in unsigned (rg_addrs_width-1 downto 0); -- Write Addresses
data5_wr : in signed (rg_data_width-1 downto 0); -- Write Data
-- Port-6
wr_en6 : in std_logic; -- Write Enable
addrs6_wr : in unsigned (rg_addrs_width-1 downto 0); -- Write Addresses
data6_wr : in signed (rg_data_width-1 downto 0); -- Write Data
-- Port-7
wr_en7 : in std_logic; -- Write Enable
addrs7_wr : in unsigned (rg_addrs_width-1 downto 0); -- Write Addresses
data7_wr : in signed (rg_data_width-1 downto 0); -- Write Data

-- Read Ports --------------------------------------
-- Port-0
addrs0_rd : in unsigned (rg_addrs_width-1 downto 0); -- Read Address
data0_rd : out signed (rg_data_width-1 downto 0); -- Read Data
-- Port-1
addrs1_rd : in unsigned (rg_addrs_width-1 downto 0); -- Read Address
data1_rd : out signed (rg_data_width-1 downto 0); -- Read Data
-- Port-2
addrs2_rd : in unsigned (rg_addrs_width-1 downto 0); -- Read Address
data2_rd : out signed (rg_data_width-1 downto 0); -- Read Data
-- Port-3
addrs3_rd : in unsigned (rg_addrs_width-1 downto 0); -- Read Address
data3_rd : out signed (rg_data_width-1 downto 0); -- Read Data
-- Port-4
addrs4_rd : in unsigned (rg_addrs_width-1 downto 0); -- Read Address
data4_rd : out signed (rg_data_width-1 downto 0); -- Read Data
-- Port-5
addrs5_rd : in unsigned (rg_addrs_width-1 downto 0); -- Read Address
data5_rd : out signed (rg_data_width-1 downto 0); -- Read Data
-- Port-6
addrs6_rd : in unsigned (rg_addrs_width-1 downto 0); -- Read Address
data6_rd : out signed (rg_data_width-1 downto 0); -- Read Data
-- Port-7
addrs7_rd : in unsigned (rg_addrs_width-1 downto 0); -- Read Address
data7_rd : out signed (rg_data_width-1 downto 0)); -- Read Data


end entity rregfile_dp;
-- End of Entity Declaration -------------------------------------------------

-- Architecture Declaration --------------------------------------------------
architecture rtl of rregfile_dp is

type regfile_type is array (natural range <>) of signed (rg_data_width-1 downto 0);
signal raccum_reg : regfile_type (0 to (2**rg_addrs_width)-1);

begin -- architecture rtl

----------------------------------------------------------
-- Write Process
----------------------------------------------------------

proc_wraccum: process (clk, rst_n) is
variable Wen_sel : std_logic_vector(7 downto 0);
begin -- process proc_wraccum
Wen_sel:=wr_en0 & wr_en1 & wr_en2 & wr_en3 & wr_en4 & wr_en5 & wr_en6 & wr_en7;
if rst_n = '0' then -- asynchronous reset (active low)
raccum_reg <= (others => (others =>'0'));
elsif clk'event and clk = '1' then -- rising clock edge
case (Wen_sel) is
when "10000000" => raccum_reg(to_integer(addrs0_wr)) <= data0_wr;
when "01000000" => raccum_reg(to_integer(addrs1_wr)) <= data1_wr;
when "00100000" => raccum_reg(to_integer(addrs2_wr)) <= data2_wr;
when "00010000" => raccum_reg(to_integer(addrs3_wr)) <= data3_wr;
when "00001000" => raccum_reg(to_integer(addrs4_wr)) <= data4_wr;
when "00000100" => raccum_reg(to_integer(addrs5_wr)) <= data5_wr;
when "00000010" => raccum_reg(to_integer(addrs6_wr)) <= data6_wr;
when "00000001" => raccum_reg(to_integer(addrs7_wr)) <= data7_wr;
when others => raccum_reg <= raccum_reg;
end case;

end if;
end process proc_wraccum;
----------------------------------------------------------

----------------------------------------------------------
-- Read Process
----------------------------------------------------------
data0_rd <= raccum_reg(to_integer(addrs0_rd));
data1_rd <= raccum_reg(to_integer(addrs1_rd));
data2_rd <= raccum_reg(to_integer(addrs2_rd));
data3_rd <= raccum_reg(to_integer(addrs3_rd));
data4_rd <= raccum_reg(to_integer(addrs4_rd));
data5_rd <= raccum_reg(to_integer(addrs5_rd));
data6_rd <= raccum_reg(to_integer(addrs6_rd));
data7_rd <= raccum_reg(to_integer(addrs7_rd));
----------------------------------------------------------

end architecture rtl;
-- End of Architecture Declaration -------------------------------------------
 

Re: small memory is taking 47% of a 1.8MillionGates Xilinx c

palai_santosh said:
----------------------------------------------------------
-- Write Process
----------------------------------------------------------

proc_wraccum: process (clk, rst_n) is
variable Wen_sel : std_logic_vector(7 downto 0);
begin -- process proc_wraccum
Wen_sel:=wr_en0 & wr_en1 & wr_en2 & wr_en3 & wr_en4 & wr_en5 & wr_en6 & wr_en7;
if rst_n = '0' then -- asynchronous reset (active low)
raccum_reg <= (others => (others =>'0'));
elsif clk'event and clk = '1' then -- rising clock edge
case (Wen_sel) is
when "10000000" => raccum_reg(to_integer(addrs0_wr)) <= data0_wr;
when "01000000" => raccum_reg(to_integer(addrs1_wr)) <= data1_wr;
when "00100000" => raccum_reg(to_integer(addrs2_wr)) <= data2_wr;
when "00010000" => raccum_reg(to_integer(addrs3_wr)) <= data3_wr;
when "00001000" => raccum_reg(to_integer(addrs4_wr)) <= data4_wr;
when "00000100" => raccum_reg(to_integer(addrs5_wr)) <= data5_wr;
when "00000010" => raccum_reg(to_integer(addrs6_wr)) <= data6_wr;
when "00000001" => raccum_reg(to_integer(addrs7_wr)) <= data7_wr;
when others => raccum_reg <= raccum_reg;
end case;

end if;
end process proc_wraccum;
----------------------------------------------------------

Your suggested code implements one write operation at a time .. and I want to be able to write in 8 different memory locations in one time ..

Effectively the code you suggested can be reduced to only one write port and there is no need to write using 8 different write ports as long as you don't use each port simultaneously with any other one.
 

Status
Not open for further replies.

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top