diff --git a/clash-shake.cabal b/clash-shake.cabal
--- a/clash-shake.cabal
+++ b/clash-shake.cabal
@@ -5,7 +5,7 @@
 -- see: https://github.com/sol/hpack
 
 name:           clash-shake
-version:        0.3.0
+version:        0.3.1
 synopsis:       Shake rules for building Clash programs
 description:    Shake rules for building Clash programs and synthesizing FPGA
                 configuration. Contains build rules for Xilinx ISE, Xilinx Vivado,
diff --git a/src/Clash/Shake/SymbiFlow.hs b/src/Clash/Shake/SymbiFlow.hs
--- a/src/Clash/Shake/SymbiFlow.hs
+++ b/src/Clash/Shake/SymbiFlow.hs
@@ -11,8 +11,8 @@
 import Development.Shake.FilePath
 import Development.Shake.Config
 
-xilinx7 :: Xilinx.Target -> ClashKit -> FilePath -> FilePath -> String -> Rules SynthKit
-xilinx7 target@Xilinx.Target{..} kit@ClashKit{..} outDir srcDir topName = do
+xilinx7 :: Xilinx.Board -> ClashKit -> FilePath -> FilePath -> String -> Rules SynthKit
+xilinx7 Xilinx.Board{ boardTarget = target@Xilinx.Target{..} } kit@ClashKit{..} outDir srcDir topName = do
     let rootDir = joinPath . map (const "..") . splitPath $ outDir
 
     let symbiflow' :: String -> [String] -> Action ()
diff --git a/src/Clash/Shake/Xilinx.hs b/src/Clash/Shake/Xilinx.hs
--- a/src/Clash/Shake/Xilinx.hs
+++ b/src/Clash/Shake/Xilinx.hs
@@ -1,10 +1,11 @@
 {-# LANGUAGE OverloadedStrings, RecordWildCards, TemplateHaskell #-}
 module Clash.Shake.Xilinx
     ( Target(..), targetPart
+    , Board(..)
     , ise
     , vivado
 
-    , papilioPro, papilioOne, nexysA750T
+    , papilioPro, papilioOne, nexysA750T, basys3
     ) where
 
 import Clash.Shake
@@ -48,9 +49,26 @@
 papilioOne :: Target
 papilioOne = Target "Spartan3E" "xc3s500e" "vq100" 5
 
-nexysA750T :: Target
-nexysA750T = Target "artix7" "xc7a50t" "csg324" 1
+data Board = Board
+    { boardSpec :: String -- TODO: what is the structure of this?
+    , boardTarget :: Target
+    }
 
+boardMustache :: Board -> [Aeson.Pair]
+boardMustache Board{..} =
+    [ "board" .= T.pack boardSpec
+    ] <>
+    targetMustache boardTarget
+
+nexysA750T :: Board
+nexysA750T = Board "digilentinc.com:nexys=a7-50t:part0:1.0" $
+    Target "artix7" "xc7a50t" "csg324" 1
+
+basys3 :: Board
+basys3 = Board "digilentinc.com:basys3:part0:1.2" $
+    Target "artix7" "xc7a35t" "cpg236" 1
+
+
 ise :: Target -> ClashKit -> FilePath -> FilePath -> String -> Rules SynthKit
 ise fpga kit@ClashKit{..} outDir srcDir topName = do
     let projectName = topName
@@ -107,8 +125,8 @@
             ]
         }
 
-vivado :: Target -> ClashKit -> FilePath -> FilePath -> String -> Rules SynthKit
-vivado fpga kit@ClashKit{..} outDir srcDir topName = do
+vivado :: Board -> ClashKit -> FilePath -> FilePath -> String -> Rules SynthKit
+vivado board kit@ClashKit{..} outDir srcDir topName = do
     let projectName = topName
         projectDir = outDir </> projectName
         xpr = projectDir </> projectName <.> "xpr"
@@ -142,8 +160,7 @@
                      [ [ "rootDir" .= T.pack rootDir]
                      , [ "project" .= T.pack projectName ]
                      , [ "top" .= T.pack topName ]
-                     , targetMustache fpga
-                     , [ "board" .= T.pack "digilentinc.com:nexys-a7-50t:part0:1.0" ] -- TODO
+                     , boardMustache board
                      , [ "srcs" .= mconcat
                          [ [ object [ "fileName" .= src ] | src <- srcs1 ]
                          , [ object [ "fileName" .= (srcDir </> src) ] | src <- srcs2 ]
@@ -172,7 +189,7 @@
         let values = object . mconcat $
                      [ [ "project" .= T.pack projectName ]
                      , [ "top" .= T.pack topName ]
-                     , targetMustache fpga
+                     , boardMustache board
                      ]
         writeFileChanged out . TL.unpack $ renderMustache template values
 
