// SPDX-License-Identifier: Apache-2.0 package firrtlTests package fixed import firrtl._ import firrtl.passes._ import firrtl.testutils._ class RemoveFixedTypeSpec extends FirrtlFlatSpec { private def executeTest(input: String, expected: Seq[String], passes: Seq[Transform]) = { val c = passes .foldLeft(CircuitState(Parser.parse(input.split("\n").toIterator), UnknownForm)) { (c: CircuitState, p: Transform) => p.runTransform(c) } .circuit val lines = c.serialize.split("\n").map(normalized) expected.foreach { e => lines should contain(e) } } "Fixed types" should "be removed" in { val passes = Seq( ToWorkingIR, CheckHighForm, ResolveKinds, InferTypes, CheckTypes, ResolveFlows, CheckFlows, new InferWidths, CheckWidths, ConvertFixedToSInt ) val input = """circuit Unit : | module Unit : | input a : Fixed<10><<2>> | input b : Fixed<10><<0>> | input c : Fixed<4><<3>> | output d : Fixed<<5>> | d <= add(a, add(b, c))""".stripMargin val check = """circuit Unit : | module Unit : | input a : SInt<10> | input b : SInt<10> | input c : SInt<4> | output d : SInt<15> | d <= shl(add(shl(a, 1), add(shl(b, 3), c)), 2)""".stripMargin executeTest(input, check.split("\n").map(normalized), passes) } "Fixed types" should "be removed, even with a bulk connect" in { val passes = Seq( ToWorkingIR, CheckHighForm, ResolveKinds, InferTypes, CheckTypes, ResolveFlows, CheckFlows, new InferWidths, CheckWidths, ConvertFixedToSInt ) val input = """circuit Unit : | module Unit : | input a : Fixed<10><<2>> | input b : Fixed<10><<0>> | input c : Fixed<4><<3>> | output d : Fixed<<5>> | d <- add(a, add(b, c))""".stripMargin val check = """circuit Unit : | module Unit : | input a : SInt<10> | input b : SInt<10> | input c : SInt<4> | output d : SInt<15> | d <- shl(add(shl(a, 1), add(shl(b, 3), c)), 2)""".stripMargin executeTest(input, check.split("\n").map(normalized), passes) } "Fixed types" should "remove binary point shift correctly" in { val passes = Seq( ToWorkingIR, CheckHighForm, ResolveKinds, InferTypes, CheckTypes, ResolveFlows, CheckFlows, new InferWidths, CheckWidths, ConvertFixedToSInt ) val input = """circuit Unit : | module Unit : | input a : Fixed<10><<2>> | output d : Fixed<12><<4>> | d <= incp(a, 2)""".stripMargin val check = """circuit Unit : | module Unit : | input a : SInt<10> | output d : SInt<12> | d <= shl(a, 2)""".stripMargin executeTest(input, check.split("\n").map(normalized), passes) } "Fixed types" should "remove binary point shift correctly in reverse" in { val passes = Seq( ToWorkingIR, CheckHighForm, ResolveKinds, InferTypes, CheckTypes, ResolveFlows, CheckFlows, new InferWidths, CheckWidths, ConvertFixedToSInt ) val input = """circuit Unit : | module Unit : | input a : Fixed<10><<2>> | output d : Fixed<9><<1>> | d <= decp(a, 1)""".stripMargin val check = """circuit Unit : | module Unit : | input a : SInt<10> | output d : SInt<9> | d <= shr(a, 1)""".stripMargin executeTest(input, check.split("\n").map(normalized), passes) } "Fixed types" should "remove an absolutely set binary point correctly" in { val passes = Seq( ToWorkingIR, CheckHighForm, ResolveKinds, InferTypes, CheckTypes, ResolveFlows, CheckFlows, new InferWidths, CheckWidths, ConvertFixedToSInt ) val input = """circuit Unit : | module Unit : | input a : Fixed<10><<2>> | output d : Fixed | d <= setp(a, 3)""".stripMargin val check = """circuit Unit : | module Unit : | input a : SInt<10> | output d : SInt<11> | d <= shl(a, 1)""".stripMargin executeTest(input, check.split("\n").map(normalized), passes) } "Fixed point numbers" should "allow binary point to be set to zero at creation" in { val input = """ |circuit Unit : | module Unit : | input clock : Clock | input reset : UInt<1> | input io_in : Fixed<6><<0>> | output io_out : Fixed | | io_in is invalid | io_out is invalid | io_out <= io_in """.stripMargin class CheckChirrtlTransform extends SeqTransform { def inputForm = ChirrtlForm def outputForm = ChirrtlForm def transforms = Seq(passes.CheckChirrtl) } val chirrtlTransform = new CheckChirrtlTransform chirrtlTransform.execute(CircuitState(parse(input), ChirrtlForm)) } "Fixed point numbers" should "remove nested AsFixedPoint" in { val passes = Seq( ToWorkingIR, CheckHighForm, ResolveKinds, InferTypes, CheckTypes, ResolveFlows, CheckFlows, new InferWidths, CheckWidths, ConvertFixedToSInt ) val input = """ |circuit Unit : | module Unit : | node x = asFixedPoint(asFixedPoint(UInt(3), 0), 1) """.stripMargin val check = """ |circuit Unit : | module Unit : | node x = asSInt(asSInt(UInt<2>("h3"))) """.stripMargin executeTest(input, check.split("\n").map(normalized), passes) } }