|
Prev: errors during MAP
Next: NIOS II + USB 2.0 host
From: Sidney Cadot on 3 Jul 2005 11:59 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;
From: Peter Alfke on 3 Jul 2005 13:57 Sidney. I am not a VHDL guru, but I claim to understand FIFOs. There is an important difference between LUTRAM and BlockRAM: In LUTRAM the reading is non-clocked (Change the read address, and the new data appears immediately at the output), while the reading from a BlockRAM is clocked (change the read address, and nothing happens at the output until the next rising clock edge) BTW, this is a long holoday weekend in the US. Most people have better things to do than watching this ng. :-) Peter Alfke
From: Mike Treseler on 3 Jul 2005 15:26 Sidney Cadot wrote: > Any help/pointers by one of the VHDL gurus here would be much appreciated. http://groups-beta.google.com/groups?q=ram_dq_da -- Mike Treseler
From: sidney on 3 Jul 2005 16:08 Mike Treseler wrote: > http://groups-beta.google.com/groups?q=ram_dq_da I reviewed the results of this query, but I don't see anything that is relevant to my problem I am afraid. The example code I gave can be inferred as BRAMs by XST by the deletion of 1 (semantically empty) line, as explained in my previous post. In that case however, it ceases to work as expected. My only conclusion is that either XST or my VHDL code must have a bug. Regards, Sidney
From: sidney on 3 Jul 2005 16:10
Peter Alfke wrote: > Sidney. I am not a VHDL guru, but I claim to understand FIFOs. > There is an important difference between LUTRAM and BlockRAM: > In LUTRAM the reading is non-clocked (Change the read address, and the > new data appears immediately at the output), while the reading from a > BlockRAM is clocked (change the read address, and nothing happens at > the output until the next rising clock edge) Yes, I understand this. My FIFO design has a delay of at least one clock cycle, I am not expecting the output to appear immediately. Note, too, that my code carefully refrains from using any Xilinx-specific components. If I enable the "ENABLE FOR BRAM" line in the code I gave, XST is able to infer a Block-RAM implementation all by itself (cf. the 'VHDL Coding Techniques' chapter of the XST User's Guide), so it apparently 'thinks' that the BRAM can provide the VHDL semantics of my code in that case. > BTW, this is a long holoday weekend in the US. > Most people have better things to do than watching this ng. :-) Impossible ... :) Thanks for your help so far. Regards, Sidney |