----------------------------------------------------------------------------- -- | -- Module : ForSyDe.Backend.VHDL -- Copyright : (c) SAM Group, KTH/ICT/ECS 2007-2008 -- License : BSD-style (see the file LICENSE) -- -- Maintainer : forsyde-dev@ict.kth.se -- Stability : experimental -- Portability : portable -- -- This module provides the VHDL backend of ForSyDe's embedded compiler -- ----------------------------------------------------------------------------- module ForSyDe.Backend.VHDL (writeVHDL, writeVHDLOps, writeAndModelsimVHDL, writeAndModelsimVHDLOps, VHDLOps(..), QuartusOps(..), QuartusAction(..), checkSynthesisQuartus, VHDLDebugLevel(..), VHDLRecursivity(..), defaultVHDLOps) where import Control.Monad.State (evalStateT) import qualified Language.Haskell.TH as TH import ForSyDe.System.SysFun import ForSyDe.ForSyDeErr import ForSyDe.OSharing (readURef) import ForSyDe.System.SysDef import ForSyDe.Backend.VHDL.Traverse import ForSyDe.Backend.VHDL.Modelsim -- | Given a System Definition whose name is a valid VHDL _basic_ identifier -- (call it \"A\") generate @A.vhd@ in current working directory using -- default compilation options. -- Imp: the input and output signal names of A must be valid VHDL identifiers -- (basic or extended) and different to @clk@ and @reset@ -- which are reserved for the main clock and reset signals writeVHDL :: SysDef a -> IO () writeVHDL = writeVHDLOps defaultVHDLOps -- | 'writeVHDL'-alternative which allows setting VHDL compilation options. writeVHDLOps :: VHDLOps -> SysDef a -> IO () writeVHDLOps ops sysDef = do -- initiate the compilation State let sinit = initVHDLTravST $ (readURef.unPrimSysDef.unSysDef) sysDef -- Compile the code res <- runErrorT $ evalStateT (setVHDLOps ops >> writeVHDLM) sinit -- Check if the compilation went well and print an error in case it didn't either printVHDLError return res -- | Generate a function which, given a system definition and some simulation -- stimuli: -- -- (1) Writes a VHDL model of the system -- -- (2) Simulates the VHDL model with Modelsim getting the results back to Haskell writeAndModelsimVHDL :: SysFunToIOSimFun sysF simF => Maybe Int -- ^ Number of cycles to simulate -- if 'Nothing' the number will be determined -- by the length of the input stimulti. -- Useful when the system to simulate doesn't -- have inputs or the inputs provided are -- infinite -> SysDef sysF -- ^ system definition to simulate -> simF writeAndModelsimVHDL = writeAndModelsimVHDLOps defaultVHDLOps -- | 'VHDLOps'-alternative of 'writeAndModelsimVHDL', note that -- compileModelSim will implicitly be set to True writeAndModelsimVHDLOps :: SysFunToIOSimFun sysF simF => VHDLOps -> Maybe Int -> SysDef sysF -> simF writeAndModelsimVHDLOps ops mCycles sysDef = fromTHStrSimFun simIO [] where sinit = initVHDLTravST $ (readURef.unPrimSysDef.unSysDef) sysDef simVHDLM :: [[TH.Exp]] -> VHDLM [[String]] simVHDLM stimuli = do setVHDLOps ops{compileModelsim=True} writeVHDLM executeTestBenchModelsim mCycles stimuli simIO :: [[TH.Exp]] -> IO [[String]] simIO stimuli = do res <- runErrorT $ evalStateT (simVHDLM stimuli) sinit either printVHDLError return res