P
pupillo
Hi,
in the code below there are two 2 bit free running counters (cnta and
cntb). The o output is generated inside oprc process sampling
alternatively cnta on the rising edge of clk and cntb on the rising
edge of clkn (that is not clk).
The output o1 is generated in the same way, except that it uses a copy
of clk (lck1) and a copy of clkn (clk1n).
The poroblem is: o and o1 are different. WHY?
This code comes from an implementation of a DDR IO pad mux from an
FPGA manufacturer.
In my opinion the problem has something to do with the fact that those
processes use a sensitivity list with two clocks.
Thanks
Pupillo
------------------------------------------------------------------------------------------------------------------------
---------------- ENTITY myff
------------------------------------------------------------------------------------------
------------------------------------------------------------------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use ieee.std_logic_arith.all;
use ieee.std_logic_unsigned.all;
entity myff is
Port ( clk : in STD_LOGIC;
rst : in STD_LOGIC;
o,o1: out STD_LOGIC_VECTOR (1 downto 0));
end myff;
architecture Behavioral of myff is
signal clkn,clk1,clkn1:std_logic;
signal cnta,cntb:std_logic_vector(1 downto 0);
begin
clkn<=not clk;
clk1<=clk;
clkn1<=clkn;
---- counter cnta ----------
cntaprc
rocess(clk) begin
if (rising_edge(clk)) then
if (rst='1') then cnta<="00";
else cnta<=cnta+1;
end if;
end if;
end process;
---- counter cntb -------------
cntbprc
rocess(clk) begin
if (rising_edge(clk)) then
if (rst='1') then cntb<="10";
else cntb<=cntb+1;
end if;
end if;
end process;
----- DDR sampling of cnta / cntb using clk / clkn ---------
oprc
rocess(clk,clkn) begin
if (rising_edge(clk)) then
o<=cnta;
end if;
if (rising_edge(clkn)) then
o<=cntb;
end if;
end process;
----- DDR sampling of cnta / cntb using clk1 / clkn1 ---------
o1prc
rocess(clk1,clkn1) begin
if (rising_edge(clk1)) then
o1<=cnta;
end if;
if (rising_edge(clkn1)) then
o1<=cntb;
end if;
end process;
end Behavioral;
------------------------------------------------------------------------------------------------------------------------
----------------------------------- TEST BENCH
-------------------------------------------------------------------------
------------------------------------------------------------------------------------------------------------------------
LIBRARY ieee;
USE ieee.std_logic_1164.ALL;
ENTITY myff_TB IS
END myff_TB;
ARCHITECTURE behavior OF myff_TB IS
COMPONENT myff
PORT(
clk : IN std_logic;
rst : IN std_logic;
o,o1 : OUT std_logic_vector(1 downto 0)
);
END COMPONENT;
--Inputs
signal clk : std_logic := '0';
signal rst : std_logic := '0';
--Outputs
signal o,o1: std_logic_vector(1 downto 0);
-- Clock period definitions
constant clk_period : time := 10 ns;
BEGIN
uut: myff PORT MAP (
clk => clk,
rst => rst,
o => o,
o1 => o1
);
-- Clock process definitions
clk_process
rocess
begin
clk <= '0';
wait for clk_period/2;
clk <= '1';
wait for clk_period/2;
end process;
-- Stimulus process
stim_proc: process
begin
-- hold reset state for 100 ns.
rst<='1';
wait for 100 ns;
rst<='0';
wait;
end process;
END;
in the code below there are two 2 bit free running counters (cnta and
cntb). The o output is generated inside oprc process sampling
alternatively cnta on the rising edge of clk and cntb on the rising
edge of clkn (that is not clk).
The output o1 is generated in the same way, except that it uses a copy
of clk (lck1) and a copy of clkn (clk1n).
The poroblem is: o and o1 are different. WHY?
This code comes from an implementation of a DDR IO pad mux from an
FPGA manufacturer.
In my opinion the problem has something to do with the fact that those
processes use a sensitivity list with two clocks.
Thanks
Pupillo
------------------------------------------------------------------------------------------------------------------------
---------------- ENTITY myff
------------------------------------------------------------------------------------------
------------------------------------------------------------------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use ieee.std_logic_arith.all;
use ieee.std_logic_unsigned.all;
entity myff is
Port ( clk : in STD_LOGIC;
rst : in STD_LOGIC;
o,o1: out STD_LOGIC_VECTOR (1 downto 0));
end myff;
architecture Behavioral of myff is
signal clkn,clk1,clkn1:std_logic;
signal cnta,cntb:std_logic_vector(1 downto 0);
begin
clkn<=not clk;
clk1<=clk;
clkn1<=clkn;
---- counter cnta ----------
cntaprc
if (rising_edge(clk)) then
if (rst='1') then cnta<="00";
else cnta<=cnta+1;
end if;
end if;
end process;
---- counter cntb -------------
cntbprc
if (rising_edge(clk)) then
if (rst='1') then cntb<="10";
else cntb<=cntb+1;
end if;
end if;
end process;
----- DDR sampling of cnta / cntb using clk / clkn ---------
oprc
if (rising_edge(clk)) then
o<=cnta;
end if;
if (rising_edge(clkn)) then
o<=cntb;
end if;
end process;
----- DDR sampling of cnta / cntb using clk1 / clkn1 ---------
o1prc
if (rising_edge(clk1)) then
o1<=cnta;
end if;
if (rising_edge(clkn1)) then
o1<=cntb;
end if;
end process;
end Behavioral;
------------------------------------------------------------------------------------------------------------------------
----------------------------------- TEST BENCH
-------------------------------------------------------------------------
------------------------------------------------------------------------------------------------------------------------
LIBRARY ieee;
USE ieee.std_logic_1164.ALL;
ENTITY myff_TB IS
END myff_TB;
ARCHITECTURE behavior OF myff_TB IS
COMPONENT myff
PORT(
clk : IN std_logic;
rst : IN std_logic;
o,o1 : OUT std_logic_vector(1 downto 0)
);
END COMPONENT;
--Inputs
signal clk : std_logic := '0';
signal rst : std_logic := '0';
--Outputs
signal o,o1: std_logic_vector(1 downto 0);
-- Clock period definitions
constant clk_period : time := 10 ns;
BEGIN
uut: myff PORT MAP (
clk => clk,
rst => rst,
o => o,
o1 => o1
);
-- Clock process definitions
clk_process
begin
clk <= '0';
wait for clk_period/2;
clk <= '1';
wait for clk_period/2;
end process;
-- Stimulus process
stim_proc: process
begin
-- hold reset state for 100 ns.
rst<='1';
wait for 100 ns;
rst<='0';
wait;
end process;
END;