Thread: Simulator

  1. #1
    Registered User
    Join Date
    Apr 2008
    Posts
    15
    I am having a problem with my cpu simulation. The first code is what I was required to write and it works with the second and third codes.

    The second code is what really decides what it is my program does. In order to make it run you have to create an input file(I use notepad) with machine code in the format of 0x12345678 in .asc format. I drag and drop the file into the executable of the program.

    My decode function has to break down the machine code by splitting the hex machine code into parts and the rest of the program runs by using these different parts to run their function.

    When I run the program you enter various inputs to debug it.
    They are:

    m // see what is stored in memory

    r // This shows the register values.

    g // This displays the control signal

    s[n] // This simulates the next n(any integer) instructions.

    c // Continues as long as program doesn't halt

    p // This prints out the machine code from input file

    When I perform s and then enter g to display the control signal it seems like it is working.
    When I press s and g again it displays the same control signal no matter what number I enter into s[] even though I know their are many different machine codes in the input file. If anyone can see anything in the first code that might be causing such a problem I would really appreciate the input.

    Code:
    #include "spimcore.h"
    
    int i = 0;
    
    /* ALU */
    void ALU(unsigned A,unsigned B,char ALUControl,unsigned *ALUresult,char *Zero)
    {
          if(ALUControl == 0)
          {
                *ALUresult = (A + B);
          }
          
          else if(ALUControl == 1)
          {
                *ALUresult = (A - B);
          }
          
          else if(ALUControl == 2)
          {
                if(A < B)
                {
                      *ALUresult = 1;
                }
                
                else
                {
                      *ALUresult = 0;
                }
          }
          
          else if(ALUControl == 3)
          {
                if((A >= 0) && (B >= 0))
                {
                      *ALUresult = 1;
                }
                
                else
                {
                      *ALUresult = 0;
                }
          }
          
          else if(ALUControl == 4)
          {
                *ALUresult = (A & B);
          }
          
          else if(ALUControl == 5)
          {
                *ALUresult = (A | B);
          }
          
          else if(ALUControl == 6)
          {
                B = B * 65536;
                *Zero = 0;
          }
          
          else
          {
                *ALUresult = (!(A | B));
          }
          
          
          if(*ALUresult == 0)
          {
                *Zero = 1;
          }
          
          else
          {
                *Zero = 0;
          }
    }
    
    /* instruction fetch */
    int instruction_fetch(unsigned PC,unsigned *Mem,unsigned *instruction)
    {
          unsigned nPC = (PC << 2);
          instruction = &Mem[nPC];
           
          if((nPC) % 4 != 0)
          {
                return 1;
          }
          
          else if((nPC) > 65536)
          {
                return 1;
          }
          
          else
          {
                return 0;
          }
    }
    
    // instruction partition 
    void instruction_partition(unsigned instruction, unsigned *op, unsigned *r1,unsigned *r2, unsigned *r3, unsigned *funct, unsigned *offset, unsigned *jsec)
    {
          *op = instruction >> 25;
          *r1 = (instruction >> 20) & 0x1F;
          *r2 = (instruction >> 15) & 0x1F;
          *r3 = (instruction >> 10) & 0x1F;
          *funct = (instruction >> 0) & 0x3F;
          *offset = instruction & 0XFFFF;
          *jsec = instruction & 0x3FFFFFF;
          
          // add $s1, $s2, $s3
          /*if(instruction == 0x02538820)
          {
                // 0
                *op = 0;
                // 18
                *r1 = 18;
                // 19
                *r2 = 19;
                // 17
                *r3 = 17;
                //32
                *funct = 32;
          }
          
          // sub $s1, $s2, $s3
          else if(instruction == 0x02538822)
          {
                // 0
                *op = 0;
                // 18
                *r1 = 18;
                // 19
                *r2 = 19;
                // 17
                *r3 = 17;
                // 36
                *funct = 36;
          }
          
          // addi $s1, $s2, 100
          else if(instruction == 0x22510064)
          {
                // op = 8
                *op = 8;
                // r1 = 18
                *r1 = 18;
                // r2 = 17
                *r2 = 17;
                // offset = 100
                *offset = 100;
          }
          
          // and $s1, $s2, $s3
          else if(instruction == 0x02538824)
          {
                // op = 0
                *op = 0;
                // r1 = 18
                *r1 = 18;
                // r2 = 19
                *r2 = 19;
                // r3 = 17
                *r3 = 17;
                // funct = 36
                *funct = 36;
          }
          
          // or $s1, $s2, $s3
          else if(instruction == 0x02538825)
          {
                // op = 0
                *op = 0;
                *r1 = 18;
                *r2 = 19;
                *r3 = 17;
                // funct = 37
                *funct = 37;
          }
          
          // nor $s1, $s2, $s3
          else if(instruction == 0x02538827)
          {
                *op = 0;
                *r1 = 18;
                *r2 = 19;
                *r3 = 17;
                *funct = 0x27;
          }
          
          // lw $s1, 100($s2)
          else if(instruction == 0x8e510064)
          {
                *op = 35;
                *r1 = 18;
                *r2 = 17;
                *offset = 100;
          }
          
          // lui $s1, 100
          else if(instruction == 0x6c110064)
          {
                //op = 27
                *op = 27;
                *r1 = 0;
                *r2 = 17;
                *offset = 100;
          }
          
          // sw $s1, 100($s2)
          else if(instruction == 0xad510064)
          {
                *op = 43;
                *r1 = 18;
                *r2 = 17;
                *offset = 100;
          }
          
          // slt $s1, $s2, $s3
          else if(instruction == 0x0253882a)
          {
                *op = 0;
                *r1 = 18;
                *r2 = 19;
                *r3 = 17;
                *funct = 0x2a;
          }
          
          // slti $s1, $s2, 100
          else if(instruction == 0x5a510064)
          {
                *op = 22;
                *r1 = 18;
                *r2 = 17;
                *offset = 100;
          }
          
          // sltu $s1, $s2, $s3
          else if(instruction == 0x0253882b)
          {
                *op = 0;
                *r1 = 18;
                *r2 = 19;
                *r3 = 17;
                // funct = 43
                *funct = 43;
                *offset;
                *jsec;
          }
          
          // sltiu $s1, $s2, 100
          else if(instruction == 0x5e510064)
          {
                // op = 23
                *op = 23;
                *r1 = 18;
                *r2 = 17;
                *offset = 100;
                *r3;
                *jsec;
                *funct;
          }
          
          // j 2500
          else if(instruction == 0x080009c4)
          {
                *op = 2;
                *jsec = 0x0009c4;
                *r1;
                *r2;
                *r3;
                *funct;
                *offset;
          }
          
          // beq $s1, $s2, 25
          else
          {
                // op = 4
                *op = 4;
                *r1 = 17;
                *r2 = 18;
                *offset = 100;
                *r3;
                *funct;
                *jsec;
          } */
    }
    
    /* instruction decode */
    int instruction_decode(unsigned op,struct_controls *controls)
    {    
          
           // R-Type Instruction 
          if(op == 0)
          {
                controls[i].MemRead = 0;
                controls[i].MemWrite = 0;
                controls[i].RegWrite = 1;
                controls[i].RegDst = 1;
                controls[i].Jump = 2;
                controls[i].Branch = 0;
                controls[i].MemtoReg = 0;
                controls[i].ALUSrc = 0;
                controls[i].ALUOp = 7;
                
                return 0;
          }
          
          // I-Type Instruction: addi
          else if(op == 8)
          {
                controls[i].MemRead = 0;
                controls[i].MemWrite = 0;
                controls[i].RegWrite = 1;
                controls[i].RegDst = 0;
                controls[i].Jump = 2;
                controls[i].Branch = 0;
                controls[i].MemtoReg = 0;
                controls[i].ALUSrc = 1;
                controls[i].ALUOp = 0;
                
                return 0;
          }
          
          // lw $s1, 100($s2)
          else if(op == 35)
          {
                controls[i].MemRead = 1;
                controls[i].MemWrite = 0;
                controls[i].RegWrite = 1;
                controls[i].RegDst = 0;
                controls[i].Jump = 2;
                controls[i].Branch = 0;
                controls[i].MemtoReg = 1;
                controls[i].ALUSrc = 1;
                controls[i].ALUOp;
                
                return 0;
          }
          
          // lui $s1, 100
          else if(op == 15)
          {
                controls[i].MemRead = 1;
                controls[i].MemWrite = 0;
                controls[i].RegWrite = 1;
                controls[i].RegDst = 0;
                controls[i].Jump = 2;
                controls[i].Branch = 0;
                controls[i].MemtoReg = 1;
                controls[i].ALUSrc = 1;
                controls[i].ALUOp;
                
                return 0;
          }
          
          // sw $s1, 100($s2)
          else if(op == 43)
          {
                controls[i].MemRead = 1;
                controls[i].MemWrite = 1;
                controls[i].RegWrite = 0;
                controls[i].RegDst = 2;
                controls[i].Jump = 2;
                controls[i].Branch = 0;
                controls[i].MemtoReg = 2;
                controls[i].ALUSrc = 1;
                controls[i].ALUOp;
                
                return 0;
          }
          
          // slti $s1, $s2, 100
          else if(op == 10)
          {
                controls[i].MemRead = 0;
                controls[i].MemWrite = 0;
                controls[i].RegWrite = 1;
                controls[i].RegDst = 0;
                controls[i].Jump = 2;
                controls[i].Branch = 2;
                controls[i].MemtoReg = 0;
                controls[i].ALUSrc = 1;
                controls[i].ALUOp = 6;
                
                return 0;
          }
          
          // sltiu $s1, $s2, 100
          else if(op == 11)
          {
                controls[i].MemRead = 0;
                controls[i].MemWrite = 0;
                controls[i].RegWrite = 1;
                controls[i].RegDst = 0;
                controls[i].Jump = 0;
                controls[i].Branch = 2;
                controls[i].MemtoReg = 0;
                controls[i].ALUSrc = 1;
                controls[i].ALUOp = 6;
                
                return 0;
          }
          
          // jump 2500
          else if(op == 2)
          {
                controls[i].RegDst = 2;
                controls[i].Jump = 1;
                controls[i].Branch = 0;
                controls[i].MemtoReg = 0;
                controls[i].MemRead = 0;
                controls[i].MemWrite = 0;
                controls[i].RegWrite = 0;
                controls[i].ALUSrc = 0;
                controls[i].ALUOp;
                
                return 0;
          }
          
          // beq
          else if(op == 4)
          {
                controls[i].MemRead = 0;
                controls[i].MemWrite = 0;
                controls[i].RegWrite = 0;
                controls[i].RegDst = 2;
                controls[i].Jump = 2;
                controls[i].Branch = 1;
                controls[i].MemtoReg = 2;
                controls[i].ALUSrc = 0;
                controls[i].ALUOp = 1;
                
                return 0;
          }
          
          // op not here
          else
          {
                return 1;
          }
          
          ++i;
    }
    
    /* Read Register */
    void read_register(unsigned r1,unsigned r2,unsigned *Reg,unsigned *data1,unsigned *data2)
    {
          *data1 = Reg[r1];
          *data2 = Reg[r2];
    }
    
    /* Sign Extend */
    void sign_extend(unsigned offset,unsigned *extended_value)
    {
          if(offset == 0x64)
          {
                *extended_value = 0x00000064;
          }
          
          else if(offset == 0x0000)
          {
                *extended_value = 0x00000000;
          }
          
          else
          {
                *extended_value = 0x0000000F;
          }
    }
    
    /* ALU operations */
    int ALU_operations(unsigned data1,unsigned data2,unsigned extended_value,unsigned funct,char ALUOp,char ALUSrc,unsigned *ALUresult,char *Zero)
    {
          // R-Type Instructions(ALUOp = 111): ALUSrc comes from data2
          if((ALUSrc == 0) && (ALUOp == 7))
          {
                // ADD
                if(funct == 32)
                {
                      ALUOp = 0;
                      ALU(data1, data2, ALUOp, ALUresult, Zero);
                }
                
                // SUBTRACT
                else if(funct == 34)
                {
                      ALUOp = 1;
                      ALU(data1, data2, ALUOp, ALUresult, Zero);
                }
                
                // AND
                else if(funct == 36)
                {
                      ALUOp = 4;
                      ALU(data1, data2, ALUOp, ALUresult, Zero);
                }
                
                // OR
                else if(funct == 37)
                {
                      ALUOp = 5;
                      ALU(data1, data2, ALUOp, ALUresult, Zero);
                }
                
                // NOR
                else if(funct == 39)
                {
                      ALUOp = 7;
                      ALU(data1, data2, ALUOp, ALUresult, Zero);
                }
                
                // None of the above: Not recognized.
                else
                {
                      return 1;
                }
          }
          
          // I-Type Instruction
          else if(ALUSrc == 1)
          {     // ADD IMMEDIATE
                if(ALUOp == 0)
                {
                      ALU(data1, extended_value, ALUOp, ALUresult, Zero); 
                }
                
                // BEQ
                else if(ALUOp == 1)
                {
                      ALU(data1, extended_value, ALUOp, ALUresult, Zero); 
                }
                
                else if(ALUOp == 2)
                {
                      ALU(data1, extended_value, ALUOp, ALUresult, Zero); 
                }
                
                else if(ALUOp == 3)
                {
                      ALU(data1, extended_value, ALUOp, ALUresult, Zero); 
                }
                
                else if(ALUOp == 4)
                {
                      ALU(data1, extended_value, ALUOp, ALUresult, Zero); 
                }
                
                else if(ALUOp == 5)
                {
                      ALU(data1, extended_value, ALUOp, ALUresult, Zero); 
                }
                
                // Set Less Than Immediate / Set Less Than Immediate Unsigned
                else if(ALUOp == 6)
                {
                      ALU(data1, extended_value, ALUOp, ALUresult, Zero); 
                }
                
                else
                {
                      return 1;
                }
          }
          
          else
          {
                return 1;
          }
    }
    
    /* Read / Write Memory */
    int rw_memory(unsigned ALUresult,unsigned data2,char MemWrite,char MemRead,unsigned *memdata,unsigned *Mem)
    {
          if(MemWrite == 1)
          {
                if((ALUresult % 4)!= 0)
                {
                      return 1;
                }
                
                else
                {
                      memdata = &ALUresult;
                }
          }
          
          else if(MemRead == 1)
          {
                if((ALUresult % 4)!= 0)
                {
                      return 1;
                }
                
                else
                {
                      ALUresult = data2;
                }
          }
          
          else 
          {
                return 1;
          }
    }
    
    /* Write Register */
    void write_register(unsigned r2,unsigned r3,unsigned memdata,unsigned ALUresult,char RegWrite,char RegDst,char MemtoReg,unsigned *Reg)
    {
          if(RegWrite == 1)
          {
                if(RegDst == 1)
                {
                      Reg[r3] = ALUresult;
                }
                
                else // if(RegDst == 0)
                {
                      Reg[r2] = ALUresult;
                }
          }
          
          else if(MemtoReg == 1)
          {
                Reg[r2] = memdata;
          }
          
          // MemtoReg == 0
          else
          {
                Reg[r3] = ALUresult;
          }
    }
    
    /* PC update */
    void PC_update(unsigned jsec,unsigned extended_value,char Branch,char Jump,char Zero,unsigned *PC)
    {
          if(Jump == 1)
          {
                PC = PC + jsec;
          }
          
          else if (Branch == 1)
          {
                extended_value = (extended_value << 2);
                PC = PC + extended_value;
          }
          
          else
          {
                PC = PC  + 4;
          }
    }
    Code:
    #include "spimcore.h"
    #include "project.c"
    
    
    #define MEMSIZE (65536 >> 2)
    #define REGSIZE 32
    #define BUFSIZE 256
    
    #define PCINIT 0x4000
    #define SPINIT 0xFFFC
    #define GPINIT 0xC000
    
    static unsigned Mem[MEMSIZE];
    static unsigned Reg[REGSIZE + 4];
    
    #define MEM(addr) (Mem[addr >> 2])
    
    #define PC (Reg[REGSIZE + 0])
    #define Status (Reg[REGSIZE + 1])
    #define LO (Reg[REGSIZE + 2])
    #define HI (Reg[REGSIZE + 3])
    
    const char RegName[REGSIZE + 4][6] = {
    	"$zero", "$at", "$v0", "$v1", "$a0", "$a1", "$a2", "$a3",
    	"$t0", "$t1", "$t2", "$t3", "$t4", "$t5", "$t6", "$t7", 
    	"$s0", "$s1", "$s2", "$s3", "$s4", "$s5", "$s6", "$s7", 
    	"$t8", "$t9", "$k0", "$k1", "$gp", "$sp", "$fp", "$ra",
    	"$pc", "$stat", "$lo", "$hi" };
    
    #define NREG(name) (*Nreg(name))
    
    const char RedirNull[] = "";
    const char RedirPrefix[] = ">";
    
    static char Buf[BUFSIZE];
    static int Halt = 0;
    static FILE *FP;
    static char *Redir = (char *) RedirNull;
    
    /*** DATAPATH Signals ***/
    // names of instruction sections
    unsigned instruction;
    unsigned op,	// instruction [31-26]
    	r1,	// instruction [25-21]
    	r2,	// instruction [20-16]
    	r3,	// instruction [15-11]
    	funct,	// instruction [5-0]
    	offset,	// instruction [15-0]
    	jsec;	// instruction [25-0]
    
    // control signals
    struct_controls controls;
    
    // Register output
    unsigned data1,data2;
    
    // sign extend
    unsigned extended_value;
    
    // ALU result
    unsigned ALUresult;
    char Zero;
    
    // data read from Memory
    unsigned memdata;
    
    /******/
    
    
    unsigned *Nreg(char *name)
    {
    	int i;
    
    	for (i = 0; i < REGSIZE + 4; i++)
    	{
    		if (strcmp(name, RegName[i]) == 0)
    			return &Reg[i];
    		if (strcmp(name, RegName[i] + 1) == 0)
    			return &Reg[i];
    	}
    	return NULL;
    }
    
    void Init(void)
    {
    	memset(Reg, 0, (REGSIZE + 4) * sizeof(unsigned));
    	NREG("pc") = PCINIT;
    	NREG("sp") = SPINIT;
    	NREG("gp") = GPINIT;
    }
    
    
    void DisplayControlSignals(void)
    {
    	fprintf(stdout, "\tControl Signals: %0x%0x%0x%0x%03x%0x%0x%0x%0x\n", 
    			controls.RegDst, 
    			controls.Jump, 
    			controls.Branch, 
    			controls.MemRead, 
    			controls.MemtoReg, 
    			controls.ALUOp, 
    			controls.MemWrite, 
    			controls.ALUSrc, 
    			controls.RegWrite);
    }
    
    
    
    void Step(void)
    {
    	/* fetch instruction from memory */
    	Halt = instruction_fetch(PC,Mem,&instruction);
    
    	if(!Halt)
    	{
    		/* partition the instruction */
    		instruction_partition(instruction,&op,&r1,&r2,&r3,&funct,&offset,&jsec);
    
    		/* instruction decode */
    		Halt = instruction_decode(op,&controls);
    	}
    
    	if(!Halt)
    	{
    		/* read_register */
    		read_register(r1,r2,Reg,&data1,&data2);
    
    		/* sign_extend */
    		sign_extend(offset,&extended_value);
    
    		/* ALU */
    		Halt = ALU_operations(data1,data2,extended_value,funct,controls.ALUOp,controls.ALUSrc,&ALUresult,&Zero);
    	}
    
    	if(!Halt)
    	{
    		/* read/write memory */
    		Halt = rw_memory(ALUresult,data2,controls.MemWrite,controls.MemRead,&memdata,Mem);
    	}
    
    	if(!Halt)
    	{
    		/* write to register */
    		write_register(r2,r3,memdata,ALUresult,controls.RegWrite,controls.RegDst,controls.MemtoReg,Reg);
    
    		/* PC update */
    		PC_update(jsec,extended_value,controls.Branch,controls.Jump,Zero,&PC);
    	}
    }
    
    void DumpReg(void)
    {
    	int i;
    	char bb[] = "     ";
    
    	for (i = 0; i < REGSIZE + 4; i++)
    	{
    		fprintf(stdout, "%s %s%s %08x%s",
    			(i % 4 == 0) ? Redir : "",
    			RegName[i], bb + strlen(RegName[i]) * sizeof(char),
    			Reg[i], (i % 4 == 3) ? "\n" : "     ");
    	}
    }
    
    // Dump Memory Content where the addresses are in decimal format
    void DumpMem(int from, int to)
    {
    	int i, mt, ma;
    
    	(to < from) && (to = from);
    	if (from == to)
    	{
    		fprintf(stdout, "%s %05d        %08x\n", Redir, from, Mem[from]);
    	}
    	else
    	{
    		mt = Mem[ma = from];
    		for (i = from + 1; i <= to; i++)
    		{
    			if (i == to || Mem[i] != mt)
    			{
    				if (i == ma + 1)
    					fprintf(stdout, "%s %05d        %08x\n",
    						Redir, ma, mt);
    				else
    					fprintf(stdout, "%s %05d-%05d  %08x\n",
    						Redir, ma, i - 1, mt);
    				(i != to) && (mt = Mem[ma = i]);
    			}
    		}
    	}
    }
    
    
    // Dump Memory Content in Hex format
    void DumpMemHex(int from, int to)
    {
    	int i, mt, ma;
    
    	(to < from) && (to = from);
    	if (from == to)
    	{
    		fprintf(stdout, "%s %05x        %08x\n", Redir, from*4, Mem[from]);
    	}
    	else
    	{
    		mt = Mem[ma = from];
    		for (i = from + 1; i <= to; i++)
    		{
    			if (i == to || Mem[i] != mt)
    			{
    				if (i == ma + 1)
    					fprintf(stdout, "%s %05x        %08x\n",
    						Redir, ma*4, mt);
    				else
    					fprintf(stdout, "%s %05x-%05x  %08x\n",
    						Redir, ma*4, (i - 1)*4, mt);
    				(i != to) && (mt = Mem[ma = i]);
    			}
    		}
    	}
    }
    
    
    
    void DumpHex(int from, int to)
    {
    	int i, j;
    
    	if (to < from)
    	{
    		for (i = from, j = 0; i >= to; i--, j++)
    		{
    			if (j % 4 == 0)
    				fprintf(stdout, "%s %04x  ", Redir, (i << 2) + 3);
    			fprintf(stdout, " %08x%s", Mem[i], (j % 4 == 3) ? "\n" : "");
    		}
    	}
    	else
    	{
    		for (i = from, j = 0; i <= to; i++, j++)
    		{
    			if (j % 4 == 0)
    				fprintf(stdout, "%s %04x  ", Redir, i << 2);
    			fprintf(stdout, " %08x%s", Mem[i], (j % 4 == 3) ? "\n" : "");
    		}
    	}
    	if (j % 4 != 0)
    		fputc('\n', stdout);
    }
    
    void Loop(void)
    {
    	char *tp;
    	int sc;
    
    	Init();
    	for (;;)
    	{
    		fprintf(stdout, "\n%s cmd: ", Redir);
    		Buf[0] = '\0';
    		if (fgets(Buf, BUFSIZE, stdin) == NULL)
    			continue;
    		if ((tp = strtok(Buf, " ,.\t\n\r")) == NULL)
    			continue;
    		fputc('\n', stdout);
    		switch (*tp)
    		{
    			case 'g': case 'G':
    				DisplayControlSignals();
    				break;
    			case 'r': case 'R':
    				DumpReg();
    				break;
    			case 'm': case 'M':
    				if ((tp = strtok(NULL, " ,.\t\n\r")) == NULL)
    				{
    					DumpMemHex(0, MEMSIZE);
    				}
    				else
    				{
    					sc = (int) strtoul(tp, (char **) NULL, 10);
    					if ((tp = strtok(NULL, " ,.\t\n\r")) == NULL)
    					{
    						DumpMemHex(sc, MEMSIZE);
    					}
    					else
    					{
    						DumpMemHex(sc, (int) strtoul(tp, (char **) NULL, 10));
    					}
    				}
    				break;
    			case 's': case 'S':
    				if ((tp = strtok(NULL, " ,.\t\n\r")) == NULL)
    					sc = 1;
    				else
    				{
                                  sc = (int) strtoul(tp, (char **) NULL, 10);
                            }
    				while (sc-- > 0 && !Halt)
    					Step();
    				fprintf(stdout, "%s step\n", Redir);
    				break;
    			case 'c': case 'C':
    				while (!Halt)
    					Step();
    				fprintf(stdout, "%s cont\n", Redir);
    				break;
    			case 'h': case 'H':
    				fprintf(stdout, "%s %s\n", Redir, Halt ? "true" : "false");
    				break;
    			case 'p': case 'P':
    				rewind(FP);
    				sc = 0;
    				while (!feof(FP))
    				{
    					if (fgets(Buf, BUFSIZE, FP))
    						fprintf(stdout, "%s % 5d  %s", Redir, sc++, Buf);
    				}
    				break;
    			case 'i': case 'I':
    				fprintf(stdout, "%s %d\n", Redir, MEMSIZE);
    				break;
    			case 'd': case 'D':
    				if ((tp = strtok(NULL, " ,.\t\n\r")) == NULL)
    				{
    					fprintf(stdout, "%s invalid cmd\n", Redir);
    					break;
    				}
    				sc = (int) strtoul(tp, (char **) NULL, 10);
    				if ((tp = strtok(NULL, " ,.\t\n\r")) == NULL)
    				{
    					fprintf(stdout, "%sinvalid cmd\n", Redir);
    					break;
    				}
    				DumpHex(sc, (int) strtoul(tp, (char **) NULL, 10));
    				break;
    			case 'x': case 'X': case 'q': case 'Q':
    				fprintf(stdout, "%s quit\n", Redir);
    				if (Redir == (char *) RedirPrefix)
    				{
    					fprintf(stdout, "%s%s\n", Redir, Redir);
    				}
    				return;
    			default:
    				fprintf(stdout, "%s invalid cmd\n", Redir);
    				break;
    		}
    		if (Redir == (char *) RedirPrefix)
    		{
    			fprintf(stdout, "%s%s\n", Redir, Redir);
    		}
    	}
    }
    
    int main(int argc, char **argv)
    {
    	int i;
    	unsigned long t;
    
    	setvbuf(stdout, (char *) NULL, _IOLBF, 0);
    	if (argc != 2 && argc != 3)
    	{
    		fprintf(stderr, "syntax: %s input_file [-r]\n", argv[0]);
    		return 1;
    	}
    	if (*argv[1] == '-')
    	{
    		fprintf(stderr, "syntax: %s input_file [-r]\n", argv[0]);
    		return 1;
    	}
    	if ((FP = fopen(argv[1], "r")) == NULL)
    	{
    		fprintf(stderr, "%s: cannot open input file %s\n", argv[0], argv[1]);
    		return 1;
    	}
    	if (argc == 3)
    	{
    		if (strcmp(argv[2], "-r") == 0)
    		{
    			Redir = (char *) RedirPrefix;
    			fprintf(stdout, "%s\n", argv[0]);
    		}
    		else
    		{
    			fprintf(stderr, "syntax: %s input_file [-r]\n", argv[0]);
    			return 1;
    		}
    	}
    	memset(Mem, 0, MEMSIZE * sizeof(unsigned));
    	for (i = PCINIT; !feof(FP); i += 4)
    	{
    		if (fgets(Buf, BUFSIZE, FP) == NULL)
    		{
    			if (feof(FP))
    				break;
    			fprintf(stderr, "%s: file %s reading error\n", argv[0], argv[1]);
    			return 1;
    		}
    		if (sscanf(Buf, "%lx", &t) != 1)
    		{
    			fprintf(stderr, "%s: file %s error in line %d, continue...\n",
    				argv[0], argv[1], i - PCINIT + 1);
    			MEM(i) = 0;
    		}
    		else
    		{
    			MEM(i) = strtoul(Buf, (char **) NULL, 16);
    		}
    	}
    	Loop();
    	fclose(FP);
    	return 0;
    }
    Code:
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    
    #ifndef SPIMCORE
    
    typedef struct
    {
    	char RegDst;
    	char Jump;
    	char Branch;
    	char MemRead;
    	char MemtoReg;
    	char ALUOp;
    	char MemWrite;
    	char ALUSrc;
    	char RegWrite;
    }struct_controls;
    
    /* ALU */
    void ALU(unsigned A,unsigned B,char ALUControl,unsigned *ALUresult,char *Zero);
    
    /* fetch instruction from memory */
    int instruction_fetch(unsigned PC,unsigned *Mem,unsigned *instruction);
    
    /* instruction partition */
    void instruction_partition(unsigned instruction, unsigned *op, unsigned *r1,unsigned *r2, unsigned *r3, unsigned *funct, unsigned *offset, unsigned *jsec);
    
    /* instruction decode */
    int instruction_decode(unsigned op,struct_controls *controls);
    
    /* read_register */
    void read_register(unsigned r1,unsigned r2,unsigned *Reg,unsigned *data1,unsigned *data2);
    
    /* sign_extend */
    void sign_extend(unsigned offset,unsigned *extended_value);
    
    /* ALU */
    int ALU_operations(unsigned data1,unsigned data2,unsigned extended_value,unsigned funct,char ALUOp,char ALUSrc,unsigned *ALUresult,char *Zero);
    
    /* read/write memory */
    int rw_memory(unsigned ALUresult,unsigned data2,char MemWrite,char MemRead,unsigned *memdata,unsigned *Mem);
    
    /* write to register */
    void write_register(unsigned r2,unsigned r3,unsigned memdata,unsigned ALUresult,char RegWrite,char RegDst,char MemtoReg,unsigned *Reg);
    
    /* PC update */
    void PC_update(unsigned jsec,unsigned extended_value,char Branch,char Jump,char Zero,unsigned *PC);
    
    #define SPIMCORE
    #endif

    Machine code to save as a .asc file:
    0x22510064
    0x02538820
    0x02538822
    0x02538824
    0x8e510064
    Last edited by MasterAchilles; 11-30-2008 at 09:42 PM.

  2. #2
    Registered User
    Join Date
    Nov 2008
    Posts
    7

    same project

    im working on it too. does yours work when you run the command c? i don't understand what your problem is.

  3. #3
    Registered User
    Join Date
    Nov 2008
    Posts
    7

    if you want a reference...

    here is code which i was given, though im not sure it is working, nor do i know for sure how to tell if it is working
    Code:
    #include "spimcore.h"
    
    /* ALU */
    void ALU(unsigned A,unsigned B,char ALUControl,unsigned *ALUresult,char *Zero)
    {
    
       unsigned Z;   //temp storage for operations
       
       if(ALUControl = '0')   //add
            Z = A + B;
       if(ALUControl = '1')   //sub
            Z = A - B;
       if(ALUControl = '2')   //slt
            if((int)A<(int)B)         
                Z = 1;
            else         
                Z = 0;
       if(ALUControl = '3')   //sltu
            if(A<B)
                Z = 1;
            else 
                Z = 0;
       if(ALUControl = '4')   //and
            Z = A&B;
       if(ALUControl = '5')   //or
            Z = A|B;
       if(ALUControl = '6')   //sll
            Z = B<<16;
       if(ALUControl = '7')   //nor
             Z = ~(A|B);
    
       *ALUresult = Z;   // output the result of Z to ALUresult
       
       if(Z == 0)   //pointer Zero is set to 1 if result is 0 otherwise is set to 0
          *Zero = '1';
       else 
          *Zero = '0';
    
    }
    
    /* instruction fetch */
    int instruction_fetch(unsigned PC,unsigned *Mem,unsigned *instruction)
    {
    
       if (PC%4 != 0)   //check if PC is word alligned
          return 1;   //halt
       else 
       {
          *instruction = Mem[PC<<2];  //obtain instructions from memory address location at PC<<2
          if(*instruction == 0)
              return 1;   //halt
          else
              return 0;   //success
       }
    }
    
    
    /* instruction partition */
    void instruction_partition(unsigned instruction, unsigned *op, unsigned *r1,unsigned *r2, unsigned *r3, unsigned *funct, unsigned *offset, unsigned *jsec)
    {
         
          // shift to the right 26 bits to obtain bits 26-31 for opcode
       *op = (instruction >> 26);
          //shift to the right 21 then and it with 0x0000001F, 0x0 0001 1111 binary, for bits 21-25
       *r1 = ((instruction >> 21) & 0x0000001F);
          //shift to the right 16 then and it with 0x0000001F, 0x0 0001 1111 binary, for bits 16-20
       *r2 = ((instruction >> 16) & 0x0000001F);
          //shift to the right 11 then and it with 0x0000001F, 0x0 0001 1111 binary, for bits 11-15
       *r3 = ((instruction >> 11) & 0x0000001F);
          //and with 0x0000001F, 0x0 0001 1111 in binary, for the first 5 bits
       *funct = (instruction & 0x0000001F);
          //and with 0x00007FFF, 0x0 0111 1111 1111 1111 in binary, for the first 15 bits
       *offset = (instruction & 0x00007FFF);
          //and with 0x01FFFFFF, 0000 0001 1111 1111 1111 1111 1111 1111, in binary, for the first 25 bits
       *jsec = (instruction & 0x01FFFFFF);
    }
    
    
    
    /* instruction decode */
    int instruction_decode(unsigned op,struct_controls *controls)
    {
        
          // R-Type
       if((op == 0))
       {  
          controls->RegDst = '1';
          controls->Jump = '0';
          controls->Branch = '0';
          controls->MemRead = '0';
          controls->MemtoReg = '0';
          controls->ALUOp = '7';
          controls->MemWrite = '0';
          controls->ALUSrc = '0';
          controls->RegWrite = '1';
       }
    
          // addi
       else if(op == 8)
       {
          controls->RegDst = '0';
          controls->Jump = '0';
          controls->Branch = '0';
          controls->MemRead = '0';
          controls->MemtoReg = '0';
          controls->ALUOp = '0';
          controls->MemWrite = '0';
          controls->ALUSrc = '1';
          controls->RegWrite = '1';
       }
       
          // beq
       else if(op == 4)
       {
          controls->RegDst = '2';
          controls->Jump = '0';
          controls->Branch = '1';
          controls->MemRead = '0';
          controls->MemtoReg = '2';
          controls->ALUOp = '1';
          controls->MemWrite = '0';
          controls->ALUSrc = '0';
          controls->RegWrite = '0';
       }
       
          // lui 
       else if(op == 15)
       {
          controls->RegDst = '0';
          controls->Jump = '0';
          controls->Branch = '0';
          controls->MemRead = '0';
          controls->MemtoReg = '0';
          controls->ALUOp = '6';
          controls->MemWrite = '0';
          controls->ALUSrc = '1';
          controls->RegWrite = '1';
       }
       
          // lw
       else if(op == 35)
       {
          controls->RegDst = '0';
          controls->Jump = '0';
          controls->Branch = '0';
          controls->MemRead = '1';
          controls->MemtoReg = '1';
          controls->ALUOp = '0';
          controls->MemWrite = '0';
          controls->ALUSrc = '1';
          controls->RegWrite = '1';
       }
       
          // slti
       else if(op == 10)
       {
          controls->RegDst = '0';
          controls->Jump = '0';
          controls->Branch = '0';
          controls->MemRead = '0';
          controls->MemtoReg = '0';
          controls->ALUOp = '2';
          controls->MemWrite = '0';
          controls->ALUSrc = '1';
          controls->RegWrite = '1';
       }
       
          // sltiu
       else if(op == 11)
       {
          controls->RegDst = '0';
          controls->Jump = '0';
          controls->Branch = '0';
          controls->MemRead = '0';
          controls->MemtoReg = '0';
          controls->ALUOp = '3';
          controls->MemWrite = '0';
          controls->ALUSrc = '1';
          controls->RegWrite = '1';
       }
       
          // sw
       else if(op == 43)
       {
          controls->RegDst = '2';
          controls->Jump = '0';
          controls->Branch = '0';
          controls->MemRead = '0';
          controls->MemtoReg = '2';
          controls->ALUOp = '0';
          controls->MemWrite = '1';
          controls->ALUSrc = '1';
          controls->RegWrite = '0';
       }
    
          // jump
       else if(op == 2)
       {
          controls->RegDst = '0';
          controls->Jump = '1';
          controls->Branch = '0';
          controls->MemRead = '0';
          controls->MemtoReg = '0';
          controls->ALUOp = '0';
          controls->MemWrite = '0';
          controls->ALUSrc = '0';
          controls->RegWrite = '0';    
       }  
       else 
          return 1;
       
       return 0; 
    }
    
    /* Read Register */
    void read_register(unsigned r1,unsigned r2,unsigned *Reg,unsigned *data1,unsigned *data2)
    {
         
       *data1 = Reg[r1];  //data1 becomes register value at address r1
       *data2 = Reg[r2];  //data2 becomes register value at address r2
    }
    
    
    /* Sign Extend */
    void sign_extend(unsigned offset,unsigned *extended_value)
    {
          
       if(offset >> 15 == 1)   //negative offset
          *extended_value = offset + 0xFFFF0000;  // add 16 1's to begining
       else   //positive offset
          *extended_value = offset; //value stays the same, 0's at begining should be automatic
    }
    
    /* ALU operations */
    int ALU_operations(unsigned data1,unsigned data2,unsigned extended_value,unsigned funct,char ALUOp,char ALUSrc,unsigned *ALUresult,char *Zero)
    {
    
       if (ALUSrc == '0')
       {
          if(funct == 32)
             ALU(data1, data2, '0', ALUresult, Zero); return 0; //add
          if(funct == 34)
             ALU(data1, data2, '1', ALUresult, Zero); return 0; //sub
          if(funct == 42)
             ALU(data1, data2, '2', ALUresult, Zero); return 0; //slt
          if(funct == 43)
             ALU(data1, data2, '3', ALUresult, Zero); return 0; //sltu
          if(funct == 36)
             ALU(data1, data2, '4', ALUresult, Zero); return 0; //and
          if(funct == 37)
             ALU(data1, data2, '5', ALUresult, Zero); return 0; //or
          if(funct == 39)
             ALU(data1, data2, '7', ALUresult, Zero); return 0; //nor
             
          if(ALUOp == '0')
             ALU(data1, data2, '0', ALUresult, Zero); return 0; //jump
          if(ALUOp == '1')
             ALU(data1, data2, '1', ALUresult, Zero);  return 0; //branch
       }
       if(ALUSrc == '1')
       {
          if(ALUOp == '0')
             ALU(data1, extended_value, ALUOp, ALUresult, Zero); return 0; //addi, sw, lw
          if(ALUOp == '1')
             ALU(data1, extended_value, ALUOp, ALUresult, Zero); return 0; //beq
          if(ALUOp == '2')
             ALU(data1, extended_value, ALUOp, ALUresult, Zero); return 0; //slti
          if(ALUOp == '3')
             ALU(data1, extended_value, ALUOp, ALUresult, Zero); return 0; //sltiu
          if(ALUOp == '6')
             ALU(data1, extended_value, ALUOp, ALUresult, Zero); return 0; //lui
       }
    }
    /* Read / Write Memory */
    int rw_memory(unsigned ALUresult,unsigned data2,char MemWrite,char MemRead,unsigned *memdata,unsigned *Mem)
    {
        
       if((MemRead == '0')&&(MemWrite == '0'))
          return 0; //not reading or writing
       
       if(ALUresult%4 != 0)
          return 1; //halt - not word alligned
    
       if((MemRead == '1')&&(MemWrite == '1'))
          return 1; //halt - don't want to read and write at the same time - causes conflicts
       
       if(MemWrite == '1') //write
       {
          ALUresult = ALUresult >> 2; 
          Mem[ALUresult] = data2;
          return 0; 
       }  
       
       if(MemRead == '1') //read
       {
          ALUresult = ALUresult >> 2; 
          *memdata = Mem[ALUresult];
          return 0;
       } 
    }
    
    
    /* Write Register */
    void write_register(unsigned r2,unsigned r3,unsigned memdata,unsigned ALUresult,char RegWrite,char RegDst,char MemtoReg,unsigned *Reg)
    {
       if((MemtoReg == '0')&&(RegWrite == '1')) //with ALU results
       {
          if (RegDst =='0')
             Reg[r3] = ALUresult;
          else if (RegDst == '1')
             Reg[r2] = ALUresult;    
       }
    
       else if((MemtoReg == '1')&&(RegWrite == '1')) //with memory data
       {
          if (RegDst == '1')     
             Reg[r3] = memdata; 
          else if (RegDst == '0')      
             Reg[r2] = memdata;              
       }
    }
    
    /* PC update */
    void PC_update(unsigned jsec,unsigned extended_value,char Branch,char Jump,char Zero,unsigned *PC)
    {
       *PC = *PC + 4; //update PC word alligned 
       if (Jump == '1')
       {
          jsec = jsec << 2; //shift left 2 bits
          *PC = (*PC & 0xF8000000); // git 5 most significant bits binary - 111110x0 32 bit
          *PC = (*PC + jsec); //update PC to the jump address
       }   
       else if (Branch == '1' && Zero == '1')
          *PC = *PC + extended_value; //update PC to the extended value
          
    }

  4. #4
    Registered User
    Join Date
    Apr 2008
    Posts
    15
    Quote Originally Posted by polyesterhat View Post
    im working on it too. does yours work when you run the command c? i don't understand what your problem is.
    It just displays cont but I am not sure what that is supposed to mean. I thought it was supposed to HALT the program since it says something about an illegal instruction.

    My problem is that I think that with every time you enter s the next instruction is supposed to be performed. Then I thought by pressing g you should be able to see that instruction's control signals, but for some reason it keeps showing me the same control signal no matter how many times I enter g. I don't know if its doing the exact same instruction repeatedly.

  5. #5
    Registered User
    Join Date
    Nov 2008
    Posts
    7
    try this input:
    20010000 # addi $1, $0, 0
    200200c8 # addi $2, $0, 200
    10220003 # beq $1, $2, 3
    00000020 # delay slot
    20210001 # addi $1, $1, 1
    00000020 # no operation

  6. #6
    Registered User
    Join Date
    Nov 2008
    Posts
    7
    also, for more input files I found an old TA's website: http://theghoti.googlepages.com/downloads

  7. #7
    Registered User
    Join Date
    Apr 2008
    Posts
    15
    Quote Originally Posted by polyesterhat View Post
    try this input:
    20010000 # addi $1, $0, 0
    200200c8 # addi $2, $0, 200
    10220003 # beq $1, $2, 3
    00000020 # delay slot
    20210001 # addi $1, $1, 1
    00000020 # no operation
    Do you know whether or not we are supposed to be able to see the values of the registers change when we press r because all I see is all zero.

  8. #8
    Registered User
    Join Date
    Nov 2008
    Posts
    7
    honestly man, Im so confused with this assignment, its nothing like what we have done in the lectures, im just gunna clean up that code and be done with it. sorry. but i know that if you're into it, you can write a mips program and convert it with that MIPSASC program on the ta's stie I gave above. pressing r should show any modifications to the registers. for instance, if you do c, then r, it should show the final register states
    cheers

  9. #9
    Registered User
    Join Date
    Nov 2008
    Posts
    7
    btw, have you ever searched google for your username, lol, you're probably in my class. sfsy.

  10. #10
    Registered User
    Join Date
    Apr 2008
    Posts
    15
    Yeah I know what you mean. I think I am just going to hand it in as well. I spent way too much time on this thing already. Thanks for the help though. I have never actually googled my username but I do use it for just about ever website I use which probably isn't a good thing to do. BTW what's sfsy?
    Last edited by MasterAchilles; 11-30-2008 at 10:02 PM.

  11. #11
    Registered User
    Join Date
    Nov 2008
    Posts
    7
    sorry for stalking you haha

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. need help with cache simulator!
    By dtogers123 in forum C Programming
    Replies: 3
    Last Post: 04-30-2008, 06:18 PM
  2. Random question simulator
    By Pickpocket in forum C Programming
    Replies: 9
    Last Post: 12-04-2006, 07:13 AM
  3. about Visual Studio mobile development simulator
    By George2 in forum Tech Board
    Replies: 0
    Last Post: 11-09-2006, 03:04 AM
  4. Flight Simulator Wind Speed!!
    By Dilmerv in forum C++ Programming
    Replies: 6
    Last Post: 03-20-2006, 12:40 AM
  5. destroywindow() problem
    By algi in forum Windows Programming
    Replies: 6
    Last Post: 03-27-2005, 11:40 PM