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.
BRAM synthesis question
Started by ●March 11, 2008
Reply by ●March 11, 20082008-03-11
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 welcomeConsider a fifo. -- Mike Treseler
Reply by ●March 11, 20082008-03-11
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.
Reply by ●March 11, 20082008-03-11
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.
Reply by ●March 11, 20082008-03-11
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
Reply by ●March 11, 20082008-03-11
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 ApplicationsHi 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
Reply by ●March 11, 20082008-03-11
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.comThis 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
Reply by ●March 11, 20082008-03-11
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
Reply by ●March 11, 20082008-03-11
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 > > donaldsorry but you may describe LUT as asynchronous ROM ? -> No Clock ! My 0.02 Laurent http://www.amontec.com
Reply by ●March 11, 20082008-03-11
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 ApplicationsA 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=.)