From a90cf1105467cab7c6708ea3faae35e1454cb0fd Mon Sep 17 00:00:00 2001 From: Albert Magyar Date: Tue, 9 Mar 2021 21:30:53 -0800 Subject: Allow direct emission of sync-read memories to Verilog * Emit readwrite ports, if applicable * Does not change VerilogMemDelays -> no effect on default flow * Use more single-line declare-and-assign statements for mem wires * Update error messages for too-complex memories in VerilogEmitter * Run scalafmt on VerilogEmitter --- src/test/scala/firrtlTests/InfoSpec.scala | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'src/test') diff --git a/src/test/scala/firrtlTests/InfoSpec.scala b/src/test/scala/firrtlTests/InfoSpec.scala index 43fb6ee1..db4828f6 100644 --- a/src/test/scala/firrtlTests/InfoSpec.scala +++ b/src/test/scala/firrtlTests/InfoSpec.scala @@ -91,11 +91,11 @@ class InfoSpec extends FirrtlFlatSpec with FirrtlMatchers { result should containTree { case DefMemory(Info1, "m", _, _, _, _, _, _, _, _) => true } result should containLine(s"reg [7:0] m [0:31]; //$Info1") result should containLine(s"wire [7:0] m_r_data; //$Info1") - result should containLine(s"wire [4:0] m_r_addr; //$Info1") - result should containLine(s"wire [7:0] m_w_data; //$Info1") - result should containLine(s"wire [4:0] m_w_addr; //$Info1") - result should containLine(s"wire m_w_mask; //$Info1") - result should containLine(s"wire m_w_en; //$Info1") + result should containLine(s"wire [4:0] m_r_addr = addr; //$Info1") + result should containLine(s"wire [7:0] m_w_data = 8'h0; //$Info1") + result should containLine(s"wire [4:0] m_w_addr = addr; //$Info1") + result should containLine(s"wire m_w_mask = 1'h0; //$Info1") + result should containLine(s"wire m_w_en = 1'h0; //$Info1") result should containLine(s"assign m_r_data = m[m_r_addr]; //$Info1") result should containLine(s"m[m_w_addr] <= m_w_data; //$Info1") } -- cgit v1.2.3 From 47cc4a8c57a7d50c9914ceeadbcd19f71f179187 Mon Sep 17 00:00:00 2001 From: Albert Magyar Date: Mon, 1 Mar 2021 09:46:25 -0800 Subject: Add tests for same-address readwrite inference * Update test to include both 'old' and 'new' read-under-write values --- .../scala/firrtlTests/InferReadWriteSpec.scala | 51 ++++++++++++++++++++++ 1 file changed, 51 insertions(+) (limited to 'src/test') diff --git a/src/test/scala/firrtlTests/InferReadWriteSpec.scala b/src/test/scala/firrtlTests/InferReadWriteSpec.scala index 1fb24297..62969df5 100644 --- a/src/test/scala/firrtlTests/InferReadWriteSpec.scala +++ b/src/test/scala/firrtlTests/InferReadWriteSpec.scala @@ -177,4 +177,55 @@ circuit sram6t : // Check correctness of firrtl res should containLine(s"mem.rw.wmode <= wen") } + + def sameAddr(ruw: String): String = { + s""" + |circuit sram6t : + | module sram6t : + | input clock : Clock + | output io : { flip addr : UInt<11>, flip valid : UInt<1>, flip write : UInt<1>, flip dataIn : UInt<32>, dataOut : UInt<32>} + | + | mem mem: + | data-type => UInt<4> + | depth => 64 + | reader => r + | writer => w + | read-latency => 1 + | write-latency => 1 + | read-under-write => ${ruw} + | + | mem.r.clk <= clock + | mem.r.addr <= io.addr + | mem.r.en <= io.valid + | io.dataOut <= mem.r.data + | + | node wen = and(io.valid, io.write) + | mem.w.clk <= clock + | mem.w.addr <= io.addr + | mem.w.en <= wen + | mem.w.mask <= UInt(1) + | mem.w.data <= io.dataIn""".stripMargin + } + + "Infer ReadWrite Ports" should "infer readwrite ports from shared addresses with undefined readUnderWrite" in { + val input = sameAddr("undefined") + val annos = Seq(memlib.InferReadWriteAnnotation) + val res = compileAndEmit(CircuitState(parse(input), HighForm, annos)) + // Check correctness of firrtl + res should containLine(s"mem.rw.wmode <= wen") + } + + Seq("old", "new").foreach { ruw => + "Infer ReadWrite Ports" should s"not infer readwrite ports from shared addresses with '${ruw}' readUnderWrite" in { + val input = sameAddr(ruw) + val annos = Seq(memlib.InferReadWriteAnnotation) + intercept[Exception] { + compileAndEmit(CircuitState(parse(input), ChirrtlForm, annos)) + } match { + case CustomTransformException(_: InferReadWriteCheckException) => // success + case _ => fail() + } + } + } + } -- cgit v1.2.3 From 78dc3d01c53f81e65ca58a166b395f26f91bc2e0 Mon Sep 17 00:00:00 2001 From: Albert Magyar Date: Wed, 24 Mar 2021 13:32:18 -0700 Subject: Add test for SeparateWriteClocks --- .../firrtlTests/SeparateWriteClocksSpec.scala | 68 ++++++++++++++++++++++ 1 file changed, 68 insertions(+) create mode 100644 src/test/scala/firrtlTests/SeparateWriteClocksSpec.scala (limited to 'src/test') diff --git a/src/test/scala/firrtlTests/SeparateWriteClocksSpec.scala b/src/test/scala/firrtlTests/SeparateWriteClocksSpec.scala new file mode 100644 index 00000000..476a3ae2 --- /dev/null +++ b/src/test/scala/firrtlTests/SeparateWriteClocksSpec.scala @@ -0,0 +1,68 @@ +// SPDX-License-Identifier: Apache-2.0 + +package firrtlTests + +import firrtl._ +import firrtl.ir._ +import firrtl.passes.memlib.SeparateWriteClocks +import firrtl.testutils._ +import firrtl.testutils.FirrtlCheckers._ + +class SeparateWriteClocksSpec extends FirrtlFlatSpec { + def transform(input: String): CircuitState = { + val csx = (new SeparateWriteClocks).execute(CircuitState(parse(input), MidForm)) + val emittedCirc = EmittedFirrtlCircuit("top", csx.circuit.serialize, ".fir") + csx.copy(annotations = Seq(EmittedFirrtlCircuitAnnotation(emittedCirc))) + } + + behavior.of("SeparateWriteClocks") + + it should "add intermediate wires to clocks of multi-write sync-read memories" in { + val result = transform(s""" + |circuit top: + | module top: + | input clk: Clock + | input raddr: UInt<10> + | output rdata: UInt<8>[4] + | input waddr_a: UInt<10> + | input we_a: UInt<1> + | input wdata_a: UInt<8>[4] + | input waddr_a: UInt<10> + | input we_a: UInt<1> + | input wdata_a: UInt<8>[4] + | + | mem m: + | data-type => UInt<8> + | depth => 1024 + | reader => r + | writer => w_a + | writer => w_b + | read-latency => 1 + | write-latency => 1 + | read-under-write => undefined + | + | m.r.clk <= clk + | m.r.addr <= raddr + | m.r.en <= UInt(1) + | rdata <= m.r.data + | + | m.w_a.clk <= clk + | m.w_a.addr <= waddr_a + | m.w_a.en <= we_a + | m.w_a.mask <= UInt(1) + | m.w_a.data <= wdata_a + | + | m.w_b.clk <= clk + | m.w_b.addr <= waddr_b + | m.w_b.en <= we_b + | m.w_b.mask <= UInt(1) + | m.w_b.data <= wdata_b""".stripMargin) + + println(result.circuit.serialize) + result should containLine("m.r.clk <= clk") + result should containLine("m.w_a.clk <= m_w_a_clk") + result should containLine("m.w_b.clk <= m_w_b_clk") + result shouldNot containLine("m.w_a.clk <= clk") + result shouldNot containLine("m.w_b.clk <= clk") + } +} -- cgit v1.2.3