Computer Architecture Lab/WS2007/Project -1 Lab4/Samples

Sample Files edit

To write a program for the Lucky Processor following steps are necessary:

  1. Use the assembler instructions to write an assembler program and save it as MyProgram.asm
  2. Drag the MyProgram.asm File on the "ToInstrMemUpdate ROM-File ASM.bat" Icon; Press Enter when it's finished
  3. Compile the Lucky.qpf Project in Quartus
  4. In the Command Prompt type in: "USBRunner MIPTop.rbf"

RandomBitTest.asm edit

Counts the number of 0s and 1s and writes, this and the content of the Random Register, to the Terminal.

UART_SEND_STRING("Let's Go!",&pc); 

LLI ("4", "0"); //Initial Value of Register 4 that contains 0s = 0
LLI ("5", "0"); //Initial Value of Register 5 that contains 1s = 0
LLI ("6", "1"); //Adder value 


LABEL(OUTPUT) //Here the actual values of $1E and counted 0s and 1s are written to the terminal

ADD("1","0","1E"); /* get current random value */
UART_SEND_STRING("\r\nInhalt Random Register: ",&pc);
DEBUG_SEND("1",&pc); /* send random value */

UART_SEND_STRING("\r\nANZAHL 0en: ",&pc);
DEBUG_SEND("4", &pc); /* send counted 0s */

UART_SEND_STRING("\r\nANZAHL 1en: ",&pc);
DEBUG_SEND("5", &pc); /* send counted 1s */


BOR(TAKEN); 
ADD("4", "4", "6"); //if Random Bit is not set Add 1 to 0s-Register
BR(OUTPUT); //Jump to OUTPUT

LABEL(TAKEN)
ADD("5", "5", "6"); //if Random Bit is set Add 1 to 1s-Register
BR(OUTPUT); //Jump to OUTPUT

HelloWorld.asm edit

Writes "Hello World! " to the Terminal

UART_SEND_STRING("Hello World! ",&pc);
LABEL(infinity)
NOOP();
BR(infinity);


BlinkingLEDs.asm edit

Toggles 2 LEDs

		LLI("0", "0");			// $0:= 0
		LLI ("1",io_WD);		
		LLI ("2", io_LED0);		
		LLI ("3", io_LED1);		
		LLI("4", "1");			// $4:= 1;	

		SW("1","4");			// MEM(io_WD) = 1			
		SW("2","4");			// MEM(io_LED0) = 1	
		SW("3","4");			// MEM(io_LED1) = 1
		LLI("8", "1");			// $8:= 1;			
LABEL(prewait)
		LLI("6","0000"); 		// $6:= 0
		SLL("6","6","8");		// $6:= 0
		LLI("7","04");			// $7:= 4
		ADD("6","6","7");		// $6:= 4
LABEL(wait)
		SUB("6","6","4");		// $6:= 3 .. 2 .. 1 .. 0
		BZS(selectswap);		
		BR(wait);
LABEL(selectswap)
		ADD("8","8","0");		// ...... $8:= 1
		BZS(swap);
		BR(swap2);
LABEL(swap)	
		SW("1","0");			
		SW("2","4");
		SW("3","4");
		LLI("8", "1");
		BR(prewait);
LABEL(swap2)	
		SW("1","4");			// ...... SWITCH Leds ....
		SW("2","0");
		SW("3","4");
		LLI("8", "0");
		BR(prewait);

casino.asm edit

A Slotmachine: Press any key to start the game, use Button0 to increase coins

/*
**** Casino 0.1 ****

Coins: 1

Result: x x x

**********************


**** Casino 0.1 ****

Coins: 1

Result: x x x

YOU HAVE WON y COIN(s)!!!

NEW GAME       PRESS SWITCH 1
INSERT COIN     PRESS SWITCH 2
**********************


Gewinn wird in Coins ausgezahlt

x = {A, B, C}
Wenn Alle gleich => +3 Coins

Fang immer mit A B C an

Schleife 32 x
	Timer ...
	Je nach ZV wechsle x1 .. x3
	Beim Wechseln piepe, toggle Leds
ZV:
xxxx xxxx xxxx xxxx xxxx xxxx xxxx xxxx
1111 1111 0101 0010 0100 1000 1000 1000 	A	 
1111 0101 0010 0100 1000 1000 1000 0100 	A*	= 0xF5248884
1010 1010 0100 1000 1000 1000 0100 0010 	B*	= 0xAA488842
0010 0100 1000 1000 1000 0100 0010 0001  	C*	= 0x24888421
0100 1000 1000 1000 0100 0010 0000 1000       B
1000 1000 1000 0100 0010 0000 1000 0010       B*
1000 1000 0100 0010 0000 1000 0010 0000       A*
1000 0100 0010 0000 1000 0010 0000 0100	A
0100 0010 0000 1000 0010 0000 0100 0000	C*
0010 0000 1000 0010 0000 0100 0000 1000	C

*/


//***************************************************** D  E  F  I  N  E  S *****************************************************
// ******************************************** PROG PARAMETERS
#define WAIT_VALUE		"00025B9A"
// ******************************************** ASCII
#define BACKSPACE		"8"
#define LF			"A"
#define CR			"D"

// ******************************************** MEMORY
#define RN_MEM			"10"
#define COINS			"60"
#define RN1			"61"
#define RN2			"62"
#define RN3			"63"
#define RN1_SWAP		"64"
#define RN2_SWAP		"65"
#define RN3_SWAP		"66"
#define WIN			"67"


// ******************************************** REGISTER-INDEX
// Special Regs
#define ZERO_REG		"0"
#define RANDOM_REG		"1E"


// PUSHED TO STACK
#define INC_REG			"1"
#define RN_MEM_REG		"2"
#define LMEMR1			"3"
#define LMEMR2			"4"
#define LED0_REG		"5"
#define LED1_REG		"6"
#define WIN_REG			"7"
#define LR1			"8"

//  must watch consistency for yourself
#define FUNC_RET_REG		"9"
#define TR1			"A"
#define TR2			"B"
#define TR3			"C"
#define TMEMR1			"D"
#define TMEMR2			"E"
#define GLOBAL_INDEX_REG  	"F"
#define TR4			"10"



START()

//******************************************** I  N  I  T  I  A  L  I  Z  A  T  I  O  N *************************************

// Standard-Register inits
	LLI (LED0_REG, io_LED0);
	LLI (LED1_REG, io_LED1);
	
	SW(LED0_REG, ZERO_REG);
	SW(LED1_REG, ZERO_REG);	

	LLI (INC_REG, "1");
	LLI (RN_MEM_REG, RN_MEM);

// store init values for random numbers into RAM
	ADD (TR1, RN_MEM_REG, ZERO_REG);
	LOAD_BIG_NUMBER (TR2, TR3, "F5248884", &pc);		// speichere schnelles A
	SW (TR1, TR2);

	ADD (TR1, TR1, INC_REG);
	LOAD_BIG_NUMBER (TR2, TR3, "AA488842",&pc);		// speichere schnelles B
	SW (TR1, TR2);

	ADD (TR1, TR1, INC_REG);
	LOAD_BIG_NUMBER (TR2, TR3, "24888421",&pc);		// speichere schnelles C
	SW (TR1, TR2);

	// ###FIX: C wird viermal reingespeichert, da vom random generator ein index im Bereich [0,3] geliefert wird
	ADD (TR1, TR1, INC_REG);
	SW (TR1, TR2);

// Init Coin Number and Results
	LLI (TMEMR1, COINS);
	LLI (TR1, "3");
	SW (TMEMR1, TR1);
	
	LLI (TMEMR1, RN2);
	LLI (TR1, "1");
	SW (TMEMR1, TR1);

	LLI (TMEMR1, RN3);
	LLI (TR1, "2");
	SW (TMEMR1, TR1);
	//### default is zero

//***************************************************** M   A   I   N    *****************************************************

LABEL(MAIN)
	
//******************* G E T     R A N D O M    N U M B E R S


//******************* S T A R T    G A M E
	LOAD_BIG_NUMBER (GLOBAL_INDEX_REG, TR3, "80000000",&pc);

	// decrement coins
	LLI (TMEMR1, COINS);
	LW (TR1, TMEMR1);
	SUB (TR1, TR1, INC_REG);
	SW (TMEMR1, TR1);

	CALL (SHOW_BOARD);
	CALL (GET_RANDOM_NR);

LABEL(SWAP_CONTINUE)
	
	CALL(WAIT);

	CALL (SWAP);
	CALL (SHOW_BOARD_REFRESH_RNs);
	
	SRL (GLOBAL_INDEX_REG, GLOBAL_INDEX_REG, "1");
	BZS (SWAP_END);
	BR(SWAP_CONTINUE);		

LABEL(SWAP_END)
	CALL (CALCULATE_COINS);
	CALL (WAIT_FOR_NEXT_GAME);
	BR (MAIN);


//***************** G E T   R A N D O M   N U M B E R S *************************************************
LABEL(GET_RANDOM_NR)
	LLI (TR2, "3"); //###FIX: RNMEM+3 moeglich, daher wurde oben der Wert fuer C zweimal eingefuegt
	LLI (TMEMR1, RN1_SWAP);
	LLI (TMEMR2, RN3_SWAP);
	ADD (TMEMR2, TMEMR2, INC_REG);

LABEL(INIT_RNs_LOOP)

	AND (TR1, RANDOM_REG, TR2);	//###FIX: TR4 uebernimmt vorlaufig Part des Random Registers
	ADD (TR3, TR1, RN_MEM_REG);	// TR3 := Random_Number (untere 2 Bits) + Addresse vom schnellen A bzw B, C

	LW (TR1, TR3);			
	SW (TMEMR1, TR1); 		// MEM (RN1_SWAP) := MEM (TR3);
	
	ADD (TMEMR1, TMEMR1, INC_REG);  // inkrementiere Pointer solange bis RN1_SWAP bis RN3_SWAP geschrieben wurde
	SUB (TR1, TMEMR2, TMEMR1);
	BZS (INIT_RNs_END);
	BR(INIT_RNs_LOOP);

LABEL(INIT_RNs_END)
	RETURN();
//***************** C A L C U L A T E    C O I N    N U M B E R     *************************************************

LABEL(CALCULATE_COINS)
	LLI(WIN_REG, WIN);
	LLI (LMEMR1, RN1);
	LLI (LMEMR2, RN2);
	LW(TR1, LMEMR1);
	LW(TR2, LMEMR2);
	SUB(TR3, TR1, TR2);
	BZC(NO_WIN);
	LLI (LMEMR1, RN3);		
	LW(TR2, LMEMR1);
	SUB(TR3, TR1, TR2);
	BZC(NO_WIN);
	// WIN
	SW(WIN_REG, INC_REG);

	LLI (TMEMR1, COINS);
	LLI (TR2, "3");
	LW (TR1, TMEMR1);
	ADD (TR1, TR1, TR2);
	SW (TMEMR1, TR1);
	UART_SEND_STRING ("\a\n\r Y O U    W I N    3    C O I N S !!!!! \n\r",&pc);
	BR(CALCULATE_COINS_END);

LABEL(NO_WIN)
	SW(WIN_REG,"0");
	UART_SEND_STRING ("\a\a\n\r Y O U    L O O S E    1    C O I N!!!!! \n\r",&pc);
	
LABEL(CALCULATE_COINS_END)
	RETURN();

//*********************************************************** S W A P     *************************************************
LABEL(SWAP)
	LLI (LR1, "0");
	LLI (TR3, "3");	
	LLI (LMEMR2, RN1);
	LLI (LMEMR1, RN1_SWAP);
	LLI (TMEMR1, RN3_SWAP);

LABEL(SWAP_LOOP)
	LW (TR1, LMEMR1);
	AND (TR2, GLOBAL_INDEX_REG, TR1);
	BZS (NO_SWAP);

LABEL(DO_SWAP)
	LLI (LR1, "1");
	LW (TR1, LMEMR2);
	ADD (TR1, TR1, INC_REG);
	SUB(TR2, TR1, TR3);
	BZC(SWAP_RN);
	LLI (TR1, "0");	
	
LABEL(SWAP_RN)
	SW (LMEMR2, TR1);			

LABEL(NO_SWAP)
	ADD (LMEMR1, LMEMR1, INC_REG);
	ADD (LMEMR2, LMEMR2, INC_REG);
	SUB (TR1, TMEMR1, LMEMR1);
	BNS (END_SWAP);
	BR(SWAP_LOOP);	

LABEL(END_SWAP)
	SUB(LR1, LR1, INC_REG);
	BZC(END_SWAP2);
	UART_SEND_STRING ("\a",&pc);

LABEL(END_SWAP2)
	RETURN();
	
//*********************************************************** W  A  I  T     *************************************************
LABEL(WAIT)
	LOAD_BIG_NUMBER (TR1, TR3, WAIT_VALUE,&pc); 	// Index bit ist MSB

LABEL(WAIT_LOOP)
	SUB (TR1, TR1, INC_REG);
	BZS (WAIT_END);
	NOOP();
	BR(WAIT_LOOP);	

LABEL(WAIT_END)
	RETURN();

//********************************************* D  I  S  P  L  A  Y   B  O  A  R  D     ************************************

LABEL(SHOW_BOARD)

	UART_SEND_STRING ("\f\r\n**** Casino 0.1 **** \n\r\nCoins: ",&pc);
	LLI (TMEMR1, COINS);
	LW (TR1, TMEMR1);
	ADD (TR1, INC_REG, TR1);	// Notwendig damit die Schleife richtig terminiert

LABEL(SHOW_BOARD_COINS)
	SUB (TR1, TR1, INC_REG);
	BZS (SHOW_BOARD_RNS_INIT);
	UART_SEND_STRING ("c",&pc);
	BR(SHOW_BOARD_COINS);

LABEL(SHOW_BOARD_RNS_INIT)
	UART_SEND_STRING("\n\rResults: ",&pc);	
LABEL(SHOW_BOARD_RNS)
	LLI (LMEMR1, RN1);
	SUB (LMEMR1, LMEMR1, INC_REG); // Notwendig damit die Schleife richtig terminiert
	LLI (LMEMR2, RN3);
	ADD (LMEMR2, LMEMR2, INC_REG); // Notwendig damit die Schleife richtig terminiert

LABEL(SHOW_BOARD_RNS_LOOP)	
	ADD (LMEMR1, LMEMR1, INC_REG);
	SUB(TR1, LMEMR2, LMEMR1);
	BZS (SHOW_BOARD_END);
	
	LW (TR1, LMEMR1);		// TR1 ist aktueller Wert der betrachteten Zufallsvariablen
	
	SUB (TR2, TR1, INC_REG);	// Wenn TR1 == 1 dann PRINT B
	BZS (PRINT_B);
	SUB (TR2, TR2, INC_REG);	// Wenn TR2 == 2 dann PRINT C
	BZS (PRINT_C);
//PRINT_A:
	UART_SEND_STRING ("A ",&pc);	// Ansonsten PRINT A
	BR(SHOW_BOARD_RNS_LOOP);	
LABEL(PRINT_B)
	UART_SEND_STRING ("B ",&pc);
	BR(SHOW_BOARD_RNS_LOOP);
LABEL(PRINT_C)		
	UART_SEND_STRING ("C ",&pc);
	BR(SHOW_BOARD_RNS_LOOP);

LABEL(SHOW_BOARD_END)	
	RETURN();

LABEL(SHOW_BOARD_REFRESH_RNs)
	UART_SEND_STRING ("\b\b\b\b\b\b",&pc);
	BR(SHOW_BOARD_RNS);

LABEL(WAIT_FOR_NEXT_GAME)
	UART_SEND_STRING ("<PRESS BUTTON 1 TO INSERT COIN> \n\r",&pc);	
	UART_SEND_STRING ("<PRESS ANY KEY TO START NEW GAME> \n\r",&pc);
	UART_SEND_STRING ("**********************\n\r",&pc);

LABEL(check_UARTInput_INIT)
	LLI (TR1, io_UART_RXD_HAS_NEW_VALUE);
	LLI (TR2, io_BUTTON0);

LABEL(checkUARTInput)		// wait on any uart input
	LW (TR3, TR1);		// check io_UART_RXD_HAS_NEW_VALUE
	BZC(START_NEW_GAME); 	// wait on new received byte
	LW (TR3, TR2);
	BZC(INSERT_COIN);
	BR(checkUARTInput);

LABEL(NO_COINS_AVAILABLE)
	UART_SEND_STRING ("** S O R R Y , Y O U   H A V E   N O   M O R E   C R E D I T S! ** \n\r",&pc);	
	BR(check_UARTInput_INIT);	

LABEL(INSERT_COIN)
	UART_SEND_STRING ("+ + Coin inserted + +\n\r", &pc);
	LLI (TMEMR1, COINS);	
	LW (TR3, TMEMR1);
	ADD (TR3, TR3, INC_REG);
	SW (TMEMR1, TR3);
	CALL(WAIT);
	BR(check_UARTInput_INIT);

LABEL(START_NEW_GAME)
	LLI (TMEMR1, COINS);
	LW (LR1, TMEMR1);
	ADD (LR1, LR1, "0");
	BZS (NO_COINS_AVAILABLE);

LABEL(SHOW_BOARD_FINISH_END)
	RETURN();