REVERSIBLE GATES
3.5. SYNTHESIS OF REVERSIBLE LOGIC CIRCUITS BASED ON 2*3 SWITCHES USING PROLOG
3.5.2. EXHAUSTIVE SEARCH ALGORITHM
3.5.2.1. GATE GENERATION
For the synthesis of reversible gates, the Y-gates may be used either in a typical manner,
as depicted in Fig. 3.5.1, or in an inverted manner, as depicted in Fig. 3.5.2. Y-gates used
in a typical manner will be referred to as G-gates, as the number of output ‘grows’ or
increases with respect to the number of inputs. Likewise, Y-gates used in a reversed
manner will be referred to as R-gates, as the number of outputs is reduced with respect to
94 To construct desired reversible gates, outputs from certain Y-gates must feed into the
inputs of other Y-gates. An order for how the ports of Y-gates are connected is
established using a generator to create all possible combinations of gate orderings. A
user defined limit is established for the number of gates to be implemented.
There are also a number of limitations that apply to how the sequence of Y-gates must be
ordered:
(1) The sequence must begin with a G-gate, and must conclude with a R-gate.
(2) There must be equal number of G-gates and R-gates.
The gate generation is constructed by creating a tree. As the first gate must be a G-gate,
the head of the tree is a lone G-gate. A binary tree is formed as each level of the tree
creates two nodes from each previously existing node. One of the new nodes will have a
G-gate added in sequence behind it, while the other new node will have a R-gate added in
sequence behind it. The resulting tree is depicted below in Fig. 3.5.1. Each node on the
95 To explain in further detail, as previously discussed, a single G-gate, the root of the tree
is the first list. The root list of each tree, in this case the lone gate is the entire list and the
head, is taken and concatenated with a G-gate to make one child node, and concatenated
with an R-gate to make another child node. These children nodes are added to a new list.
The root list is then traversed, so the concatenation process that occurred with the original
root, now takes place with the next element in the list. This procedure takes place until
the entire list (node) has been traversed. Once the entire list has been traversed, the same
concatenation procedure is applied to the new list of nodes that were previously
considered children.
96 The code for generation of the binary tree is shown below, with the first line serving to
assure the appending process halts when the list is empty. The first argument of the
binary tree determines the number of Y-gates to be used. The clause append is a library
defined clause that concatenates the first two arguments of the rule to define the third
argument. binarytree(0,[],_,[],[]):-!. binarytree(N,Left,Root,Right,L):- N1 is N-1, append(Root,[g],Left), append(Root,[r],Right), binarytree(N1,_,Left,_,L0), binarytree(N1,_,Right,_,L1), append([Left|L0],[Right|L1],L).
As previously established, there must be an equal number of G-gates and R-gates. This
check is easily implemented by an established counter for the number of G-gates, and a
counter for the number of R-gates. Clause count, counts the number of occurrences of
its first argument in its second argument (a list), and stores the count as its third
argument.
97 applyconstraint([H|T],L):- count(g,H,N1), %count g count(r,H,N2), %count r applyconstraint(T,L0), is_equal(N1,N2,H,L0,L). 3.5.2.2. WIRE CONNECTIVITY
In the implemented Prolog program, the inputs to the Y-gates are no longer just single
bits, but lists. Boolean functions are defined that perform the desired operation on every
item in a list. Use of the Y-gates and reverse Y-gates requires the Boolean functions of
negation, conjunction and disjunction.
The argument Mask is a bit-string of all ‘1’s, used for exclusive disjunction with another
sting, to obtain the negation of that string.
applyF(and,Input1,Input2,Output):- Output is /\(Input1,Input2). applyF(or,Input1,Input2,Output):- Output is \/(Input1,Input2). applyF(negate,Mask,Input,NegatedInput):- NegatedInput is xor(Mask,Input).
98 The Y-gate and reverse Y-gate are constructed using Boolean functions, as well as the
clause different, which elsewhere defined, ensures its two arguments are not equivalent.
In this implementation, it specifically ensures the outputs are correctly ported to.
applyF(ygate,Mask,A,B,X,Y,Z):- X = A, applyF(negate,Mask,A,NA), applyF(and,NA,B,Y), applyF(and,A,B,Z), different(Y,0), different(Z,0). applyF(rygate,Mask,A,B,X,Y,Z):- A = X, applyF(or,Y,Z,B), applyF(ygate,Mask,A,B,X,Y,Z).
Input and output lists are comprised of unused Y-gate inputs and output ports. While the
program iterates through placing together all feasible connections, the used ports of the
99 In the code for the wire connection below, the special_delete clause deletes the input
from the input list or the output list, and updates whichever list was taken from.
Grow Function:- apply(g,Mask,Control,Input,Y,Z,InputList,OutputList,[X|NewInputList],[Y|[Z|New OutputList]]):- union(OutputList,InputList,InOutList), member(Input,InOutList), special_delete(Input,InputList,OutputList,NewInputList,NewOutputList), applyF(ygate,Mask,Control,Input,X,Y,Z).
If arguments Input,Y and Z are ignored, as they are solely utilized for circuit printing
purpose, the function shown above can be represented in the form:-
apply(g,Mask,Conrtol,InputList,OutputList,NewInputList,NewOutputList)
InputList and OutputList represent the wire connectivity before applying Ygate, and NewInputList and NewoutputList represent the wire after applying Ygate. Mask is simply passed to Ygate.
100 apply(r,Mask,Control,Y,Input1,Input2,InputList,OutputList,[X|InputList],[Y|New OutputList]):- member(Input1,OutputList), delete(OutputList,Input1,OutputList0), member(Input2,OutputList0), delete(OutputList0,Input2, NewOutputList), applyF(rygate,Mask,X,Y,Control,Input1,Input2).
Ignoring arguments Y, Input1, Input2 , as they are solely used for printing purpose, the
function is of similar form to the previously described Grow function.
apply(r,Mask, Conrtol,InputList,OutputList, NewInputList,NewOutputList)
The member function is used to select an element, while delete is used to delete an
element from the list.
As double-rail implementations require negation of input variables, inputs, variable H1 in
the code below, are taken and XORed with a bit string of ‘1’s to create the negated input
variable, NH1.
101 doublerail_inputs(Mask,[H1|T1],[H1|[NH1|L0]]):-
doublerail_inputs(Mask,T1,L0), applyF(negate,Mask,H1,NH1).
The above function is simply not incorporated into the synthesis of the single-rail
reversible circuits.
The syn function, shown below for the double-rail implementation, forms the heart of the
synthesis algorithm. The applyP function, defined elsewhere, takes the gate tree (pattern)
and attempts to satisfy the end goal.
synDR(NbOfVariables,NbOfYGates,Goal):- N is (((NbOfYGates-(NbOfYGates mod 2))/2)-1), get_pattern(N,[g],PatternList), all_ones_mask(NbOfVariables,Mask), vars_to_bitstring_ints(NbOfVariables,InputList0), doublerail_inputs(Mask,InputList0,InputList), member(P,PatternList), applyDP(P,Mask,InputList,[],Goal), print_variables(97,Mask,InputList0).
102 The single-rail synthesis function is identical, with the exception of the omission of the
doublerail_inputs function, and the declaration of N, which establishes the input pattern to be mirrored.