aboutsummaryrefslogtreecommitdiff
path: root/src/test/scala/firrtlTests/ParserSpec.scala
blob: 0cc893e2f8ac5c54e50a3f09064266e0588d7076 (plain)
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
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
// See LICENSE for license details.

package firrtlTests

import org.scalatest._
import firrtl._

class ParserSpec extends FirrtlFlatSpec {

  private object MemTests {
    val prelude = Seq("circuit top :", "  module top :", "    mem m : ")
    val fields = Map("data-type" -> "UInt<32>",
                     "depth" -> "4",
                     "read-latency" -> "1",
                     "write-latency" -> "1",
                     "reader" -> "a",
                     "writer" -> "b",
                     "readwriter" -> "c"
                    )
    def fieldsToSeq(m: Map[String, String]): Seq[String] =
      m map { case (k,v) => s"      ${k} => ${v}" } toSeq
  }

  private object RegTests {
    val prelude = Seq("circuit top :", "  module top :")
    val reg = "    reg r : UInt<32>, clock"
    val reset = "reset => (radReset, UInt(\"hdeadbeef\"))"
  }

  private object KeywordTests {
    val prelude = Seq("circuit top :", "  module top :")
    val keywords = Seq( "circuit", "module", "extmodule", "input", "output",
      "UInt", "SInt", "flip", "Clock", "wire", "reg", "reset", "with", "mem",
      "data-type", "depth", "read-latency", "write-latency",
      "read-under-write", "reader", "writer", "readwriter", "inst", "of",
      "node", "is", "invalid", "when", "else", "stop", "printf", "skip", "old",
      "new", "undefined", "mux", "validif", "UBits", "SBits", "cmem", "smem",
      "mport", "infer", "read", "write", "rdwr"
    ) ++ PrimOps.listing
  }

  // ********** Memories **********
  "Memories" should "allow arbitrary ordering of fields" in {
    val fields = MemTests.fieldsToSeq(MemTests.fields)
    val golden = firrtl.Parser.parse((MemTests.prelude ++ fields))

    fields.permutations foreach { permutation =>
      val circuit = firrtl.Parser.parse((MemTests.prelude ++ permutation))
      assert(golden === circuit)
    }
  }

  it should "have exactly one of each: data-type, depth, read-latency, and write-latency" in {
    import MemTests._
    def parseWithoutField(s: String) = firrtl.Parser.parse((prelude ++ fieldsToSeq(fields - s)))
    def parseWithDuplicate(k: String, v: String) =
      firrtl.Parser.parse((prelude ++ fieldsToSeq(fields) :+ s"      ${k} => ${v}"))

    Seq("data-type", "depth", "read-latency", "write-latency") foreach { field =>
      evaluating { parseWithoutField(field) } should produce [ParameterNotSpecifiedException]
      evaluating { parseWithDuplicate(field, fields(field)) } should produce [ParameterRedefinedException]
    }
  }

  // ********** Registers **********
  "Registers" should "allow no implicit reset" in {
    import RegTests._
    firrtl.Parser.parse((prelude :+ reg))
  }

  it should "allow same-line reset" in {
    import RegTests._
    firrtl.Parser.parse((prelude :+ s"${reg} with : (${reset})" :+ "    wire a : UInt"))
  }

  it should "allow multi-line reset" in {
    import RegTests._
    firrtl.Parser.parse((prelude :+ s"${reg} with :\n      (${reset})"))
  }

  // ********** Keywords **********
  "Keywords" should "be allowed as Ids" in {
    import KeywordTests._
    keywords foreach { keyword =>
      firrtl.Parser.parse((prelude :+ s"      wire ${keyword} : UInt"))
    }
  }

  it should "be allowed on lhs in connects" in {
    import KeywordTests._
    keywords foreach { keyword =>
      firrtl.Parser.parse((prelude ++ Seq(s"      wire ${keyword} : UInt",
                                          s"      ${keyword} <= ${keyword}")))
    }
  }
}