IR2067: Logical link interface abstraction

Description of Problem

It is quite common that one logical connection between two component instances consists of several data and handshake lines. With RECORDs it is possible to combine lines in one direction. But there is no way to combine bidirectional lines to one logical link. This lack of abstraction capabilities for communication is in some cases the main reason why System C is preferred.

Proposed Resolution

A solution could consist of one additional language element called "interface". "interface" introduces a hierarchy to an entity port definition:

    INTERFACE data_in IS
       GENERIC( 
          width    :
    INTEGER;
       );
       PORT( 
         data : IN STD_ULOGIC_VECTOR (width-1 DOWNTO 0);
         handshake_forth : IN STD_ULOGIC;
         handshake_back  : OUT STD_ULOGIC);
    END INTERFACE;
    
    INTERFACE data_out IS
       GENERIC( 
          width    : INTEGER;
       );
       PORT( 
         data : OUT STD_ULOGIC_VECTOR (width-1 DOWNTO 0);
         handshake_forth : OUT STD_ULOGIC;
         handshake_back  : IN STD_ULOGIC);
    END INTERFACE;
    
    INTERFACE control IS
       PORT( 
         a : OUT STD_ULOGIC;
         b : IN STD_ULOGIC;
    END INTERFACE;
    
    ENTITY data_flow_control IS
       GENERIC( 
          data_width    : INTEGER);
       PORT( 
         p_in : INTERFACE IN data_in(width: >data_width);
         p_out : INTERFACE OUT data_out(width=>data_width);
         ctrl : INTERFACE INOUT control);
         -- the direction (IN/OUT) of the INTERFACE is only a logical direction
    END ENTITY;
    
    ARCHITECTURE structural OF data_flow_control IS
       COMPONENT submodule
         PORT( 
           handshake_forth_in  : IN STD_ULOGIC;
           handshake_forth_out : OUT STD_ULOGIC;
           ctrl : INTERFACE INOUT control);
       END COMPONENT;
    BEGIN
      p_out.data <= p_in.data;
      p_in.handshake_back <= p_out.handshake_back;
      mod_inst : submodule
          GENERIC MAP (
            width => 16)
          PORT MAP (
            handshake_forth_in  => p_in.handshake_forth,
            handshake_forth_out => p_out.handshake_forth
            ctrl => ctrl) -- attention: this is a bidirectional connection
    END ARCHITECTURE;
    
  -- more usage of abstraction features: 
  --  Function calls can be used to be independent from the current INTERFACE 
  --    definition
    --  => it is much easier to replace a logical link interface used by the 
    --    whole design with another one.
    ENTITY source IS
       PORT( 
         clk : IN STD_ULOGIC;
         rst : IN STD_ULOGIC;
         p_out : INTERFACE OUT data_out(width=>16));
    END ENTITY;
    
    ARCHITECTURE behavioral OF source IS
      FUNCTION send_data( port : INTERFACE OUT data_out(width=>16),
                      data : STD_ULOGIC_VECTOR(15 DOWNTO 0) ) RETURN BOOLEAN IS
      BEGIN
        port.data <= data;
        port.handshake_forth <= '1';
        IF port.handshake_back = '0' THEN RETURN FALSE;
        ELSE RETURN TRUE;
      END FUNCTION;
       
       -- Architecture Declarations
       TYPE STATE_TYPE IS (
          zeros,
          ones
       );
       -- Declare current and next state signals
       SIGNAL current_state : STATE_TYPE ;
       SIGNAL next_state : STATE_TYPE ;
    BEGIN
       -----------------------------------------------------------------
       clocked_proc : PROCESS(clk,rst)
       -----------------------------------------------------------------
       BEGIN
          IF (rst = '1') THEN
             current_state <= zeros;
          ELSIF (clk'EVENT AND clk = '1') THEN
             current_state <= next_state;
          END IF;
       END PROCESS clocked_proc;
    
       -----------------------------------------------------------------
       nextstate_proc : PROCESS (current_state)
       -----------------------------------------------------------------
       BEGIN
          CASE current_state IS
          WHEN zeros =>
             IF (send_data(p_out,x"0000")) THEN
                next_state <= ones;
             ELSE
                next_state <= zeros;
             END IF;
          WHEN ones =>
             IF (send_data(p_out,x"FFFF")) THEN
                next_state <= zeros;
             ELSE
                next_state <= ones;
             END IF;
          WHEN OTHERS =>
             next_state <= zeros;
          END CASE;
       END PROCESS nextstate_proc;
    
    END ARCHITECTURE;


Advantages:

  • hierarchical abstraction of entity interfaces
  • hiding of interface internals possible by offering access functions or protocol conversion blocks


There is also an alternative that makes more use of the "logical" interface direction:

    
    INTERFACE sync_handshake IS
       GENERIC( 
          width    : INTEGER;
       );
       PORT( 
         -- for an INTERFACE IN: FORTH = IN and BACK = OUT
         -- for an INTERFACE OUT: FORTH = OUT and BACK = IN
         data : FORTH STD_ULOGIC_VECTOR (width-1 DOWNTO 0);
         handshake_forth : FORTH STD_ULOGIC;
         handshake_back  : BACK STD_ULOGIC);
    END INTERFACE;
    
    ENTITY channel IS
       PORT( 
         p_in  : INTERFACE IN sync_handshake(width=>16));
         p_out : INTERFACE OUT sync_handshake(width=>16));
         -- NOT ALLOWED: p_inout : INTERFACE INOUT data_out(width=>16));
    END ENTITY;
    
    ARCHITECTURE struc OF channel IS
    BEGIN
      p_out <=> p_in; -- Attention: this is a bidirectional assignment
      -- this equals:
      p_out.data <= p_in.data;
      p_out.handshake_forth <= p_in.handshake_forth;
      p_in.handshake_back <= p_out.handshake_back;
    END ARCHITECTURE;
Topic revision: r3 - 2016-01-21 - 11:51:33 - BrentHahoe
 
Copyright © 2008-2024 by the contributing authors. All material on this collaboration platform is the property of the contributing authors.
Ideas, requests, problems regarding TWiki? Send feedback