if (a) b = c; d = b + e; if (q) d = 22; |
b <= (a) ? c : b; d <= q ? 22 : ((a) ? c : b) + e; |
v <= (a) ? 0: (v>>1) |
v[0] <= (a[0]|a[1]) ? 0: v[1]; v[1] <= (a[0]|a[1]) ? 0: v[2]; v[2] <= 0; |
When generating gates a target technology cell library needs to be read in by the logic synthesiser. Likewise, when generating FPGA logic, the details of the CLBs and limitations of the programmable wiring need to be known by the logic synthesiser.
Further detail on selected constructs:
1. How can we make a simple adder ?
The following ML fragment will make a ripple carry adder from lsb-first lists of nets:
fun add c (nil, nil) = [c] | add c (a::at, b::bt) = let val s = gen_xor(a, b) val c1 = gen_and(a, b) val c2 = gen_and(s, c) in (gen_xor(s, c))::(add (gen_or(c2, c1)) (at, bt)) end
2. Can general division be bit-blasted ? Yes, and for some constants it is quite simple.
For instance, division by a constant value of 8 needs no gates - you just need wiring!
For dynamic shifts make a barrel shifter using a succession of broadside multiplexors, each operated by a different bit of the shifting expression.
See link »Barrel Shifter, ML fragment.
3. Can we do better for constant divisors? To divide by a constant 10 you can use that 8/10 is 0.11001100 recurring, so if n and q are 32 bit unsigned registers, the following computes n/10:
q = (n >> 1) + (n >> 2); q += (q >> 4); q += (q >> 8); q += (q >> 16); return q>>3;
21: (C) 2008-18, DJ Greaves, University of Cambridge, Computer Laboratory. | Flash Player Upgrade Needed ![]() ![]() | ![]() |