/* BITSTREAM.PL */ /* This program demonstrates how to use Prolog to simulate digital circuits. In effect, this is a demonstration of how to implement another logical system in Prolog. Circuit layout is specified by naming the wires between components. In the example below, these names are a, b, c, d, x, y. The dynamic behaviour of a circuit is given by specifying the voltage levels on the wires, as a series of clauses for 'spec': spec( W, Expression ): The voltage on wire W has the value given by Expression. The syntax of expressions: Expression ::= Expression + Expression Expression ::= Expression - Expression Expression ::= Primitive Primitive ::= Number Primitive ::= Wire Primitive ::= Wire lag Time A primitive which is a wire name denotes the voltage on that wire in the current clock cycle. A primitive of the form (wire lag time) denotes the voltage on that wire 'time' cycles ago. 'time' must be a number. You can have conditional clauses of the form spec( W, Expression ) if Condition When looking for a value for W, the system will evaluate Condition, and only use the clause for spec if it is true. Make sure you have enough conditions to cover all cases. The Condition is two Expressions compared by one of =, \=, >, <, >=, =<. To specify initial values, use 'init': init( W, Time, Number ) means that wire W has voltage Number at time T. To use the simulator, call eval_wire( W+, Time+, V- ) which will give the value on W at Time, or run( W+ ) which will display a sequence of values for W. Note: it does not check for inconsistencies. */ /* Define 'lag' and 'if' for the specification clauses. */ :- op( 10, xfx, lag ). :- op( 255, xfx, if ). /* signal( W+, Time+, V- ): Succeeds if there is a spec clause for W at time T, in which case value is V. Otherwise fails. */ signal( Wire, _, V ) :- clause( spec( Wire, V ), true ), !. signal( Wire, N, V ) :- clause( (spec( Wire, V ) if Cond), true ), eval_cond( Cond, N ), !. /* eval_cond( Cond+, Time+ ): Succeeds if Cond is true at Time, otherwise fails. */ eval_cond( A>B, N ) :- !, eval_expr( A, N, VA ), eval_expr( B, N, VB ), VA > VB. eval_cond( A>=B, N ) :- !, eval_expr( A, N, VA ), eval_expr( B, N, VB ), VA >= VB. eval_cond( A 0. spec( c, 0 ) if b =< 0. spec( y, c lag 1 ). spec( d, 1 ) if y = 1. spec( d, -1 ) if y = 0. init( d, 1, 0 ). init( b, 0, 0 ). test :- go( c ).