diff --git a/src/lib.rs b/src/lib.rs
index 95cd285f7e0388a6ec79b9902de5ab7e522e46ec..5de85110b2030c301d06eb0fd410c26dd55c40b7 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -114,17 +114,8 @@ pub enum IpTo {
     Method(Ident),
 }
 
-///
-#[derive(Debug)]
-pub struct Ip {
-    /// Input port type
-    ty: Ty,
-    /// Input port binding
-    to: IpTo,
-}
-
-/// `$($Ident: $Ty,)*`
-pub type Ips = HashMap<Ident, Ty>;
+/// `$($Ident: $Ty > $Path,)*`
+pub type Ips = HashMap<Ident, (Ty, Path)>;
 
 /// `crc! { .. }`
 #[derive(Debug)]
diff --git a/src/parse.rs b/src/parse.rs
index cdb2bd506a7ec95c3c0f5ce935a2c52eeee5a523..6e88ea2c0549dc229b43981fce0c33e5474362b5 100644
--- a/src/parse.rs
+++ b/src/parse.rs
@@ -2,7 +2,8 @@ use std::collections::{HashMap, HashSet};
 use std::iter::Peekable;
 use std::slice::Iter;
 
-use syn::{self, DelimToken, Ident, IntTy, Lit, Path, Token, TokenTree, Ty};
+use syn::{self, DelimToken, Ident, IntTy, Lit, Path, Token, BinOpToken,
+          TokenTree, Ty};
 
 use error::*;
 
@@ -503,11 +504,11 @@ fn crcs(tts: &mut Peekable<Iter<TokenTree>>) -> Result<Crcs> {
     })
 }
 
-/// Parses `$($Ident: $Path,)*`
+/// Parses `$($Ident: $Ty > $Path,)*`
 fn ip(tts: &mut Peekable<Iter<TokenTree>>) -> Result<Ips> {
     ::parse::delimited(tts, DelimToken::Brace, |tts| {
         let mut ips = HashMap::new();
-        let mut tts = tts.iter();
+        let mut tts = tts.iter().peekable();
         while let Some(tt) = tts.next() {
             let ident = if let &TokenTree::Token(Token::Ident(ref id)) = tt {
                 id
@@ -530,7 +531,11 @@ fn ip(tts: &mut Peekable<Iter<TokenTree>>) -> Result<Ips> {
             let ty = ::parse::ty(&mut tts).chain_err(|| {
                 format!("parsing `type` for {:?}", ident)
             })?;
-            ips.insert(ident.clone(), ty);
+
+            let path = ::parse::path(&mut tts).chain_err(|| "parsing `path`")?;
+            tts.next();
+
+            ips.insert(ident.clone(), (ty, path));
         }
         Ok(ips)
 
@@ -538,17 +543,18 @@ fn ip(tts: &mut Peekable<Iter<TokenTree>>) -> Result<Ips> {
 }
 
 /// Parses `$Ty `
-fn ty(tts: &mut Iter<TokenTree>) -> Result<Ty> {
+fn ty(tts: &mut Peekable<Iter<TokenTree>>) -> Result<Ty> {
     let mut fragments = vec![];
     loop {
         if let Some(tt) = tts.next() {
-            if tt == &TokenTree::Token(Token::Comma) {
+            // if tt == &TokenTree::Token(Token::BinOp(BinOpToken::Minus)) {
+            if tt == &TokenTree::Token(Token::Gt) {
                 break;
             } else {
                 fragments.push(tt);
             }
         } else {
-            bail!("expected comma, found end of macro");
+            bail!("expected `>`, found end of macro");
         }
     }