Skip to content
Open
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
2 changes: 1 addition & 1 deletion src/comp/GenWrap.hs
Original file line number Diff line number Diff line change
Expand Up @@ -1814,7 +1814,7 @@ isParamType :: Type -> GWMonad Bool
isParamType t =
do
t' <- expandSynSym t
return (t' == tReal || t' == tString)
return (t' == tReal || t' == tString || t' == tInteger)

isClockType :: Type -> GWMonad Bool
isClockType t =
Expand Down
12 changes: 12 additions & 0 deletions src/comp/IExpand.hs
Original file line number Diff line number Diff line change
Expand Up @@ -3503,6 +3503,12 @@ conAp' tfs (ICPrim _ PrimIntegerToBit) fe [T ty@(ITNum k), E e] = evalStaticOp e
| otherwise = result
where err = errG (getIdPosition i, EInvalidLiteral "Bit" k (pfpString il))
result = return $ pExpr $ iMkLitWBAt (getIdPosition i) (itBitN k) w b (mask k l)
-- a module parameter of type Integer has no literal value at
-- elaboration time; re-type the reference at the target size so
-- it lowers to a reference to the Verilog parameter
-- (no range check is possible on a symbolic value)
handleInt (ICon i (ICModParam it)) | it == itInteger =
return $ pExpr $ ICon i (ICModParam (itBitN k))
handleInt e' = nfError "primIntegerToBit" $ mkAp fe [T ty, E e']

-- Special case of doPrimOp that checks bounds and keeps the base.
Expand All @@ -3513,6 +3519,9 @@ conAp' tfs (ICPrim _ PrimIntegerToUIntBits) fe [T ty@(ITNum k), E e] = evalStati
errG (getIdPosition i, EInvalidLiteral "UInt" k (pfpString il))
else
return $ pExpr $ iMkLitWBAt (getIdPosition i) (itBitN k) w b (mask k l)
-- symbolic Integer module parameter (see PrimIntegerToBit)
handleInt (ICon i (ICModParam it)) | it == itInteger =
return $ pExpr $ ICon i (ICModParam (itBitN k))
handleInt e' = nfError "primIntegerToUIntBits" $ mkAp fe [T ty, E e']

-- Special case of doPrimOp that checks bounds and keeps the base.
Expand All @@ -3528,6 +3537,9 @@ conAp' tfs (ICPrim _ PrimIntegerToIntBits) fe [T ty@(ITNum k), E e] = evalStatic
| otherwise = result
where err = errG (getIdPosition i, EInvalidLiteral "Int" k (pfpString il))
result = return $ pExpr $ iMkLitWBAt (getIdPosition i) (itBitN k) w b (mask k l)
-- symbolic Integer module parameter (see PrimIntegerToBit)
handleInt (ICon i (ICModParam it)) | it == itInteger =
return $ pExpr $ ICon i (ICModParam (itBitN k))
handleInt e' = nfError "primIntegerToIntBits" $ mkAp fe [T ty, E e']

-- XXX This could go in doPrimOp
Expand Down
2 changes: 1 addition & 1 deletion src/comp/IExpandUtils.hs
Original file line number Diff line number Diff line change
Expand Up @@ -381,7 +381,7 @@ isPrimTAp (ITAp a (ITNum _)) = isPrimTAp a
isPrimTAp _ = False

isParamOnlyType :: IType -> Bool
isParamOnlyType t = t == itString || t == itReal
isParamOnlyType t = t == itString || t == itReal || t == itInteger

-----------------------------------------------------------------------------

Expand Down
15 changes: 13 additions & 2 deletions src/comp/SimExpand.hs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ import FStringCompat(mkFString)
import Backend

import PreStrings (sSigned, sUnsigned)
import PreIds (idDefaultClock, idDefaultReset)
import PreIds (idDefaultClock, idDefaultReset, idInteger)
import Id (mkId,
setSignedId, getIdString, unQualId, isRdyId,
getIdBaseString, getIdQualString, setIdQualString, emptyId,
Expand Down Expand Up @@ -218,13 +218,24 @@ simExpandABin errh flags (abi,ver) = do

let insts = apkg_state_instances apkg

let
-- Integer parameters are canonicalized to Bit 32 at instantiation
-- (see PrimParam in the Prelude) and referenced at Bit types, so
-- give the input the same representation; Bluesim has no value
-- type for an abstract Integer
cvtIntegerParam (AAI_Port (i, ATAbstract t []), vai)
| isParam vai && t == idInteger = AAI_Port (i, ATBit 32)
cvtIntegerParam (ai, _) = ai

inputs = map cvtIntegerParam (getAPackageInputs apkg)

let simpkg = SimPackage {
sp_name = apkg_name apkg,
sp_is_wrapped = apkg_is_wrapped apkg,
sp_version = ver,
sp_pps = abmi_pps abi,
sp_size_params = apkg_size_params apkg,
sp_inputs = apkg_inputs apkg,
sp_inputs = inputs,
sp_clock_domains = apkg_clock_domains apkg,
sp_external_wires = apkg_external_wires apkg,
sp_reset_list = apkg_reset_list apkg,
Expand Down
27 changes: 27 additions & 0 deletions testsuite/bsc.verilog/parameters/integer/IntParam.bs
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
package IntParam where

-- Test that a module argument of type Integer becomes a Verilog
-- parameter on a synthesis boundary. The parameter can be displayed
-- directly and can be used in hardware expressions via fromInteger,
-- which lowers to a sized reference to the Verilog parameter.
-- (In Bluesim, the parameter becomes a 32-bit module input, since the
-- instantiation value is canonicalized to Bit 32.)

{-# verilog mkIntParamSub { parameter val } #-}
mkIntParamSub :: Integer -> Module Empty
mkIntParamSub val =
module
count :: Reg (UInt 8) <- mkReg 0
rules
"count": when (count /= fromInteger val) ==>
count := count + 1
"done": when (count == fromInteger val) ==>
action
$display "val = %0d" val
$display "count = %0d" count
$finish 0

-- Test that a parent module can provide the value
{-# verilog sysIntParam #-}
sysIntParam :: Module Empty
sysIntParam = mkIntParamSub 5
14 changes: 14 additions & 0 deletions testsuite/bsc.verilog/parameters/integer/IntParamErr1.bs
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package IntParamErr1 where

-- An Integer module argument is only supported as a parameter;
-- without the "parameter" pragma it should be reported as an error

{-# verilog mkIntParamErr #-}
mkIntParamErr :: Integer -> Module Empty
mkIntParamErr val =
module
rules
"test": when True ==>
action
$display "val = %0d" val
$finish 0
5 changes: 5 additions & 0 deletions testsuite/bsc.verilog/parameters/integer/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# for "make clean" to work everywhere

CONFDIR = $(realpath ../../..)

include $(CONFDIR)/clean.mk
22 changes: 22 additions & 0 deletions testsuite/bsc.verilog/parameters/integer/integer_param.exp
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
#
# Tests for Integer module arguments as parameters
#

# An Integer module argument is only supported on a synthesis boundary
# as a parameter (with the "parameter" pragma / keyword); the value is
# canonicalized to 32 bits at the instantiation site.

# Test that an Integer parameter can be displayed and used in hardware
# expressions (via fromInteger), and that a parent module can provide
# the value
test_c_veri_bs_modules IntParam mkIntParamSub

if { $vtest == 1 } {
# the parameter is declared unsized, with a zero default
find_regexp mkIntParamSub.v {parameter val \= 0\;}
# the parent provides the elaborated value
find_regexp sysIntParam.v {\.val\((32\'d)?5\)}
}

# require the parameter pragma on Integer module arguments
compile_verilog_fail_error IntParamErr1.bs G0120
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
val = 5
count = 5
Loading