Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > VHDL > Using a BlockRam in an async FIFO for bus width conversion ?

Reply
Thread Tools

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

 
 
Arnaud
Guest
Posts: n/a
 
      06-25-2004
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;




 
Reply With Quote
 
 
 
 
Peter Alfke
Guest
Posts: n/a
 
      06-25-2004
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" <(E-Mail Removed)>
> 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;
>
>
>
>


 
Reply With Quote
 
 
 
 
Arnaud
Guest
Posts: n/a
 
      06-26-2004
Thanks Peter,

I was thinking,the behaviour was:
- on the clock_write rising edge : I setup Address, data, Write Enable and
ENable, as setup time is not valid, BlockRam doesn't take them into account
- on the next clock_write rising edge, I setup the new value, and the
BlockRam gets the previous value (line above), and set the memory cell
- and so on..

It works fine in behavioral not in post place and route, it seems, that some
part of the value changed at the rising edge are taken from the "before
rising edge" values, while others are taken from the "after rising edge"
values, in post place and route.

To do what you told me "at least a set-up time before", I changed my block
Ram to react on FallingEdge, while my logical set all the values at the
RisingEdge....
But I don't know if it's the "good way"...

I didn't succeed to find any trivial example about the use of DualPort
BlockRam... if anyone has one, I would love to get it.

Many thanks,

Arnaud

"Peter Alfke" <(E-Mail Removed)> a écrit dans le message de
news:BD01EB55.71BA%(E-Mail Removed)...
> 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" <(E-Mail Removed)>
> > 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;
> >
> >
> >
> >

>



 
Reply With Quote
 
Peter Alfke
Guest
Posts: n/a
 
      06-28-2004
You can treat the inputs to the BlockRAM just as if it were a register.
Give it all its information and then apply the right clock edge. It's as
simple as that.

But an asynchronous FIFO is not simple, especially if you are after high
clock rates. The problem is detecting EMPTY reliably, and that involves the
use of Gray counters etc.
As you may have read in today's press announcement, we took care of that in
Virtex-4, where we incorporated a FIFO controller with all the bells and
whistles and impressive speed...
Peter Alfke

> From: "Arnaud" <(E-Mail Removed)>
> Organization: Guest of ProXad - France
> Newsgroups: comp.arch.fpga,comp.lang.vhdl
> Date: Sat, 26 Jun 2004 09:34:40 +0200
> Subject: Re: Using a BlockRam in an async FIFO for bus width conversion ?
>
> Thanks Peter,
>
> I was thinking,the behaviour was:
> - on the clock_write rising edge : I setup Address, data, Write Enable and
> ENable, as setup time is not valid, BlockRam doesn't take them into account
> - on the next clock_write rising edge, I setup the new value, and the
> BlockRam gets the previous value (line above), and set the memory cell
> - and so on..
>
> It works fine in behavioral not in post place and route, it seems, that some
> part of the value changed at the rising edge are taken from the "before
> rising edge" values, while others are taken from the "after rising edge"
> values, in post place and route.
>
> To do what you told me "at least a set-up time before", I changed my block
> Ram to react on FallingEdge, while my logical set all the values at the
> RisingEdge....
> But I don't know if it's the "good way"...
>
> I didn't succeed to find any trivial example about the use of DualPort
> BlockRam... if anyone has one, I would love to get it.
>
> Many thanks,
>
> Arnaud
>
> "Peter Alfke" <(E-Mail Removed)> a écrit dans le message de
> news:BD01EB55.71BA%(E-Mail Removed)...
>> 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" <(E-Mail Removed)>
>>> 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;
>>>
>>>
>>>
>>>

>>

>
>


 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
FIFO, FIFO, It's Off To Queue We Go... Lawrence D'Oliveiro NZ Computing 7 05-09-2009 08:37 AM
any body having complete code for synchronous fifo or know a link where fifo codes are available plz help chaitu VHDL 1 06-01-2007 07:03 PM
any body having complete code for a synchronous FIFO or know a link where FIFO codes are available chaitu VHDL 1 06-01-2007 03:45 AM
any body having complete code for a synchronous FIFO or know a link where FIFO codes are available chaitu VHDL 1 05-31-2007 03:31 PM
any body having complete code for a synchronous FIFO or know a link where FIFO codes are available chaitu VHDL 0 05-31-2007 02:28 PM



Advertisments