plain CS/EE 5750/6750: Asynchronous Circuit Design

CS/EE 5750/6750: Asynchronous Circuit Design

Chris J. Myers
Lecture 3: Communication Protocols
Chapter 3

Block Diagram for Passive/Active wine_shop

Figure

Initial Shop Specification

Shop_PA_reshuffled:process
begin
     wait until req_wine = '1';          
     ack_wine <= '1' after delay(1,5);   
     wait until ack_patron = '0';        
     req_patron <= '1' after delay(1,5); 
     wait until req_wine = '0';          
     ack_wine <= '0' after delay(1,5);   
     wait until ack_patron = '1';        
     req_patron <= '0' after delay(1,5); 
end process;

Shop Specification with True Waits

Shop_PA_reshuffled:process
begin
     if (req_wine /= '1') then           
       wait until req_wine = '1'; 
     end if;
     ack_wine <= '1' after delay(1,5);  
     if (ack_patron /= '0') then         
       wait until ack_patron = '0';
     end if;
     req_patron <= '1' after delay(1,5); 
     ...

Shop Specification with True Assignments

Shop_PA_reshuffled:process
begin
     if (req_wine /= '1') then           
       wait until req_wine = '1'; 
     end if;
     ack_wine <= '1' after delay(1,5);   
     wait until ack_wine = '1';
     if (ack_patron /= '0') then         
       wait until ack_patron = '0';
     end if;
     req_patron <= '1' after delay(1,5); 
     wait until req_patron = '1';
     ...

guard and assign Procedures

guard(s,v);
replaces:
if (s /= v) then
  wait until s = v;
end if;

assign(s,v,l,u);
replaces:
s <= v after delay(l,u);
wait until s = v;

Shop Specification with guard's and assign's

Shop_PA_reshuffled:process
begin
     guard(req_wine,'1');        
     assign(ack_wine,'1',1,5);   
     guard(ack_patron,'0');      
     assign(req_patron,'1',1,5); 
     guard(req_wine,'0');        
     assign(ack_wine,'0',1,5);   
     guard(ack_patron,'1');      
     assign(req_patron,'0',1,5); 
end process;

Active and Passive Ports

  • Channel has an active and a passive port.
  • Active port initiates communication.
  • Passive port must patiently wait.
  • If a process uses the probe function on a channel, it must connect to the passive port.
  • If a channel is not probed, then the assignment is arbitrary.

Active and Passive Ports

entity wineshopPA is
  port(wine_delivery : inout channel:=passive;
       wine_selling : inout channel:=active );
end wineshopPA;

Passive/Active wine_shop using Bundled Data

Figure

Two-Phase Bundled-Data Winery (part I)

library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_arith.all;
use ieee.std_logic_unsigned.all;
use work.nondeterminism.all;
use work.handshake.all;

entity winery_bundled is
port(req_wine : inout std_logic := '0';
     ack_wine : in std_logic;
     bottle : inout std_logic_vector(2 downto 0):="000");
end winery_bundled;

Two-Phase Bundled-Data Winery (part II)

architecture two_phase of winery_bundled is
begin
winery_bundled_2phase:process
begin
     assign(req_wine,not req_wine,1,5); -- call winery
     guard(ack_wine,req_wine);          -- wine delivered
     bottle <= bottle + 1 after delay(1,2); 
     wait for 5 ns;
end process;
end two_phase;

Two-Phase Bundled-Data Patron

patronP_bundled_2phase:process
begin
     guard(req_patron,not ack_patron);      -- shop calls 
     brown_bag <= shelf after delay(1,2);
     wait for 5 ns;
     assign(ack_patron,not ack_patron,1,5); -- buys wine
end process;

Two-Phase Bundled-Data Shop

shop_bundled_2phase:process
begin
     guard(req_wine,not ack_wine);         -- winery calls
     shelf <= bottle after delay(1,2);
     wait for 5 ns;
     assign(ack_wine,not ack_wine,1,5);    -- wine arrives
     assign(req_patron,not req_patron,1,5);-- call patron
     guard(ack_patron,req_patron);         -- patron buys
end process;

Four-Phase Bundled-Data Winery

winery_bundled_4phase:process
begin
     assign(req_wine,'1',1,5);   -- call winery
     guard(ack_wine,'1');        -- wine delivered
     assign(req_wine,'0',1,5);   -- reset req_wine
     guard(ack_wine,'0');        -- ack_wine resets
     bottle <= bottle + 1 after delay(1,2); 
     wait for 5 ns;
end process;

Four-Phase Bundled-Data Patron

patronP_bundled_4phase:process
begin
     guard(req_patron,'1');       -- shop calls 
     brown_bag <= shelf after delay(1,2);
     wait for 5 ns;
     assign(ack_patron,'1',1,5);  -- patron buys wine
     guard(req_patron,'0');       -- req_patron resets
     assign(ack_patron,'0',1,5);  -- reset ack_patron
end process;

Four-Phase Bundled-Data Shop

shop_bundled_4phase:process
begin
     guard(req_wine,'1');        -- winery calls
     shelf <= bottle after delay(1,2);
     wait for 5 ns;
     assign(ack_wine,'1',1,2);   -- shop receives wine
     guard(req_wine,'0');        -- req_wine resets
     assign(ack_wine,'0',1,2);   -- reset ack_wine
     assign(req_patron,'1',1,2); -- call patron
     guard(ack_patron,'1');      -- patron buys wine
     assign(req_patron,'0',1,2); -- reset req_patron
     guard(ack_patron,'0');      -- ack_patron resets
end process;

Reshuffled Shop

Shop_PA_reshuffled:process
begin
     guard(req_wine,'1');        -- winery calls
     shelf <= bottle after delay(1,2);
     wait for 5 ns;
     assign(ack_wine,'1',1,5);   -- shop receives wine
     assign(req_patron,'1',1,5); -- call patron
     guard(req_wine,'0');        -- req_wine resets
     assign(ack_wine,'0',1,5);   -- reset ack_wine
     guard(ack_patron,'1');      -- patron buys wine
     assign(req_patron,'0',1,5); -- reset req_patron
     guard(ack_patron,'0');      -- ack_patron resets
end process;

Lazy-Active Shop

Shop_PA_lazy_active:process
begin
     guard(req_wine,'1');        -- winery calls
     shelf <= bottle after delay(1,2);
     wait for 5 ns;
     assign(ack_wine,'1',1,5);   -- shop receives wine
     guard(ack_patron,'0');      -- ack_patron resets
     assign(req_patron,'1',1,5); -- call patron
     guard(req_wine,'0');        -- req_wine resets
     assign(ack_wine,'0',1,5);   -- reset ack_wine
     guard(ack_patron,'1');      -- patron buys wine
     assign(req_patron,'0',1,5); -- reset req_patron
end process;

Deadlock

Winery_Patron:process
begin
     assign(req_wine,'1',1,5);   -- call winery
     guard(ack_wine,'1');        -- wine delivered
     guard(req_patron,'1');      -- shop calls patron
     brown_bag <= shelf after delay(1,2);
     wait for 5 ns;
     assign(ack_patron,'1',1,5); -- patron buys wine
     guard(req_patron,'0');      -- req_patron resets
     assign(ack_patron,'0',1,5); -- reset ack_patron
     assign(req_wine,'0',1,5);   -- reset req_wine
     guard(ack_wine,'0');        -- ack_wine resets
     ...

State Variable Insertion

Shop_PA_SV:process
begin
     guard(req_wine,'1');        -- winery calls
     shelf <= bottle after delay(1,2);
     wait for 5 ns;
     assign(ack_wine,'1',1,5);   -- shop receives wine
     assign(x,'1',1,5);          -- set x
     guard(req_wine,'0');        -- req_wine resets
     assign(ack_wine,'0',1,5);   -- reset ack_wine
     assign(req_patron,'1',1,5); -- call patron
     guard(ack_patron,'1');      -- patron buys wine
     assign(x,'0',1,5);          -- reset x
     ...

Passive/Active wine_shop using Dual-Rail (1 bit)

Figure

Dual-Rail Winery (part I)

library ieee;
use ieee.std_logic_1164.all;
use work.nondeterminism.all;
use work.handshake.all;

entity winery_dualrail is
  port(ack_wine : in std_logic;
       bottle1 : inout std_logic := '0';
       bottle0 : inout std_logic := '0');
end winery_dualrail;

Dual-Rail Winery (part II)

winery_dual_rail:process
begin
     bottle1 <= bottle after delay(2,5);    
     bottle0 <= not bottle after delay(2,5);
     guard(ack_wine,'1');                   
     bottle1 <= '0' after delay(2,5);       
     bottle0 <= '0' after delay(2,5);       
     guard(ack_wine,'0');                   
     bottle <= not bottle;
     wait for 5 ns;
end process;

Dual-Rail Shop (part I)

shopPA_dual_rail:process
begin
     guard(ack_patron,'0');   
     if (bottle0 /= '1' and bottle1 /= '1') then
       wait until bottle0 = '1' or bottle1 = '1';
     end if;
     if bottle0 = '1' then
       assign(shelf0,'1',1,2);
     elsif bottle1 = '1' then
       assign(shelf1,'1',1,2);
     end if;
     assign(ack_wine,'1',1,2);
     guard(ack_patron,'1');   

Dual-Rail Shop (part II)

     if shelf0 = '1' then
       assign(shelf0,'0',1,2);
     elsif shelf1 = '1' then
       assign(shelf1,'0',1,2);
     end if;
     if (bottle0 /= '0' or bottle1 /= '0') then
       wait until bottle0 = '0' and bottle1 = '0';
     end if;
     assign(ack_wine,'0',1,2);
end process;

Dual-Rail Patron (part I)

patronP_dualrail:process
begin
     if (shelf1 /= '1' and shelf0 /= '1') then
       wait until shelf1 = '1' or shelf0 = '1'; 
     end if;
     if shelf0 = '1' then
       brown_bag <= '0';
     elsif shelf1 = '1' then
       brown_bag <= '1';
     end if;
     wait for 5 ns;

Dual-Rail Patron (part II)

     assign(ack_patron,'1',2,5);                
     if (shelf1 /= '0' or shelf0 /= '0') then   
       wait until shelf1 = '0' and shelf0 = '0';
     end if;
     assign(ack_patron,'0',2,5);             
end process;

Passive/Active wine_shop using Dual-Rail

Figure

Dual-Rail Winery (part I)

-- header
entity winery_dualrail3 is
  port(ack_wine2 : in std_logic;
       bottle2_1 : inout std_logic := '0';
       bottle2_0 : inout std_logic := '0';
       ack_wine1 : in std_logic;
       bottle1_1 : inout std_logic := '0';
       bottle1_0 : inout std_logic := '0';
       ack_wine0 : in std_logic;
       bottle0_1 : inout std_logic := '0';
       bottle0_0 : inout std_logic := '0');
end winery_dualrail3;

Dual-Rail Winery (part II)

winery_dual_rail:process
begin
     bottle2_1 <= bottle(2) after delay(2,5);     
     bottle2_0 <= not bottle(2) after delay(2,5);
     bottle1_1 <= bottle(1) after delay(2,5);     
     bottle1_0 <= not bottle(1) after delay(2,5);
     bottle0_1 <= bottle(0) after delay(2,5);     
     bottle0_0 <= not bottle(0) after delay(2,5);
     wait until ack_wine2 = '1' and
                ack_wine1 = '1' and
                ack_wine0 = '1';

Dual-Rail Winery (part III)

     bottle2_1 <= '0' after delay(2,5);
     bottle2_0 <= '0' after delay(2,5);
     bottle1_1 <= '0' after delay(2,5);
     bottle1_0 <= '0' after delay(2,5);
     bottle0_1 <= '0' after delay(2,5);
     bottle0_0 <= '0' after delay(2,5);
     wait until ack_wine2 = '0' and
                ack_wine1 = '0' and
                ack_wine0 = '0'; 
     bottle <= bottle + 1;
     wait for 5 ns;
end process;

Dual-Rail Patron (part I)

patronP_dualrail:process
begin
     if ((shelf2_1 /= '1' and shelf2_0 /= '1') and
         (shelf1_1 /= '1' and shelf1_0 /= '1') and
         (shelf0_1 /= '1' and shelf0_0 /= '1')) then
       wait until (shelf2_1 = '1' or shelf2_0 = '1') and 
                  (shelf1_1 = '1' or shelf1_0 = '1') and
                  (shelf0_1 = '1' or shelf0_0 = '1');   
     end if;

Dual-Rail Patron (part II)

     if shelf2_0 = '1' then
       brown_bag(2) <= '0';
     elsif shelf2_1 = '1' then
       brown_bag(2) <= '1';
     end if;
     if shelf1_0 = '1' then
       brown_bag(1) <= '0';
     elsif shelf1_1 = '1' then
       brown_bag(1) <= '1';
     end if;

Dual-Rail Patron (part III)

     ack_patron2 <= '1' after delay(2,5);
     ack_patron1 <= '1' after delay(2,5);
     ack_patron0 <= '1' after delay(2,5);
     if ((shelf2_1 /= '0' or shelf2_0 /= '0') or
         (shelf1_1 /= '0' or shelf1_0 /= '0') or
         (shelf0_1 /= '0' or shelf0_0 /= '0')) then
       wait until shelf2_1 = '0' and shelf2_0 = '0' and
                  shelf1_1 = '0' and shelf1_0 = '0' and
                  shelf0_1 = '0' and shelf0_0 = '0';
     end if;
     ack_patron2 <= '0' after delay(2,5);
     ack_patron1 <= '0' after delay(2,5);
     ack_patron0 <= '0' after delay(2,5);

Two Wine Shops

Figure

Winery for Two Wine Shops

winery : process
variable z : integer;
begin
  z := selection(2);
  case z is
  when 1 =>
    send(wine_to_new_shop,bottle);
  when others =>
    send(wine_to_old_shop,bottle);
  end case;
  bottle <= bottle + 1;
  wait for 5 ns;
end process winery;

Shop for Two Wine Shops

shop:process
begin
  receive(winery_to_shop,shelf);
  send(shop_to_patron,shelf);
end process wine_shop;

Patron for Two Wine Shops

patron : process
begin
  if (probe(old_shop_to_patron)) then 
    receive(old_shop_to_patron,brown_bag);
    wine_drunk <= wine_type'val(conv_integer(brown_bag));
  elsif (probe(new_shop_to_patron)) then
    receive(new_shop_to_patron,brown_bag);
    wine_drunk <= wine_type'val(conv_integer(brown_bag));
  end if;
  wait for 2 ns;
end process patron;

Two Wine Shops

Figure

Winery for Two Wine Shops (part I)

winery:process
variable z : integer;
begin
     z := selection(2);
     case z is
     when 1 => 
       bottle1 <= bottle after delay(1,2);
       wait for 5 ns;
       assign(req_wine1,'1',1,5);   -- call winery
       guard(ack_wine1,'1');        -- wine delivered
       assign(req_wine1,'0',1,5);   -- reset req_wine
       guard(ack_wine1,'0');        -- ack_wine resets

Winery for Two Wine Shops (part II)

     when others =>
       bottle2 <= bottle after delay(1,2);
       wait for 5 ns;
       assign(req_wine2,'1',1,5);   -- call winery
       guard(ack_wine2,'1');        -- wine delivered
       assign(req_wine2,'0',1,5);   -- reset req_wine
       guard(ack_wine2,'0');        -- ack_wine resets
     end case;
     bottle <= bottle + 1 after delay(1,2); 
     wait for 5 ns;
end process;

Patron for Two Wine Shops (part I)

patronP:process
begin
     if (req_patron1 = '1') then
       brown_bag <= shelf1 after delay(1,2);
       wait for 5 ns;
       assign(ack_patron1,'1',1,5);  -- patron buys wine
       guard(req_patron1,'0');       -- req_patron resets
       assign(ack_patron1,'0',1,5);  -- reset ack_patron

Patron for Two Wine Shops (part II)

     elsif (req_patron2 = '1') then
       brown_bag <= shelf2 after delay(1,2);
       wait for 5 ns;
       assign(ack_patron2,'1',1,5);  -- patron buys wine
       guard(req_patron2,'0');       -- req_patron resets
       assign(ack_patron2,'0',1,5);  -- reset ack_patron
     end if;
     wait for 2 ns;
end process;

Example for Syntax-Directed Translation

shop:process
begin
  receive(winery_to_shop,shelf);
  send(shop_to_patron,shelf);
end process wine_shop;

Circuit for Looping Constructs

Figure

Circuit for Process Statement

Figure

Circuit for Assignment to shelf

Figure

Circuit for Assignment from Two Locations

Figure

Circuit for Receive Procedure

Figure

Circuit for Send Procedure

Figure

Conditional Statements

if (cond1) then
  S1;
elsif (cond2) then
  S2;
else
  S3;
end if;

Circuit for Selection Statement

Figure

Circuit for Sequential Composition

Figure

Circuit for Receive followed by Send

Figure

Circuit for Parallel Composition

Figure

Unoptimized Circuit for the wine_shop

Figure

Circuit after CALL Module Optimization

Figure

Circuit after SEL and Merge Module Optimizations

Figure

Final Circuit for the wine_shop

Figure

Summary

  • guard, assign, and delay functions
  • Active and passive protocols
  • Handshaking expansion
  • Reshuffling
  • State variable insertion
  • Dual-rail data encoding
  • Syntax-directed translation


File translated from TEX by TTH, version 2.22.
On 25 Jan 2000, 06:44.