A realistic C++ line counter

This program asks the user for a c++ source file. It displays the file’s linecount to the screen. Program exits on invalid input. This sourcefile is 90 lines of code(according to itself).
Each of the following counts as one line of code:

  1. Preprocessor directives
  2. if()
  3. while()
  4. do..while()
  5. switch()
  6. non-repeating semicolons

#include <iostream>
#include <fstream>
#include <string>

using namespace std;

// accepts a valid C++ filename, returns a C++ linecount. Prints a error and exits program on invalid input.
int loc(string filename);

int main()
{
	string filename;
	cout << "Enter a cpp filename to linecount " << endl;
	cin >> filename;
	cout << filename << " has " << loc(filename) << " lines of code." << endl;
	system("pause");
	return 0;
}

int loc(string filename){
/* open file. exit on failure
 * read the file one character at a time
 * accumulate a linecount by counting if, do, while, switch and semicolons.
 * ignore keywords and semi's that are inside strings and comments
 */
    ifstream OpenFile;
    OpenFile.open(filename.c_str());
    char ch;
    int linecount = 0;

    if (!OpenFile) {
    cout << "loc() was unable to open file. Exiting program." << endl;
	system("pause");
	exit(1);
    }

    while(!OpenFile.eof()){

        OpenFile.get(ch);

        //dont count anything inside line or block comments
        if(ch == '/'){
                OpenFile.get(ch);
                if(ch == '/'){
                        while(ch != '\n')
                                OpenFile.get(ch);
                }else if(ch == '*'){
                        OpenFile.get(ch);
                        while(ch != '*' && ch+1 != '/'){
                                OpenFile.get(ch);
                        }
                }

        // handle the \" escape character here, to prevent errors in string parsing
        }else if(ch == '\\'){
            if(OpenFile.peek()=='\"'){
                OpenFile.get(ch);
                OpenFile.get(ch);
            }

        // dont count anything inside of strings, remember to ignore the /" escape character
        }else if(ch=='\"'){
            OpenFile.get(ch);
            while(ch!='\"'){
                if(ch == '\\'){
                    if(OpenFile.peek()=='\"'){
                        OpenFile.get(ch);
                        OpenFile.get(ch);
                    }
                }OpenFile.get(ch);
            }
        }

        // count if()'s
        else if(ch == 'i'){
                if(OpenFile.peek() == 'f'){
                        OpenFile.get(ch);
                        if(OpenFile.peek() == ' ' || OpenFile.peek() == '('  || OpenFile.peek() == '\n' || OpenFile.peek() == '\r' || OpenFile.peek() == '\t' ){
                                linecount++;
                        }
                }
        }

        // count while()'s
        else if(ch == 'w'){
                if(OpenFile.peek() == 'h'){
                        OpenFile.get(ch);
                        if(OpenFile.peek() == 'i'){
                                OpenFile.get(ch);
                                if(OpenFile.peek() == 'l'){
                                OpenFile.get(ch);
                                        if(OpenFile.peek() == 'e'){
                                        OpenFile.get(ch);
                                                if(OpenFile.peek() == ' ' || OpenFile.peek() == '('  || OpenFile.peek() == '\n' || OpenFile.peek() == '\r' || OpenFile.peek() == '\t' ){
                                                linecount++;
                                                }
                                        }
                                }
                        }
                }

        // count do..while();    this routine eliminates double counting because do{..}while(); loops always end with a semi.
                // the whole block is effectivly ignored, and the ending semi is counted like normal
        }else if(ch == 'd'){
                if(OpenFile.peek() == 'o'){
                        OpenFile.get(ch);
                        bool flag = false;
                        while( !flag ){
                                OpenFile.get(ch);
                                if(ch == 'w'){
                                        if(OpenFile.peek() == 'h'){
                                                OpenFile.get(ch);
                                                if(OpenFile.peek() == 'i'){
                                                        OpenFile.get(ch);
                                                        if(OpenFile.peek() == 'l'){
                                                        OpenFile.get(ch);
                                                                if(OpenFile.peek() == 'e'){
                                                                OpenFile.get(ch);
                                                                        if(OpenFile.peek() == ' ' || OpenFile.peek() == '('  || OpenFile.peek() == '\n' || OpenFile.peek() == '\r' || OpenFile.peek() == '\t' ){
                                                                        flag = true;
                                                                        }
                                                                }
                                                        }
                                                }
                                        }
                                }
                        }
                }
        }

        // count switch()'s
        else if(ch == 's'){
                if(OpenFile.peek() == 'w'){
                        OpenFile.get(ch);
                        if(OpenFile.peek() == 'i'){
                                OpenFile.get(ch);
                                if(OpenFile.peek() == 't'){
                                OpenFile.get(ch);
                                        if(OpenFile.peek() == 'c'){
                                        OpenFile.get(ch);
                                                if(OpenFile.peek() == 'h'){
                                                OpenFile.get(ch);
                                                        if(OpenFile.peek() == ' ' || OpenFile.peek() == '('  || OpenFile.peek() == '\n' || OpenFile.peek() == '\r' || OpenFile.peek() == '\t' ){
                                                        linecount++;
                                                        }
                                                }
                                        }
                                }
                        }
                }
        }

        // counts semi's, remember that ;;;;; only counts as one line, not 5.
        else if(ch == ';'){
                while ( OpenFile.peek() == ';' || OpenFile.peek() == ' '  || OpenFile.peek() == '\n' || OpenFile.peek() == '\r' || OpenFile.peek() == '\t' ){
                        OpenFile.get(ch);
                }
                linecount++;
        }

        //and count meta, # character counting is all thats necessasary because
        else if(ch == '#'){
                linecount++;
        }
    }

    OpenFile.close();
    return linecount;
}

16 bit ALU Verilog design

//B Turley
//16 bit ALU

`timescale 1ns/100ps

module sep_alu(Y, cout16, cout15, rightout, leftout, A, B, s, cin, rightin, leftin);
    output [15:0] Y;
    output cout16, cout15;
    output rightout, leftout;
    input  [15:0] A; //first input
    input  [15:0] B; //second input
    input  [3:0]  s; //operation input
    input         cin; // carry in
    input rightin, leftin; // shift inputs

    wire    [15:0]  cvect;
    wire    [15:0]  rvect;
    wire    [15:0]  lvect;

        alu_slice u0(Y[0], cvect[0], rvect[0], lvect[0],  A[0], B[0], s, cin, rvect[1], leftin);
        alu_slice u1(Y[1], cvect[1], rvect[1], lvect[1],  A[1], B[1], s, cvect[0], rvect[2], lvect[0]);
        alu_slice u2(Y[2], cvect[2], rvect[2], lvect[2],  A[2], B[2], s, cvect[1], rvect[3], lvect[1]);
        alu_slice u3(Y[3], cvect[3], rvect[3], lvect[3],  A[3], B[3], s, cvect[2], rvect[4], lvect[2]);
        alu_slice u4(Y[4], cvect[4], rvect[4], lvect[4],  A[4], B[4], s, cvect[3], rvect[5], lvect[3]);
        alu_slice u5(Y[5], cvect[5], rvect[5], lvect[5],  A[5], B[5], s, cvect[4], rvect[6], lvect[4]);
        alu_slice u6(Y[6], cvect[6], rvect[6], lvect[6],  A[6], B[6], s, cvect[5], rvect[7], lvect[5]);
        alu_slice u7(Y[7], cvect[7], rvect[7], lvect[7],  A[7], B[7], s, cvect[6], rvect[8], lvect[6]);
        alu_slice u8(Y[8], cvect[8], rvect[8], lvect[8],  A[8], B[8], s, cvect[7], rvect[9], lvect[7]);
        alu_slice u9(Y[9], cvect[9], rvect[9], lvect[9],  A[9], B[9], s, cvect[8], rvect[10], lvect[8]);
        alu_slice u10(Y[10], cvect[10], rvect[10], lvect[10],  A[10], B[10], s, cvect[9], rvect[11], lvect[9]);
        alu_slice u11(Y[11], cvect[11], rvect[11], lvect[11],  A[11], B[11], s, cvect[10], rvect[12], lvect[10]);
        alu_slice u12(Y[12], cvect[12], rvect[12], lvect[12],  A[12], B[12], s, cvect[11], rvect[13], lvect[11]);
        alu_slice u13(Y[13], cvect[13], rvect[13], lvect[13],  A[13], B[13], s, cvect[12], rvect[14], lvect[12]);
        alu_slice u14(Y[14], cvect[14], rvect[14], lvect[14],  A[14], B[14], s, cvect[13], rvect[15], lvect[13]);
        alu_slice u15(Y[15], cvect[15], rvect[15], lvect[15],  A[15], B[15], s, cvect[14], rightin, lvect[14]);

        assign cout16 = cvect[15];
        assign cout15 = cvect[14];
        assign rightout = rvect[0];
        assign leftout = lvect[15];

endmodule
/*****************************************************

File: sep_alu_tb.v
Author: Jeremy Wood
Date: 6-8-04

Desc: This is the test bench for the ALU 

modified 9-18-04  Added driveable left and right
                  shift inputs
modified 2-17-11  By B K Turley,
					Corrected error with cin timing
*****************************************************/

`timescale 1ns/100ps

module sep_alu_tb;

        reg     [15:0]  A;                      // A Input
        reg     [15:0]  B;                      // B Input
        reg     [3:0]   s;                      // Operation select input
        reg             cin;                    // Carry input
        reg             rightIn;                // Right Input from the shift operations
        reg             leftIn;                 // Left Input from the shift operations

        wire    [15:0]  Y;                      // Y Ouput
        wire            cout16, cout15;          // Carry Outputs
        wire            rightout, leftout;       // Shift Outputs

        // Invoke an instance of the test bench
        sep_alu         alu(Y, cout16, cout15, rightout, leftout, A, B, s, cin, rightIn, leftIn);

        initial begin

                $dumpfile("./sep_alu.dmp");
                $dumpvars(6, sep_alu_tb);

                A <= 16'habcd;
                B <= 16'h1234;
                rightIn <= 1'b0;
                leftIn <= 1'b0;

                // Addition
                #20 s <= 4'b0000;
                cin <= 1'b0;

                // Addition with Carry
                #20 cin <= 1'b1;

                // Subtract with Borrow
                #20 s <= 4'b0001;
                cin <= 1'b0;

                // Subtraction
                #20 cin <= 1'b1;

                // Transfer A
                #20 s <= 4'b0010;
                cin <= 1'b0;

                // Increment
                #20 cin <=1'b1;

                // Decrement A
                #20 s <= 4'b0011;
                cin <= 1'b0;

                // Transfer A
                #20 s <= 4'b0010;

                // AND
                #20 s <= 4'b0100;

                // OR
                #20 s <= 4'b0101;

                // XOR
                #20 s <= 4'b0110;

                // Complement A
                #20 s <= 4'b0111;

                // Shift right A into F
                #20 s <= 4'b1000;

                // Shift left A into F
                #20 s <= 4'b1100;

                // 42 + -13
                #20 A <= 16'd42;
                    B <= 16'b1111111111110011;
                    s <= 4'd0;

                // -42 - -13
                #20 A <= 16'b1111111111010110;
                    B <= 16'b1111111111110011;
                    s <= 4'd1;

                // 70 + 80
                #20 A <= 16'd70;
                    B <= 16'd80;
                    s <= 4'd0;

                // -70 + -80
                #20 A <= 16'b1111111110111010;
                    B <= 16'b1111111110110000;

                // Clear signals for Simvision
                #20 A <= 16'h0000;
                    B <= 16'h0000;

                #20 $finish;
        end
endmodule
//B Turley
//ALU one bit slice

`timescale 1ns/100ps

module alu_slice(Y, cout, rightout, leftout, A, B, s, cin, rightin, leftin);
    output Y;
    output cout;
    output rightout, leftout;
    input A;
    input B;
    input [3:0] s;
    input cin;
    input rightin, leftin;

    wire sum;
    wire Bin, Lout;

    mux_4to1 arithmatic(Bin, s[1:0], B, ~B, 1'b0, 1'b1);
    mux_4to1 logicpart(Lout, s[1:0], A&B, A|B, A^B, ~A);
    adder_1bit adder(sum, cout, A, Bin, cin);
    mux_4to1 slicemux(Y, s[3:2], sum, Lout, rightin, leftin);

    assign rightout = A;
    assign leftout = A;

endmodule
// 1 bit adder
// BK Turley

`timescale 1ns/100ps

module adder_1bit(sum, cout, in1, in2, cin);

        input   in1;
        input   in2;
        input   cin;

        output  sum;
        output  cout;

        assign cout = (in1 & in2) | (in1 & cin) | (in2 & cin);
        assign sum = in1 ^ in2 ^ cin;

endmodule

// 4 channel, 1 bit mux
// BK Turley

`timescale 1ns/100ps

module mux_4to1(out, sel, in0, in1, in2, in3);

output out;
input [1:0] sel;
input in0;
input in1;
input in2;
input in3;

reg out;

always @( sel or in0 or in1 or in2 or in3)

case (sel)
2′b00 : out <= in0;
2′b01 : out <= in1;
2′b10 : out <= in2;
2′b11 : out <= in3;
default : out <= in0;
endcase

endmodule

8 channel, 16 bit Verilog Multiplexer

// 8 channel mux
// BK Turley

`timescale 1ns/100ps

module mux_8to1_16bit(out, sel, in0, in1, in2, in3, in4, in5, in6, in7);

	input	[2:0]	sel;
	input	[15:0]	in0;
	input	[15:0]	in1;
	input	[15:0]	in3;
	input	[15:0]	in4;
	input	[15:0]	in5;
	input	[15:0]	in6;
	input	[15:0]	in7;
	output	[15:0]	out; 

	reg	[15:0]	out; 

	always @( sel or in0 or in1 or in2 or in3
		      or in4 or in5 or in6 or in7)

		case (sel)
		    3'b000 :	out <= in0;
		    3'b001 :	out <= in1;
		    3'b010 :	out <= in2;
		    3'b011 :	out <= in3;
		    3'b100 :	out <= in4;
		    3'b101 :	out <= in5;
		    3'b110 :	out <= in6;
		    3'b111 :	out <= in7;
		    default :	out <= in0; // channel 0 is selected on high impedence input
		endcase

endmodule

// B. Turley
//mux_8to1_16bit_tb.v

`timescale 1ns/100ps

module mux_8to1_16bit_tb;

    reg     [2:0]   mux_sel;
	reg     [15:0]  mux_in0;
	reg     [15:0]  mux_in1;
	reg     [15:0]  mux_in2;
	reg     [15:0]  mux_in3;
	reg     [15:0]  mux_in4;
	reg     [15:0]  mux_in5;
	reg     [15:0]  mux_in6;
	reg     [15:0]  mux_in7;
	wire    [15:0]  mux_out;

	mux_8to1_16bit  mux(mux_out, mux_sel, mux_in0, mux_in1, mux_in2,
		mux_in3, mux_in4, mux_in5, mux_in6, mux_in7);

	initial begin

		$dumpfile("./mux_8to1_16bit.dmp");
		$dumpvars(2, mux_8to1_16bit_tb);

		mux_in0 <= 16'h0000;
		mux_in1 <= 16'h0001;
		mux_in2 <= 16'h0002;
		mux_in3 <= 16'h0003;
		mux_in4 <= 16'h0004;
		mux_in5 <= 16'h0005;
		mux_in6 <= 16'h0006;
		mux_in7 <= 16'h0007;
		mux_sel <= 3'b000;

		#20 mux_sel <= 3'b001;
		#20 mux_sel <= 3'b010;
		#20 mux_sel <= 3'b011;
		#20 mux_sel <= 3'b100;
		#20 mux_sel <= 3'b101;
		#20 mux_sel <= 3'b110;
		#20 mux_sel <= 3'b111;
		#20 mux_sel <= 3'b000;

		#20 $finish;
	end
endmodule

Verilog 16 bit register with testbench.

//16 bit Register by B Kyle Turley
//Verilog

`timescale 1ns/100ps

module reg_16bit (out, in, load, clear, clk);
 input   [15:0]   in;
 input           load;
 input           clear;
 input           clk;
 output  [15:0]   out;

 reg     [15:0]   Q;

 always @(posedge clk)
 begin
 if(clear == 1'b1) // If clear is high, it has priority
 Q <= 16'b000000000000000;
 else if(load == 1'b1) // load has the next highest
 Q <= in;
 else
 Q <= Q;
 end

 /* Set output equal to the internal state */
 assign out = Q;

endmodule
`timescale 1ns/100ps

module reg_16bit_tb;

	reg	[15:0]	reg_input;
	reg		reg_load;
	reg		reg_clear;
	reg		clk;

	wire	[15:0]	reg_out;
	integer		fid;

	reg_16bit	register(reg_out, reg_input, reg_load, reg_clear, clk);

	initial begin
		clk = 1'b0;
		forever #10 clk <= ~clk;
	end

	initial begin

		fid = $fopen("./reg_16bit.out");
		$fmonitor(fid, $time, " out = %h, in = %h, load = %b, clear = %b",
			reg_out, reg_input, reg_load, reg_clear ) ;

		$dumpfile("./reg_16bit.dmp");
		$dumpvars(2, reg_16bit_tb);

		reg_clear <= 1'b1;
		reg_load <= 1'b0;
		reg_input <= 16'hABCD;
		#20 reg_clear <= 1'b0;
		#20 reg_load <= 1'b1;
		#20 reg_load <= 1'b0;
		#20 reg_input <= 16'h1234;
		#20 reg_load <= 1'b1;
		#20 reg_load <= 1'b0;
		reg_input <= 16'h0000;
		reg_clear <= 1'b1;
		#20 reg_clear <= 1'b0;
		#20 $finish;
	end

endmodule

Can’t use a string in a switch statement? Here is a simple alternative

Many programmers are surprised to find that switch statements aren’t compatible with strings in C++.

When attempting to compile, you will see an error:

Visual Studio 2010 —–  error C2450: switch expression of type ‘std::string’ is illegal

Netbeans 6.9.1 —– error: switch quantity not an integer

Here is an example of invalid code

#include <iostream>
#include <string>

using namespace std;

int main(){

	string dayofweek = "wednesday";

	switch(dayofweek){
		case "monday":
			cout << "Watch football" << endl;
			break;
		case "tuesday":
			cout << "steal a car"<< endl;
			break;
		case "wednesday":
			cout << "rob a bank" << endl;
			break;
		case "thursday":
			cout << "count the money" << endl;
			break;
		case "friday":
			cout << "hire a good lawyer" << endl;
			break;
	}
	return 0;
}

The problem is that strings are not a basic type in the C++ language. Whenever a C++ programmer uses basic variables types like int, bool, and char, nothing extra needed. But when a C++ programmer wishes to use strings in a program, they must add #include <string> to the top of the code to enable that functionality. Basic switch statements don’t have the capability to understand “add on” features such as strings and other filestreams.

There is still hope. The people who created the string library were kind enough to include a function to compare strings – strcmp() function. The string compare function can be used along with if..else statements to achieve the desired result.

this is the same logic as before without using a switch statement:

#include <iostream>
#include <string>

using namespace std;

int main(){

	string str = "wednesday";

	if ((!strcmp(str.c_str(), "monday"))){
		cout << "Watch football" << endl;
	}else if (!strcmp(str.c_str(), "tuesday")){
        cout << "steal a car"<< endl;
	}else if (!strcmp(str.c_str(), "wednesday")){
        cout << "rob a bank" << endl;
	}else if (!strcmp(str.c_str(), "thursday")){
		cout << "count the money" << endl;
	}else if (!strcmp(str.c_str(), "friday")){
		cout << "hire a good lawyer" << endl;
	}else{ // same as default
		cout << "Enjoy the Weekend" << endl;
	}

	return 0;
}

A Lexical Analyizer for C++ tokens

Lexical analysis is step 1 of compiling code down to machine language. The process breaks source code down into a long list of pieces called tokens. This list of tokens is used by a parser algorithm that extracts meaning from the order and arrangement of the tokens. Here is a small example of lex analysis:

code:

int main(void) {

float myvar = 2.5;

return 0;

}

list of tokens:

  1. int type
  2. main reserved word
  3. (
  4. void keyword
  5. )
  6. {
  7. float keyword
  8. myvar identifier
  9. = operator
  10. 2.5 floating point constant
  11. ; end statement
  12. return keyword
  13. 0 integer constant
  14. ; end statemant
  15. }

As you can see, the list of tokens gets long rather quickly. Absolutely no syntax checking is done during lex. That happens later down the line.

I have written a basic lexical analyzer to break C++ code into tokens.  Its own source code is C++ as well.

// B.K. Turley
// 1/26/2011

// Compile with g++ only, The nesting is limited to 128 in VS2010.
// This limit is exceeded by the massive if..else..if..else statement
// in identify_token()

// Known bugs:
// block comments are wrongly terminated with / instead of */

// Tokens are also stored in a linked list for later processing

#include <iostream>  //  Include <iostream> whenever using C++ I/O (cin and cout)
#include <iomanip>   //  Include <iomanip> along with iostream and you can't go wrong
#include <fstream>   //  Include <fstream> whenever working with external files.
#include <string>    //  Include <string> whenever using variable of type string.
#include <sstream>
#include <list>

using namespace std;

int find_split_point(string word);
	//accepts a string, returns a integer representing the length of the first token in the string

void identify_token(string str);
	//accepts a string, pritnt the type of token (operator, reverved, meta ect.) followed by str.

list<string> tokens;
int main()
    {

    string filename = "";
	fstream in;
	while(!in.is_open()){
	cout << "Enter a valid C++ file file to tokenize  ";
        cin >> filename;
	in.open(filename.c_str());
	}

	std::stringstream buffer;
	buffer << in.rdbuf();

	string lexme(buffer.str());

    //begin lex
    while(lexme != ""){
		int splitpoint = find_split_point(lexme);// if splitpoint is set to anything but zero here, string begins with operator or META

		if(splitpoint==0)//   string doesn't begin with op or meta. so set splitpoint to the index to the first occurence of space, operator, or META
				splitpoint = lexme.find_first_of(" #\"/=+-*%!^&|<>~,?.:;()[]{}\t");

		if(splitpoint==lexme.length()){ // this only executes whenever the very last piece of the string contains no ops or META
						identify_token(lexme);
						lexme = "";
		}
		else{
				if(splitpoint==0) splitpoint++;
				string token = lexme.substr(0,splitpoint);
				identify_token(token);
				lexme = lexme.substr(splitpoint, lexme.length()-splitpoint);
		}
	}

    return 0;
}

int find_split_point(string word){
// tests if first character is an operator(or META) and returns its length.
/*
    examples:
	isfirstcharoperator("hello there") returns zero.
	isfirstcharoperator("++i;") returns 2.
	isfirstcharoperator("!!crazy!") returns 1. (there is no !! operator)
	isfirstcharoperator("#include <string>") returns 8. (#inclued is a meta word)

*/
	string::iterator itr=word.begin();

        if(itr != word.end() && *itr=='#'){
		int i = 0;
		while(*itr != ' '){
		   i++;
		   itr++;
		   }
		return i;
	}
	else if(itr != word.end() && *itr=='"'){
            int i = 2;
            itr++;
            while(*itr != '"'){
                if(*itr=='\\'){
                    i++;
                    itr++;
                }
                 i++;
                    itr++;
		}
            return i;
	}
	else if(itr != word.end() && *itr=='/'){
		itr++;
		if(itr != word.end() && *itr=='/'){
                    int i = 1;
			while(itr != word.end() && *itr != '\n'){
                            i++;
                            itr++;
                        }
                    return i;
                }else if(itr != word.end() && *itr=='=')
                    return 2;
                else if(itr != word.end() && *itr=='*'){
                    int i = 3;
                    itr++;
                    do {
                        i++;
                        itr++;
                        }while(*itr != '/');//bug
                        return i;
                }
        }
	else if(itr != word.end() && *itr=='+'){
		itr++;
		if(itr != word.end() && *itr=='+')
			return 2;
		else if(itr != word.end() && *itr=='=')
			return 2;
		else
			return 1;
	}
	else if(itr != word.end() && *itr=='-'){
		itr++;
		if(itr != word.end() && *itr=='-')
			return 2;
		else if(itr != word.end() && *itr=='=')
			return 2;
		else if(itr != word.end() && *itr=='>')
			return 2;
		else
			return 1;

	}
        else if(itr != word.end() && *itr=='*'){
		itr++;
		if(itr != word.end() && *itr=='=')
			return 2;
		else if(itr != word.end() && *itr=='/')
			return 2;
		else
			return 1;

	}
	else if(itr != word.end() && *itr=='%'){
		itr++;
		if(itr != word.end() && *itr=='=')
			return 2;
		else
			return 1;
	}
	else if(itr != word.end() && *itr=='!'){
		itr++;
		if(itr != word.end() && *itr=='=')
			return 2;
		else
			return 1 ;
	}
        else if(itr != word.end() && *itr=='^'){
		itr++;
		if(itr != word.end() && *itr=='=')
			return 2;
		else{
			return 1;
		}
	}
	else if(itr != word.end() && *itr=='&'){
		itr++;
		if(itr != word.end() && *itr=='=')
			return 2;
		else if(itr != word.end() && *itr=='&')
			return 2;
		else
			return 1;
	}
	else if(itr != word.end() && *itr=='|'){
		itr++;
		if(itr != word.end() && *itr=='|')
			return 2;
		else if(itr != word.end() && *itr=='=')
			return 2;
		else
			return 1;
	}
	else if(itr != word.end() && *itr=='<'){ // bug,
		itr++;
		if(itr != word.end() && *itr=='<'){
			itr++;
			if(itr != word.end() && *itr=='=')
				return 3;
			else
				return 2;
		}
		else if(itr != word.end() && *itr=='=')
			return 2;
		else
			return 1;
	}
	else if(itr != word.end() && *itr=='>'){ // bug,
		itr++;
		if(itr != word.end() && *itr=='>'){
			itr++;
			if(itr != word.end() && *itr=='=')
				return 3;
			else
				return 2;
		}
		else if(itr != word.end() && *itr=='=')
			return 2;
		else
			return 1;
	}
        else if(itr != word.end() && *itr==':'){
		itr++;
		if(itr != word.end() && *itr==':')
                    return 2;
		return 1;
	}
        else if(itr != word.end() && *itr=='='){
		itr++;
		if(itr != word.end() && *itr=='=')
                    return 2;
		return 1;
	}

	else if(
                *itr=='\'' ||
                *itr==',' ||
                *itr=='~' ||
                *itr=='?' ||
                *itr=='.' ||
                *itr==';' ||
                *itr==':' ||
                *itr=='(' ||
                *itr==')' ||
                *itr=='{' ||
                *itr=='}' ||
                *itr=='[' ||
                *itr==']' ||
                *itr==' ' ||
                *itr=='\r'||
                *itr=='\n'
                )
                return 1;

	// not an operator
	return 0;

}

void identify_token(string str){

   // purge whitespace
    if ((!strcmp(str.c_str(), " ")))
            return;
    else if (!strcmp(str.c_str(), "\t"))
        return;
    else if (!strcmp(str.c_str(), "\r"))
        return;
    else if (!strcmp(str.c_str(), "\n"))
        return;

    //check for operators
    else if (!strcmp(str.c_str(), "?"))
            cout << "questionmark\t" << str << endl;
    else if (!strcmp(str.c_str(), "'"))
            cout << "singlequote\t" << str << endl;
    else if (!strcmp(str.c_str(), ";"))
            cout << "semicolon\t" << str << endl;
    else if (!strcmp(str.c_str(), "::"))
            cout << "scoperes\t" << str << endl;
    else if (!strcmp(str.c_str(), ":"))
            cout << "colon   \t" << str << endl;
    else if (!strcmp(str.c_str(), "{"))
            cout << "leftcurley\t" << str << endl;
    else if (!strcmp(str.c_str(), "}"))
            cout << "rightcurly\t" << str << endl;
    else if (!strcmp(str.c_str(), "["))
            cout << "arraysubL\t" << str << endl;
    else if (!strcmp(str.c_str(), "]"))
            cout << "arraysubR\t" << str << endl;
    else if (!strcmp(str.c_str(), ".*"))
            cout << "pointtomember\t" << str << endl;
    else if (!strcmp(str.c_str(), "."))
            cout << "dotoperator\t" << str << endl;
    else if (!strcmp(str.c_str(), "->*"))
            cout << "pointtomtmber\t" << str << endl;
    else if (!strcmp(str.c_str(), "->"))
            cout << "arrow\t" << str << endl;
    else if (!strcmp(str.c_str(), "("))
            cout << "leftparen\t" << str << endl;
    else if (!strcmp(str.c_str(), ")"))
            cout << "rightparen\t" << str << endl;
    else if (!strcmp(str.c_str(), "++"))
            cout << "increment\t" << str << endl;
    else if (!strcmp(str.c_str(), "--"))
            cout << "decrement\t" << str << endl;
    else if (!strcmp(str.c_str(), "typid"))
            cout << "type info\t" << str << endl;
    else if (!strcmp(str.c_str(), "*_cast"))
            cout << "C++ cast\t" << str << endl;
    else if (!strcmp(str.c_str(), "sizeof"))
            cout << "size info\t" << str << endl;
    else if (!strcmp(str.c_str(), "~"))
            cout << "bitwise NOT\t" << str << endl;
    else if (!strcmp(str.c_str(), "!="))
            cout << "not equal\t" << str << endl;
    else if (!strcmp(str.c_str(), "!"))
            cout << "NOT      \t" << str << endl;
    else if (!strcmp(str.c_str(), "-="))
            cout << "sub&assign\t" << str << endl;
    else if (!strcmp(str.c_str(), "-"))
            cout << "minus\t" << str << endl;
    else if (!strcmp(str.c_str(), "+="))
            cout << "add&assign\t" << str << endl;
    else if (!strcmp(str.c_str(), "+"))
            cout << "add/concat\t" << str << endl;
    else if (!strcmp(str.c_str(), "&&"))
            cout << "logicAND\t" << str << endl;
    else if (!strcmp(str.c_str(), "&="))
            cout << "AND&assign\t" << str << endl;
    else if (!strcmp(str.c_str(), "&"))
            cout << "address of\t" << str << endl;
    else if (!strcmp(str.c_str(), "*="))
            cout << "mult&assign\t" << str << endl;
    else if (!strcmp(str.c_str(), "*/"))
            cout << "closecomment\t" << str << endl;
    else if (!strcmp(str.c_str(), "*"))
            cout << "mult/deref\t" << str << endl;
    else if (!strcmp(str.c_str(), "new"))
            cout << "allocate\t" << str << endl;
    else if (!strcmp(str.c_str(), "delete"))
            cout << "deallocate\t" << str << endl;
    else if (!strcmp(str.c_str(), "/*"))
            cout << "opencomment\t" << str << endl;
    else if (!strcmp(str.c_str(), "//"))       // ?
            cout << "linecomment\t" << str << endl;
    else if (!strcmp(str.c_str(), "/"))
            cout << "divide op\t" << str << endl;
    else if (!strcmp(str.c_str(), "%="))
            cout << "mod&assign\t" << str << endl;
    else if (!strcmp(str.c_str(), "%"))
            cout << "modulo\t" << str << endl;
    else if (!strcmp(str.c_str(), "<<="))
            cout << "shftL&assign\t" << str << endl;
    else if (!strcmp(str.c_str(), "<<"))
            cout << "shiftleft\t" << str << endl;
    else if (!strcmp(str.c_str(), "<="))
            cout << "less or eq\t" << str << endl;
    else if (!strcmp(str.c_str(), "<"))
            cout << "less than\t" << str << endl;
    else if (!strcmp(str.c_str(), ">>="))
            cout << "shftR&assign\t" << str << endl;
    else if (!strcmp(str.c_str(), ">>"))
            cout << "shiftright\t" << str << endl;
    else if (!strcmp(str.c_str(), ">="))
            cout << "greateroreq\t" << str << endl;
    else if (!strcmp(str.c_str(), ">"))
            cout << "greater than\t" << str << endl;
    else if (!strcmp(str.c_str(), "=="))
            cout << "equal to\t" << str << endl;
    else if (!strcmp(str.c_str(), "="))
            cout << "assignment\t" << str << endl;
    else if (!strcmp(str.c_str(), "^="))
            cout << "XOR&assign\t" << str << endl;
    else if (!strcmp(str.c_str(), "^"))
            cout << "bitwiseXOR\t" << str << endl;
    else if (!strcmp(str.c_str(), "||"))
            cout << "logic OR\t" << str << endl;
    else if (!strcmp(str.c_str(), "|="))
            cout << "OR&assign\t" << str << endl;
    else if (!strcmp(str.c_str(), "throw"))
            cout << "throwex\t" << str << endl;
    else if (!strcmp(str.c_str(), ","))
            cout << "sequence\t" << str << endl;

    // check for reserved words
    else if (!strcmp(str.c_str(), "and"))
            cout << "Reserved\t" << str << endl;
    else if (!strcmp(str.c_str(), "and_eq"))
            cout << "Reserved\t" << str << endl;
    else if (!strcmp(str.c_str(), "asm"))
            cout << "Reserved\t" << str << endl;
    else if (!strcmp(str.c_str(), "auto"))
            cout << "Reserved\t" << str << endl;
    else if (!strcmp(str.c_str(), "bitand"))
            cout << "Reserved\t" << str << endl;
    else if (!strcmp(str.c_str(), "bitor"))
            cout << "Reserved\t" << str << endl;
    else if (!strcmp(str.c_str(), "bool"))
            cout << "Type    \t" << str << endl;
    else if (!strcmp(str.c_str(), "break"))
            cout << "Reserved\t" << str << endl;
    else if (!strcmp(str.c_str(), "case"))
            cout << "Reserved\t" << str << endl;
    else if (!strcmp(str.c_str(), "catch"))
            cout << "Reserved\t" << str << endl;
    else if (!strcmp(str.c_str(), "char"))
            cout << "Type    \t" << str << endl;
    else if (!strcmp(str.c_str(), "class"))
            cout << "Classtype\t" << str << endl;
    else if (!strcmp(str.c_str(), "compl"))
            cout << "Reserved\t" << str << endl;
    else if (!strcmp(str.c_str(), "const"))
            cout << "Reserved\t" << str << endl;
    else if (!strcmp(str.c_str(), "const_cast"))
            cout << "Reserved\t" << str << endl;
    else if (!strcmp(str.c_str(), "continue"))
            cout << "Reserved\t" << str << endl;
    else if (!strcmp(str.c_str(), "default"))
            cout << "Reserved\t" << str << endl;
    else if (!strcmp(str.c_str(), "delete"))
            cout << "Reserved\t" << str << endl;
    else if (!strcmp(str.c_str(), "do"))
            cout << "Reserved\t" << str << endl;
    else if (!strcmp(str.c_str(), "double"))
            cout << "Type    \t" << str << endl;
    else if (!strcmp(str.c_str(), "dynamic_cast"))
            cout << "Reserved\t" << str << endl;
    else if (!strcmp(str.c_str(), "else"))
            cout << "Reserved\t" << str << endl;
    else if (!strcmp(str.c_str(), "enum"))
            cout << "Grouptype\t" << str << endl;
    else if (!strcmp(str.c_str(), "explicit"))
            cout << "Reserved\t" << str << endl;
    else if (!strcmp(str.c_str(), "export"))
            cout << "Reserved\t" << str << endl;
    else if (!strcmp(str.c_str(), "extern"))
            cout << "Reserved\t" << str << endl;
    else if (!strcmp(str.c_str(), "false"))
            cout << "Reserved\t" << str << endl;
    else if (!strcmp(str.c_str(), "float"))
            cout << "Type    \t" << str << endl;
    else if (!strcmp(str.c_str(), "for"))
            cout << "Reserved\t" << str << endl;
    else if (!strcmp(str.c_str(), "friend"))
            cout << "Reserved\t" << str << endl;
    else if (!strcmp(str.c_str(), "goto"))
            cout << "Reserved\t" << str << endl;
    else if (!strcmp(str.c_str(), "if"))
            cout << "Reserved\t" << str << endl;
    else if (!strcmp(str.c_str(), "inline"))
            cout << "Reserved\t" << str << endl;
    else if (!strcmp(str.c_str(), "int"))
            cout << "Type    \t" << str << endl;
    else if (!strcmp(str.c_str(), "long"))
            cout << "Type    \t" << str << endl;
    else if (!strcmp(str.c_str(), "mutable"))
            cout << "Reserved\t" << str << endl;
    else if (!strcmp(str.c_str(), "namespace"))
            cout << "Reserved\t" << str << endl;
    else if (!strcmp(str.c_str(), "not"))
            cout << "Reserved\t" << str << endl;
    else if (!strcmp(str.c_str(), "not_eq"))
            cout << "Reserved\t" << str << endl;
    else if (!strcmp(str.c_str(), "operator"))
            cout << "Reserved\t" << str << endl;
    else if (!strcmp(str.c_str(), "or"))
            cout << "Reserved\t" << str << endl;
    else if (!strcmp(str.c_str(), "or_eq"))
            cout << "Reserved\t" << str << endl;
    else if (!strcmp(str.c_str(), "private"))
            cout << "Reserved\t" << str << endl;
    else if (!strcmp(str.c_str(), "protected"))
            cout << "Reserved\t" << str << endl;
    else if (!strcmp(str.c_str(), "public"))
            cout << "Reserved\t" << str << endl;
    else if (!strcmp(str.c_str(), "register"))
            cout << "Reserved\t" << str << endl;
    else if (!strcmp(str.c_str(), "reinterpret_cast"))
            cout << "Reserved\t" << str << endl;
    else if (!strcmp(str.c_str(), "return"))
            cout << "Reserved\t" << str << endl;
    else if (!strcmp(str.c_str(), "short"))
            cout << "Type    \t" << str << endl;
    else if (!strcmp(str.c_str(), "signed"))
            cout << "Reserved\t" << str << endl;
    else if (!strcmp(str.c_str(), "sizeof"))
            cout << "Reserved\t" << str << endl;
    else if (!strcmp(str.c_str(), "static"))
            cout << "Reserved\t" << str << endl;
    else if (!strcmp(str.c_str(), "static_cast"))
            cout << "Reserved\t" << str << endl;
    else if (!strcmp(str.c_str(), "struct"))
            cout << "Classtype\t" << str << endl;
    else if (!strcmp(str.c_str(), "switch"))
            cout << "Reserved\t" << str << endl;
    else if (!strcmp(str.c_str(), "template"))
            cout << "Reserved\t" << str << endl;
    else if (!strcmp(str.c_str(), "this"))
            cout << "Reserved\t" << str << endl;
    else if (!strcmp(str.c_str(), "throw"))
            cout << "Reserved\t" << str << endl;
    else if (!strcmp(str.c_str(), "true"))
            cout << "Reserved\t" << str << endl;
    else if (!strcmp(str.c_str(), "try"))
            cout << "Reserved\t" << str << endl;
    else if (!strcmp(str.c_str(), "typedef"))
            cout << "Reserved\t" << str << endl;
    else if (!strcmp(str.c_str(), "typeid"))
            cout << "Reserved\t" << str << endl;
    else if (!strcmp(str.c_str(), "typename"))
            cout << "Reserved\t" << str << endl;
    else if (!strcmp(str.c_str(), "union"))
            cout << "Classtype\t" << str << endl;
    else if (!strcmp(str.c_str(), "unsigned"))
            cout << "Reserved\t" << str << endl;
    else if (!strcmp(str.c_str(), "using"))
            cout << "Reserved\t" << str << endl;
    else if (!strcmp(str.c_str(), "virtual"))
            cout << "Reserved\t" << str << endl;
    else if (!strcmp(str.c_str(), "void"))//
            cout << "Reserved\t" << str << endl;
    else if (!strcmp(str.c_str(), "volitile"))
            cout << "Reserved\t" << str << endl;
    else if (!strcmp(str.c_str(), "wchar_t"))
            cout << "Type    \t" << str << endl;
    else if (!strcmp(str.c_str(), "while"))
            cout << "Reserved\t" << str << endl;
    else if (!strcmp(str.c_str(), "xor"))
            cout << "Reserved\t" << str << endl;
    else if (!strcmp(str.c_str(), "xor_eq"))
            cout << "Reserved\t" << str << endl;

	// check for predefined words
    else if (!strcmp(str.c_str(), "cin"))
	cout << "Predefined\t" << str << endl;
    else if (!strcmp(str.c_str(), "endl"))
	cout << "Predefined\t" << str << endl;
    else if (!strcmp(str.c_str(), "main"))
	cout << "Predefined\t" << str << endl;
    else if (!strcmp(str.c_str(), "cout"))
	cout << "Predefined\t" << str << endl;
    else if (!strcmp(str.c_str(), "NULL"))
	cout << "Predefined\t" << str << endl;
    else if (!strcmp(str.c_str(), "string"))
	cout << "Predefined\t" << str << endl;

    // check for META
    else if (!strcmp(str.c_str(), "#define"))
        cout << "META     \t" << str << endl;
    else if (!strcmp(str.c_str(), "#undef"))
        cout << "META     \t" << str << endl;
    else if (!strcmp(str.c_str(), "#ifdef"))
        cout << "META     \t" << str << endl;
    else if (!strcmp(str.c_str(), "#ifndef"))
        cout << "META     \t" << str << endl;
    else if (!strcmp(str.c_str(), "#else"))
        cout << "META     \t" << str << endl;
    else if (!strcmp(str.c_str(), "#endif"))
        cout << "META     \t" << str << endl;
    else if (!strcmp(str.c_str(), "#if"))
        cout << "META     \t" << str << endl;
    else if (!strcmp(str.c_str(), "#elif"))
        cout << "META     \t" << str << endl;
    else if (!strcmp(str.c_str(), "#error"))
        cout << "META     \t" << str << endl;
    else if (!strcmp(str.c_str(), "#line"))
        cout << "META     \t" << str << endl;
    else if (!strcmp(str.c_str(), "#pragma"))
        cout << "META     \t" << str << endl;
    else if (!strcmp(str.c_str(), "#include"))
        cout << "META     \t" << str << endl;

    //check for numbers and floating points
    else if(str.find_first_not_of("1234567890") == string::npos)
	cout << "CONST_NUM\t" << str << endl;
    else if(str.find_first_not_of(" 1234567890.", 0) == string::npos)
        cout << "CONST_FLOAT\t" << str << endl;

    // check for string
    else if (str[0] == '"' && str[str.length()-1]=='"')
            cout << "CONST_STR\t" << str << endl;

    // check for line comments
    else if (str[0] == '/' && str[1]=='/')
            cout << "LINECOMMENT\t" << str << endl;

    // check for block comments
    else if (str[0] == '/' && str[1] == '*' && str[str.length()-2]=='*' &&str[str.length()-1]=='/'){
            cout << "BLOCKCOMMENT\t" << str; cout << endl;}

    // all checks complete, assuming whatever passes all checkes is a
    // valid identifier(not in real life, identifiers can't begin with numeric characters)
    // we are assuming that the input is a valid c++ file, so this shouldn't be an issue.
    else cout << "IDENTIFIER\t" << str << endl;

}

Verilog model of a control unit for the SEP (Simple Educational Processor)

module cu(clk, reset, IRin, C, SC_Val);

input clk, reset;
input [15:0] IRin;

output [14:0] C;
output [3:0] SC_Val;

wire [7:0] D;
wire [7:0] T;

wire w1;

decoder_df IR_decoder(IRin[14],IRin[13],IRin[12], 0, D);
decoder_df Cnt_decoder(SC_Val[2],SC_Val[1],SC_Val[0], 0, T);
SecCounter SC(SC_Val, clk, w1, 0);

or (w1,C[8],reset);

assign
C[0] = T[0] | T[2] | (~D[7] & IRin[15] & T[3]),
C[1] = D[4] & T[4],
C[2] = T[1],
C[3] = D[2] & T[4],
C[4] = D[2] & T[5],
C[5] = T[1],
C[6] = T[1] | (~D[7] & IRin[15] & T[3]) | (D[2] & T[4]),
C[7] = D[3] & T[4],
C[8] = (D[2] & T[5]) | (D[3] & T[4]) | (D[4] & T[4]),
C[9] = T[1] | T[2] | T[3] | (T[4] & D[2]) | (T[4] & D[3]),
C[10] = T[0] | T[1] | T[3] | (T[4] & D[2]),
C[11] = T[1] | T[2] | T[3] | (T[4] & D[2]) | (T[4] & D[4]),
C[12] = 0,
C[13] = 0,
C[14] = 0;

endmodule

module decoder_df (A,B,C,E,D);
input A,B,C,E;
output [7:0] D;
assign D[0] = (~A & ~B & ~C & ~E),
D[1] = (~A & ~B & C & ~E),
D[2] = (~A & B & ~C & ~E),
D[3] = (~A & B & C & ~E),
D[4] = (A & ~B & ~C & ~E),
D[5] = (A & ~B & C & ~E),
D[6] = (A & B & ~C & ~E),
D[7] = (A & B & C & ~E);
endmodule

module SecCounter(count, CLK, RST, INC);
parameter n = 4;

output [n-1:0] count;
reg [n-1:0] count;
input CLK;
input RST;
input INC;

// Increment count on clock
always @(negedge CLK)
if (RST)
count = 0;
else if (~INC)
count = count + 1;

endmodule

Verilog Clock and Oscillator

The clock signal is essential when designing sequential circuits, the following two code examples demonstrate how to produce a clock signal for your FPGA projects. These modules could also be used to produce square wave oscillations for other purposes such as audio tones.


module Clk_Signal (clock);		// Verilog 1995
parameter	delay = 5;
output	clock;
reg		clock;</code>

initial begin
clock = 0;
forever #delay clock = ~clock;
end
endmodule

module Clk_Signal #(parameter delay = 5) (output reg clock);		// V2001

initial forever #delay clock = ~clock;
endmodule

How to do structs in MIPS

#	Learning Objectives:
#	Functions, arrays, structures.

############################################
####   C++ Code
############################################

#void DisplayTemps(Temp temps[], int len);
#
#struct Temp {
#   int lo;
#   int hi;
#};
#
#int main() {
#  Temp temps[] = { {40, 74}, {45, 80}, {60, 91} };
#
#  DisplayTemps(temps, 3);
#
#  return (0);
#}
#
#void DisplayTemp(Temp temps[], int len) {
#  cout < < "Listing of (lo, hi) temps:"
#       << endl;
#  for (int i = 0; i < len; i++) {
#    cout << temps[i].lo
#         << "  "
#         << temps[i].hi
#         << endl;
#  }
#}
###

###########################################
####    MIPS code
###########################################

		.data

	words: .asciiz "Listing of (lo, hi) temps:\n"
	somespace: .asciiz "  "
	newline: .asciiz "\n"

	temps:
		# declare an array of structs that is preloaded with values
		.word 40,74  #( Just like a 2d array )
		.word 45,80
		.word 60,91

		.text

main:

#######
	addiu $sp, $sp, -4
	sw $ra, 0($sp)
	S
	la $a0, temps  					#  DisplayTemps(temps, 3);
	addi $a1, $zero, 3				#
	jal DisplayTemps 				####

	lw    $ra, 0($sp)
	addiu $sp, $sp, 4
	jr    $ra

DisplayTemps:

###############

	li $v0, 4 			# print_string
	la $a0, words		# " Listing of (lo, hi) temps:"
	syscall

# FOR LOOP

	la $t0, temps	#$t0 holds the address of the 1st element
	li $t1, 1          # iterator = 1
	#a0 holds the current elements value

for:

	bgt $t1, $a1, exitfor  # exit if iterator > a1 (len)

	li $v0, 1			# print_int
	lw $a0, ($t0)
	syscall

	li $v0, 4 			# print_string
	la $a0, somespace	# "   "
	syscall

	li $v0, 1			# print_int
	add $t0, 4			# increment the index
	lw $a0, ($t0)
	syscall

	add $t0, 4	#increment index again
	lw $a0, ($t0)

	li $v0, 4 			# print_string
	la $a0, newline		# "\n"
	syscall
	#Increment iterator
	add $t1, 1

	j for

exitfor:

	jr $ra