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.

why this block ram vhdl code inffer additional dff?

Status
Not open for further replies.

milan.km

Member level 3
Joined
Sep 14, 2015
Messages
55
Helped
0
Reputation
0
Reaction score
0
Trophy points
6
Activity points
435
hi
i wrote the following code for makin a block ram,but as my input is 32 bit width,32 DFFs inferred too,
is this sth wrong with my code?
single port block ram
Code:
library ieee;   
use ieee.std_logic_1164.all;   
use ieee.std_logic_unsigned.all;   
use ieee.std_logic_arith.all;
 
entity spbram is  
 generic ( w : integer := 32; 
             -- number of bits per RAM word
            r : integer := 12); 
             -- 2^r = number of words in RAM 	
  port (clk  : in std_logic;   
        we   : in std_logic;   
        adr    : in std_logic_vector(r-1 downto 0);   
        di   : in std_logic_vector(w-1 downto 0);   
        do  : out std_logic_vector(w-1 downto 0));   
end spbram;   
architecture spbram_arch of spbram is   
  type ram_type is array (2**r-1 downto 0) of std_logic_vector (w-1 downto 0);   
  signal RAM : ram_type;   
begin   
  process (clk)   
  begin   
    if (clk'event and clk = '1') then   
      if (we = '1') then   
        RAM(conv_integer(unsigned(adr))) <= di;  
      end if; 
     do <= RAM(conv_integer(unsigned(adr)));		
    end if;   
  end process;   
        
 end spbram_arch;

1.PNG
 

Code:
  process (clk)   
  begin   
    if (clk'event and clk = '1') then   
      if (we = '1') then   
        RAM(conv_integer(unsigned(adr))) <= di;  
      end if; 
     [COLOR="#FF0000"]do <= RAM(conv_integer(unsigned(adr)));	[/COLOR]	
    end if;   
  end process;
Infers DFFs at the output.


removing the other statements for writing to improve visibility of the problem.

Code VHDL - [expand]
1
2
3
4
5
6
process (clk)   
  begin   
    if (clk'event and clk = '1') then   
     do <= RAM(conv_integer(unsigned(adr)));.
    end if;   
  end process;


assign the output do outside the process right now it's within the if rising_edge(clk) then (which you should be using instead of 'event stuff).
 

thanks ads-ee for answering
if I assign the output do outside the process the synthesizer will use distributed ram instead of block ram

- - - Updated - - -

i change the code like this but it inffered 32 bit register
Code:
library ieee;   
use ieee.std_logic_1164.all;   
use ieee.std_logic_unsigned.all;   
use ieee.std_logic_arith.all;
 
entity spbram is  
 generic ( w : integer := 32; 
             -- number of bits per RAM word
            r : integer := 12); 
             -- 2^r = number of words in RAM 	
  port (clk  : in std_logic;   
        we   : in std_logic;  
        en   : in std_logic;		  
        addr    : in std_logic_vector(r-1 downto 0);   
        di   : in std_logic_vector(w-1 downto 0);   
        do  : out std_logic_vector(w-1 downto 0));   
end spbram;   
architecture spbram_arch of spbram is   
  type ram_type is array (2**r-1 downto 0) of std_logic_vector (w-1 downto 0);   
  signal RAM : ram_type;   
begin   
  process (clk)   
  begin   
    if (clk'event and clk = '1') then   
      if (en = '1') then 
        do <= RAM(conv_integer(unsigned(addr)));
        if (we = '1') then   
           RAM(conv_integer(unsigned(addr))) <= di;
        end if; 
      end if;  						
    end if;  
  end process;   
        
 end spbram_arch;

- - - Updated - - -

i use spartan 6 as my hardware and i found the following block diagram in spartan 6 bram resources,
2.PNG
 

This is taken from the whitepaper. It's kind of old but Xilinx hasn't changed the inference of BRAM since then AFAIK.

Code VHDL - [expand]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
-- 'write first' or transparent mode
process (clk)
begin
if (rising_edge(clk)) then
if (we = '1') then
 mem(conv_integer(addr)) <= di ;
 do <= di;
else
 do <= mem(conv_integer(addr));
end if;
end if;
end process;
-- 'read first' or read before write(slower)
process (clk)
begin
if (rising_edge(clk)) then
if (we = '1') then
mem(conv_integer(addr)) <= di;
end if;
do <= mem(conv_integer(addr));
end if;
end process;
-- 'no change' mode
process (clk)
begin
if (rising_edge(clk)) then
if (we = '1') then
mem(conv_integer(addr)) <= di ;
else
do <= mem(conv_integer(addr));
end if;
end if;
end process;



XST user guide shows this code but it looks like what you wrote.

Code VHDL - [expand]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
Single-Port RAM in Read-First Mode VHDL Coding Example One
--
-- Read-First Mode
--
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
entity rams_01 is
port (clk : in std_logic;
we : in std_logic;
en : in std_logic;
addr : in std_logic_vector(5 downto 0);
di : in std_logic_vector(15 downto 0);
do : out std_logic_vector(15 downto 0));
end rams_01;
architecture syn of rams_01 is
type ram_type is array (63 downto 0) of std_logic_vector (15 downto 0);
signal RAM: ram_type;
begin
process (clk)
begin
if clk’event and clk =1then
if en =1then
if we =1then
RAM(conv_integer(addr)) <= di;
end if;
do <= RAM(conv_integer(addr)) ;
end if;
end if;
end process;
end syn;


Is the view you are using the post par schematic? Have you checked with a placed and routed design to see if MAP used the internal register?
 

3.PNG
i change it to no change mode as u write but it still has 32-bit register.
 

Status
Not open for further replies.

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top