/*********************************************************************** * handshake.cpp * * Test driver for second part of 6-21 on pg. 305 of Mano & Kime. * * This code assumes the following: * * Signal Parallel Port Pin * ------ ----------------- * CLK D0 * RESET D1 * R D2 * A D3 * E S3 ***********************************************************************/ #include #include #include #include "pport.h" /* Bit masks for the FPGA inputs. Note that RESET is active low, so * it will *ordinarily* be set. */ #define CLOCK 0x1 #define RESET 0x2 #define R 0x4 #define A 0x8 /* Function prototypes. */ void fpga(char *r, char * a, char *e); void init(void); int clock(int data, char err); void fatal(char *mesg); /*********************************************************************** * main() ***********************************************************************/ int main() { /* Issue the test cases. */ fpga("01100", "00110", "00000"); fpga("0000111111110000000000", "0000000011111111000000", "0000000000000000000000"); fpga("11001100", "01100110", "00000000"); fpga("011", "100", "111"); fpga("101", "011", "011"); fpga("1110", "0101", "0011"); fpga("11010", "01100", "00011"); fpga("000000000010101011010101011111111", "100011011000110110001101100011011", "111111111111111111111111111111111"); fpga("11001100", "01100110", "00000000"); printf("\nAll test cases passed!!\n\n"); return 0; } /*********************************************************************** * void fpga(char *r, char *a, char *e) * * r : a binary string of inputs to the circuit's r input. * * a : a binary string of inputs to the circuit's a input. * * e : a binary string of expected e outputs. * * The behavior of this function is to apply the current r and a inputs * to the circuit and then sample e. If a mismatch occurs, a message is * printed giving the position within the input stream where the * mismatch occurred and the input streams themselves. Note that the * positions are numbered starting from 0. * * Following the application of the new r and a inputs, the clock is * strobed. * * If a mismatch the function terminates program execution. ***********************************************************************/ void fpga(char *r, char *a, char *e) { int len = strlen(r); int i; /* The strings should all be the same length. Confirm this */ if (len != strlen(a) || len != strlen(e)) fatal("fpga() inputs of differing lengths.\n"); /* Reset the circuit. */ init(); /* Feed the inputs to the FPGA and check the result. */ for (i = 0; i < len; ++i) /* Get the current r and a input bits, rotate them into proper * position for the parallel port, and clock the circuit. */ if (!clock(((r[i] == '1') ? R : 0) | ((a[i] == '1') ? A : 0), e[i])) { printf("\n\nFailed Test Case during clock %d:\n", i); printf(" r: %s\n", r); printf(" a: %s\n", a); printf(" e: %s\n\n", e); exit(1); } } /*********************************************************************** * void init(void) * * Bring reset low and then high. This should asynchronously reset * the circuit to its initial state. **********************************************************************/ void init(void) { writeDataReg(0); writeDataReg(RESET); } /*********************************************************************** * int clock(int data, char err) * * data : the r and a values to apply. It is assumed that they are * already aligned for the parallel port. * * err : the expected error output. * * return value : 1 if the actual error output matched the expected * error output. 0 otherwise. ***********************************************************************/ int clock(int data, char err) { int errInt = err - '0'; /* Convert err to an integer. */ /* Write the new data values to the FPGA. */ writeDataReg(data | RESET); /* Check the error output. */ if (errInt != (readStatusReg() & 0x1)) return 0; /* Pulse the clock. */ writeDataReg(CLOCK | data | RESET); writeDataReg(RESET); return 1; } /*********************************************************************** * void fatal(char *mesg) * * Print mesg and terminate. ***********************************************************************/ void fatal(char *mesg) { printf("Fatal: %s", mesg); exit(1); }