Site Home Archive Home FAQ Home How to search the Archive How to Navigate the Archive
Compare FPGA features and resources
Threads starting:
Authors:A B C D E F G H I J K L M N O P Q R S T U V W X Y Z
The "waiting for clock" status indicates that your acquisition clock is not active. As other posters indicated, you should check that your acquisition clock is active and specified correctly in your SignalTap II file. You can select your acquisition clock by browsing to your clock input from the Signal Configuration Pane of the SignalTap II file (.stp). When the acquisition clock is active and the trigger condition is met, the status of the ELA changes to "Acquiring post-trigger data", indicating that the Embedded Logic Analyzer (ELA) is acquiring data and filling your circular buffer. When the buffer is full, the status will change to "Offloading acquired data" and then to "Ready to acquire". So I don't think you're overwriting your own data, as your first post asked. When you say you reset the device, what do you mean? Toggling a reset signal on your logic that enables a gated clock would be strange, and I'd recommend you switch to using a non-gated clock for your acquisition clock. If you are asserting the DEVCLRn pin to do a hardware reset of the device, you will have trouble. DEVCLRn clears all registers in the device including the ELA registers. When the ELA registers are cleared, the SignalTap II file will not display the correct status until you re-run the analysis by choosing Stop Analysis followed by Run Analysis (Processing menu). It seems most likely that your acquisition clock is incorrectly set in the SignalTap II file (.stp), or has strange logic on the clock path, given your recent posting. Hence cleaning up this clock / using another clock would be a good idea. For more info and details, see the SignalTap chapter of the Quartus reference manual at http://www.altera.com/literature/hb/qts/qts_qii53009.pdf Hope this helps, Vaughn Altera [v b e t z (at) altera.com]Article: 86676
First time post... Quick question regarding post PAR simulation. What can be done to retain sensible signal names when doing post place-and-route (timing) simulation in ModelSim? Behavioural simulation retains the nice hierarchical structure of all instances and their respective signal names, and I would like to find out whether this is possible for timing simulation, or what is the closest setup that can be achieved. I have "Retain Hierarchy" selected under the Simulation Model Properties, and my Simulation Model Target is ModelSimXE (VHDL). Am using Xilinx ISE 7.1 (SP2) and MXE6.0.Article: 86677
Take a look at the paper writte by Julius Smith from Stanford centre for computer/music research (google it). It is THE definitive paper on arbitrary sample rate conversion of band-limited signals. I'd be intererested to hear if anyone has attempted an FPGA implementation of sample rate conversion based on his algorithm... Good luck, PeterC.Article: 86678
Hi, there I am a newbie in fpga area. I have a question about xps 6.3 mapper I am creating a project file based on xapp 482 which has a bootloader function and one can load application code( in C ) to the SRAM. >From the hardware aspect, I wanna add custom function using FSL. But as XPS goes through the xflow. It stopped at the map phase. It has two suggestions came from the tool. Now the questions 1. I dont know where can change this parameter "-r" and 2. if the "-r" doesnot work, must I change to another board? actually the user function core has only 1 int array with 40 elements as input, and 1 int array with 1 element as output. can somebody tell me why the size turn to so big. coz i checked the usage of "Number of 4 input LUTs:" without using the user function is 50%. ############################# Release 6.3i Map G.38 Xilinx Mapping Report File for Design 'system' Design Information ------------------ Command Line : map -o system_map.ncd -pr b system.ngd system.pcf Target Device : 3s200 Target Package : ft256 Target Speed : -4 Mapper Version : spartan3 -- $Revision: 1.16.8.2 $ Mapped Date : Mon Jul 04 00:44:16 2005 Design Summary -------------- Number of errors: 0 Number of warnings: 71 Logic Utilization: Number of Slice Flip Flops: 1,521 out of 3,840 39% Number of 4 input LUTs: 1,924 out of 3,840 50% Number of RPM macros: 5 Total equivalent gate count for design: 130,923 Additional JTAG gate count for IOBs: 3,744 project with user function ######################################### ERROR:Pack:18 - The design is too large for the given device and package. If the slice count exceeds device resources you might try to disable register ordering (-r). Also if your design contains AREA_GROUPs, you may be able to improve density by adding COMPRESSION to your AREA_GROUPs if you haven't done so already. NOTE: An NCD file will still be generated to allow you to examine the mapped design. This file is intended for evaluation use only, and will not process successfully through PAR. This mapped NCD file can be used to evaluate how the design's logic has been mapped into FPGA logic resources. It can also be used to analyze preliminary, logic-level (pre-route) timing with one of the Xilinx static timing analysis tools (TRCE or Timing Analyzer). Design Summary: Number of errors: 1 Number of warnings: 75 Logic Utilization: Number of Slice Flip Flops: 1,793 out of 3,840 46% Number of 4 input LUTs: 11,925 out of 3,840 310% (OVERMAPPED) Logic Distribution: Number of occupied Slices: 6,580 out of 1,920 342% (OVERMAPPED) Number of Slices containing only related logic: 6,123 out of 6,580 93% Number of Slices containing unrelated logic: 457 out of 6,580 6% *See NOTES below for an explanation of the effects of unrelated logic Total Number 4 input LUTs: 12,929 out of 3,840 336% (OVERMAPPED) Number used as logic: 11,925 Number used as a route-thru: 579 Number used for Dual Port RAMs: 264 (Two LUTs used per Dual Port RAM) Number used as Shift registers: 161 Number of bonded IOBs: 78 out of 173 45% IOB Flip Flops: 74 Number of Block RAMs: 1 out of 12 8% Number of MULT18X18s: 3 out of 12 25% Number of GCLKs: 2 out of 8 25% Number of BSCANs: 1 out of 1 100% Number of RPM macros: 5 Total equivalent gate count for design: 226,883 Additional JTAG gate count for IOBs: 3,744 Peak Memory Usage: 163 MB Thanks for any kinds of tips and helpsArticle: 86679
Any further suggestions ? Rgds Andr=E9Article: 86680
I recently tried out DDR controller design from Xilinx(xapp608), and found it does not work properly during simulation when I tried to use full burst read and write. I want to burst for one full row, but the controller always stops after it reaches column 508, I wonder why? Has anybody used this before? Regards HongtuArticle: 86681
On 3 Jul 2005 20:58:03 -0700, peter@geckoaudio.com wrote: >Quick question regarding post PAR simulation. What can be done to >retain sensible signal names when doing post place-and-route (timing) >simulation in ModelSim? It ain't ModelSim's fault. The simulator is simulating the signal names it found in the code it was given. Synthesis typically builds lots of new signals, changes the names of things, optimises things away and so forth. Sometimes you can control some of this. Most times, most of it will change :-) >Behavioural simulation retains the nice hierarchical structure of all >instances and their respective signal names It hardly "retains" it - as I said, the simulator simulates what it's given. In the case of behavioural (pre-synthesis) simulation, what it's given is exactly your source code. > and I would like to find >out whether this is possible for timing simulation, or what is the >closest setup that can be achieved. I have "Retain Hierarchy" >selected under the Simulation Model Properties, and my Simulation Model >Target is ModelSimXE (VHDL). Am using Xilinx ISE 7.1 (SP2) and MXE6.0. Now I'm a little out of my depth, as I don't know ISE all that well. It sounds as though you are doing all the sensible things. Sometimes you can set "don't touch" or similar attributes on objects such as registers. Note that synthesis usually flattens all VHDL structures to either single bit std_logics or to one-dimensional std_logic_vectors, so if you've used any records or two-dimensional arrays then their names will almost certainly disappear. Also, if you have made any parameterised entities using VHDL generics, the actual instances after synthesis will probably have component names that are in some way decorated with the actual values of the generic - so, for example, MyInstance : MyComponent generic map (N=>5) port map... might appear after synthesis as an instance of a component called "MyComponent_5" or suchlike. Sorry to be so unhelpful, but it's a problem! I guess some ISE experts will chime in to give you some more specific suggestions. -- Jonathan Bromley, Consultant DOULOS - Developing Design Know-how VHDL, Verilog, SystemC, Perl, Tcl/Tk, Verification, Project Services Doulos Ltd. Church Hatch, 22 Market Place, Ringwood, BH24 1AW, UK Tel: +44 (0)1425 471223 mail:jonathan.bromley@doulos.com Fax: +44 (0)1425 471573 Web: http://www.doulos.com The contents of this message may contain personal views which are not the views of Doulos Ltd., unless specifically stated.Article: 86682
"geoffrey wall" <wallge@eng.fsu.edu> writes: > Is anyone aware of a software package that can cross reference vhdl language > components and > instantiations of those components? VHDL-mode of Emacs can do this (if I understand you correctly). Alternatively, VHDLDoc generates hyperlinked html of your source files, showing what is instantiated where. Maybe that helps? The manual is here: http://schwick.home.cern.ch/schwick/vhdldoc/doc/vhdldoc-manual.html Cheers, Martin -- martin.j.thompson@trw.com TRW Conekt, Solihull, UK http://www.trw.com/conektArticle: 86683
Thanks alfek for your suggestion.Article: 86684
More informations about my configuration: I use a Virtex-II PRO XC2VP7 FG456-6 development board . The SDRAM is 100 MHz 32 bits ( so I was expecting a speed around 400 MB/s ?) For testing the writing speed, the programme is : XGpio_mSetDataReg(XPAR_CARTE_DLP_OUT_BASEADDR, 0x2);// led on for(j=0;j<10;j++) { position_ecriture = START_SDRAM; // start adress of the 32 MB SDRAM for (i=0;i<0x7FFFFF;i++){ *position_ecriture = 1; // writing test // k = *position_ecriture; // reading test position_ecriture ++; } } XGpio_mSetDataReg(XPAR_CARTE_DLP_OUT_BASEADDR, 0x3);// led off I calculate the time between the led turn ON and OFF. When I use memcopy, it's the same time. When the INCLUDE_BURST_CACHELN_SUPPORT is activated, the writing speed is 53 MB/s (and 33 MB/s when not) 2 questions about what was said: - How can I activate the cache? - a 64 bits mode exists for the SDRAM ? PierreArticle: 86685
Hi, When you enabled the line, the signal cur_address_r2 is assigned. But I can't find any uses of the signal, so XST will in any case remove the assignment. Could you also explain more on what the failure is when you enabled the line? The error condition can explain what the problem is. Göran Sidney Cadot wrote: > Dear all, > > Lately I have been trying to design and implement a synchronous FIFO > using a cyclic buffer, that can be synthesized by XST to use Block RAMs. > > I now have a version that works (it does so in simulation using GHDL). I > have attached it below. However, since it doesn't follow the prescribed > pattern for BLOCK RAM inference, the code as shown synthesizes to an > implementation that uses "distributed RAM" instead. > > Fortunately, I can easily get it in a form where BRAM can be inferred by > enabling the currently-commented-out line marked "ENABLE FOR BRAM", > around line 70. > > The thing is that if I do this, the entity stops functioning as > intended. This is particularly strange since (as far as I can tell) the > change shouldn't affect the architecture's semantics in any way! > > Any help/pointers by one of the VHDL gurus here would be much appreciated. > > Best regards, > > Sidney > > ------------- ramfifo.vhdl > > > library ieee; > > use ieee.std_logic_1164.all, > ieee.numeric_std.all; > > entity RAMFIFO is > port( > CLK : in std_logic; > data_in : in std_logic_vector(7 downto 0); > data_out : out std_logic_vector(7 downto 0); > status : out std_logic_vector(7 downto 0); > reset : in std_logic; > shift_in : in std_logic; > shift_out : in std_logic > ); > end entity RAMFIFO; > > architecture arch of RAMFIFO is > > signal cur_address_r : unsigned(3 downto 0) := "0000"; > signal cur_address_r2 : unsigned(3 downto 0) := "0000"; > signal cur_num_entries : unsigned(3 downto 0) := "0000"; > signal cur_address_w : unsigned(3 downto 0); > > signal nxt_address_r : unsigned(3 downto 0); > signal nxt_num_entries : unsigned(3 downto 0); > > signal sig_data_r : std_logic_vector(7 downto 0); > > type RAMType is array(0 to 15) of std_logic_vector(7 downto 0); > > -- initialize the ram below with sensible ascii values for debugging > signal ram : RAMType := ( > x"30", x"31", x"32", x"33", x"34", x"35", x"36", x"37", > x"38", x"39", x"41", x"42", x"43", x"44", x"45", x"46" > ); > > signal shift_in_possible : std_logic; > signal shift_out_possible : std_logic; > signal shift_in_will_happen : std_logic; > signal shift_out_will_happen : std_logic; > > begin > > status <= std_logic_vector(cur_address_r) & > std_logic_vector(cur_num_entries); > > process (CLK) is > begin > if rising_edge(CLK) then > if reset = '1' then > cur_num_entries <= "0000"; > else > if shift_in_will_happen = '1' then > ram(to_integer(cur_address_w)) <= data_in; > end if; > cur_address_r <= nxt_address_r; > cur_num_entries <= nxt_num_entries; > > -- if the line below is commented out, > -- XST generates DISTRIBUTED RAM, > -- and the FIFO works properly. > -- > -- if the line below is enabled, > -- XST generates BLOCK RAM, > -- and the fifo does not work properly. > > -- cur_address_r2 <= nxt_address_r; -- ENABLE FOR BRAM > > end if; > end if; > end process; > > sig_data_r <= ram(to_integer(cur_address_r)); > > with cur_num_entries select > data_out <= x"00" when "0000", > sig_data_r when others; > > nxt_address_r <= cur_address_r + 1 when shift_out_will_happen = '1' > else cur_address_r; > > nxt_num_entries <= cur_num_entries + 1 when shift_in_will_happen = > '1' and shift_out_will_happen = '0' > else cur_num_entries - 1 when shift_in_will_happen = > '0' and shift_out_will_happen = '1' > else cur_num_entries; > > cur_address_w <= cur_address_r + cur_num_entries; > > shift_in_will_happen <= shift_in and shift_in_possible; > shift_out_will_happen <= shift_out and shift_out_possible; > > shift_in_possible <= '1' when (cur_num_entries /= "1111") or > shift_out = '1' else '0'; > shift_out_possible <= '1' when (cur_num_entries /= "0000") else '0'; > > end architecture arch;Article: 86686
Hi Ben, I am just curious how does it work, what you've mentioned above. You sample a pushbutton signal that bounces, then edge-detect it and make sure that edge is one system clock wide. As a resullt you have several SYSTEM_CLK wide edges following push/release. Which one should be counted as actual push signal? Could you please explain it a bit more. I've heard of another way to fight with switch bouncing. The trick lies in using a shift register to input pushbutton signal and an AND gate to detect all-ones case, which is equivalent to pushed button state. RegardsArticle: 86687
A question for the Xilinx guru's out there: I am experimenting with the map -bp switch (map slice logic) in order to make better use of device resources. I am constraining my outputs with IOB = TRUE so that the mapper maps them to IOB flops. When I use the -bp switch, however, I have an output flop that is mapped to a block RAM despite the IOB constraint. The clk-to-out timing specification is unreachable so the map fails with an error message. I have tried applying the IOB constraint in the verilog and in the UCF file. Is there a way to force the mapper to ignore the -bp switch for certain flops (other than creating and maintaining a mapping file), or am I stuck with having to choose between IOB packed flops and block RAM mapping? I am using ISE6.1i. Thanks in advance! MarkArticle: 86688
Hi bobrics, > I am just curious how does it work, what you've mentioned above. You > sample a pushbutton signal that bounces, then edge-detect it and make > sure that edge is one system clock wide. As a resullt you have several > SYSTEM_CLK wide edges following push/release. Which one should be > counted as actual push signal? Could you please explain it a bit more. Actually, I wasn't giving advice on how to de-bounce a switch, but on how generally it's a bad idea to clock a register from something that isn't a clock. However, the circuit I (sort-of) described will work quite well if you sample at some very slow rate, 1ms or so. That is, the edge-detector should work on samples from the PBswitch line that are 1ms apart. For level-detection, your AND-gate-and-shift-register circuit will also work, but again you should sample (i.e. shift) at a much lower rate than your system clock. This under-sampling is just a crude low-pass filter on the input signal. I'd never bother with an external debounce circuit (not even RC) - in an FPGA, the simple digital filter is so close to being free it makes no difference... :-) -Ben-Article: 86689
The FPGAworld Conference addresses all aspects of digital and hardware/software system engineering on FPGA technology. It is a discussion and network forum for researchers and engineers working on industrial and research projects, state-of-the-art investigations, development, and applications. The programme for this year's event will soon be made public. Our committees are currently in the process of selecting the most intersting papers. The number of registered visitors are increasing and the number of seats are limited so be shure to register in time! We are also proud to announce that Xilinx, Synplicity and Vinova have decided to sponsor the conference. Swedish electronics publication, Elektroniktidningen, is our media partner for this year's event. More information is available at http://www.fpgaworld.com/conferenceArticle: 86690
"Sidney Cadot" <sidney@jigsaw.nl> wrote in message news:b9e71$42c80b47$915e9a26$2732@news1.tudelft.nl... > Dear all, > > Lately I have been trying to design and implement a synchronous FIFO > using a cyclic buffer, that can be synthesized by XST to use Block RAMs. > > I now have a version that works (it does so in simulation using GHDL). I > have attached it below. However, since it doesn't follow the prescribed > pattern for BLOCK RAM inference, the code as shown synthesizes to an > implementation that uses "distributed RAM" instead. > > Fortunately, I can easily get it in a form where BRAM can be inferred by > enabling the currently-commented-out line marked "ENABLE FOR BRAM", > around line 70. > /SNIP/ > process (CLK) is > begin /SNIP/ > end process; > > sig_data_r <= ram(to_integer(cur_address_r)); > /SNIP/ Hi Sidney, I'm not a guru. I haven't taken the time to read every line of your code and I don't understand how it *ever* infers BRAM. It seems to me with my limited knowledge that you need to both write the FIFO and read the FIFO inside clocked processes. Looks here, like you're reading it asynchronously. If you just put the line: sig_data_r <= ram(to_integer(cur_address_r)); after the "else" in your process, I might expect it to infer a BRAM. Cheers, -- Alf Katz alfkatz@remove.the.obvious.ieee.orgArticle: 86691
Hi All Does anybody know if an XBD file is available for the Xilinx ML402 board? I'm currently using EDK6.3 - I'd also be grateful if someone could tell me whether a BSP for this board comes with EDK7.1. I've been adding my own plb peripherals to the Xilinx ML402 reference design, but I've reached a stage now where I really need to start afresh with a smaller design. Synthesis and implementation are taking too long, and aside from my own peripherals, I only really need an opb2plb_bridge, plb_ddr and perhaps a uart for debugging. Best regards Allan WillcoxArticle: 86692
Evening... The NIOS2 sources are only available on the shipped CD's..right? So...then the downloadble NIOS2 evaluation version breaks the GPL since it only contains gcc/binutils binaries? rickArticle: 86693
"Sidney Cadot" <sidney@jigsaw.nl> wrote in message news:b9e71$42c80b47$915e9a26$2732@news1.tudelft.nl... > Dear all, > > Lately I have been trying to design and implement a synchronous FIFO > using a cyclic buffer, that can be synthesized by XST to use Block RAMs. > > I now have a version that works (it does so in simulation using GHDL). I > have attached it below. However, since it doesn't follow the prescribed > pattern for BLOCK RAM inference, the code as shown synthesizes to an > implementation that uses "distributed RAM" instead. > > Fortunately, I can easily get it in a form where BRAM can be inferred by > enabling the currently-commented-out line marked "ENABLE FOR BRAM", > around line 70. > > The thing is that if I do this, the entity stops functioning as > intended. This is particularly strange since (as far as I can tell) the > change shouldn't affect the architecture's semantics in any way! > > Any help/pointers by one of the VHDL gurus here would be much appreciated. > > Best regards, > > Sidney > > ------------- ramfifo.vhdl > > > library ieee; > > use ieee.std_logic_1164.all, > ieee.numeric_std.all; > > entity RAMFIFO is > port( > CLK : in std_logic; > data_in : in std_logic_vector(7 downto 0); > data_out : out std_logic_vector(7 downto 0); > status : out std_logic_vector(7 downto 0); > reset : in std_logic; > shift_in : in std_logic; > shift_out : in std_logic > ); > end entity RAMFIFO; > > architecture arch of RAMFIFO is > > signal cur_address_r : unsigned(3 downto 0) := "0000"; > signal cur_address_r2 : unsigned(3 downto 0) := "0000"; > signal cur_num_entries : unsigned(3 downto 0) := "0000"; > signal cur_address_w : unsigned(3 downto 0); > > signal nxt_address_r : unsigned(3 downto 0); > signal nxt_num_entries : unsigned(3 downto 0); > > signal sig_data_r : std_logic_vector(7 downto 0); > > type RAMType is array(0 to 15) of std_logic_vector(7 downto 0); > > -- initialize the ram below with sensible ascii values for debugging > signal ram : RAMType := ( > x"30", x"31", x"32", x"33", x"34", x"35", x"36", x"37", > x"38", x"39", x"41", x"42", x"43", x"44", x"45", x"46" > ); > > signal shift_in_possible : std_logic; > signal shift_out_possible : std_logic; > signal shift_in_will_happen : std_logic; > signal shift_out_will_happen : std_logic; > > begin > > status <= std_logic_vector(cur_address_r) & > std_logic_vector(cur_num_entries); > > process (CLK) is > begin > if rising_edge(CLK) then > if reset = '1' then > cur_num_entries <= "0000"; > else > if shift_in_will_happen = '1' then > ram(to_integer(cur_address_w)) <= data_in; > end if; > cur_address_r <= nxt_address_r; > cur_num_entries <= nxt_num_entries; > > -- if the line below is commented out, > -- XST generates DISTRIBUTED RAM, > -- and the FIFO works properly. > -- > -- if the line below is enabled, > -- XST generates BLOCK RAM, > -- and the fifo does not work properly. > > -- cur_address_r2 <= nxt_address_r; -- ENABLE FOR BRAM > > end if; > end if; > end process; > > sig_data_r <= ram(to_integer(cur_address_r)); > > with cur_num_entries select > data_out <= x"00" when "0000", > sig_data_r when others; > > nxt_address_r <= cur_address_r + 1 when shift_out_will_happen = '1' > else cur_address_r; > > nxt_num_entries <= cur_num_entries + 1 when shift_in_will_happen = > '1' and shift_out_will_happen = '0' > else cur_num_entries - 1 when shift_in_will_happen = > '0' and shift_out_will_happen = '1' > else cur_num_entries; > > cur_address_w <= cur_address_r + cur_num_entries; > > shift_in_will_happen <= shift_in and shift_in_possible; > shift_out_will_happen <= shift_out and shift_out_possible; > > shift_in_possible <= '1' when (cur_num_entries /= "1111") or > shift_out = '1' else '0'; > shift_out_possible <= '1' when (cur_num_entries /= "0000") else '0'; > > end architecture arch; Hi Sidney, There is one serious flaw in your code: you don't reset the pointers, so resetting your fifo after some usage will actually bring it in a non-working state. In my follow-up post, I'll dump some code (entity + lbram and bram architectures + package + testbench). It does simulate, but I didn't try to synthesize it. Feel free to use and improve it (you can dump the fifo count by using the pointers and sacrificing 1 entry). Regards, Alvin.Article: 86694
Here's the code. Alvin. ----------------------------------------------------------- -- RAMFIFO.vhd ----------------------------------------------------------- library ieee; use ieee.std_logic_1164.all; use ieee.numeric_std.all; entity RAMFIFO is generic ( address_width : POSITIVE := 4 ); port ( CLK : in std_logic; data_in : in std_logic_vector(7 downto 0); data_out : out std_logic_vector(7 downto 0); status : out std_logic_vector(2 * address_width downto 0); reset : in std_logic; shift_in : in std_logic; shift_out : in std_logic ); end entity RAMFIFO; ----------------------------------------------------------- -- RAMFIFO_LBRAM.vhd ----------------------------------------------------------- architecture LBRAM of RAMFIFO is signal rd_addr : unsigned(address_width - 1 downto 0) := (others => '0'); signal wr_addr : unsigned(address_width - 1 downto 0) := (others => '0'); signal has_data : boolean := false; signal count : unsigned(address_width downto 0) := (others => '0'); signal read_data : std_logic_vector(7 downto 0); type RAMType is array(0 to 2**address_width - 1) of std_logic_vector(7 downto 0); signal ram : RAMType := (others => (others => '0')); signal full : boolean; signal empty : boolean; signal push : boolean; signal pop : boolean; begin empty <= not has_data; full <= has_data and (rd_addr = wr_addr); push <= not full and (shift_in = '1'); pop <= not empty and (shift_out = '1'); state: process (CLK) is begin if rising_edge(CLK) then if (reset = '1') then rd_addr <= (others => '0'); wr_addr <= (others => '0'); has_data <= false; count <= (others => '0'); else if push then wr_addr <= wr_addr + 1; end if; if pop then rd_addr <= rd_addr + 1; end if; if (push and not pop) then count <= count + 1; has_data <= true; elsif (not push and pop) then count <= count - 1; has_data <= (count /= 1); end if; end if; end if; end process; -- LBRAM ramdesc: process (CLK) is begin if rising_edge(CLK) then if push then ram(to_integer(wr_addr)) <= data_in; end if; end if; end process; read_data <= ram(to_integer(rd_addr)); -- delay by one cycle, clear the data when no pop ram_if: process (CLK) is begin if rising_edge(CLK) then if pop then data_out <= read_data; else data_out <= (others => '0'); end if; end if; end process; status <= std_logic_vector(rd_addr) & std_logic_vector(count); end architecture LBRAM; ----------------------------------------------------------- -- RAMFIFO_BRAM.vhd ----------------------------------------------------------- architecture BRAM of RAMFIFO is signal rd_addr : unsigned(address_width - 1 downto 0) := (others => '0'); signal wr_addr : unsigned(address_width - 1 downto 0) := (others => '0'); signal has_data : boolean := false; signal count : unsigned(address_width downto 0) := (others => '0'); signal read_data : std_logic_vector(7 downto 0); type RAMType is array(0 to 2**address_width - 1) of std_logic_vector(7 downto 0); signal ram : RAMType := (others => (others => '0')); signal full : boolean; signal empty : boolean; signal push : boolean; signal pop : boolean; begin empty <= not has_data; full <= has_data and (rd_addr = wr_addr); push <= not full and (shift_in = '1'); pop <= not empty and (shift_out = '1'); state: process (CLK) is begin if rising_edge(CLK) then if (reset = '1') then rd_addr <= (others => '0'); wr_addr <= (others => '0'); has_data <= false; count <= (others => '0'); else if push then wr_addr <= wr_addr + 1; end if; if pop then rd_addr <= rd_addr + 1; end if; if (push and not pop) then count <= count + 1; has_data <= true; elsif (not push and pop) then count <= count - 1; has_data <= (count /= 1); end if; end if; end if; end process; -- BRAM ramwrdesc: process (CLK) is begin if rising_edge(CLK) then if push then ram(to_integer(wr_addr)) <= data_in; end if; end if; end process; ramrddesc: process (CLK) is begin if rising_edge(CLK) then if not pop then read_data <= (others => '0'); -- reset happens in RAM too else read_data <= ram(to_integer(rd_addr)); end if; end if; end process; -- copy bram output data_out <= read_data; status <= std_logic_vector(rd_addr) & std_logic_vector(count); end architecture BRAM; ----------------------------------------------------------- -- RAMFIFO_PCK.vhd ----------------------------------------------------------- library ieee; use ieee.std_logic_1164.all; use ieee.numeric_std.all; package RAMFIFO_PCK is component RAMFIFO generic ( address_width : POSITIVE := 4 ); port ( CLK : in std_logic; data_in : in std_logic_vector(7 downto 0); data_out : out std_logic_vector(7 downto 0); status : out std_logic_vector(2 * address_width downto 0); reset : in std_logic; shift_in : in std_logic; shift_out : in std_logic ); end component; end package RAMFIFO_PCK; package body RAMFIFO_PCK is -- Empty end package body RAMFIFO_PCK; ----------------------------------------------------------- -- RAMFIFO_TB.vhd ----------------------------------------------------------- library ieee; use ieee.std_logic_1164.all; use ieee.numeric_std.all; use work.ramfifo_pck.all; entity RAMFIFO_TB is end entity RAMFIFO_TB; architecture TB1 of RAMFIFO_TB is signal clk : std_logic := '0'; signal reset : std_logic := '0'; signal data_in : std_logic_vector(7 downto 0) := (others => '1'); signal shift_in : std_logic := '0'; signal shift_out : std_logic := '0'; signal data_out : std_logic_vector(7 downto 0); signal status : std_logic_vector(4 + 5 - 1 downto 0); type stimulus is record reset : std_logic; data_in : std_logic_vector(7 downto 0); shift_in : std_logic; shift_out : std_logic; end record; type stimuli is array (natural range <>) of stimulus; constant max_vector : natural := 68; constant vector : stimuli(1 to max_vector) := ( ('1', x"fe", '0', '0'), -- reset fifo ('0', x"fd", '0', '1'), -- pop empty ('0', x"01", '1', '0'), -- push 01 ('0', x"02", '1', '0'), -- push 02 ('0', x"03", '1', '0'), -- push 03 ('0', x"04", '1', '0'), -- push 04 ('0', x"05", '1', '0'), -- push 05 ('0', x"06", '1', '0'), -- push 06 ('0', x"07", '1', '0'), -- push 07 ('0', x"08", '1', '0'), -- push 08 ('0', x"09", '1', '0'), -- push 09 ('0', x"0a", '1', '0'), -- push 0A ('0', x"0b", '1', '0'), -- push 0B ('0', x"fc", '0', '1'), -- pop 01 ('0', x"fb", '0', '1'), -- pop 02 ('0', x"fa", '0', '1'), -- pop 03 ('0', x"f9", '0', '1'), -- pop 04 ('0', x"f8", '0', '1'), -- pop 05 ('0', x"f7", '0', '1'), -- pop 06 ('0', x"f6", '0', '1'), -- pop 07 ('0', x"f5", '0', '1'), -- pop 08 ('0', x"f4", '0', '1'), -- pop 09 ('0', x"f3", '0', '1'), -- pop 0a ('0', x"f2", '0', '1'), -- pop 0b ('0', x"f1", '0', '1'), -- pop empty ('0', x"10", '1', '0'), -- push 10 ('0', x"11", '1', '0'), -- push 11 ('0', x"12", '1', '0'), -- push 12 ('0', x"13", '1', '0'), -- push 13 ('0', x"14", '1', '0'), -- push 14 ('0', x"15", '1', '0'), -- push 15 ('0', x"16", '1', '0'), -- push 16 ('0', x"17", '1', '0'), -- push 17 ('0', x"18", '1', '0'), -- push 18 ('0', x"19", '1', '0'), -- push 19 ('0', x"1a", '1', '0'), -- push 1a ('0', x"1b", '1', '0'), -- push 1b ('0', x"1c", '1', '0'), -- push 1c ('0', x"1d", '1', '0'), -- push 1d ('0', x"1e", '1', '0'), -- push 1e ('0', x"1f", '1', '0'), -- push 1f ('0', x"20", '1', '0'), -- push 20 -- overflow garanteed ('0', x"f0", '0', '1'), -- pop 10 ('0', x"ef", '0', '1'), -- pop 11 ('0', x"ee", '0', '1'), -- pop 12 ('0', x"ed", '0', '1'), -- pop 13 ('0', x"ec", '0', '1'), -- pop 14 ('0', x"eb", '0', '1'), -- pop 15 ('0', x"ea", '0', '1'), -- pop 16 ('0', x"e9", '0', '1'), -- pop 17 ('0', x"e8", '0', '1'), -- pop 18 ('0', x"e7", '0', '1'), -- pop 19 ('0', x"e6", '0', '1'), -- pop 1a ('0', x"e5", '0', '1'), -- pop 1b ('0', x"e4", '0', '1'), -- pop 1c ('0', x"e3", '0', '1'), -- pop 1d ('0', x"e2", '0', '1'), -- pop 1e ('0', x"e1", '0', '1'), -- pop 1f? ('0', x"e0", '0', '1'), -- pop empty (overflow 20) ('0', x"30", '1', '1'), -- Mixed push/pop ('0', x"31", '1', '0'), ('0', x"df", '0', '1'), ('0', x"32", '1', '0'), ('0', x"de", '0', '0'), ('0', x"33", '1', '0'), ('0', x"34", '1', '1'), ('0', x"dd", '0', '1'), ('0', x"35", '1', '1') ); signal ptr : integer range 1 to max_vector := 1; begin clk <= not clk after 5 ns; -- 100 MHz sel: process (clk) is begin if rising_edge(clk) then if (ptr /= max_vector) then ptr <= ptr + 1; else ptr <= 1; end if; end if; end process; reset <= vector(ptr).reset; data_in <= vector(ptr).data_in; shift_in <= vector(ptr).shift_in; shift_out <= vector(ptr).shift_out; dut : RAMFIFO generic map ( address_width => 4 ) port map ( CLK => clk, data_in => data_in, data_out => data_out, status => status, reset => reset, shift_in => shift_in, shift_out => shift_out ); end architecture TB1;Article: 86695
G=F6ran Bilski wrote: > When you enabled the line, the signal cur_address_r2 is assigned. > But I can't find any uses of the signal, so XST will in any case remove t= he > assignment. No, it will not simply remove the assignment. It will detect cur_address_r2 as a register that can be used as a BRAM register (in contrast to cur_address_r, that is used as an expression to calculate cur_address_w, and cannot therefore be internal to the BRAM). This explains, I think, why enabling the line makes XST infer BRAMS instead of distributed RAM. > Could you also explain more on what the failure is when you enabled the l= ine? > The error condition can explain what the problem is. If I enable the line, the code still compiles perfectly but the resulting FIFO (now implemented by XST using BRAM) doesn't work as intended. As you see, I initialize the RAM to "0123456789ABCDEF". When I hook up the FIFO to a simple RS232-output component, and try to emit "abcdefghij...." (etc.), I will actually get: "0123456789ABCDEFabcdefghij......." So, the bytes I put into the FIFO actually get stored, but they are not made available on time. Regards, SidneyArticle: 86696
> I'm not a guru. I haven't taken the time to read every line of your > code and I don't understand how it *ever* infers BRAM. Well, if you remove the comment line, it does :) > It seems to me with my limited knowledge that you need to both write the > FIFO and read the FIFO inside clocked processes. No, that is not the case. The code is loosely modelled after the sample VHDL code given in the "XST User's Guide" for a dual-ported, synchronous BRAM inference. You will see the same pattern there. Basically, the BRAM is registered; one needs to set the address for both ports synchronously and the contents will then be available on the next clock cycle. > Looks here, like you're > reading it asynchronously. If you just put the line: > > sig_data_r <= ram(to_integer(cur_address_r)); > > after the "else" in your process, I might expect it to infer a BRAM. It does also when the indicated line is uncommented. Try it! :) Regards, SidneyArticle: 86697
Hi Alvin, > There is one serious flaw in your code: you don't reset the pointers, so > resetting your fifo after some usage will actually bring it in a non-working > state. Why so? I synchronously set only the counter to zero upon reset (this is by design); there is no reason why "cur_address_r" would need to be zero as well upon reset. The location "cur_address_r" points to is immaterial- a FIFO is empty iff cur_num_entries is zero. > In my follow-up post, I'll dump some code (entity + lbram and bram > architectures + package + testbench). It does simulate, but I didn't try to > synthesize it. Feel free to use and improve it (you can dump the fifo count > by using the pointers and sacrificing 1 entry). Thanks a lot, I will test this for sure - but I am still curious to know what goes wrong with my code. Best regards, SidneyArticle: 86698
> Here's the code. Thanks. I hope this was something you had made already and not something you did specially for me- I'd feel all guilty. :) One small nit: your line: push <= not full and (shift_in = '1'); Couldn't this be replaced by push <= (not full or shift_out = '1') and (shift_in = '1'); This would allow shifting into an already full buffer, iff in the same cycle you are shifting data out. Regards, SidneyArticle: 86699
<sidney@jigsaw.nl> wrote in message news:1120519464.755269.123880@z14g2000cwz.googlegroups.com... > Hi Alvin, > > > There is one serious flaw in your code: you don't reset the pointers, so > > resetting your fifo after some usage will actually bring it in a non-working > > state. > > Why so? I synchronously set only the counter to zero upon reset (this > is by design); there is no reason why "cur_address_r" would need to be > zero as well upon reset. The location "cur_address_r" points to is > immaterial- a FIFO is empty iff cur_num_entries is zero. > > > In my follow-up post, I'll dump some code (entity + lbram and bram > > architectures + package + testbench). It does simulate, but I didn't try to > > synthesize it. Feel free to use and improve it (you can dump the fifo count > > by using the pointers and sacrificing 1 entry). > > Thanks a lot, I will test this for sure - but I am still curious to > know what goes wrong with my code. > > Best regards, Sidney Oops, I was too fast. Normally, I'd create a read and write pointer (because it's faster than what you're doing). In that case, not resetting both would kill the fifo. you're using the number of words for address calculation. This inferes a full adder, which is slower than an increment. Regards, Alvin.
Site Home Archive Home FAQ Home How to search the Archive How to Navigate the Archive
Compare FPGA features and resources
Threads starting:
Authors:A B C D E F G H I J K L M N O P Q R S T U V W X Y Z