1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
|
// SPDX-License-Identifier: Apache-2.0
package firrtlTests
import firrtl.transforms.InlineAcrossCastsTransform
import firrtl.testutils.FirrtlFlatSpec
import firrtl.testutils.FirrtlCheckers._
class InlineAcrossCastsEquivalenceSpec extends FirrtlFlatSpec {
/*
* Note: InlineCasts is still part of mverilog, so this test must both:
* - Test that the InlineCasts fix is effective given the current mverilog
* - Provide a test that will be robust if and when InlineCasts is no longer run in mverilog
*
* This is why the test passes InlineCasts as a custom transform: to future-proof it so that
* it can do real LEC against no-InlineCasts. It currently is just a sanity check that the
* emitted Verilog is legal, but it will automatically become a more meaningful test when
* InlineCasts is not run in mverilog.
*/
"InlineCastsTransform" should "not produce broken Verilog" in {
val input =
s"""circuit literalsel_fir:
| module literalsel_fir:
| input i: UInt<4>
| output o: SInt<8>
| o <= pad(asSInt(UInt<2>("h1")), 8)
|""".stripMargin
firrtlEquivalenceTest(input, Seq(new InlineAcrossCastsTransform))
}
it should "not inline complex expressions into other complex expressions" in {
val input =
"""circuit NeverInlineComplexIntoComplex :
| module NeverInlineComplexIntoComplex :
| input a : SInt<3>
| input b : UInt<2>
| input c : UInt<2>
| input sel : UInt<1>
| output out : SInt<3>
| node diff = sub(b, c)
| out <= mux(sel, a, asSInt(diff))
|""".stripMargin
val expected =
"""module NeverInlineComplexIntoComplexRef(
| input [2:0] a,
| input [1:0] b,
| input [1:0] c,
| input sel,
| output [2:0] out
|);
| wire [2:0] diff = b - c;
| assign out = sel ? $signed(a) : $signed(diff);
|endmodule
|""".stripMargin
firrtlEquivalenceWithVerilog(input, expected)
}
it should "inline casts on both sides of a more complex expression" in {
val input =
"""circuit test :
| module test :
| input clock : Clock
| input in : UInt<8>
| output out : UInt<8>
|
| node _T_1 = asUInt(clock)
| node _T_2 = not(_T_1)
| node clock_n = asClock(_T_2)
| reg r : UInt<8>, clock_n
| r <= in
| out <= r
|""".stripMargin
val verilog = compileToVerilogCircuitState(input)
verilog should containLine("always @(posedge clock_n) begin")
}
}
|