4. A Calculator with code memory: Fish
Fish is "programmable invertebrate": In fish, rather than supplying control signals and clock edges by a human hand, we record all the control signals required for the desired computation in a memory chip and replace the pushbutton with a clock. After doing that, the memory chip supplies the required control signals automatically and sequentially to the processor at every clock cycle. These recorded cotrol signals are called "machine code".
Structure of Memory
Before going on connecting a memory chip to our processor, we have to develop a notation to explain memory operations. Software sees memory as a one dimensional array of 2^k kocations, where k is the number of address bits.
M[0] = 0xabcd
4.1 "Machine Language" for Fish
Recall that each instruction of invertebrate must generate four control signals, ie,
- ALUOp (4 bits) ,
- Ra (3bits),
- Rb (3 bits)
- Rc (3 bits)
If these four control signals are concatenated together into an 13 bit entity, the result is called "a machine instruction" for fish. In each machine instruction, we have fields for ALUOp, Ra, Rb and Rc. The order of concatenation is arbitrary. We will use the order indicated in Figure below. Other orderings are also possible. But once we choose an ordering, we must stick with it, as the hardware is to be designed with this particular ordering in mind, and it will not understand any other ordering.
Each assembly language instruction has a corresponding machine language instruction and vice versa. Hence it is possible to translate between them.
In the following table, we give some assembly language instructions and their corresponding machine language translations as examples:
ASSEMBLY LANGUAGE | MACHINE LANGUAGE INSTRUCTION (binary) | MACHINE LANGUAGE INSTRUCTION (hex) |
---|---|---|
and 3 1 2 | 001 010 0010 010 | 0x512 |
or 0 3 0 | 000 011 0011 000 | 0x198 |
inc 5 | ||
dec 2 | ||
not 0 3 | ||
mov 5 7 | ||
sub 7 2 1 | ||
xor 1 1 1 |
In Fish, we needed a human operator to enter the commands REG1CHOOSE, REG2CHOOSE, ALUOP and REGSELECT at every clock cycle. In frog, we store these commands into a memory chip whose data bus width 13 bits. At every clock cycle
- A Memory chip:
Exercise: Assume that we use a different concatenation ordering. How would the diagram change?
4.3 Programming the Fish
Contrary to Fish, Frog is programmable.
The program must be already loaded into the memory at the start of the operation. Each location in memory
How the program is loaded into memory is left unspecified.
4.4 Example programs
4.5 Assembler for Fish
This assembler converts Fish assembly code into Fish machine code. Fill in the missing parts. Also, ordering of the fields ALUOP, Ra, Rb and Rc is wrong. Correct it.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
//Converts a hexadecimal string to integer.
int hex2int( char* hex)
{
int result=0;
while ((*hex)!='\0')
{
if (('0'<=(*hex))&&((*hex)<='9'))
result = result*16 + (*hex) -'0';
else if (('a'<=(*hex))&&((*hex)<='f'))
result = result*16 + (*hex) -'a'+10;
else if (('A'<=(*hex))&&((*hex)<='F'))
result = result*16 + (*hex) -'A'+10;
hex++;
}
return(result);
}
main()
{
FILE *fp;
char line[100];
char *token = NULL;
char *op1, *op2, *op3, *label;
char ch;
int chch;
int program[1000];
int counter=0; //holds the address of the machine code instruction
fp = fopen("name_of_program","r");
while(fgets(line,sizeof line,fp)!= NULL)
{
token=strtok(line,"\n\t\r "); //get the instruction mnemonic or labe
if (strcmp(token,"add")==0) //----------------- ADD -------------------------------
{
op1 = strtok(NULL,"\n\t\r ");
op2 = strtok(NULL,"\n\t\r ");
op3 = strtok(NULL,"\n\t\r ");
chch = (op1[0]-48)| ((op2[0]-48)<<3)|((op3[0]-48)<<6);
program[counter]=0x7000+((chch)&0x00ff);
counter++;
}
else if (strcmp(token,"sub")==0)
{
//to be added
}
else if (strcmp(token,"and")==0)
{
//to be added
}
else if (strcmp(token,"or")==0)
{
//to be added
}
else if (strcmp(token,"xor")==0)
{
//to be added
}
else if (strcmp(token,"not")==0)
{
op1 = strtok(NULL,"\n\t\r ");
op2 = strtok(NULL,"\n\t\r ");
ch = (op1[0]-48)| ((op2[0]-48)<<3);
program[counter]=0x7500+((ch)&0x00ff);
counter++;
}
else if (strcmp(token,"mov")==0)
{
//to be added
}
else if (strcmp(token,"inc")==0)
{
op1 = strtok(NULL,"\n\t\r ");
ch = (op1[0]-48)| ((op1[0]-48)<<3);
program[counter]=0x7700+((ch)&0x00ff);
counter++;
}
else if (strcmp(token,"dec")==0)
{
//to be added
}
else //------WHAT IS ENCOUNTERED IS NOT A VALID INSTRUCTION OPCODE
{
printf("no valid opcode\n");
}
} //while
fclose(fp);
fp = fopen("RAM","w");
fprintf(fp,"v2.0 raw\n"); //needed for logisim, remove this line for verilog..
for (i=0;i<counter+dataarea;i++) //complete this for memory size in verilog
fprintf(fp,"%04x\n",program[i]);
} //main