Created
February 7, 2009 06:51
-
-
Save dodeja/59800 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| # ECE 486 Project 1 | |
| # PDP 8 Benchmarking tool | |
| # | |
| require 'PDP8_stats' | |
| class PDP8 | |
| # Read the object file and load it to | |
| f = File.open("TestISZ.obj","r") | |
| lines = f.readlines | |
| @n = 0 | |
| f.close | |
| prog_data = Hash.new { |hash, key| hash[key] = {:addr => "", :data => ""} } | |
| prog_addr = Hash.new | |
| @prog_branch = Hash.new | |
| ins = 0 # => Instruction Counter | |
| first_addr = false # => First Instruction | |
| @branch_addr = 0 | |
| # => Increment Octal by 1 | |
| #----------------------------------------------------------------------------------------------------- | |
| def self.incre_oct(val) | |
| new_val = (val.to_i(8) + 1).to_s(8) | |
| if(new_val.length > 3) | |
| return new_val | |
| else | |
| return "0"+new_val | |
| end | |
| end | |
| # => Increment Octal by 1 | |
| #----------------------------------------------------------------------------------------------------- | |
| def self.incre_data(val) | |
| new_val = (val.to_i(8) + 1).to_s(8) | |
| if(new_val.to_i > 7777) | |
| return 0 | |
| else | |
| return new_val | |
| end | |
| end | |
| # => Parse the Lines into a 2-D Array | |
| #----------------------------------------------------------------------------------------------------- | |
| first_inst = 0 | |
| lines.each_index do |x| | |
| if(x % 2 == 0) | |
| if(lines[x].index('1') == 0) | |
| n = 0 | |
| prog_data[ins][:addr] = "0" + lines[x][1..2].to_i.to_s + lines[x + 1][1..2] | |
| prog_data[ins][:data] = lines[x + 2][1..2] + lines[x + 3][1..2] | |
| ins = ins + 1 | |
| first_addr = true | |
| else | |
| if(!first_addr) | |
| new_oct = incre_oct(prog_data[ins-1][:addr]) | |
| prog_data[ins][:addr] = "0" + new_oct | |
| prog_data[ins][:data] = lines[x][1..2] + lines[x + 1][1..2] | |
| ins = ins + 1 | |
| else | |
| first_addr = false | |
| end | |
| end | |
| end | |
| end | |
| # Set up another data Structure | |
| last_inst = 0 | |
| 0.upto(prog_data.length-1) do |k| | |
| if(prog_data[k][:data] == "7402") | |
| last_inst = k | |
| elsif(prog_data[k][:addr] == "0200") | |
| first_inst = k | |
| end | |
| prog_addr[prog_data[k][:addr].to_i] = prog_data[k][:data] | |
| puts "#{prog_data[k][:addr].to_i} - #{prog_addr[prog_data[k][:addr].to_i]}" | |
| end | |
| @ac = 0 # => Accumulator | |
| @pc = "200" # => Program Counter starts at 200 | |
| @eaddr = "" | |
| @temp_data = 0 | |
| # => Get Effective address | |
| #----------------------------------------------------------------------------------------------------- | |
| def self.get_eddr(current_data, prog_addr) | |
| if(current_data[1..1].to_i < 4) | |
| if(current_data[1..1].to_i < 2) | |
| @eaddr = ((current_data[1..1].to_i % 2).to_s + current_data[2..3]).to_i | |
| else | |
| @eaddr = ((@pc[0..1].to_i*100 + (current_data[1..1].to_i % 2)*100 + current_data[2..3].to_i).to_s).to_i | |
| end | |
| elsif( current_data[1..1].to_i > 3 && current_data[1..1].to_i < 6) | |
| @eaddr = ((current_data[1..1].to_i % 2).to_s + current_data[2..3]).to_i | |
| @eaddr = prog_addr[@eaddr] | |
| else | |
| @eaddr = ((@pc[0..1].to_i*100 + (current_data[1..1].to_i % 2)*100 + current_data[2..3].to_i).to_s).to_i | |
| @eaddr = prog_addr[@eaddr] | |
| end | |
| if(current_data[1..1].to_i > 3) | |
| if(current_data.to_i >= 10 && current_data.to_i <= 17) | |
| @eaddr = incre_oct(prog_adr[@eaddr]) | |
| end | |
| Stat.update({:cycle =>1 }) | |
| end | |
| end | |
| # => AND Instruction [case 0] | |
| #----------------------------------------------------------------------------------------------------- | |
| def self.AND_inst(current_data, prog_addr) | |
| get_eddr(current_data, prog_addr) | |
| @temp_data = prog_addr[@eaddr.to_i] | |
| @ac = @temp_data.to_s.oct & @ac.to_s.oct | |
| @ac = @ac.to_s(8).to_i | |
| Stat.update({:AND =>1, :cycle =>2, :inst =>1, }) | |
| end | |
| # => TAD Instruction [case 1] | |
| #----------------------------------------------------------------------------------------------------- | |
| def self.TAD_inst(current_data, prog_addr) | |
| get_eddr(current_data, prog_addr) | |
| @temp_data = prog_addr[@eaddr.to_i] | |
| @ac = @temp_data.to_s.oct + @ac.to_s.oct | |
| @ac = @ac.to_s(8).to_i | |
| Stat.update({:TAD =>1, :cycle =>2, :inst =>1, }) | |
| end | |
| # => ISZ Instruction [case 2] | |
| #----------------------------------------------------------------------------------------------------- | |
| def self.ISZ_inst(current_data, prog_addr) | |
| get_eddr(current_data, prog_addr) | |
| @temp_data = prog_addr[@eaddr.to_i] | |
| @temp_data = incre_data(@temp_data) | |
| prog_addr[@eaddr.to_i] = @temp_data | |
| if(@temp_data.to_i == 0) | |
| if(@prog_branch[@pc]) | |
| @prog_branch[@pc][:exec] += 1 | |
| @prog_branch[@pc][:taken] += 1 | |
| @prog_branch[@pc][:percent_taken] = @prog_branch[@pc][:taken] / @prog_branch[@pc][:exec] | |
| else | |
| @prog_branch[@pc] = { :type => "conditional", :exec => 1, :taken => 1, :percent_taken => 1} | |
| end | |
| @pc = incre_oct(@pc) | |
| else | |
| if(@prog_branch[@pc]) | |
| @prog_branch[@pc][:exec] += 1 | |
| @prog_branch[@pc][:percent_taken] = @prog_branch[@pc][:taken] / @prog_branch[@pc][:exec] | |
| else | |
| @prog_branch[@pc] = { :type => "conditional", :exec => 1, :taken => 0, :percent_taken => 0} | |
| end | |
| end | |
| Stat.update({:ISZ =>1, :cycle =>2, :inst =>1, }) | |
| # TRACE FILE | |
| end | |
| # => DCA Instruction [case 3] | |
| #----------------------------------------------------------------------------------------------------- | |
| def self.DCA_inst(current_data, prog_addr) | |
| get_eddr(current_data, prog_addr) | |
| @temp_data = @ac.to_s | |
| prog_addr[@eaddr.to_i] = @temp_data | |
| @ac = 0 | |
| Stat.update({:DCA =>1, :cycle =>2, :inst =>1, }) | |
| end | |
| # => JMS Instruction [case 4] | |
| #----------------------------------------------------------------------------------------------------- | |
| def self.JMS_inst(current_data, prog_addr) | |
| @prog_branch[@pc] = { :type => "unconditional", :exec => 1, :taken => 1, :percent_taken => 100} | |
| get_eddr(current_data, prog_addr) | |
| @temp_data = @ac.to_s | |
| prog_addr[@eaddr.to_i] = @temp_data | |
| @ac = 0 | |
| Stat.update({:DCA =>1, :cycle =>2, :inst =>1, }) | |
| end | |
| # => Run Loop | |
| #----------------------------------------------------------------------------------------------------- | |
| run_prog = true | |
| while run_prog do | |
| current_data = prog_addr[@pc.to_i] | |
| current_instruction = current_data[0..0].to_i | |
| case current_instruction | |
| when 0 | |
| AND_inst(current_data, prog_addr) | |
| when 1 | |
| TAD_inst(current_data, prog_addr) | |
| when 2 | |
| ISZ_inst(current_data, prog_addr) | |
| when 3 | |
| DCA_inst(current_data, prog_addr) | |
| when 4 | |
| DCA_inst(current_data, prog_addr) | |
| end | |
| if(prog_addr[@pc.to_i] == "7402") | |
| run_prog = false | |
| end | |
| @pc = incre_oct(@pc) | |
| puts "#{@pc} #{prog_addr[@pc.to_i]} | AC = #{@ac} Eaddr = #{@eaddr}" | |
| end | |
| puts @prog_branch | |
| Stat.display | |
| end | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment