OpenCores
URL https://opencores.org/ocsvn/myblaze/myblaze/trunk

Subversion Repositories myblaze

[/] [myblaze/] [trunk/] [model/] [emulator.py] - Rev 6

Compare with Previous | Blame | View Log

#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""
    emulator.py
    ===========
 
    An Emulator for MicroBlaze INA
 
    :copyright: Copyright (c) 2010 Jian Luo
    :author-email: jian.luo.cn(at_)gmail.com
    :license: LGPL, see LICENSE for details
    :revision: $Id: emulator.py 6 2010-11-21 23:18:44Z rockee $
"""
 
from random import randrange
from myhdl import *
 
operations = """
| ADD | Rd,Ra,Rb | 000000 | Rd | Ra | Rb & 00000000000 | Rd := Rb + Ra
| RSUB | Rd,Ra,Rb | 000001 | Rd | Ra | Rb & 00000000000 | Rd := Rb + Ra + 1
| ADDC | Rd,Ra,Rb | 000010 | Rd | Ra | Rb & 00000000000 | Rd := Rb + Ra + C
| RSUBC | Rd,Ra,Rb | 000011 | Rd | Ra | Rb & 00000000000 | Rd := Rb + Ra + C
| ADDK | Rd,Ra,Rb | 000100 | Rd | Ra | Rb & 00000000000 | Rd := Rb + Ra
| RSUBK | Rd,Ra,Rb | 000101 | Rd | Ra | Rb & 00000000000 | Rd := Rb + Ra + 1
| ADDKC | Rd,Ra,Rb | 000110 | Rd | Ra | Rb & 00000000000 | Rd := Rb + Ra + C
| RSUBKC | Rd,Ra,Rb | 000111 | Rd | Ra | Rb & 00000000000 | Rd := Rb + Ra + C
| CMP | Rd,Ra,Rb | 000101 | Rd | Ra | Rb & 00000000001 | Rd := Rb + Ra + 1
                                                      Rd[0] := 0 if (Rb >= Ra) else
                                                      Rd[0] := 1
| CMPU | Rd,Ra,Rb | 000101 | Rd | Ra | Rb & 00000000011 | Rd := Rb + Ra + 1 (unsigned)
                                                      Rd[0] := 0 if (Rb >= Ra, unsigned) else
                                                      Rd[0] := 1
| ADDI | Rd,Ra,Imm | 001000 | Rd | Ra | Imm        | Rd := s(Imm) + Ra
| RSUBI | Rd,Ra,Imm | 001001 | Rd | Ra | Imm        | Rd := s(Imm) + Ra + 1
| ADDIC | Rd,Ra,Imm | 001010 | Rd | Ra | Imm        | Rd := s(Imm) + Ra + C
| RSUBIC | Rd,Ra,Imm | 001011 | Rd | Ra | Imm        | Rd := s(Imm) + Ra + C
| ADDIK | Rd,Ra,Imm | 001100 | Rd | Ra | Imm        | Rd := s(Imm) + Ra
| RSUBIK | Rd,Ra,Imm | 001101 | Rd | Ra | Imm        | Rd := s(Imm) + Ra + 1
| ADDIKC | Rd,Ra,Imm | 001110 | Rd | Ra | Imm        | Rd := s(Imm) + Ra + C
| RSUBIKC | Rd,Ra,Imm | 001111 | Rd | Ra | Imm        | Rd := s(Imm) + Ra + C
#| MUL | Rd,Ra,Rb | 010000 | Rd | Ra | Rb & 00000000000 | Rd := Ra * Rb
#| MULH | Rd,Ra,Rb | 010000 | Rd | Ra | Rb & 00000000001 | Rd := (Ra * Rb) >> 32 (signed)
#| MULHU | Rd,Ra,Rb | 010000 | Rd | Ra | Rb & 00000000011 | Rd := (Ra * Rb) >> 32 (unsigned)
#| MULHSU | Rd,Ra,Rb | 010000 | Rd | Ra | Rb & 00000000010 | Rd := (Ra, signed * Rb, unsigned) >> 32 (signed)
#| BSRA | Rd,Ra,Rb | 010001 | Rd | Ra | Rb & 01000000000 | Rd := s(Ra >> Rb)
#| BSLL | Rd,Ra,Rb | 010001 | Rd | Ra | Rb & 10000000000 | Rd := (Ra << Rb) & 0
#| MULI | Rd,Ra,Imm | 011000 | Rd | Ra | Imm        | Rd := Ra * s(Imm)
#| BSRLI | Rd,Ra,Imm | 011001 | Rd | Ra | 00000000000 & Imm5  | Rd := 0 & (Ra >> Imm5)
#| BSRAI | Rd,Ra,Imm | 011001 | Rd | Ra | 00000010000 & Imm5  | Rd := s(Ra >> Imm5)
#| BSLLI | Rd,Ra,Imm | 011001 | Rd | Ra | 00000100000 & Imm5  | Rd := (Ra << Imm5) & 0
#| IDIV | Rd,Ra,Rb | 010010 | Rd | Ra | Rb & 00000000000 | Rd := Rb/Ra
#| IDIVU | Rd,Ra,Rb | 010010 | Rd | Ra | Rb & 00000000010 | Rd := Rb/Ra, unsigned
#| TNEAGETD | Rd,Rb | 010011 | Rd | 00000 | Rb & 0N0TAE00000 | Rd := FSL Rb[28:31] (data read)
                                                      #MSR[FSL] := 1 if (FSL_S_Control = 1)
                                                      #MSR[C] := not FSL_S_Exists if N = 1
#| TNAPUTD | Ra,Rb |    010011 | 00000 | Ra |  Rb & 0N0TA000000 |  FSL Rb[28:31] := Ra (data write)
                                                      #MSR[C] := FSL_M_Full if N = 1
#| TNECAGETD | Rd,Rb | 010011 | Rd |  00000 | Rb & 0N1TAE00000  |  Rd := FSL Rb[28:31] (control read)
                                                     #MSR[FSL] := 1 if (FSL_S_Control = 0)
                                                     #MSR[C] := not FSL_S_Exists if N = 1
#| TNCAPUTD | Ra,Rb |  010011 | 00000 | Ra |  Rb & 0N1TA000000  |  FSL Rb[28:31] := Ra (control write)
                                                     #MSR[C] := FSL_M_Full if N = 1
                                                     #Rd := Rb+Ra, float1
#FADD Rd,Ra,Rb    010110  Rd    Ra   Rb   00000000000
                                                     #Rd := Rb-Ra, float1
#FRSUB Rd,Ra,Rb   010110  Rd    Ra   Rb   00010000000
                                                     #Rd := Rb*Ra, float1
#FMUL Rd,Ra,Rb    010110  Rd    Ra   Rb   00100000000
                                                     #Rd := Rb/Ra, float1
#FDIV Rd,Ra,Rb    010110  Rd    Ra   Rb   00110000000
                                                     #Rd := 1 if (Rb = NaN or Ra = NaN, float1)
#FCMP.UN Rd,Ra,Rb 010110  Rd    Ra   Rb   01000000000
                                                     #else
                                                     #Rd := 0
                                                     #Rd := 1 if (Rb < Ra, float1) else
#FCMP.LT Rd,Ra,Rb 010110  Rd    Ra   Rb   01000010000
                                                     #Rd := 0
                                                     #Rd := 1 if (Rb = Ra, float1) else
#FCMP.EQ Rd,Ra,Rb 010110  Rd    Ra   Rb   01000100000
                                                     #Rd := 0
                                                     #Rd := 1 if (Rb <= Ra, float1) else
#FCMP.LE Rd,Ra,Rb 010110  Rd    Ra   Rb   01000110000
                                                     #Rd := 0
                                                     #Rd := 1 if (Rb > Ra, float1) else
#FCMP.GT Rd,Ra,Rb 010110  Rd    Ra   Rb   01001000000
                                                     #Rd := 0
                                                     #Rd := 1 if (Rb != Ra, float1) else
#FCMP.NE Rd,Ra,Rb 010110  Rd    Ra   Rb   01001010000
                                                     #Rd := 0
                                                     #Rd := 1 if (Rb >= Ra, float1) else
#FCMP.GE Rd,Ra,Rb 010110  Rd    Ra   Rb   01001100000
                                                     #Rd := 0
                                                     #Rd := float (Ra)1
#FLT Rd,Ra        010110  Rd    Ra    0   01010000000
                                                     #Rd := int (Ra)1
#FINT Rd,Ra       010110  Rd    Ra    0   01100000000
                                                     #Rd := sqrt (Ra)1
#FSQRT Rd,Ra      010110  Rd    Ra    0   01110000000
#| TNEAGET | Rd,FSLx |  011011 |  Rd |  00000 | 0N0TAE000000 & FSLx |  Rd := FSLx (data read, blocking if N = 0)
                                                 #MSR[FSL] := 1 if (FSLx_S_Control = 1)
                                                     #MSR[C] := not FSLx_S_Exists if N = 1
#| TNAPUT | Ra,FSLx |  011011 | 00000 | Ra |  1N0TA0000000 & FSLx | FSLx := Ra (data write, blocking if N = 0)
                                                 #MSR[C] := FSLx_M_Full if N = 1
#| TNECAGET | Rd,FSLx | 011011 | Rd |  00000 | 0N1TAE000000 & FSLx |  Rd := FSLx (control read, blocking if N = 0)
                                                 #MSR[FSL] := 1 if (FSLx_S_Control = 0)
                                                     #MSR[C] := not FSLx_S_Exists if N = 1
#| TNCAPUT | Ra,FSLx | 011011 | 00000 |  Ra  | 1N1TA0000000 & FSLx |  FSLx := Ra (control write, blocking if N = 0)
                                                 #MSR[C] := FSLx_M_Full if N = 1
| OR | Rd,Ra,Rb | 100000 | Rd | Ra | Rb & 00000000000 | Rd := Ra or Rb
| AND | Rd,Ra,Rb | 100001 | Rd | Ra | Rb & 00000000000 | Rd := Ra and Rb
| XOR | Rd,Ra,Rb | 100010 | Rd | Ra | Rb & 00000000000 | Rd := Ra xor Rb
| ANDN | Rd,Ra,Rb | 100011 | Rd | Ra | Rb & 00000000000 | Rd := Ra and Rb
#| PCMPBF | Rd,Ra,Rb | 100000 | Rd | Ra | Rb & 10000000000 | Rd := 1 if (Rb[0:7] = Ra[0:7]) else
                                                  Rd := 2 if (Rb[8:15] = Ra[8:15]) else
                                                  Rd := 3 if (Rb[16:23] = Ra[16:23]) else
                                                  Rd := 4 if (Rb[24:31] = Ra[24:31]) else
                                                  Rd := 0
#PCMPEQ Rd,Ra,Rb 100010  Rd   Ra Rb    10000000000 Rd := 1 if (Rd = Ra) else
                                                  #Rd := 0
#PCMPNE Rd,Ra,Rb 100011  Rd   Ra Rb    10000000000 Rd := 1 if (Rd != Ra) else
                                                  #Rd := 0
| SRA | Rd,Ra | 100100 | Rd | Ra | 0000000000000001  | Rd := s(Ra >> 1)
                                                  C := Ra[31]
| SRC | Rd,Ra | 100100 | Rd | Ra | 0000000000100001  | Rd := C & (Ra >> 1)
                                                  C := Ra[31]
| SRL | Rd,Ra | 100100 | Rd | Ra | 0000000001000001  | Rd := 0 & (Ra >> 1)
                                                  C := Ra[31]
 
 
| SEXT8 | Rd,Ra | 100100 | Rd | Ra | 0000000001100000  | Rd := s(Ra[24:31])
| SEXT16 | Rd,Ra | 100100 | Rd | Ra | 0000000001100001  | Rd := s(Ra[16:31])
 
#WIC Ra,Rb       100100 00000 Ra Rb      01101000  ICache_Line[Ra >> 4].Tag := 0 if
                                                  #(C_ICACHE_LINE_LEN = 4)
                                                  #ICache_Line[Ra >> 5].Tag := 0 if
                                                  #(C_ICACHE_LINE_LEN = 8)
#WDC Ra,Rb       100100 00000 Ra Rb      01100100  DCache_Line[Ra >> 4].Tag := 0 if
                                                  #(C_DCACHE_LINE_LEN = 4)
                                                  #DCache_Line[Ra >> 5].Tag := 0 if
                                                  #(C_DCACHE_LINE_LEN = 8)
#| MTS | Sd,Ra | 100101 | 00000 | Ra | 11 & Sd      | SPR[Sd] := Ra, where:
                                                  #•  SPR[0x0001] is MSR
                                                  #•  SPR[0x0007] is FSR
                                                  #•  SPR[0x1000] is PID
                                                  #•  SPR[0x1001] is ZPR
                                                  #•  SPR[0x1002] is TLBX
                                                  #•  SPR[0x1003] is TLBLO
                                                  #•  SPR[0x1004] is TLBHI
                                                  #•  SPR[0x1005] is TLBSX
#| MFS | Rd,Sa | 100101 | Rd | 00000 | 10 & Sa      | Rd := SPR[Sa], where:
                                                   #• SPR[0x0000] is PC
                                                   #• SPR[0x0001] is MSR
                                                   #• SPR[0x0003] is EAR
                                                   #• SPR[0x0005] is ESR
                                                   #• SPR[0x0007] is FSR
                                                   #• SPR[0x000B] is BTR
                                                   #• SPR[0x000D] is EDR
                                                   #• SPR[0x1000] is PID
                                                   #• SPR[0x1001] is ZPR
                                                   #• SPR[0x1002] is TLBX
                                                   #• SPR[0x1003] is TLBLO
                                                   #• SPR[0x1004] is TLBHI
                                                   #• SPR[0x2000 to 0x200B] is PVR[0 to 11]
#| MSRCLR | Rd,Imm | 100101 | Rd | 00001 | 00 & Imm14     | Rd := MSR
                                                   #MSR := MSR and Imm14
#| MSRSET | Rd,Imm | 100101 | Rd | 00000 | 00 & Imm14     | Rd := MSR
                                                   #MSR := MSR or Imm14
| BR | Rb | 100110 | 00000 | 00000 | Rb & 00000000000 | PC := PC + Rb
| BRD | Rb | 100110 | 00000 | 10000 | Rb & 00000000000 | PC := PC + Rb
| BRLD | Rd,Rb | 100110 | Rd | 10100 | Rb & 00000000000 | PC := PC + Rb
                                                   Rd := PC
| BRA | Rb | 100110 | 00000 | 01000 | Rb & 00000000000 | PC := Rb
| BRAD | Rb | 100110 | 00000 | 11000 | Rb & 00000000000 | PC := Rb
| BRALD | Rd,Rb | 100110 | Rd | 11100 | Rb & 00000000000 | PC := Rb
                                                   Rd := PC
| BRK | Rd,Rb | 100110 | Rd | 01100 | Rb & 00000000000 | PC := Rb
                                                   Rd := PC
                                                   MSR[BIP] := 1
| BEQ | Ra,Rb | 100111 | 00000 | Ra | Rb & 00000000000 | PC := PC + Rb if Ra = 0
| BNE | Ra,Rb | 100111 | 00001 | Ra | Rb & 00000000000 | PC := PC + Rb if Ra != 0
| BLT | Ra,Rb | 100111 | 00010 | Ra | Rb & 00000000000 | PC := PC + Rb if Ra < 0
| BLE | Ra,Rb | 100111 | 00011 | Ra | Rb & 00000000000 | PC := PC + Rb if Ra <= 0
| BGT | Ra,Rb | 100111 | 00100 | Ra | Rb & 00000000000 | PC := PC + Rb if Ra > 0
| BGE | Ra,Rb | 100111 | 00101 | Ra | Rb & 00000000000 | PC := PC + Rb if Ra >= 0
| BEQD | Ra,Rb | 100111 | 10000 | Ra | Rb & 00000000000 | PC := PC + Rb if Ra = 0
| BNED | Ra,Rb | 100111 | 10001 | Ra | Rb & 00000000000 | PC := PC + Rb if Ra != 0
| BLTD | Ra,Rb | 100111 | 10010 | Ra | Rb & 00000000000 | PC := PC + Rb if Ra < 0
| BLED | Ra,Rb | 100111 | 10011 | Ra | Rb & 00000000000 | PC := PC + Rb if Ra <= 0
| BGTD | Ra,Rb | 100111 | 10100 | Ra | Rb & 00000000000 | PC := PC + Rb if Ra > 0
| BGED | Ra,Rb | 100111 | 10101 | Ra | Rb & 00000000000 | PC := PC + Rb if Ra >= 0
| ORI | Rd,Ra,Imm | 101000 | Rd | Ra | Imm         | Rd := Ra or s(Imm)
| ANDI | Rd,Ra,Imm | 101001 | Rd | Ra | Imm         | Rd := Ra and s(Imm)
| XORI | Rd,Ra,Imm | 101010 | Rd | Ra | Imm         | Rd := Ra xor s(Imm)
| ANDNI | Rd,Ra,Imm | 101011 | Rd | Ra | Imm         | Rd := Ra and s(Imm)
 
 
| IMM | Imm | 101100 | 00000 | 00000 | Imm         | Imm[0:15] := Imm
| RTSD | Ra,Imm | 101101 | 10000 | Ra | Imm         | PC := Ra + s(Imm)
| RTID | Ra,Imm | 101101 | 10001 | Ra | Imm         | PC := Ra + s(Imm)
                                                  MSR[IE] := 1
| RTBD | Ra,Imm | 101101 | 10010 | Ra | Imm         | PC := Ra + s(Imm)
                                                  MSR[BIP] := 0
| RTED | Ra,Imm | 101101 | 10100 | Ra | Imm         | PC := Ra + s(Imm)
                                                  MSR[EE] := 1, MSR[EIP] := 0
                                                  ESR := 0
| BRI | Imm | 101110 | 00000 | 00000 | Imm         | PC := PC + s(Imm)
| BRID | Imm | 101110 | 00000 | 10000 | Imm         | PC := PC + s(Imm)
| BRLID | Rd,Imm | 101110 | Rd | 10100 | Imm         | PC := PC + s(Imm)
                                                 Rd := PC
| BRAI | Imm | 101110 | 00000 | 01000 | Imm         | PC := s(Imm)
| BRAID | Imm | 101110 | 00000 | 11000 | Imm         | PC := s(Imm)
| BRALID | Rd,Imm | 101110 | Rd | 11100 | Imm         | PC := s(Imm)
                                                 Rd := PC
| BRKI | Rd,Imm | 101110 | Rd | 01100 | Imm         | PC := s(Imm)
                                                  Rd := PC
                                                  MSR[BIP] := 1
| BEQI | Ra,Imm | 101111 | 00000 | Ra | Imm         | PC := PC + s(Imm) if Ra = 0
| BNEI | Ra,Imm | 101111 | 00001 | Ra | Imm         | PC := PC + s(Imm) if Ra != 0
| BLTI | Ra,Imm | 101111 | 00010 | Ra | Imm         | PC := PC + s(Imm) if Ra < 0
| BLEI | Ra,Imm | 101111 | 00011 | Ra | Imm         | PC := PC + s(Imm) if Ra <= 0
| BGTI | Ra,Imm | 101111 | 00100 | Ra | Imm         | PC := PC + s(Imm) if Ra > 0
| BGEI | Ra,Imm | 101111 | 00101 | Ra | Imm         | PC := PC + s(Imm) if Ra >= 0
| BEQID | Ra,Imm | 101111 | 10000 | Ra | Imm         | PC := PC + s(Imm) if Ra = 0
| BNEID | Ra,Imm | 101111 | 10001 | Ra | Imm         | PC := PC + s(Imm) if Ra != 0
| BLTID | Ra,Imm | 101111 | 10010 | Ra | Imm         | PC := PC + s(Imm) if Ra < 0
| BLEID | Ra,Imm | 101111 | 10011 | Ra | Imm         | PC := PC + s(Imm) if Ra <= 0
| BGTID | Ra,Imm | 101111 | 10100 | Ra | Imm         | PC := PC + s(Imm) if Ra > 0
| BGEID | Ra,Imm | 101111 | 10101 | Ra | Imm         | PC := PC + s(Imm) if Ra >= 0
| LBU | Rd,Ra,Rb | 110000 | Rd | Ra | Rb & 00000000000 | Addr := Ra + Rb
                                              Rd[0:23] := 0
                                              Rd[24:31] := *Addr[0:7]
| LHU | Rd,Ra,Rb | 110001 | Rd | Ra | Rb & 00000000000 | Addr := Ra + Rb
                                              Rd[0:15] := 0
                                              Rd[16:31] := *Addr[0:15]
| LW | Rd,Ra,Rb | 110010 | Rd | Ra | Rb & 00000000000 | Addr := Ra + Rb
                                              Rd := *Addr
| SB | Rd,Ra,Rb | 110100 | Rd | Ra | Rb & 00000000000 | Addr := Ra + Rb
                                              *Addr[0:8] := Rd[24:31]
| SH | Rd,Ra,Rb | 110101 | Rd | Ra | Rb & 00000000000 | Addr := Ra + Rb
                                              *Addr[0:16] := Rd[16:31]
| SW | Rd,Ra,Rb | 110110 | Rd | Ra | Rb & 00000000000 | Addr := Ra + Rb
                                              *Addr := Rd
| LBUI | Rd,Ra,Imm | 111000 | Rd | Ra | Imm         | Addr := Ra + s(Imm)
                                              Rd[0:23] := 0
                                              Rd[24:31] := *Addr[0:7]
| LHUI | Rd,Ra,Imm | 111001 | Rd | Ra | Imm         | Addr := Ra + s(Imm)
                                              Rd[0:15] := 0
                                              Rd[16:31] := *Addr[0:15]
| LWI | Rd,Ra,Imm | 111010 | Rd | Ra | Imm         | Addr := Ra + s(Imm)
                                              Rd := *Addr
| SBI | Rd,Ra,Imm | 111100 | Rd | Ra | Imm         | Addr := Ra + s(Imm)
                                              *Addr[0:7] := Rd[24:31]
| SHI | Rd,Ra,Imm | 111101 | Rd | Ra | Imm         | Addr := Ra + s(Imm)
                                              *Addr[0:15] := Rd[16:31]
| SWI | Rd,Ra,Imm | 111110 | Rd | Ra | Imm         | Addr := Ra + s(Imm)
                                                *Addr := Rd
"""
 
OPC_SFT = 26
OPC_MSK = 0x3f
REG_MSK = 0x1f
RD_SFT  = 21
RA_SFT  = 16
RB_SFT  = 11
IMM_MSK = 0xffff
 
# mask
OPC_IMM = 0x08
ADDSUB_K   = 0x04
ADDSUB_C   = 0x02
SUB_CMP = 0x01
SUB_CMPU = 0x02
 
import sys
 
QUIET=1
def log(string, params, file=sys.stdout):
    if QUIET:
        return
    params.update(
        rd = params['r'][params['d']],
        ra = params['r'][params['a']],
        rb = params['r'][params['b']],
    )
    print >>file, string.format(**params)
 
def log_gpr(params, file=sys.stdout):
    if QUIET:
        return
    print >>file, '\tGPRF:\t',
    for i, v in enumerate(params['r']):
        print >>file, '%8x' % v,
        if i%8 == 7:
            print >>file, '\n\t\t',
    print >>file, ''
 
def log_spr(params, file=sys.stdout):
    if QUIET:
        #print '{pc:x}'.format(**params)
        return
 
    print >>file, '{steps}:\tPC={pc:#x}\tCarry={m[0]:d}'.format(**params)
 
__max = 0x7fffffff
__min = 0x80000000
 
def _signed32(v):
    return (v & __max) - (v & __min)
 
def _signed16(v):
    return (v % (2**15)) - (v & (1<<15))
 
_umax = 0xffffffff
_max = _signed32(__max)
_min = _signed32(__min)
 
class MyBlazeEmulator(object):
 
    def __init__(self, filename='rom.vmem', max_steps=1000):
        ram = read_vmem(filename)
        print 'size=%d' % len(ram)
        fetch(ram, max_steps=max_steps)
 
def addi(d, a, i, k, c, r, m, **kw):
    x = _signed32(r[a]) + _signed32(i) + (bool(c) & m[0])
    r[d] = _signed32(x)
    m[0] = m[0] if k else not (_min <= x <= _max)
 
def add(b, r, i=None, **kw):
    addi(i=r[b], r=r, **kw)
 
def rsubi(d, a, i, k, c, r, m, **kw):
    x = _signed32(i) - _signed32(r[a]) - (bool(c) & m[0])
    r[d] = _signed32(x)
    m[0] = m[0] if k else not (_min <= x <= _max)
 
def rsub(b, r, i=None, **kw):
    rsubi(i=r[b], r=r, **kw)
 
def cmp(d, a, b, u, r, m, **kw):
    rsub(d=d, a=a, b=b, k=True, c=False, r=r, m=m, **kw)
    #if u:
        #if (r[a] & _umax) > (r[b] & _umax):
            #r[d] |= __min
        #else:
            #r[d] &= __max
        #r[d] = _signed32(r[d])
    if u and (r[a] & __min) ^ (r[b] & __min):
        msb = r[a] & __min
        r[d] = _signed32((r[d]&__max) | msb)
 
def sra(d, a, r, m, **kw):
    msb = (bool(r[a]&__min)) << 31
    m[0] = r[d] & 1
    r[d] = _signed32(msb | (r[d] >> 1))
 
def src(d, r, m, **kw):
    msb = m[0] << 31
    m[0] = r[d] & 1
    r[d] = _signed32(msb | (r[d] >> 1))
 
def srl(d, r, m, **kw):
    m[0] = r[d] & 1
    r[d] = _signed32((r[d] >> 1))
 
def sext8(d, a, r, **kw):
    if (r[a] & 0x80):
        r[d] = _signed32(0xffffff00 | r[a])
    else:
        r[d] = _signed32(0xff & r[a])
 
def sext16(d, a, r, **kw):
    if (r[a] & 0x8000):
        r[d] = _signed32(0xffff0000 | r[a])
    else:
        r[d] = _signed32(0xffff & r[a])
 
def bri(d, i, ab, ln, pc, r, **kw):
    if ln:
        r[d] = pc
    return i if ab else pc + i
 
def br(b, r, i=None, **kw):
    return bri(i=r[b], r=r, **kw)
 
def logici(d, a, i, op, r, **kw):
    ra = r[a]
    r[d] = _signed32([ra | i, ra & i, ra ^ i, ~ra & i][op])
 
def logic(b, r, i=None, **kw):
    logici(i=r[b], r=r, **kw)
 
def bcci(a, i, op, pc, r, **kw):
    ra = _signed32(r[a])
    branch = [ra == 0,
              ra != 0,
              ra < 0,
              ra <= 0,
              ra > 0,
              ra >= 0][op]
    return pc+i if branch else None
 
def bcc(b, r, i=None, **kw):
    return bcc(i=r[b], r=r, **kw)
 
def loadi(d, a, i, op, r, ram, **kw):
    addr = r[a] + i
    if op == 0:
        r[d] = ram[addr]
    elif op == 1:
        r[d] = (ram[addr]<<8) + ram[addr+1]
    else:
        r[d] = _signed32((ram[addr]<<24) +(ram[addr+1]<<16)
                        +(ram[addr+2]<<8) +ram[addr+3])
        #print 'load@r[%d]: %s' % (d,r[d])
 
def load(b, r, i=None, **kw):
    loadi(i=r[b], r=r, **kw)
 
def storei(d, a, i, op, r, ram, **kw):
    addr = r[a] + i
    if addr<0:
        # UART Emulation
        if addr == -64:
            sys.stdout.write(chr(r[d] & 0xff))
            sys.stdout.flush()
        #else:
            #print 'store@%#x <- r[%d]=%d' % (addr&_umax, d, r[d])
        return
    if op == 0:
        ram[addr] = r[d] & 0xff
    elif op == 1:
        ram[addr] = (r[d] >> 8) & 0xff
        ram[addr+1] = r[d] & 0xff
    else:
        ram[addr] = (r[d] >> 24) & 0xff
        ram[addr+1] = (r[d] >> 16) & 0xff
        ram[addr+2] = (r[d] >> 8) & 0xff
        ram[addr+3] = r[d] & 0xff
 
def store(b, r, i=None, **kw):
    storei(i=r[b], r=r, **kw)
 
def dec_store(opcode, **kw):
    op = opcode & 0x03
    kw.update(
        op_name = ['sb', 'sh', 'sw'][op],
        op = op,
    )
    if opcode & OPC_IMM:
        storei(**kw)
        log('\t\t{op_name}i\tr{d}({rd}), r{a}({ra}), {i}', kw)
    else:
        store(**kw)
        log('\t\t{op_name}\tr{d}({rd}), r{a}({ra}), r{b}({rb})', kw)
 
def dec_load(opcode, **kw):
    op = opcode & 0x03
    kw.update(
        op_name = ['lbu', 'lhu', 'lw'][op],
        op = op,
    )
    if opcode & OPC_IMM:
        loadi(**kw)
        log('\t\t{op_name}i\tr{d}({rd}), r{a}({ra}), {i}', kw)
    else:
        load(**kw)
        log('\t\t{op_name}\tr{d}({rd}), r{a}({ra}), r{b}({rb})', kw)
 
 
def dec_add(opcode, **kw):
    kw.update(
        k = ['','k'][bool(opcode & ADDSUB_K)],
        c = ['','c'][bool(opcode & ADDSUB_C)],
    )
    if opcode & OPC_IMM:
        addi(**kw)
        log('\t\taddi{k}{c}\tr{d}({rd}), r{a}({ra}), {i}', kw)
    else:
        add(**kw)
        log('\t\tadd{k}{c}\tr{d}({rd}), r{a}({ra}), r{b}({rb})', kw)
 
def dec_sub(opcode, **kw):
    i = kw['i']
    kw.update(
        k = ['','k'][bool(opcode & ADDSUB_K)],
        c = ['','c'][bool(opcode & ADDSUB_C)],
        u = ['','u'][bool(i & SUB_CMPU)],
    )
    if opcode & OPC_IMM:
        rsubi(**kw)
        log('\t\trsubi{k}{c}\tr{d}({rd}), r{a}({ra}), {i}', kw)
    elif not i & SUB_CMP:
        rsub(**kw)
        log('\t\trsub{k}{c}\tr{d}({rd}), r{a}({ra}), r{b}({rb})', kw)
    else:
        cmp(**kw)
        log('\t\tcmp{u}\tr{d}({rd}), r{a}({ra}), r{b}({rb})', kw)
 
def dec_logic(opcode, **kw):
    op = opcode & 0x03
    kw.update(
        op=op,
        op_name=['or', 'and', 'xor', 'andn'][op]
    )
    if opcode & OPC_IMM:
        logici(**kw)
        log('\t\t{op_name}i\tr{d}({rd}), r{a}({ra}), {i}', kw)
    else:
        logic(**kw)
        log('\t\t{op_name}\tr{d}({rd}), r{a}({ra}), r{b}({rb})', kw)
 
EXT_MAPPING = dict(
    sra   = (0b0000001, 0b1111111, sra),
    src   = (0b0100001, 0b1111111, src),
    srl   = (0b1000001, 0b1111111, srl),
    sext8 = (0b1100000, 0b1111111, sext8),
    sext16= (0b1100001, 0b1111111, sext16),
)
 
def dec_extended(opcode, **kw):
    i = kw['i']
    for op_name, (value, mask, func) in EXT_MAPPING.items():
        if (i & mask) == value:
            func(**kw)
            kw['op_name'] = op_name
            log('\t\t{op_name}\tr{d}({rd}), r{a}({ra})', kw)
 
def dec_ret(**kw):
    a = kw['a']
    r = kw['r']
    i = kw['i']
    next = r[a] + i
    log('\t\trtsd\tr{a}({ra}), {i}', kw)
    return next, True
 
def dec_br(opcode, **kw):
    a = kw['a']
    dl = ['', 'd'][bool(a & 0b10000)]
    kw.update(
        ln = ['', 'l'][bool(a & 0b00100)],
        ab = ['', 'a'][bool(a & 0b01000)],
        dl = dl,
    )
    if opcode & OPC_IMM:
        next = bri(**kw)
        if kw['ln']:
            log('\t\tbr{ab}li{dl}\tr{d}({rd}), {i}', kw)
        else:
            log('\t\tbr{ab}i{dl}\t{i}', kw)
    else:
        next = br(**kw)
        if kw['ln']:
            log('\t\tbr{ab}l{dl}\tr{d}({rd}), {i}', kw)
        else:
            log('\t\tbr{ab}{dl}\t{i}', kw)
    return next, bool(dl)
 
def dec_bcc(opcode, **kw):
    d = kw['d']
    a = kw['a']
    b = kw['b']
    i = kw['i']
    r = kw['r']
    op = d & 0b111
    dl = ['', 'd'][bool(d & 0b10000)]
    kw.update(
        op_name = ['beq', 'bne', 'blt', 'ble', 'bgt', 'bge'][op],
        op = op,
        dl = dl,
    )
    #print dl, d
    if opcode & OPC_IMM:
        next = bcci(**kw)
        log('\t\t{op_name}i{dl}\tr{a}({ra}), {i}', kw)
    else:
        next = bcc(**kw)
        log('\t\t{op_name}{dl}\tr{a}({ra}), r{b}({rb})', kw)
    if next:
        return next, bool(dl)
 
def dec_imm(i, imm, **kw):
    imm[0] = i
    kw.update(i=i)
    log('\t\timm\t{i}', kw)
 
# value, mask
OPGROUP_MAPPING = dict(
    DEC_ADD = (     0b0, 0b110001, dec_add),
    DEC_SUB = (     0b1, 0b110001, dec_sub),
    DEC_LOG = (0b100000, 0b110100, dec_logic),
    DEC_IMM = (0b101100, 0b111111, dec_imm),
    DEC_EXT = (0b100100, 0b111111, dec_extended),
    DEC_RET = (0b101101, 0b111111, dec_ret),
    DEC_BR  = (0b100110, 0b110111, dec_br),
    DEC_BCC = (0b100111, 0b110111, dec_bcc),
    DEC_LD  = (0b110000, 0b110100, dec_load),
    DEC_ST  = (0b110100, 0b110100, dec_store),
)
 
def decode(instruction, pc, r, m, imm, ram, steps):
    opcode = (instruction >> OPC_SFT) & OPC_MSK
 
    # Process immediate
    i = instruction & IMM_MSK
    if imm[0] is not None:
        i += imm[0]<<16
        imm[0] = None
        i = _signed32(i)
    else:
        #if (i & 0x8000):
            #i |= 0xffff0000
        #else:
            #i &= 0xffff
        i = _signed16(i)
 
    kw = dict(
        instruction=instruction,
        opcode = opcode,
        d = (instruction >> RD_SFT) & REG_MSK,
        a = (instruction >> RA_SFT) & REG_MSK,
        b = (instruction >> RB_SFT) & REG_MSK,
        i = i,
        pc = pc,
        r = r,
        m = m,
        imm = imm,
        ram = ram,
        steps = steps,
    )
    for value, mask, func in OPGROUP_MAPPING.values():
        if (opcode & mask) == value:
            log_spr(kw)
            result = func(**kw)
            log_gpr(kw)
            return result
 
def fetch(ram, pc=0, max_steps=-1, single=False):
    r = [0]*32 # gprf
    m = [0]*32 # msr
    imm = [None]  # immediate
    steps = 0
    delayed = False
    while steps != max_steps:
        instruction = (ram[pc]<<24) +(ram[pc+1]<<16) +(ram[pc+2]<<8) +ram[pc+3]
        kw = dict(
            r=r,m=m,imm=imm,pc=pc,
            ram=ram,
            instruction=instruction,
            steps=steps,
        )
        result = decode(**kw)
        if result is not None:
            next, delay = result
            #print next, delay
 
        if single:
            raw_input('Press [Any-Key] to continue ;)')
        steps += 1
 
        if delayed:
            pc = branch_target
            delayed = False
            #print 'delayed'
        elif result is None:
            pc += 4
            delayed = False
            #print 'normal'
        elif delay:
            pc += 4
            delayed = True
            branch_target = next
            #print 'delay'
        else:
            pc = next
            delayed = False
            #print 'branch'
        #print '%x, %s' % (pc, delay)
 
def read_vmem(filename, bank=4, width=8):
    print filename
    source = open(filename).readlines()
    ram = []
    for line in source:
        value = int(line.strip(), 16)
        for i in range(bank):
            ram.append((value >> (width*(bank-1-i))) % (2**width))
    return ram
 
 
 
import sys
if __name__ == '__main__':
    MyBlazeEmulator(sys.argv[1], max_steps=2000)
 
### EOF ###
# vim:smarttab:sts=4:ts=4:sw=4:et:ai:tw=80:
 
 

Compare with Previous | Blame | View Log

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.