1 |
8 |
fcorthay |
--##############################################################################
|
2 |
|
|
--
|
3 |
|
|
-- nanoProcessor
|
4 |
|
|
-- Processor core
|
5 |
|
|
--
|
6 |
|
|
-- This describes the processor core, without the instruction ROM.
|
7 |
|
|
--
|
8 |
|
|
--------------------------------------------------------------------------------
|
9 |
|
|
--
|
10 |
|
|
-- Versions / Authors
|
11 |
|
|
-- 1.0 Francois Corthay first implementation
|
12 |
|
|
--
|
13 |
|
|
-- Provided under GNU LGPL licence: <http://www.gnu.org/copyleft/lesser.html>
|
14 |
|
|
--
|
15 |
|
|
-- by the electronics group of "HES-SO//Valais Wallis", in Switzerland:
|
16 |
|
|
-- <http://www.hevs.ch/en/rad-instituts/institut-systemes-industriels/>.
|
17 |
|
|
--
|
18 |
|
|
--------------------------------------------------------------------------------
|
19 |
|
|
--
|
20 |
|
|
-- Hierarchy
|
21 |
|
|
-- Used by "nanoblaze".
|
22 |
|
|
--
|
23 |
|
|
--##############################################################################
|
24 |
|
|
|
25 |
|
|
LIBRARY ieee;
|
26 |
|
|
USE ieee.std_logic_1164.all;
|
27 |
|
|
USE ieee.numeric_std.all;
|
28 |
|
|
|
29 |
|
|
ENTITY nanoProcessor IS
|
30 |
|
|
GENERIC(
|
31 |
|
|
addressBitNb : positive := 8;
|
32 |
|
|
registerBitNb : positive := 8;
|
33 |
|
|
registerAddressBitNb : positive := 4;
|
34 |
|
|
programCounterBitNb : positive := 10;
|
35 |
|
|
stackPointerBitNb : positive := 5;
|
36 |
|
|
instructionBitNb : positive := 18;
|
37 |
|
|
scratchpadAddressBitNb : natural := 4
|
38 |
|
|
);
|
39 |
|
|
PORT(
|
40 |
9 |
fcorthay |
reset : IN std_uLogic;
|
41 |
|
|
clock : IN std_uLogic;
|
42 |
|
|
en : IN std_uLogic;
|
43 |
|
|
progCounter : OUT unsigned(programCounterBitNb-1 DOWNTO 0);
|
44 |
|
|
instruction : IN std_ulogic_vector(instructionBitNb-1 DOWNTO 0);
|
45 |
|
|
dataAddress : OUT unsigned(addressBitNb-1 DOWNTO 0);
|
46 |
|
|
dataOut : OUT std_ulogic_vector(registerBitNb-1 DOWNTO 0);
|
47 |
|
|
dataIn : IN std_ulogic_vector(registerBitNb-1 DOWNTO 0);
|
48 |
|
|
readStrobe : OUT std_uLogic;
|
49 |
|
|
writeStrobe : OUT std_uLogic;
|
50 |
|
|
int : IN std_uLogic;
|
51 |
|
|
intAck : OUT std_ulogic
|
52 |
8 |
fcorthay |
);
|
53 |
|
|
END nanoProcessor ;
|
54 |
|
|
|
55 |
|
|
--==============================================================================
|
56 |
|
|
|
57 |
|
|
ARCHITECTURE struct OF nanoProcessor IS
|
58 |
|
|
|
59 |
|
|
constant aluCodeBitNb: positive := 5;
|
60 |
|
|
constant opCodeBitNb: positive := 5;
|
61 |
|
|
constant branchCondBitNb: positive := 3;
|
62 |
|
|
constant intCodeBitNb: positive := 5;
|
63 |
|
|
|
64 |
|
|
SIGNAL addrA : unsigned(registerAddressBitNb-1 DOWNTO 0);
|
65 |
|
|
SIGNAL addrB : unsigned(registerAddressBitNb-1 DOWNTO 0);
|
66 |
|
|
SIGNAL aluCode : std_ulogic_vector(aluCodeBitNb-1 DOWNTO 0);
|
67 |
|
|
SIGNAL branchCond : std_ulogic_vector(branchCondBitNb-1 DOWNTO 0);
|
68 |
|
|
SIGNAL cIn : std_ulogic;
|
69 |
|
|
SIGNAL cOut : std_ulogic;
|
70 |
|
|
SIGNAL incPC : std_ulogic;
|
71 |
|
|
SIGNAL instrAddress : unsigned(programCounterBitNb-1 DOWNTO 0);
|
72 |
|
|
SIGNAL instrData : signed(registerBitNb-1 DOWNTO 0);
|
73 |
|
|
SIGNAL instrDataSel : std_ulogic;
|
74 |
|
|
SIGNAL instrString : string(1 TO 16);
|
75 |
|
|
SIGNAL intCode : std_ulogic_vector(intCodeBitNb-1 DOWNTO 0);
|
76 |
|
|
SIGNAL loadInstrAddress : std_ulogic;
|
77 |
|
|
SIGNAL loadStoredPC : std_ulogic;
|
78 |
|
|
SIGNAL opCode : std_ulogic_vector(opCodeBitNb-1 DOWNTO 0);
|
79 |
|
|
SIGNAL portIn : signed(registerBitNb-1 DOWNTO 0);
|
80 |
|
|
SIGNAL portInSel : std_ulogic;
|
81 |
|
|
SIGNAL portIndexedSel : std_ulogic;
|
82 |
|
|
SIGNAL portInstrAddress : unsigned(addressBitNb-1 DOWNTO 0);
|
83 |
|
|
SIGNAL portOut : signed(registerBitNb-1 DOWNTO 0);
|
84 |
|
|
SIGNAL portRegAddress : unsigned(addressBitNb-1 DOWNTO 0);
|
85 |
|
|
SIGNAL prevPC : std_ulogic;
|
86 |
|
|
SIGNAL regWrite : std_ulogic;
|
87 |
|
|
SIGNAL registerFileSel : std_ulogic;
|
88 |
|
|
SIGNAL scratchpadSel : std_ulogic;
|
89 |
|
|
SIGNAL scratchpadWrite : std_ulogic;
|
90 |
|
|
SIGNAL spadAddress : unsigned(scratchpadAddressBitNb-1 DOWNTO 0);
|
91 |
|
|
SIGNAL spadIn : signed(registerBitNb-1 DOWNTO 0);
|
92 |
|
|
SIGNAL spadIndexedSel : std_ulogic;
|
93 |
|
|
SIGNAL spadInstrAddress : unsigned(scratchpadAddressBitNb-1 DOWNTO 0);
|
94 |
|
|
SIGNAL spadOut : signed(registerBitNb-1 DOWNTO 0);
|
95 |
|
|
SIGNAL spadRegAddress : unsigned(scratchpadAddressBitNb-1 DOWNTO 0);
|
96 |
|
|
SIGNAL storePC : std_ulogic;
|
97 |
|
|
SIGNAL storedProgCounter : unsigned(programCounterBitNb-1 DOWNTO 0);
|
98 |
|
|
SIGNAL twoRegInstr : std_ulogic;
|
99 |
|
|
SIGNAL zero : std_ulogic;
|
100 |
|
|
|
101 |
|
|
SIGNAL progCounter_int : unsigned(progCounter'range);
|
102 |
|
|
|
103 |
|
|
COMPONENT aluAndRegs
|
104 |
|
|
GENERIC (
|
105 |
|
|
registerBitNb : positive := 8;
|
106 |
|
|
registerAddressBitNb : positive := 4;
|
107 |
|
|
aluCodeBitNb : positive := 5;
|
108 |
|
|
portAddressBitNb : positive := 8;
|
109 |
|
|
scratchpadAddressBitNb : natural := 4
|
110 |
|
|
);
|
111 |
|
|
PORT (
|
112 |
9 |
fcorthay |
reset : IN std_ulogic;
|
113 |
|
|
clock : IN std_ulogic;
|
114 |
|
|
aluCode : IN std_ulogic_vector(aluCodeBitNb-1 DOWNTO 0);
|
115 |
8 |
fcorthay |
addrA : IN unsigned(registerAddressBitNb-1 DOWNTO 0);
|
116 |
|
|
addrB : IN unsigned(registerAddressBitNb-1 DOWNTO 0);
|
117 |
|
|
instrData : IN signed(registerBitNb-1 DOWNTO 0);
|
118 |
9 |
fcorthay |
registerFileSel : IN std_ulogic;
|
119 |
8 |
fcorthay |
instrDataSel : IN std_ulogic;
|
120 |
|
|
portInSel : IN std_ulogic;
|
121 |
9 |
fcorthay |
scratchpadSel : IN std_ulogic;
|
122 |
8 |
fcorthay |
regWrite : IN std_ulogic;
|
123 |
9 |
fcorthay |
cIn : IN std_ulogic;
|
124 |
8 |
fcorthay |
cOut : OUT std_ulogic;
|
125 |
9 |
fcorthay |
zero : OUT std_ulogic;
|
126 |
8 |
fcorthay |
portAddr : OUT unsigned(portAddressBitNb-1 DOWNTO 0);
|
127 |
|
|
portOut : OUT signed(registerBitNb-1 DOWNTO 0);
|
128 |
9 |
fcorthay |
portIn : IN signed(registerBitNb-1 DOWNTO 0);
|
129 |
8 |
fcorthay |
scratchpadAddr : OUT unsigned(scratchpadAddressBitNb-1 DOWNTO 0);
|
130 |
|
|
spadOut : OUT signed(registerBitNb-1 DOWNTO 0);
|
131 |
9 |
fcorthay |
spadIn : IN signed(registerBitNb-1 DOWNTO 0)
|
132 |
8 |
fcorthay |
);
|
133 |
|
|
END COMPONENT;
|
134 |
|
|
|
135 |
|
|
COMPONENT branchStack
|
136 |
|
|
GENERIC (
|
137 |
|
|
programCounterBitNb : positive := 10;
|
138 |
|
|
stackPointerBitNb : positive := 5
|
139 |
|
|
);
|
140 |
|
|
PORT (
|
141 |
9 |
fcorthay |
reset : IN std_ulogic;
|
142 |
8 |
fcorthay |
clock : IN std_ulogic;
|
143 |
9 |
fcorthay |
progCounter : IN unsigned(programCounterBitNb-1 DOWNTO 0);
|
144 |
8 |
fcorthay |
prevPC : IN std_ulogic;
|
145 |
|
|
storePC : IN std_ulogic;
|
146 |
9 |
fcorthay |
storedProgCounter : OUT unsigned(programCounterBitNb-1 DOWNTO 0)
|
147 |
8 |
fcorthay |
);
|
148 |
|
|
END COMPONENT;
|
149 |
|
|
|
150 |
|
|
COMPONENT controller
|
151 |
|
|
GENERIC (
|
152 |
|
|
intCodeBitNb : positive := 5;
|
153 |
|
|
branchCondBitNb : positive := 3;
|
154 |
|
|
opCodeBitNb : positive := 5
|
155 |
|
|
);
|
156 |
|
|
PORT (
|
157 |
9 |
fcorthay |
reset : IN std_ulogic;
|
158 |
8 |
fcorthay |
clock : IN std_ulogic;
|
159 |
|
|
en : IN std_ulogic;
|
160 |
|
|
opCode : IN std_ulogic_vector(opCodeBitNb-1 DOWNTO 0);
|
161 |
|
|
twoRegInstr : IN std_ulogic;
|
162 |
9 |
fcorthay |
registerFileSel : OUT std_ulogic;
|
163 |
|
|
instrDataSel : OUT std_ulogic;
|
164 |
|
|
portInSel : OUT std_ulogic;
|
165 |
|
|
scratchpadSel : OUT std_ulogic;
|
166 |
|
|
regWrite : OUT std_ulogic;
|
167 |
|
|
readStrobe : OUT std_ulogic;
|
168 |
|
|
writeStrobe : OUT std_uLogic;
|
169 |
|
|
scratchpadWrite : OUT std_ulogic;
|
170 |
|
|
branchCond : IN std_ulogic_vector(branchCondBitNb-1 DOWNTO 0);
|
171 |
|
|
cOut : IN std_ulogic;
|
172 |
8 |
fcorthay |
zero : IN std_ulogic;
|
173 |
|
|
cIn : OUT std_ulogic;
|
174 |
|
|
incPC : OUT std_ulogic;
|
175 |
|
|
loadInstrAddress : OUT std_ulogic;
|
176 |
|
|
loadStoredPC : OUT std_ulogic;
|
177 |
|
|
prevPC : OUT std_ulogic;
|
178 |
|
|
storePC : OUT std_ulogic;
|
179 |
9 |
fcorthay |
intCode : IN std_ulogic_vector(intCodeBitNb-1 DOWNTO 0);
|
180 |
|
|
int : IN std_ulogic;
|
181 |
|
|
intAck : OUT std_ulogic
|
182 |
8 |
fcorthay |
);
|
183 |
|
|
END COMPONENT;
|
184 |
|
|
|
185 |
|
|
COMPONENT instructionDecoder
|
186 |
|
|
GENERIC (
|
187 |
|
|
registerBitNb : positive := 8;
|
188 |
|
|
registerAddressBitNb : positive := 4;
|
189 |
|
|
aluCodeBitNb : positive := 5;
|
190 |
|
|
instructionBitNb : positive := 18;
|
191 |
|
|
programCounterBitNb : positive := 10;
|
192 |
|
|
opCodeBitNb : positive := 5;
|
193 |
|
|
branchCondBitNb : positive := 3;
|
194 |
|
|
intCodeBitNb : positive := 5;
|
195 |
|
|
spadAddressBitNb : natural := 4;
|
196 |
|
|
portAddressBitNb : positive := 8
|
197 |
|
|
);
|
198 |
|
|
PORT (
|
199 |
|
|
instruction : IN std_ulogic_vector(instructionBitNb-1 DOWNTO 0);
|
200 |
9 |
fcorthay |
aluCode : OUT std_ulogic_vector(aluCodeBitNb-1 DOWNTO 0);
|
201 |
8 |
fcorthay |
addrA : OUT unsigned(registerAddressBitNb-1 DOWNTO 0);
|
202 |
|
|
addrB : OUT unsigned(registerAddressBitNb-1 DOWNTO 0);
|
203 |
9 |
fcorthay |
instrData : OUT signed(registerBitNb-1 DOWNTO 0);
|
204 |
|
|
instrAddress : OUT unsigned(programCounterBitNb-1 DOWNTO 0);
|
205 |
|
|
opCode : OUT std_ulogic_vector(opCodeBitNb-1 DOWNTO 0);
|
206 |
|
|
twoRegInstr : OUT std_ulogic;
|
207 |
8 |
fcorthay |
branchCond : OUT std_ulogic_vector(branchCondBitNb-1 DOWNTO 0);
|
208 |
|
|
intCode : OUT std_ulogic_vector(intCodeBitNb-1 DOWNTO 0);
|
209 |
9 |
fcorthay |
portIndexedSel : OUT std_ulogic;
|
210 |
8 |
fcorthay |
portAddress : OUT unsigned(portAddressBitNb-1 DOWNTO 0);
|
211 |
|
|
spadIndexedSel : OUT std_ulogic;
|
212 |
9 |
fcorthay |
spadAddress : OUT unsigned(spadAddressBitNb-1 DOWNTO 0)
|
213 |
8 |
fcorthay |
);
|
214 |
|
|
END COMPONENT;
|
215 |
|
|
|
216 |
|
|
COMPONENT programCounter
|
217 |
|
|
GENERIC (
|
218 |
|
|
programCounterBitNb : positive := 10
|
219 |
|
|
);
|
220 |
|
|
PORT (
|
221 |
9 |
fcorthay |
reset : IN std_ulogic;
|
222 |
8 |
fcorthay |
clock : IN std_ulogic;
|
223 |
9 |
fcorthay |
instrAddress : IN unsigned(programCounterBitNb-1 DOWNTO 0);
|
224 |
|
|
storedProgCounter : IN unsigned(programCounterBitNb-1 DOWNTO 0);
|
225 |
8 |
fcorthay |
incPC : IN std_ulogic;
|
226 |
|
|
loadInstrAddress : IN std_ulogic;
|
227 |
|
|
loadStoredPC : IN std_ulogic;
|
228 |
9 |
fcorthay |
progCounter : OUT unsigned(programCounterBitNb-1 DOWNTO 0)
|
229 |
8 |
fcorthay |
);
|
230 |
|
|
END COMPONENT;
|
231 |
|
|
|
232 |
|
|
COMPONENT scratchpad
|
233 |
|
|
GENERIC (
|
234 |
|
|
registerBitNb : positive := 8;
|
235 |
|
|
spadAddressBitNb : natural := 4
|
236 |
|
|
);
|
237 |
|
|
PORT (
|
238 |
9 |
fcorthay |
reset : IN std_ulogic;
|
239 |
|
|
clock : IN std_ulogic;
|
240 |
8 |
fcorthay |
addr : IN unsigned(spadAddressBitNb-1 DOWNTO 0);
|
241 |
9 |
fcorthay |
write : IN std_ulogic;
|
242 |
8 |
fcorthay |
dataIn : IN signed(registerBitNb-1 DOWNTO 0);
|
243 |
|
|
dataOut : OUT signed(registerBitNb-1 DOWNTO 0 )
|
244 |
|
|
);
|
245 |
|
|
END COMPONENT;
|
246 |
|
|
|
247 |
|
|
BEGIN
|
248 |
|
|
I_alu : aluAndRegs
|
249 |
|
|
GENERIC MAP (
|
250 |
|
|
registerBitNb => registerBitNb,
|
251 |
|
|
registerAddressBitNb => registerAddressBitNb,
|
252 |
|
|
aluCodeBitNb => aluCodeBitNb,
|
253 |
|
|
portAddressBitNb => addressBitNb,
|
254 |
|
|
scratchpadAddressBitNb => scratchpadAddressBitNb
|
255 |
|
|
)
|
256 |
|
|
PORT MAP (
|
257 |
9 |
fcorthay |
reset => reset,
|
258 |
|
|
clock => clock,
|
259 |
|
|
aluCode => aluCode,
|
260 |
8 |
fcorthay |
addrA => addrA,
|
261 |
|
|
addrB => addrB,
|
262 |
|
|
instrData => instrData,
|
263 |
9 |
fcorthay |
registerFileSel => registerFileSel,
|
264 |
8 |
fcorthay |
instrDataSel => instrDataSel,
|
265 |
|
|
portInSel => portInSel,
|
266 |
9 |
fcorthay |
scratchpadSel => scratchpadSel,
|
267 |
8 |
fcorthay |
regWrite => regWrite,
|
268 |
9 |
fcorthay |
cIn => cIn,
|
269 |
8 |
fcorthay |
cOut => cOut,
|
270 |
9 |
fcorthay |
zero => zero,
|
271 |
8 |
fcorthay |
portAddr => portRegAddress,
|
272 |
|
|
portOut => portOut,
|
273 |
9 |
fcorthay |
portIn => portIn,
|
274 |
8 |
fcorthay |
scratchpadAddr => spadRegAddress,
|
275 |
|
|
spadOut => spadOut,
|
276 |
9 |
fcorthay |
spadIn => spadIn
|
277 |
8 |
fcorthay |
);
|
278 |
|
|
|
279 |
|
|
I_BR : branchStack
|
280 |
|
|
GENERIC MAP (
|
281 |
|
|
programCounterBitNb => programCounterBitNb,
|
282 |
|
|
stackPointerBitNb => stackPointerBitNb
|
283 |
|
|
)
|
284 |
|
|
PORT MAP (
|
285 |
9 |
fcorthay |
reset => reset,
|
286 |
8 |
fcorthay |
clock => clock,
|
287 |
9 |
fcorthay |
progCounter => progCounter_int,
|
288 |
8 |
fcorthay |
prevPC => prevPC,
|
289 |
|
|
storePC => storePC,
|
290 |
|
|
storedProgCounter => storedProgCounter
|
291 |
|
|
);
|
292 |
|
|
|
293 |
|
|
I_ctrl : controller
|
294 |
|
|
GENERIC MAP (
|
295 |
|
|
intCodeBitNb => 5,
|
296 |
|
|
branchCondBitNb => branchCondBitNb,
|
297 |
|
|
opCodeBitNb => opCodeBitNb
|
298 |
|
|
)
|
299 |
|
|
PORT MAP (
|
300 |
9 |
fcorthay |
reset => reset,
|
301 |
8 |
fcorthay |
clock => clock,
|
302 |
|
|
en => en,
|
303 |
|
|
opCode => opCode,
|
304 |
|
|
twoRegInstr => twoRegInstr,
|
305 |
9 |
fcorthay |
registerFileSel => registerFileSel,
|
306 |
|
|
instrDataSel => instrDataSel,
|
307 |
|
|
portInSel => portInSel,
|
308 |
|
|
scratchpadSel => scratchpadSel,
|
309 |
|
|
regWrite => regWrite,
|
310 |
|
|
readStrobe => readStrobe,
|
311 |
|
|
writeStrobe => writeStrobe
|
312 |
|
|
scratchpadWrite => scratchpadWrite,
|
313 |
|
|
branchCond => branchCond,
|
314 |
|
|
cOut => cOut,
|
315 |
8 |
fcorthay |
zero => zero,
|
316 |
|
|
cIn => cIn,
|
317 |
|
|
incPC => incPC,
|
318 |
|
|
loadInstrAddress => loadInstrAddress,
|
319 |
|
|
loadStoredPC => loadStoredPC,
|
320 |
|
|
prevPC => prevPC,
|
321 |
|
|
storePC => storePC,
|
322 |
9 |
fcorthay |
intCode => intCode,
|
323 |
|
|
int => int,
|
324 |
|
|
intAck => intAck
|
325 |
8 |
fcorthay |
);
|
326 |
|
|
|
327 |
|
|
I_instr : instructionDecoder
|
328 |
|
|
GENERIC MAP (
|
329 |
|
|
registerBitNb => registerBitNb,
|
330 |
|
|
registerAddressBitNb => registerAddressBitNb,
|
331 |
|
|
aluCodeBitNb => aluCodeBitNb,
|
332 |
|
|
instructionBitNb => instructionBitNb,
|
333 |
|
|
programCounterBitNb => programCounterBitNb,
|
334 |
|
|
opCodeBitNb => opCodeBitNb,
|
335 |
|
|
branchCondBitNb => branchCondBitNb,
|
336 |
|
|
intCodeBitNb => 5,
|
337 |
|
|
spadAddressBitNb => scratchpadAddressBitNb,
|
338 |
|
|
portAddressBitNb => addressBitNb
|
339 |
|
|
)
|
340 |
|
|
PORT MAP (
|
341 |
|
|
instruction => instruction,
|
342 |
9 |
fcorthay |
aluCode => aluCode,
|
343 |
8 |
fcorthay |
addrA => addrA,
|
344 |
|
|
addrB => addrB,
|
345 |
9 |
fcorthay |
instrData => instrData,
|
346 |
|
|
instrAddress => instrAddress,
|
347 |
|
|
opCode => opCode,
|
348 |
|
|
twoRegInstr => twoRegInstr,
|
349 |
8 |
fcorthay |
branchCond => branchCond,
|
350 |
|
|
intCode => intCode,
|
351 |
9 |
fcorthay |
portIndexedSel => portIndexedSel,
|
352 |
8 |
fcorthay |
portAddress => portInstrAddress,
|
353 |
|
|
spadIndexedSel => spadIndexedSel,
|
354 |
9 |
fcorthay |
spadAddress => spadInstrAddress
|
355 |
8 |
fcorthay |
);
|
356 |
|
|
|
357 |
|
|
I_PC : programCounter
|
358 |
|
|
GENERIC MAP (
|
359 |
|
|
programCounterBitNb => programCounterBitNb
|
360 |
|
|
)
|
361 |
|
|
PORT MAP (
|
362 |
9 |
fcorthay |
reset => reset,
|
363 |
8 |
fcorthay |
clock => clock,
|
364 |
9 |
fcorthay |
instrAddress => instrAddress,
|
365 |
|
|
storedProgCounter => storedProgCounter,
|
366 |
8 |
fcorthay |
incPC => incPC,
|
367 |
|
|
loadInstrAddress => loadInstrAddress,
|
368 |
|
|
loadStoredPC => loadStoredPC,
|
369 |
|
|
progCounter => progCounter_int
|
370 |
|
|
);
|
371 |
|
|
|
372 |
|
|
generate_scratchpad: IF scratchpadAddressBitNb > 0 GENERATE
|
373 |
|
|
BEGIN
|
374 |
|
|
I_sPad : scratchpad
|
375 |
|
|
GENERIC MAP (
|
376 |
|
|
registerBitNb => registerBitNb,
|
377 |
|
|
spadAddressBitNb => scratchpadAddressBitNb
|
378 |
|
|
)
|
379 |
|
|
PORT MAP (
|
380 |
9 |
fcorthay |
reset => reset,
|
381 |
|
|
clock => clock,
|
382 |
8 |
fcorthay |
addr => spadAddress,
|
383 |
9 |
fcorthay |
write => scratchpadWrite,
|
384 |
8 |
fcorthay |
dataIn => spadOut,
|
385 |
|
|
dataOut => spadIn
|
386 |
|
|
);
|
387 |
|
|
END GENERATE generate_scratchpad;
|
388 |
|
|
|
389 |
|
|
portIn <= signed(dataIn);
|
390 |
|
|
dataAddress <= portInstrAddress when portIndexedSel = '0' else portRegAddress;
|
391 |
|
|
dataOut <= std_ulogic_vector(portOut);
|
392 |
|
|
spadAddress <= spadInstrAddress when spadIndexedSel = '0' else spadRegAddress;
|
393 |
|
|
|
394 |
|
|
progCounter <= progCounter_int;
|
395 |
|
|
|
396 |
|
|
------------------------------------------------------------------------------
|
397 |
|
|
-- disassembler: reads "instruction" and writes "instrString"
|
398 |
|
|
--
|
399 |
|
|
-- pragma translate_off
|
400 |
|
|
process(instruction)
|
401 |
|
|
|
402 |
|
|
constant bitsPerHexDigit : positive := 4;
|
403 |
|
|
|
404 |
|
|
function pad(inString : string; outLength : positive) return string is
|
405 |
|
|
variable outString : string(1 to outLength);
|
406 |
|
|
begin
|
407 |
|
|
outString := (others => ' ');
|
408 |
|
|
outString(inString'range) := inString;
|
409 |
|
|
return outString;
|
410 |
|
|
end function pad;
|
411 |
|
|
|
412 |
|
|
function hexDigitNb(bitNb : positive) return positive is
|
413 |
|
|
begin
|
414 |
|
|
return (bitNb-1)/bitsPerHexDigit+1;
|
415 |
|
|
end function hexDigitNb;
|
416 |
|
|
|
417 |
|
|
variable opCode : unsigned(1+opCodeBitNb-1 downto 0);
|
418 |
|
|
variable destRegister : unsigned(registerAddressBitNb-1 downto 0);
|
419 |
|
|
variable destRegisterString : string(1 to 1+hexDigitNb(registerAddressBitNb));
|
420 |
|
|
variable sourceRegister : unsigned(registerAddressBitNb-1 downto 0);
|
421 |
|
|
variable sourceRegisterString : string(1 to 1+hexDigitNb(registerAddressBitNb));
|
422 |
|
|
variable sourceConstant : unsigned(registerBitNb-1 downto 0);
|
423 |
|
|
variable sourceConstantString : string(1 to hexDigitNb(registerBitNb));
|
424 |
|
|
variable branchAddress : unsigned(programCounterBitNb-1 downto 0);
|
425 |
|
|
variable branchAddressString : string(1 to hexDigitNb(programCounterBitNb));
|
426 |
|
|
variable branchKind : unsigned(1 downto 0);
|
427 |
|
|
variable shRotCin : unsigned(2 downto 0);
|
428 |
|
|
variable shRotDir: std_ulogic;
|
429 |
|
|
|
430 |
|
|
function toHexDigit(binary : unsigned(bitsPerHexDigit-1 downto 0)) return character is
|
431 |
|
|
begin
|
432 |
|
|
if binary <= 9 then
|
433 |
|
|
return character'val(character'pos('0') + to_integer(to_01(binary)));
|
434 |
|
|
else
|
435 |
|
|
return character'val(character'pos('A') + to_integer(to_01(binary)) - 10);
|
436 |
|
|
end if;
|
437 |
|
|
end function toHexDigit;
|
438 |
|
|
|
439 |
|
|
function toHexString(binary : unsigned) return string is
|
440 |
|
|
variable hexString : string(1 to hexDigitNb(binary'length));
|
441 |
|
|
begin
|
442 |
|
|
for index in hexString'high-1 downto 0 loop
|
443 |
|
|
hexString(hexString'high-index) := toHexDigit(
|
444 |
|
|
resize(shift_right(binary, bitsPerHexDigit*index), bitsPerHexDigit)
|
445 |
|
|
);
|
446 |
|
|
end loop;
|
447 |
|
|
return hexString;
|
448 |
|
|
end function toHexString;
|
449 |
|
|
|
450 |
|
|
begin
|
451 |
|
|
|
452 |
|
|
opCode := resize(
|
453 |
|
|
shift_right(unsigned(instruction), instruction'length-opCode'length),
|
454 |
|
|
opCode'length
|
455 |
|
|
);
|
456 |
|
|
destRegister := resize(
|
457 |
|
|
shift_right(unsigned(instruction), instruction'length-opCode'length-destRegister'length),
|
458 |
|
|
destRegister'length
|
459 |
|
|
);
|
460 |
|
|
destRegisterString := 's' & toHexDigit(destRegister);
|
461 |
|
|
sourceRegister := resize(
|
462 |
|
|
shift_right(unsigned(instruction), instruction'length-opCode'length-destRegister'length-sourceRegister'length),
|
463 |
|
|
sourceRegister'length
|
464 |
|
|
);
|
465 |
|
|
sourceRegisterString := 's' & toHexDigit(sourceRegister);
|
466 |
|
|
sourceConstant := resize(unsigned(instruction), sourceConstant'length);
|
467 |
|
|
sourceConstantString := toHexString(sourceConstant);
|
468 |
|
|
branchKind := resize(
|
469 |
|
|
shift_right(unsigned(instruction), instruction'length-opCode'length-branchKind'length),
|
470 |
|
|
branchKind'length
|
471 |
|
|
);
|
472 |
|
|
branchAddress := resize(unsigned(instruction), branchAddress'length);
|
473 |
|
|
branchAddressString := toHexString(branchAddress);
|
474 |
|
|
shRotCin := resize(shift_right(unsigned(instruction), 1), shRotCin'length);
|
475 |
|
|
shRotDir := instruction(0);
|
476 |
|
|
|
477 |
|
|
case opCode is
|
478 |
|
|
when "000000" => instrString <= pad("LOAD " & destRegisterString & " " & sourceConstantString, instrString'length);
|
479 |
|
|
when "000001" => instrString <= pad("LOAD " & destRegisterString & " " & sourceRegisterString, instrString'length);
|
480 |
|
|
when "000100" => instrString <= pad("INPUT " & destRegisterString & " " & sourceConstantString, instrString'length);
|
481 |
|
|
when "000101" => instrString <= pad("INPUT " & destRegisterString & " " & sourceRegisterString, instrString'length);
|
482 |
|
|
when "000110" => instrString <= pad("FETCH " & destRegisterString & " " & sourceConstantString, instrString'length);
|
483 |
|
|
when "000111" => instrString <= pad("FETCH " & destRegisterString & " " & sourceRegisterString, instrString'length);
|
484 |
|
|
when "001010" => instrString <= pad("AND " & destRegisterString & " " & sourceConstantString, instrString'length);
|
485 |
|
|
when "001011" => instrString <= pad("AND " & destRegisterString & " " & sourceRegisterString, instrString'length);
|
486 |
|
|
when "001100" => instrString <= pad("OR " & destRegisterString & " " & sourceConstantString, instrString'length);
|
487 |
|
|
when "001101" => instrString <= pad("OR " & destRegisterString & " " & sourceRegisterString, instrString'length);
|
488 |
|
|
when "001110" => instrString <= pad("XOR " & destRegisterString & " " & sourceConstantString, instrString'length);
|
489 |
|
|
when "001111" => instrString <= pad("XOR " & destRegisterString & " " & sourceRegisterString, instrString'length);
|
490 |
|
|
when "010010" => instrString <= pad("TEST " & destRegisterString & " " & sourceConstantString, instrString'length);
|
491 |
|
|
when "010011" => instrString <= pad("TEST " & destRegisterString & " " & sourceRegisterString, instrString'length);
|
492 |
|
|
when "010100" => instrString <= pad("COMP " & destRegisterString & " " & sourceConstantString, instrString'length);
|
493 |
|
|
when "010101" => instrString <= pad("COMP " & destRegisterString & " " & sourceRegisterString, instrString'length);
|
494 |
|
|
when "011000" => instrString <= pad("ADD " & destRegisterString & " " & sourceConstantString, instrString'length);
|
495 |
|
|
when "011001" => instrString <= pad("ADD " & destRegisterString & " " & sourceRegisterString, instrString'length);
|
496 |
|
|
when "011010" => instrString <= pad("ADDCY " & destRegisterString & " " & sourceConstantString, instrString'length);
|
497 |
|
|
when "011011" => instrString <= pad("ADDCY " & destRegisterString & " " & sourceRegisterString, instrString'length);
|
498 |
|
|
when "011100" => instrString <= pad("SUB " & destRegisterString & " " & sourceConstantString, instrString'length);
|
499 |
|
|
when "011101" => instrString <= pad("SUB " & destRegisterString & " " & sourceRegisterString, instrString'length);
|
500 |
|
|
when "011110" => instrString <= pad("SUBCY " & destRegisterString & " " & sourceConstantString, instrString'length);
|
501 |
|
|
when "011111" => instrString <= pad("SUBCY " & destRegisterString & " " & sourceRegisterString, instrString'length);
|
502 |
|
|
when "100000" =>
|
503 |
|
|
case shRotCin is
|
504 |
|
|
when "000" => instrString <= pad("SLA " & destRegisterString, instrString'length);
|
505 |
|
|
when "001" => instrString <= pad("RL " & destRegisterString, instrString'length);
|
506 |
|
|
when "010" => instrString <= pad("SLX " & destRegisterString, instrString'length);
|
507 |
|
|
when "011" =>
|
508 |
|
|
case shRotDir is
|
509 |
|
|
when '0' => instrString <= pad("SL0 " & destRegisterString, instrString'length);
|
510 |
|
|
when '1' => instrString <= pad("SL1 " & destRegisterString, instrString'length);
|
511 |
|
|
when others => instrString <= pad("--------", instrString'length);
|
512 |
|
|
end case;
|
513 |
|
|
when "100" => instrString <= pad("SRA " & destRegisterString, instrString'length);
|
514 |
|
|
when "101" => instrString <= pad("SRX " & destRegisterString, instrString'length);
|
515 |
|
|
when "110" => instrString <= pad("RR " & destRegisterString, instrString'length);
|
516 |
|
|
when "111" =>
|
517 |
|
|
case shRotDir is
|
518 |
|
|
when '0' => instrString <= pad("SR0 " & destRegisterString, instrString'length);
|
519 |
|
|
when '1' => instrString <= pad("SR1 " & destRegisterString, instrString'length);
|
520 |
|
|
when others => instrString <= pad("--------", instrString'length);
|
521 |
|
|
end case;
|
522 |
|
|
when others => instrString <= pad("--------", instrString'length);
|
523 |
|
|
end case;
|
524 |
|
|
when "101100" => instrString <= pad("OUTPUT " & destRegisterString & " " & sourceConstantString, instrString'length);
|
525 |
|
|
when "101101" => instrString <= pad("OUTPUT " & destRegisterString & " (" & sourceRegisterString & ")", instrString'length);
|
526 |
|
|
when "101110" => instrString <= pad("STORE " & destRegisterString & " " & sourceConstantString, instrString'length);
|
527 |
|
|
when "101111" => instrString <= pad("STORE " & destRegisterString & " (" & sourceRegisterString & ")", instrString'length);
|
528 |
|
|
when "101010" => instrString <= pad("RET", instrString'length);
|
529 |
|
|
when "101011" =>
|
530 |
|
|
case branchKind is
|
531 |
|
|
when "00" => instrString <= pad("RET Z", instrString'length);
|
532 |
|
|
when "01" => instrString <= pad("RET NZ", instrString'length);
|
533 |
|
|
when "10" => instrString <= pad("RET C", instrString'length);
|
534 |
|
|
when "11" => instrString <= pad("RET NC", instrString'length);
|
535 |
|
|
when others => instrString <= pad("--------", instrString'length);
|
536 |
|
|
end case;
|
537 |
|
|
when "110000" => instrString <= pad("CALL " & branchAddressString, instrString'length);
|
538 |
|
|
when "110001" =>
|
539 |
|
|
case branchKind is
|
540 |
|
|
when "00" => instrString <= pad("CALL Z " & branchAddressString, instrString'length);
|
541 |
|
|
when "01" => instrString <= pad("CALL NZ " & branchAddressString, instrString'length);
|
542 |
|
|
when "10" => instrString <= pad("CALL C " & branchAddressString, instrString'length);
|
543 |
|
|
when "11" => instrString <= pad("CALL NC " & branchAddressString, instrString'length);
|
544 |
|
|
when others => instrString <= pad("--------", instrString'length);
|
545 |
|
|
end case;
|
546 |
|
|
when "110100" => instrString <= pad("JUMP " & branchAddressString, instrString'length);
|
547 |
|
|
when "110101" =>
|
548 |
|
|
case branchKind is
|
549 |
|
|
when "00" => instrString <= pad("JUMP Z " & branchAddressString, instrString'length);
|
550 |
|
|
when "01" => instrString <= pad("JUMP NZ " & branchAddressString, instrString'length);
|
551 |
|
|
when "10" => instrString <= pad("JUMP C " & branchAddressString, instrString'length);
|
552 |
|
|
when "11" => instrString <= pad("JUMP NC " & branchAddressString, instrString'length);
|
553 |
|
|
when others => instrString <= pad("--------", instrString'length);
|
554 |
|
|
end case;
|
555 |
|
|
when others => instrString <= pad("--------", instrString'length);
|
556 |
|
|
end case;
|
557 |
|
|
|
558 |
|
|
end process;
|
559 |
|
|
-- pragma translate_on
|
560 |
|
|
--
|
561 |
|
|
-- end of disassembler
|
562 |
|
|
------------------------------------------------------------------------------
|
563 |
|
|
|
564 |
|
|
END ARCHITECTURE struct;
|