Esempio n. 1
0
 def f(n):
     if n.nodetype == ast.Node.BITVECVAR and n.name in port_names:
         assert n.width == 8
         n_p = ast.BitVecVar(n.name + 'INREG', n.width)
         return n_p
     else:
         return n
Esempio n. 2
0
 def f(n):
     if n.nodetype == ast.Node.READMEM:
         if not n.mem.isMemVar():
             err_msg = 'Reading from modified memories not supported yet.'
             raise NotImplementedError, err_msg
         s = subs.getSub(param, n.mem, n.addr)
         if not s:
             name = 'RD_%s_%d' % (n.mem.name, subs.count(param, n.mem))
             s = ast.BitVecVar(name, n.mem.dwidth)
             subs.addSub(param, n.mem, n.addr, s)
         return s
     else:
         return n
Esempio n. 3
0
def rewriteAST(name, n):
    if 'width' in n.__dict__:
        inp = ast.BitVecVar(name, n.width)
        if inp == n:
            return n
        else:
            S = z3.Solver()
            y = z3.Bool('y')
            S.add(y == z3.Distinct(inp.toZ3(), n.toZ3()))
            if S.check(y) == z3.unsat:
                inp.clearCache()
                return inp
            else:
                n.clearCache()
                return n
    else:
        return n
Esempio n. 4
0
    def f(n):
        if n.nodetype == ast.Node.APPLY:
            width = n.width
            nchunks = width // 64
            chunksizes = [64] * nchunks
            assert sum(chunksizes) <= width
            if (nchunks * 64) < width:
                chunksizes.append(width % 64)
            assert sum(chunksizes) == width
            assert 0 not in chunksizes

            these_inputs = []
            for cs in chunksizes:
                name = 'input_%s_%d' % (n.fun.name, len(inputs))
                var = ast.BitVecVar(name, cs)
                inp = (var, name, (cs - 1, 0))
                inputs.append(inp)
                these_inputs.append(var)
            return ast.Concat(*these_inputs)
        else:
            return n
Esempio n. 5
0
    def getExpr(self, cnst, mem, sub, this_opcode=None, vctx=None):
        exprs = []
        all_same = False
        for p, m, a, s in self.subs:
            if mem == m and sub == s:
                exprs.append((p, a))
                if p == -1:
                    all_same = True

        assert len(exprs) >= 1
        if all_same: assert len(exprs) == 1

        if this_opcode and not all_same:
            assert vctx != None

            abstr_addr_name = sub.name + '_ABSTR_ADDR'
            vctx.cinputs.append((abstr_addr_name, (mem.awidth - 1, 0)))
            abstr_addr = ast.BitVecVar(abstr_addr_name, mem.awidth)
            vctx.objects[abstr_addr] = abstr_addr_name

            addr = None
            for p, a in exprs:
                if p == this_opcode:
                    addr = a
                    break
            if addr:
                return ast.If(ast.Equal(cnst, ast.BitVecVal(p, cnst.width)),
                              addr, abstr_addr)
            else:
                return abstr_addr

        def createIf(i):
            [p, a] = exprs[i]
            if i == len(exprs) - 1:
                return a
            else:
                return ast.If(ast.Equal(cnst, ast.BitVecVal(p, mem.awidth)), a,
                              createIf(i + 1))

        return createIf(0)
Esempio n. 6
0
def createInputs(syn):
    xram = syn.addInput(ast.MemVar('xram', 16, 8))
    op = syn.addInput(ast.BitVecVar('op', 4))
    addrin = syn.addInput(ast.BitVecVar('addrin', 16))
    datain = syn.addInput(ast.BitVecVar('datain', 8))

    aes_state = syn.addInput(ast.BitVecVar('aes_state', 8))
    aes_addr = syn.addInput(ast.BitVecVar('aes_addr', 16))
    aes_len = syn.addInput(ast.BitVecVar('aes_len', 16))
    aes_ctr = syn.addInput(ast.BitVecVar('aes_ctr', 128))
    aes_key0 = syn.addInput(ast.BitVecVar('aes_key0', 128))
    aes_key1 = syn.addInput(ast.BitVecVar('aes_key1', 128))
    aes_bytes_processed = syn.addInput(ast.BitVecVar('aes_bytes_processed',
                                                     16))
    aes_read_data = syn.addInput(ast.BitVecVar('aes_read_data', 128))
    aes_enc_data = syn.addInput(ast.BitVecVar('aes_enc_data', 128))
    # There is a minor bug here - the aes_func should be from bv384 -> bv128
    # I forgot to include the key in the input. But it doesn't matter that much
    # right now because we don't verify the AES output.
    aes_func = syn.addInput(ast.FuncVar('aes_func', 256, 128))

    sha_state = syn.addInput(ast.BitVecVar('sha_state', 8))
    sha_rdaddr = syn.addInput(ast.BitVecVar('sha_rdaddr', 16))
    sha_wraddr = syn.addInput(ast.BitVecVar('sha_wraddr', 16))
    sha_len = syn.addInput(ast.BitVecVar('sha_len', 16))
    sha_bytes_processed = syn.addInput(ast.BitVecVar('sha_bytes_processed',
                                                     16))
    sha_read_data = syn.addInput(ast.BitVecVar('sha_read_data', 512))
    sha_digest = syn.addInput(ast.BitVecVar('sha_digest', 160))
    sha_func = syn.addInput(ast.FuncVar('sha_func', 512 + 160, 160))

    return XmemContext(xram=xram,
                       op=op,
                       addrin=addrin,
                       datain=datain,
                       aes_state=aes_state,
                       aes_addr=aes_addr,
                       aes_len=aes_len,
                       aes_ctr=aes_ctr,
                       aes_key0=aes_key0,
                       aes_key1=aes_key1,
                       aes_bytes_processed=aes_bytes_processed,
                       aes_read_data=aes_read_data,
                       aes_enc_data=aes_enc_data,
                       aes_func=aes_func,
                       sha_state=sha_state,
                       sha_rdaddr=sha_rdaddr,
                       sha_wraddr=sha_wraddr,
                       sha_len=sha_len,
                       sha_bytes_processed=sha_bytes_processed,
                       sha_read_data=sha_read_data,
                       sha_digest=sha_digest,
                       sha_func=sha_func)
Esempio n. 7
0
def main(argv):
    if len(argv) != 3:
        print 'Syntax error.'
        print 'Usage: %s <ast-dir> <output.v>'
        return 1

    asts = readAllASTs(argv[1])
    assert len(asts) == 0x10

    vctx = VerilogContext()
    cnst = ast.Concat(ast.Extract(1, 0, ast.BitVecVar('sha_state', 8)),
                      ast.Extract(1, 0, ast.BitVecVar('aes_state', 8)))

    vctx.setCnst(cnst)

    vctx.cinputs.append(('op', (3, 0)))
    vctx.cinputs.append(('addrin', (15, 0)))
    vctx.cinputs.append(('datain', (7, 0)))
    vctx.objects[ast.BitVecVar('op', 4)] = 'op'
    vctx.objects[ast.BitVecVar('addrin', 16)] = 'addrin'
    vctx.objects[ast.BitVecVar('datain', 8)] = 'datain'

    vctx.addInput(ast.BoolVar('WR_XRAM_EN'), None)
    vctx.addInput(ast.BitVecVar('WR_XRAM_ADDR', 16), (15, 0))

    subs = ast2verilog.AddrSubs()
    asts_p = []
    nondet_inputs = []
    for opcode, astdict in enumerate(asts):
        astdict_p = []
        acc_v = None
        for st, v in astdict.iteritems():
            v_p1 = ast2verilog.stripMacros(v)
            v_p2 = rewriteComplexMemReads(v_p1)
            v_p3 = ast2verilog.replaceFunctions(v_p2, nondet_inputs)
            v_p4 = ast2verilog.rewriteMemReads(opcode, v_p3, subs)
            astdict_p.append((st, v_p4))

        asts_p.append(astdict_p)

    for var, name, width in nondet_inputs:
        vctx.cinputs.append((name, width))
        vctx.objects[var] = name

    ports = subs.getReadPorts()
    for m, s in ports:
        vctx.addComment("port: " + m.name + "->" + str(s))
        vctx.createWire(s)
        vctx.cinputs.append((s, vctx.getWidth(s)))
        vctx.objects[s] = s.name

    for m, s in ports:
        addr_expr = subs.getExpr(cnst, m, s)
        addr_name = s.name + "_ADDR"
        vctx.addComment(addr_name + "=" + str(addr_expr))
        vctx.addAssignment(addr_expr, vctx.getExpr(addr_expr), addr_name)
        vctx.outputs.append((addr_name, vctx.getWidth(addr_expr)))

    max_writes = 120
    choice_vars = []
    for i in xrange(120):
        name = 'nondet_memwrite_choice_%d' % i
        var = ast.BoolVar(name)
        vctx.cinputs.append((name, None))
        vctx.objects[var] = name
        choice_vars.append(var)

    for opcode, astdict in enumerate(asts_p):
        assert len(astdict) == 18

        memwrites = []
        for st, v in astdict:
            # ignore the case where nothing changes.
            if v.isVar() and v.name == st: continue

            # some comments to show what is going on.
            vctx.addComment('')
            vctx.addComment('%s_%02x' % (st, opcode))
            vctx.addComment('')

            if not v.isMem():
                name = '%s_%02x' % (st, opcode)
                vctx.addAssignment(v, vctx.getExpr(v), name)
                vctx.addStateChange(st, opcode, name)
            else:
                vctx.getMemWriteAddrs(ast.BoolVal(1), st, v, memwrites)
                # mw = vctx.getMemWrite(st, v)
                # if mw != None: vctx.addMemWrite(st, opcode, mw)

        cond, addr = nondetChooseMemWrite(choice_vars, memwrites)
        vctx.addAssignment(cond, vctx.getExpr(cond),
                           'WR_XRAM_EN_%02x' % opcode)
        vctx.addStateChange('WR_XRAM_EN', opcode, 'WR_XRAM_EN_%02x' % opcode)
        vctx.addAssignment(addr, vctx.getExpr(addr),
                           'WR_XRAM_ADDR_%02x' % opcode)
        vctx.addStateChange('WR_XRAM_ADDR', opcode,
                            'WR_XRAM_ADDR_%02x' % opcode)

    vctx.inputs.append(('dataout', (7, 0)))
    vctx.addOutputs()
    # vctx.addMems()

    with open(argv[2], 'wt') as f:
        vctx.dump(f, 'xm8051_golden_model')
Esempio n. 8
0
def forceRegsToZero(st, v):
    if st in zero_regs:
        return ast.BitVecVar(st, 8)
    return v
Esempio n. 9
0
def gen_gm(astdir, cnstfile, opcode, outputfile):
    asts = readAllASTs(astdir)
    assert len(asts) == 0x100

    vctx = VerilogContext() 
    cnst = readCnst(cnstfile)

    subs = ast2verilog.AddrSubs()
    cnst_p = ast2verilog.rewriteMemReads(-1, cnst, subs)
    vctx.setCnst(cnst_p)

    this_opcode = opcode
    vctx.cinputs.append(('XRAM_DATA_IN', (7, 0)))
    vctx.objects[ast.BitVecVar('XRAM_DATA_IN', 8)] = 'XRAM_DATA_IN'
    vctx.addInput(ast.BitVecVar('XRAM_ADDR', 16), (15,0))
    vctx.addInput(ast.BitVecVar('XRAM_DATA_OUT', 8), (7,0))

    for i in xrange(4):
        pi = 'P%dIN' % i
        pireg = 'P%dINREG' % i
        vctx.cinputs.append((pi, (7,0)))
        vctx.always_stmts.append('%s <= %s;' % (pireg, pi))


    asts_p = []
    for opcode, astdict in enumerate(asts):
        astdict_p = []
        acc_v = None
        for st, v in astdict.iteritems():
            v_p1 = ast2verilog.stripMacros(v)
            v_p2 = ast2verilog.rewriteMemReads(opcode, v_p1, subs)
            v_p3 = forceRegsToZero(st, v_p2)
            v_p = rewritePortsAsInputs(opcode, st, v_p3)
            astdict_p.append((st, v_p))
            if st == 'ACC':
                acc_v = v_p

        assert acc_v != None
        acc_p = ast.BVXor(ast.Extract(7, 7, acc_v),
                ast.BVXor(ast.Extract(6, 6, acc_v),
                ast.BVXor(ast.Extract(5, 5, acc_v),
                ast.BVXor(ast.Extract(4, 4, acc_v),
                ast.BVXor(ast.Extract(3, 3, acc_v),
                ast.BVXor(ast.Extract(2, 2, acc_v),
                ast.BVXor(ast.Extract(1, 1, acc_v), 
                ast.Extract(0, 0, acc_v))))))))
        for i in xrange(len(astdict_p)):
            st = astdict_p[i][0]
            v = astdict_p[i][1]
            if st == 'PSW':
                v_p = ast.Concat(ast.Extract(7, 1, v), acc_p)
                astdict_p[i] = (st, v_p)

        asts_p.append(astdict_p)

    ports = subs.getReadPorts()
    for m, s in ports:
        vctx.addComment("port: " + m.name + "->" + str(s))
        vctx.createWire(s)
        if m.name == 'ROM':
            vctx.cinputs.append((s, vctx.getWidth(s)))
            vctx.objects[s] = s.name;

    for m, s in ports:
        addr_expr = subs.getExpr(cnst_p, m, s, this_opcode, vctx)
        addr_name = s.name + "_ADDR"
        vctx.addComment(addr_name + "=" + str(addr_expr))
        vctx.addAssignment(addr_expr, vctx.getExpr(addr_expr), addr_name)
        if(m.name != 'ROM'):
            rd_expr = ast2verilog.resizeMem(ast.ReadMem(m, addr_expr), 'IRAM', 4)
            vctx.addAssignment(rd_expr, vctx.getExpr(rd_expr), s.name)
        else:
            vctx.outputs.append((addr_name, vctx.getWidth(addr_expr)))

    for opcode, astdict in enumerate(asts_p):
        assert len(astdict) == 25

        for st, v in astdict:
            # ignore the case where nothing changes.
            if v.isVar() and v.name == st and v.isMem(): continue
            if st in zero_regs: continue

            # some comments to show what is going on.
            vctx.addComment('')
            vctx.addComment('%s_%02x' % (st, opcode))
            vctx.addComment('')

            if v.isMem(): 
                mw = vctx.getMemWrite(st, ast2verilog.resizeMem(v, 'IRAM', 4))
                if mw != None: vctx.addMemWrite(st, opcode, mw)
            else:
                if opcode != this_opcode: continue

                name = '%s_%02x' % (st, opcode)
                vctx.addAssignment(v, vctx.getExpr(v), name)
                vctx.addStateChange(st, opcode, name)


    vctx.addOutputsSingleOp(this_opcode)
    vctx.addMems(this_opcode)
    vctx.outputs.append(('IRAM_full', (127,0)))
    vctx.statements.append('assign IRAM_full = {IRAM[15], IRAM[14], IRAM[13], IRAM[12], IRAM[11], IRAM[10], IRAM[9], IRAM[8], IRAM[7], IRAM[6], IRAM[5], IRAM[4], IRAM[3], IRAM[2], IRAM[1], IRAM[0]} ;')
    vctx.setRst('P0', 'ff')
    vctx.setRst('P1', 'ff')
    vctx.setRst('P2', 'ff')
    vctx.setRst('P3', 'ff')
    vctx.setRst('TCON', '0')
    vctx.setRst('SP', '7')
    addZeroRegs(vctx)
    addMissingInputs(vctx)

    vctx.init_mem_guard = 'OC8051_SIMULATION'
    with open(outputfile, 'wt') as f:
        vctx.dump(f, 'oc8051_golden_model')
Esempio n. 10
0
    def writeMem(self, mem, writes, this_opcode):
        wrports = WritePorts()

        if this_opcode:
            maxports = 0
            for opcode, stmts in writes.iteritems():
                if maxports < len(stmts):
                    maxports = len(stmts)

            a_conds, a_addrs, a_datas = [], [], []
            for i in xrange(maxports):
                ca_i = 'WR_COND_ABSTR_%s_%d' % (mem.name, i)
                aa_i = 'WR_ADDR_ABSTR_%s_%d' % (mem.name, i)
                da_i = 'WR_DATA_ABSTR_%s_%d' % (mem.name, i)

                cond_i = '(%s && !(%s))' % (
                    ca_i,
                    self.getExpr(
                        ast.Equal(self.cnst,
                                  ast.BitVecVal(this_opcode,
                                                self.cnst.width))))
                a_conds.append(cond_i)
                a_addrs.append(aa_i)
                a_datas.append(da_i)

                self.cinputs.append((ca_i, None))
                self.cinputs.append((aa_i, (mem.awidth - 1, 0)))
                self.cinputs.append((da_i, (mem.dwidth - 1, 0)))

        for opcode, stmts in writes.iteritems():
            if this_opcode:
                for i, [c, m, a, d] in enumerate(stmts):
                    assert m == mem
                    if opcode == this_opcode:
                        wrports.addWrite(i, c, a, d)
            else:
                for i, [c, m, a, d] in enumerate(stmts):
                    assert m == mem
                    wrports.addWrite(i, c, a, d)

        if this_opcode:
            for i in xrange(maxports):
                wrports.addWrite(i, a_conds[i], a_addrs[i], a_datas[i])
        # print mem.name, 'num ports:', wrports.numPorts
        for i in xrange(wrports.numPorts):
            addrport = 'WR_ADDR_%d_%s' % (i, mem.name)
            dataport = 'WR_DATA_%d_%s' % (i, mem.name)
            condport = 'WR_COND_%d_%s' % (i, mem.name)
            addr = ast.BitVecVar(addrport, mem.awidth)
            self.createWire(addr)
            data = ast.BitVecVar(dataport, mem.dwidth)
            self.createWire(data)
            cond = ast.BoolVar(condport)
            self.createWire(cond)

            self.addAssignment(addr, wrports.addrExpr(i), addr.name)
            self.addAssignment(data, wrports.dataExpr(i), data.name)
            self.addAssignment(cond, wrports.condExpr(i), cond.name)

            self.always_stmts.append('if (%s) %s[%s] <= %s;' %
                                     (condport, mem.name, addrport, dataport))
Esempio n. 11
0

def eval(op, inputs, outputs):
    a = inputs['a']
    b = inputs['b']
    c = inputs['c']

    if op == 0:
        outputs['r'] = ((a + b) & 0xFF) if c == 227 else 0
    else:
        outputs['r'] = (a + op) & 0xFF


syn = Synthesizer()

a = syn.addInput(ast.BitVecVar('a', 8))
b = syn.addInput(ast.BitVecVar('b', 8))
c = syn.addInput(ast.BitVecVar('c', 8))

r_add = ast.If(
    ast.Equal(c,
              ast.BVInRange('c', ast.BitVecVal(220, 8), ast.BitVecVal(230,
                                                                      8))),
    ast.Add(a, b), ast.BitVecVal(0, 8))
r_inc = ast.Add(
    a, ast.BVInRange('inc', ast.BitVecVal(1, 8), ast.BitVecVal(11, 8)))
r = ast.Choice('r', None, [r_add, r_inc])

syn.addOutput('r', r, Synthesizer.BITVEC)

syn.VERBOSITY = 2