mirror of https://github.com/zachjs/sv2v.git
support complex modport expressions
- modports can use complex expressions - update interface_infer test for consistency across simulators - fix interface inlining of implicitly typed data declarations
This commit is contained in:
parent
8ae925d92e
commit
8d37db30e5
|
|
@ -101,8 +101,8 @@ Other:
|
||||||
## Supported Features
|
## Supported Features
|
||||||
|
|
||||||
sv2v supports most synthesizable SystemVerilog features. Current notable
|
sv2v supports most synthesizable SystemVerilog features. Current notable
|
||||||
exceptions include `export` and complex (non-identifier) `modport` expressions.
|
exceptions include `export` and interface arrays. Assertions are also supported,
|
||||||
Assertions are also supported, but are simply dropped during conversion.
|
but are simply dropped during conversion.
|
||||||
|
|
||||||
If you find a bug or have a feature request, please create an issue. Preference
|
If you find a bug or have a feature request, please create an issue. Preference
|
||||||
will be given to issues which include examples or test cases.
|
will be given to issues which include examples or test cases.
|
||||||
|
|
|
||||||
|
|
@ -38,8 +38,10 @@ convert =
|
||||||
-- we can only collect/map non-extern interfaces
|
-- we can only collect/map non-extern interfaces
|
||||||
collectDesc :: Description -> Writer (Interfaces, Modules) ()
|
collectDesc :: Description -> Writer (Interfaces, Modules) ()
|
||||||
collectDesc (orig @ (Part _ False kw _ name ports items)) = do
|
collectDesc (orig @ (Part _ False kw _ name ports items)) = do
|
||||||
if kw == Interface
|
if kw == Interface then
|
||||||
then tell (Map.singleton name (ports, items), Map.empty)
|
if all fullyResolved items
|
||||||
|
then tell (Map.singleton name (ports, items), Map.empty)
|
||||||
|
else return ()
|
||||||
else tell (Map.empty, Map.singleton name (params, decls))
|
else tell (Map.empty, Map.singleton name (params, decls))
|
||||||
where
|
where
|
||||||
params = map fst $ parameters items
|
params = map fst $ parameters items
|
||||||
|
|
@ -51,8 +53,19 @@ convert =
|
||||||
collectDecl _ = return ()
|
collectDecl _ = return ()
|
||||||
collectDesc _ = return ()
|
collectDesc _ = return ()
|
||||||
isInterface :: Description -> Bool
|
isInterface :: Description -> Bool
|
||||||
isInterface (Part _ False Interface _ _ _ _) = True
|
isInterface (Part _ False Interface _ _ _ items) =
|
||||||
|
all fullyResolved items
|
||||||
isInterface _ = False
|
isInterface _ = False
|
||||||
|
-- returns whether a ModuleItem still contains TypeOf
|
||||||
|
fullyResolved :: ModuleItem -> Bool
|
||||||
|
fullyResolved =
|
||||||
|
not . any isTypeOf . execWriter .
|
||||||
|
collectNestedModuleItemsM (collectTypesM collectType)
|
||||||
|
where
|
||||||
|
collectType :: Type -> Writer [Type] ()
|
||||||
|
collectType t = tell [t]
|
||||||
|
isTypeOf TypeOf{} = True
|
||||||
|
isTypeOf _ = False
|
||||||
|
|
||||||
convertDescription :: Interfaces -> Modules -> Description -> Description
|
convertDescription :: Interfaces -> Modules -> Description -> Description
|
||||||
convertDescription interfaces modules (Part attrs extern Module lifetime name ports items) =
|
convertDescription interfaces modules (Part attrs extern Module lifetime name ports items) =
|
||||||
|
|
@ -72,7 +85,9 @@ convertDescription interfaces modules (Part attrs extern Module lifetime name po
|
||||||
collectInterface (MIPackageItem (Decl (Variable _ t ident _ _))) =
|
collectInterface (MIPackageItem (Decl (Variable _ t ident _ _))) =
|
||||||
case t of
|
case t of
|
||||||
InterfaceT interfaceName (Just modportName) [] ->
|
InterfaceT interfaceName (Just modportName) [] ->
|
||||||
tell (Map.empty, Map.singleton ident (interfaceName, modportDecls))
|
if Map.member interfaceName interfaces
|
||||||
|
then tell (Map.empty, Map.singleton ident (interfaceName, modportDecls))
|
||||||
|
else return ()
|
||||||
where Just modportDecls = lookupModport interfaceName modportName
|
where Just modportDecls = lookupModport interfaceName modportName
|
||||||
Alias Nothing interfaceName [] ->
|
Alias Nothing interfaceName [] ->
|
||||||
case impliedModport interfaceName of
|
case impliedModport interfaceName of
|
||||||
|
|
@ -92,7 +107,8 @@ convertDescription interfaces modules (Part attrs extern Module lifetime name po
|
||||||
-- expand instantiation of a modport
|
-- expand instantiation of a modport
|
||||||
case Map.lookup ident modports of
|
case Map.lookup ident modports of
|
||||||
Just (_, modportDecls) -> Generate $ map GenModuleItem $
|
Just (_, modportDecls) -> Generate $ map GenModuleItem $
|
||||||
filter shouldKeep interfaceItems ++ map makePortDecl modportDecls
|
filter shouldKeep interfaceItems ++ map makePortDecl
|
||||||
|
(prefixModportDecls ident modportDecls)
|
||||||
Nothing -> orig
|
Nothing -> orig
|
||||||
where
|
where
|
||||||
interfaceName = case t of
|
interfaceName = case t of
|
||||||
|
|
@ -108,10 +124,10 @@ convertDescription interfaces modules (Part attrs extern Module lifetime name po
|
||||||
shouldKeep (MIPackageItem Function{}) = True
|
shouldKeep (MIPackageItem Function{}) = True
|
||||||
shouldKeep _ = False
|
shouldKeep _ = False
|
||||||
makePortDecl :: ModportDecl -> ModuleItem
|
makePortDecl :: ModportDecl -> ModuleItem
|
||||||
makePortDecl (dir, port, expr) =
|
makePortDecl (dir, port, typ, _) =
|
||||||
MIPackageItem $ Decl $
|
MIPackageItem $ Decl $
|
||||||
Variable dir mpt (ident ++ "_" ++ port) mprs Nil
|
Variable dir mpt (ident ++ "_" ++ port) mprs Nil
|
||||||
where (mpt, mprs) = lookupType interfaceItems ident expr
|
where (mpt, mprs) = (typ, [])
|
||||||
mapInterface (Instance part params ident [] instancePorts) =
|
mapInterface (Instance part params ident [] instancePorts) =
|
||||||
-- expand modport port bindings
|
-- expand modport port bindings
|
||||||
case Map.lookup part interfaces of
|
case Map.lookup part interfaces of
|
||||||
|
|
@ -201,7 +217,7 @@ convertDescription interfaces modules (Part attrs extern Module lifetime name po
|
||||||
-- modport directly bound to a modport
|
-- modport directly bound to a modport
|
||||||
expandPortBinding' interfaceName portName ident
|
expandPortBinding' interfaceName portName ident
|
||||||
(map redirect modportDecls)
|
(map redirect modportDecls)
|
||||||
where redirect (d, x, _) = (d, x, Ident x)
|
where redirect (d, x, t, _) = (d, x, t, Ident x)
|
||||||
expandPortBinding _ other _ = ([], [other])
|
expandPortBinding _ other _ = ([], [other])
|
||||||
|
|
||||||
expandPortBinding' :: Identifier -> Identifier -> Identifier ->
|
expandPortBinding' :: Identifier -> Identifier -> Identifier ->
|
||||||
|
|
@ -214,7 +230,7 @@ convertDescription interfaces modules (Part attrs extern Module lifetime name po
|
||||||
interfaceParamNames = map fst $ parameters interfaceItems
|
interfaceParamNames = map fst $ parameters interfaceItems
|
||||||
toParamBinding x = (portName ++ '_' : x, Right $ Ident $ instanceName ++ '_' : x)
|
toParamBinding x = (portName ++ '_' : x, Right $ Ident $ instanceName ++ '_' : x)
|
||||||
portBindings = map toPortBinding modportDecls
|
portBindings = map toPortBinding modportDecls
|
||||||
toPortBinding (_, x, e) = (x', e')
|
toPortBinding (_, x, _, e) = (x', e')
|
||||||
where
|
where
|
||||||
x' = portName ++ '_' : x
|
x' = portName ++ '_' : x
|
||||||
e' = traverseNestedExprs prefixExpr e
|
e' = traverseNestedExprs prefixExpr e
|
||||||
|
|
@ -247,8 +263,8 @@ convertDescription interfaces modules (Part attrs extern Module lifetime name po
|
||||||
mapM (collectNestedModuleItemsM collectModportDecls) $
|
mapM (collectNestedModuleItemsM collectModportDecls) $
|
||||||
interfaceItems
|
interfaceItems
|
||||||
collectModportDecls :: ModuleItem -> Writer [ModportDecl] ()
|
collectModportDecls :: ModuleItem -> Writer [ModportDecl] ()
|
||||||
collectModportDecls (MIPackageItem (Decl (Variable d _ x _ _))) =
|
collectModportDecls (MIPackageItem (Decl (Variable d t x _ _))) =
|
||||||
tell [(d', x, Ident x)]
|
tell [(d', x, t, Ident x)]
|
||||||
where d' = if d == Local then Inout else d
|
where d' = if d == Local then Inout else d
|
||||||
collectModportDecls _ = return ()
|
collectModportDecls _ = return ()
|
||||||
|
|
||||||
|
|
@ -268,7 +284,8 @@ convertDescription interfaces modules (Part attrs extern Module lifetime name po
|
||||||
convertPort ident =
|
convertPort ident =
|
||||||
case Map.lookup ident modports of
|
case Map.lookup ident modports of
|
||||||
Nothing -> [ident]
|
Nothing -> [ident]
|
||||||
Just (_, decls) -> map (\(_, x, _) -> ident ++ "_" ++ x) decls
|
Just (_, decls) -> map (\(_, x, _, _) ->
|
||||||
|
ident ++ "_" ++ x) decls
|
||||||
|
|
||||||
convertDescription _ _ other = other
|
convertDescription _ _ other = other
|
||||||
|
|
||||||
|
|
@ -324,20 +341,23 @@ collectIdentsM item = collectDeclsM collectDecl item
|
||||||
collectDecl (ParamType _ x _) = tell $ Set.singleton x
|
collectDecl (ParamType _ x _) = tell $ Set.singleton x
|
||||||
collectDecl (CommentDecl _) = return ()
|
collectDecl (CommentDecl _) = return ()
|
||||||
|
|
||||||
lookupType :: [ModuleItem] -> Identifier -> Expr -> (Type, [Range])
|
-- add a prefix to the expressions in a modport definition
|
||||||
lookupType items prefix (Ident ident) =
|
prefixModportDecls :: Identifier -> [ModportDecl] -> [ModportDecl]
|
||||||
case mapMaybe findType items of
|
prefixModportDecls name modportDecls =
|
||||||
[] -> error $ "unable to locate type of " ++ ident
|
map mapper modportDecls
|
||||||
ts -> head ts
|
|
||||||
where
|
where
|
||||||
findType :: ModuleItem -> Maybe (Type, [Range])
|
mapper :: ModportDecl -> ModportDecl
|
||||||
findType (MIPackageItem (Decl (Variable _ t x rs _))) =
|
mapper (d, x, t, e) = (d, x, t', e')
|
||||||
if x == prefix ++ "_" ++ ident then Just (t, rs) else Nothing
|
where
|
||||||
findType _ = Nothing
|
exprMapper = traverseNestedExprs prefixExpr
|
||||||
lookupType _ _ expr =
|
t' = traverseNestedTypes (traverseTypeExprs exprMapper) t
|
||||||
-- TODO: Add support for non-Ident modport expressions.
|
e' = exprMapper e
|
||||||
error $ "interface conversion does not support modport expressions that "
|
prefix :: Identifier -> Identifier
|
||||||
++ " are not identifiers: " ++ show expr
|
prefix = (++) $ name ++ "_"
|
||||||
|
prefixExpr :: Expr -> Expr
|
||||||
|
prefixExpr (Ident ('$' : x)) = Ident $ '$' : x
|
||||||
|
prefixExpr (Ident x) = Ident (prefix x)
|
||||||
|
prefixExpr other = other
|
||||||
|
|
||||||
-- convert an interface instantiation into a series of equivalent module items
|
-- convert an interface instantiation into a series of equivalent module items
|
||||||
inlineInterface :: Interface -> (Identifier, [ParamBinding], [PortBinding]) -> [ModuleItem]
|
inlineInterface :: Interface -> (Identifier, [ParamBinding], [PortBinding]) -> [ModuleItem]
|
||||||
|
|
@ -367,7 +387,11 @@ inlineInterface (ports, items) (instanceName, instanceParams, instancePorts) =
|
||||||
|
|
||||||
removeDeclDir :: ModuleItem -> ModuleItem
|
removeDeclDir :: ModuleItem -> ModuleItem
|
||||||
removeDeclDir (MIPackageItem (Decl (Variable _ t x a e))) =
|
removeDeclDir (MIPackageItem (Decl (Variable _ t x a e))) =
|
||||||
MIPackageItem $ Decl $ Variable Local t x a e
|
MIPackageItem $ Decl $ Variable Local t' x a e
|
||||||
|
where t' = case t of
|
||||||
|
Implicit Unspecified rs ->
|
||||||
|
IntegerVector TLogic Unspecified rs
|
||||||
|
_ -> t
|
||||||
removeDeclDir other = other
|
removeDeclDir other = other
|
||||||
removeModport :: ModuleItem -> ModuleItem
|
removeModport :: ModuleItem -> ModuleItem
|
||||||
removeModport (Modport x _) =
|
removeModport (Modport x _) =
|
||||||
|
|
|
||||||
|
|
@ -56,10 +56,11 @@ convert =
|
||||||
portName ++ " in module " ++ name
|
portName ++ " in module " ++ name
|
||||||
collectPortsM _ = return ()
|
collectPortsM _ = return ()
|
||||||
collectDeclDirsM :: ModuleItem -> Writer [(Identifier, Direction)] ()
|
collectDeclDirsM :: ModuleItem -> Writer [(Identifier, Direction)] ()
|
||||||
collectDeclDirsM (MIPackageItem (Decl (Variable dir _ ident _ _))) =
|
collectDeclDirsM (MIPackageItem (Decl (Variable dir t ident _ _))) =
|
||||||
if dir == Local
|
case (dir, t) of
|
||||||
then return ()
|
(_, InterfaceT{}) -> tell [(ident, Local)]
|
||||||
else tell [(ident, dir)]
|
(Local, _) -> return ()
|
||||||
|
_ -> tell [(ident, dir)]
|
||||||
collectDeclDirsM _ = return ()
|
collectDeclDirsM _ = return ()
|
||||||
|
|
||||||
convertDescription :: Ports -> Description -> Description
|
convertDescription :: Ports -> Description -> Description
|
||||||
|
|
|
||||||
|
|
@ -648,9 +648,10 @@ traverseExprsM' strat exprMapper = moduleItemMapper
|
||||||
return $ GenCase e' cases'
|
return $ GenCase e' cases'
|
||||||
genItemMapper other = return other
|
genItemMapper other = return other
|
||||||
|
|
||||||
modportDeclMapper (dir, ident, e) = do
|
modportDeclMapper (dir, ident, t, e) = do
|
||||||
|
t' <- typeMapper t
|
||||||
e' <- exprMapper e
|
e' <- exprMapper e
|
||||||
return (dir, ident, e')
|
return (dir, ident, t', e')
|
||||||
|
|
||||||
traverseExprs' :: TFStrategy -> Mapper Expr -> Mapper ModuleItem
|
traverseExprs' :: TFStrategy -> Mapper Expr -> Mapper ModuleItem
|
||||||
traverseExprs' strat = unmonad $ traverseExprsM' strat
|
traverseExprs' strat = unmonad $ traverseExprsM' strat
|
||||||
|
|
@ -933,6 +934,11 @@ traverseTypesM' strategy mapper item =
|
||||||
then fullMapper t >>= \t' -> return (i, Left t')
|
then fullMapper t >>= \t' -> return (i, Left t')
|
||||||
else return (i, Left t)
|
else return (i, Left t)
|
||||||
mapParam (i, Right e) = return $ (i, Right e)
|
mapParam (i, Right e) = return $ (i, Right e)
|
||||||
|
miMapper (Modport name decls) =
|
||||||
|
mapM mapModportDecl decls >>= return . Modport name
|
||||||
|
where
|
||||||
|
mapModportDecl (d, x, t, e) =
|
||||||
|
fullMapper t >>= \t' -> return (d, x, t', e)
|
||||||
miMapper other = return other
|
miMapper other = return other
|
||||||
|
|
||||||
traverseTypes' :: TypeStrategy -> Mapper Type -> Mapper ModuleItem
|
traverseTypes' :: TypeStrategy -> Mapper Type -> Mapper ModuleItem
|
||||||
|
|
|
||||||
|
|
@ -28,7 +28,7 @@ import Language.SystemVerilog.AST.Expr (Expr(Ident, Nil), Range, TypeOrExpr, sho
|
||||||
import Language.SystemVerilog.AST.GenItem (GenItem)
|
import Language.SystemVerilog.AST.GenItem (GenItem)
|
||||||
import Language.SystemVerilog.AST.LHS (LHS)
|
import Language.SystemVerilog.AST.LHS (LHS)
|
||||||
import Language.SystemVerilog.AST.Stmt (Stmt, AssertionItem, Timing(Delay))
|
import Language.SystemVerilog.AST.Stmt (Stmt, AssertionItem, Timing(Delay))
|
||||||
import Language.SystemVerilog.AST.Type (Identifier, DriveStrength)
|
import Language.SystemVerilog.AST.Type (Type, Identifier, DriveStrength)
|
||||||
|
|
||||||
data ModuleItem
|
data ModuleItem
|
||||||
= MIAttr Attr ModuleItem
|
= MIAttr Attr ModuleItem
|
||||||
|
|
@ -99,16 +99,16 @@ showParam (i, arg) =
|
||||||
where fmt = if i == "" then "%s%s" else ".%s(%s)"
|
where fmt = if i == "" then "%s%s" else ".%s(%s)"
|
||||||
|
|
||||||
showModportDecl :: ModportDecl -> String
|
showModportDecl :: ModportDecl -> String
|
||||||
showModportDecl (dir, ident, e) =
|
showModportDecl (dir, ident, t, e) =
|
||||||
if e == Ident ident
|
if e == Ident ident
|
||||||
then printf "%s %s" (show dir) ident
|
then printf "%s %s" (show dir) ident
|
||||||
else printf "%s .%s(%s)" (show dir) ident (show e)
|
else printf "%s .%s(/* type: %s */ %s)" (show dir) ident (show t) (show e)
|
||||||
|
|
||||||
type PortBinding = (Identifier, Expr)
|
type PortBinding = (Identifier, Expr)
|
||||||
|
|
||||||
type ParamBinding = (Identifier, TypeOrExpr)
|
type ParamBinding = (Identifier, TypeOrExpr)
|
||||||
|
|
||||||
type ModportDecl = (Direction, Identifier, Expr)
|
type ModportDecl = (Direction, Identifier, Type, Expr)
|
||||||
|
|
||||||
data AlwaysKW
|
data AlwaysKW
|
||||||
= Always
|
= Always
|
||||||
|
|
|
||||||
|
|
@ -588,7 +588,7 @@ ModportPortsDeclarations :: { [ModportDecl] }
|
||||||
ModportPortsDeclaration(delim) :: { [ModportDecl] }
|
ModportPortsDeclaration(delim) :: { [ModportDecl] }
|
||||||
: ModportSimplePortsDeclaration(delim) { $1 }
|
: ModportSimplePortsDeclaration(delim) { $1 }
|
||||||
ModportSimplePortsDeclaration(delim) :: { [ModportDecl] }
|
ModportSimplePortsDeclaration(delim) :: { [ModportDecl] }
|
||||||
: Direction ModportSimplePorts delim { map (\(a, b) -> ($1, a, b)) $2 }
|
: Direction ModportSimplePorts delim { map (\(a, b) -> ($1, a, TypeOf b, b)) $2 }
|
||||||
ModportSimplePorts :: { [(Identifier, Expr)] }
|
ModportSimplePorts :: { [(Identifier, Expr)] }
|
||||||
: ModportSimplePort { [$1] }
|
: ModportSimplePort { [$1] }
|
||||||
| ModportSimplePorts "," ModportSimplePort { $1 ++ [$3] }
|
| ModportSimplePorts "," ModportSimplePort { $1 ++ [$3] }
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
localparam SOME_VAL = 3;
|
localparam SOME_VAL = 3;
|
||||||
interface Interface;
|
interface Interface;
|
||||||
logic x;
|
logic x = 0;
|
||||||
modport Modport(
|
modport Modport(
|
||||||
input x
|
input x
|
||||||
);
|
);
|
||||||
|
|
@ -15,11 +15,11 @@ module Module(Interface.Modport foo);
|
||||||
initial $display("Module %d", foo.x);
|
initial $display("Module %d", foo.x);
|
||||||
endmodule
|
endmodule
|
||||||
module top;
|
module top;
|
||||||
|
Interface i();
|
||||||
|
Module m(i);
|
||||||
generate
|
generate
|
||||||
for (genvar g = 0; g < 5; ++g) begin
|
for (genvar g = 0; g < 5; ++g) begin
|
||||||
initial $display(g);
|
initial $display(g);
|
||||||
end
|
end
|
||||||
endgenerate
|
endgenerate
|
||||||
Interface i();
|
|
||||||
Module m(i);
|
|
||||||
endmodule
|
endmodule
|
||||||
|
|
|
||||||
|
|
@ -2,16 +2,16 @@ module Module(input wire x);
|
||||||
initial $display("Module %d", x);
|
initial $display("Module %d", x);
|
||||||
endmodule
|
endmodule
|
||||||
module top;
|
module top;
|
||||||
wire i_x;
|
wire i_x = 0;
|
||||||
localparam SOME_VAL = 3;
|
localparam SOME_VAL = 3;
|
||||||
initial $display("Interface %d %d", i_x, SOME_VAL);
|
initial $display("Interface %d %d", i_x, SOME_VAL);
|
||||||
Module m(.x(i_x));
|
Module m(.x(i_x));
|
||||||
generate
|
generate
|
||||||
genvar g;
|
genvar g;
|
||||||
for (g = 0; g < 5; g = g + 1) begin
|
for (g = 10; g < 15; g = g + 1) begin
|
||||||
initial $display(g);
|
initial $display(g);
|
||||||
end
|
end
|
||||||
for (g = 10; g < 15; g = g + 1) begin
|
for (g = 0; g < 5; g = g + 1) begin
|
||||||
initial $display(g);
|
initial $display(g);
|
||||||
end
|
end
|
||||||
endgenerate
|
endgenerate
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,51 @@
|
||||||
|
interface Interface #(parameter WIDTH = 4) (
|
||||||
|
input clock,
|
||||||
|
output [$clog2(WIDTH) - 1:0] indices [2]
|
||||||
|
);
|
||||||
|
logic [2*WIDTH-1:0] x;
|
||||||
|
modport ModportA(
|
||||||
|
input clock,
|
||||||
|
output indices,
|
||||||
|
input .x(x[2*WIDTH-1:WIDTH]), .y(x[WIDTH-1:0])
|
||||||
|
);
|
||||||
|
modport ModportB(
|
||||||
|
input clock,
|
||||||
|
output .x(x)
|
||||||
|
);
|
||||||
|
endinterface
|
||||||
|
|
||||||
|
module ModuleA(Interface.ModportA m);
|
||||||
|
assign m.indices[0] = $clog2(m.x);
|
||||||
|
assign m.indices[1] = $clog2(m.y);
|
||||||
|
endmodule
|
||||||
|
|
||||||
|
module ModuleB(Interface.ModportB m);
|
||||||
|
initial m.x = 1;
|
||||||
|
localparam WIDTH = 2 * m.WIDTH;
|
||||||
|
always @(posedge m.clock) begin
|
||||||
|
logic temp;
|
||||||
|
temp = m.x[WIDTH-1];
|
||||||
|
for (integer i = WIDTH-1; i > 0; --i) begin
|
||||||
|
m.x[i] = m.x[i-1];
|
||||||
|
end
|
||||||
|
m.x[0] = temp;
|
||||||
|
end
|
||||||
|
endmodule
|
||||||
|
|
||||||
|
module ModuleBWrapper(Interface.ModportB m);
|
||||||
|
ModuleB b(m);
|
||||||
|
endmodule
|
||||||
|
|
||||||
|
module ModuleAWrapper(Interface.ModportA m);
|
||||||
|
ModuleA a(m);
|
||||||
|
endmodule
|
||||||
|
|
||||||
|
module Tester(input clock);
|
||||||
|
parameter WIDTH = 1;
|
||||||
|
logic [WIDTH-1:0] idx1, idx2;
|
||||||
|
Interface #(2 ** WIDTH) i(clock, '{idx1, idx2});
|
||||||
|
ModuleAWrapper a(i);
|
||||||
|
ModuleBWrapper b(i);
|
||||||
|
always @(negedge clock)
|
||||||
|
$display("%d %0d %2d %2d %b", $time, WIDTH, idx1, idx2, i.x);
|
||||||
|
endmodule
|
||||||
|
|
@ -0,0 +1,26 @@
|
||||||
|
module Tester(input clock);
|
||||||
|
parameter WIDTH = 1;
|
||||||
|
|
||||||
|
localparam DATA_WIDTH = 2 ** WIDTH;
|
||||||
|
|
||||||
|
reg [2*DATA_WIDTH-1:0] x;
|
||||||
|
initial x = 1;
|
||||||
|
|
||||||
|
wire [WIDTH-1:0] idx1, idx2;
|
||||||
|
assign idx1 = $clog2(x[2*DATA_WIDTH-1:DATA_WIDTH]);
|
||||||
|
assign idx2 = $clog2(x[DATA_WIDTH-1:0]);
|
||||||
|
|
||||||
|
always @(posedge clock) begin : block
|
||||||
|
localparam SIZE = 2 * DATA_WIDTH;
|
||||||
|
integer i;
|
||||||
|
reg temp;
|
||||||
|
temp = x[SIZE-1];
|
||||||
|
for (i = SIZE-1; i > 0; i = i - 1) begin
|
||||||
|
x[i] = x[i-1];
|
||||||
|
end
|
||||||
|
x[0] = temp;
|
||||||
|
end
|
||||||
|
|
||||||
|
always @(negedge clock)
|
||||||
|
$display("%d %0d %2d %2d %b", $time, WIDTH, idx1, idx2, x);
|
||||||
|
endmodule
|
||||||
|
|
@ -0,0 +1,18 @@
|
||||||
|
module top;
|
||||||
|
reg clock;
|
||||||
|
initial begin
|
||||||
|
clock = 1;
|
||||||
|
forever #5 clock = ~clock;
|
||||||
|
end
|
||||||
|
|
||||||
|
initial begin
|
||||||
|
repeat(30)
|
||||||
|
@(posedge clock);
|
||||||
|
$finish;
|
||||||
|
end
|
||||||
|
|
||||||
|
Tester #(1) t1(clock);
|
||||||
|
Tester #(2) t2(clock);
|
||||||
|
Tester #(3) t3(clock);
|
||||||
|
Tester #(4) t4(clock);
|
||||||
|
endmodule
|
||||||
Loading…
Reference in New Issue