------------------------------------------------------------------------------- --- $Id: ISE.hs#2 2010/09/24 18:47:10 REDMOND\\satnams $ ------------------------------------------------------------------------------- module Lava.ISE (Effort(..), xflow, implement) where import Directory import System.Cmd import Control.Monad -- * Circuit implementation with the Xilinx ISE tools data Effort = Balanced | FastRuntime | HighEffort deriving (Eq, Show) ------------------------------------------------------------------------------- showEffort :: Effort -> String showEffort effort = case effort of Balanced -> "balanaced" FastRuntime -> "fast_runtime" HighEffort -> "high_effort" ------------------------------------------------------------------------------- effortFile :: Effort -> String effortFile effort = case effort of Balanced -> "balanaced.opt" FastRuntime -> "fast_runtime.opt" HighEffort -> "high_effort.opt" ------------------------------------------------------------------------------- -- | The 'xflow' function executes the Xilinx ISE implementation tools -- with the specified circuit, part, package, speed grade and -- implementation effort. The name of the primary clock is assumed -- to be clk. xflow :: String -- ^ The name of the circuit to be implemented -> String -- ^ The part to be used for the implementation -> String -- ^ The package to be used for the implementation -> Int -- ^ The speed grade to be used for the implementation -> Int -- ^ The target operating frequency -> Effort -- ^ The implementaiton effort -> IO () xflow circuitName part package speedGrade frequency effort = do writeFile (circuit ++ ".ucf") (unlines ["NET \"clk\" TNM_NET = clk;", "TIMESPEC TS_clk = PERIOD \"clk\" " ++ show frequency ++ " MHz HIGH 50%;"]) putStrLn command system command return () where circuit = circuitName ++ "_" ++ part ++ "_" ++ show speedGrade ++ "_" ++ package ++ "_" ++ show frequency ++ "MHz_" ++ showEffort effort partName = part ++ "-" ++ show speedGrade ++ package command = "xflow -wd " ++ circuit ++ " -p " ++ partName ++ " -synth xst_vhdl.opt " ++ circuitName ++ " -implement " ++ effortFile effort ------------------------------------------------------------------------------- implement :: String -- ^ The name of the circuit to be implemented -> String -- ^ The part to be used for the implementation -> String -- ^ The package to be used for the implementation -> Int -- ^ The speed grade to be used for the implementation -> Int -- ^ The target operating frequency -> Effort -- ^ The implementaiton effort -> IO () implement circuitName part package speedGrade frequency effort = do putStrLn ("Implementing " ++ circuit) writeFile (circuitName ++ ".prj") ("vhdl work " ++ circuitName ++ ".vhd") exists <- doesDirectoryExist circuit when (not exists) $ createDirectory circuit setCurrentDirectory circuit writeFile (circuitName ++ ".ucf") (unlines ["NET \"clk\" TNM_NET = clk;", "TIMESPEC TS_clk = PERIOD \"clk\" " ++ show frequency ++ " MHz HIGH 50%;"]) writeFile (circuitName ++ ".xst") (unlines (xstOptions circuitName partName)) system ("xst -intstyle silent -ifn " ++ circuitName ++ ".xst -ofn " ++ circuitName ++ ".syr") system ("ngdbuild -intstyle silent -quiet -dd _ngo -nt timestamp -uc " ++ circuitName ++ ".ucf -p " ++ partName ++ " " ++ circuitName ++ ".ngc " ++ circuitName ++ ".ngd") system ("map -intstyle silent -p " ++ partName ++ " -w -logic_opt off -ol high -t 1 -xt 0 -register_duplication off -global_opt off -mt off -ir off -pr off -lc off -power off -o " ++ circuitName ++ "_map.ncd " ++ circuitName ++ ".ngd " ++ circuitName ++ ".pcf") system ("par -w -intstyle silent -ol high -mt off " ++ circuitName ++ "_map.ncd " ++ circuitName ++ ".ncd " ++ circuitName ++ ".pcf") reportPAR circuitName setCurrentDirectory ".." return () where partName = part ++ "-" ++ show speedGrade ++ package circuit = circuitName ++ "_" ++ part ++ "_" ++ show speedGrade ++ "_" ++ package ++ "_" ++ show frequency ++ "MHz_" ++ showEffort effort ------------------------------------------------------------------------------- xstOptions :: String -> String -> [String] xstOptions circuit part = ["set -xsthdpdir \"xst\"", "run", "-ifn ../" ++ circuit ++ ".prj", "-ifmt mixed", "-ofn " ++ circuit, "-ofmt NGC", "-p " ++ part, "-top " ++ circuit, "-opt_mode Speed", "-opt_level 1" ] ------------------------------------------------------------------------------- reportPAR :: String -> IO () reportPAR circuit = do parFile <- readFile (circuit++".par") let Just results = findPARresults (lines parFile) putStrLn (unlines results) ------------------------------------------------------------------------------- findPARresults :: [String] -> Maybe [String] findPARresults [] = Nothing findPARresults (l1:l2:l3:l4:l5:l6:l7:l8:rest) | length l1 >= 10 && length l2 >= 12 = if take 10 l1 == "----------" && take 12 l2 == " Constraint" then if moreResults /= Nothing then moreResults else Just [l1,l2,l3,l4,l5,l6,l7,l8] else findPARresults (l2:l3:l4:l5:l6:l7:l8:rest) where moreResults = findPARresults rest findPARresults (x:xs) = findPARresults xs -------------------------------------------------------------------------------