Commit 231b7f99 by Zachary Snow

interface conversion respects port direction when inlining bindings

parent c168ec47
...@@ -6,7 +6,7 @@ ...@@ -6,7 +6,7 @@
module Convert.Interface (convert) where module Convert.Interface (convert) where
import Data.Maybe (isJust, mapMaybe) import Data.Maybe (mapMaybe)
import Control.Monad.Writer import Control.Monad.Writer
import qualified Data.Map.Strict as Map import qualified Data.Map.Strict as Map
import qualified Data.Set as Set import qualified Data.Set as Set
...@@ -216,10 +216,10 @@ inlineInterface (ports, items) (instanceName, instancePorts) = ...@@ -216,10 +216,10 @@ inlineInterface (ports, items) (instanceName, instancePorts) =
flip (++) portBindings $ flip (++) portBindings $
map (traverseNestedModuleItems removeModport) $ map (traverseNestedModuleItems removeModport) $
map (traverseNestedModuleItems removeMIDeclDir) $ map (traverseNestedModuleItems removeMIDeclDir) $
map (prefixModuleItems prefix) $ itemsPrefixed
items
where where
prefix = instanceName ++ "_" prefix = instanceName ++ "_"
itemsPrefixed = map (prefixModuleItems prefix) $ items
origInstancePortNames = map fst instancePorts origInstancePortNames = map fst instancePorts
instancePortExprs = map snd instancePorts instancePortExprs = map snd instancePorts
instancePortNames = instancePortNames =
...@@ -228,8 +228,7 @@ inlineInterface (ports, items) (instanceName, instancePorts) = ...@@ -228,8 +228,7 @@ inlineInterface (ports, items) (instanceName, instancePorts) =
then ports then ports
else origInstancePortNames else origInstancePortNames
portBindings = portBindings =
map (\(ident, Just expr) -> Assign Nothing (LHSIdent ident) expr) $ mapMaybe portBindingItem $
filter (isJust . snd) $
zip instancePortNames instancePortExprs zip instancePortNames instancePortExprs
removeMIDeclDir :: ModuleItem -> ModuleItem removeMIDeclDir :: ModuleItem -> ModuleItem
...@@ -240,3 +239,29 @@ inlineInterface (ports, items) (instanceName, instancePorts) = ...@@ -240,3 +239,29 @@ inlineInterface (ports, items) (instanceName, instancePorts) =
removeModport (Modport x _) = removeModport (Modport x _) =
MIPackageItem $ Comment $ "removed modport " ++ x MIPackageItem $ Comment $ "removed modport " ++ x
removeModport other = other 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"
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
\ No newline at end of file
// 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
\ No newline at end of file
`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
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment