Continue to Site

Welcome to EDAboard.com

Welcome to our site! EDAboard.com is an international Electronics Discussion Forum focused on EDA software, circuits, schematics, books, theory, papers, asic, pld, 8051, DSP, Network, RF, Analog Design, PCB, Service Manuals... and a whole lot more! To participate you need to register. Registration is free. Click here to register now.

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.
data read problem.JPG

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

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top