// This Jazz&Rhythm&Blues tutorial provides an example // of (virtual) circuit design, simulation and test. // Chosen example is the sec/mn counter in a digital watch. import jazz.circuit.*; import jazz.circuit.Net.*; // Put 2 devices on a test board: gen1net and babylon. device gen1net { output incr:Net; // communication between devices thru wire incr // Jazz synthesizes sequencial logic from periodic binary sequences incr = constant(#1011001111110(1)); // input test sequence, reasonable here } // This device is compiled into the netlist gen1net.jzn export gen1net(); // gen1net can generates input for a single input devices, such as cm60. // the name of the single input on the other device must also be incr, // if we want to simulate both together: connections between devices // for the Blues simulator are made thru the names given to external IOs. device babylon { input incr:Net; output u4:Net[4], d4:Net[4], // decimal coded binary u7:Net[7], d7:Net[7], // 7 segments display incr59:Net; // counter will reset to 0 on next cycle (u4, d4, incr9, incr59) = cm60(incr); // count mod 60 u7 = decode7segs(u4); d7 = decode7segs(d4); // although net incr9 is not an output from the device, we // want to see its values, while debugging thru simulation @Debug.probe(incr9, "incr9"); } // This device is compiled into the netlist babylon.jzn export babylon(); // counter modulo 60, from the Babylonians fun cm60(incr:Net) = (u:Net[4], d:Net[4], // Decimal Coded Binary incr9:Net, // u=9, and incr incr59:Net) // u+10d=59, and incr { (u, incr9) = countMod(10)(incr); // counter modulo 10 (d', incr59)= countMod(6)(incr9); // counter modulo 6 d[0..2]=d'; d[3]=constant(0); // extend to 4 bits } // Binary n bit counter fun counter(n:int)(incr:Net) = (sum:Net[n], ovfl:Net){ for (k<n) // n half-adders, and sum registers (sum[k], carry[k+1]) = (reg(sum[k]^carry[k]), sum[k]&carry[k]); ovfl = carry[n]; // incr when Sum=2**n-1 carry[0] = incr; } fun even(p) = (0 == p.bit(0)); fun odd(p) = (1 == p.bit(0)); // Counter modulo m fun countMod(m:int)(incr:Net) = (sum:Net[], ovfl:Net) { assert(m>1); // Counters modulo 0 or 1 are not allowed if (m==2) // a counter, modulo 2, (sum, ovfl) = counter(1)(incr); // is a 1 bit binary counter else if (even(m)) { // to count modulo 2m', (sum[0..0], c1) = counter(1)(incr); // count modulo 2, (sum[1..], ovfl) = countMod(m div 2)(c1); // and modulo m' } else { // count modulo an odd number 1+2m' n = (m-1).prefixLength(); // number of bits in counter (sum, _) = reset(counter(n)(incr), ovfl); // reset to 0 // when the counter gets incremented from the value sum=m-1. ovfl = incr & subset(m-1)(sum); } // Test if sum(s[k]2**k) is equal to n fun subset(n:int)(s:Net[]) = result:Net { // result = AND{s[k]: n##k=1} = 1 iff n subset S result = (n==1) ? s[0] : even(n) ? r2 : s[0] & r2; r2 = subset(n div 2)(s[1..]); } } // This circuit was obtained thru BDD synthesis from Truth Tables fun decode7segs(b:Net[4]) = s:Net[7] { // Shared expressions, over 1 bit input b[0] z = constant(0); // (0) u = constant(-1); // (1) n = ~ b[0]; // 10 = ~ b[0] // Shared expressions, over 2 bits input b[0..1] d1 = mux(b[1],z,n); // 1000 = ~(b[0] | b[1]) d2 = mux(b[1],n,u); // 1110 = ~(b[0] & b[1]) d3 = mux(b[1],n,z); // 0010 = ~ b[0] & b[1] d4 = mux(b[1],u,n); // 1011 = ~ b[0] | b[1] d5 = mux(b[1],n,b[0]); // 0110 = b[0] ^ b[1] d6 = mux(b[1],b[0],u); // 1101 = ~ b[1] | b[0] d7 = mux(b[1],b[0],n); // 1001 = ~(b[0] ^ b[1]) d8 = mux(b[1],u,b[0]); // 0111 = b[0] | b[1] // Shared expressions, over 3 bits input b[0..2] t1 = mux(b[2],d2,d1); // 1000 1110 t2 = mux(b[2],d2,b[1]); // 0011 1110 t3 = mux(b[2],d5,d4); // 1011 0110 t4 = mux(b[2],u,d6); // 1101 1111 t5 = mux(b[2],d7,u); // 1111 1001 t6 = mux(b[2],d8,d4); // 1011 0111 t7 = mux(b[2],d3,n); // 1010 0010 // 7 segments output from decoder, with truth tables s[0] = mux(b[3],u,t1); // 10001110 11111111 s[1] = mux(b[3],u,t2); // 00111110 11111111 s[2] = t7; // 10100010 10100010 s[3] = mux(b[3],u,t3); // 10110110 11111111 s[4] = mux(b[3],u,t4); // 11011111 11111111 s[5] = mux(b[3],u,t5); // 11111001 11111111 s[6] = mux(b[3],u,t6); // 10110111 11111111 }