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

Subversion Repositories natalius_8bit_risc

[/] [natalius_8bit_risc/] [trunk/] [assembler/] [assembler.py] - Blame information for rev 14

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 2 fabioandre
#!/usr/bin/python
2
 
3
import sys
4
import re
5
 
6
tipo1=['ldi','ldm','stm', 'adi']
7
tipo2=['cmp','add','sub','and','oor','xor']
8
tipo3=['jmp','jpz','jnz','jpc','jnc','csr', 'csz', 'cnz', 'csc', 'cnc']
9
tipo4=['sl0','sl1','sr0','sr1','rrl','rrr', 'not']
10
tipo5=['ret', 'nop']
11
#instruccion   opcode
12
opcodes={}
13
opcodes['ldi']=2;
14
opcodes['ldm']=3;
15
opcodes['stm']=4;
16
opcodes['cmp']=5;
17
opcodes['add']=6;
18
opcodes['sub']=7;
19
opcodes['and']=8;
20
opcodes['oor']=9;
21
opcodes['xor']=10;
22
opcodes['jmp']=11;
23
opcodes['jpz']=12;
24
opcodes['jnz']=13;
25
opcodes['jpc']=14;
26
opcodes['jnc']=15;
27
opcodes['csr']=16;
28
opcodes['ret']=17;
29
opcodes['adi']=18;
30
opcodes['csz']=19;
31
opcodes['cnz']=20;
32
opcodes['csc']=21;
33
opcodes['cnc']=22;
34
opcodes['sl0']=23;
35
opcodes['sl1']=24;
36
opcodes['sr0']=25;
37
opcodes['sr1']=26;
38
opcodes['rrl']=27;
39
opcodes['rrr']=28;
40
opcodes['not']=29;
41
opcodes['nop']=30;
42
 
43
 
44
 
45
def verify_args(line):
46
    if len(line)>1:
47
        line_split=line.split()
48
        opcode=line_split[0]
49
        if opcode in tipo1+tipo2+tipo4:
50
            args=re.findall(r'r(\d+)',line)
51
    else:
52
        return 'invalid command'
53
 
54
    if not opcode in tipo1+tipo2+tipo3+tipo4+tipo5:
55
        return 'invalid command'
56
    else:
57
        if opcode in tipo1:
58
            arg2=line.split(',')
59
            direccion=arg2[1]
60
 
61
            if len(args)!=1 :
62
                return 'incorrect number of arguments'
63
            else:
64
                if int(args[0])<0 or int(args[0])>7:
65
                    return 'arg1 out of range (0-7)'
66
                else:
67
                    if int(direccion)<0 or int(direccion)>255:
68
                        return 'addr out of range (0-255)'
69
                    else:
70
                        return 'ok'
71
 
72
        if opcode in tipo2:
73
            if len(args)!=2:
74
                return 'incorrect number of arguments'
75
            else:
76
                if int(args[0])<0 or int(args[0])>7:
77
                    return 'arg1 out of range (0-7)'
78
                else:
79
                    if int(args[1])<0 or int(args[1])>7:
80
                        return 'arg2 out of range (0-7)'
81
                    else:
82
                        return 'ok'
83
        if opcode in tipo3:
84
            addr=line_split[1]
85
            if len(line_split)!=2:
86
                return 'incorrect argument'
87
            else:
88
                if int(addr)<0 or int(addr)>2048:
89
                    return 'addr out of range (0-2048)'
90
                else:
91
                    return 'ok'
92
 
93
        if opcode in tipo4:
94
            if len(args)!=2 :
95
                return 'incorrect number of arguments'
96
            else:
97
                if int(args[1])<0 or int(args[1])>7:
98
                    return 'arg1 out of range (0-7)'
99
                else:
100
                    return 'ok'
101
 
102
        if opcode in tipo5:
103
            return 'ok'
104
 
105
 
106
def extract_info(file,flag):
107
    tags={}
108
    f=open(file,'rU')
109
    text=f.read()
110
    f.close()
111
    text=text.lower()
112
 
113
 
114
    #para quitar los saltos de linea '\n' '\t' al final del archivo
115
    while text[-1]=='\n' or text[-1]=='\t' or text[-1]=='\s' or text[-1]=='\r':
116
        text=text[:-1]
117
 
118
    lines=text.split('\n')
119
    line_number=0
120
    lines2=[]
121
 
122
    for line in lines:
123
        if len(line)!=0:
124
            line_split=line.split()
125
            opcode=line_split[0]
126
            if not opcode in tipo1+tipo2+tipo3+tipo4+tipo5:
127
                if not opcode in tags:
128
                    tags[opcode]=line_number
129
                    line=' '.join(line_split[1:])
130
                    line='\t'+line
131
 
132
                else:
133
                    print 'label used more than once'
134
 
135
            lines2.append(line)
136
            line_number+=1
137
 
138
    text2='\n'.join(lines2)
139
    ##parte que se encarga de reemplazar los tags en las direcciones
140
    for tags_elements in tags.keys():
141
        line2=text2.split(tags_elements)
142
        text2=str(tags[tags_elements]).join(line2)
143
 
144
 
145
    lines=text2.split('\n')
146
    error_line=0
147
    text_asm=''
148
    for line in lines:
149
        erro=verify_args(line)
150
        if erro!='ok':
151
            print 'error in line:',error_line
152
            print line, '->', erro,'\n'
153
        else:
154
            line_split=line.split()
155
            opcode=line_split[0]
156
            if opcode in tipo1+tipo2+tipo4:
157
                args=re.findall(r'r(\d+)',line)
158
            if opcode in tipo1:
159
                arg2=line.split(',')
160
                direccion=arg2[1]
161
                dato=(opcodes[opcode]<<11) | (int(args[0])<<8) | int(direccion)
162
                text_asm+= '%X' % dato + '\n'
163
            if opcode in tipo2:
164
                dato=(opcodes[opcode]<<11) | (int(args[0])<<8) | (int(args[1])<<5)
165
                text_asm+= '%X' % dato + '\n'
166
            if opcode in tipo3:
167
                addr=line_split[1]
168
                dato=(opcodes[opcode]<<11) | int(addr)
169
                text_asm+= '%X' % dato + '\n'
170
            if opcode in tipo4:
171
                dato=(opcodes[opcode]<<11) | (int(args[1])<<8)
172
                text_asm+= '%X' % dato + '\n'
173
            if opcode in tipo5:
174
                dato=(opcodes[opcode]<<11)
175
                text_asm+= '%X' % dato + '\n'
176
        error_line+=1
177
 
178
    line_show=text2.split('\n')
179
    line_text=text_asm.split('\n')
180
 
181
    if flag:
182
        print 'addr inst\t\t\t\tasm\n'
183
        for i in range(len(line_show)):
184
            esp=4-len(line_text[i])
185
            val=''
186
            while esp:
187
                esp-=1
188
                val+=' '
189
 
190
            ntabs=5-len(str(i))
191
            tab=' '
192
            etab=''
193
            ctabs=0
194
            while ctabs<ntabs:
195
                ctabs+=1
196
                etab+=tab
197
 
198
            print str(i)+etab+line_text[i]+val+'\t'+line_show[i]
199
 
200
    line_zero=''
201
 
202
    for i in range(2048-len(line_show)):
203
        line_zero=line_zero+'0000\n'
204
    text_asm+=line_zero
205
 
206
    return text_asm
207
 
208
def main():
209
 
210
    args = sys.argv[1:]
211
 
212
    if not args:
213
        print 'uso: ./assembler.py [-s] archivo.asm'
214
        sys.exit(1)
215
 
216
    show = False
217
    if args[0] == '-s':
218
        show = True
219
        del args[0]
220
 
221
    text=extract_info(args[0],show)
222
    outf = open('instructions.mem', 'w')
223
    outf.write(text)
224
    outf.close()
225
 
226
 
227
 
228
if __name__ == '__main__':
229
  main()

powered by: WebSVN 2.1.0

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