A logic circuit, consisting of gates, flipflops etc., performs boolean operations on it's input lines
and assigns the results to it's output lines. At the very basic level, a person desirous of simulating a
logic circuit will find it easy and intuitive to describe circuits at the gate level. As the circuits become
larger and more complex, gate level description of logic circuits becomes tedious and prone to errors.
We have seen in the previous chapter that one can build modules which model the actual gate-level circuit at
the behavioral level instead of laboriusly describing the circuit at the gate level. This way, one can test
the functionality of the logic circuit in a quick and easy way, and avoid errors. Similarly,
**data flow modelling** is another way of modelling circuits, using which one can build logic circuits in a
quick and easy way to test their functionality. Data flow modelling is at one level of abstraction higher
than gate level circuit description. As in Verilog, a powerfull concept called **continuous assignments**
facilitate data flow modelling in libLCS. In this chapter, we will learn about continuous assignments and the
constructs which one has to use in order to incorporate continuous assignments in libLCS.

Continuous assignments are equivalent to modules which encapuslate a boolean relation between their inputs and outputs. That is, if the outputs of a module can be expressed as a result of a boolean expression of it's inputs, then one can use continuous assignments instead of the module. Continuous assignments assign results of a boolean expression, over different busses and/or bus lines, to another bus or bus line continuously. In the rest of this chapter, we will refer to the expression as the RHS of the continuous assignment, and the bus or bus line to which the value of the expression is assigned to as the LHS.

LHS [is continuously assigned with] RHS EXPRESSION;

Whenever there is a change in the value of an operand in the RHS, the RHS is re-evaluated with the new value of
the operand, and the result is assigned to the LHS. This way, continuous assignments provide a short hand
alternative to a module - A simple assignment statement replaces an entire module definition. In libLCS, continuous
assignments can be made only to busses of type `Bus`

or `InOutBus`

. The next details the constructs
which facilitate continuous assignments in libLCS.

In circuits described using libLCS, continuous assignments should be incorporated by using the template function
`cass`

which is a member of the class `Bus`

. The explicit template parameter, which *has* to be
specified, is the assignment delay. The general syntax for using continuous assignements if as follows.

[BUS | BUS LINE].cass<ASSIGNMENT DELAY>(RHS EXPRESSION);

For example, to assign the result of the expression `(c[0] ^ c[1])`

(`c`

is some bus) continuously to a
bus `b`

with an assignment delay of 5 system time units, one has to incorporate the following statement in
his/her code.

b.cass<5>(c[0] ^ c[1]);

The example in the next section will illustrate the usage of continuous assignments in detail. One should note that libLCS currently supports only bitwise operators. Arithmetic operators and bit-shift operators are not yet supported.

In this section, we will build a 1-bit fulladder using contnuous assignments. The input to the fulladder is a 3-line bus consisting of two input bit lines, and one carry input line. The output is a 2-line bus consisting of the sum line and the carry output line. The complete program is as follows. The code has inline comments which elaborate on the new constructs used to facilitate continuous assignments.

#include <lcs/lcs.h> using namespace lcs; int main(void) { // The input bus consisting of two input lines // and the carry input. Bus<3> IN; // The output bus consisting of the sum line // and carry output line. Bus<2> S; // Continuous assignment statements to generate // the sum and carry outputs. The template parameters // indicate the assignment delay. We have used 0 // delay here. Note the RHS expression consisting of // bitwise operators. S[0].cass<0>(IN[0]&~IN[1]&~IN[2] | ~IN[0]&IN[1]&~IN[2] | ~IN[0]&~IN[1]&IN[2] | IN[0]&IN[1]&IN[2]); S[1].cass<0>(IN[0]&IN[1]&~IN[2] | IN[0]&~IN[1]&IN[2] | ~IN[0]&IN[1]&IN[2] | IN[0]&IN[1]&IN[2]); ChangeMonitor<3> inputMonitor(IN, "Input"); ChangeMonitor<2> outputMonitor(S, "Sum"); Tester<3> tester(IN); Simulation::setStopTime(1000); Simulation::start(); return 0; }

When the above program in compiled and run, the following is the output obtained.

At time: 0, Input: 000 At time: 0, Sum: 00 At time: 200, Input: 001 At time: 200, Sum: 01 At time: 300, Input: 010 At time: 400, Input: 011 At time: 400, Sum: 10 At time: 500, Input: 100 At time: 500, Sum: 01 At time: 600, Input: 101 At time: 600, Sum: 10 At time: 700, Input: 110 At time: 800, Input: 111 At time: 800, Sum: 11