FPGARelated.com
Forums

BRAM synthesis question

Started by Paul Boven March 11, 2008
Hi everyone,

While trying to build a simple VGA driver, I'm running into trouble
getting my video-ram (actually, sample ram) to be synthesized as a dual
port block-ram - it keeps wanting to use up 25% of my LUTs. I've tried
to describe the BRAM as instructed in the xst.pdf documentation, but as
soon as I try to read out the BRAM, the Synthesizer turns it into
distributed RAM. I wonder if anyone would be so kind as to help me
understand why?

The circuit consists of an 8 bit sampler which produces 2's complement
data. It is connected to my Spartan-3 kit and I want the data to be
displayed by the VGA port, as a primitive oscilloscope - just to verify
that I'm getting valid data from the sampler.
The display is generated by comparing the current vertical position
against the sample ram contents for the current horizontal position, and
drawing a pixel if they match -  repeat for every position as the VGA
display is scanned. This would undoubtedly benefit from more advanced
concepts like double-buffering, but I'm slowly working my way up to that.

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;

entity main is
	Port (clk: in STD_LOGIC;
		sample: in STD_LOGIC_VECTOR(7 downto 0)
		red, green, blue: out STD_LOGIC));
...
end main;

architecture Behavioural of main is

type bram_type is array (511 downto 0) of signed (7 downto 0);
signal BRAM: bram_type;
signal BRAM_addra: unsigned (8 downto 0) := "000000000";
signal BRAM_addrb: unsigned (8 downto 0) := "000000000";
signal vert: unsigned (9 downto 0) := "0000000000";

process(clk) -- Read data from the sampler
begin
if(clk'event and clk='1') then
...
	BRAM(to_integer(BRAM_addra)) <= signed(sample);
end if;
end process;

process(clk) -- Display VGA image
begin
if (clk'event and clk = '1')
...
	-- vert runs form 40 to 520, vert - 200 should center signed(0).
	if(BRAM(to_integer(BRAM_addrb)) = signed (vert  - 200)) then
		red <= '1'; green <= '1'; blue <= '1';
	else
		red <='0'; green <= '0'; blue <= '0';
	end if;
	BRAM_addrb <= BRAM_addrb + 1;
	(increment/reset BRAM_addrb and vert as appropriate to scan)
end if;
end process;

The code above gives me this warning: XST:2664 HDL ADVISOR - Unit <main>
: The RAM <Mram_BRAM> will be implemented on LUTs either because you
have described an asynchronous read or because of currently unsupported
block RAM features. If you have described an asynchronous read, making
it synchronous would allow you to take advantage of available block RAM
resources, for optimized device usage and improved timings. Please refer
to your documentation for coding guidelines.

I don't see (and would welcome any suggestions) why this is an
asynchronous read, as it only happens during 'clk' transitions.
If one would rather see the full vhd file, please see
http://www.xs4all.nl/~epboven/main.vhd

Now in order to sidestep this problem, I've introduced a signal bram_buffer:

signal bram_buffer: signed(7 downto 0)
...
	if(bram_buffer = signed(vert - 200) then
		red <= '1'; green <= '1'; blue <= '1';
...
	bram_buffer <= BRAM(to_integer(BRAM_addrb));

This does result in an implementation that uses a block ram, but
curiously the output from XST suggests that the buffer isn't actually
used at all:
INFO:Xst:2691 - Unit <main> : The RAM <Mram_BRAM> will be implemented as
a BLOCK RAM, absorbing the following register(s): <bram_buffer>.

So hooray, but as I just pipelined the BRAM output, my assumption was
that I would now be getting my samples one pixel 'late' and would need
to compensate for that - with the above message thrown in, I'm not sure
of that anymore.

Any comments welcome (please be gentle...)

Regards, Paul Boven.
Paul Boven wrote:

> While trying to build a simple VGA driver, I'm running into trouble > getting my video-ram (actually, sample ram) to be synthesized as a dual > port block-ram - it keeps wanting to use up 25% of my LUTs. I've tried
...
> Any comments welcome
Consider a fifo. -- Mike Treseler
On Mar 11, 9:55 am, Paul Boven <bo...@jive.nl> wrote:
> Hi everyone, > > While trying to build a simple VGA driver, I'm running into trouble > getting my video-ram (actually, sample ram) to be synthesized as a dual > port block-ram - it keeps wanting to use up 25% of my LUTs. I've tried > to describe the BRAM as instructed in the xst.pdf documentation, but as > soon as I try to read out the BRAM, the Synthesizer turns it into > distributed RAM. I wonder if anyone would be so kind as to help me > understand why? > > The circuit consists of an 8 bit sampler which produces 2's complement > data. It is connected to my Spartan-3 kit and I want the data to be > displayed by the VGA port, as a primitive oscilloscope - just to verify > that I'm getting valid data from the sampler. > The display is generated by comparing the current vertical position > against the sample ram contents for the current horizontal position, and > drawing a pixel if they match - repeat for every position as the VGA > display is scanned. This would undoubtedly benefit from more advanced > concepts like double-buffering, but I'm slowly working my way up to that. > > library IEEE; > use IEEE.STD_LOGIC_1164.ALL; > use IEEE.NUMERIC_STD.ALL; > > entity main is > Port (clk: in STD_LOGIC; > sample: in STD_LOGIC_VECTOR(7 downto 0) > red, green, blue: out STD_LOGIC)); > ... > end main; > > architecture Behavioural of main is > > type bram_type is array (511 downto 0) of signed (7 downto 0); > signal BRAM: bram_type; > signal BRAM_addra: unsigned (8 downto 0) := "000000000"; > signal BRAM_addrb: unsigned (8 downto 0) := "000000000"; > signal vert: unsigned (9 downto 0) := "0000000000"; > > process(clk) -- Read data from the sampler > begin > if(clk'event and clk='1') then > ... > BRAM(to_integer(BRAM_addra)) <= signed(sample); > end if; > end process; > > process(clk) -- Display VGA image > begin > if (clk'event and clk = '1') > ... > -- vert runs form 40 to 520, vert - 200 should center signed(0). > if(BRAM(to_integer(BRAM_addrb)) = signed (vert - 200)) then > red <= '1'; green <= '1'; blue <= '1'; > else > red <='0'; green <= '0'; blue <= '0'; > end if; > BRAM_addrb <= BRAM_addrb + 1; > (increment/reset BRAM_addrb and vert as appropriate to scan) > end if; > end process; > > The code above gives me this warning: XST:2664 HDL ADVISOR - Unit <main> > : The RAM <Mram_BRAM> will be implemented on LUTs either because you > have described an asynchronous read or because of currently unsupported > block RAM features. If you have described an asynchronous read, making > it synchronous would allow you to take advantage of available block RAM > resources, for optimized device usage and improved timings. Please refer > to your documentation for coding guidelines. > > I don't see (and would welcome any suggestions) why this is an > asynchronous read, as it only happens during 'clk' transitions. > If one would rather see the full vhd file, please seehttp://www.xs4all.nl/~epboven/main.vhd > > Now in order to sidestep this problem, I've introduced a signal bram_buffer: > > signal bram_buffer: signed(7 downto 0) > ... > if(bram_buffer = signed(vert - 200) then > red <= '1'; green <= '1'; blue <= '1'; > ... > bram_buffer <= BRAM(to_integer(BRAM_addrb)); > > This does result in an implementation that uses a block ram, but > curiously the output from XST suggests that the buffer isn't actually > used at all: > INFO:Xst:2691 - Unit <main> : The RAM <Mram_BRAM> will be implemented as > a BLOCK RAM, absorbing the following register(s): <bram_buffer>. > > So hooray, but as I just pipelined the BRAM output, my assumption was > that I would now be getting my samples one pixel 'late' and would need > to compensate for that - with the above message thrown in, I'm not sure > of that anymore. > > Any comments welcome (please be gentle...) > > Regards, Paul Boven.
The read operation from a BRAM needs to be clocked. Either feed the read address through a register before using it to index the RAM, or register the output of the RAM. Either of these result in a 1 clock delay between the read address and the output data. There are code templates online in the XST users guide. Hope this helps.
Hi Paul,
Yeah, if you look at your code, you're trying to do an asynchronous read. I 
suggest you try simulating your design and also a design where you 
instantiate a block ram. You'll be able to compare and see clearly what the 
block ram does.
HTH., Syms. 


On Mar 11, 7:19=A0am, "Symon" <symon_bre...@hotmail.com> wrote:
> Hi Paul, > Yeah, if you look at your code, you're trying to do an asynchronous read. =
I
> suggest you try simulating your design and also a design where you > instantiate a block ram. You'll be able to compare and see clearly what th=
e
> block ram does. > HTH., Syms.
This is not the first time that someone has tried to read the BRAM asynchronously. I have posted many times, and also inserted a sentence into our documentation that "nothing happens without a clock". Any ideas how we can spread this important (and non-obvious) information even better and wider??? Peter Alfke, Xilinx Applications
On Mar 11, 4:48 pm, Peter Alfke <pe...@xilinx.com> wrote:
> On Mar 11, 7:19 am, "Symon" <symon_bre...@hotmail.com> wrote: > > > Hi Paul, > > Yeah, if you look at your code, you're trying to do an asynchronous read. I > > suggest you try simulating your design and also a design where you > > instantiate a block ram. You'll be able to compare and see clearly what the > > block ram does. > > HTH., Syms. > > This is not the first time that someone has tried to read the BRAM > asynchronously. I have posted many times, and also inserted a sentence > into our documentation that "nothing happens without a clock". > Any ideas how we can spread this important (and non-obvious) > information even better and wider??? > Peter Alfke, Xilinx Applications
Hi Peter, Just rename your component from BRAM to BSRAM ! Synchronous RAM ! As a ROM based on BRAM should be renamed by BSROM. (It is not regular to have synchronous ROM, but yes it is synchronous ( need CLK clock ) too when based on Xilinx BRAM ) Regards, Laurent http://www.amontec.com
job@amontec.com wrote:
> On Mar 11, 4:48 pm, Peter Alfke <pe...@xilinx.com> wrote: >> On Mar 11, 7:19 am, "Symon" <symon_bre...@hotmail.com> wrote: >> >>> Hi Paul, >>> Yeah, if you look at your code, you're trying to do an asynchronous read. I >>> suggest you try simulating your design and also a design where you >>> instantiate a block ram. You'll be able to compare and see clearly what the >>> block ram does. >>> HTH., Syms. >> This is not the first time that someone has tried to read the BRAM >> asynchronously. I have posted many times, and also inserted a sentence >> into our documentation that "nothing happens without a clock". >> Any ideas how we can spread this important (and non-obvious) >> information even better and wider??? >> Peter Alfke, Xilinx Applications > > Hi Peter, > > Just rename your component from BRAM to BSRAM ! Synchronous RAM ! > > As a ROM based on BRAM should be renamed by BSROM. (It is not regular > to have synchronous ROM, but yes it is synchronous ( need CLK clock ) > too when based on Xilinx BRAM ) > > Regards, > Laurent > http://www.amontec.com
This is an FPGA is it not. Nothing in an FPGA happens without a clock. Why would anyone think that BRAM would operate differently ?? My .02 donald
Peter Alfke wrote:

> This is not the first time that someone has tried to read the BRAM > asynchronously. I have posted many times, and also inserted a sentence > into our documentation that "nothing happens without a clock". > Any ideas how we can spread this important (and non-obvious) > information even better and wider???
The problems I see in this newsgroup are a result of hdl designers continuously reinventing templates to infer a block ram by trial and error. If I worked for Xilinx I would write an ap note in vhdl and verilog for a useful application example that infers block ram from code, and then reference that example in all related documents. Feel free to use my public template if you like: http://home.comcast.net/~mike_treseler/block_ram.vhd -- Mike Treseler
On Mar 11, 6:10 pm, donald <Don...@dontdoithere.com> wrote:
> j...@amontec.com wrote: > > On Mar 11, 4:48 pm, Peter Alfke <pe...@xilinx.com> wrote: > >> On Mar 11, 7:19 am, "Symon" <symon_bre...@hotmail.com> wrote: > > >>> Hi Paul, > >>> Yeah, if you look at your code, you're trying to do an asynchronous read. I > >>> suggest you try simulating your design and also a design where you > >>> instantiate a block ram. You'll be able to compare and see clearly what the > >>> block ram does. > >>> HTH., Syms. > >> This is not the first time that someone has tried to read the BRAM > >> asynchronously. I have posted many times, and also inserted a sentence > >> into our documentation that "nothing happens without a clock". > >> Any ideas how we can spread this important (and non-obvious) > >> information even better and wider??? > >> Peter Alfke, Xilinx Applications > > > Hi Peter, > > > Just rename your component from BRAM to BSRAM ! Synchronous RAM ! > > > As a ROM based on BRAM should be renamed by BSROM. (It is not regular > > to have synchronous ROM, but yes it is synchronous ( need CLK clock ) > > too when based on Xilinx BRAM ) > > > Regards, > > Laurent > >http://www.amontec.com > > This is an FPGA is it not. > > Nothing in an FPGA happens without a clock. > > Why would anyone think that BRAM would operate differently ?? > > My .02 > > donald
sorry but you may describe LUT as asynchronous ROM ? -> No Clock ! My 0.02 Laurent http://www.amontec.com
Peter Alfke <peter@xilinx.com> wrote:

>On Mar 11, 7:19=A0am, "Symon" <symon_bre...@hotmail.com> wrote: >> Hi Paul, >> Yeah, if you look at your code, you're trying to do an asynchronous read. = >I >> suggest you try simulating your design and also a design where you >> instantiate a block ram. You'll be able to compare and see clearly what th= >e >> block ram does. >> HTH., Syms. > >This is not the first time that someone has tried to read the BRAM >asynchronously. I have posted many times, and also inserted a sentence >into our documentation that "nothing happens without a clock". >Any ideas how we can spread this important (and non-obvious) >information even better and wider??? >Peter Alfke, Xilinx Applications
A world wide advertising campagne include TV commercials? "And now a serious message from our Xilinx Jedi masters: use the clock!" -- Programmeren in Almere? E-mail naar nico@nctdevpuntnl (punt=.)