Example #1
0
        public void PerformStore()
        {
            while (!areWeDone)
            {
                storeEvent.WaitOne();
                Console.WriteLine("In Store");
                if (executed_instructions.Count > 0)
                {
                    ExecutedInstruction instrResult = executed_instructions.Dequeue();
                    Console.WriteLine("Store dequeued: " + Memory.getAssemblyInstructions().ElementAt(instrResult.instrIndex));
                    if (instrResult.type == StoreType.Accumulator)
                    {
                        ACC = instrResult.result;
                    }
                    else if (instrResult.type == StoreType.Memory)
                    {
                        memory[instrResult.memoryIndex] = instrResult.result;
                        Console.WriteLine("Stored " + instrResult.result + " into memory index " + instrResult.memoryIndex);
                    }
                    //Console.WriteLine("Performed store on: " + binary);
                    PC++;
                    Console.WriteLine("PC is: " + PC + " and Fetch counter is: " + Fetch_Counter);
                    if (OnStoreDone != null)
                    {
                        Console.WriteLine("Stored: " + Memory.getAssemblyInstructions().ElementAt(instrResult.instrIndex) + "--------------");
                        OnStoreDone(this, new StoreEventArgs(instrResult.instrIndex, false));
                        //OnStoreDone(this, new StageDoneEventArgs(instrResult.instrIndex, StageType.Store));
                    }

                    /*if (OnStageDone != null)
                     * {
                     *  OnStageDone(this, new StageDoneEventArgs(StageType.Store));
                     * }*/
                    //Store_Counter++;
                }

                CPU_OnStageDone(StageType.Store);
                if ((Fetch_Counter == Memory.getBinaryInstructions().Count()) && (executed_instructions.Count == 0) &&
                    (decoded_instructions.Count == 0) && (fetched_instructions.Count == 0) && instrExecute == null)
                {
                    //this means we just stored the final instruction, so increment PC to trip the end of the program
                    //PC++;
                    Console.WriteLine("PROGRAM DONE");
                    OnStoreDone(this, new StoreEventArgs(-1, true));
                }
                //CPU_OnStageDone(StageType.Store);
            }
        }
Example #2
0
        public void executeInstruction(DecodedInstruction instr)
        {
            //PC++;
            string binaryString = Convert.ToString(instr.binary, 2).PadLeft(16, '0');
            String opcode       = instr.opcode;
            String command      = instr.command;
            String flag         = instr.flag;
            short  value        = instr.value;
            int    instrIndex   = instr.index;
            //Defaults to none for things like NOP and branches
            ExecutedInstruction executedInstr = new ExecutedInstruction(0, StoreType.None, instrIndex);

            Console.WriteLine("Executing ---->" + binaryString + " O " + opcode + " C " + command + " F " + flag + " V " + value);

            switch (opcode)
            {
            case "000":                // --------------GROUP1
                if (command == "0000") // NOP
                {
                    Debug.WriteLine("NOP has been reached");
                    //return;
                }
                else      // HLT
                          //DO HLT
                {
                    Debug.WriteLine("HLT has been reached");
                    //return;
                }
                break;

            case "001":                // ------------GROUP2
                if (command == "0001") //LDA
                //Maybe signal to the GUI here that there was a load-use delay
                {
                    if (!bypassing)
                    {
                        //penalty for a load-use delay is 1 cycle
                        cycle_penalties++;
                    }
                    if (flag == "1")
                    {
                        //#
                        Debug.WriteLine("LDA# has been reached");
                        //ACC = value;
                        executedInstr = new ExecutedInstruction(value, StoreType.Accumulator, instrIndex);
                    }
                    else
                    {
                        //$
                        Debug.WriteLine("LDA$ has been reached");
                        //ACC = Memory.stack[value];
                        //ACC = memory[value];
                        executedInstr = new ExecutedInstruction(memory[value], StoreType.Accumulator, instrIndex);
                    }
                }
                if (command == "0010")     //STA
                {
                    Debug.WriteLine("STA has been reached");
                    //Memory.stack[value] = ACC;
                    //memory[value] = ACC;
                    executedInstr = new ExecutedInstruction(ACC, StoreType.Memory, instrIndex, value);
                    Debug.Write("Stored the value " + ACC + " into stack at index " + value);
                }
                else if (command == "1010")
                {
                    Debug.WriteLine("STA special has been reached");
                    TEMP = ACC;
                    Debug.WriteLine("TEMP = " + TEMP);
                }
                break;

            case "010":                // --------------GROUP3
                if (command == "0001") //ADD
                {
                    if (flag == "1")
                    {
                        //#
                        Debug.WriteLine("ADD# has been reached");
                        Debug.Write("Value is " + value);
                        //ACC += value;
                        executedInstr = new ExecutedInstruction(ACC + value, StoreType.Accumulator, instrIndex);
                        Debug.Write(" ACC is " + ACC);
                    }
                    else
                    {
                        //$
                        Debug.WriteLine("ADD$ has been reached");
                        //ACC += Memory.stack[value];
                        //ACC += memory[value];
                        executedInstr = new ExecutedInstruction(ACC + memory[value], StoreType.Accumulator, instrIndex);
                    }
                    break;
                }
                if (command == "1001")    //Special add
                {
                    Debug.WriteLine("Special ADD has been reached");
                    ACC += TEMP;
                }
                if (command == "0010")     // SUB
                {
                    if (flag == "1")
                    {
                        //#
                        Debug.WriteLine("SUB# has been reached");
                        Debug.WriteLine("ACC is " + ACC + " and value is " + value);
                        //ACC -= value;
                        executedInstr = new ExecutedInstruction(ACC - value, StoreType.Accumulator, instrIndex);
                        Debug.WriteLine("ACC is now " + ACC);
                    }
                    else
                    {
                        //$
                        //int temp = Memory.stack[value];
                        //int temp1 = memory[value];
                        Debug.WriteLine("SUB$ has been reached");
                        //Debug.WriteLine("ACC is " + ACC + " and value is " + temp1);
                        //ACC -= temp;
                        executedInstr = new ExecutedInstruction(ACC - memory[value], StoreType.Accumulator, instrIndex);
                        Debug.WriteLine("ACC is now " + ACC);
                    }
                }
                if (command == "0011")    //MUL
                //maybe signal to the GUI that there was a hazard
                {
                    cycle_penalties = cycle_penalties + 4;
                    mdHazard        = true;
                    if (flag == "1")
                    {
                        //#
                        Debug.WriteLine("MUL# has been reached");
                        //ACC = ACC * value;
                        executedInstr = new ExecutedInstruction(ACC * value, StoreType.Accumulator, instrIndex);
                    }
                    else
                    {
                        //$
                        Debug.WriteLine("MUL$ has been reached");
                        //ACC = ACC * Memory.stack[value];
                        //ACC = ACC * memory[value];
                        executedInstr = new ExecutedInstruction(ACC * memory[value], StoreType.Accumulator, instrIndex);
                    }
                }
                if (command == "0100")    //DIV
                //maybe signal to the GUI that there was a hazard
                {
                    cycle_penalties = cycle_penalties + 4;
                    mdHazard        = true;
                    if (flag == "1")
                    {
                        //#
                        Debug.WriteLine("DIV# has been reached");
                        //ACC = ACC / value;
                        executedInstr = new ExecutedInstruction(ACC / value, StoreType.Accumulator, instrIndex);
                    }
                    else
                    {
                        //$
                        Debug.WriteLine("DIV$ has been reached");
                        //ACC = ACC / Memory.stack[value];
                        //ACC = ACC / memory[value];
                        executedInstr = new ExecutedInstruction(ACC / memory[value], StoreType.Accumulator, instrIndex);
                    }
                }
                if (command == "0101")    //SHL
                //SHL things
                {
                    Debug.WriteLine("SHL has been reached");
                    ACC = ACC << value;
                }
                break;

            case "011":                //-----------------GROUP4
                if (command == "0001") //AND
                {
                    if (flag == "1")
                    {
                        //#
                        Debug.WriteLine("AND# has been reached");
                        //ACC = ACC & value;
                        executedInstr = new ExecutedInstruction(ACC & value, StoreType.Accumulator, instrIndex);
                    }
                    else
                    {
                        //$
                        //int temp = Memory.stack[value];
                        //int temp = memory[value];
                        Debug.WriteLine("AND$ has been reached");
                        //Debug.WriteLine("ACC is " + ACC + " and value is " + temp);
                        //ACC = ACC & temp;
                        executedInstr = new ExecutedInstruction(ACC & memory[value], StoreType.Accumulator, instrIndex);
                        Debug.WriteLine("ACC is now " + ACC);
                    }
                }
                if (command == "0010")    //OR
                {
                    if (flag == "1")
                    {
                        //#
                        Debug.WriteLine("OR# has been reached");
                        //ACC = ACC | (ushort)value; // Do we need to cast here? perhaps
                        executedInstr = new ExecutedInstruction(ACC | (ushort)value, StoreType.Accumulator, instrIndex);
                    }
                    else
                    {
                        //$
                        Debug.WriteLine("OR$ has been reached");
                        //ACC = ACC | Memory.stack[value];
                        //ACC = ACC | memory[value];
                        executedInstr = new ExecutedInstruction(ACC | memory[value], StoreType.Accumulator, instrIndex);
                    }
                }
                if (command == "0011")    //NOTA
                //NOTA things
                {
                    Debug.WriteLine("NOTA# has been reached");
                    Debug.WriteLine("!" + ACC + " is " + ~ACC);
                    //ACC = ~ACC; // I think ~ is a bitwise not
                    executedInstr = new ExecutedInstruction(~ACC, StoreType.Accumulator, instrIndex);
                }
                break;

            case "100":                // ------------------GROUP5
                tookBranch = false;
                if (command == "0001") //BA
                {
                    Debug.WriteLine("BA has been reached");

                    tookBranch = true;
                }
                if (command == "0010")    //BE
                {
                    Debug.WriteLine("BE has been reached");
                    if (CC == 0)
                    {
                        tookBranch = true;
                    }
                }
                if (command == "0011")    //BL
                {
                    Debug.WriteLine("BL has been reached");
                    if (CC < 0)
                    {
                        tookBranch = true;
                    }
                }
                if (command == "0100")     //BG
                {
                    Debug.WriteLine("BG has been reached");
                    if (CC > 0)
                    {
                        tookBranch = true;
                    }
                }

                foreach (var branch in branches)
                {
                    if (branch.branchlabel.CompareTo(Memory.getAssemblyInstructions().ElementAt(instrIndex)) == 0)
                    {
                        branch.numTaken++;
                        branch.updateChoice(tookBranch);
                    }
                }

                if (tookBranch)
                {
                    //Normal branching code
                    PC              = (short)(value - 1); //think it was -1 due to the PC incrementing after// PC = (short)(value - 1);
                    Fetch_Counter   = PC + 1;
                    Decode_Counter  = -1;                 //PC
                    Execute_Counter = -1;                 //PC
                    fetched_instructions.Clear();
                    decoded_instructions.Clear();
                    executed_instructions.Clear();
                    //penalty for a taken branch is 1 cycle
                    cycle_penalties++;
                    //gotta call something here to flush out pipeline queue in GUI
                    //moved to execute thread
                    if (OnBranch != null)
                    {
                        OnBranch(this, new BranchEventArgs(instr, instrIndex, true));
                        //OnFetchDone(this, new FetchEventArgs(0, -1));
                        //OnDecodeDone(this, new DecodeEventArgs(null, -1));
                        //OnExecuteDone(this, new ExecuteEventArgs(0, -1));
                    }
                }
                else
                {
                    if (OnBranch != null)
                    {
                        OnBranch(this, new BranchEventArgs(instr, instrIndex, false));
                    }
                }
                break;
            }

            //This is to avoid the next instruction being a branch and depending on the
            //cc to be updated from the previous instruction when it goes to store
            if (executedInstr.type == StoreType.Accumulator)
            {
                if (executedInstr.result > 0)
                {
                    CC = 1;
                }
                else if (executedInstr.result < 0)
                {
                    CC = -1;
                }
                else
                {
                    CC = 0;
                }
            }
            //Passes the result of execute to the store stage, to be stored next cycle
            executed_instructions.Enqueue(executedInstr);

            return;
        }
Example #3
0
        public void executeInstruction(DecodedInstruction instr)
        {

            //PC++;
            string binaryString = Convert.ToString(instr.binary, 2).PadLeft(16, '0');
            String opcode = instr.opcode;
            String command = instr.command;
            String flag = instr.flag;
            short value = instr.value;
            int instrIndex = instr.index;
            //Defaults to none for things like NOP and branches
            ExecutedInstruction executedInstr = new ExecutedInstruction(0, StoreType.None, instrIndex);           

            Console.WriteLine("Executing ---->" + binaryString + " O " + opcode + " C " + command + " F " + flag + " V " + value);

            switch (opcode)
            {
                case "000":// --------------GROUP1
                    if(command == "0000"){ // NOP
                        Debug.WriteLine("NOP has been reached");
                        //return;
                    }
                    else{ // HLT
                        //DO HLT 
                        Debug.WriteLine("HLT has been reached");
                        //return;
                    }
                    break;
                case "001":// ------------GROUP2
                    if(command == "0001"){ //LDA
                        //Maybe signal to the GUI here that there was a load-use delay
                        if (!bypassing)
                        {
                            //penalty for a load-use delay is 1 cycle
                            cycle_penalties++;
                        }
                        if(flag == "1"){
                            //#
                            Debug.WriteLine("LDA# has been reached");
                            //ACC = value;
                            executedInstr = new ExecutedInstruction(value, StoreType.Accumulator, instrIndex);
                        }
                        else{
                            //$
                            Debug.WriteLine("LDA$ has been reached");
                            //ACC = Memory.stack[value];
                            //ACC = memory[value];
                            executedInstr = new ExecutedInstruction(memory[value], StoreType.Accumulator, instrIndex);
                        }
                    }
                    if(command == "0010"){ //STA
                        Debug.WriteLine("STA has been reached");
                        //Memory.stack[value] = ACC;
                        //memory[value] = ACC;
                        executedInstr = new ExecutedInstruction(ACC, StoreType.Memory, instrIndex, value);
                        Debug.Write("Stored the value " + ACC + " into stack at index " + value);
                    }
                    else if(command == "1010"){
                        Debug.WriteLine("STA special has been reached");
                        TEMP = ACC;
                        Debug.WriteLine("TEMP = " + TEMP);
                    }
                    break;
                case "010":// --------------GROUP3
                    if(command == "0001"){ //ADD
                        if(flag == "1"){
                            //#
                            Debug.WriteLine("ADD# has been reached");
                            Debug.Write("Value is " + value);
                            //ACC += value;
                            executedInstr = new ExecutedInstruction(ACC + value, StoreType.Accumulator, instrIndex);
                            Debug.Write(" ACC is " + ACC);
                        }
                        else{
                            //$
                            Debug.WriteLine("ADD$ has been reached");
                            //ACC += Memory.stack[value];
                            //ACC += memory[value];
                            executedInstr = new ExecutedInstruction(ACC + memory[value], StoreType.Accumulator, instrIndex);
                        }
                        break;
                    }
                    if (command == "1001")//Special add
                    {
                        Debug.WriteLine("Special ADD has been reached");
                        ACC += TEMP;
                    }
                    if(command == "0010"){ // SUB
                      if(flag == "1"){
                            //#
                          Debug.WriteLine("SUB# has been reached");
                          Debug.WriteLine("ACC is " + ACC + " and value is " + value);
                          //ACC -= value;
                          executedInstr = new ExecutedInstruction(ACC - value, StoreType.Accumulator, instrIndex);
                          Debug.WriteLine("ACC is now " + ACC);
                        }
                        else{
                           //$
                            //int temp = Memory.stack[value];
                            //int temp1 = memory[value];
                            Debug.WriteLine("SUB$ has been reached");
                            //Debug.WriteLine("ACC is " + ACC + " and value is " + temp1);
                            //ACC -= temp;
                            executedInstr = new ExecutedInstruction(ACC - memory[value], StoreType.Accumulator, instrIndex);
                            Debug.WriteLine("ACC is now " + ACC);
                        }
                    }
                    if(command == "0011"){//MUL
                        //maybe signal to the GUI that there was a hazard
                        cycle_penalties = cycle_penalties + 4;
                        mdHazard = true;
                        if(flag == "1"){
                            //#
                            Debug.WriteLine("MUL# has been reached");
                            //ACC = ACC * value;
                            executedInstr = new ExecutedInstruction(ACC * value, StoreType.Accumulator, instrIndex);
                        }
                        else{
                            //$
                            Debug.WriteLine("MUL$ has been reached");
                            //ACC = ACC * Memory.stack[value];
                            //ACC = ACC * memory[value];
                            executedInstr = new ExecutedInstruction(ACC * memory[value], StoreType.Accumulator, instrIndex);
                        }
                    }
                    if(command == "0100"){//DIV
                        //maybe signal to the GUI that there was a hazard
                        cycle_penalties = cycle_penalties + 4;
                        mdHazard = true;
                        if(flag == "1"){
                            //#
                            Debug.WriteLine("DIV# has been reached");
                            //ACC = ACC / value;
                            executedInstr = new ExecutedInstruction(ACC / value, StoreType.Accumulator, instrIndex);
                        }
                        else{
                            //$
                            Debug.WriteLine("DIV$ has been reached");
                            //ACC = ACC / Memory.stack[value];
                            //ACC = ACC / memory[value];
                            executedInstr = new ExecutedInstruction(ACC / memory[value], StoreType.Accumulator, instrIndex);

                        }
                    }
                    if(command == "0101"){//SHL
                      //SHL things
                        Debug.WriteLine("SHL has been reached");
                        ACC = ACC << value;
                    }
                    break;
                case "011": //-----------------GROUP4
                    if(command == "0001"){//AND
                        if(flag == "1"){
                            //#
                            Debug.WriteLine("AND# has been reached");
                            //ACC = ACC & value;
                            executedInstr = new ExecutedInstruction(ACC & value, StoreType.Accumulator, instrIndex);
                        }
                        else{
                            //$
                            //int temp = Memory.stack[value];
                            //int temp = memory[value];
                            Debug.WriteLine("AND$ has been reached");
                            //Debug.WriteLine("ACC is " + ACC + " and value is " + temp);
                            //ACC = ACC & temp;
                            executedInstr = new ExecutedInstruction(ACC & memory[value], StoreType.Accumulator, instrIndex);
                            Debug.WriteLine("ACC is now " + ACC);
                        }
                    }
                    if(command == "0010"){//OR
                        if(flag == "1"){
                            //#
                            Debug.WriteLine("OR# has been reached");
                            //ACC = ACC | (ushort)value; // Do we need to cast here? perhaps
                            executedInstr = new ExecutedInstruction(ACC | (ushort)value, StoreType.Accumulator, instrIndex);
                        }
                        else{
                            //$
                            Debug.WriteLine("OR$ has been reached");
                            //ACC = ACC | Memory.stack[value];
                            //ACC = ACC | memory[value];
                            executedInstr = new ExecutedInstruction(ACC | memory[value], StoreType.Accumulator, instrIndex);
                        }
                    }
                    if(command == "0011"){//NOTA
                      //NOTA things
                        Debug.WriteLine("NOTA# has been reached");
                        Debug.WriteLine("!" + ACC + " is " + ~ACC);
                        //ACC = ~ACC; // I think ~ is a bitwise not
                        executedInstr = new ExecutedInstruction(~ACC, StoreType.Accumulator, instrIndex);
                    }
                    break;
                case "100": // ------------------GROUP5
                    tookBranch = false;
                    if (command == "0001"){//BA
                        Debug.WriteLine("BA has been reached");
                        
                        tookBranch = true;
                    } 
                    if(command == "0010"){//BE
                        Debug.WriteLine("BE has been reached");
                        if (CC == 0)
                        {
                            
                            tookBranch = true;
                        }
                    } 
                    if(command == "0011"){//BL
                        Debug.WriteLine("BL has been reached");
                        if (CC < 0)
                        {
                            
                            tookBranch = true;
                        }
                    }
                    if (command == "0100"){//BG
                        Debug.WriteLine("BG has been reached");
                        if (CC > 0)
                        {
                            
                            tookBranch = true;
                        }
                    }

                    foreach (var branch in branches)
                    {
                        if (branch.branchlabel.CompareTo(Memory.getAssemblyInstructions().ElementAt(instrIndex)) == 0)
                        {
                            branch.numTaken++;
                            branch.updateChoice(tookBranch);
                        }
                    }

                    if (tookBranch)
                    {

                        //Normal branching code
                        PC = (short)(value-1);//think it was -1 due to the PC incrementing after// PC = (short)(value - 1);
                        Fetch_Counter = PC+1;
                        Decode_Counter = -1;//PC
                        Execute_Counter = -1;//PC
                        fetched_instructions.Clear();
                        decoded_instructions.Clear();
                        executed_instructions.Clear();
                        //penalty for a taken branch is 1 cycle
                        cycle_penalties++;
                        //gotta call something here to flush out pipeline queue in GUI
                        //moved to execute thread
                        if (OnBranch != null)
                        {
                            OnBranch(this, new BranchEventArgs(instr, instrIndex, true));
                            //OnFetchDone(this, new FetchEventArgs(0, -1));
                            //OnDecodeDone(this, new DecodeEventArgs(null, -1));
                            //OnExecuteDone(this, new ExecuteEventArgs(0, -1));

                        }
                    }
                    else
                    {
                        if (OnBranch != null)
                        {
                            OnBranch(this, new BranchEventArgs(instr, instrIndex, false));
                        }
                    }
                    break;
            }

            //This is to avoid the next instruction being a branch and depending on the
            //cc to be updated from the previous instruction when it goes to store
            if (executedInstr.type == StoreType.Accumulator)
            {
                if (executedInstr.result > 0)
                {
                    CC = 1;
                }
                else if (executedInstr.result < 0)
                {
                    CC = -1;
                }
                else CC = 0;
            }
            //Passes the result of execute to the store stage, to be stored next cycle
            executed_instructions.Enqueue(executedInstr);

            return;
        }