diff --git a/src/Main_.hs b/src/Main_.hs new file mode 100755 index 0000000..c760ac0 --- /dev/null +++ b/src/Main_.hs @@ -0,0 +1,103 @@ +{- + + eTeak synthesiser a GALS back-end for the Balsa language + Copyright (C) 2012- The University of Manchester + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . + + Mahdi Jelodari (and others, see AUTHORS) + School of Computer Science, The University of Manchester + Oxford Road, MANCHESTER, M13 9PL, UK +-} + +{-# OPTIONS_GHC -fno-warn-incomplete-patterns #-} + +module Main ( + main + ) where + + + import Bind + import Context + import Eval + import Finish + import Gen + import Misc + import NetParts + import Gui + import Options + import ParseTree + import Report + import Print + import Sim + import SimTypes + import Teak + import Config + import Latch + import Plot + import Layout + import Balsa + import Rule + import Optim + import Monitor + import ToolOptions + import SimPN + import State + import Dot + import Scp + import Network + import Gates + + import VeriOpt + import DeElastisise + import WriteRTL + + import System.Environment + import System.Exit + import System.Time + import System.FilePath + import Data.List hiding (group) + import System.Directory + import Control.Monad + import System.IO + import Data.Maybe + import Control.Monad.Trans + import qualified Data.Map as DM + import Debug.Trace as DT + import System.IO.Unsafe + + type TeakNetwork = Network.Network + + main :: IO () + main = do + + let + readNetwork :: String -> WhyT IO [Part Network] + readNetwork = readNetworkFile + inpDirectory = "./" + outDirectory = "./" + + filename <- getArgs + Why comp parts <- runWhyT $ readNetwork (inpDirectory ++ (head filename) ++ ".teak") + + let + + part = head parts + list' = cycleMeasure part + part' = foldl runPart_ part list' + backLinks = map (\(x,_) -> x) $ tryPart part $ findBackLinks 1 + print backLinks +-- writeNetworkFile False "" (outDirectory ++ (head filename) ++ "_SM.teak") [part'] + + diff --git a/src/VeriOpt.hs b/src/VeriOpt.hs new file mode 100644 index 0000000..c3c7183 --- /dev/null +++ b/src/VeriOpt.hs @@ -0,0 +1,393 @@ +{-- + eTeak synthesiser a GALS back-end for the Balsa language + Copyright (C) 2012- The University of Manchester + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . + + Mahdi Jelodari (and others, see AUTHORS) + School of Computer Science, The University of Manchester + Oxford Road, MANCHESTER, M13 9PL, UK +--} + + +module VeriOpt ( + + makePartFSM, + stLinkToSt + + ) where + + import Misc + import SimTypes + import SimBuiltin + import ParseTree hiding (Chan) + import NetParts + import Bits + import Dot + import Show + import State + import GuiSupport (colours, black) + + import qualified Data.Map as DM + import Data.List + import Data.Bits + import Control.Monad.State + import Data.Maybe + import Data.Char + import System.IO + + newtype StLink = Link { fsmLink :: Int } + deriving (Eq, Ord, Show) + + + + + fsmAddSt :: Sts -> MkFSMonad m value (Sts) + fsmAddSt st = state op + where op nw = (st', nw { + fsmLabel = label', + fsmStsCount = count', + fsmSts = sts'}) + where + st' = st + label' = fsmLabel nw + count' = fsmStsCount nw + 1 + sts' = DM.insert count' st (fsmSts nw) + + fsmAddName :: String -> MkFSMonad m value [String] + fsmAddName str = state op + where op nw = (label', nw { + fsmLabel = label'}) + where + label' = [str] + + + stLinkToSt :: StNo -> NetworkLinkRef -> FSM -> Maybe StNo + stLinkToSt stNoRef link fsm = takeNO link fsm + where + takeNO link fsm = mostCloseSt stNoRef $ map (isEq link) $ DM.assocs $ fsmStsS fsm + where + mostCloseSt stNoRef xs = do + + let xs' = filter (\x -> x /= Nothing) $ xs + + if null xs' == True then Nothing + else do + + let xs'' = filter (\(Just x) -> x > stNoRef) xs' + + if null xs'' == True then Nothing + else head xs'' + + --FIXME this might cause backward links to be filtered. choosing the head means that the closest. + + isEq link (stNo,st) = if (findIndex (== link) $ inpLinks st) == Nothing then Nothing + else Just stNo + + + + getLinkAccs :: (NetworkIF network) => Part network -> [NetworkLinkRef] + getLinkAccs part = tryPart part $ do + let + portLinks <- liftM concat $ mapM' (nwGetPortAccess . fromJust . nwPortRef) $ networkPorts part + return portLinks + + + + --this function returns the compoenet conenncted to the Go + getFirstComp :: (NetworkIF network) => Part network -> NetworkComp + getFirstComp part = tryPart part $ do + let + portLinks <- liftM head $ nwGetPortAccess $ fromJust $ nwPortRef $ (networkPorts part) !! go + Just (comp , _) <- nwLinkToComp Passive portLinks + return comp + + where + (Just go) = findIndex (fromMaybe False . liftM (== GoAccess) . nwPortRef) $ networkPorts part + + getLastComp :: (NetworkIF network) => Part network -> NetworkComp + getLastComp part = tryPart part $ do + let + --FIXME just one output port is being selected! + outLink = head $ map (\out -> tryPart part $ liftM head $ nwGetPortAccess $ fromJust $ nwPortRef $ (networkPorts part) !! out) outsIndices + Just (comp , _) <- nwLinkToComp Active outLink + return comp + + where + outsIndices = findIndices ((== Output) . nwPortDirection) $ networkPorts part + + + visitComp :: NetworkIF network => Part network -> NetworkLinkRef -> NetworkComp -> Maybe (Sts) + visitComp part upLink (TeakComp compNo teakTyp links _) = do + let + + chanLinks = links + linkWidths = tryPart part $ mapM' (mapM' nwGetLinkWidth . flattenSome) links + partName = networkName part + + do + case (teakTyp, chanLinks, linkWidths) of + (TeakR, [One out], [outWidth]) -> Just (Sts compNo teakTyp links [] outWidth [] [] []) + (TeakI, [One inp, One out], [inpWidths, outWidths]) -> Just (Sts compNo teakTyp links inpWidths outWidths [] [] [inp]) + (TeakM, [Many inp, One out], [inpWidths, [outWidth]]) -> Just (Sts compNo teakTyp [One upLink, One out] inpWidths [outWidth] [] [] inp) + (TeakS guardSlice impsXOffsets, [One inp, Many out], [[inpWidth], outWidths]) -> let + + (impss, offsets) = unzip impsXOffsets + outSlices = zipWith (+:) offsets outWidths + in Just (Sts compNo teakTyp links [inpWidth] outWidths outSlices impss [inp]) + + (TeakF offsets, [One inp, Many out], [inpWidths, outWidths]) -> Just (Sts compNo teakTyp links inpWidths outWidths [] [] [inp]) + (TeakJ, [Many inp, One out], [inpWidths, outWidths]) -> Just (Sts compNo teakTyp links inpWidths outWidths [] [] inp) + (TeakA, [Many inp, One out], [inpWidths, outWidths]) -> Just (Sts compNo teakTyp links inpWidths outWidths [] [] inp) + (TeakO terms, [One inp, One out], [inpWidths, outWidths]) -> Just (Sts compNo teakTyp links inpWidths outWidths [] [] [inp]) + (TeakV _ width _ wOffsets rOffsets, [Many wg, Many wd, Many rg, Many rd],[wWidths, _, _, rWidths]) -> Just (Sts compNo teakTyp [One upLink, Many wg, Many wd, Many rg, Many rd] wWidths rWidths [] [] (wg ++ rg) ) + (_, _, _) -> error $ "makeComp: unrecognised component " ++ show teakTyp + + + -- nwConnectedComps : returns all the components reachable from the given + -- one to the requested depth + getNextComps :: NetworkIF network => Part network -> NetworkLinkRef -> NetworkCompRef -> [Integer] -> NetworkMonad network [(NetworkCompRef,NetworkLinkRef)] + getNextComps part link comp valSteer = connectedComps1 comp link + where + connectedComps1 compRef link = do + comp <- nwGetComp compRef + if isJust comp + then do +-- let links = nwCompLinks (fromJust comp) +-- liftM concat $ mapM linkComps $ concatMap flattenSome links + let chanLinks = nwCompLinks (fromJust comp) + let compType = nwTeakType (fromJust comp) + let val = head valSteer + + --return just output links + case (compType, chanLinks) of + (TeakR, [One out]) -> liftM concat $ mapM linkComps [out] + (TeakI, [One inp, One out]) -> liftM concat $ mapM linkComps [out] + (TeakM, [Many inp, One out]) -> liftM concat $ mapM linkComps [out] + (TeakS _ matches, [One inp, Many out]) -> liftM concat $ mapM linkComps $ takeOne val matches out + (TeakF _, [One inp, Many out]) -> liftM concat $ mapM linkComps out + (TeakJ, [Many inp, One out]) -> liftM concat $ mapM linkComps [out] + (TeakA, [Many inp, One out]) -> liftM concat $ mapM linkComps [out] + (TeakO _, [One inp, One out]) -> liftM concat $ mapM linkComps [out] + (TeakV _ _ _ _ _, [Many wg, Many wd, Many rg, Many rd]) -> liftM concat $ mapM linkCompsV [link] + else return [] + + --this fucntion select only one out link based on the value of valSteer which is coming from a teakO + takeOne val matches outs = do + + let matches' = concat $ map (\(xs,_) -> xs) matches + index = findIndex (\(Imp value dcs) -> value == val) matches' + if index == Nothing then outs + else [outs !! (fromJust index)] + + + -- gets the link and returns the associated component in form of (component, link) + linkComps link = do + pas <- nwLinkToComp Passive link + return $ map ((\x -> tryPart part $ attachLink x link) . fst) $ catMaybes [pas] + + where + attachLink newComp upLink = do + + return $ (\x -> (x,upLink)) $ refComp newComp + + -- this function is to detect the right component next to the variable + linkCompsV link = do + pas <- nwLinkToComp Passive link --thiscomp + return $ map ((\x -> tryPart part $ nexToVar x link) . fst) $ catMaybes [pas] + + where + -- this fucntion simply skipps the Variables and considers them a part of data flow rather than control flow + nexToVar thisComp link = do + + let (TeakComp compNo teakTyp links _) = thisComp + [Many wg, Many wd, Many rg, Many rd] = links + + if (head $ wg) == link then do + + let wd' = head wd + + pp <- nwLinkToComp Passive wd' + + if pp == Nothing then + return $ (\x -> (x,wd')) $ refComp $ getLastComp part + else return $ (\x -> (x,wd')) $ refComp $ fst $ fromJust pp + + else do + + let rgNo = elemIndex link rg + when (isNothing rgNo) $ + error $ "Read go link is not pointing at the variable with read go list of " ++ show rg + let rd' = rd !! (fromJust rgNo) + + pp <- nwLinkToComp Passive $ rd' + + if pp == Nothing then + return $ (\x -> (x,rd')) $ refComp $ getLastComp part + else return $ (\x -> (x,rd')) $ refComp $ fst $ fromJust pp + + rmDup :: [NetworkCompRef] -> [NetworkCompRef] + rmDup [] = [] + rmDup (x:xs) = x : rmDup (filter (\y -> not(x == y)) xs) + + + makePartFSM :: NetworkIF network => Part network -> ([(NetworkCompRef,Int)], FSM) + makePartFSM part = runMkFSMonad0 $ body [] [] compSet + where + tempLink = NetParts.Link {nwLink = 0} + compSet = (fstCompRef,fstCompRef,tempLink) --each component with its predecessor component, this will help us to detect if a comp is already marked by a fork + fstCompRef = refComp $ getFirstComp part -- who is 1st comp? the one that is connected to the go signal! + lstCompRef = refComp $ getLastComp part + + + body valForSteer visited compS + | partialVisited lstCompRef compS visited part = return visited + | otherwise = do + + let + (topComp,compref,upLink) = compS + valForSteer' = constTeakO part compref valForSteer + newCompRefs' = tryPart part $ getNextComps part upLink compref valForSteer' + valForSteer'' = consumeConstTeakO part upLink compref valForSteer' + --FIXME rmDup temproraly removed. + newCompRefs = map (\(a,b) -> (compref,a,b)) newCompRefs' + + fsmAddSt $ fromJust $ visitComp part upLink $ tryPart part $ refToComp compref + + --before passing visited I should inserted the corresponding components in the list + let newVisited = foldl (markJoin part) visited newCompRefs' + + foldM (body valForSteer'') newVisited newCompRefs + + refToComp compref = do + + comp <- nwGetComp compref + when (isNothing comp) $ + error $ "nwLinkToCompUsage: no component at compNo " ++ show comp + return $ fromJust comp + + + consumeConstTeakO part upLink thisComp valSteer = do + + let (TeakComp _ teakTyp _ _) = fromJust $ tryPart part $ nwGetComp thisComp + case (teakTyp) of + + -- (TeakV _ _ _ _ _) -> do + -- let width = tryPart part $ nwGetLinkWidth upLink + -- if width == 0 then valSteer + -- else drop 1 valSteer + + (TeakS _ _) -> drop 1 valSteer + (_) -> valSteer + + + constTeakO part thisComp valSteer = do + + let (TeakComp _ teakTyp links _) = fromJust $ tryPart part $ nwGetComp thisComp + case (teakTyp) of + + (TeakO terms) -> case last terms of + + (_, TeakOConstant _ value) -> value:valSteer + (_) -> valSteer --if it is not a constant then drop the previous value + + (_) -> valSteer + + partialVisited lstComp compS visited part = fromMaybe False $ do + + + let (topComp, thisComp , _) = compS + (TeakComp _ teakTyp _ _) = fromJust $ tryPart part $ nwGetComp thisComp + (TeakComp _ topTyp _ _) = fromJust $ tryPart part $ nwGetComp topComp + + if lstComp == thisComp then do return True + + else do + case (teakTyp) of + + (TeakJ) -> do + + if hasPortInput thisComp part then do + return False + -- yes it does have inputports and iteration is allowed to continue + else do + case (topTyp) of + + --(TeakF _) -> do return True + + -- if exactFullyVisited thisComp visited part then do + -- return False + -- else return True + + (_) -> do + return $ not $ fullyVisited thisComp visited part + + (_) -> do return False + + markJoin part visited thisComp = do + + let (thisComp', _) = thisComp + (TeakComp compNo teakTyp links _) = fromJust $ tryPart part $ nwGetComp thisComp' + + case (teakTyp) of + + (TeakJ) -> do + + if notMember thisComp' visited then do + insertIn thisComp' 1 visited + + else do + let Just markValue = lookUp thisComp' visited + insertIn thisComp' ((+) 1 markValue) $ deleteOut thisComp' visited + + (_) -> visited + + notMember thisComp visited = notElem thisComp visited' + where + visited' = map (\(a,b) -> a) visited + + insertIn thisComp mark visited = (thisComp,mark):visited + + lookUp thisComp visited = lookup thisComp visited + + deleteOut thisComp visited = do + let visited' = map (\(a,b) -> a) visited + index = elemIndex thisComp visited' + if index == Nothing then visited + else f (fromJust index) visited + where + f index visited = take index visited ++ (f index . drop (index+1)) visited + + + fullyVisited thisComp visited part = fromMaybe False $ do + + let (TeakComp compNo teakTyp [Many inp, One out] _) = fromJust $ tryPart part $ nwGetComp thisComp + + exist <- lookUp thisComp visited + + if (length inp) == exist then do + let refined = visited +-- DM.delete thisComp visited + return True +--DM.insert thisComp 0 $ + else do return False + + hasPortInput thisComp part = fromMaybe False $ do + + let (TeakComp compNo teakTyp [Many inp, One out] _) = fromJust $ tryPart part $ nwGetComp thisComp + + let checked = tryPart part $ mapM nwLinkIsPort inp + + return $ elem True checked + diff --git a/src/WriteRTL.hs b/src/WriteRTL.hs new file mode 100644 index 0000000..8dfbd71 --- /dev/null +++ b/src/WriteRTL.hs @@ -0,0 +1,259 @@ +{- + eTeak synthesiser a GALS back-end for the Balsa language + Copyright (C) 2012- The University of Manchester + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . + + Mahdi Jelodari (and others, see AUTHORS) + School of Computer Science, The University of Manchester + Oxford Road, MANCHESTER, M13 9PL, UK +-} + +module WriteRTL ( + + writeRTL, + transStToExpr + + ) where + + import Misc + import SimTypes + import SimBuiltin + import ParseTree hiding (Chan) + import NetParts + import Bits + import Dot + import Show + import State + import GuiSupport (colours, black) + import VeriOpt + + import qualified Data.Map as DM + import Data.List + import Data.Bits + import Control.Monad.State + import Data.Maybe + import Data.Char + import System.IO + + transStToExpr :: StNo -> Sts -> FSM-> String + transStToExpr stNo st fsm = do + + let + typ = compLabel st + chanLinks = links st + inpW = inpWidths st + outW = outWidths st + outSlc = outSlice st + impS = imps st + + case (typ , chanLinks) of + (TeakJ, [Many inp, One out]) -> (showConcat stNo inp out inpW) $ "" + (TeakF offset, [One inp, Many out]) -> (showFork stNo offset inp out inpW outW) $ "" + (TeakM, [One inp, One out]) -> (showChoice stNo inp out ) $ "" + (TeakV str _ _ _ _, [One upLink, Many wg, Many wd, Many rg, Many rd]) -> (showVar stNo str upLink wg wd rg rd inpW outW) $ "" + (TeakS _ _, [One inp, Many out]) -> (showSteer stNo inp out outSlc impS) $ "" + (TeakO terms , [One inp, One out]) -> (showTerms stNo inp out terms ) $ "" + (_) -> "" + where + + showTerms stNo inp out terms = (showString $ intercalate " " $ map (\x -> showTerm x "") terms ) . showNextSt out + where + showNextSt out = showString "ns <= " . (shows $ stLinkToSt stNo out fsm) . showString ";" + + showTerm (i, term) = case term of + + TeakOConstant width value -> shows stNo . + showString ": ". showString "temp". showString " = ". shows value. showString ";" + + TeakOAppend count slices -> shows out . showString " = " . + wrapBracket (intercalate "," $ map (\(i,slice) -> printName i. verilogShowSlice slice $ "") slices) . + showString "" + where + wrapBracket str = showString "{" . showString str . showString "};" + printName i = if i == 0 then shows inp else showString "temp" + + _ -> shows "error" + + showFork stNo offset inp out inpW outW = + -- if head inpW == 0 then showString "" + shows stNo . showString ": " . showImp inp out . showNextSt stNo + where + + showNextSt stNo = showString "ns <= " . shows (stNo + 1) . showString ";" + + showImp inp out = showString $ intercalate " " $ + map (\(x,(y,z)) -> (show x ++ " = " ++ show y ++ verilogShowSlice z "" ++ ";" ) ) imps + slice = zipWith (+:) offset outW + inp' = map (\x -> (inp,x)) slice + imps = zip out $ filter (\(x,y) -> not $ isEmptySlice y) inp' + + --FIXME remove the links that have 0 width because they are not data links + -- zeroWs = elemIndices 0 outW + -- out' = filter zeroWs out + + + showVar stNo str link wg wd rg rd inpW outW = + + if (head $ wg) == link then + shows stNo . showString ": " . showString str . showString " = " . shows link . showString ";" + else + shows stNo . showString ": " . shows rd' . showString " = " . showString str . showString ";" + where + rd' = rd !! (fromJust $ elemIndex link rg) + + + showConcat stNo inp out inpW = shows stNo . + showString ": " . shows out . showString " = " . showChar '{' . (showLinks inp) . showString "};" . showNextSt out + where + showNextSt out = showString "ns <= " . (shows $ stLinkToSt stNo out fsm) . showString ";" + showLinks inp = showString $ intercalate "," $ map (\(x,y) -> show x ) inp' + where + -- inp' = filter (\(x,y) -> y /= 0) $ zip inp inpW + inp' = zip inp inpW --FIXME I have to remove the links with 0 width + + showChoice stNo inp out = shows stNo . showString ": " . shows out . showString " = " . shows inp . showString ";" . showNextSt out + + where + showNextSt out = showString "ns <= " . (shows $ stLinkToSt stNo out fsm) . showString ";" + + showSteer stNo inp out outSlc impS = shows stNo . showString ": " . showString "case (" . shows inp . showString "):" . + showString "\n" . showLinks out inp impS + where + + showLinks out inp impS = showString $ intercalate "\n" $ map (\x -> takeImps x inp "") $ zip impS out + + where + takeImps (imp',out') inp = showString $ intercalate "\n" $ map (\x -> printImp x out' inp "") imp' + + where + printImp (Imp choice _) out' inp= showString "\t". shows choice . showString ": " . + showString "ns <= " .(shows $ stLinkToSt stNo out' fsm) . showString ";" + + + + + writeRTL :: FilePath -> String -> FSM -> IO () + writeRTL file _partName fsm = do + handle <- openFile file WriteMode + hPutStr handle "module " + hPutStr handle _partName + hPutStrLn handle " ( ); " + hPutStrLn handle "" + hPutStrLn handle "always@(posedge clk) begin" + hPutStrLn handle "" + hPutStrLn handle "case(state)" + + mapM_ (printSt handle) $ DM.assocs $ fsmStsS fsm + + hPutStrLn handle "default : $display();" + hPutStrLn handle "endcase" + hPutStrLn handle "" + hPutStrLn handle "end" + hPutStr handle "endmodule" + where + printSt handle (stNo,st) = do + let + typ = compLabel st + chanLinks = links st + inpW = inpWidths st + outW = outWidths st + outSlc = outSlice st + impS = imps st + + + case (typ , chanLinks) of + (TeakJ, [Many inp, One out]) -> hPutStrLn handle $ (showConcat stNo inp out inpW) $ "" + (TeakF offset, [One inp, Many out]) -> hPutStrLn handle $ (showFork stNo offset inp out inpW outW) $ "" + (TeakM, [One inp, One out]) -> hPutStrLn handle $ (showChoice stNo inp out ) $ "" + (TeakV str _ _ _ _, [One upLink, Many wg, Many wd, Many rg, Many rd]) -> hPutStrLn handle $ + (showVar stNo str upLink wg wd rg rd inpW outW) $ "" + (TeakS _ _, [One inp, Many out]) -> hPutStrLn handle $ (showSteer stNo inp out outSlc impS) $ "" + (TeakO terms , [One inp, One out]) -> hPutStrLn handle $ (showTerms stNo inp out terms ) $ "" + (_) -> hPutStr handle "" + where + + showTerms stNo inp out terms = (showString $ intercalate " " $ map (\x -> showTerm x "") terms ) . showNextSt out + where + showNextSt out = showString "ns <= " . (shows $ stLinkToSt stNo out fsm) . showString ";" + + showTerm (i, term) = case term of + + TeakOConstant width value -> shows stNo . + showString ": ". showString "temp". showString " = ". shows value. showString ";" + + TeakOAppend count slices -> shows out . showString " = " . + wrapBracket (intercalate "," $ map (\(i,slice) -> printName i. verilogShowSlice slice $ "") slices) . + showString "" + where + wrapBracket str = showString "{" . showString str . showString "};" + printName i = if i == 0 then shows inp else showString "temp" + + _ -> shows "error" + + showFork stNo offset inp out inpW outW = + if head inpW == 0 then showString "" + else shows stNo . showString ": " . showImp inp out . showNextSt stNo + where + + showNextSt stNo = showString "ns <= " . shows (stNo + 1) . showString ";" + + showImp inp out = showString $ intercalate " " $ + map (\(x,(y,z)) -> (show x ++ " = " ++ show y ++ verilogShowSlice z "" ++ ";" ) ) imps + slice = zipWith (+:) offset outW + inp' = map (\x -> (inp,x)) slice + imps = zip out $ filter (\(x,y) -> not $ isEmptySlice y) inp' + + --FIXME remove the links that have 0 width because they are not data links + -- zeroWs = elemIndices 0 outW + -- out' = filter zeroWs out + + + showVar stNo str link wg wd rg rd inpW outW = + + if (head $ wg) == link then + shows stNo . showString ": " . showString str . showString " = " . shows link . showString ";" + else + shows stNo . showString ": " . shows rd' . showString " = " . showString str . showString ";" + where + rd' = rd !! (fromJust $ elemIndex link rg) + + + showConcat stNo inp out inpW = shows stNo . + showString ": " . shows out . showString " = " . showChar '{' . (showLinks inp) . showString "};" . showNextSt out + where + showNextSt out = showString "ns <= " . (shows $ stLinkToSt stNo out fsm) . showString ";" + showLinks inp = showString $ intercalate "," $ map (\(x,y) -> show x ) inp' + where + inp' = filter (\(x,y) -> y /= 0) $ zip inp inpW + + + showChoice stNo inp out = shows stNo . showString ": " . shows out . showString " = " . shows inp . showString ";" . showNextSt out + + where + showNextSt out = showString "ns <= " . (shows $ stLinkToSt stNo out fsm) . showString ";" + + showSteer stNo inp out outSlc impS = shows stNo . showString ": " . showString "case (" . shows inp . showString "):" . + showString "\n" . showLinks out inp impS + where + + showLinks out inp impS = showString $ intercalate "\n" $ map (\x -> takeImps x inp "") $ zip impS out + + where + takeImps (imp',out') inp = showString $ intercalate "\n" $ map (\x -> printImp x out' inp "") imp' + + where + printImp (Imp choice _) out' inp= showString "\t". shows choice . showString ": " . + showString "ns <= " . (shows $ stLinkToSt stNo out' fsm) . showString ";" +