Commit 231b7f99 by Zachary Snow

interface conversion respects port direction when inlining bindings

parent c168ec47
......@@ -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"
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