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;
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;