-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathProgramControlUnit.java
More file actions
159 lines (150 loc) · 6.73 KB
/
ProgramControlUnit.java
File metadata and controls
159 lines (150 loc) · 6.73 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
import java.util.HashMap;
class ProgramControlUnit {
ISA ISA;
Registers registers;
ALU ALU;
Memory memory;
ProgramControlUnit(ALU ALU,Memory memory){
this.ISA=new ISA();
this.registers=new Registers();
this.ALU=ALU;
this.memory=memory;
}
class Registers{
int PC;
BitsArray MAR,IR,IBR;
Registers(){
this.PC=0;
this.MAR=new BitsArray(12,0);
this.IR=new BitsArray(8,0);
this.IBR=new BitsArray(20,0);
}
}
class ISA{
HashMap<String,Runnable>opcodes;
ISA(){
opcodes=new HashMap<String,Runnable>();
//LOAD_MQ
opcodes.put("00001010", ()->{
ALU.registers.AC=ALU.registers.MQ;});
//LOAD_MQ_MX
opcodes.put("00001001", ()->{
ALU.registers.MBR=memory.m.get(registers.MAR.getValue());
ALU.registers.MQ=ALU.registers.MBR;});
//STOR_MX
opcodes.put("00100001", ()->{
memory.m.set(registers.MAR.getValue(), ALU.registers.AC);});
//LOAD_MX
opcodes.put("00000001", ()->{
ALU.registers.MBR=memory.m.get(registers.MAR.getValue());
ALU.registers.AC=ALU.registers.MBR;});
//LOAD_negMX()
opcodes.put("00000010", ()->{
ALU.registers.MBR=memory.m.get(registers.MAR.getValue());
ALU.registers.AC=ALU.getNeg(ALU.registers.MBR);});
//LOAD_modMX
opcodes.put("00000011", ()->{
ALU.registers.MBR=memory.m.get(registers.MAR.getValue());
ALU.registers.AC=ALU.getNeg(ALU.getMOD(ALU.registers.MBR));});
//LOAD_negModMX
opcodes.put("00000100", ()->{
ALU.registers.MBR=memory.m.get(registers.MAR.getValue());
ALU.registers.AC=ALU.getNeg(ALU.getMOD(ALU.registers.MBR));});
//JUMP_MXleft
opcodes.put("00001101", ()->{
registers.PC=registers.MAR.getValue();
registers.IBR=new BitsArray(20,0);});
//JUMP_MXright
opcodes.put("00001110", ()->{
registers.PC=registers.MAR.getValue();
registers.IBR=memory.m.get(registers.MAR.getValue()).getRange(20, 40);});
//condJUMP_MXleft
opcodes.put("00001111", ()->{
if(ALU.registers.AC.getValue()>=0){
registers.PC=registers.MAR.getValue();
registers.IBR=new BitsArray(20,0);
}});
//condJUMP_MXright
opcodes.put("00010000", ()->{
if(ALU.registers.AC.getValue()>=0){
registers.PC=registers.MAR.getValue();
registers.IBR=memory.m.get(registers.MAR.getValue()).getRange(20, 40);
}});
//ADD_MX
opcodes.put("00000101", ()->{
ALU.registers.MBR=memory.m.get(registers.MAR.getValue());
ALU.registers.AC=ALU.add(ALU.registers.AC,ALU.registers.MBR);});
//ADD_modMX
opcodes.put("00000111", ()->{
ALU.registers.MBR=memory.m.get(registers.MAR.getValue());
ALU.registers.AC=ALU.add(ALU.registers.AC,ALU.getMOD(ALU.registers.MBR));});
//SUB_MX
opcodes.put("00000110", ()->{
ALU.registers.MBR=memory.m.get(registers.MAR.getValue());
ALU.registers.AC=ALU.sub(ALU.registers.AC,ALU.registers.MBR);});
//SUB_modMX
opcodes.put("00001000", ()->{
ALU.registers.MBR=memory.m.get(registers.MAR.getValue());
ALU.registers.AC=ALU.sub(ALU.registers.AC,ALU.getMOD(ALU.registers.MBR));});
//MUL_MX
opcodes.put("00001011", ()->{
ALU.registers.MBR=memory.m.get(registers.MAR.getValue());
BitsArray multiplication=ALU.mul(ALU.registers.MBR, ALU.registers.MQ);
ALU.registers.AC=multiplication.getRange(0, 40);
ALU.registers.MQ=multiplication.getRange(0, 80);});
//DIV_MX
opcodes.put("00001100", ()->{
ALU.registers.MBR=memory.m.get(registers.MAR.getValue());
BitsArray[]result=ALU.div(ALU.registers.AC,ALU.registers.MBR);
ALU.registers.MQ=result[0];
ALU.registers.AC=result[1];});
//LSH
opcodes.put("00010100", ()->{
ALU.registers.AC=ALU.LSH(ALU.registers.AC);});
//RSH
opcodes.put("00010101", ()->{
ALU.registers.AC=ALU.RSH(ALU.registers.AC);});
//STOR_MXleft
opcodes.put("00010010", ()->{
memory.m.set(registers.MAR.getValue(), memory.m.get(registers.MAR.getValue()).setRange(8, 20, ALU.registers.AC.getRange(28, 40)));});
//STOR_MXright
opcodes.put("00010011", ()->{
memory.m.set(registers.MAR.getValue(), memory.m.get(registers.MAR.getValue()).setRange(28, 40, ALU.registers.AC.getRange(28, 40)));});
//HALT
//opcodes.put("00000000", HALT());
}
}
MixedReturn decode(){
//HALT
if(registers.IR.isEmpty()){
return new MixedReturn(0,null);
}
//Opcode not found
else if(ISA.opcodes.get(registers.IR.getBits())==null){
return new MixedReturn(-1,null);
}
return new MixedReturn(1, ISA.opcodes.get(registers.IR.getBits()));
}
void fetch(){
if(!registers.IBR.isEmpty()){
registers.IR=registers.IBR.getRange(0,8);
registers.MAR=registers.IBR.getRange(8,20);
registers.IBR=new BitsArray(20,0);
registers.PC++;
}
else{
registers.MAR=new BitsArray(12,registers.PC);
ALU.registers.MBR=memory.m.get(registers.MAR.getValue());
if(!ALU.registers.MBR.getRange(0,20).isEmpty()){
registers.IR=ALU.registers.MBR.getRange(0,8);
registers.MAR=ALU.registers.MBR.getRange(8,20);
registers.IBR=ALU.registers.MBR.getRange(20,40);
}
else{
registers.IR=ALU.registers.MBR.getRange(20,28);
registers.MAR=ALU.registers.MBR.getRange(28,40);
registers.PC++;
}
}
}
}