Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add initial support for coreir-verilog instance params #463

Merged
merged 5 commits into from
Oct 23, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
12 changes: 6 additions & 6 deletions docs/FAQ.md
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ class Top(m.Circuit):
io.O <= m.join([ff0, ff1])(d=io.I, rst=io.ASYNCRESET)


m.compile("top", Top, output="verilog")
m.compile("top", Top, output="coreir-verilog")
```

This produces the following Verilog, notice how the arguments to the magma
Expand All @@ -62,11 +62,11 @@ end

assign q = ff;
endmodule
module Top (input [1:0] I, output [1:0] O, input CLK, input ASYNCRESET);
wire FF_inst0_q;
wire FF_inst1_q;
FF #(.init(0)) FF_inst0 (.clk(CLK), .rst(ASYNCRESET), .d(I[0]), .q(FF_inst0_q));
FF #(.init(1)) FF_inst1 (.clk(CLK), .rst(ASYNCRESET), .d(I[1]), .q(FF_inst1_q));
module Top (input ASYNCRESET, input CLK, input [1:0] I, output [1:0] O);
wire FF_inst0_q;
wire FF_inst1_q;
FF #(.init(0)) FF_inst0(.clk(CLK), .d(I[0]), .q(FF_inst0_q), .rst(ASYNCRESET));
FF #(.init(1)) FF_inst1(.clk(CLK), .d(I[1]), .q(FF_inst1_q), .rst(ASYNCRESET));
assign O = {FF_inst1_q,FF_inst0_q};
endmodule

Expand Down
35 changes: 32 additions & 3 deletions magma/backend/coreir_.py
Original file line number Diff line number Diff line change
Expand Up @@ -254,8 +254,14 @@ def compile_declaration(self, declaration):
if isinstance(declaration.interface, InterfaceKind):
module_type = self.context.Flip(module_type)

coreir_module = self.context.global_namespace.new_module(declaration.coreir_name,
module_type)
kwargs = {}
if hasattr(declaration, "coreir_config_param_types"):
kwargs["cparams"] = \
self.make_cparams(declaration.coreir_config_param_types)

coreir_module = \
self.context.global_namespace.new_module(declaration.coreir_name,
module_type, **kwargs)
if get_codegen_debug_info() and declaration.debug_info:
coreir_module.add_metadata("filename", json.dumps(make_relative(declaration.debug_info.filename)))
coreir_module.add_metadata("lineno", json.dumps(str(declaration.debug_info.lineno)))
Expand Down Expand Up @@ -299,14 +305,37 @@ def connect_non_outputs(self, module_definition, port,
self.connect(module_definition, port, port.value(),
non_input_ports)

def make_cparams(self, param_types):
cparams = {}
for param, type_ in param_types.items():
if type_ is int:
type_ = self.context.Int()
elif type_ is bool:
type_ = self.context.Bool()
elif type_ is str:
type_ = self.context.String()
elif type_ is BitVector:
type_ = self.context.BitVector()
else:
raise NotImplementedError(type_)
cparams[param] = type_
return self.context.newParams(cparams)

def compile_definition(self, definition):
logger.debug(f"Compiling definition {definition}")
if definition.name in self.modules:
logger.debug(f" {definition} already compiled, skipping")
return self.modules[definition.name]
self.check_interface(definition)
module_type = self.convert_interface_to_module_type(definition.interface)
coreir_module = self.context.global_namespace.new_module(definition.coreir_name, module_type)
kwargs = {}
if hasattr(definition, "coreir_config_param_types"):
kwargs["cparams"] = \
self.make_cparams(definition.coreir_config_param_types)

coreir_module = \
self.context.global_namespace.new_module(definition.coreir_name,
module_type, **kwargs)
if get_codegen_debug_info() and definition.debug_info:
coreir_module.add_metadata("filename", json.dumps(make_relative(definition.debug_info.filename)))
coreir_module.add_metadata("lineno", json.dumps(str(definition.debug_info.lineno)))
Expand Down
29 changes: 18 additions & 11 deletions magma/fromverilog.py
Original file line number Diff line number Diff line change
Expand Up @@ -164,7 +164,7 @@ def ParseVerilogModule(node, type_map):


def FromVerilog(source, func, type_map, target_modules=None, shallow=False,
external_modules={}):
external_modules={}, param_map={}):
parser = VerilogParser()
ast = parser.parse(source)
visitor = ModuleVisitor(shallow)
Expand All @@ -187,6 +187,7 @@ def _get_lines(start_line, end_line):
parsed_name, args = ParseVerilogModule(verilog_defn, type_map)
assert parsed_name == name
magma_defn = func(name, *args)
magma_defn.coreir_config_param_types = param_map
if func == DefineCircuit:
# Attach relevant lines of verilog source.
magma_defn.verilogFile = _get_lines(
Expand All @@ -210,11 +211,13 @@ def _get_lines(start_line, end_line):
# Filter modules based on target_modules list.
return [v for k, v in magma_defns.items() if k in target_modules]

def FromVerilogFile(file, func, type_map, target_modules=None, shallow=False, external_modules={}):
def FromVerilogFile(file, func, type_map, target_modules=None, shallow=False,
external_modules={}, param_map={}):
if file is None:
return None
verilog = open(file).read()
result = FromVerilog(verilog, func, type_map, target_modules, shallow, external_modules)
result = FromVerilog(verilog, func, type_map, target_modules, shallow,
external_modules, param_map=param_map)
# Store the original verilog file name, currently used by m.compile to
# generate a .sv when compiling a circuit that was defined from a verilog
# file
Expand All @@ -233,11 +236,11 @@ def FromTemplatedVerilogFile(file, func, type_map, **kwargs):
return FromTemplatedVerilog(templatedverilog, func, type_map, **kwargs)


def DeclareFromVerilog(source, type_map={}):
return FromVerilog(source, DeclareCircuit, type_map)
def DeclareFromVerilog(source, type_map={}, param_map={}):
return FromVerilog(source, DeclareCircuit, type_map, param_map=param_map)

def DeclareFromVerilogFile(file, target_modules=None, type_map={}):
return FromVerilogFile(file, DeclareCircuit, type_map, target_modules)
def DeclareFromVerilogFile(file, target_modules=None, type_map={}, param_map={}):
return FromVerilogFile(file, DeclareCircuit, type_map, target_modules, param_map=param_map)

def DeclareFromTemplatedVerilog(source, type_map={}, **kwargs):
return FromTemplatedVerilog(source, DeclareCircuit, type_map, **kwargs)
Expand All @@ -246,13 +249,17 @@ def DeclareFromTemplatedVerilogFile(file, type_map={}, **kwargs):
return FromTemplatedVerilogFile(file, DeclareCircuit, type_map, **kwargs)


def DefineFromVerilog(source, type_map={}, target_modules=None, shallow=False, external_modules={}):
def DefineFromVerilog(source, type_map={}, target_modules=None, shallow=False,
external_modules={}, param_map={}):
return FromVerilog(source, DefineCircuit, type_map, target_modules,
shallow=shallow, external_modules=external_modules)
shallow=shallow, external_modules=external_modules,
param_map=param_map)

def DefineFromVerilogFile(file, target_modules=None, type_map={}, shallow=False, external_modules={}):
def DefineFromVerilogFile(file, target_modules=None, type_map={},
shallow=False, external_modules={}, param_map={}):
return FromVerilogFile(file, DefineCircuit, type_map, target_modules,
shallow=shallow, external_modules=external_modules)
shallow=shallow, external_modules=external_modules,
param_map=param_map)

def DefineFromTemplatedVerilog(source, type_map={}, **kwargs):
return FromTemplatedVerilog(source, DefineCircuit, type_map, **kwargs)
Expand Down
15 changes: 15 additions & 0 deletions tests/test_verilog/ff.v
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
// ff.v
module FF(input clk, input rst, input d, output q);

parameter init = 0;

reg ff;
always @(posedge clk or posedge rst) begin
if (!rst)
ff <= init;
else
ff <= d;
end

assign q = ff;
endmodule
22 changes: 22 additions & 0 deletions tests/test_verilog/gold/top-coreir-verilog.v
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
module FF(input clk, input rst, input d, output q);

parameter init = 0;

reg ff;
always @(posedge clk or posedge rst) begin
if (!rst)
ff <= init;
else
ff <= d;
end

assign q = ff;
endmodule
module Top (input ASYNCRESET, input CLK, input [1:0] I, output [1:0] O);
wire FF_inst0_q;
wire FF_inst1_q;
FF #(.init(0)) FF_inst0(.clk(CLK), .d(I[0]), .q(FF_inst0_q), .rst(ASYNCRESET));
FF #(.init(1)) FF_inst1(.clk(CLK), .d(I[1]), .q(FF_inst1_q), .rst(ASYNCRESET));
assign O = {FF_inst1_q,FF_inst0_q};
endmodule

46 changes: 46 additions & 0 deletions tests/test_verilog/gold/top-coreir.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
{"top":"global.Top",
"namespaces":{
"global":{
"modules":{
"FF":{
"type":["Record",[
["clk",["Named","coreir.clkIn"]],
["rst",["Named","coreir.arstIn"]],
["d","BitIn"],
["q","Bit"]
]],
"modparams":{"init":"Int"},
"metadata":{"verilog":{"verilog_string":"module FF(input clk, input rst, input d, output q);\n\nparameter init = 0;\n\nreg ff; \nalways @(posedge clk or posedge rst) begin\n if (!rst)\n ff <= init;\n else\n ff <= d; \nend\n\nassign q = ff;\nendmodule"}}
},
"Top":{
"type":["Record",[
["I",["Array",2,"BitIn"]],
["O",["Array",2,"Bit"]],
["CLK",["Named","coreir.clkIn"]],
["ASYNCRESET",["Named","coreir.arstIn"]]
]],
"instances":{
"FF_inst0":{
"modref":"global.FF",
"modargs":{"init":["Int",0]}
},
"FF_inst1":{
"modref":"global.FF",
"modargs":{"init":["Int",1]}
}
},
"connections":[
["self.CLK","FF_inst0.clk"],
["self.I.0","FF_inst0.d"],
["self.O.0","FF_inst0.q"],
["self.ASYNCRESET","FF_inst0.rst"],
["self.CLK","FF_inst1.clk"],
["self.I.1","FF_inst1.d"],
["self.O.1","FF_inst1.q"],
["self.ASYNCRESET","FF_inst1.rst"]
]
}
}
}
}
}
9 changes: 9 additions & 0 deletions tests/test_verilog/gold/top-declare-coreir-verilog.v
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
// Module `FF` defined externally
module Top (input ASYNCRESET, input CLK, input [1:0] I, output [1:0] O);
wire FF_inst0_q;
wire FF_inst1_q;
FF #(.init(0)) FF_inst0(.clk(CLK), .d(I[0]), .q(FF_inst0_q), .rst(ASYNCRESET));
FF #(.init(1)) FF_inst1(.clk(CLK), .d(I[1]), .q(FF_inst1_q), .rst(ASYNCRESET));
assign O = {FF_inst1_q,FF_inst0_q};
endmodule

45 changes: 45 additions & 0 deletions tests/test_verilog/gold/top-declare-coreir.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
{"top":"global.Top",
"namespaces":{
"global":{
"modules":{
"FF":{
"type":["Record",[
["clk",["Named","coreir.clkIn"]],
["rst",["Named","coreir.arstIn"]],
["d","BitIn"],
["q","Bit"]
]],
"modparams":{"init":"Int"}
},
"Top":{
"type":["Record",[
["I",["Array",2,"BitIn"]],
["O",["Array",2,"Bit"]],
["CLK",["Named","coreir.clkIn"]],
["ASYNCRESET",["Named","coreir.arstIn"]]
]],
"instances":{
"FF_inst0":{
"modref":"global.FF",
"modargs":{"init":["Int",0]}
},
"FF_inst1":{
"modref":"global.FF",
"modargs":{"init":["Int",1]}
}
},
"connections":[
["self.CLK","FF_inst0.clk"],
["self.I.0","FF_inst0.d"],
["self.O.0","FF_inst0.q"],
["self.ASYNCRESET","FF_inst0.rst"],
["self.CLK","FF_inst1.clk"],
["self.I.1","FF_inst1.d"],
["self.O.1","FF_inst1.q"],
["self.ASYNCRESET","FF_inst1.rst"]
]
}
}
}
}
}
8 changes: 8 additions & 0 deletions tests/test_verilog/gold/top-declare-verilog.v
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
module Top (input [1:0] I, output [1:0] O, input CLK, input ASYNCRESET);
wire FF_inst0_q;
wire FF_inst1_q;
FF #(.init(0)) FF_inst0 (.clk(CLK), .rst(ASYNCRESET), .d(I[0]), .q(FF_inst0_q));
FF #(.init(1)) FF_inst1 (.clk(CLK), .rst(ASYNCRESET), .d(I[1]), .q(FF_inst1_q));
assign O = {FF_inst1_q,FF_inst0_q};
endmodule

46 changes: 46 additions & 0 deletions tests/test_verilog/gold/top-define-coreir-verilog.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
{"top":"global.Top",
"namespaces":{
"global":{
"modules":{
"FF":{
"type":["Record",[
["clk",["Named","coreir.clkIn"]],
["rst",["Named","coreir.arstIn"]],
["d","BitIn"],
["q","Bit"]
]],
"modparams":{"init":"Int"},
"metadata":{"verilog":{"verilog_string":"module FF(input clk, input rst, input d, output q);\n\nparameter init = 0;\n\nreg ff; \nalways @(posedge clk or posedge rst) begin\n if (!rst)\n ff <= init;\n else\n ff <= d; \nend\n\nassign q = ff;\nendmodule"}}
},
"Top":{
"type":["Record",[
["I",["Array",2,"BitIn"]],
["O",["Array",2,"Bit"]],
["CLK",["Named","coreir.clkIn"]],
["ASYNCRESET",["Named","coreir.arstIn"]]
]],
"instances":{
"FF_inst0":{
"modref":"global.FF",
"modargs":{"init":["Int",0]}
},
"FF_inst1":{
"modref":"global.FF",
"modargs":{"init":["Int",1]}
}
},
"connections":[
["self.CLK","FF_inst0.clk"],
["self.I.0","FF_inst0.d"],
["self.O.0","FF_inst0.q"],
["self.ASYNCRESET","FF_inst0.rst"],
["self.CLK","FF_inst1.clk"],
["self.I.1","FF_inst1.d"],
["self.O.1","FF_inst1.q"],
["self.ASYNCRESET","FF_inst1.rst"]
]
}
}
}
}
}
22 changes: 22 additions & 0 deletions tests/test_verilog/gold/top-define-coreir-verilog.v
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
module FF(input clk, input rst, input d, output q);

parameter init = 0;

reg ff;
always @(posedge clk or posedge rst) begin
if (!rst)
ff <= init;
else
ff <= d;
end

assign q = ff;
endmodule
module Top (input ASYNCRESET, input CLK, input [1:0] I, output [1:0] O);
wire FF_inst0_q;
wire FF_inst1_q;
FF #(.init(0)) FF_inst0(.clk(CLK), .d(I[0]), .q(FF_inst0_q), .rst(ASYNCRESET));
FF #(.init(1)) FF_inst1(.clk(CLK), .d(I[1]), .q(FF_inst1_q), .rst(ASYNCRESET));
assign O = {FF_inst1_q,FF_inst0_q};
endmodule