Merge pull request #133 from ucb-bar/fixes

Fixes for IOCell + MacroCompiler
This commit is contained in:
Jerry Zhao
2023-07-31 14:12:55 -07:00
committed by GitHub
3 changed files with 83 additions and 60 deletions

View File

@@ -1,46 +0,0 @@
// See LICENSE for license details
`timescale 1ns/1ps
module GenericAnalogIOCell(
inout pad,
inout core
);
assign core = 1'bz;
assign pad = core;
endmodule
module GenericDigitalGPIOCell(
inout pad,
output i,
input ie,
input o,
input oe
);
assign pad = oe ? o : 1'bz;
assign i = ie ? pad : 1'b0;
endmodule
module GenericDigitalInIOCell(
input pad,
output i,
input ie
);
assign i = ie ? pad : 1'b0;
endmodule
module GenericDigitalOutIOCell(
output pad,
input o,
input oe
);
assign pad = oe ? o : 1'bz;
endmodule

View File

@@ -3,7 +3,7 @@
package barstools.iocell.chisel package barstools.iocell.chisel
import chisel3._ import chisel3._
import chisel3.util.{Cat, HasBlackBoxResource} import chisel3.util.{Cat, HasBlackBoxResource, HasBlackBoxInline}
import chisel3.experimental.{Analog, BaseModule, DataMirror, IO} import chisel3.experimental.{Analog, BaseModule, DataMirror, IO}
// The following four IO cell bundle types are bare-minimum functional connections // The following four IO cell bundle types are bare-minimum functional connections
@@ -93,21 +93,73 @@ trait DigitalOutIOCell extends IOCell {
// implementation of an IO cell. For building a real chip, it is important to implement // implementation of an IO cell. For building a real chip, it is important to implement
// and use similar classes which wrap the foundry-specific IO cells. // and use similar classes which wrap the foundry-specific IO cells.
abstract class GenericIOCell extends BlackBox with HasBlackBoxResource { abstract class GenericIOCell extends BlackBox with HasBlackBoxInline {
addResource("/barstools/iocell/vsrc/IOCell.v") val impl: String
val moduleName = this.getClass.getSimpleName
setInline(s"$moduleName.v", impl);
} }
class GenericAnalogIOCell extends GenericIOCell with AnalogIOCell { class GenericAnalogIOCell extends GenericIOCell with AnalogIOCell {
val io = IO(new AnalogIOCellBundle) val io = IO(new AnalogIOCellBundle)
lazy val impl = s"""
`timescale 1ns/1ps
module GenericAnalogIOCell(
inout pad,
inout core
);
assign core = 1'bz;
assign pad = core;
endmodule"""
} }
class GenericDigitalGPIOCell extends GenericIOCell with DigitalGPIOCell { class GenericDigitalGPIOCell extends GenericIOCell with DigitalGPIOCell {
val io = IO(new DigitalGPIOCellBundle) val io = IO(new DigitalGPIOCellBundle)
lazy val impl = s"""
`timescale 1ns/1ps
module GenericDigitalGPIOCell(
inout pad,
output i,
input ie,
input o,
input oe
);
assign pad = oe ? o : 1'bz;
assign i = ie ? pad : 1'b0;
endmodule"""
} }
class GenericDigitalInIOCell extends GenericIOCell with DigitalInIOCell { class GenericDigitalInIOCell extends GenericIOCell with DigitalInIOCell {
val io = IO(new DigitalInIOCellBundle) val io = IO(new DigitalInIOCellBundle)
lazy val impl = s"""
`timescale 1ns/1ps
module GenericDigitalInIOCell(
input pad,
output i,
input ie
);
assign i = ie ? pad : 1'b0;
endmodule"""
} }
class GenericDigitalOutIOCell extends GenericIOCell with DigitalOutIOCell { class GenericDigitalOutIOCell extends GenericIOCell with DigitalOutIOCell {
val io = IO(new DigitalOutIOCellBundle) val io = IO(new DigitalOutIOCellBundle)
lazy val impl = s"""
`timescale 1ns/1ps
module GenericDigitalOutIOCell(
output pad,
input o,
input oe
);
assign pad = oe ? o : 1'bz;
endmodule"""
} }
trait IOCellTypeParams { trait IOCellTypeParams {

View File

@@ -14,7 +14,6 @@ import firrtl.ir._
import firrtl.options.Dependency import firrtl.options.Dependency
import firrtl.stage.TransformManager.TransformDependency import firrtl.stage.TransformManager.TransformDependency
import firrtl.stage.{FirrtlSourceAnnotation, FirrtlStage, Forms, OutputFileAnnotation, RunFirrtlTransformAnnotation} import firrtl.stage.{FirrtlSourceAnnotation, FirrtlStage, Forms, OutputFileAnnotation, RunFirrtlTransformAnnotation}
import firrtl.transforms.NoDCEAnnotation
import firrtl.{PrimOps, _} import firrtl.{PrimOps, _}
import mdf.macrolib.{PolarizedPort, PortPolarity, SRAMCompiler, SRAMGroup, SRAMMacro} import mdf.macrolib.{PolarizedPort, PortPolarity, SRAMCompiler, SRAMGroup, SRAMMacro}
@@ -898,16 +897,34 @@ object MacroCompiler extends App {
val macroCompiled = (new MacroCompilerTransform).execute(macroCompilerInput) val macroCompiled = (new MacroCompilerTransform).execute(macroCompilerInput)
// Run FIRRTL compiler // Run FIRRTL compiler
(new FirrtlStage).execute( // For each generated module, have to create a new circuit with that module
Array.empty, // as top, and all other modules as ExtModules. This guarantees all modules
Seq( // are elaborated
OutputFileAnnotation(params.getOrElse(Verilog, "")), val verilog = macroCompiled.circuit.modules
RunFirrtlTransformAnnotation(new VerilogEmitter), .map(_.name)
EmitCircuitAnnotation(classOf[VerilogEmitter]), .map { macroName =>
NoDCEAnnotation, val (mainMod, otherMods) = macroCompiled.circuit.modules.partition(_.name == macroName)
FirrtlSourceAnnotation(macroCompiled.circuit.serialize) val extMods = otherMods.map(m => ExtModule(NoInfo, m.name, m.ports, m.name, Nil))
)
) val circuit = Circuit(NoInfo, mainMod ++ extMods, macroName)
(new FirrtlStage)
.execute(
Array.empty,
Seq(
RunFirrtlTransformAnnotation(new VerilogEmitter),
EmitCircuitAnnotation(classOf[VerilogEmitter]),
FirrtlSourceAnnotation(circuit.serialize)
)
)
.collect { case c: EmittedVerilogCircuitAnnotation => c }
.head
.value
.value
}
.mkString("\n")
val verilogWriter = new FileWriter(new File(params.get(Verilog).get))
verilogWriter.write(verilog)
verilogWriter.close()
params.get(HammerIR) match { params.get(HammerIR) match {
case Some(hammerIRFile: String) => case Some(hammerIRFile: String) =>