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; |
(The details of the algorithms on these links and being able to reproduce them is not examinable but being able to draw the gate-level circuit for a few lines of RTL is examinable).
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-16, DJ Greaves, University of Cambridge, Computer Laboratory. | Flash Player Upgrade Needed ![]() ![]() | ![]() |