Using a BlockRam in an async FIFO for bus width conversion ?

A

Arnaud

Guest
Hi all,
First of all, I'm a newbie in FPGA, so sorry if my questions are not very
smart... :)
In a larger design, I try to use a Xilinx BlockRam for a data width
conversion between 2 clocks domains.
I look through the different Xilinx example (xapp131, xapp258, ..). As my
needs was much more simpler I try to make mine (mostly to understand).

During behavioral or post-translate simulation everything is ok. But during
Post-Place & Route Simulation. It doesn't work.
I try 2 write 2 32bits words from one side and to get on the other side a
64bits word.
In my test bench, I write
1st - 0x00000000 and 0x00000001
and the read side I get 0x0000000100000000
2nd - 0x00000002 and 0x00000003
and the read side I get 0x0000000300000002
and so on.

BUT in place and route simulation I have
In my test bench, I write
1st - 0x00000000 and 0x00000001
and the read side I get 0x0000000000000000
2nd - 0x00000002 and 0x00000003
and the read side I get 0x0000000200000001
2nd - 0x00000004 and 0x00000005
and the read side I get 0x0000000400000003
and so on.


Basically, I always miss the first value, as It is not taken into account,
and the "word" are reordered (so with the wrong pair association).

I saw on the newsgroups, that maybe I have to set the WriteEnable _before_
the rising edge, but I don't understand how and why if it's the case ?

I have isolated my problem in the two following file (testbench and
"converter")

Thanks a lot.

Arnaud



Converter
----------------------------------------------------------------------------
----------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;

-- Uncomment the following lines to use the declarations that are
-- provided for instantiating Xilinx primitive components.
library UNISIM;
use UNISIM.VComponents.all;

entity test_fifo is
Port ( clk_wr_in : in std_logic;
clk_rd_in : in std_logic;
bus_in : in std_logic_vector(31 downto 0);
bus_out : out std_logic_vector(63 downto 0);
wr : in std_logic;
rd : in std_logic;
sr : in std_logic);
end test_fifo;

architecture Behavioral of test_fifo is

component bram_w32_r64
port (
addra: IN std_logic_VECTOR(4 downto 0);
addrb: IN std_logic_VECTOR(3 downto 0);
clka: IN std_logic;
clkb: IN std_logic;
dina: IN std_logic_VECTOR(31 downto 0);
doutb: OUT std_logic_VECTOR(63 downto 0);
ena: IN std_logic;
enb: IN std_logic;
wea: IN std_logic);
end component;


signal addra: std_logic_VECTOR(4 downto 0);
signal addrb: std_logic_VECTOR(3 downto 0);



signal clk_rd: std_logic;
signal clk_wr: std_logic;

signal rst : std_logic;

begin


gclk1: BUFGP port map (I => clk_rd_in, O => clk_rd);
gclk2: BUFGP port map (I => clk_wr_in, O => clk_wr);

rst <= not sr;

bram : bram_w32_r64
port map (
addra => addra,
addrb => addrb,
clka => clk_wr,
clkb => clk_rd,
dina => bus_in,
doutb => bus_out,
ena => wr,
enb => rst,
wea => '1');


writer: process(sr, clk_wr)
begin
if ( sr = '1' ) then

addra <= (others => '0');

elsif (rising_edge(clk_wr)) then

if ( wr = '1' ) then
addra <= addra + 1 ;
end if;

end if;

end process writer;



reader: process(sr, clk_rd)
begin
if ( sr = '1' ) then

addrb <= (others => '0');

elsif (rising_edge(clk_rd)) then
if (rd = '1') then
addrb <= addrb + 1 ;
end if;

end if;

end process reader;

end Behavioral;


TEST_BENCH
----------------------------------------------------------------------------
----------------------------
LIBRARY ieee;
USE ieee.std_logic_1164.ALL;
USE ieee.numeric_std.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;


ENTITY test_fifo_tb IS
END test_fifo_tb;

ARCHITECTURE behavior OF test_fifo_tb IS

COMPONENT test_fifo
PORT(
clk_wr_in : IN std_logic;
clk_rd_in : IN std_logic;
bus_in : IN std_logic_vector(31 downto 0);
bus_out : out std_logic_vector(63 downto 0);
wr : IN std_logic;
rd : IN std_logic;
sr : IN std_logic
);
END COMPONENT;

SIGNAL clk_wr : std_logic := '0';
SIGNAL clk_rd : std_logic := '0';
SIGNAL bus_in : std_logic_vector(31 downto 0):= (others => '0');
SIGNAL bus_out : std_logic_vector(63 downto 0):= (others => '0');
SIGNAL wr : std_logic :='0';
SIGNAL rd : std_logic := '0';
SIGNAL sr : std_logic := '1';

BEGIN

uut: test_fifo PORT MAP(
clk_wr_in => clk_wr,
clk_rd_in => clk_rd,
bus_in => bus_in,
bus_out => bus_out,
wr => wr,
rd => rd,
sr => sr
);


-- *** Test Bench - User Defined Section ***

clk_wr <= not clk_wr after 30 ns / 2;
clk_rd <= not clk_rd after 15 ns / 2;
sr <= transport '0' after 120 ns;

tb : PROCESS
BEGIN
wait; -- will wait forever
END PROCESS;
-- *** End Test Bench - User Defined Section ***

writer: process( clk_wr, sr)
begin

if ( sr ='1' ) then

bus_in <= (others => '1');

elsif (rising_edge(clk_wr)) then

if ( bus_out /= 8 ) then
rd <= '0';
wr <= '1';
bus_in <= bus_in + 1;
else
wr <= '0';
rd <= '1';
end if;

end if;

end process writer;
END;
 
Remember, all BlockRAM operations are synchronous, activated by the clock
edge (your choice of clock polarity).
That means all inputs must be there at least a set-up time before that clock
edge.
"All" means: Address, Data, Write Enable, and ENable.

Peter Alfke, Xilinx Applications

From: "Arnaud" <arnaud@trisky.com
Organization: Guest of ProXad - France
Newsgroups: comp.arch.fpga,comp.lang.vhdl
Date: Fri, 25 Jun 2004 22:11:03 +0200
Subject: Using a BlockRam in an async FIFO for bus width conversion ?

Hi all,
First of all, I'm a newbie in FPGA, so sorry if my questions are not very
smart... :)
In a larger design, I try to use a Xilinx BlockRam for a data width
conversion between 2 clocks domains.
I look through the different Xilinx example (xapp131, xapp258, ..). As my
needs was much more simpler I try to make mine (mostly to understand).

During behavioral or post-translate simulation everything is ok. But during
Post-Place & Route Simulation. It doesn't work.
I try 2 write 2 32bits words from one side and to get on the other side a
64bits word.
In my test bench, I write
1st - 0x00000000 and 0x00000001
and the read side I get 0x0000000100000000
2nd - 0x00000002 and 0x00000003
and the read side I get 0x0000000300000002
and so on.

BUT in place and route simulation I have
In my test bench, I write
1st - 0x00000000 and 0x00000001
and the read side I get 0x0000000000000000
2nd - 0x00000002 and 0x00000003
and the read side I get 0x0000000200000001
2nd - 0x00000004 and 0x00000005
and the read side I get 0x0000000400000003
and so on.


Basically, I always miss the first value, as It is not taken into account,
and the "word" are reordered (so with the wrong pair association).

I saw on the newsgroups, that maybe I have to set the WriteEnable _before_
the rising edge, but I don't understand how and why if it's the case ?

I have isolated my problem in the two following file (testbench and
"converter")

Thanks a lot.

Arnaud



Converter
----------------------------------------------------------------------------
----------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;

-- Uncomment the following lines to use the declarations that are
-- provided for instantiating Xilinx primitive components.
library UNISIM;
use UNISIM.VComponents.all;

entity test_fifo is
Port ( clk_wr_in : in std_logic;
clk_rd_in : in std_logic;
bus_in : in std_logic_vector(31 downto 0);
bus_out : out std_logic_vector(63 downto 0);
wr : in std_logic;
rd : in std_logic;
sr : in std_logic);
end test_fifo;

architecture Behavioral of test_fifo is

component bram_w32_r64
port (
addra: IN std_logic_VECTOR(4 downto 0);
addrb: IN std_logic_VECTOR(3 downto 0);
clka: IN std_logic;
clkb: IN std_logic;
dina: IN std_logic_VECTOR(31 downto 0);
doutb: OUT std_logic_VECTOR(63 downto 0);
ena: IN std_logic;
enb: IN std_logic;
wea: IN std_logic);
end component;


signal addra: std_logic_VECTOR(4 downto 0);
signal addrb: std_logic_VECTOR(3 downto 0);



signal clk_rd: std_logic;
signal clk_wr: std_logic;

signal rst : std_logic;

begin


gclk1: BUFGP port map (I => clk_rd_in, O => clk_rd);
gclk2: BUFGP port map (I => clk_wr_in, O => clk_wr);

rst <= not sr;

bram : bram_w32_r64
port map (
addra => addra,
addrb => addrb,
clka => clk_wr,
clkb => clk_rd,
dina => bus_in,
doutb => bus_out,
ena => wr,
enb => rst,
wea => '1');


writer: process(sr, clk_wr)
begin
if ( sr = '1' ) then

addra <= (others => '0');

elsif (rising_edge(clk_wr)) then

if ( wr = '1' ) then
addra <= addra + 1 ;
end if;

end if;

end process writer;



reader: process(sr, clk_rd)
begin
if ( sr = '1' ) then

addrb <= (others => '0');

elsif (rising_edge(clk_rd)) then
if (rd = '1') then
addrb <= addrb + 1 ;
end if;

end if;

end process reader;

end Behavioral;


TEST_BENCH
----------------------------------------------------------------------------
----------------------------
LIBRARY ieee;
USE ieee.std_logic_1164.ALL;
USE ieee.numeric_std.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;


ENTITY test_fifo_tb IS
END test_fifo_tb;

ARCHITECTURE behavior OF test_fifo_tb IS

COMPONENT test_fifo
PORT(
clk_wr_in : IN std_logic;
clk_rd_in : IN std_logic;
bus_in : IN std_logic_vector(31 downto 0);
bus_out : out std_logic_vector(63 downto 0);
wr : IN std_logic;
rd : IN std_logic;
sr : IN std_logic
);
END COMPONENT;

SIGNAL clk_wr : std_logic := '0';
SIGNAL clk_rd : std_logic := '0';
SIGNAL bus_in : std_logic_vector(31 downto 0):= (others => '0');
SIGNAL bus_out : std_logic_vector(63 downto 0):= (others => '0');
SIGNAL wr : std_logic :='0';
SIGNAL rd : std_logic := '0';
SIGNAL sr : std_logic := '1';

BEGIN

uut: test_fifo PORT MAP(
clk_wr_in => clk_wr,
clk_rd_in => clk_rd,
bus_in => bus_in,
bus_out => bus_out,
wr => wr,
rd => rd,
sr => sr
);


-- *** Test Bench - User Defined Section ***

clk_wr <= not clk_wr after 30 ns / 2;
clk_rd <= not clk_rd after 15 ns / 2;
sr <= transport '0' after 120 ns;

tb : PROCESS
BEGIN
wait; -- will wait forever
END PROCESS;
-- *** End Test Bench - User Defined Section ***

writer: process( clk_wr, sr)
begin

if ( sr ='1' ) then

bus_in <= (others => '1');

elsif (rising_edge(clk_wr)) then

if ( bus_out /= 8 ) then
rd <= '0';
wr <= '1';
bus_in <= bus_in + 1;
else
wr <= '0';
rd <= '1';
end if;

end if;

end process writer;
END;
 

Welcome to EDABoard.com

Sponsor

Back
Top