-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathIAS.py
More file actions
210 lines (182 loc) · 8.11 KB
/
IAS.py
File metadata and controls
210 lines (182 loc) · 8.11 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
from bitstring import BitStream
class IAS:
def read(self, address):
'''
do the computation
'''
baddress = BitStream('0b' + address)
return self.selectron[baddress.int]
def input(self, address, value):
'''
provide input for the machine
'''
baddress = BitStream('0b' + address)
self.selectron[baddress.int] = BitStream(int = value, length = 40)
def instruction(self, opcode, address):
'''
0b will be put automatically
'''
bopcode = BitStream('0b' + opcode)
baddress = BitStream('0b' + address)
self.ops[bopcode.read('bin:8')](baddress.int)
'''Data transfer instructions '''
def loadToAC (self, register):
'''
LOAD MQ: Transfer contents of register MQ to the accumulator AC
'''
self.AC = self.MQ
def loadToMQ(self, register):
'''
LOAD MQ,M(X): Transfer contents of memory location X (M(X)) to MQ
'''
self.MQ = BitStream(int=self.selectron[register].int, length=40)
def store(self, register):
'''
STOR M(X): Transfer contents of accumulator AC to memory location X (M(X))
'''
self.selectron[register] = self.AC
def load(self, register):
'''
LOAD M(X): Transfer M(X) to the accumulator AC
'''
self.AC = self.selectron[register]
def loadNeg(self, register):
'''
LOAD -M(X): Transfer -M(X) to the accumulator AC
'''
self.AC = self.selectron[register] | 0x8000000000
def loadAbs(self, register):
'''
LOAD |M(X)|: Transfer absolute value of M(X) to the accumulator AC
'''
mask = self.selectron[register]>>39
mask = mask ^ self.selectron[register]
self.AC = (mask^n) - mask
def loadNegAbs(self, register):
'''
LOAD -|M(X)|: Transfer -|M(X)| to the accumulator AC
'''
mask = self.selectron[register]>>39
mask ^ self.selectron[register]
self.AC = ((mask^n) - mask) | 0x8000000000
'''End data transfer instructions'''
'''Unconditional jump instructions'''
def jumpL(self, register):
'''
JUMP M(X,0:19): Take next instruction from left half of M(X)
'''
ops[self.selectron[register][0:19]](register)
def jumpR(self, register):
'''
JUMP M(X,20:39): Take next instruction from right half of M(X)
'''
ops[self.selectron[register][20:39]](register)
''''End unconditional jump instructions'''
'''Conditional jump instructions'''
def condJumpL(self, register):
'''
JUMP+M(X,0:19): If number in the accumulator AC is nonnegative, take next instruction from left half of M(X)
'''
if(self.AC[39] == 1):
ops[self.selectron[register][0:7]](self.selectron[register][8:19].int)
def condJumpR(self, register):
'''
JUMP+M(X,20:39): If number in the accumulator AC is nonnegative , take next instruction from right half of M(X)
'''
if(self.AC[39] == 1):
ops[self.selectron[register][20:27]](self.selectron[register][28:40].int)
'''End conditional jump instructions'''
'''Arithmetic instructions'''
def add(self, register):
'''
ADD M(X): Add M(X) to AC; put the result in AC
'''
self.AC = BitStream(int=self.AC.int + self.selectron[register].int, length=40)
def addAbs(self, register):
'''
ADD |M(X)|: Add |M(X)| to AC; put the result in AC
'''
self.AC = BitStream(int=self.AC.int + abs(self.selectron[register].int), length=40)
def sub(self, register):
'''
SUB M(X): Subtract M(X) from AC; put the result in AC
'''
self.AC = BitStream(int=self.AC.int - self.selectron[register].int, length=40)
def subRem(self, register):
'''
SUB |M(X)|: Subtract |M(X)| from AC; put the remainder in self.AC
'''
self.AC = BitStream(int=self.AC.int + abs(self.selectron[register].int), length=40)
def mul(self, register):
'''
MUL M(X): Multiply M(X) by M(Q); put most significant bits of result in AC, put less significant bits in M(Q)
'''
res = BitStream(int=self.MQ.int * self.selectron[register].int, length=80)
self.AC = BitStream(int=res[40:80].int, length=40)
self.MQ = BitStream(int=res[0:39].int, length=40)
def div(self, register):
'''
DIV M(X): Divide AC by M(X); put the quotient in MQ and the remainder in AC
'''
quo = BitStream(int=(self.AC.int / self.selectron[register].int), length=40)
rem = BitStream(int=self.AC.int % self.selectron[register].int, length=40)
self.AC = quo
self.MQ = rem
def ls(self, register):
'''
LSH: Multiply accumulator by 2 (i.e., shift left one bit position)
'''
self.AC <<= 1
def rs(self, register):
'''
RSH: Divide accumulator by 2 (i.e., shift right one bit position)
'''
self.AC >>= 1
'''End arithmetic instructions'''
'''Address modify instructions'''
def storL(self, register):
'''
STOR M(X,8:19): Replace left address field at M(X) by 12 right-most bits of AC
'''
self.selectron[register][20:39] = self.AC[0:19]
def storR(self, register):
'''
STOR M(X,28:39): Replace right address field at M(X) by 12 right-most bits of AC
'''
self.selectron[register][0:19] = self.AC[0:19]
'''End address modify instructions'''
def __init__(self):
'''
define opcodes for the instructions
'''
self.ops = {
'00001010': self.loadToAC, #LOAD MQ: Transfer contents of register MQ to the accumulator AC
'00001001': self.loadToMQ, #LOAD MQ,M(X): Transfer contents of memory location X to MQ
'00100001': self.store, #STOR M(X): Transfer contents of accumulator to memory location X
'00000001': self.load, #LOAD M(X): Transfer M(X) to the accumulator
'00000010': self.loadNeg, #LOAD -M(X): Transfer -M(X) to the accumulator
'00000011': self.loadAbs, #LOAD |M(X)|: Transfer absolute value of M(X) to the accumulator
'00000100': self.loadNegAbs, #LOAD -|M(X)|: Transfer -|M(X)| to the accumulator
'00001101': self.jumpL, #JUMP M(X,0:19): Take next instruction from left half of M(X)
'00001110': self.jumpR, #JUMP M(X,20:39): Take next instruction from right half of M(X)
'00001111': self.condJumpL, #JUMP+M(X,0:19): If number in the accumulator is nonnegative, take next instruction from left half of M(X)
'00010000': self.condJumpR, #JUMP+M(X,20:39): If number in the accumulator is nonnegative , take next instruction from right half of M(X)
'00000101': self.add, #ADD M(X): Add M(X) to AC; put the result in AC
'00000111': self.addAbs, #ADD |M(X)|: Add |M(X)| to AC; put the result in AC
'00000110': self.sub, #SUB M(X): Subtract M(X) from AC; put the result in AC
'00001000': self.subRem, #SUB |M(X)|: Subtract |M(X)} from AC; put the remainder in AC
'00001011': self.mul, #MUL M(X): Multiply M(X) by M(Q); put most significant bits of result in AC, put less significant bits in M(Q)
'00001100': self.div, #DIV M(X): Divide AC by M(X); put the quotient in MQ and the remainder in AC
'00010100': self.ls, #LSH: Multiply accumulator by 2 (i.e., shift left one bit position)
'00010101': self.rs, #RSH: Divide accumulator by 2 (i.e., shift right one bit position)
'00010010': self.storL, #STOR M(X,8:19): Replace left address field at M(X) by 12 right-most bits of AC
'00010011': self.storR, #STOR M(X,28:39): Replace right address field at M(X) by 12 right-most bits of AC
}
# define Accumulator and MQ registers
self.AC = BitStream(int=0, length=40)
self.MQ = BitStream(int=0, length=40)
self.selectron = []
i = 0
while i < 4096:
self.selectron.append(BitStream(int=0,length=40))
i+=1