Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Generate VPI files in the same dir with Verilog #576

Merged
merged 2 commits into from
Aug 2, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions src/comp/Error.hs
Original file line number Diff line number Diff line change
Expand Up @@ -1118,6 +1118,7 @@ data ErrMsg =
| EMissingUserFile String [String]
| EUnrecognizedCmdLineText String
| EUnknownVerilogSim String [String] Bool
| EMissingVPIWrapperFile String Bool

-- ABin (.ba) file issues
| WExtraABinFiles [String]
Expand Down Expand Up @@ -4416,6 +4417,12 @@ getErrorText (WNonDemotableErrors tags) =
in s2par ("Cannot demote the following error" ++ s ++ ":") $$
nest 2 (sepList (map text tags) comma))

getErrorText (EMissingVPIWrapperFile fname is_dpi) =
(System 95, empty,
let ifctype = if is_dpi then "DPI" else "VPI"
in s2par ("Cannot find the " ++ ifctype ++ " file " ++ ishow fname ++
" in the Verilog search path."))

-- Runtime errors
getErrorText (EMutuallyExclusiveRulesFire r1 r2) =
(Runtime 1, empty,
Expand Down
6 changes: 4 additions & 2 deletions src/comp/VPIWrappers.hs
Original file line number Diff line number Diff line change
Expand Up @@ -300,8 +300,8 @@ mkVPIRegisterBody name has_return stores_handles =

genVPIRegistrationArray :: ErrorHandle ->
Flags -> String -> [String] -> [ForeignFunction] ->
IO ()
genVPIRegistrationArray _ _ _ _ [] = return ()
IO [String]
genVPIRegistrationArray _ _ _ _ [] = return []
genVPIRegistrationArray errh flags prefix blurb ffs =
do let -- generate the registration array file name
c_filename = mkVPIArrayCName (vdir flags) prefix
Expand All @@ -316,6 +316,8 @@ genVPIRegistrationArray errh flags prefix blurb ffs =
writeFileCatch errh c_filename c_contents
-- report the file to the user with relative path
unless (quiet flags) $ putStrLnF $ "VPI registration array file created: " ++ c_filename_rel
-- return the file name
return [c_filename]

mkVPIRegistrationArray :: Flags -> String -> [ForeignFunction] -> Bool -> CCFragment
mkVPIRegistrationArray flags prefix ffs with_fn =
Expand Down
62 changes: 37 additions & 25 deletions src/comp/bsc.hs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import System.Environment(getArgs, getProgName)
import System.Process(runInteractiveProcess, waitForProcess)
import System.Process(system)
import System.Exit(ExitCode(ExitFailure, ExitSuccess))
import System.FilePath(takeDirectory)
import System.IO(hFlush, stdout, hPutStr, stderr, hGetContents, hClose, hSetBuffering, BufferMode(LineBuffering))
import System.IO(hSetEncoding, latin1)
import System.Posix.Files(fileMode, unionFileModes, ownerExecuteMode, groupExecuteMode, setFileMode, getFileStatus, fileAccess)
Expand All @@ -16,7 +17,7 @@ import Data.Char(isSpace, toLower, ord)
import Data.List(intersect, nub, partition, intersperse, sort,
isPrefixOf, isSuffixOf, unzip5, intercalate)
import Data.Time.Clock.POSIX(getPOSIXTime)
import Data.Maybe(isJust, isNothing {-, fromMaybe-})
import Data.Maybe(isJust, isNothing)
import Numeric(showOct)

import Control.Monad(when, unless, filterM, liftM, foldM)
Expand All @@ -25,6 +26,7 @@ import Control.Concurrent(forkIO)
import Control.Concurrent.MVar(newEmptyMVar, putMVar, takeMVar)
import qualified Control.Exception as CE
import qualified Data.Map as M
import qualified Data.Set as S

import ListMap(lookupWithDefault)
import SCC(scc)
Expand All @@ -34,15 +36,16 @@ import ParseOp
import PFPrint
import Util(headOrErr, fromJustOrErr, joinByFst, quote)
import FileNameUtil(baseName, hasDotSuf, dropSuf, dirName, mangleFileName,
mkAName, mkVName, mkVPICName, mkVPIArrayCName,
mkAName, mkVName, mkVPICName,
mkNameWithoutSuffix,
mkSoName, mkObjName, mkMakeName,
bscSrcSuffix, bseSrcSuffix, binSuffix,
hSuffix, cSuffix, cxxSuffix, cppSuffix, ccSuffix,
objSuffix, useSuffix,
genFileName, createEncodedFullFilePath,
getFullFilePath, getRelativeFilePath)
import FileIOUtil(writeFileCatch, readFileMaybe, removeFileCatch)
import FileIOUtil(writeFileCatch, readFileMaybe, removeFileCatch,
readFilePath)
import TopUtils
import SystemCheck(doSystemCheck)
import BuildSystem
Expand Down Expand Up @@ -462,8 +465,8 @@ compilePackage
vpi_wrappers <- if (backend flags /= Just Verilog)
then return []
else if (useDPI flags)
then genDPIWrappers errh flags "./" blurb ffuncs
else genVPIWrappers errh flags "./" blurb ffuncs
then genDPIWrappers errh flags prefix blurb ffuncs
else genVPIWrappers errh flags prefix blurb ffuncs
t <- dump errh flags t DFgenVPI dumpnames vpi_wrappers

-- Simplify a little
Expand Down Expand Up @@ -1531,12 +1534,13 @@ cmdCompileBluesimCFile flags cName = do
return (cmd, oName, msg)

-- returns the name of the object file created
compileVPICFile :: ErrorHandle -> Flags -> String -> IO String
compileVPICFile errh flags cName = do
compileVPICFile :: ErrorHandle -> Flags -> [String] -> String -> IO String
compileVPICFile errh flags incdirs cName = do
let oName = mkObjName Nothing "" (dropSuf cName)
-- show is used for quoting
let incflags = map (("-I"++) . show) (cIncPath flags) ++
["-I" ++ show (bluespecDir flags) ++ "/VPI"]
["-I" ++ show (bluespecDir flags) ++ "/VPI"] ++
map (\d -> "-I" ++ d) incdirs
switches = incflags ++
[ "-fPIC"
, "-c"
Expand Down Expand Up @@ -2083,13 +2087,14 @@ vGenFFuncs :: ErrorHandle -> Flags -> TimeInfo -> String ->
IO (TimeInfo, [String])
vGenFFuncs errh flags t prefix cfilenames_unique [] = return (t,[])
vGenFFuncs errh flags t prefix cfilenames_unique ffuncs = do
t <-
if (useDPI flags) then return t
(t, vpiarray_filenames) <-
if (useDPI flags) then return (t, [])
else do
-- generate the vpi_startup_array file
blurb <- mkGenFileHeader flags
genVPIRegistrationArray errh flags prefix blurb ffuncs
timestampStr flags "generate VPI registration array" t
filenames <- genVPIRegistrationArray errh flags prefix blurb ffuncs
t <- timestampStr flags "generate VPI registration array" t
return (t, filenames)

-- compile user-supplied C files
let (cfiles1, ofiles1) = partition (\f -> hasDotSuf cSuffix f ||
Expand All @@ -2101,23 +2106,30 @@ vGenFFuncs errh flags t prefix cfilenames_unique ffuncs = do
ofiles2 <- mapM (compileUserCFile errh flags True) cfiles1
t <- timestampStr flags "compile user-provided C files" t

{-
-- XXX If any of BSC's pre-compiled .ba libraries has a VPI wrapper
-- XXX that goes along with it, they would need to included here?
do let to = fromMaybe "." (vdir flags)
mapM_ (\src -> do let dst = to ++ "/" ++ (baseName src)
copyFileCatch errh src dst)
vpi_wrapper_c_h_files
-}

(t, ofiles3) <-
if (useDPI flags) then return (t, [])
else do
-- compile all necessary vpi wrapper files
let mkVPIFileName s = mkVPICName (vdir flags) prefix s
vpifiles = map (mkVPIFileName . getIdString . ff_name) ffuncs ++
[ mkVPIArrayCName (vdir flags) prefix ]
files <- mapM (compileVPICFile errh flags) vpifiles

-- first, find the VPI wrapper files in the vsearch path
let findVPIWrapperFile ffunc = do
let ffunc_name = getIdString (ff_name ffunc)
vpiwrapper_filename = mkVPICName Nothing "" ffunc_name
mfile <- readFilePath errh noPosition False vpiwrapper_filename (vPath flags)
case mfile of
Nothing -> bsError errh [(noPosition, EMissingVPIWrapperFile vpiwrapper_filename False)]
Just (_, filename) -> return filename
vpiwrapper_filenames <- mapM findVPIWrapperFile ffuncs

-- collect the directories of the VPI wrapper files
-- to use as a search path for header files when compiling
-- the VPI registration array file
let vpidirs = S.toList (S.fromList (map takeDirectory vpiwrapper_filenames))

-- include the vpi registration array file
wrapper_files <- mapM (compileVPICFile errh flags []) vpiwrapper_filenames
array_files <- mapM (compileVPICFile errh flags vpidirs) vpiarray_filenames
let files = wrapper_files ++ array_files
t <- timestampStr flags "compile VPI wrapper files" t
return (t, files)

Expand Down
1 change: 1 addition & 0 deletions testsuite/bsc.options/.gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -5,5 +5,6 @@ bsc.path_dup_bdir.out.expected.post-m4-stage1
bsc.path_dup_no_bdir.out.expected.post-m4-stage1
bsc.path_nonidentical_dup_no_bdir.out.expected.post-m4-stage1
incfiles/
srcfiles/
directc_sysGCD.sft
my_time.c
2 changes: 1 addition & 1 deletion testsuite/bsc.options/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
CONFDIR = $(realpath ..)

DONTKEEPFILES = *.post-m4 *.post-m4-stage1 \
simfiles bfiles vfiles incfiles \
simfiles bfiles vfiles incfiles srcfiles vfiles_link \
SplitIfNested.bs.expandif.atsexpand.expected \
NoSplitIfNested.bs.expandif.atsexpand.expected \
NoSplitIfNested.bs.noexpandif.atsexpand.expected \
Expand Down
66 changes: 66 additions & 0 deletions testsuite/bsc.options/options.exp
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,72 @@ files_exist { simfiles/mkDummyModule.cxx \
# Test the above flags with absolute paths?


###########
#
# Test that the compile stage writes 'vpi_wrapper_*' files to vdir
# or (if no vdir) to the same directory where the source file sits.
#
# And test that the linking step can find VPI wrapper files
# by looking through the Verilog search path, to successfully
# compile the wrappers and to compile the registration array.
#
# The directory of the source file is not the current directory
# (where BSC was invoked from) when -u is used to compile files
# found in multiple directories. However, it can also occur if
# the source file given on the command line include a directory
# (which is what we will test here).

# ---
# Test compile without vdir

nukedir srcfiles
erase_many {vpi_*.{c,h,o}}

# Set up the source file in a directory
mkdir srcfiles
copy GCD.bsv srcfiles

compile_verilog_pass srcfiles/GCD.bsv {} {-p srcfiles:+}
files_exist {srcfiles/vpi_wrapper_my_time.h srcfiles/vpi_wrapper_my_time.c}

# ---
# Test compile with vdir

nukedir srcfiles
nukedir vfiles
erase_many {vpi_*.{c,h,o}}

# Set up the source file in a directory
mkdir srcfiles
copy GCD.bsv srcfiles

# Create the vdir
mkdir vfiles

compile_verilog_pass srcfiles/GCD.bsv {} {-vdir vfiles -p srcfiles:+}
files_exist {vfiles/vpi_wrapper_my_time.h vfiles/vpi_wrapper_my_time.c}

# The above will have placed vpi wrappers in 'vfiles/'
# so now we test that linking can find it,
# both with or without its own other vdir

# ---
# Test link with vdir

nukedir vfiles_link
mkdir vfiles_link

link_verilog_pass {srcfiles/my_time.ba} {sysGCD} {-vsearch vfiles:+ -vdir vfiles_link}
files_exist {vfiles/vpi_wrapper_my_time.o vfiles_link/vpi_startup_array.o}

# ---
# Test link without vdir

erase_many {vfiles/vpi_*.o vpi_*.{c,h,o}}

link_verilog_pass {srcfiles/my_time.ba} {sysGCD} {-vsearch vfiles:+}
files_exist {vfiles/vpi_wrapper_my_time.o vpi_startup_array.o}

###########
#
# Test that preprocessor gets `include from the -p import path
Expand Down