diff --git a/macros/src/main/scala/CostMetric.scala b/macros/src/main/scala/CostMetric.scala index afcb2660..68aafaa5 100644 --- a/macros/src/main/scala/CostMetric.scala +++ b/macros/src/main/scala/CostMetric.scala @@ -117,8 +117,9 @@ object DefaultMetric extends CostMetric with CostMetricCompanion { val memMask = mem.src.ports map (_.maskGran) find (_.isDefined) map (_.get) val libMask = lib.src.ports map (_.maskGran) find (_.isDefined) map (_.get) val memWidth = (memMask, libMask) match { - case (Some(1), Some(1)) | (None, _) => mem.src.width - case (Some(p), _) => p // assume that the memory consists of smaller chunks + case (None, _) => mem.src.width + case (Some(p), Some(q)) if p % q == 0 => mem.src.width + case (Some(p), _) => (mem.src.width / p) * lib.src.width // assume that the memory consists of smaller chunks } return Some( (((mem.src.depth - 1) / lib.src.depth) + 1) * diff --git a/macros/src/main/scala/MacroCompiler.scala b/macros/src/main/scala/MacroCompiler.scala index ad38d344..2c33b19b 100644 --- a/macros/src/main/scala/MacroCompiler.scala +++ b/macros/src/main/scala/MacroCompiler.scala @@ -298,6 +298,9 @@ class MacroCompilerPass(mems: Option[Seq[Macro]], val name = s"mem_${i}_${j}" // Create the instance. stmts += WDefInstance(NoInfo, name, lib.src.name, lib.tpe) + stmts ++= lib.sortedPorts flatMap (_.ports collect { + case Port(_, pname, Input, _) => IsInvalid(NoInfo, WSubField(WRef(name), pname)) + }) // Connect extra ports of the lib. stmts ++= lib.extraPorts map { case (portName, portValue) => Connect(NoInfo, WSubField(WRef(name), portName), portValue) @@ -418,7 +421,7 @@ class MacroCompilerPass(mems: Option[Seq[Macro]], // zero out the upper bits. zero } else { - if (i >= memPort.src.width.get) { + if ((low + i) >= memPort.src.width.get) { // If our bit is larger than the whole width of the mem, just zero out the upper bits. zero } else { @@ -467,6 +470,7 @@ class MacroCompilerPass(mems: Option[Seq[Macro]], /* Palmer: It's safe to ignore read enables, but we pass them through * to the vendor memory if there's a port on there that * implements the read enables. */ + /* Donggyu: this is broken as read enables should be piped (memPort.src.readEnable, libPort.src.readEnable) match { case (_, None) => case (Some(PolarizedPort(mem, _)), Some(PolarizedPort(lib, lib_polarity))) => @@ -474,6 +478,13 @@ class MacroCompilerPass(mems: Option[Seq[Macro]], case (None, Some(PolarizedPort(lib, lib_polarity))) => stmts += connectPorts(andAddrMatch(not(memWriteEnable)), lib, lib_polarity) } + */ + // Donggyu: thus, just connect 1 to read enables for now + libPort.src.readEnable match { + case None => + case Some(PolarizedPort(lib, lib_polarity)) => + stmts += connectPorts(one, lib, lib_polarity) + } /* Palmer: This is actually the memory compiler: it figures out how to * implement the outer memory's collection of ports using what @@ -509,6 +520,14 @@ class MacroCompilerPass(mems: Option[Seq[Macro]], case (None, None, None) => // No write ports to match up (this may be a read-only port). // This isn't necessarily an error condition. + case (None, None, Some(PolarizedPort(en, en_polarity))) => + // Correctly connect read-only port's chip enable + stmts += (memPort.src.readEnable match { + case None => + connectPorts(addrMatch, en, en_polarity) + case Some(PolarizedPort(mem, _)) => + connectPorts(andAddrMatch(WRef(mem)), en, en_polarity) + }) } } // Cat macro outputs for selection @@ -707,7 +726,7 @@ object MacroCompiler extends App { // Note: the last macro in the input list is (seemingly arbitrarily) // determined as the firrtl "top-level module". val circuit = Circuit(NoInfo, macros, macros.last.name) - val annotations = AnnotationMap( + val annotations = Seq(MacroCompilerAnnotation( circuit.main, MacroCompilerAnnotation.Params( @@ -717,8 +736,7 @@ object MacroCompiler extends App { params.contains(UseCompiler) ) )) - ) - val state = CircuitState(circuit, HighForm, Some(annotations)) + val state = CircuitState(circuit, HighForm, annotations) // Run the compiler. val result = new MacroCompiler().compileAndEmit(state) diff --git a/macros/src/main/scala/SynFlops.scala b/macros/src/main/scala/SynFlops.scala index 48ee368c..a55c0980 100644 --- a/macros/src/main/scala/SynFlops.scala +++ b/macros/src/main/scala/SynFlops.scala @@ -32,9 +32,9 @@ class SynFlopsPass(synflops: Boolean, libs: Seq[Macro]) extends firrtl.passes.Pa lib.src.depth, 1, // writeLatency 1, // readLatency. This is possible because of VerilogMemDelays - lib.readers.indices map (i => s"R_$i"), - lib.writers.indices map (i => s"W_$i"), - lib.readwriters.indices map (i => s"RW_$i") + lib.readers.indices map (i => s"R$i"), + lib.writers.indices map (i => s"W$i"), + lib.readwriters.indices map (i => s"RW$i") ) val readConnects = lib.readers.zipWithIndex flatMap { case (r, i) => @@ -48,16 +48,16 @@ class SynFlopsPass(synflops: Boolean, libs: Seq[Macro]) extends firrtl.passes.Pa case (None, Some(re_port)) => portToExpression(re_port) case (None, None) => one } - val data = memPortField(mem, s"R_$i", "data") + val data = memPortField(mem, s"R$i", "data") val read = (dataType: @unchecked) match { case VectorType(tpe, size) => cat(((0 until size) map (k => WSubIndex(data, k, tpe, UNKNOWNGENDER))).reverse) case _: UIntType => data } Seq( - Connect(NoInfo, memPortField(mem, s"R_$i", "clk"), clock), - Connect(NoInfo, memPortField(mem, s"R_$i", "addr"), address), - Connect(NoInfo, memPortField(mem, s"R_$i", "en"), enable), + Connect(NoInfo, memPortField(mem, s"R$i", "clk"), clock), + Connect(NoInfo, memPortField(mem, s"R$i", "addr"), address), + Connect(NoInfo, memPortField(mem, s"R$i", "en"), enable), Connect(NoInfo, WRef(r.src.output.get.name), read) ) } @@ -73,13 +73,13 @@ class SynFlopsPass(synflops: Boolean, libs: Seq[Macro]) extends firrtl.passes.Pa case (None, Some(we)) => portToExpression(we) case (None, None) => zero // is it possible? } - val mask = memPortField(mem, s"W_$i", "mask") - val data = memPortField(mem, s"W_$i", "data") + val mask = memPortField(mem, s"W$i", "mask") + val data = memPortField(mem, s"W$i", "data") val write = portToExpression(w.src.input.get) Seq( - Connect(NoInfo, memPortField(mem, s"W_$i", "clk"), clock), - Connect(NoInfo, memPortField(mem, s"W_$i", "addr"), address), - Connect(NoInfo, memPortField(mem, s"W_$i", "en"), enable) + Connect(NoInfo, memPortField(mem, s"W$i", "clk"), clock), + Connect(NoInfo, memPortField(mem, s"W$i", "addr"), address), + Connect(NoInfo, memPortField(mem, s"W$i", "en"), enable) ) ++ (dataType match { case VectorType(tpe, size) => val width = bitWidth(tpe).toInt @@ -108,9 +108,9 @@ class SynFlopsPass(synflops: Boolean, libs: Seq[Macro]) extends firrtl.passes.Pa case (None, Some(re)) => or(portToExpression(re), wmode) case (None, None) => one } - val wmask = memPortField(mem, s"RW_$i", "wmask") - val wdata = memPortField(mem, s"RW_$i", "wdata") - val rdata = memPortField(mem, s"RW_$i", "rdata") + val wmask = memPortField(mem, s"RW$i", "wmask") + val wdata = memPortField(mem, s"RW$i", "wdata") + val rdata = memPortField(mem, s"RW$i", "rdata") val write = portToExpression(rw.src.input.get) val read = (dataType: @unchecked) match { case VectorType(tpe, size) => cat(((0 until size) map (k => @@ -118,10 +118,10 @@ class SynFlopsPass(synflops: Boolean, libs: Seq[Macro]) extends firrtl.passes.Pa case _: UIntType => rdata } Seq( - Connect(NoInfo, memPortField(mem, s"RW_$i", "clk"), clock), - Connect(NoInfo, memPortField(mem, s"RW_$i", "addr"), address), - Connect(NoInfo, memPortField(mem, s"RW_$i", "en"), enable), - Connect(NoInfo, memPortField(mem, s"RW_$i", "wmode"), wmode), + Connect(NoInfo, memPortField(mem, s"RW$i", "clk"), clock), + Connect(NoInfo, memPortField(mem, s"RW$i", "addr"), address), + Connect(NoInfo, memPortField(mem, s"RW$i", "en"), enable), + Connect(NoInfo, memPortField(mem, s"RW$i", "wmode"), wmode), Connect(NoInfo, WRef(rw.src.output.get.name), read) ) ++ (dataType match { case VectorType(tpe, size) =>