diff options
| author | Andrew Waterman | 2018-07-03 15:45:00 -0700 |
|---|---|---|
| committer | Jack Koenig | 2018-07-03 15:45:00 -0700 |
| commit | ceac36d7ce1223078ca47bc097884532faacd7e1 (patch) | |
| tree | 275334042d0a41d362108404ec89e18a357d4104 /src/test/scala/firrtlTests/InferReadWriteSpec.scala | |
| parent | 2b405652a266114377816b8175ef9fad7d36ed14 (diff) | |
Improve code generation for smem wmode and [w]mask ports (#834)
[skip formal checks] LEC passes with Formality
* Improve code generation for smem RW-port wmode port
A common case for these port-enables is
wen = valid & write
ren = valid & !write
which the RW-port transform currently turns into
en = (valid & write) | (valid & !write)
wmode = valid & write
because it proved `wen` and `ren` are mutually exclusive via `write`.
Synthesis tools can trivially optimize `en` to `valid`, so that's not a
problem, but the wmode field can't be optimized if going into a black box.
This PR instead sets `wmode` to whatever node was used to prove
mutual exclusion, which is always a simpler expression. In this case:
en = (valid & write) | (valid & !write)
wmode = write
* In RemoveCHIRRTL, infer mask relative to port definition
Previously, it was inferred relative to the memory definition causing
the mask condition to be redundantly conjoined with the enable signal.
Also enable ReplSeqMems to ignore all ValidIfs (not just on Clocks) to
improve QoR.
Diffstat (limited to 'src/test/scala/firrtlTests/InferReadWriteSpec.scala')
| -rw-r--r-- | src/test/scala/firrtlTests/InferReadWriteSpec.scala | 34 |
1 files changed, 34 insertions, 0 deletions
diff --git a/src/test/scala/firrtlTests/InferReadWriteSpec.scala b/src/test/scala/firrtlTests/InferReadWriteSpec.scala index 34e228be..bffb1b51 100644 --- a/src/test/scala/firrtlTests/InferReadWriteSpec.scala +++ b/src/test/scala/firrtlTests/InferReadWriteSpec.scala @@ -7,6 +7,7 @@ import firrtl.ir._ import firrtl.passes._ import firrtl.Mappers._ import annotations._ +import FirrtlCheckers._ class InferReadWriteSpec extends SimpleTransformSpec { class InferReadWriteCheckException extends PassException( @@ -138,4 +139,37 @@ circuit sram6t : compileAndEmit(CircuitState(parse(input), ChirrtlForm, annos)) } } + + "wmode" should "be simplified" in { + val input = """ +circuit sram6t : + module sram6t : + input clock : Clock + input reset : UInt<1> + output io : { flip addr : UInt<11>, flip valid : UInt<1>, flip write : UInt<1>, flip dataIn : UInt<32>, dataOut : UInt<32>} + + io is invalid + smem mem : UInt<32> [2048] + node wen = and(io.valid, io.write) + node ren = and(io.valid, not(io.write)) + when wen : + write mport _T_14 = mem[io.addr], clock + _T_14 <= io.dataIn + node _T_16 = eq(wen, UInt<1>("h0")) + when _T_16 : + wire _T_18 : UInt + _T_18 is invalid + when ren : + _T_18 <= io.addr + node _T_20 = or(_T_18, UInt<11>("h0")) + node _T_21 = bits(_T_20, 10, 0) + read mport _T_22 = mem[_T_21], clock + io.dataOut <= _T_22 +""".stripMargin + + val annos = Seq(memlib.InferReadWriteAnnotation) + val res = compileAndEmit(CircuitState(parse(input), ChirrtlForm, annos)) + // Check correctness of firrtl + res should containLine (s"mem.rw.wmode <= wen") + } } |
