# Computer Architecture Lab/WS2007/Project -1 Lab2/Project -1 Lab2
## Chain

To get a program into our processor Lucky, the following steps must be taken: - Create a asm file, e.g., test.asm in our "confortable" assembler language - Drag&Drop your asm file onto the Windows batch file "Update ROM File.bat" - - This will create a rom.vhdl for the Lucky processor which is automatically copied into the right directory - Open Quartus and start the Compilation - Burn the Programm onto the FPGA with USBrunner

## Update ROM File.bat

Batch file for Drag&Drop compilation

## createAo.sh

Inserts C Structures and does some substitutions to convert the assembler program into a valid C file

## sedScript1.sed

SED script which converts assembler commands into c function names

## adr_res.exe / resolvebranches.c

Calculates valid prog. adresses for labels and substitute them within the rom.vhdl

## asm1.sh

Preprocesses the assembler file converts the Lucky machine code program into a vhdl file

## mip.c

Converts ascii machine code file into a binary file

## lucky2.h

C Functions that substitute the assembler commands. They consists of printf functions to create machinecode
int labelpc;
"0000", "0001", "0010", "0011", "0100" , "0101", "0110", "0111", "1000", "1001" , "1010", "1011", "1100", "1101", "1110", "1111" };
int index = 0; int inplength = 0; int array_index; char tempbuf[100]=""; char *resbuf = (char*) malloc (17);
//printf("Input: %s", input);
while (input[index] != 0) { if ((input[index] >= 48) && (input[index] <= 57)) {
array_index = input[index] - 48; } else if ((input[index] >= 65) && (input[index] <= 70)) { array_index = input[index] - 55; } else if ((input[index] >= 97) && (input[index] <= 102)) { array_index = input[index] - 87; } else { index ++; continue; }
strcat (tempbuf, hex_to_bin_array [array_index]); //printf ("Char: -%c-, ArrayIndex: %d, Strcat:%s, Tempbuf:%s\n",input[index], array_index, hex_to_bin_array [array_index],tempbuf); index ++; inplength ++; } if (inplength*4 > length) { strcpy (resbuf, tempbuf + inplength*4 - length); } else { strcpy (resbuf, "0000000000000000"); strcpy (resbuf + length - inplength * 4, tempbuf); } return resbuf;
char *buf = (char*) malloc (3); sprintf(buf, "%x", (int)inp); return buf;
void printSTI (char *op, char* regS, char* regT, char* im) { char temp[33];
strcpy (temp, op); strcat (temp, hex_to_bin (regS, 5)); strcat (temp, hex_to_bin (regT, 5)); strcat (temp, hex_to_bin (im, 16));
printf ("%s\n", temp);
void printSTImCrude (char *op, char* regS, char* regT, char* im) { char temp[33];
strcpy (temp, op); strcat (temp, hex_to_bin (regS, 5)); strcat (temp, hex_to_bin (regT, 5)); strcat (temp, im); printf ("%s\n", temp);
void printSTDI (char *op, char* regS, char* regT, char* regD,char* im) { char temp[33];
strcpy (temp, op); strcat (temp, hex_to_bin (regS, 5)); strcat (temp, hex_to_bin (regT, 5)); strcat (temp, hex_to_bin (regD, 5)); strcat (temp, hex_to_bin (im, 5)); strcat (temp, "000000"); printf ("%s\n", temp);
void printTSD (char *op, char* regT, char* regS, char* regD) { char temp[33];
strcpy (temp, op); strcat (temp, hex_to_bin (regS, 5)); strcat (temp, hex_to_bin (regT, 5)); strcat (temp, hex_to_bin (regD, 5)); strcat (temp, "00000000000");
printf ("%s\n", temp);
void TOASCII (char* regD, char* regS, char* regT, int *pc) { printTSD (opTOASCII, regT, regS, regD); (*pc)++; }
void LW (char* regD, char* regS, int *pc) { printTSD (opLW, "0", regS, regD); (*pc)++; }
void NOOP (int *pc) { char temp[33]; strcpy (temp, opNOOP); strcat (temp, "00000000000000000000000000"); printf ("%s\n", temp);
(*pc)++; }
void JR (char* regS, int *pc) { printTSD (opJR, "0", regS, "0"); (*pc)++; }
void SW (char* regS, char* regT, int *pc) { printTSD (opSW, regT, regS, "0"); (*pc)++; }
char* handleBr(int jump_pc, int *pc) { int rel_pc = 0; static char Im[33]; char* ret; int i=0;
// char temp[50];
// strncpy(temp, jmpName, 50); // strncat(temp, "\0",2); // printf("CHECK %i - %s END CHECK\n",jump_pc, temp);
// for(i=0;i<LABEL_MAX_AMOUNT;i++){ // if((jump_pc ==labels[i].labelname)){
// if((rel_pc=labels[i].labelpc - (*pc))<0){ // rel_pc = rel_pc ^ 0xFFFF; // rel_pc += 1;
// } // break; // } // }
sprintf(Im, "%x", rel_pc);
ret = hex_to_bin (Im,16);
//printf("DEBUG ret=%i",ret);
if(jump_pc < 0) { sprintf (Im, "#!%i",jump_pc); // printf("Im = %s\n", Im); //ret = hex_to_bin ("0000000000000000", 16);//Im; ret = Im; // printf("RET=%s\n",ret); } else { rel_pc = jump_pc - (*pc) ; sprintf (Im, "%x", rel_pc); ret = hex_to_bin (Im, 16);
} // fprintf(stdout,"DEBUG-INFO: New branching to %i from %i: %s\n",jump_pc,(*pc),ret); return ret; }
//void BZS (int jump_pc, char* jmpName,int *pc) void BZS(int jump_pc, int *pc) { printSTImCrude (opBZS, "0", "0", handleBr(jump_pc, pc)); (*pc)++; }
void BZC (int jump_pc, int *pc) { printSTImCrude (opBZC, "0", "0", handleBr(jump_pc, pc)); (*pc)++; }
void BNS (int jump_pc, int *pc) { printSTImCrude (opBNS, "0", "0", handleBr(jump_pc, pc)); (*pc)++; }
void BNC (int jump_pc, int *pc) { printSTImCrude (opBNC, "0", "0", handleBr(jump_pc, pc)); (*pc)++; }
void BOR (int jump_pc, int *pc) { printSTImCrude (opBOR, "0", "0", handleBr(jump_pc, pc)); (*pc)++; }
void BOS (int jump_pc, int *pc) { printSTImCrude (opBOS, "0", "0", handleBr(jump_pc, pc)); (*pc)++; }
void BR (int jump_pc, int *pc) { printSTImCrude (opBR, "0", "0", handleBr(jump_pc, pc)); (*pc)++; }
void myBRrel (int relWidth, int *pc) { static char Im[33]; sprintf (Im, "%x", relWidth); printSTImCrude (opBR, "0", "0", hex_to_bin (Im, 16)); (*pc)++; }
void SSLV (char* regD, char* regS, char* regT, int *pc) { printTSD (opSLLV, regT, regS, regD); (*pc)++; }
void SUBU (char* regD, char* regS, char* regT, int *pc) { printTSD (opSUBU, regT, regS, regD); (*pc)++; }
void SUB (char* regD, char* regS, char* regT, int *pc) { printTSD (opSUB, regT, regS, regD); (*pc)++; }
void ADD (char* regD, char* regS, char* regT, int *pc) { printTSD (opADD, regT, regS, regD); (*pc)++; }
void MULT (char* regD, char* regS, char* regT, int *pc) { printTSD (opMULT, regT, regS, regD);(*pc)++; }
void MULTU (char* regD, char* regS, char* regT, int *pc) { printTSD (opMULTU, regT, regS, regD);(*pc)++; }
void ADDU (char* regD, char* regS, char* regT, int *pc) { printTSD (opADDU, regT, regS, regD);(*pc)++; }
void AND (char* regD, char* regS, char* regT, int *pc) { printTSD (opAND, regT, regS, regD);(*pc)++; }
void SRL (char* regD, char* regT, char* Im,int *pc) { printSTDI (opSRL, "0", regT, regD, Im); (*pc)++; }
void SLL (char* regD, char* regT, char* Im,int *pc) { printSTDI (opSLL, "0", regT, regD, Im); (*pc)++; }
void OR (char* regD, char* regS, char* regT, int *pc) { printTSD (opOR, regT, regS, regD);(*pc)++; }
void SRLV (char* regD, char* regS, char* regT, int *pc) { printTSD (opSRLV, regT, regS, regD);(*pc)++; }
void XOR (char* regD, char* regS, char* regT, int *pc) { printTSD (opXOR, regT, regS, regD);(*pc)++; }
void LLI (char* regT, char* Im, int *pc) { printSTI (opLLI, "0", regT, Im); (*pc)++; }
void LOAD_BIG_NUMBER(char* target, char* tempReg,char* Im, int *pc) { int i= 0; char bufLow[5]="0000\0"; char bufHigh[5]="0000\0"; bufLow[4]=0; bufHigh[5]=0; for(i=strlen(Im)-1;i>=0;i--){ if(i>3){ bufLow[i-4] = Im[i]; } else { bufHigh[i] = Im[i]; } }
LLI(target,bufHigh,pc); //LoadHighbyte: SLL(target,target,"10",pc); LLI(tempReg,bufLow,pc); ADD(target,target,tempReg,pc); }
int LABEL_NEW (int *newLabel, int *pc) { fprintf(stderr, "#!%i:%i\n", (*newLabel), (*pc)); return (*pc); }
void ENDPROC (int *pc,char *labelStr) { //fprintf(stderr,"DEBUG INFO: Reached end at %i, Labels:\n%s",(*pc),labelStr); }
void savePCtoReg (char* regT, int pc) { char Im[33]; sprintf (Im, "%x", pc); printSTI (opLLI, "0", regT, Im); }
char * intToAscii(const char * regStr) { int n,i = 0; int sLen = strlen(regStr); char *resbuf = (char*) malloc (2*sLen); char *beginning = resbuf; for(i=0;i<sLen;i++){ n = sprintf (resbuf, "%X", regStr[i]); resbuf+=2; } return beginning; }
void CALL(int jmpLabel,int *pc) { ADD("1B","0","1F",pc); BR(CALL_INT0, pc); BR(jmpLabel,pc);
BR(RETURN_INT0, pc);
int stLen = strlen(asciiStr); int i =0; char buff[3] = "000"; char lenBuff[33]; buff[2]=0;
LLI (incre,"1",pc);
char * hexStr = intToAscii(asciiStr);
buff[0] = hexStr[2*i]; buff[1] = hexStr[2*i+1]; LLI(regSize,buff,pc); SW(regBeginn,regSize,pc); ADD(regBeginn,incre,regBeginn,pc); } sprintf (lenBuff, "%X",stLen);
lenBuff[16]='\0'; LLI(regSize,lenBuff,pc); SUB(regBeginn,regBeginn,regSize,pc);
RAMENTER_INT0(regBeginn,regSize,"11", asciiStr, pc);
ADD("1B","9","0",pc); //Temporary "9"->1B ADD("9",availibleMemoryAdress,"0",pc); //overwrite "9" with the value to show (if we check "1D" it now still has the correct value, not altered by DebugSend) LLI("1C","1",pc); //load 1 for decrementing SUB("1D","1D","1C",pc); //decrement Stackpointer SW("1D","1B",pc); //"push" 1B=Original "9" on stack SUB("1D","1D","1C",pc); //decrement Stackpointer SW("1D","A",pc); //"push" "A" on stack LLI("A",availibleMemoryAdress,pc); //overwrite "A" with the register number to show CALL(DEBUG_SEND_INT0,pc); LLI("1C","1",pc); //load 1 for decrementing LW("A","1D",pc); //"pop" A ADD("1D","1D","1C",pc); //inc stack LW("9","1D",pc); //"pop" 9 ADD("1D","1D","1C",pc); //inc stack
int stLen = strlen(asciiStr); int i; char buff[3] = "000"; buff[2]=0; char * hexStr = intToAscii(asciiStr);
buff[0] = hexStr[2*i]; buff[1] = hexStr[2*i+1]; LLI("9",buff,pc); CALL(UART_SEND,pc);
int i; char byteBuff[33]; DEBUG_SEND_INT0 = LABEL_NEW (&DEBUG_SEND_INT0, pc); ADD("3","9","0",pc); //Value to be displayed ADD("4","A","0",pc); //Registernumber LLI("1","1",pc); UART_SEND_STRING("Content of reg 0x",pc); TOASCII("9", "4", "1", pc); CALL(UART_SEND,pc); TOASCII("9", "4", "0", pc); CALL(UART_SEND,pc); UART_SEND_STRING(" is: 0x",pc); for(i=7;i>=0;i--){ sprintf (byteBuff, "%X",i); LLI("2",byteBuff,pc); TOASCII("9", "3", "2", pc); CALL(UART_SEND,pc); } UART_SEND_STRING("\n\r",pc); RETURN(pc);
char* sendMemoryStart = "9"; char* sendMemoryLength = "A"; char* sendContent = "9"; char* tempReg1 = "3"; UART_SEND_MEM = LABEL_NEW (&UART_SEND_MEM, pc); LLI (tempReg1,"1",pc); ADD("1",sendMemoryStart,"0",pc); ADD("2",sendMemoryLength,"0",pc); UART_SEND_MEM_INT0 = LABEL_NEW (&UART_SEND_MEM_INT0, pc); LW(sendContent,"1",pc); CALL(UART_SEND,pc); ADD("1","1",tempReg1,pc); SUB("2","2",tempReg1,pc); BZC (UART_SEND_MEM_INT0,pc); // if we are done leave RETURN(pc);
char* tempReg1 = "1"; UART_RECV = LABEL_NEW(&UART_RECV, pc); LLI (tempReg1,io_UART_RXD_HAS_NEW_VALUE,pc); UART_RECV_INT0 = LABEL_NEW (&UART_RECV_INT0, pc); LW("9",tempReg1,pc);
BZS(UART_RECV_INT0,pc); LLI (tempReg1,io_UART_GET_RXD_BYTE,pc); LW("9",tempReg1,pc); RETURN(pc);
char* sendContent = "9"; char* tempReg1 = "1"; char* tempReg2 = "2";
UART_SEND = LABEL_NEW(&UART_SEND, pc); LLI (tempReg1,io_UART_TXD_READY_TO_SEND,pc); UART_SEND_INT0 = LABEL_NEW (&UART_SEND_INT0, pc); LW(tempReg2,tempReg1,pc);
BZS(UART_SEND_INT0,pc); //Comment out for simulation LLI (tempReg2, io_UART_SET_TXD_BYTE,pc); // $2 := Address To UART send now flag
SW(tempReg2,sendContent,pc); // set UART TXD BYTE to $6 LLI (tempReg1,"1",pc); LLI (tempReg2, io_UART_TXD_SEND_NOW,pc); SW(tempReg2,tempReg1,pc); // trigger UART send now flag SW(tempReg2,"0",pc); // disable UART send now flag RETURN(pc);
LLI("1D","1FF",pc); //Initialize Stack BR(START_INT0,pc); //Start User Program
CALL_INT0 = LABEL_NEW (&CALL_INT0, pc); //Call invoked (reg 0x1B has (callingAddress-1) int i; char memBuff[33]; LLI("1C","1",pc); //Increment/Decrement for(i=START_MEM_REG;i<(START_MEM_REG+NUM_OF_MEM_REG);i++) { sprintf (memBuff, "%X",i); memBuff[16]='\0'; SUB("1D","1D","1C",pc); //decrement Stackpointer SW("1D",memBuff,pc); //"push" on stack } SUB("1D","1D","1C",pc); //decrement Stackpointer LLI("1C", "3",pc); //(callingAddress-1) + 3 = next instr. after a call (return address) ADD("1C","1C","1B",pc); //correcting call Address SW ("1D","1C",pc); //"push" return address on Stack LLI("1C", "2",pc); //(callingAddress-1)+2 = (callingAddress+1) -> next instruction which is the actual branch to the function called ADD("1B","1B","1C",pc); //correcting backjmp JR("1B",pc); //backjmp
RETURN_INT0 = LABEL_NEW (&RETURN_INT0, pc); //Return invoked
LLI("1C","1",pc); LW("1B","1D",pc); ADD("1D","1D","1C",pc); for(i=(START_MEM_REG+NUM_OF_MEM_REG-1);i>=START_MEM_REG;i--) { sprintf (memBuff, "%X",i); memBuff[16]='\0'; LW(memBuff,"1D",pc); ADD("1D","1D","1C",pc); } JR("1B",pc);
UART_SEND_MEM_FUNC(pc); UART_RECV_FUNC(pc); UART_SEND_FUNC(pc); START_INT0 = LABEL_NEW (&START_INT0, pc);