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