-
Notifications
You must be signed in to change notification settings - Fork 3
/
Copy pathalu.py
executable file
·164 lines (127 loc) · 4.37 KB
/
alu.py
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
from block import Block
from data import Data
class ALU(Block):
"""
Inputs:
- X - 32b vstupní data
- Y - 32b vstupní data
- i - 31. bit v instruckti (předposlední)
- funct3:
000: add ('i' = 0)
000: sub ('i' = 1)
010: slt (set if less than) (pokud pravda tak výsledek = 1)
011: sltu (set if less than unsigned) (pokud pravda tak výsledek = 1)
100: xor
110: or
111: and
- funct3; porovnávání: (nastavování 'branch' pokud je to pravda)
000: beq (branch if equal)
001: bne (branch if not equal)
100: blt (branch if less than)
101: bge (branch if greater or equal)
110: bltu (branch if less than unsigned)
111: bgeu (branch if greater or equal unsigned)
Outputs:
- result - 32b ouptut
- branch - 1b, potvrzení podmíněného skoku
"""
def __init__(self, data: Data) -> None:
super().__init__(data)
def clock_up(self):
self.at_clock()
def clock_down(self):
self.at_clock()
def at_clock(self):
result = 0
prepared_instruction = bin(self.data.instruction)[2:].zfill(32)
funct3 = int(prepared_instruction[17:20], 2)
i = int(prepared_instruction[1], 2)
# funct3 = (self.data.instruction & 0b00000000000000000111000000000000) >> 12
# i = (self.data.instruction & 0b01000000000000000000000000000000) >> 30
# print(prepared_instruction, funct32, funct3)
X = self.data.read_register_1
Y = self.data.mux_out
# logger.info(f"DEBUG -> RB0: {self.data.read_register_1}, MUXO: {self.data.mux_out}, f3: {funct3}, i: {i}")
n = X & 0xffffffff
signed_X = (n ^ 0x80000000) - 0x80000000
n = Y & 0xffffffff
signed_Y = (n ^ 0x80000000) - 0x80000000
alu_op_0 = self.data.ALU_OP_0
alu_op_1 = self.data.ALU_OP_1
if alu_op_0 and not alu_op_1:
funct3 = 0
i = 0
elif alu_op_1:
i = 0
# --------------------------------
# ALU
# --------------------------------
self.data.Branch = 0
if funct3 == 0b000:
# add
if i == 0:
result = (X + Y) & 0xffffffff
# sub
else:
result = (X - Y) & 0xffffffff
# beq
if X == Y:
self.data.Branch = 1
# bne
elif funct3 == 0b001:
if X != Y:
self.data.Branch = 1
# slt
elif funct3 == 0b010:
if signed_X < signed_Y:
result = 1
# sltu
elif funct3 == 0b011:
if X < Y:
result = 1
# xor
elif funct3 == 0b100:
result = X ^ Y
# blt
if signed_X < signed_Y:
self.data.Branch = 1
# bge
elif funct3 == 0b101:
if signed_X >= signed_Y:
self.data.Branch = 1
# or
elif funct3 == 0b110:
result = X | Y
# bltu
if X <= Y:
self.data.Branch = 1
# and
elif funct3 == 0b111:
result = X & Y
# bgeu
if X >= Y:
self.data.Branch = 1
self.data.alu_out = int(result) & 0xffffffff
# ALU_should_be = self.debug_data.get_value("ALU", self.data.pulse_count)
# logger.info(f"Operand X: {X} Y: {Y}")
# logger.info(
# f"ALU result = {result} (0x{hex(result)[2:].zfill(8)}) Branch = {is_branch} (should be: 0x{hex(ALU_should_be)[2:].zfill(8)})")
# if ALU_should_be != result:
# # logger.error("ALU error!!")
# if __name__ == '__main__':
# f3 = 0b000
# i = 0
#
# data = Data()
# alu = ALU(data, logger)
#
# data.ALU_OP_0 = 0
# data.ALU_OP_1 = 0
#
# data.read_register_1 = 0xffffffff & 1
# data.mux_out = 0xffffffff & 0
# data.instruction = (f3 << 12) | (i << 30)
#
# alu.at_clock()
# print(f"result: {data.alu_out}, 0b{bin(data.alu_out)[2:].zfill(32)}")
# print(f"branch: {data.Branch}")