Academic Integrity: tutoring, explanations, and feedback — we don’t complete graded work or submit on a student’s behalf.

#include <stdint.h> #include <stdio.h> int main () { unsigned int S2; /* current

ID: 3601065 • Letter: #

Question

#include <stdint.h>

#include <stdio.h>

int

main ()

{

unsigned int S2; /* current FSM state */

unsigned int S1;

unsigned int S0;

unsigned int S2_plus; /* FSM state in next clock cycle */

unsigned int S1_plus;

unsigned int S0_plus;

unsigned int A; /* outputs A and P */

unsigned int P;

unsigned int TBits; /* input T as a bit vector (LSB first) */

unsigned int T; /* input T in the current cycle */

unsigned int cycle; /* cycle number (discrete time) */

/* Initialize input bit vector. */

TBits = 0x09915C;

/* Force FSM into state 000 initially. */

S2 = 0;

S1 = 0;

S0 = 0;

/* Print a header for the output table. */

printf (" cycle | current state | outputs | input | next state ");

printf ("number | S2 S1 S0 | A P | T | S2+ S1+ S0+ ");

printf ("-------+---------------+---------+-------+------------- ");

for (cycle = 0; 21 > cycle; cycle = cycle + 1) {

/*

* Copy the next bit from the input vector into T, and

* discard the bit copied from the vector by shifting

* it to the right.

*/

T = (TBits & 1);

TBits = (TBits >> 1);

/*

* Calculate the outputs. Discard all but the low bit from

* the logic expressions by bitwise ANDing with 1.

*/

A = (((~S2) & (~S1)) & 1);

P = (((~S1) & S0) & 1);

/*

* Calculate the next state. Discard all but the low bit from

* the logic expressions by bitwise ANDing with 1.

*/

S2_plus = ((((~S2) & (~S1)) | (S0 ^ T) | (S2 & S0)) & 1);

S1_plus = ((((~S2) & (~S1)) | (~(S2 ^ S0)) | (S1 & (~T))) & 1);

S0_plus = (((S0 & (~T)) | ((~S2) & (~T)) | ((~S2) & S1 & S0)) & 1);

/* Print the current state, outputs, input, and next state. */

printf (" %3d | %d %d %d | %d %d | %d | %d %d %d ",

cycle, S2, S1, S0, A, P, T, S2_plus, S1_plus, S0_plus);

/* Simulate the rising edge of the clock. */

S2 = S2_plus;

S1 = S1_plus;

S0 = S0_plus;

}

/* Success! */

return 0;

}

The above code outputs the following program.

cycle | current state | outputs | input | next state
number | S2 S1 S0 | A P | T | S2+ S1+ S0+
-------+---------------+---------+-------+-------------
0 | 0 0 0 | 1 0 | 0 | 1 1 1
1 | 1 1 1 | 0 0 | 0 | 1 1 1
2 | 1 1 1 | 0 0 | 1 | 1 1 0
3 | 1 1 0 | 0 0 | 1 | 1 0 0
4 | 1 0 0 | 0 0 | 1 | 1 0 0
5 | 1 0 0 | 0 0 | 0 | 0 0 0
6 | 0 0 0 | 1 0 | 1 | 1 1 0
7 | 1 1 0 | 0 0 | 0 | 0 1 0
8 | 0 1 0 | 0 0 | 1 | 1 1 0
9 | 1 1 0 | 0 0 | 0 | 0 1 0
10 | 0 1 0 | 0 0 | 0 | 0 1 1
11 | 0 1 1 | 0 0 | 0 | 1 1 1
12 | 1 1 1 | 0 0 | 1 | 1 1 0
13 | 1 1 0 | 0 0 | 0 | 0 1 0
14 | 0 1 0 | 0 0 | 0 | 0 1 1
15 | 0 1 1 | 0 0 | 1 | 0 0 1
16 | 0 0 1 | 1 1 | 1 | 1 1 0
17 | 1 1 0 | 0 0 | 0 | 0 1 0
18 | 0 1 0 | 0 0 | 0 | 0 1 1
19 | 0 1 1 | 0 0 | 1 | 0 0 1
20 | 0 0 1 | 1 1 | 0 | 1 1 1

Use the state transition diagram (or, if you prefer, the next state table) to calculate next-state logic expressions for the FSM program above using only NAND gates (start with optimal SOP, then transform the equations to NAND, remembering that both state variables and their complements are available directly from the flip-flops).

In the program FSM replace the output and next-state computations with your NAND expressions. Note that (A NAND B) in C appears as (~(A & B)); if you use other combinations of bitwise operators, or use any logical operators, you will lose points. Be sure that you remove all but the LSB from each variable using &1, as is already done in the program.

Now replace the test vector input (on line 57) with the bits provided under “Testing the Design”. You should include both the initialization sequence as well as the testing sequence from the notes in the new value of TBits. Note that the input value T is taken first from the LSB of TBits, so you will need to reverse the order given in the notes, then translate from binary to hexadecimal (do not use decimal). Your full test sequence should require 15 inputs, so you should have four hex digits. Change the loop to simulate for 15 cycles instead of 21.

Screenshot a printout of the modified version of FSM code and output containing your NAND-only equations for A, P, and the three next-state variables, S2+, S1+, and S0+.

- Repeat part (a) using only NOR gates (start with POS, then transform the equations to NOR). Note that (A NOR B) in C appears as (~(A | B)); if you use other combinations of bitwise operators, or use any logical operators, you will lose points. Follow the same steps: insert your NOR-based equations into the FSM program, compile it

Screenshot a printout of the modified version of FSM code and output containing NOR-only equations for A, P, and the three next-state variables, S2+, S1+, and S0+.

outputs should match

cycle | current state | outputs | input | next state
number | S2 S1 S0 | A P | T | S2+ S1+ S0+
-------+---------------+---------+-------+-------------
0 | 0 0 0 | 1 0 | 0 | 0 0 1
1 | 0 0 1 | 0 0 | 0 | 0 0 1
2 | 0 0 1 | 0 0 | 1 | 1 0 1
3 | 1 0 1 | 1 1 | 1 | 1 0 0
4 | 1 0 0 | 1 0 | 1 | 1 1 0
5 | 1 1 0 | 0 0 | 1 | 1 1 0
6 | 1 1 0 | 0 0 | 0 | 0 1 0
7 | 0 1 0 | 1 1 | 1 | 1 0 0
8 | 1 0 0 | 1 0 | 0 | 0 1 0
9 | 0 1 0 | 1 1 | 0 | 0 0 0
10 | 0 0 0 | 1 0 | 1 | 1 0 1
11 | 1 0 1 | 1 1 | 0 | 0 0 0
12 | 0 0 0 | 1 0 | 0 | 0 0 1
13 | 0 0 1 | 0 0 | 0 | 0 0 1
14 | 0 0 1 | 0 0 | 1 | 1 0 1

3.3.4 Testing the Design Having a complete design on paper is a good step forward, but humans make mistakes at all stages. How can we know that a circuit that we build in the lab correctly implements the FSM that we have outlined in these notes? For the lab design, we have two problems to solve. First, we have not specified an initialization scheme for the FSM. We may want the FSM to start in one of the PAID states, but adding initialization logic to the design may mean requiring you to wire together significantly more chips. Second, we need a sequence of inputs that manages to test that all of the next-state and output logic implementations are correct. Testing sequential logic, including FSMs, is in general extremely difficult. In fact, large sequential systems today are generally converted into combinational logic by using shift registers to fill the flip-flops with a particular pattern, executing the logic for one clock cycle, and checking that the resulting pattern of bits in the flip-flops is correct. This approach is called scan-based testing, and is discussed in ECE 543. You will make use of a similar approach when you test your combinational logic in the second week of the lab, before wiring up the flip-flops. We have designed our FSM to be easy to test (even small FSMs may be challenging) with a brute force approach. In particular, we identify two input sequences that together serve both to initialize and to test a correctly implemented variant of our FSM. Our initialization sequence forces the FSM into a specific state regardless of its initial state. And our test sequence crosses every transition arc leaving the six valid states. In terms of T, the coin type, we initialize the FSM with the input sequence 001. Notice that such a sequence takes any initial state into PAID2 For testing, we use the input sequence 111010010001. You should trace this sequence, starting from PAID2, on the diagram below to see how the test sequence covers all of the possible arcs. As we test, we need also to observe the A and P outputs in each state to check the output logic. 0uDO PAIDI oILAX REJECTO OTR

Explanation / Answer

#include <stdint.h>

#include <stdio.h>

int

main ()

{

unsigned int S2; /* current FSM state */

unsigned int S1;

unsigned int S0;

unsigned int S2_plus; /* FSM state in next clock cycle */

unsigned int S1_plus;

unsigned int S0_plus;

unsigned int A; /* outputs A and P */

unsigned int P;

unsigned int TBits; /* input T as a bit vector (LSB first) */

unsigned int T; /* input T in the current cycle */

unsigned int cycle; /* cycle number (discrete time) */

/* Initialize input bit vector. */

TBits = 0x09915C;

/* Force FSM into state 000 initially. */

S2 = 0;

S1 = 0;

S0 = 0;

/* Print a header for the output table. */

printf (" cycle | current state | outputs | input | next state ");

printf ("number | S2 S1 S0 | A P | T | S2+ S1+ S0+ ");

printf ("-------+---------------+---------+-------+------------- ");

for (cycle = 0; 21 > cycle; cycle = cycle + 1) {

/*

* Copy the next bit from the input vector into T, and

* discard the bit copied from the vector by shifting

* it to the right.

*/

T = (TBits & 1);

TBits = (TBits >> 1);

/*

* Calculate the outputs. Discard all but the low bit from

* the logic expressions by bitwise ANDing with 1.

*/

A = (((~S2) & (~S1)) & 1);

P = (((~S1) & S0) & 1);

/*

* Calculate the next state. Discard all but the low bit from

* the logic expressions by bitwise ANDing with 1.

*/

S2_plus = ((((~S2) & (~S1)) | (S0 ^ T) | (S2 & S0)) & 1);

S1_plus = ((((~S2) & (~S1)) | (~(S2 ^ S0)) | (S1 & (~T))) & 1);

S0_plus = (((S0 & (~T)) | ((~S2) & (~T)) | ((~S2) & S1 & S0)) & 1);

/* Print the current state, outputs, input, and next state. */

printf (" %3d | %d %d %d | %d %d | %d | %d %d %d ",

cycle, S2, S1, S0, A, P, T, S2_plus, S1_plus, S0_plus);

/* Simulate the rising edge of the clock. */

S2 = S2_plus;

S1 = S1_plus;

S0 = S0_plus;

}

/* Success! */

return 0;

}