From 69e4bc2c4f4e7c2940633f12a40a5550205eb75e Mon Sep 17 00:00:00 2001 From: Adam Izraelevitz Date: Wed, 22 Jul 2015 15:42:40 -0700 Subject: Fixed verilog so it emits non-random inital values. Changed Not to be correct. --- src/main/stanza/verilog.stanza | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/main/stanza/verilog.stanza b/src/main/stanza/verilog.stanza index 50794eeb..6d9e2962 100644 --- a/src/main/stanza/verilog.stanza +++ b/src/main/stanza/verilog.stanza @@ -116,7 +116,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 +177,7 @@ defn emit-module (m:InModule) : val inst-ports = HashTable>(symbol-hash) val sh = get-sym-hash(m) + val rand-value = "0" for x in vdecs do : val sym = key(x) @@ -196,11 +197,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 +223,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()) add(my-clk-update,[name(index*) " <= " emit(index(s)) ";"]) updates[get-name(clock(mem-declaration))] = my-clk-update -- cgit v1.2.3 From 0c7aca561aef907314b0d9c9737fcea04ae6ce82 Mon Sep 17 00:00:00 2001 From: Adam Izraelevitz Date: Tue, 28 Jul 2015 13:29:55 -0700 Subject: Integrated bigint. Mostly works, but getting "cast" error for make Test. --- src/main/stanza/bigint.stanza | 424 ++++++++++++++++++++++++++++++++ src/main/stanza/custom-passes.stanza | 7 +- src/main/stanza/errors.stanza | 3 +- src/main/stanza/firrtl-ir.stanza | 7 +- src/main/stanza/firrtl-lexer.stanza | 12 +- src/main/stanza/firrtl-test-main.stanza | 1 + src/main/stanza/flo.stanza | 6 +- src/main/stanza/ir-parser.stanza | 26 +- src/main/stanza/passes.stanza | 17 +- src/main/stanza/verilog.stanza | 4 +- 10 files changed, 472 insertions(+), 35 deletions(-) create mode 100644 src/main/stanza/bigint.stanza (limited to 'src') diff --git a/src/main/stanza/bigint.stanza b/src/main/stanza/bigint.stanza new file mode 100644 index 00000000..f5122323 --- /dev/null +++ b/src/main/stanza/bigint.stanza @@ -0,0 +1,424 @@ +defpackage bigint : + import core + import verse + + +public defn to-hex (num: Int) -> String : + val buf = StringBuffer() + print(buf, "0x") + var rems = List() + var x : Int = num + defn* loop () : + rems = List(x % 16, rems) + x = x / 16 + if x > 0: loop() + loop() + for r in rems do : + print(buf, to-char((to-int('0') + r) when r < 10 else (to-int('a') + r - 10))) + to-string(buf) + + +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 ;val-n-bits +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) : val-all-ones >> (32 - n) + +public defclass BigInt <: Gettable & Settable & Lengthable +public defmulti to-bin (b: BigInt) -> String +public defmulti num-words (b: BigInt) -> Int +public defmulti dat (b: BigInt) -> Array +public defn BigInt (len: Int) : + val d = Array(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) ;val-all-ones + defmethod dat (this) -> Array : d + defmethod length (this) -> Int : len + defmethod num-words (this) -> Int : length(d) + defmethod to-bin (this) -> String : + string-join $ + generate : + 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) : + var s = "" + for x in d do : s = string-join([x s]) + s + ;defmethod to-string (this) : string-join(["BigInt<" len ">(" to-bin(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] = val-all-ones + 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-n-bits + val bi = s % 32 ;val-n-bits + 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 : + 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? + +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) + +public defn BigIntLit (f: (Int) -> Int, len: Int) : + fill!(f, BigInt(len)) + +;val hex-nibbles = "0123456789abcdef" + +defn as-digit (c: Char) -> Int : + var index = 0 + for (x in "0123456789abcdef", i in 0 to false) do : + if x == c: index = i + index + ;val x = index-of(hex-nibbles, c) + ;x as Int + +public defn BigIntLit (s: String) : BigIntLit(s, -1) + +;public defn BigIntLit (i: Int) : BigIntLit(string-join(["x" to-hex(to-string(i))])) + +public defn BigIntLit (s: String, w:Int) : + val hd = s[0] + val base = if hd == 'b': 1 else if hd == 'x': 4 else: 'd' + val shamt = if base == 'b': 1 else if base == 'x': 4 else: 4 + val digits = if base == 'b': substring(s, 1) else if base == 'x': substring(s, 1) else: s + val len = if w == -1: length(digits) * shamt else: w + println-all(["STRING " s]) + println-all(["BASE " base " SHAMT " shamt " DIGITS " digits " LEN " len]) + var lit = BigInt(len) + for i in 0 to num-words(lit) do : + lit[i] = 0 + + + switch {base == _} : + 'd' : + for i in 0 to length(digits) do : + val y = shift-left(lit,3) + shift-left(lit,1) + val x = to-int(substring(digits,i,i + 1)) + val z = BigInt(length(y)) + z[0] = x + lit = y + z + println-all(["DIGIT = " x]) + println-all(["Before LIT = " lit]) + + ;println-all(["After LIT = " lit]) + ;println-all(["RES = " to-bin(lit)]) + ;println-all(["RES = " lit]) + lit + else : + for i in 0 to length(digits) do : + val off = (length(digits) - 1 - i) * shamt + val wi = off / 32;val-n-bits + val bi = off % 32;val-n-bits + ;println-all(["OFF " off " wi " wi " bi " bi " digits " digits]) + lit[wi] = lit[wi] | ((as-digit(digits[i]) & 1) << bi) + ;println-all([" lit[wi] " lit[wi] " => " lit]) + ;println-all(["RES = " to-bin(lit)]) + ;println-all(["RES = " lit]) + lit + +public defn sizeof (in: Int) -> Int : + max(1, ceil-log2(in + 1)) + +public defn BigIntLit (x: Int, w: Int) : + fill!({_ + x}, BigInt(w)) + +public defn BigIntLit (x: Int) : BigIntLit(x, sizeof(x)) + +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 : + 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-bits + val n-shift-words = amount / 32;val-n-bits + val n-rev-shift-bits = 32 - n-shift-bits;val-n-bits + val is-zero-carry = n-shift-bits == 0 + val msb = s0[nw - 1] >> (w - nw * 32 - 1);val-n-bits + 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 * val-n-bits + if idx > boundary : + d[i] = val-all-ones + loop(i - 1) + else : + d[i] = d[i] | (val-all-ones << (boundary - idx)) + d[nw - 1] = d[nw - 1] & (val-all-ones >> ((nw - 1) * val-n-bits - 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 % val-n-bits + val n-shift-words = amount / val-n-bits + val n-rev-shift-bits = val-n-bits - 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 % val-n-bits + val n-shift-words = amount / val-n-bits + val n-rev-shift-bits = val-n-bits - 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 " val-n-bits " 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(d); +;; half-val-t* u = reinterpret-cast(s0); +;; half-val-t* v = reinterpret-cast(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("xfafa") << 16, BigIntLit("xfafa0000", 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(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 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("0") : 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..8ee90f68 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 : @@ -287,11 +288,12 @@ defn eat-number () : (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)) + token-eaten(Token(BigIntLit(str),info)) + ;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 defn eat-here-string () : diff --git a/src/main/stanza/firrtl-test-main.stanza b/src/main/stanza/firrtl-test-main.stanza index beb288b1..a5050c47 100644 --- a/src/main/stanza/firrtl-test-main.stanza +++ b/src/main/stanza/firrtl-test-main.stanza @@ -13,6 +13,7 @@ #include("compilers.stanza") #include("flo.stanza") #include("verilog.stanza") +#include("bigint.stanza") ;Custom Packages #include("custom-passes.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, 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..44b51f30 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 : @@ -88,6 +89,9 @@ defsyntax firrtl : ;Parses next form if symbol sym = (?x) when unwrap-token(x) typeof Symbol : unwrap-token(x) + + bigint = (?x) when unwrap-token(x) typeof BigInt : + unwrap-token(x) ;Error Handling Productions defrule : @@ -107,6 +111,10 @@ defsyntax firrtl : =! = (=) : `= =! != () : FPE(form, "Expected a '=' here.") + ;Error if not a single bigint + bigint$ = (?i:#bigint ?rest ...) when empty?(rest) : i + bigint$ != () : FPE(form, "Expected a single big integer literal here.") + ;Error if not a single integer int$ = (?i:#int ?rest ...) when empty?(rest) : i int$ != () : FPE(form, "Expected a single integer literal here.") @@ -191,7 +199,7 @@ defsyntax firrtl : type = (?t:#typeterm ?ops:#typeop ...) : apply-suffix-ops(t, ops) type = (?t:#clktype) : t - typeop = ((@get ?size:#int$)) : (fn (t) : VectorType(t, size)) + typeop = ((@get ?size:#bigint$)) : (fn (t) : VectorType(t, size[0])) typeterm = (?t:#inttype) : t typeterm = ({?fs:#field ... ?rest ...}) : @@ -210,10 +218,10 @@ defsyntax firrtl : accdir = (rdwr) : RDWR defrule width : - width = (?x:#intorlong) : - match(x) : - (x:Int) : IntWidth(x) - (x:Long) : LongWidth(x) + width = (?x:#bigint) : + if num-words(x) == 1 : IntWidth(x[0]) + else if num-words(x) == 2 : LongWidth(to-long(x[1]) * to-long(1 << 32) + to-long(x[0])) + else : IntWidth(x[0]) width = (?) : UnknownWidth() ;Main Statement Productions @@ -253,20 +261,20 @@ defsyntax firrtl : defrule exp : ;Suffix Operators exp = (?x:#expterm ?ops:#expop ...) : apply-suffix-ops(x, ops) - expop = ((@get ?f:#int)) : (fn (x) : Index(x, f, UnknownType())) + expop = ((@get ?f:#bigint)) : (fn (x) : Index(x, f[0], UnknownType())) expop = (. ?f:#id!) : (fn (x) : Subfield(x, f, UnknownType())) ;Prefix Operators - expterm = (?t:#inttype(?v:#long$)) : + expterm = (?t:#inttype(?v:#bigint$)) : match(t) : (t:UIntType) : UIntValue(v, width(t)) (t:SIntType) : SIntValue(v, width(t)) - expterm = (?op:#sym(?es:#exp ... ?ints:#int ... ?rest ...)) : + expterm = (?op:#sym(?es:#exp ... ?ints:#bigint ... ?rest ...)) : if not empty?(rest) : FPE(rest, "Illegal operands to primitive operator.") match(primop(op)) : - (p:PrimOp) : DoPrim(p, es, ints, UnknownType()) + (p:PrimOp) : DoPrim(p, es, map(get{_,0},ints), UnknownType()) (p:False) : FPE(form, "Unrecognized primitive operator '~'." << [op]) expterm = (?op:#sym) : Ref(op, UnknownType()) diff --git a/src/main/stanza/passes.stanza b/src/main/stanza/passes.stanza index 33ef666c..255354a3 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) -> 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),UnknownWidth())), Connect(info(s),l,exp(s)), EmptyStmt() ) @@ -1164,7 +1165,7 @@ defn expand-connect-indexed-stmt (s: Stmt,sh:HashTable) -> 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),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("b0"),IntWidth(1)) +val one = UIntValue(BigIntLit("b1"),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 == UIntValue(BigIntLit("b1"),UnknownWidth()) : 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 == UIntValue(BigIntLit("b1"),UnknownWidth()) : 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, v:Vector) -> 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 6d9e2962..d39c89e4 100644 --- a/src/main/stanza/verilog.stanza +++ b/src/main/stanza/verilog.stanza @@ -65,8 +65,8 @@ defn emit-signed-if-any (e:Expression,ls:List) -> 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) : string-join $ [width!(type(e)) "'" value(e)] + (e:SIntValue) : string-join $ [width!(type(e)) "'s" value(e)] (e:Subfield) : error("Non-supported expression") (e:Index) : error("Non-supported expression") (e:DoPrim) : -- cgit v1.2.3 From 6ce20db7e2f81cd3ef8f859614f423bea897484b Mon Sep 17 00:00:00 2001 From: Adam Izraelevitz Date: Wed, 29 Jul 2015 11:22:02 -0700 Subject: Add bigint support. --- src/main/stanza/bigint.stanza | 173 +++++++++++++------------------- src/main/stanza/firrtl-lexer.stanza | 6 +- src/main/stanza/firrtl-test-main.stanza | 2 +- src/main/stanza/ir-parser.stanza | 29 +++--- src/main/stanza/verilog.stanza | 10 +- 5 files changed, 97 insertions(+), 123 deletions(-) (limited to 'src') diff --git a/src/main/stanza/bigint.stanza b/src/main/stanza/bigint.stanza index f5122323..7d8e6426 100644 --- a/src/main/stanza/bigint.stanza +++ b/src/main/stanza/bigint.stanza @@ -2,45 +2,45 @@ defpackage bigint : import core import verse - -public defn to-hex (num: Int) -> String : - val buf = StringBuffer() - print(buf, "0x") - var rems = List() - var x : Int = num - defn* loop () : - rems = List(x % 16, rems) - x = x / 16 - if x > 0: loop() - loop() - for r in rems do : - print(buf, to-char((to-int('0') + r) when r < 10 else (to-int('a') + r - 10))) - to-string(buf) - - 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 ;val-n-bits +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) : val-all-ones >> (32 - n) +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 public defn BigInt (len: Int) : val d = Array(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) ;val-all-ones + defmethod set (this, i: Int, x: Int) : d[i] = x & -1 defmethod dat (this) -> Array : 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 : @@ -49,11 +49,8 @@ public defn BigInt (len: Int) : yield(if (d[pos / 32] >> (pos % 32))&1 == 1: '1' else: '0') loop(pos - 1) loop(len - 1) - defmethod to-string (this) : - var s = "" - for x in d do : s = string-join([x s]) - s ;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)) @@ -78,7 +75,7 @@ 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] = val-all-ones + d[i] = -1 for i in n-full-words to num-words(d) do : d[i] = 0 if n-word-bits > 0 : @@ -97,8 +94,8 @@ defn extract! (d:BigInt, s0:BigInt, e:Int, s:Int) -> BigInt : trim!(rsh!(d, s0, 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-n-bits - val bi = s % 32 ;val-n-bits + val wi = s / 32 + val bi = s % 32 s0[wi] >> bi defn inject! (d:BigInt, s0:BigInt, f:BigInt, start:Int) -> BigInt : @@ -151,71 +148,41 @@ public defn greater-eq?! (diff:BigInt, x:BigInt, y:BigInt) -> True|False : not l 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)) -;val hex-nibbles = "0123456789abcdef" +public defn BigIntLit (x: Int, w: Int) : + fill!({_ + x}, BigInt(w)) -defn as-digit (c: Char) -> Int : - var index = 0 - for (x in "0123456789abcdef", i in 0 to false) do : - if x == c: index = i - index - ;val x = index-of(hex-nibbles, c) - ;x as Int +public defn BigIntLit (x: Int) : BigIntLit(x, sizeof(x)) public defn BigIntLit (s: String) : BigIntLit(s, -1) -;public defn BigIntLit (i: Int) : BigIntLit(string-join(["x" to-hex(to-string(i))])) - public defn BigIntLit (s: String, w:Int) : - val hd = s[0] - val base = if hd == 'b': 1 else if hd == 'x': 4 else: 'd' - val shamt = if base == 'b': 1 else if base == 'x': 4 else: 4 - val digits = if base == 'b': substring(s, 1) else if base == 'x': substring(s, 1) else: s + 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 - println-all(["STRING " s]) - println-all(["BASE " base " SHAMT " shamt " DIGITS " digits " LEN " len]) - var lit = BigInt(len) + val lit = BigInt(len) + ;; println-all(["BASE " base " SHAMT " shamt " DIGITS " digits]) for i in 0 to num-words(lit) do : lit[i] = 0 - - - switch {base == _} : - 'd' : - for i in 0 to length(digits) do : - val y = shift-left(lit,3) + shift-left(lit,1) - val x = to-int(substring(digits,i,i + 1)) - val z = BigInt(length(y)) - z[0] = x - lit = y + z - println-all(["DIGIT = " x]) - println-all(["Before LIT = " lit]) - - ;println-all(["After LIT = " lit]) - ;println-all(["RES = " to-bin(lit)]) - ;println-all(["RES = " lit]) - lit - else : - for i in 0 to length(digits) do : - val off = (length(digits) - 1 - i) * shamt - val wi = off / 32;val-n-bits - val bi = off % 32;val-n-bits - ;println-all(["OFF " off " wi " wi " bi " bi " digits " digits]) - lit[wi] = lit[wi] | ((as-digit(digits[i]) & 1) << bi) - ;println-all([" lit[wi] " lit[wi] " => " lit]) - ;println-all(["RES = " to-bin(lit)]) - ;println-all(["RES = " lit]) - lit + 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 : + println(in) max(1, ceil-log2(in + 1)) -public defn BigIntLit (x: Int, w: Int) : - fill!({_ + x}, BigInt(w)) - -public defn BigIntLit (x: Int) : BigIntLit(x, sizeof(x)) - defn op (f:(BigInt, BigInt, BigInt) -> True|False, x:BigInt, y:BigInt) -> True|False : f(BigInt(max(length(x), length(y))), x, y) @@ -273,11 +240,11 @@ 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-bits - val n-shift-words = amount / 32;val-n-bits - val n-rev-shift-bits = 32 - n-shift-bits;val-n-bits + 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);val-n-bits + val msb = s0[nw - 1] >> (w - nw * 32 - 1) var carry = 0; if msb == 0 : @@ -297,13 +264,13 @@ public defn rsha! (d:BigInt, s0:BigInt, amount:Int) -> BigInt : defn* loop (i:Int) : if i >= 0 : - val idx = i * val-n-bits + val idx = i * 32 if idx > boundary : - d[i] = val-all-ones + d[i] = -1 loop(i - 1) else : - d[i] = d[i] | (val-all-ones << (boundary - idx)) - d[nw - 1] = d[nw - 1] & (val-all-ones >> ((nw - 1) * val-n-bits - w)) + d[i] = d[i] | (-1 << (boundary - idx)) + d[nw - 1] = d[nw - 1] & (-1 >> ((nw - 1) * 32 - w)) loop(nw - 1) d @@ -312,9 +279,9 @@ public defn signed-shift-right (b:BigInt, n:Int) -> BigInt : rsha!(BigInt(length public defn rsh! (d:BigInt, s0:BigInt, amount:Int) -> BigInt : val nw = num-words(d) var carry = 0 - val n-shift-bits = amount % val-n-bits - val n-shift-words = amount / val-n-bits - val n-rev-shift-bits = val-n-bits - n-shift-bits + 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 @@ -331,14 +298,14 @@ public defn shift-right (b:BigInt, n:Int) -> BigInt : rsh!(BigInt(length(b)), b, public defn lsh! (d:BigInt, s0:BigInt, amount:Int) : ;; println-all(["LSH " s0 " AMOUNT " amount " INTO BIGINT<" length(d) ">"]) - val n-shift-bits = amount % val-n-bits - val n-shift-words = amount / val-n-bits - val n-rev-shift-bits = val-n-bits - n-shift-bits + 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 " val-n-bits " NSB " n-shift-bits " NSW " n-shift-words " NRSB " n-rev-shift-bits]) + ;; 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)]) @@ -410,15 +377,15 @@ defn check (msg:String, x:BigInt) : ;; 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("xfafa") << 16, BigIntLit("xfafa0000", 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")) +check("S1 ", BigIntLit("xfafa") << 16, BigIntLit("xfafa0000", 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/firrtl-lexer.stanza b/src/main/stanza/firrtl-lexer.stanza index 8ee90f68..7581b26c 100644 --- a/src/main/stanza/firrtl-lexer.stanza +++ b/src/main/stanza/firrtl-lexer.stanza @@ -287,14 +287,14 @@ defn eat-number () : match(to-float(str)) : (f:Float) : token-eaten(Token(f, info)) (f:False) : throw(InvalidNumber(info)) - else : - token-eaten(Token(BigIntLit(str),info)) + 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)) - ;else : token-eaten(Token(to-int(str), info)) <- ADAM CHANGE, FROM THIS 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 a5050c47..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") @@ -13,7 +14,6 @@ #include("compilers.stanza") #include("flo.stanza") #include("verilog.stanza") -#include("bigint.stanza") ;Custom Packages #include("custom-passes.stanza") diff --git a/src/main/stanza/ir-parser.stanza b/src/main/stanza/ir-parser.stanza index 44b51f30..b0ab8652 100644 --- a/src/main/stanza/ir-parser.stanza +++ b/src/main/stanza/ir-parser.stanza @@ -82,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) @@ -90,9 +93,6 @@ defsyntax firrtl : sym = (?x) when unwrap-token(x) typeof Symbol : unwrap-token(x) - bigint = (?x) when unwrap-token(x) typeof BigInt : - unwrap-token(x) - ;Error Handling Productions defrule : ;Error if not an identifier @@ -111,10 +111,6 @@ defsyntax firrtl : =! = (=) : `= =! != () : FPE(form, "Expected a '=' here.") - ;Error if not a single bigint - bigint$ = (?i:#bigint ?rest ...) when empty?(rest) : i - bigint$ != () : FPE(form, "Expected a single big integer literal here.") - ;Error if not a single integer int$ = (?i:#int ?rest ...) when empty?(rest) : i int$ != () : FPE(form, "Expected a single integer literal here.") @@ -199,7 +195,7 @@ defsyntax firrtl : type = (?t:#typeterm ?ops:#typeop ...) : apply-suffix-ops(t, ops) type = (?t:#clktype) : t - typeop = ((@get ?size:#bigint$)) : (fn (t) : VectorType(t, size[0])) + typeop = ((@get ?size:#int$)) : (fn (t) : VectorType(t, size[0])) typeterm = (?t:#inttype) : t typeterm = ({?fs:#field ... ?rest ...}) : @@ -218,7 +214,7 @@ defsyntax firrtl : accdir = (rdwr) : RDWR defrule width : - width = (?x:#bigint) : + width = (?x:#int) : if num-words(x) == 1 : IntWidth(x[0]) else if num-words(x) == 2 : LongWidth(to-long(x[1]) * to-long(1 << 32) + to-long(x[0])) else : IntWidth(x[0]) @@ -261,16 +257,21 @@ defsyntax firrtl : defrule exp : ;Suffix Operators exp = (?x:#expterm ?ops:#expop ...) : apply-suffix-ops(x, ops) - expop = ((@get ?f:#bigint)) : (fn (x) : Index(x, f[0], UnknownType())) + expop = ((@get ?f:#int)) : (fn (x) : Index(x, f[0], UnknownType())) expop = (. ?f:#id!) : (fn (x) : Subfield(x, f, UnknownType())) ;Prefix Operators - expterm = (?t:#inttype(?v:#bigint$)) : + 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(abs(v as Int)), width(t)) + (t:SIntType) : SIntValue(BigIntLit(v as Int), width(t)) - expterm = (?op:#sym(?es:#exp ... ?ints:#bigint ... ?rest ...)) : + expterm = (?op:#sym(?es:#exp ... ?ints:#int ... ?rest ...)) : if not empty?(rest) : FPE(rest, "Illegal operands to primitive operator.") match(primop(op)) : diff --git a/src/main/stanza/verilog.stanza b/src/main/stanza/verilog.stanza index d39c89e4..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) -> String : defn emit (e:Expression) -> String : match(e) : (e:Ref) : to-string $ name(e) - (e:UIntValue) : string-join $ [width!(type(e)) "'" value(e)] - (e:SIntValue) : string-join $ [width!(type(e)) "'s" 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) : -- cgit v1.2.3 From 7646c2e3edf90ea13a83b76c97f35877263c5e63 Mon Sep 17 00:00:00 2001 From: Adam Izraelevitz Date: Wed, 29 Jul 2015 15:00:37 -0700 Subject: Finished supporting Chisel 2.0 Ref Chip --- src/main/stanza/bigint.stanza | 26 +++++++++++++++----------- src/main/stanza/errors.stanza | 2 +- src/main/stanza/ir-parser.stanza | 15 ++++++--------- src/main/stanza/passes.stanza | 12 ++++++------ 4 files changed, 28 insertions(+), 27 deletions(-) (limited to 'src') diff --git a/src/main/stanza/bigint.stanza b/src/main/stanza/bigint.stanza index 7d8e6426..427ad7ff 100644 --- a/src/main/stanza/bigint.stanza +++ b/src/main/stanza/bigint.stanza @@ -118,15 +118,18 @@ defn fill! (f: (Int) -> Int, b: BigInt) : b public defmethod equal? (x:BigInt, y:BigInt) -> True|False : - 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? + 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) @@ -180,7 +183,6 @@ public defn BigIntLit (s: String, w:Int) : lit public defn sizeof (in: Int) -> Int : - println(in) max(1, ceil-log2(in + 1)) defn op (f:(BigInt, BigInt, BigInt) -> True|False, x:BigInt, y:BigInt) -> True|False : @@ -377,7 +379,9 @@ defn check (msg:String, x:BigInt) : ;; 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("xfafa") << 16, BigIntLit("xfafa0000", 32)) +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)) diff --git a/src/main/stanza/errors.stanza b/src/main/stanza/errors.stanza index 80ad3e56..6cdd1dca 100644 --- a/src/main/stanza/errors.stanza +++ b/src/main/stanza/errors.stanza @@ -278,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) < BigIntLit("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/ir-parser.stanza b/src/main/stanza/ir-parser.stanza index b0ab8652..fdf4c383 100644 --- a/src/main/stanza/ir-parser.stanza +++ b/src/main/stanza/ir-parser.stanza @@ -195,7 +195,7 @@ defsyntax firrtl : type = (?t:#typeterm ?ops:#typeop ...) : apply-suffix-ops(t, ops) type = (?t:#clktype) : t - typeop = ((@get ?size:#int$)) : (fn (t) : VectorType(t, size[0])) + typeop = ((@get ?size:#int$)) : (fn (t) : VectorType(t, size)) typeterm = (?t:#inttype) : t typeterm = ({?fs:#field ... ?rest ...}) : @@ -214,10 +214,7 @@ defsyntax firrtl : accdir = (rdwr) : RDWR defrule width : - width = (?x:#int) : - if num-words(x) == 1 : IntWidth(x[0]) - else if num-words(x) == 2 : LongWidth(to-long(x[1]) * to-long(1 << 32) + to-long(x[0])) - else : IntWidth(x[0]) + width = (?x:#int) : IntWidth(x) width = (?) : UnknownWidth() ;Main Statement Productions @@ -257,7 +254,7 @@ defsyntax firrtl : defrule exp : ;Suffix Operators exp = (?x:#expterm ?ops:#expop ...) : apply-suffix-ops(x, ops) - expop = ((@get ?f:#int)) : (fn (x) : Index(x, f[0], UnknownType())) + expop = ((@get ?f:#int)) : (fn (x) : Index(x, f, UnknownType())) expop = (. ?f:#id!) : (fn (x) : Subfield(x, f, UnknownType())) ;Prefix Operators @@ -268,14 +265,14 @@ defsyntax firrtl : expterm = (?t:#inttype(?v:#int$)) : match(t) : - (t:UIntType) : UIntValue(BigIntLit(abs(v as Int)), width(t)) - (t:SIntType) : SIntValue(BigIntLit(v as Int), 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) : FPE(rest, "Illegal operands to primitive operator.") match(primop(op)) : - (p:PrimOp) : DoPrim(p, es, map(get{_,0},ints), UnknownType()) + (p:PrimOp) : DoPrim(p, es, ints, UnknownType()) (p:False) : FPE(form, "Unrecognized primitive operator '~'." << [op]) expterm = (?op:#sym) : Ref(op, UnknownType()) diff --git a/src/main/stanza/passes.stanza b/src/main/stanza/passes.stanza index 255354a3..db1a056e 100644 --- a/src/main/stanza/passes.stanza +++ b/src/main/stanza/passes.stanza @@ -1151,7 +1151,7 @@ defn expand-connect-indexed-stmt (s: Stmt,sh:HashTable) -> Stmt : to-list $ for (i in 0 to false, l in locs(s)) stream : Conditionally( info(s), - equality(ref,UIntValue(BigIntLit(i),UnknownWidth())), + equality(ref,UIntValue(BigIntLit(i,32),UnknownWidth())), Connect(info(s),l,exp(s)), EmptyStmt() ) @@ -1165,7 +1165,7 @@ defn expand-connect-indexed-stmt (s: Stmt,sh:HashTable) -> Stmt : to-list $ for (i in 1 to false, e in tail(exps(s))) stream : Conditionally( info(s), - equality(ref,UIntValue(BigIntLit(i),UnknownWidth())), + equality(ref,UIntValue(BigIntLit(i,32),UnknownWidth())), Connect(info(s),loc(s),e), EmptyStmt() ) @@ -1211,8 +1211,8 @@ public defmethod short-name (b:ExpandWhens) -> String : "expand-whens" ; ======== Expression Computation Library =========== -val zero = UIntValue(BigIntLit("b0"),IntWidth(1)) -val one = UIntValue(BigIntLit("b1"),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) : @@ -1548,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(BigIntLit("b1"),UnknownWidth()) : + if en == one : add{cons,_} $ Connect(info(s),ref,e) else : add{cons,_} $ Conditionally(info(s),en,Connect(info(s),ref,e),EmptyStmt()) @@ -1563,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(BigIntLit("b1"),UnknownWidth()) : + if en == one : add{cons,_} $ Connect(info(s),ref,e) else : add{cons,_} $ Conditionally(info(s),en,Connect(info(s),ref,e),EmptyStmt()) -- cgit v1.2.3