aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorazidar2015-07-29 20:07:36 -0700
committerazidar2015-07-29 20:07:36 -0700
commitc8e06e9b3b0945d0b8634aa3ab1fd71a600a7e01 (patch)
treeffc36b60e08653ff28a34d70998a85e0294e4808 /src
parente4552dcbc844b00e7e4799c882eb00a8be165e9f (diff)
parent7646c2e3edf90ea13a83b76c97f35877263c5e63 (diff)
Merge branch 'master' of github.com:ucb-bar/firrtl into new-low-firrtl
Diffstat (limited to 'src')
-rw-r--r--src/main/stanza/bigint.stanza395
-rw-r--r--src/main/stanza/custom-passes.stanza7
-rw-r--r--src/main/stanza/errors.stanza3
-rw-r--r--src/main/stanza/firrtl-ir.stanza7
-rw-r--r--src/main/stanza/firrtl-lexer.stanza16
-rw-r--r--src/main/stanza/firrtl-test-main.stanza1
-rw-r--r--src/main/stanza/flo.stanza6
-rw-r--r--src/main/stanza/ir-parser.stanza22
-rw-r--r--src/main/stanza/passes.stanza17
-rw-r--r--src/main/stanza/verilog.stanza18
10 files changed, 453 insertions, 39 deletions
diff --git a/src/main/stanza/bigint.stanza b/src/main/stanza/bigint.stanza
new file mode 100644
index 00000000..427ad7ff
--- /dev/null
+++ b/src/main/stanza/bigint.stanza
@@ -0,0 +1,395 @@
+defpackage bigint :
+ import core
+ import verse
+
+val val-n-bytes = 4
+val val-n-bits = val-n-bytes * 8
+val val-all-ones = -1 ;; TODO
+val val-n-half-bits = 32 / 2
+defn val-n-words (nbits: Int) -> Int : 1 + (nbits - 1) / 32
+defn val-n-half-words (nbits: Int) -> Int : (1 + (nbits - 1)) / val-n-half-bits
+defn val-top-bit (v: Int) -> Int : v >> (32 - 1)
+defn val-n-full-words (nbits: Int) -> Int : nbits / 32
+defn val-n-word-bits (nbits: Int) -> Int : nbits % 32
+defn mask-val (n: Int) : -1 >> (32 - n)
+
+public defclass BigInt <: Gettable & Settable & Lengthable
+public defmulti to-bin (b: BigInt) -> String
+public defmulti to-hex (b: BigInt) -> String
+public defmulti num-words (b: BigInt) -> Int
+public defmulti dat (b: BigInt) -> Array<Int>
+public defn BigInt (len: Int) :
+ val d = Array<Int>(val-n-words(len))
+ new BigInt :
+ defmethod get (this, i: Int) -> Int : d[i]
+ defmethod set (this, i: Int, x: Int) : d[i] = x & -1
+ defmethod dat (this) -> Array<Int> : d
+ defmethod length (this) -> Int : len
+ defmethod num-words (this) -> Int : length(d)
+ defmethod to-hex (this) -> String :
+ defn as-hex (i: Int) -> String :
+ val str = "0123456789abcdef"
+ substring(str,i,i + 1)
+ var str = "h"
+ ;println(to-bin(this))
+ for i in 0 to len by 4 do :
+ val pos = len - 4 - i
+ ;println(pos)
+ val digit = (d[pos / 32] >> (pos % 32)) & 15
+ ;println(digit)
+ val hex = as-hex(digit)
+ ;println(hex)
+ str = string-join([str hex])
+ string-join([ "\"" str "\""])
+ defmethod to-bin (this) -> String :
+ string-join $
+ generate<Char> :
+ defn* loop (pos:Int) :
+ if (pos >= 0) :
+ yield(if (d[pos / 32] >> (pos % 32))&1 == 1: '1' else: '0')
+ loop(pos - 1)
+ loop(len - 1)
+ ;defmethod to-string (this) : string-join(["BigInt<" len ">(" to-bin(this) ")"])
+ defmethod to-string (this) : to-hex(this)
+
+defmethod print (o:OutputStream, b:BigInt) :
+ print(o, to-string(b))
+
+defn assert (cond:True|False, msg:String) : if not cond: error(msg)
+
+defn assert (cond:True|False) : assert(cond, "failure")
+
+;; loop macro with starting values
+
+;; defn map-range (s:Int, e:Int, f: (Int) -> False) :
+;; for i in s to e do : f(i)
+
+defn map! (f: (Int, Int) -> Int, d: BigInt, s0: BigInt, s1: BigInt) -> BigInt :
+ ;; assert(length(d) == length(s0) and length(s0) == length(s1),
+ ;; string-join(["LENS != " num-words(d) " " num-words(s0) " " num-words(s1)]))
+ for i in 0 to num-words(d) do :
+ d[i] = f(s0[i], s1[i])
+ d
+
+defn mask! (d: BigInt) -> BigInt :
+ val n-full-words = val-n-full-words(length(d))
+ val n-word-bits = val-n-word-bits(length(d))
+ for i in 0 to n-full-words do :
+ d[i] = -1
+ for i in n-full-words to num-words(d) do :
+ d[i] = 0
+ if n-word-bits > 0 :
+ d[n-full-words] = mask-val(n-word-bits)
+ d
+
+defn trim! (d:BigInt) -> BigInt :
+ val n-full-words = val-n-full-words(length(d))
+ val n-word-bits = val-n-word-bits(length(d))
+ if n-word-bits > 0 :
+ d[n-full-words] = d[n-full-words] & mask-val(n-word-bits)
+ d
+
+defn extract! (d:BigInt, s0:BigInt, e:Int, s:Int) -> BigInt : trim!(rsh!(d, s0, s))
+
+public defn bits (s0:BigInt, e:Int, s:Int) -> BigInt : extract!(BigInt(e - s + 1), s0, e, s)
+
+public defn bit (s0:BigInt, s:Int) -> Int :
+ val wi = s / 32
+ val bi = s % 32
+ s0[wi] >> bi
+
+defn inject! (d:BigInt, s0:BigInt, f:BigInt, start:Int) -> BigInt :
+ val bw = length(f)
+ val msk = mask!(BigInt(bw))
+ val msk-lsh = msk << start
+ val inv-msk-lsh = bit-invert!(msk-lsh, msk-lsh)
+ val f-lsh = f << start
+ (s0 & inv-msk-lsh) | f-lsh
+
+defn map! (f: (Int) -> Int, d: BigInt, s0: BigInt) -> BigInt :
+ ;; assert(length(d) == length(s0), string-join(["LENS != " num-words(d) " " num-words(s0)]))
+ for i in 0 to num-words(d) do :
+ d[i] = f(s0[i])
+ d
+
+defn fill! (f: (Int) -> Int, b: BigInt) :
+ for i in 0 to num-words(b) do :
+ b[i] = f(i)
+ b
+
+public defmethod equal? (x:BigInt, y:BigInt) -> True|False :
+ val tf =
+ if num-words(x) != num-words(y) :
+ false
+ else :
+ var eq? = true
+ for i in 0 to num-words(x) do :
+ val e = (x[i] == y[i])
+ ;if not e : ;println-all(["NOT-EQUAL " x " AND " y " i=" i " X[i] " x[i] " Y[i] " y[i]])
+ eq? = eq? and e
+ eq?
+ ;println-all(["EQUAL? " x " AND " y " " tf])
+ tf
+
+public defn less?! (diff:BigInt, x:BigInt, y:BigInt) -> True|False :
+ sub!(diff, x, y)
+ val-top-bit(diff[num-words(diff) - 1]) == 1
+
+public defn less? (x:BigInt, y:BigInt) -> True|False : op(less?!, x, y)
+
+public defn less-eq?! (diff:BigInt, x:BigInt, y:BigInt) -> True|False :
+ sub!(diff, y, x)
+ val-top-bit(diff[num-words(diff) - 1]) == 0
+
+public defn less-eq? (x:BigInt, y:BigInt) -> True|False : op(less-eq?!, x, y)
+
+public defn greater?! (diff:BigInt, x:BigInt, y:BigInt) -> True|False : not less-eq?!(diff, x, y)
+
+public defn greater? (x:BigInt, y:BigInt) -> True|False : op(greater?!, x, y)
+
+public defn greater-eq?! (diff:BigInt, x:BigInt, y:BigInt) -> True|False : not less?!(diff, x, y)
+
+public defn greater-eq? (x:BigInt, y:BigInt) -> True|False : op(greater-eq?!, x, y)
+
+defn as-digit (c: Char) -> Int :
+ index-of("0123456789abcdef", c) as Int
+
+public defn BigIntLit (f: (Int) -> Int, len: Int) :
+ fill!(f, BigInt(len))
+
+public defn BigIntLit (x: Int, w: Int) :
+ fill!({_ + x}, BigInt(w))
+
+public defn BigIntLit (x: Int) : BigIntLit(x, sizeof(x))
+
+public defn BigIntLit (s: String) : BigIntLit(s, -1)
+
+public defn BigIntLit (s: String, w:Int) :
+ val base = s[0]
+ val shamt = if base == 'b': 1 else if base == 'h': 4 else: 2
+ val digits = substring(s, 1)
+ val len = if w == -1: length(digits) * shamt else: w
+ val lit = BigInt(len)
+ ;; println-all(["BASE " base " SHAMT " shamt " DIGITS " digits])
+ for i in 0 to num-words(lit) do :
+ lit[i] = 0
+ for i in 0 to length(digits) do :
+ val off = (length(digits) - 1 - i) * shamt
+ val wi = off / 32
+ val bi = off % 32
+ lit[wi] = lit[wi] | (as-digit(digits[i]) << bi)
+ ;; println-all(["OFF " off " wi " wi " bi " bi " lit[wi] " lit[wi] " => " lit])
+ ;; println-all(["RES = " lit])
+ lit
+
+public defn sizeof (in: Int) -> Int :
+ max(1, ceil-log2(in + 1))
+
+defn op (f:(BigInt, BigInt, BigInt) -> True|False, x:BigInt, y:BigInt) -> True|False :
+ f(BigInt(max(length(x), length(y))), x, y)
+
+defn op (f:(BigInt, BigInt, BigInt) -> BigInt, x:BigInt, y:BigInt) -> BigInt :
+ f(BigInt(max(length(x), length(y))), x, y)
+
+defn op (f:(BigInt, BigInt) -> BigInt, x:BigInt) -> BigInt :
+ f(BigInt(length(x)), x)
+
+defn int (x: True|False) -> Int : if x : 1 else : 0
+
+public defn plus! (d: BigInt, s0: BigInt, s1: BigInt) -> BigInt :
+ var carry = false
+ for i in 0 to num-words(d) do :
+ d[i] = s0[i] + s1[i] + int(carry)
+ carry = ((s0[i] + s1[i]) < s0[i]) or (d[i] < int(carry))
+ d
+
+public defn plus (x:BigInt, y:BigInt) -> BigInt : op(plus!, x, y)
+
+public defn cat! (d: BigInt, s0: BigInt, s1: BigInt) -> BigInt :
+ lsh!(d, s0, length(s1))
+ ;; println-all([" LSH! " s0 " " length(s1) " => " d])
+ for i in 0 to num-words(s1) do :
+ d[i] = d[i] | s1[i]
+ d
+
+public defn cat (x:BigInt, y:BigInt) -> BigInt :
+ ;; println-all(["> CAT " x " " y])
+ val res = cat!(BigInt(length(x) + length(y)), x, y)
+ ;; println-all(["< CAT " x " " y " => " res])
+ res
+
+public defn cat (args:Streamable<BigInt>) -> BigInt :
+ reduce(cat, args)
+
+public defn sub! (d: BigInt, s0: BigInt, s1: BigInt) -> BigInt :
+ var borrow = false
+ for i in 0 to num-words(d) do :
+ d[i] = s0[i] - s1[i] + int(borrow)
+ borrow = (s0[i] < (s0[i] - s1[i])) or (s0[i] - s1[i]) < d[i]
+ d
+
+public defn sub (x:BigInt, y:BigInt) -> BigInt : op(sub!, x, y)
+
+public defn neg! (d: BigInt, s0: BigInt) -> BigInt :
+ var borrow = false
+ for i in 0 to num-words(d) do :
+ d[i] = neg(s0[i]) - int(borrow)
+ borrow = (s0[i] > 0) or (d[i] > 0)
+ d
+
+public defn neg (x:BigInt) -> BigInt : op(neg!, x)
+
+public defn rsha! (d:BigInt, s0:BigInt, amount:Int) -> BigInt :
+ val w = length(s0)
+ val nw = num-words(d)
+ val n-shift-bits = amount % 32
+ val n-shift-words = amount / 32
+ val n-rev-shift-bits = 32 - n-shift-bits
+ val is-zero-carry = n-shift-bits == 0
+ val msb = s0[nw - 1] >> (w - nw * 32 - 1)
+ var carry = 0;
+
+ if msb == 0 :
+ for i in 0 to n-shift-words do :
+ d[nw - i - 1] = 0
+
+ defn* loopy (i:Int) :
+ if i >= n-shift-words :
+ val x = s0[i]
+ d[i - n-shift-words] = (x >> n-shift-bits) | carry
+ carry = if is-zero-carry: 0 else: x << n-rev-shift-bits
+ loopy(i - 1)
+ loopy(nw - 1)
+
+ if msb != 0 :
+ val boundary = (w - amount)
+
+ defn* loop (i:Int) :
+ if i >= 0 :
+ val idx = i * 32
+ if idx > boundary :
+ d[i] = -1
+ loop(i - 1)
+ else :
+ d[i] = d[i] | (-1 << (boundary - idx))
+ d[nw - 1] = d[nw - 1] & (-1 >> ((nw - 1) * 32 - w))
+ loop(nw - 1)
+ d
+
+public defn signed-shift-right (b:BigInt, n:Int) -> BigInt : rsha!(BigInt(length(b)), b, n)
+
+public defn rsh! (d:BigInt, s0:BigInt, amount:Int) -> BigInt :
+ val nw = num-words(d)
+ var carry = 0
+ val n-shift-bits = amount % 32
+ val n-shift-words = amount / 32
+ val n-rev-shift-bits = 32 - n-shift-bits
+ val is-zero-carry = n-shift-bits == 0
+ for i in 0 to n-shift-words do :
+ d[nw - i - 1] = 0
+ defn* loop (i:Int) :
+ if i >= n-shift-words :
+ val x = s0[i]
+ d[i - n-shift-words] = (x >> n-shift-bits) | carry
+ carry = if is-zero-carry: 0 else: x << n-rev-shift-bits
+ loop(i - 1)
+ loop(nw - 1)
+ d
+
+public defn shift-right (b:BigInt, n:Int) -> BigInt : rsh!(BigInt(length(b)), b, n)
+
+public defn lsh! (d:BigInt, s0:BigInt, amount:Int) :
+ ;; println-all(["LSH " s0 " AMOUNT " amount " INTO BIGINT<" length(d) ">"])
+ val n-shift-bits = amount % 32
+ val n-shift-words = amount / 32
+ val n-rev-shift-bits = 32 - n-shift-bits
+ val is-zero-carry = n-shift-bits == 0
+ for i in 0 to num-words(d) do :
+ d[i] = 0
+ var carry = 0;
+ ;; println-all(["LSH AMOUNT " amount " VNB " 32 " NSB " n-shift-bits " NSW " n-shift-words " NRSB " n-rev-shift-bits])
+ for i in 0 to (num-words(d) - n-shift-words) do :
+ val x = if i >= num-words(s0) : 0 else: s0[i]
+ ;; println-all([" SHIFTING " (i + n-shift-words) " VAL " (x << n-shift-bits)])
+ d[i + n-shift-words] = (x << n-shift-bits) | carry
+ carry = if is-zero-carry: 0 else: x >> n-rev-shift-bits
+ d
+
+public defn shift-left (b:BigInt, n:Int) -> BigInt : lsh!(BigInt(length(b) + n), b, n)
+
+;; defn mul! (d: BigInt, s0: BigInt, s1: BigInt, nb0: Int, nb1: Int) -> BigInt :
+;; ;; Adapted from Hacker's Delight, from Knuth
+;; var nbd = nb0 + nb1
+;; for i in 0 to val-n-words(nbd) do :
+;; d[i] = 0
+;;
+;; half-val-t* w = reinterpret-cast<half-val-t*>(d);
+;; half-val-t* u = reinterpret-cast<half-val-t*>(s0);
+;; half-val-t* v = reinterpret-cast<half-val-t*>(s1);
+;; val m = val-n-half-words(nb0)
+;; val n = val-n-half-words(nb1)
+;; val p = val-n-half-words(nbd)
+;;
+;; for j in 0 to n do :
+;; var k = 0
+;; for i in 0 to min(m, p - j) do :
+;; val t = u[i] * v[j] + w[i + j] + k
+;; w[i + j] = t
+;; k = t >> val-n-half-bits()
+;; if ((j + m) < p)
+;; w[j + m] = k
+;; d
+
+public defn bit-xor! (d: BigInt, s0: BigInt, s1: BigInt) : map!(bit-xor, d, s0, s1)
+
+public defn bit-xor (b0:BigInt, b1:BigInt) : op(bit-xor!, b0, b1)
+
+public defn bit-or! (d: BigInt, s0: BigInt, s1: BigInt) : map!(bit-or, d, s0, s1)
+
+public defn bit-or (b0:BigInt, b1:BigInt) : op(bit-or!, b0, b1)
+
+public defn bit-and! (d: BigInt, s0: BigInt, s1: BigInt) : map!(bit-and, d, s0, s1)
+
+public defn bit-and (b0:BigInt, b1:BigInt) : op(bit-and!, b0, b1)
+
+public defn bit-invert! (d: BigInt, s0: BigInt) : map!(bit-xor, d, s0, mask!(d))
+
+public defn bit-invert (b0:BigInt) : op(bit-invert!, b0)
+
+defn check (msg:String, x:BigInt, e:BigInt) :
+ println-all([msg " " x " E " e " ? " x == e])
+
+defn check (msg:String, x:BigInt) :
+ println-all([msg " " x])
+
+;; check("Ba ", BigIntLit({ _ }, 1))
+;; check("Bb ", BigIntLit({ _ }, 16))
+;; check("Bc ", BigIntLit({ _ }, 32))
+;; check("Bd ", BigIntLit({ _ }, 48))
+;; check("Be ", BigIntLit({ _ }, 64))
+;; check("Bf ", BigIntLit({ _ }, 65))
+;; check("B1 ", BigIntLit(1, 8))
+;; check("B2 ", BigIntLit(2, 8))
+;; check("B+ ", BigIntLit(3, 8) + BigIntLit(5, 8), BigIntLit(3 + 5, 8))
+;; check("B- ", BigIntLit(5, 8) + BigIntLit(3, 8), BigIntLit(5 + 3, 8))
+;; check("B| ", BigIntLit(5, 8) | BigIntLit(9, 8), BigIntLit(5 | 9, 8))
+;; check("B& ", BigIntLit(5, 8) & BigIntLit(9, 8), BigIntLit(5 & 9, 8))
+;; check("B^ ", BigIntLit(5, 8) ^ BigIntLit(9, 8), BigIntLit(5 ^ 9, 8))
+;; check("B< ", BigIntLit(5, 8) << 1, BigIntLit(5 << 1, 9))
+;; check("B< ", BigIntLit(5, 3) << 10, BigIntLit(5 << 1, 13))
+;; check("B< ", BigIntLit(5, 3) << 32, BigIntLit(5 << 1, 38))
+;; check("B< ", BigIntLit("b1010") << 1, BigIntLit(10 << 1, 5))
+check("S1 ", BigIntLit("hfafa") << 16, BigIntLit("hfafa0000", 32))
+check("S1 ", BigIntLit(1,32) , BigIntLit(1,32))
+check("S1 ", BigIntLit(0,32) , BigIntLit(0,32))
+;; check("B< ", BigIntLit(5, 3) << 64, BigIntLit(5 << 1, 67))
+;; check("BN ", neg(BigIntLit(2, 8)), BigIntLit(-2, 8))
+check("S2 ", BigIntLit("b11111010") << 8, BigIntLit("b1111101000000000", 16))
+check("C1 ", cat(BigIntLit("b11111010", 8), BigIntLit("b10111100", 8)), BigIntLit("b1111101010111100", 16))
+check("C3 ", cat(cat(BigIntLit("b1111"), BigIntLit("b1010")), cat(BigIntLit("b1011"), BigIntLit("b1100"))), BigIntLit("b1111101010111100", 16))
+check("C4 ", cat([BigIntLit("b1111"), BigIntLit("b1010"), BigIntLit("b1011"), BigIntLit("b1100")]), BigIntLit("b1111101010111100", 16))
+check("C5 ", BigIntLit("b101111001"), BigIntLit("b101111001"))
+check("C6 ", cat(BigIntLit("b1"), BigIntLit("b01111001")), BigIntLit("b101111001"))
+check("C7 ", cat(BigIntLit("b11101"), BigIntLit("b101111001")), BigIntLit("b11101101111001"))
+check("C8 ", cat([BigIntLit("b11"), BigIntLit("b101"), BigIntLit("b1011"), BigIntLit("b11001")]), BigIntLit("b11101101111001"))
+check("C0 ", bits(BigIntLit("b11101101111001"), 10, 1), BigIntLit("b0110111100"))
diff --git a/src/main/stanza/custom-passes.stanza b/src/main/stanza/custom-passes.stanza
index 4904d6d1..ecd7aed1 100644
--- a/src/main/stanza/custom-passes.stanza
+++ b/src/main/stanza/custom-passes.stanza
@@ -3,6 +3,7 @@ defpackage firrtl/custom-passes :
import verse
import firrtl/ir-utils
import firrtl/ir2
+ import bigint
;============ When Coverage =============
public defstruct WhenCoverage <: Pass :
@@ -46,7 +47,7 @@ defn when-coverage (port-name:Symbol, reg-name:Symbol, instrument?:HashTable<Sym
val sym = HashTable<Symbol,Int>(symbol-hash)
val w1 = IntWidth(1)
val t1 = UIntType(w1)
- val u1 = UIntValue(to-long $ 1,w1)
+ val u1 = UIntValue(BigIntLit("1"),w1)
defn when-coverage (s:Stmt) -> Stmt :
match(s) :
(s:Conditionally) :
@@ -71,7 +72,7 @@ defn when-coverage (port-name:Symbol, reg-name:Symbol, instrument?:HashTable<Sym
if length(w-ls) != 0 :
val reg-ref = Ref(reg-name,UIntType(IntWidth(length(w-ls))))
;add{logic,_} $ DefRegister(FileInfo(),name(reg-ref),type(reg-ref)) TODO add clock and reset
- add{logic,_} $ OnReset(FileInfo(),reg-ref,UIntValue(to-long $ 0,IntWidth(length(w-ls))))
+ add{logic,_} $ OnReset(FileInfo(),reg-ref,UIntValue(BigIntLit("0"),IntWidth(length(w-ls))))
for (x in w-ls, i in 0 to false) do :
add{logic,_} $ DefWire(FileInfo(),name(x),type(x))
add{logic,_} $ Connect(FileInfo(),x,DoPrim(BIT-SELECT-OP,list(reg-ref),list(i),UIntType(w1)))
@@ -81,7 +82,7 @@ defn when-coverage (port-name:Symbol, reg-name:Symbol, instrument?:HashTable<Sym
if length(i-ls) != 0 :
for (x in i-ls, i in 0 to false) do :
add{logic,_} $ DefWire(FileInfo(),name(x),type(x))
- add{logic,_} $ Connect(FileInfo(),x,UIntValue(to-long $ 0,UnknownWidth()))
+ add{logic,_} $ Connect(FileInfo(),x,UIntValue(BigIntLit("0"),UnknownWidth()))
if instrument?[name(m)] : add{logic,_} $ Connect(FileInfo(),port-ref,concat-all(append(w-ls,i-ls)))
diff --git a/src/main/stanza/errors.stanza b/src/main/stanza/errors.stanza
index d8969dd3..6cdd1dca 100644
--- a/src/main/stanza/errors.stanza
+++ b/src/main/stanza/errors.stanza
@@ -6,6 +6,7 @@ defpackage firrtl/errors :
import firrtl/primops
import firrtl/passes
import firrtl-main
+ import bigint
; TODO
; make sure it compiles, write tests, look over code to make sure its right
@@ -277,7 +278,7 @@ public defn check-high-form (c:Circuit) -> Circuit :
(e) : add(errors,InvalidIndex(info))
(e:DoPrim) : check-high-form-primop(e,errors,info)
(e:UIntValue) :
- if value(e) < to-long $ 0 : add(errors,NegUInt(info))
+ if value(e) < BigIntLit("h0",length(value(e))) : add(errors,NegUInt(info))
(e) : false
map(check-high-form-w{info,_:Width},e)
map(check-high-form-t{info,_:Type},e)
diff --git a/src/main/stanza/firrtl-ir.stanza b/src/main/stanza/firrtl-ir.stanza
index 15666a9a..822b8610 100644
--- a/src/main/stanza/firrtl-ir.stanza
+++ b/src/main/stanza/firrtl-ir.stanza
@@ -1,6 +1,7 @@
defpackage firrtl/ir2 :
import core
import verse
+ import bigint
public defmulti info! (x:?) -> FileInfo
public defmethod info! (x:?) : FileInfo()
@@ -31,7 +32,7 @@ public defstruct UnknownWidth <: Width
public defstruct IntWidth <: Width :
width: Int
public defstruct LongWidth <: Width :
- width : Long
+ width: Long
public definterface PrimOp
public val ADD-OP = new PrimOp
@@ -85,10 +86,10 @@ public defstruct Index <: Expression :
value: Int
type: Type with: (as-method => true)
public defstruct UIntValue <: Expression :
- value: Long
+ value: BigInt
width: Width
public defstruct SIntValue <: Expression :
- value: Long
+ value: BigInt
width: Width
public defstruct DoPrim <: Expression :
op: PrimOp
diff --git a/src/main/stanza/firrtl-lexer.stanza b/src/main/stanza/firrtl-lexer.stanza
index f0673a72..7581b26c 100644
--- a/src/main/stanza/firrtl-lexer.stanza
+++ b/src/main/stanza/firrtl-lexer.stanza
@@ -2,6 +2,7 @@ defpackage firrtl/lexer :
import core
import core/stringeater
import verse
+ import bigint
;=============== PUBLIC INTERFACE ===========================
public defn lex (text:String) -> List<Token> :
@@ -286,13 +287,14 @@ defn eat-number () :
match(to-float(str)) :
(f:Float) : token-eaten(Token(f, info))
(f:False) : throw(InvalidNumber(info))
- else :
- match(to-long(str)) :
- (l:Long) :
- if l < (to-long("2147483647") as Long) and l > (to-long("-2147483648") as Long) : token-eaten(Token(to-int(str), info))
- else : token-eaten(Token(l, info))
- (l:False) : token-eaten(Token(to-int(str), info))
- ;else : token-eaten(Token(to-int(str), info)) <- ADAM CHANGE, FROM THIS
+ else : token-eaten(Token(to-int(str), info))
+ ;else : token-eaten(Token(BigIntLit(str),info))
+ ;else :
+ ;match(to-long(str)) :
+ ; (l:Long) :
+ ; if l < (to-long("2147483647") as Long) and l > (to-long("-2147483648") as Long) : token-eaten(Token(to-int(str), info))
+ ; else : token-eaten(Token(l, info))
+ ; (l:False) : token-eaten(Token(to-int(str), info))
defn eat-here-string () :
if EATER[0] == '\\' and EATER[1] == '<' :
diff --git a/src/main/stanza/firrtl-test-main.stanza b/src/main/stanza/firrtl-test-main.stanza
index beb288b1..9762966b 100644
--- a/src/main/stanza/firrtl-test-main.stanza
+++ b/src/main/stanza/firrtl-test-main.stanza
@@ -3,6 +3,7 @@
#include<"compiler/stz-algorithms.stanza">
#include<"compiler/stz-parser.stanza">
#include<"compiler/stz-lexer.stanza">
+#include("bigint.stanza")
#include("firrtl-lexer.stanza")
#include("firrtl-ir.stanza")
#include("ir-utils.stanza")
diff --git a/src/main/stanza/flo.stanza b/src/main/stanza/flo.stanza
index d8fe705f..f4b453ba 100644
--- a/src/main/stanza/flo.stanza
+++ b/src/main/stanza/flo.stanza
@@ -4,6 +4,7 @@ defpackage firrtl/flo :
import firrtl/ir-utils
import firrtl/ir2
import firrtl/passes
+ import bigint
;============= Flo Backend ================
@@ -72,9 +73,6 @@ defn prim-width (type:Type) -> Int :
(t:ClockType) : 1
(t) : error("Bad prim width type")
-defn sizeof (in: Int) -> Int :
- max(1, ceil-log2(in + 1))
-
defn emit-all (es:Streamable, top:Symbol) :
for e in es do :
match(e) :
@@ -171,7 +169,7 @@ defn emit-s (s:Stmt, flokinds:HashTable<Symbol,FloKind>, top:Symbol,sh:HashTable
(s:DefNode) :
emit-all([top "::" name(s) " = " maybe-mov(value(s)) value(s) "\n"], top)
(s:Begin) : do(emit-s{_, flokinds, top,sh}, body(s))
- (s:Connect) : emit-connect(s,UIntValue(to-long(1),IntWidth(1)))
+ (s:Connect) : emit-connect(s,UIntValue(BigIntLit("1"),IntWidth(1)))
(s:Conditionally) : emit-connect(conseq(s) as Connect,pred(s))
(s) : s
diff --git a/src/main/stanza/ir-parser.stanza b/src/main/stanza/ir-parser.stanza
index 7e07eb8b..fdf4c383 100644
--- a/src/main/stanza/ir-parser.stanza
+++ b/src/main/stanza/ir-parser.stanza
@@ -4,6 +4,7 @@ defpackage firrtl/parser :
import firrtl/ir2
import stz/parser
import firrtl/lexer
+ import bigint
;======= Convenience Functions ========
defn first-info? (form) -> FileInfo|False :
@@ -81,6 +82,9 @@ defsyntax firrtl :
int = (?x) when unwrap-token(x) typeof Int :
unwrap-token(x)
+ string = (?x) when unwrap-token(x) typeof String :
+ unwrap-token(x)
+
;Parses next form if long literal
intorlong = (?x) when unwrap-token(x) typeof Int|Long :
unwrap-token(x)
@@ -88,7 +92,7 @@ defsyntax firrtl :
;Parses next form if symbol
sym = (?x) when unwrap-token(x) typeof Symbol :
unwrap-token(x)
-
+
;Error Handling Productions
defrule :
;Error if not an identifier
@@ -210,10 +214,7 @@ defsyntax firrtl :
accdir = (rdwr) : RDWR
defrule width :
- width = (?x:#intorlong) :
- match(x) :
- (x:Int) : IntWidth(x)
- (x:Long) : LongWidth(x)
+ width = (?x:#int) : IntWidth(x)
width = (?) : UnknownWidth()
;Main Statement Productions
@@ -257,10 +258,15 @@ defsyntax firrtl :
expop = (. ?f:#id!) : (fn (x) : Subfield(x, f, UnknownType()))
;Prefix Operators
- expterm = (?t:#inttype(?v:#long$)) :
+ expterm = (?t:#inttype(?v:#string)) :
+ match(t) :
+ (t:UIntType) : UIntValue(BigIntLit(v as String), width(t))
+ (t:SIntType) : SIntValue(BigIntLit(v as String), width(t))
+
+ expterm = (?t:#inttype(?v:#int$)) :
match(t) :
- (t:UIntType) : UIntValue(v, width(t))
- (t:SIntType) : SIntValue(v, width(t))
+ (t:UIntType) : UIntValue(BigIntLit(v as Int,32), width(t))
+ (t:SIntType) : SIntValue(BigIntLit(v as Int,32), width(t))
expterm = (?op:#sym(?es:#exp ... ?ints:#int ... ?rest ...)) :
if not empty?(rest) :
diff --git a/src/main/stanza/passes.stanza b/src/main/stanza/passes.stanza
index 33ef666c..db1a056e 100644
--- a/src/main/stanza/passes.stanza
+++ b/src/main/stanza/passes.stanza
@@ -6,6 +6,7 @@ defpackage firrtl/passes :
import firrtl/primops
import firrtl-main
import firrtl/errors
+ import bigint
;============== Pass List ================
public val standard-passes = to-list $ [
@@ -1150,7 +1151,7 @@ defn expand-connect-indexed-stmt (s: Stmt,sh:HashTable<Symbol,Int>) -> Stmt :
to-list $
for (i in 0 to false, l in locs(s)) stream : Conditionally(
info(s),
- equality(ref,UIntValue(to-long $ i,UnknownWidth())),
+ equality(ref,UIntValue(BigIntLit(i,32),UnknownWidth())),
Connect(info(s),l,exp(s)),
EmptyStmt()
)
@@ -1164,7 +1165,7 @@ defn expand-connect-indexed-stmt (s: Stmt,sh:HashTable<Symbol,Int>) -> Stmt :
to-list $
for (i in 1 to false, e in tail(exps(s))) stream : Conditionally(
info(s),
- equality(ref,UIntValue(to-long $ i,UnknownWidth())),
+ equality(ref,UIntValue(BigIntLit(i,32),UnknownWidth())),
Connect(info(s),loc(s),e),
EmptyStmt()
)
@@ -1210,8 +1211,8 @@ public defmethod short-name (b:ExpandWhens) -> String : "expand-whens"
; ======== Expression Computation Library ===========
-val zero = UIntValue(to-long $ 0,IntWidth(1))
-val one = UIntValue(to-long $ 1,IntWidth(1))
+val zero = UIntValue(BigIntLit(0,32),IntWidth(1))
+val one = UIntValue(BigIntLit(1,32),IntWidth(1))
defmethod equal? (e1:Expression,e2:Expression) -> True|False :
match(e1,e2) :
@@ -1547,7 +1548,7 @@ public defn expand-whens (c:Circuit) -> Circuit :
(e:Expression) :
val ref = WRef(name(s),type(s),NodeKind(),FEMALE)
val en = to-exp(optimize $ get-write-enable(table[name(s)])) as Expression
- if en == UIntValue(to-long(1),UnknownWidth()) :
+ if en == one :
add{cons,_} $ Connect(info(s),ref,e)
else :
add{cons,_} $ Conditionally(info(s),en,Connect(info(s),ref,e),EmptyStmt())
@@ -1562,7 +1563,7 @@ public defn expand-whens (c:Circuit) -> Circuit :
match(e) :
(e:Expression) :
val en = (to-exp $ optimize $ get-write-enable(table[n])) as Expression
- if en == UIntValue(to-long(1),UnknownWidth()) :
+ if en == one :
add{cons,_} $ Connect(info(s),ref,e)
else :
add{cons,_} $ Conditionally(info(s),en,Connect(info(s),ref,e),EmptyStmt())
@@ -1957,14 +1958,14 @@ defn gen-constraints (m:Module, h:HashTable<Symbol,Type>, v:Vector<WGeq>) -> Mod
match(width(e)) :
(w:UnknownWidth) :
val w* = VarWidth(firrtl-gensym(`w,width-name-hash))
- add(v,WGeq(w*,IntWidth(to-int $ to-string $ ceil-log2(value(e)))))
+ add(v,WGeq(w*,IntWidth(length(to-bin(value(e))))))
UIntValue(value(e),w*)
(w) : e
(e:SIntValue) :
match(width(e)) :
(w:UnknownWidth) :
val w* = VarWidth(firrtl-gensym(`w,width-name-hash))
- add(v,WGeq(w*,IntWidth(1 + to-int $ to-string $ ceil-log2(abs(value(e))))))
+ add(v,WGeq(w*,IntWidth(1 + length(to-bin(value(e))))))
SIntValue(value(e),w*)
(w) : e
(e) : e
diff --git a/src/main/stanza/verilog.stanza b/src/main/stanza/verilog.stanza
index 50794eeb..ca47170b 100644
--- a/src/main/stanza/verilog.stanza
+++ b/src/main/stanza/verilog.stanza
@@ -65,8 +65,14 @@ defn emit-signed-if-any (e:Expression,ls:List<Expression>) -> String :
defn emit (e:Expression) -> String :
match(e) :
(e:Ref) : to-string $ name(e)
- (e:UIntValue) : string-join $ [width!(type(e)) "'d" value(e)]
- (e:SIntValue) : string-join $ [width!(type(e)) "'sd" value(e)]
+ (e:UIntValue) :
+ val str = to-string(value(e))
+ val out = substring(str,1,length(str) - 1)
+ string-join $ [width!(type(e)) "'" out]
+ (e:SIntValue) : ;string-join $ [width!(type(e)) "'s" value(e)]
+ val str = to-string(value(e))
+ val out = substring(str,1,length(str) - 1)
+ string-join $ [width!(type(e)) "'s" out]
(e:Subfield) : error("Non-supported expression")
(e:Index) : error("Non-supported expression")
(e:DoPrim) :
@@ -116,7 +122,7 @@ defn emit (e:Expression) -> String :
match(type(args(e)[0])) :
(t:UIntType) : ["{1'b0," emit-as-type(args(e)[0],type(e)) "}"]
(t:SIntType) : [emit-as-type(args(e)[0],type(e))]
- BIT-NOT-OP : ["!" emit-as-type(args(e)[0],type(e))]
+ BIT-NOT-OP : ["~ " emit-as-type(args(e)[0],type(e))]
BIT-AND-OP : [emit-as-type(args(e)[0],type(e)) " & " emit-as-type(args(e)[1],type(e))]
BIT-OR-OP : [emit-as-type(args(e)[0],type(e)) " | " emit-as-type(args(e)[1],type(e))]
BIT-XOR-OP : [emit-as-type(args(e)[0],type(e)) " ^ " emit-as-type(args(e)[1],type(e))]
@@ -177,6 +183,7 @@ defn emit-module (m:InModule) :
val inst-ports = HashTable<Symbol,Vector<Streamable>>(symbol-hash)
val sh = get-sym-hash(m)
+ val rand-value = "0"
for x in vdecs do :
val sym = key(x)
@@ -196,11 +203,12 @@ defn emit-module (m:InModule) :
else :
add(my-clk-update,[sym " <= " emit(cons[sym]) ";"])
updates[get-name(clock(s))] = my-clk-update
+ add(inits,[sym " = {" width!(type(s)) "{" rand-value "}};"])
(s:DefMemory) :
val vtype = type(s) as VectorType
add(regs,["reg " get-width(type(vtype)) " " sym " [0:" size(vtype) "];"])
add(inits,["for (initvar = 0; initvar < " size(vtype) "; initvar = initvar+1)"])
- add(inits,[" " sym "[initvar] = {" width!(type(vtype)) "{$random}};"])
+ add(inits,[" " sym "[initvar] = {" width!(type(vtype)) "{" rand-value "}};"])
(s:DefNode) :
add(wires,["wire " get-width(type(value(s))) " " sym ";"])
add(assigns,["assign " sym " = " emit(value(s)) ";"])
@@ -221,7 +229,7 @@ defn emit-module (m:InModule) :
; to make it sequential, register the index for an additional cycle
val index* = Ref(firrtl-gensym(name(index(s) as Ref),sh),type(index(s)))
add(regs,[ "reg " get-width(type(index*)) " " name(index*) ";"])
- add(inits,[name(index*) " = {" width!(type(index*)) "{$random}};"])
+ add(inits,[name(index*) " = {" width!(type(index*)) "{" rand-value "}};"])
val my-clk-update = get?(updates,get-name(clock(mem-declaration)),Vector<Streamable>())
add(my-clk-update,[name(index*) " <= " emit(index(s)) ";"])
updates[get-name(clock(mem-declaration))] = my-clk-update