mirror of https://github.com/zachjs/sv2v.git
interface conversion respects port direction when inlining bindings
This commit is contained in:
parent
c168ec4794
commit
231b7f9936
|
|
@ -6,7 +6,7 @@
|
|||
|
||||
module Convert.Interface (convert) where
|
||||
|
||||
import Data.Maybe (isJust, mapMaybe)
|
||||
import Data.Maybe (mapMaybe)
|
||||
import Control.Monad.Writer
|
||||
import qualified Data.Map.Strict as Map
|
||||
import qualified Data.Set as Set
|
||||
|
|
@ -216,10 +216,10 @@ inlineInterface (ports, items) (instanceName, instancePorts) =
|
|||
flip (++) portBindings $
|
||||
map (traverseNestedModuleItems removeModport) $
|
||||
map (traverseNestedModuleItems removeMIDeclDir) $
|
||||
map (prefixModuleItems prefix) $
|
||||
items
|
||||
itemsPrefixed
|
||||
where
|
||||
prefix = instanceName ++ "_"
|
||||
itemsPrefixed = map (prefixModuleItems prefix) $ items
|
||||
origInstancePortNames = map fst instancePorts
|
||||
instancePortExprs = map snd instancePorts
|
||||
instancePortNames =
|
||||
|
|
@ -228,8 +228,7 @@ inlineInterface (ports, items) (instanceName, instancePorts) =
|
|||
then ports
|
||||
else origInstancePortNames
|
||||
portBindings =
|
||||
map (\(ident, Just expr) -> Assign Nothing (LHSIdent ident) expr) $
|
||||
filter (isJust . snd) $
|
||||
mapMaybe portBindingItem $
|
||||
zip instancePortNames instancePortExprs
|
||||
|
||||
removeMIDeclDir :: ModuleItem -> ModuleItem
|
||||
|
|
@ -240,3 +239,29 @@ inlineInterface (ports, items) (instanceName, instancePorts) =
|
|||
removeModport (Modport x _) =
|
||||
MIPackageItem $ Comment $ "removed modport " ++ x
|
||||
removeModport other = other
|
||||
|
||||
portBindingItem :: PortBinding -> Maybe ModuleItem
|
||||
portBindingItem (ident, Just expr) =
|
||||
Just $ if declDirs Map.! ident == Input
|
||||
then Assign Nothing (LHSIdent ident) expr
|
||||
else Assign Nothing (exprToLHS expr) (Ident ident)
|
||||
portBindingItem (_, Nothing) = Nothing
|
||||
|
||||
declDirs = execWriter $
|
||||
mapM (collectDeclsM collectDeclDir) itemsPrefixed
|
||||
collectDeclDir :: Decl -> Writer (Map.Map Identifier Direction) ()
|
||||
collectDeclDir (Variable dir _ ident _ _) =
|
||||
if dir /= Local
|
||||
then tell $ Map.singleton ident dir
|
||||
else return ()
|
||||
collectDeclDir _ = return ()
|
||||
|
||||
exprToLHS :: Expr -> LHS
|
||||
exprToLHS (Ident x ) = LHSIdent x
|
||||
exprToLHS (Bit l e ) = LHSBit (exprToLHS l) e
|
||||
exprToLHS (Range l m r) = LHSRange (exprToLHS l) m r
|
||||
exprToLHS (Dot l x ) = LHSDot (exprToLHS l) x
|
||||
exprToLHS (Concat ls ) = LHSConcat $ map exprToLHS ls
|
||||
exprToLHS other =
|
||||
error $ "trying to bind (part of) an interface output to " ++
|
||||
show other ++ " but that can't be an LHS"
|
||||
|
|
|
|||
|
|
@ -0,0 +1,49 @@
|
|||
interface CacheSetInterface(
|
||||
input logic [7:0] request,
|
||||
output logic [7:0] response
|
||||
);
|
||||
|
||||
modport CacheSet(
|
||||
input request,
|
||||
output response
|
||||
);
|
||||
|
||||
endinterface
|
||||
|
||||
module CacheWithInterface(
|
||||
input logic [7:0] dataIn,
|
||||
output logic [7:0] dataOut,
|
||||
input logic clock, clear
|
||||
);
|
||||
|
||||
logic [7:0] myRequest;
|
||||
logic [7:0] myResponse;
|
||||
|
||||
CacheSetInterface dataInterface(
|
||||
.request(myRequest),
|
||||
.response(myResponse)
|
||||
);
|
||||
|
||||
CacheSet set(
|
||||
.data(dataInterface.CacheSet),
|
||||
.clock,
|
||||
.clear
|
||||
);
|
||||
|
||||
assign myRequest = dataIn;
|
||||
assign dataOut = myResponse;
|
||||
|
||||
endmodule
|
||||
|
||||
module CacheSet (
|
||||
CacheSetInterface.CacheSet data,
|
||||
input logic clock, clear
|
||||
);
|
||||
|
||||
always_ff @(posedge clock)
|
||||
if(clear)
|
||||
data.response <= 8'h0;
|
||||
else
|
||||
data.response <= ~data.request;
|
||||
|
||||
endmodule
|
||||
|
|
@ -0,0 +1,59 @@
|
|||
// interface CacheSetInterface(
|
||||
// input logic [7:0] request,
|
||||
// output logic [7:0] response
|
||||
// );
|
||||
|
||||
// modport CacheSet(
|
||||
// input request,
|
||||
// output response
|
||||
// );
|
||||
|
||||
// endinterface
|
||||
|
||||
module CacheWithInterface(
|
||||
input wire [7:0] dataIn,
|
||||
output wire [7:0] dataOut,
|
||||
input wire clock, clear
|
||||
);
|
||||
|
||||
wire [7:0] myRequest;
|
||||
wire [7:0] myResponse;
|
||||
|
||||
// CacheSetInterface dataInterface(
|
||||
// .request(myRequest),
|
||||
// .response(myResponse)
|
||||
// );
|
||||
|
||||
wire [7:0] dataInterface_request;
|
||||
wire [7:0] dataInterface_response;
|
||||
generate
|
||||
assign dataInterface_request = myRequest;
|
||||
// dataInterface.myResponse is an output
|
||||
assign myResponse = dataInterface_response;
|
||||
endgenerate
|
||||
|
||||
CacheSet set(
|
||||
.data_request(dataInterface_request),
|
||||
.data_response(dataInterface_response),
|
||||
.clock(clock),
|
||||
.clear(clear)
|
||||
);
|
||||
|
||||
assign myRequest = dataIn;
|
||||
assign dataOut = myResponse;
|
||||
|
||||
endmodule
|
||||
|
||||
module CacheSet (
|
||||
input wire [7:0] data_request,
|
||||
output reg [7:0] data_response,
|
||||
input wire clock, clear
|
||||
);
|
||||
|
||||
always @(posedge clock)
|
||||
if(clear)
|
||||
data_response <= 8'h0;
|
||||
else
|
||||
data_response <= ~data_request;
|
||||
|
||||
endmodule
|
||||
|
|
@ -0,0 +1,39 @@
|
|||
`default_nettype none
|
||||
|
||||
module top;
|
||||
|
||||
reg [8:0] dataIn;
|
||||
wire [7:0] dataOut;
|
||||
reg clock, clear;
|
||||
|
||||
|
||||
CacheWithInterface dut(
|
||||
.dataIn(dataIn[7:0]),
|
||||
.dataOut(dataOut),
|
||||
.clock(clock),
|
||||
.clear(clear)
|
||||
);
|
||||
|
||||
initial begin
|
||||
clock = 1;
|
||||
forever #5 clock = ~clock;
|
||||
end
|
||||
|
||||
reg [7:0] last;
|
||||
initial begin
|
||||
$monitor($time, " %h -> %h [%h]", dataIn, dataOut, last);
|
||||
clear = 1'b1;
|
||||
last = 8'h0;
|
||||
dataIn = 8'h0;
|
||||
repeat (3) @(posedge clock);
|
||||
clear = 1'b0;
|
||||
for (dataIn = 8'h0; dataIn <= 9'hff; dataIn = dataIn + 8'h1) begin
|
||||
@(posedge clock);
|
||||
if (~dataOut != last)
|
||||
$error("Mismatch");
|
||||
last = last + 8'h1;
|
||||
end
|
||||
$finish;
|
||||
end
|
||||
endmodule
|
||||
|
||||
Loading…
Reference in New Issue