Linout port input timing constraint problem

Status
Not open for further replies.

johnnysmith911

Newbie level 5
Joined
Feb 23, 2017
Messages
10
Helped
0
Reputation
0
Reaction score
0
Trophy points
1
Activity points
112
I have a design like this ( full code, UCF & test bench towards the end)..

Code:
data_in <= data when (readwrite = '0' and reset = '0') else (others =>'0');
 
process(clk,reset)
.
.
if(reset = '1') then
.
.
elsif(clk'event and clk = '1') then
.
    if(readwrite = '0') then
        counter <= data_in;
    end if;
.
counter_out <= counter;
end if;

"data" is an inout port & it's value is fed into "counter" if the flag "readwrite" is 0, i.e. in read mode. In this mode, I have a constraint that the "data" port's value must be registered only after 9ns from the rising clock edge, which is done through this line in the UCF.

Code:
NET "data[*]" TNM = "DATA_GROUP";
TIMEGRP "DATA_GROUP" OFFSET = OUT 12.5 ns AFTER "clk" RISING;
[B]TIMEGRP "DATA_GROUP" OFFSET = IN 11 ns VALID 20 ns BEFORE "clk" RISING[/B];

When I simulate my design via a test bench, I can see that the input is actually being registered before the 9 ns mark.


Now, as you can see from the post-P&R timing diagram, at the 9 ns mark as pointed to by the 2nd cursor, the value of "data" is 10101010 but at the end of that clock cycle/start of the next clock cycle, you can see that the value of "counter_out" is 01010101 which is the value before the 9 ns mark.

If the data port was read at the 9ns mark as specified by the constraint,
TIMEGRP "DATA_GROUP" OFFSET = IN 11 ns VALID 20 ns BEFORE "clk" RISING;

shouldn't the value at the end of that clock cycle be 10101010?

Thanks,
John


VHDL code:

Code:
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;

-- Uncomment the following library declaration if using
-- arithmetic functions with Signed or Unsigned values
use IEEE.NUMERIC_STD.ALL;

-- Uncomment the following library declaration if instantiating
-- any Xilinx primitives in this code.
--library UNISIM;
--use UNISIM.VComponents.all;

entity interface is

	port(
		clk : in std_logic;
		reset: in std_logic;
		data : inout std_logic_vector(7 downto 0);
		readwrite: in std_logic;
		
		counter_out : out std_logic_vector(7 downto 0)
	);

end interface;

architecture Behavioral of interface is

type counter_state is
(
	state_read,
	state_wait,
	state_write
);

signal counter : std_logic_vector(7 downto 0);-- := (OTHERS => '0');
signal data_in, data_out : std_logic_vector(7 downto 0);-- := (OTHERS => '0');
signal state_counter : counter_state;

begin

	--Get data from bus everytime
	data_in <= data when (readwrite = '0' and reset = '0') else (others =>'0');
	--Write counter to data_out all the time
	data_out <= counter when (reset = '0') else (others =>'0');
	
	--Driver to send data out of the inout port
	data_bus_driver: process(reset,readwrite,data_out)
	begin
	--		
		if(reset = '1') then
			data <= (OTHERS => 'Z');
		elsif(readwrite = '1') then
			data <= data_out;
		else
			data <= (OTHERS => 'Z');
		end if;
		
	end process;
	
	--State machine
	process(clk,reset)
	begin
	
		if(reset = '1') then
			state_counter <= state_read;
			counter <= (OTHERS => '0');
			counter_out <= (OTHERS => '0');
			--data <= (OTHERS => 'Z');
		
		elsif(clk'event and clk = '1') then
		
			case state_counter is
				
			when state_read =>
			
				if(readwrite = '0') then
					counter <= data_in;
					state_counter <= state_read;
				else
					state_counter <= state_wait;
				end if;
			
			when state_wait =>
			
				if(readwrite = '1') then
					counter <= std_logic_vector(unsigned(counter) + 1);
					state_counter <= state_write;
				else
					state_counter <= state_read;
				end if;
			when state_write =>
		
				if(readwrite = '1') then
					counter <= std_logic_vector(unsigned(counter) + 1);
					state_counter <= state_write;
				else
					state_counter <= state_wait;
				end if;
		
			end case;
			
			counter_out <= counter;
		
		end if;
		
	end process;	

end Behavioral;

UCF:

Code:
NET "clk" TNM_NET = "clk";
TIMESPEC TS_clk = PERIOD "clk" 50 MHz HIGH 50 %;

NET "readwrite" OFFSET = IN 11 ns VALID 20 ns BEFORE "clk" RISING;

#NET "readwrite" TNM = "enable";
#TIMESPEC TS_tristate = FROM "enable" TO "DATA_GROUP" 4.5 ns ;

NET "data[*]" TNM = "DATA_GROUP";
TIMEGRP "DATA_GROUP" OFFSET = OUT 12.5 ns AFTER "clk" RISING;
TIMEGRP "DATA_GROUP" OFFSET = IN 11 ns VALID 20 ns BEFORE "clk" RISING;

# PlanAhead Generated IO constraints 
NET "data[7]" IOSTANDARD = LVCMOS33;
NET "data[6]" IOSTANDARD = LVCMOS33;
NET "data[5]" IOSTANDARD = LVCMOS33;
NET "data[4]" IOSTANDARD = LVCMOS33;
NET "data[3]" IOSTANDARD = LVCMOS33;
NET "data[2]" IOSTANDARD = LVCMOS33;
NET "data[1]" IOSTANDARD = LVCMOS33;
NET "data[0]" IOSTANDARD = LVCMOS33;
NET "data[7]" SLEW = FAST;
NET "data[6]" SLEW = FAST;
NET "data[5]" SLEW = FAST;
NET "data[4]" SLEW = FAST;
NET "data[3]" SLEW = FAST;
NET "data[2]" SLEW = FAST;
NET "data[1]" SLEW = FAST;
NET "data[0]" SLEW = FAST;
NET "clk" IOSTANDARD = LVCMOS33;
NET "readwrite" IOSTANDARD = LVCMOS33;

# PlanAhead Generated physical constraints 
NET "data[5]" LOC = U7;
NET "data[1]" LOC = V7;
NET "data[4]" LOC = T4;
NET "data[0]" LOC = V4;
NET "data[7]" LOC = U5;
NET "data[6]" LOC = V5;
NET "data[3]" LOC = R3;
NET "data[2]" LOC = T3;

NET "clk" LOC = R8;
NET "readwrite" LOC = U8;

Testbench:

Code:
LIBRARY ieee;
USE ieee.std_logic_1164.ALL;
 
-- Uncomment the following library declaration if using
-- arithmetic functions with Signed or Unsigned values
--USE ieee.numeric_std.ALL;
 
ENTITY inout_test_tb IS
END inout_test_tb;
 
ARCHITECTURE behavior OF inout_test_tb IS 
 
    -- Component Declaration for the Unit Under Test (UUT)
 
    COMPONENT interface
    PORT(
         clk : IN  std_logic;
			reset : IN  std_logic;
         data : INOUT  std_logic_vector(7 downto 0);
         readwrite : IN  std_logic;
			
			counter_out : out std_logic_vector(7 downto 0)
        );
    END COMPONENT;
    

   --Inputs
   signal clk : std_logic := '0';
	signal reset : std_logic := '0';
   signal readwrite : std_logic := '0';

	--BiDirs
   signal data : std_logic_vector(7 downto 0);
	
	--Outputs
	signal counter_out : std_logic_vector(7 downto 0);
	
	signal data_out_tb : std_logic_vector(7 downto 0) := (OTHERS => '0');
	signal data_in_tb : std_logic_vector(7 downto 0) := (OTHERS => '0');

   -- Clock period definitions
   constant clk_period : time := 20 ns;
 
BEGIN
 
	-- Instantiate the Unit Under Test (UUT)
   uut: interface PORT MAP (
          clk => clk,
          reset => reset,
			 data => data,
          readwrite => readwrite,
			 counter_out => counter_out
        );

   -- Clock process definitions
   clk_process :process
   begin
		clk <= '0';
		wait for clk_period/2;
		clk <= '1';
		wait for clk_period/2;
   end process;
	
	--data <= data_in_tb when (readwrite = '0') else (others => 'Z');
	--data_out_tb <= data when (readwrite = '1') else (others => '0');
 

   -- Stimulus process
   stim_proc: process
   begin		
      
		reset <= '1';
		data <= (others => '0');
		wait for clk_period*10;
		reset <= '0';
		
		readwrite <= '0';
		data_in_tb <= "01010101";
		data <= "01010101";
		
		wait until rising_edge(clk);
		wait for 6 ns;
		data_in_tb <= "10101010";
		data <= "10101010";
		
		wait until rising_edge(clk);
		wait for 6 ns;
		data_in_tb <= "11111111";
		data <= "11111111";

      wait for clk_period*10;
		wait until rising_edge(clk);
		wait for 8 ns;
 
		readwrite <= '1';
		
		wait until rising_edge(clk);
		data <= (others => 'Z');
		data_out_tb <= data;
		wait until rising_edge(clk);
		data <= (others => 'Z');
		data_out_tb <= data;
		wait until rising_edge(clk);
		data <= (others => 'Z');
		data_out_tb <= data;
		wait until rising_edge(clk);
		data <= (others => 'Z');
		data_out_tb <= data;
		wait until rising_edge(clk);
		data <= (others => 'Z');
		data_out_tb <= data;
		wait for 8 ns;
		
		readwrite <= '0';
		wait until rising_edge(clk);
		
		data_in_tb <= "10101010";
		data <= "10101010";

      wait;
   end process;

END;
 

Status
Not open for further replies.

Similar threads

Cookies are required to use this site. You must accept them to continue using the site. Learn more…