Well let me summarize what we have done so far in class. Our big project this semester is a cpu simulator. We have started this out by building the basic logic gates that everything else will be built on. Yesterday we were introduced to flipflops. Flipflops are these crazy things that I have no idea how they work. I am currently trying to get some understanding of them so I can move on to registers. I am excited even now to see how everything we are doing is building on itself.
Today I worked on my first keyword for my opus. As I was thinking, I realized this would be my last first keyword. As I held back the tears I started to define me some logic gates which was pretty fun. I'm still pretty excited about this whole cpu simulator thing. I've been reading more in my book about how we are going to be building everything. Peace out yo!
I'm back dating this entry since I forgot to do it on Friday.
Today in Computer Organization we all discussed a Turing machine. A Turing machine is a device that changes symbols on a infinite strip of tape. It changes these symbols by referencing a table of instructions. This machine can simulate logic that is used in computer algorithms. This theoretical device was imagined by Alan Turing in 1936 and is useful for representing a computer..
Other than that, our class is still working on our CPU simulator. The next steps are building a menu and building registers.
Toady had been fairly productive. I finished up my keywords and have started work on my experiments. I'm kinda struggling with what to do for my experiments though. Some of the experiments I can think of just seem trivial to do. I'll keep thinking about it and come up with something.
I also need to do an objective. Looking at the course objectives, most of them have to do with knowing the assembly language. I think that I still can do one of them at this point.
Well have a happy leap day tmrw!
Logic operations are represented by logic gates in Computer Science. These gates perform Boolean operations, meaning they get input and produce a single output(usually represented as true(1), false(2)).
The AND operation can be represented by the following true table.
p | q | p AND q | ||
T | T | T | ||
T | F | F | ||
F | T | F | ||
F | F | F |
A True will be returned iff both inputs are true. Otherwise, the returned value is false.
The OR operation can be represented by the following true table.
p | q | p OR q | ||
T | T | T | ||
T | F | T | ||
F | T | T | ||
F | F | F |
OR returns False if both inputs are false. Otherwise, it returns true.
The XOR operation can be represented by the following true table.
p | q | p XOR q | ||
T | T | F | ||
T | F | T | ||
F | T | T | ||
F | F | F |
A true is returned if the inputs are not equal. Otherwise a false is returned.
The following code is attributed to the Computer Organization class.
#include "and.h" bool AND::getX() { bool tmp = false; if((A == true) && (B == true)) { tmp = true; } return tmp; }
#include "or.h" bool OR :: getX() { bool tmp = false; if((A == true) || (B == true)) { tmp = true; } return(tmp); }
bool XOR::getX() { bool tmp = true; if((A == B)) { tmp = false; } return tmp; }
Like the title says, Negated logic operations simply negate the output from their logic operator cousins. A NOT gate simply negates whatever input it gets. If it gets as input FALSE, it will output TRUE and vice versa. The other three logic operations can be made by sending there logic operator cousin through a NOT gate.
I will not bother demonstrating all the gates because I think that would be a waste of precious opus space but I think if you understand one of them you will understand the rest. I realize as I write this explanation of why I will not be demonstrating all the negated logic gates that I am wasting opus space in this explanation. Now that we've got that settled, I will demonstrate a NAND gate.
Remember that a NAND gate is a negated AND gate.
#include "nand.h" NAND::NAND() { myandgate = new AND(); mynotgate = new NOT(); } bool NAND::getX() { bool tmp = true; myandgate -> setA(A); myandgate -> setB(B); tmp = myandgate -> getX(); mynotgate -> setA(tmp); tmp = mynotgate -> getX(); return(tmp); }
The code above sends two inputs into an AND gate and gets an output. It then sends that output into a not gate and returns that Boolean value.
The other two negated logic gates work the same way.
When we think of numbers, we think of 0 1 2 3 4 5 6 7 8 and 9. This is called a base 10(Decimal) number system. But what if instead of have 10 different symbols to represent values, we only had 2. This number system is called Binary. These two values are 0 and 1. Hexadecimal (base 16)on the other hand has 16 different symbols ( 0 1 2 3 4 5 6 7 8 9 A B C D E and F) that represent values.
For example, lets take the decimal number 45. Since this is base 10, the 4 is in the 10^1 place and the 5 is in the 10^0 place and can be represented as (4 * 10^1) + (5 * (10^0) = 45. Representing 45 in binary is different now because there is only two symbols to represent the number. In binary the first placeholder from the right is the 2^0 place followed by 2^1 place and so on. Therefore to represent 45 in binary we have to start with the 2^5 (32) place. Since 32 goes into 45 we place a 1 in that position and subtract 32 from 45 giving us 13. Since 13 doesn't go into the next position(2^4 = 16), we place a 0 in that position and move to the next one. Since 13 goes into 8(2^3) we place a 1 in the position and subtract 8 from 13 giving us 5. We move onto the next position which is (2^2) a see if 5 goes into that. Since it does we place a 1 in that position and subtract 4 from 5 giving us 1 left. Now we look at the 2^1 position and see that 1 does not goes into 2, we place a zero in that position and move onto the final position which is 2^0. Since 1 goes evenly into 1 we place a 1 in the 2^0 position and we are done. We get in binary is 101101 which is equal to 45 in decimal.
To represent 45 in hexadecimal we must look at the place holders for base 16. The rightmost place holder is 16^0 followed by 16^1 and so on. For example 10 in hexadecimal is equal to 16 in decimal. This is because ((1 * 10^1) + (0 * 10^0) = 10). Therefore, the hexadecimal equivalent of 45 is 2D( where D represents 13).
von Neumann computer architecture is based around a Central Processing Unit, interaction with a memory device that contains both the instructions and data and sending/receiving data through input/output.
Harvard architecture has physically separate storage and signal pathways for instructions and data.
When you compare these two different architectures, the biggest difference is how the CPU functions. With the von Neumann architecture, the CPU “can be either reading an instruction or reading/writing data from/to the memory. Both cannot occur at the same time since the instructions and data use the same bus system. (Wikipedia)”. Whereas a Harvard computer architecture allows for simultaneous instruction/data reading/writing.
The following pictures show diagrams of how these different architectures work.
Harvard architecture
von Neumann architecture where the memory contains both the data and the instructions
The fetch-execute cycle “is the basic operation cycle of a computer. It is the process by which a computer retrieves a program instruction from its memory, determines what actions the instruction requires, and carries out those actions. This cycle is repeated continuously by the central processing unit (CPU), from bootup to when the computer is shut down” (Wikipedia).
The fetch-execute cycle is basically how the computer functions. It starts by retrieving instructions, determine what those instructions mean, and then doing whatever those instructions say.
Computers storage refers to the way computers retain data. Storage comes in several different forms but when broken down, there are two main types of storage. The first type is called volatile storage. Volatile storage requires constant power for it to retain the data it stores. Volatile storage is typically seen in the computers Random Access Memory.
The other main type of storage is non-volatile storage. Unlike volatile storage, non-volatile storage does not require constant power to retain its data. The most common types of non-volatile storage are flash memory, optical storage and magnetic storage.
The following diagram shows how storage functions in the operation of a computer.
A subroutines(also know as functions, methods, etc…) is a block of code that is used to perform a certain task. This task is usually a task that needs to be repeated. This is useful because having to rewrite that portion of code over and aver again would waste time and space. Instead, a subroutine can be written to perform a certain task. Every time that task needs to be done, we say that you call the function. Once you call the function, the program goes to where the function is in memory and performs the task. Once that is done it either returns a value or if it is a void function it does not return anything.
/* * This program uses a function to find the avererage of three numbers */ #include<stdio.h> int average(int,int,int); int main() { int a = 1; int b = 5; int c = 10; int ave = 0; ave = average(a,b,c); printf("The average of the %d, %d, and %d, is = %d\n",a,b,c,ave); return 0; } int average(int x, int y, int z) { return((x + y + z)/3); }
Writing a function that finds the average would be useful if you need to find alot of averages.
Input/Ouput is how the computer communicates with the outside world.
Common input devices are keyboards, mice, scanners, etc. This is how a user can communicate with the computer.
Common output devices are display monitors and printers. This is how the computer communicates with the user.
Computers are also able to communicate back and forth to each other though I/O. They do do this using NIC's and modems.
I'm not sure just how to demonstrate this keyword but I was thinking that even looking a command line would work.
Through the keyboard I can type a set of characters into the command line and hit enter(me communicating with the computer). It then processes that command and outputs it answer(the computer communicating with me).
lab46:~$ whoami dschoeff lab46:~$
Familiarity with the organization of a computer system.
This objective will require a knowledge of how computers function. This includes memory, storage, processing and I/O to name a few.
I will start to gain a familiarity with the organization of a computer system by reading, writing up keywords, performing experiments and more reading.
This is an ongoing process through out the semester. Refer to the keywords I have defined and demonstrated above. Also look at the experiments I have tested.
Reflect upon your results of the measurement to ascertain your achievement of the particular course objective.
I don't know if this is a particular question but I will playing around with a fairly new feature in C++. This feature is the auto typed variable. What this allows you to do is create a variable with the keyword auto. The compiler will determine what kinda of variable it is based upon its initializing expression.
I guess I will be testing whether this actually works or not.
Based upon my reading of this article, I think the feature will work as expected.
I will create a test program that declares variable of different types including the auto type. I will the initialize them to the same value and print out the contents of the variables.
The following is the test program that I wrote.
#include<iostream> using namespace std; int main() { int intvar1 = 'a'; char charvar1 = 'a'; double doublevar1 = 'a'; auto autovar1 = 'a'; int intvar2 = 65; char charvar2 = 65; double doublevar2 = 65; auto autovar2 = 65; int intvar3 = 65.51; char charvar3 = 65.51; double doublevar3 = 65.51; auto autovar3 = 65.51; cout << "intended value 'a'" << endl; cout << "intvar1 = " << intvar1 << endl << "doublevar1 = " << doublevar1 << endl << "charvar1 = " << charvar1 << endl << "autovar1 = " << autovar1 << endl << endl; cout << "intended value 65" << endl; cout << "intvar2 = " << intvar2 << endl << "doublevar2 = " << doublevar2 << endl << "charvar2 = " << charvar2 << endl << "autovar2 = " << autovar2 << endl << endl; cout << "intended value 65.51" << endl; cout << "intvar3 = " << intvar3 << endl << "doublevar3 = " << doublevar3 << endl << "charvar3 = " << charvar3 << endl << "autovar3 = " << autovar3 << endl << endl; return (0); }
I then tried to compile this code with the following command and got this error message.
lab46:~$ g++ autotest.cc -o autotest autotest.cc: In function 'int main()': autotest.cc:10: error: ISO C++ forbids declaration of 'autovar1' with no type autotest.cc:14: error: ISO C++ forbids declaration of 'autovar2' with no type autotest.cc:18: error: ISO C++ forbids declaration of 'autovar3' with no type lab46:~$
I then talked to Matt about why this was happening and he found out that i needed to include the following argument.
lab46:~$ g++ --std=c++0x autotest.cc -o autotest lab46:~$
I believe this was to tell the compiler to include the right libraries which it wouldn't do by default.
Once the code was compiled I ran the code.
lab46:~$ ./autotest intended value 'a' intvar1 = 97 doublevar1 = 97 charvar1 = a autovar1 = a intended value 65 intvar2 = 65 doublevar2 = 65 charvar2 = A autovar2 = 65 intended value 65.51 intvar3 = 65 doublevar3 = 65.51 charvar3 = A autovar3 = 65.51 lab46:~$
Based on the data collected:
The auto typed variable is just as simple to use as any other type of variable. As of now I am not aware of any big advantages this type of variable has besides dumbing down the programming a bit. Maybe as I explore this more some of those advantages will show themselves.
I guess this will piggy back of the last experiment. The question I am posing is will a auto typed variable once initialized be able to change types.
I believe it will not be able to change data types once initialized.
I will write a program that declares and initializes an auto typed variable to an int. I will then try to put different data types in it and see what happens.
Here is the short program I wrote to test my hypothesis.
#include<iostream> using namespace std; int main() { auto autovar = 'a';//i will be changing this initialization through my testing proccess. cout << "value stored in auto typed variable - > " << autovar << endl; cout << "enter value to put in auto typed variable: " ; cin >> autovar; cout << "value stored in auto typed variable - > " << autovar << endl; return (0); }
I then compiled and ran my code.
lab46:~$ ./autotest value stored in auto typed variable - > a enter value to put in auto typed variable: b value stored in auto typed variable - > b lab46:~$ ./autotest value stored in auto typed variable - > a enter value to put in auto typed variable: 7 value stored in auto typed variable - > 7 lab46:~$ ./autotest value stored in auto typed variable - > a enter value to put in auto typed variable: 6.234 value stored in auto typed variable - > 6 lab46:~$
I then changes the initialized value to 5.
lab46:~$ ./autotest value stored in auto typed variable - > 5 enter value to put in auto typed variable: 6 value stored in auto typed variable - > 6 lab46:~$ ./autotest value stored in auto typed variable - > 5 enter value to put in auto typed variable: a value stored in auto typed variable - > 5 lab46:~$ ./autotest value stored in auto typed variable - > 5 enter value to put in auto typed variable: 6.34 value stored in auto typed variable - > 6 lab46:~$
Based on the data collected:
Just as expected, once an autotyped variable is given a data type it cannot be changed.
My final experiment will be whether you can declare an auto variable without initializing it and if so how will it respond.
I believe you will not be able to declare the auto typed variable without initializing it.
I will write a program that declares an auto typed variable without initializing it. If it compiles, I will then try to store data in the variable and print its contents.
Here is my code.
#include<iostream> using namespace std; int main() { auto autovar; cout << "enter value to put in auto typed variable: " ; cin >> autovar; cout << "value stored in auto typed variable - > " << autovar << endl; return (0); }
I then tried to compile my code and got this error.
lab46:~$ g++ --std=c++0x autotest.cc -o autotest autotest.cc: In function 'int main()': autotest.cc:7: error: declaration of 'auto autovar' has no initializer lab46:~$
Based on the data collected:
This experiment has furthered my lack of understanding for why there would be a need for this type of declaration.
If the the variable has to be initialized before compile time, you obviously know what type of variable you will need anyways. Ugh!