· 8 years ago · Jan 17, 2018, 02:08 PM
1------------------------------------------------------------------------------
2-- --
3-- Intel 80386 VHDL model --
4-- Copyright (C) Convergent, Inc. 1988 --
5-- --
6-- File: i80386.vhd --
7-- Revision: E0.1 --
8-- Date Created: 6-12-1988 --
9-- Author: Mark Dakur --
10-- Function: This VHDL model emulates the Intel 80386 32-bit CPU --
11-- to the instruction and bus timing level. --
12-- Generics: Debug 1=Enable Reporting of Model Status. --
13-- 0=None (Default) --
14-- Inst --
15-- Performance --
16-- Speed --
17-- Target Simulator: ViewSim --
18-- --
19-- Reference Material: Intel Data Book, 80386-20, Oct., 1987 --
20-- Intel 80386 Programmers Reference, 1986 --
21-- 80386 Technical Reference, Edmund Strauss, 1987 --
22-- --
23-- Verification: No --
24-- Validation: No --
25-- Certification: No --
26-- --
27-- Behavioral models have two main parts: a package declaration and its --
28-- corresponding package body, and an entity declaration and its --
29-- corresponding architecture body. The package declaration and --
30-- package body define subprograms used by the behavioral model; --
31-- the entity declaration and architecture body define the behavior --
32-- of the model. --
33-- This file contains the entity declaration and architecture. --
34------------------------------------------------------------------------------
35------------------------------------------------------------------------------
36-- Specification --
37-- --
38-- 1.0 Introduction --
39-- 2.0 Description --
40-- --
41-- The i80386 consists of 6 functional units defined as follows: --
42-- --
43-- 1) Bus Interface Unit {BIunit} --
44-- Accepts internal requests for code fetches from the CPunit and --
45-- data transfers from the Eunit and prioritizes the requests. --
46-- It is the interface to the external pins (ports) of the package. --
47-- --
48-- 2) Code Prefetch Unit {CPunit} --
49-- Performs the program look ahead function. When the BIunit is not --
50-- performing bus cycles to execute an instruction, it uses the BIunit --
51-- to to fetch sequentially along the instruction byte stream. These --
52-- prefetched instructions are stored in the 16-byte Code Queue to --
53-- await processing by the IDunit. --
54-- --
55-- 3) Instruction Decode Unit {IDunit} --
56-- a) Instructions Supported: --
57-- 1) nop --
58-- 2) mov eax,"immediate 32 bit data" --
59-- 3) mov ebx,"immediate 32 bit data" --
60-- 4) mov eax,[ebx] --
61-- 5) mov [ebx],eax --
62-- 6) in al,"byte address" --
63-- 7) out "byte address",al --
64-- 8) inc eax --
65-- 9) inc ebx --
66-- 10) jmp "label" (relative nears and shorts) --
67-- --
68-- 4) Execution Unit {Eunit} --
69-- a) Control Unit {Cunit} --
70-- b) Data Unit {Dunit} --
71-- c) Protection Test Unit {PTunit} --
72-- --
73-- 5) Segmentation Unit {Sunit} --
74-- --
75-- 6) Paging Unit {Punit} --
76-- a) Page Translator Unit {PTunit} --
77-- i) Translation Lookaside Buffer {TLB} --
78-- a) Page Directory --
79-- b) Page Table --
80------------------------------------------------------------------------------
81------------------------------------------------------------------------------
82-- Revision History --
83-- --
84-- Revision --
85-- Level Date Engineer Description --
86-- -------- ------- --------------- --------------------------------------- --
87-- E0.1 6-12-88 Dakur First Release --
88------------------------------------------------------------------------------
89------------------------------------------------------------------------------
90--
91-- Entity declaration for i80386:
92--
93-- The following entity declaration begins the definition of the
94-- behavioral model of the i80386. It declares the model's name
95-- and its IO signals, or ports. This declaration defines the
96-- model's interface with enclosing designs; it defines the part
97-- of the model that is externally visible. Following this
98-- entity declaration is its corresponding architecture body;
99-- the architecture body defines the behavior of the model.
100--
101-----------------------------------------------------------------------
102PACKAGE i80386 is
103FUNCTION tohex (CONSTANT value, Bytes: IN INTEGER) RETURN integer;
104
105END i80386;
106
107PACKAGE BODY i80386 is
108FUNCTION tohex (CONSTANT value, Bytes: IN INTEGER) RETURN integer IS
109 VARIABLE dWord: vlbit_1d(31 downto 0);
110 VARIABLE Byte: vlbit_1d(31 downto 0);
111 VARIABLE Count: INTEGER;
112BEGIN
113 Count := 1;
114 dWord := vlbit_vector(value);
115 Convert: WHILE Count <= Bytes LOOP
116 CASE integer(Bytes) is
117 WHEN 4 =>
118 CASE Count is
119 WHEN 1 =>
120 Byte := X"000000" & dWord(31 downto 24);
121 WHEN 2 =>
122 Byte := X"000000" & dWord(23 downto 16);
123 WHEN 3 =>
124 Byte := X"000000" & dWord(15 downto 8);
125 WHEN 4 =>
126 Byte := X"000000" & dWord(7 downto 0);
127 WHEN OTHERS => NULL;
128 END CASE;
129 WHEN 2 =>
130 CASE Count is
131 WHEN 1 =>
132 Byte := X"000000" & dWord(15 downto 8);
133 WHEN 2 =>
134 Byte := X"000000" & dWord(7 downto 0);
135 WHEN OTHERS => NULL;
136 END CASE;
137 WHEN 1 =>
138 Byte := X"000000" & dWord(7 downto 0);
139 WHEN OTHERS => NULL;
140 END CASE;
141 Count := Count + 1;
142 CASE integer(Byte(7 downto 4)) is
143 WHEN 15 =>
144 put("F");
145 WHEN 14 =>
146 put("E");
147 WHEN 13 =>
148 put("D");
149 WHEN 12 =>
150 put("C");
151 WHEN 11 =>
152 put("B");
153 WHEN 10 =>
154 put("A");
155 WHEN 9 =>
156 put("9");
157 WHEN 8 =>
158 put("8");
159 WHEN 7 =>
160 put("7");
161 WHEN 6 =>
162 put("6");
163 WHEN 5 =>
164 put("5");
165 WHEN 4 =>
166 put("4");
167 WHEN 3 =>
168 put("3");
169 WHEN 2 =>
170 put("2");
171 WHEN 1 =>
172 put("1");
173 WHEN 0 =>
174 put("0");
175 WHEN OTHERS => put("X");
176 END CASE;
177 CASE integer(Byte(3 downto 0)) is
178 WHEN 15 =>
179 put("F");
180 WHEN 14 =>
181 put("E");
182 WHEN 13 =>
183 put("D");
184 WHEN 12 =>
185 put("C");
186 WHEN 11 =>
187 put("B");
188 WHEN 10 =>
189 put("A");
190 WHEN 9 =>
191 put("9");
192 WHEN 8 =>
193 put("8");
194 WHEN 7 =>
195 put("7");
196 WHEN 6 =>
197 put("6");
198 WHEN 5 =>
199 put("5");
200 WHEN 4 =>
201 put("4");
202 WHEN 3 =>
203 put("3");
204 WHEN 2 =>
205 put("2");
206 WHEN 1 =>
207 put("1");
208 WHEN 0 =>
209 put("0");
210 WHEN OTHERS => put("X");
211 END CASE;
212 END LOOP Convert;
213 put("h");
214 RETURN 1;
215END tohex;
216
217END i80386;
218USE work.i80386.tohex;
219entity i80386 is
220
221 GENERIC (CONSTANT Debug: BOOLEAN := FALSE;
222 CONSTANT Inst: BOOLEAN := FALSE;
223 CONSTANT Performance: INTEGER := 1;
224 CONSTANT Speed: INTEGER := 32);
225
226-- USE: Pass a value to the above generics from attributes attached to the 80386 symbol
227-- on the schematic.
228
229-- Description: Debug; A value of integer 1 (one) means that the model will output
230-- status information as simulation progresses. The default if no attribute exists is
231-- FALSE, or no status reported.
232
233-- Inst; A value of interger 1 (one) means that the model will output
234-- instructions. The Debug generic overides this one.
235
236-- Performance; 0=min, 1=typ, 2=max
237
238-- Speed; Processor speed choices, values are: 0=16MHz, 1=20MHz, 2=25MHZ, 3=30MHz
239
240 port (BE_n: out vlbit_1d(3 downto 0) := B"0000";
241 Address: out vlbit_1d(31 downto 2) := B"111111111111111111111111111111";
242 W_R_n: out vlbit := '0';
243 D_C_n: out vlbit := '1';
244 M_IO_n: out vlbit := '0';
245 LOCK_n, ADS_n: out vlbit := '1';
246 HLDA: out vlbit := '0';
247 Data: inout vlbit_1d(31 downto 0) := X"ZZZZZZZZ";
248 CLK2: in vlbit := '0';
249 NA_n, BS16_n: in vlbit := '1';
250 READY_n, HOLD, PERQ: in vlbit := '0';
251 BUSY_n, ERROR_n: in vlbit := '1';
252 INTR: in vlbit := '0';
253 NMI, RESET: in vlbit := '0');
254
255-- THE ORDER OF THE PORTS IS IMPORTANT FOR COMPATIBILITY WITH THE "PINORDER"
256-- ATTRIBUTE ON THE SYMBOL FOR THIS MODEL.
257
258end i80386;
259
260-----------------------------------------------------------------------
261-----------------------------------------------------------------------
262--
263-- Architecture Body of i80386:
264--
265-- The following architecture body defines the behavior of the i80386
266-- model. It consists of a set of process statements and other
267-- concurrent statements. These statements are all invoked when
268-- simulation begins, and continue to execute concurrently throughout
269-- simulation. The statements communicate via the internal signals
270-- declared at the top of the architecture body. Each statement either
271-- checks the validity of input signals, or modifies the values of
272-- output signals or internal signals in response to changes on input
273-- signals or internal signals.
274--
275-----------------------------------------------------------------------
276
277architecture behavior of i80386 is
278
279-- Internal Signals
280-- These information paths allow for communication between Concurent
281-- Process Blocks within the model. All signals that are defined here have
282-- global visibility. Signals, variables and constants defined within process
283-- blocks have local visibility within that process ONLY.
284
285 SIGNAL CLK: vlbit := '1'; -- 80386 internal clock=CLK2 / 2
286
287 SIGNAL StateNA: vlbit := '1';
288 SIGNAL StateBS16: vlbit := '1';
289 SIGNAL RequestPending: vlbit := '1';
290 CONSTANT Pending: vlbit := '1';
291 CONSTANT NotPending: vlbit := '0';
292 SIGNAL NonAligned: vlbit := '0';
293 SIGNAL ReadRequest: vlbit := '1';
294 SIGNAL MemoryFetch: vlbit := '1';
295 SIGNAL CodeFetch: vlbit := '1';
296 SIGNAL ByteEnable: vlbit_1d(3 downto 0) := X"0";
297 SIGNAL DataWidth: vlbit_1d(31 downto 0) := X"00000002";
298 CONSTANT WidthByte: INTEGER := 0; -- Byte
299 CONSTANT WidthWord: INTEGER := 1; -- Word (2 bytes)
300 CONSTANT WidthDword: INTEGER := 2; -- Dword (4 bytes)
301 SIGNAL dWord: vlbit_1d(31 downto 0) := X"00000000";
302
303 SIGNAL State: vlbit_1d(31 downto 0) := X"00000000"; -- State Register, Initialized to StateTi
304 CONSTANT StateTi: INTEGER := 0; -- Reset State
305 CONSTANT StateT1: INTEGER := 1; -- First state of a non-pipelined bus cycle
306 CONSTANT StateT2: INTEGER := 2; -- State where NA_n is false (non-pipelined)
307 CONSTANT StateT1P: INTEGER := 3; -- First state of a pipelined bus cycle
308 CONSTANT StateTh: INTEGER := 4; -- Hold acknowledge state
309 CONSTANT StateT2P: INTEGER := 5; -- Subsequent state of a pipelined bus cycle
310 CONSTANT StateT2I: INTEGER := 6; -- Subsequent state of a potential pipelined
311 -- bus cycle.
312 -- The constants are indexes into the vector State where each constant represents 1 bit of the vector.
313
314-- Internal User Registers
315--- General Purpose Data and Address
316 SIGNAL EAX: vlbit_1d(31 DOWNTO 0);
317 SIGNAL EDX: vlbit_1d(31 DOWNTO 0);
318 SIGNAL ECX: vlbit_1d(31 DOWNTO 0);
319 SIGNAL EBX: vlbit_1d(31 DOWNTO 0);
320 SIGNAL EBP: vlbit_1d(31 DOWNTO 0);
321 SIGNAL ESI: vlbit_1d(31 DOWNTO 0);
322 SIGNAL EDI: vlbit_1d(31 DOWNTO 0);
323 SIGNAL ESP: vlbit_1d(31 DOWNTO 0);
324-- NOTE: Create a proceedure that can be called with the appropriate mnemonic
325-- to access the appropriate register. Futher work must be done to implement
326-- the 16-bit and 8-bit versions of these registers.
327
328--- Segment Selectors
329 SIGNAL CS: vlbit_1d(15 DOWNTO 0); -- Code Segment
330 SIGNAL SS: vlbit_1d(15 DOWNTO 0); -- Stack Segment
331 SIGNAL DS: vlbit_1d(15 DOWNTO 0); -- Data Segment Module A
332 SIGNAL ES: vlbit_1d(15 DOWNTO 0); -- Data Segment Structure 1
333 SIGNAL FSS: vlbit_1d(15 DOWNTO 0); -- Data Segment Structure 2
334 SIGNAL GS: vlbit_1d(15 DOWNTO 0); -- Data Segment Structure 3
335
336--- Segment Descripters
337--- These register are associated with each Segment Selector Register and are
338--- not visible to the programmer.
339--- Instruction Pointer and Flags
340 SIGNAL rEIP: vlbit_1d(31 downto 0) := X"FFFFFFF0";
341-- Must create a proceedure to access by mnemonic the IP within the EIP register.
342 SIGNAL rEFLAGS: vlbit_1d(31 downto 0) := B"XXXXXXXXXXXXXXXX0XXXXXXXXX0X0X1X";
343 CONSTANT VM: INTEGER := 0;
344 CONSTANT RF: INTEGER := 0;
345 CONSTANT NT: INTEGER := 0;
346 CONSTANT IOPL: INTEGER := 0;
347 CONSTANT xOF: INTEGER := 0;
348 CONSTANT DF: INTEGER := 0;
349 CONSTANT xIF: INTEGER := 0;
350 CONSTANT TF: INTEGER := 0;
351 CONSTANT SF: INTEGER := 0;
352 CONSTANT ZF: INTEGER := 0;
353 CONSTANT AF: INTEGER := 4;
354 CONSTANT PF: INTEGER := 2;
355 CONSTANT CF: INTEGER := 0;
356
357--- Machine Control
358 SIGNAL rCR0: vlbit_1d(31 downto 0) := X"00000000";
359 SIGNAL rCR1: vlbit_1d(31 downto 0) := X"00000000";
360 SIGNAL rCR2: vlbit_1d(31 downto 0) := X"00000000";
361 -- Page Directory Base Register
362 SIGNAL rCR3: vlbit_1d(31 downto 0) := X"00000000";
363
364--- System Address (Memory Mapping Management)
365 -- Global Descripter Table Pointer
366 SIGNAL rGDTbase: vlbit_1d(31 downto 0) := X"00000000";
367 SIGNAL rGDTlimit: vlbit_1d(15 downto 0) := X"0000";
368 SIGNAL rGDTselector: vlbit_1d(15 downto 0) := X"0000";
369 -- Local Descripter Table Pointer
370 SIGNAL rLDTbase: vlbit_1d(31 downto 0) := X"00000000";
371 SIGNAL rLDTlimit: vlbit_1d(15 downto 0) := X"0000";
372 SIGNAL rLDTselector: vlbit_1d(15 downto 0) := X"0000";
373 -- Interrupt Descripter Table Pointer
374 SIGNAL rIDTbase: vlbit_1d(31 downto 0) := X"00000000";
375 SIGNAL rIDTlimit: vlbit_1d(15 downto 0) := X"0000";
376 SIGNAL rIDTselector: vlbit_1d(15 downto 0) := X"0000";
377 -- Task State Segment Descripter Table Pointer
378 SIGNAL rTSSbase: vlbit_1d(31 downto 0) := X"00000000";
379 SIGNAL rTSSlimit: vlbit_1d(15 downto 0) := X"0000";
380 SIGNAL rTSSselector: vlbit_1d(15 downto 0) := X"0000";
381 -- Page Table Register Files
382-- SIGNAL rfPageDir: vlbit_2d(0 to 1024,31 downto 0);
383-- SIGNAL rfPageTable: vlbit_2d(0 to 1024,31 downto 0);
384--- Debug
385--- Test
386
387-- 80386 Instruction Set (Supported by this model)
388
389--- Instruction Prefixes
390 CONSTANT REP: INTEGER := 16#F3#;
391 CONSTANT REPNE: INTEGER := 16#F2#;
392 CONSTANT LOCK: INTEGER := 16#F0#;
393
394--- Segment Override Prefixes
395 CONSTANT CSsop: INTEGER := 16#2E#;
396 CONSTANT SSsop: INTEGER := 16#36#;
397 CONSTANT DSsop: INTEGER := 16#3E#;
398 CONSTANT ESsop: INTEGER := 16#26#;
399 CONSTANT FSsop: INTEGER := 16#64#;
400 CONSTANT GSsop: INTEGER := 16#65#;
401 CONSTANT OPsop: INTEGER := 16#66#;
402 CONSTANT ADsop: INTEGER := 16#67#;
403
404--- Data Transfer
405 CONSTANT MOV_al_b: INTEGER := 16#B0#;
406 CONSTANT MOV_eax_dw: INTEGER := 16#B8#; -- mov eax,0000A5A5h
407 CONSTANT MOV_ebx_dw: INTEGER := 16#BB#; -- mov ebx,0FFFFFFF0h
408 CONSTANT MOV_ebx_eax: INTEGER := 16#89#; -- mov [ebx],eax {89,03}
409 CONSTANT MOV_eax_ebx: INTEGER := 16#8B#; -- mov eax,[ebx] {8B,03}
410 CONSTANT IN_al: INTEGER := 16#E4#;
411 CONSTANT OUT_al: INTEGER := 16#E6#;
412--- Arithmetic
413 CONSTANT ADD_al_b: INTEGER := 16#04#;
414 CONSTANT ADD_ax_w: INTEGER := 16#05#;
415--- Shift/Rotate
416 CONSTANT ROL_eax_b: INTEGER := 16#D1#; -- rol eax,1 {D1,C0}
417 CONSTANT ROL_al_1: INTEGER := 16#D0#;
418 CONSTANT ROL_al_n: INTEGER := 16#C0#;
419--- String Manipulation
420 CONSTANT INC_eax: INTEGER := 16#40#;
421 CONSTANT INC_ebx: INTEGER := 16#43#;
422--- Bit Manipulation
423--- Control Transfer
424 CONSTANT JMP_rel_short: INTEGER := 16#EB#;
425 CONSTANT JMP_rel_near: INTEGER := 16#E9#;
426 CONSTANT JMP_intseg_immed: INTEGER := 16#EA#;
427--- High Level Language Support
428--- Operating System Support
429--- Processor Control
430 CONSTANT HLT: INTEGER := 16#F4#;
431 CONSTANT WAITx: INTEGER := 16#9B#;
432 CONSTANT NOP: INTEGER := 16#90#;
433
434 BEGIN
435
436-- Begin Fault Detection Section
437 Faults: PROCESS
438 BEGIN
439 WAIT UNTIL now > 1;
440 assert not bitunknown(CLK2)
441 report "Clock {i}: CLK2 (pin F12) is undefined"
442 severity FAILURE;
443 assert not bitunknown(READY_n)
444 report "Control {i}: READY (pin G13) is undefined"
445 severity FAILURE;
446 END PROCESS Faults;
447-- End Fault Detection Section
448
449-- Begin Behavioral Blocks
450 -- Port Signals Status Reports Begin
451 CLK2status: PROCESS -- Function: The first time (after the loading the network)
452 -- the simulation is run, this process will report
453 -- status of the 80386's CLK2 input from the network.
454
455 VARIABLE StartTime: INTEGER;
456 VARIABLE Pwidth: INTEGER;
457 VARIABLE freq: INTEGER;
458 BEGIN
459 WAIT UNTIL prising(CLK2);
460 StartTime := now;
461 WAIT UNTIL prising(CLK2);
462 Pwidth := (now - StartTime);
463 freq := 10000000 / Pwidth;
464 put("CLK2 Pulse Width is=",Pwidth);
465 putline(" in 10ths of nS");
466 put("CLK2 Frequency is=",freq);
467 putline("kHZ");
468 WAIT;
469 end PROCESS CLK2status;
470 -- Port Signals Status Reports End
471
472 -- Internal Control Logic Processes Begin
473 GenCLK: PROCESS
474 begin
475 -- CLK is the 80386's internal clock an is 1/2 of CLK2
476 wait until prising(CLK2);
477 CLK <= not CLK;
478 end PROCESS GenCLK;
479
480 Initialize: PROCESS
481 BEGIN
482 EAX <= X"00000000";
483 rEFLAGS <= X"00000002";
484 rEIP <= X"FFFFFFF0";
485 rIDTbase <= X"00000000";
486 rIDTlimit <= X"03FF";
487 State <= vlbit_vector(StateTi);
488 IF Debug THEN
489 putline("DEBUG: State=RESET");
490 END IF;
491 WAIT UNTIL pfalling(RESET); -- De-assert the drivers
492 IF Debug THEN
493 putline("DEBUG: 80386 was successfully Reset.");
494 END IF;
495 EAX <= X"ZZZZZZZZ";
496 rEFLAGS <= X"ZZZZZZZZ";
497 rEIP <= X"ZZZZZZZZ";
498 rIDTbase <= X"ZZZZZZZZ";
499 rIDTlimit <= X"ZZZZ";
500 State <= X"ZZZZZZZZ";
501 RequestPending <= 'Z';
502 WAIT UNTIL prising(RESET);
503 end PROCESS Initialize;
504
505 TstateMachine: PROCESS
506 VARIABLE nState: vlbit_1d(31 downto 0) := X"00000000";
507 BEGIN
508 WAIT UNTIL pfalling(CLK);
509 CASE integer(State) is
510 WHEN StateTi =>
511 IF Debug THEN
512 put("DEBUG: 80386 is in State Ti");
513 END IF;
514 IF RESET = '0' and RequestPending = Pending THEN
515 nState := vlbit_vector(StateT1);
516 IF Debug THEN
517 putline(", Moving to StateT1");
518 END IF;
519 ELSIF RESET = '0' and HOLD = '1' THEN
520 nState := vlbit_vector(StateTh);
521 IF Debug THEN
522 putline(", Moving to StateTh");
523 END IF;
524 ELSE
525 nState := vlbit_vector(StateTi);
526 IF Debug THEN
527 IF RESET = '1' THEN
528 putline(", Due to RESET = Asserted");
529 ELSE
530 putline(", Due to NO Requests Pending");
531 END IF;
532 END IF;
533 END IF;
534
535 WHEN StateT1 =>
536 IF Debug THEN
537 putline("DEBUG: 80386 is in State T1, Moving to StateT2");
538 END IF;
539 nState := vlbit_vector(StateT2);
540
541 WHEN StateT2 =>
542 IF Debug THEN
543 putline("DEBUG: 80386 is in State T2");
544 END IF;
545 IF READY_n = '0' and HOLD ='0' and RequestPending = Pending THEN
546 nState := vlbit_vector(StateT1);
547 ELSIF READY_N = '1' and NA_n = '1' THEN
548 NULL;
549 ELSIF (RequestPending = Pending or HOLD = '1') and (READY_N = '1' and NA_n = '0') THEN
550 nState := vlbit_vector(StateT2I);
551 ELSIF RequestPending = Pending and HOLD = '0' and READY_N = '1' and NA_n = '0' THEN
552 nState := vlbit_vector(StateT2P);
553 ELSIF RequestPending = NotPending and HOLD = '0' and READY_N = '0' THEN
554 nState := vlbit_vector(StateTi);
555 ELSIF HOLD = '1' and READY_N = '1' THEN
556 nState := vlbit_vector(StateTh);
557 END IF;
558
559 WHEN StateT1P =>
560 IF Debug THEN
561 putline("DEBUG: 80386 is in State T1P");
562 END IF;
563 IF NA_n = '0' and HOLD = '0' and RequestPending = Pending THEN
564 nState := vlbit_vector(StateT2P);
565 ELSIF NA_n = '0' and (HOLD = '1' or RequestPending = NotPending) THEN
566 nState := vlbit_vector(StateT2I);
567 ELSIF NA_n = '1' THEN
568 nState := vlbit_vector(StateT2);
569 END IF;
570
571 WHEN StateTh =>
572 IF Debug THEN
573 putline("DEBUG: 80386 is in State Th");
574 END IF;
575 IF HOLD = '1' THEN
576 NULL;
577 ELSIF HOLD = '0' and RequestPending = Pending THEN
578 nState := vlbit_vector(StateT1);
579 ELSIF HOLD = '0' and RequestPending = NotPending THEN
580 nState := vlbit_vector(StateTi);
581 END IF;
582
583 WHEN StateT2P =>
584 IF Debug THEN
585 putline("DEBUG: 80386 is in State T2P");
586 END IF;
587 IF READY_n = '0' THEN
588 nState := vlbit_vector(StateT1P);
589 END IF;
590
591 WHEN StateT2I =>
592 IF Debug THEN
593 putline("DEBUG: 80386 is in State T2I");
594 END IF;
595 IF READY_n = '1' and (RequestPending = NotPending or HOLD = '1') THEN
596 NULL;
597 ELSIF READY_n = '1' and RequestPending = Pending and HOLD = '0' THEN
598 nState := vlbit_vector(StateT2P);
599 ELSIF READY_n = '0' and HOLD = '1' THEN
600 nState := vlbit_vector(StateTh);
601 ELSIF READY_n = '0' and HOLD = '0' and RequestPending = Pending THEN
602 nState := vlbit_vector(StateT1);
603 ELSIF READY_n = '0' and HOLD = '0' and RequestPending = NotPending THEN
604 nState := vlbit_vector(StateTi);
605 END IF;
606
607 WHEN OTHERS => putline("MODEL ERROR: Invalid State=",State);
608 END CASE;
609 State <= nState; -- This is where the next State is actually assigned.
610 end PROCESS TstateMachine;
611 -- Internal Control Logic Processes End
612
613 -- Instruction Pre-Fetch, Decode and Execution Unit Begin
614 InstDecode: PROCESS
615 VARIABLE InstQueue: vlbit_2d(1 to 16,7 downto 0);
616 VARIABLE InstQueueRd_Addr: INTEGER := 1; -- Address used by the decode unit to read the queue.
617 VARIABLE InstQueueWr_Addr: INTEGER := 1; -- Address used by the Pre-fetch unit to fill the queue.
618 VARIABLE InstQueueLimit: INTEGER := 16; -- Maximum length of the Queue.
619 VARIABLE InstAddrPointer: INTEGER := 0; -- Allways points to the current instruction's Address.
620 VARIABLE PhyAddrPointer: INTEGER := 0; -- Allways points to the Systems Physical Address.
621 VARIABLE Extended: BOOLEAN := FALSE; -- True if an extended op-code prefix was detected.
622 VARIABLE More: BOOLEAN := FALSE; -- True if instruction was decoded correctly and
623 -- another read is needed for data.
624 VARIABLE Flush: BOOLEAN := FALSE; -- True if JMP was executed, flush the Queue.
625 VARIABLE First: BOOLEAN := TRUE; -- First time thru.
626 VARIABLE Byte: vlbit_1d(7 downto 0);
627 VARIABLE lWord: vlbit_1d(15 downto 0);
628 VARIABLE uWord: vlbit_1d(15 downto 0);
629 VARIABLE fWord: vlbit_1d(31 downto 0);
630 VARIABLE Dummy: INTEGER;
631
632 BEGIN
633 IF First THEN
634 PhyAddrPointer := integer(rEIP);
635 InstAddrPointer := PhyAddrPointer;
636 First := FALSE;
637 END IF;
638 RequestPending <= Pending;
639 ReadRequest <= Pending;
640 MemoryFetch <= Pending;
641 CodeFetch <= Pending;
642 IF Debug THEN
643 put("DEBUG: Fetching 1st Word @ Addr=");Dummy := tohex(PhyAddrPointer,4);putline("");
644 END IF;
645 WAIT UNTIL pfalling(READY_n);
646 RequestPending <= NotPending;
647 WAIT UNTIL pfalling(CLK);
648 InstQueue(InstQueueWr_Addr) := Data(7 downto 0);
649 InstQueueWr_Addr := InstQueueWr_Addr + 1;
650 InstQueue(InstQueueWr_Addr) := Data(15 downto 8);
651 InstQueueWr_Addr := InstQueueWr_Addr + 1;
652 IF StateBS16 = '1' THEN -- A dWord code fetch
653 InstQueue(InstQueueWr_Addr) := Data(23 downto 16);
654 InstQueueWr_Addr := InstQueueWr_Addr + 1;
655 InstQueue(InstQueueWr_Addr) := Data(31 downto 24);
656 InstQueueWr_Addr := InstQueueWr_Addr + 1;
657 PhyAddrPointer := PhyAddrPointer + 4; -- Point to next dWord since BS16- = 1
658 ELSE
659 PhyAddrPointer := PhyAddrPointer + 2; -- Point to next word since BS16- = 0
660 IF Debug THEN
661 put("DEBUG: Fetching 2nd Word @ Addr=");Dummy := tohex(PhyAddrPointer,4);putline("");
662 END IF;
663 rEIP <= vlbit_vector(PhyAddrPointer);
664 WAIT UNTIL prising(CLK);
665 RequestPending <= Pending;
666 WAIT UNTIL pfalling(READY_n);
667 RequestPending <= NotPending;
668 WAIT UNTIL pfalling(CLK);
669 InstQueue(InstQueueWr_Addr) := Data(7 downto 0);
670 InstQueueWr_Addr := InstQueueWr_Addr + 1;
671 InstQueue(InstQueueWr_Addr) := Data(15 downto 8);
672 InstQueueWr_Addr := InstQueueWr_Addr + 1;
673 PhyAddrPointer := PhyAddrPointer + 2; -- Point to next word since BS16- = 0
674 END IF;
675 Decode: WHILE InstQueueRd_Addr < InstQueueWr_Addr LOOP
676 IF DEBUG THEN
677 putline("DEBUG: InstQueueRd_Addr=",InstQueueRd_Addr);
678 putline("DEBUG: InstQueueWr_Addr=",InstQueueWr_Addr);
679 putline("DEBUG: InstQueueLimit=",InstQueueLimit);
680 put("DEBUG: InstAddrPointer=");Dummy := tohex(InstAddrPointer,4);putline("");
681 put("DEBUG: PhyAddrPointer=");Dummy := tohex(PhyAddrPointer,4);putline("");
682 putline("DEBUG: Extended=",Extended);
683 putline("DEBUG: Flush=",Flush);
684 putline("DEBUG: More=",More);
685 put("DEBUG: InstQueue( 1)=");Dummy := tohex(integer(InstQueue(1)),1);putline("");
686 put("DEBUG: InstQueue( 2)=");Dummy := tohex(integer(InstQueue(2)),1);putline("");
687 put("DEBUG: InstQueue( 3)=");Dummy := tohex(integer(InstQueue(3)),1);putline("");
688 put("DEBUG: InstQueue( 4)=");Dummy := tohex(integer(InstQueue(4)),1);putline("");
689 put("DEBUG: InstQueue( 5)=");Dummy := tohex(integer(InstQueue(5)),1);putline("");
690 put("DEBUG: InstQueue( 6)=");Dummy := tohex(integer(InstQueue(6)),1);putline("");
691 put("DEBUG: InstQueue( 7)=");Dummy := tohex(integer(InstQueue(7)),1);putline("");
692 put("DEBUG: InstQueue( 8)=");Dummy := tohex(integer(InstQueue(8)),1);putline("");
693 put("DEBUG: InstQueue( 9)=");Dummy := tohex(integer(InstQueue(9)),1);putline("");
694 put("DEBUG: InstQueue(10)=");Dummy := tohex(integer(InstQueue(10)),1);putline("");
695 put("DEBUG: InstQueue(11)=");Dummy := tohex(integer(InstQueue(11)),1);putline("");
696 put("DEBUG: InstQueue(12)=");Dummy := tohex(integer(InstQueue(12)),1);putline("");
697 put("DEBUG: InstQueue(13)=");Dummy := tohex(integer(InstQueue(13)),1);putline("");
698 put("DEBUG: InstQueue(14)=");Dummy := tohex(integer(InstQueue(14)),1);putline("");
699 put("DEBUG: InstQueue(15)=");Dummy := tohex(integer(InstQueue(15)),1);putline("");
700 put("DEBUG: InstQueue(16)=");Dummy := tohex(integer(InstQueue(16)),1);putline("");
701 END IF;
702 CASE integer(InstQueue(InstQueueRd_Addr)) is
703 WHEN NOP =>
704 InstAddrPointer := InstAddrPointer + 1;
705 InstQueueRd_Addr := InstQueueRd_Addr + 1;
706 Flush := FALSE;
707 More := FALSE;
708 IF Debug OR Inst THEN
709 putline("DEBUG: Executing NOP");
710 END IF;
711 WHEN OPsop =>
712 InstAddrPointer := InstAddrPointer + 1;
713 InstQueueRd_Addr := InstQueueRd_Addr + 1;
714 Extended := TRUE;
715 Flush := FALSE;
716 More := FALSE;
717 IF Debug OR Inst THEN
718 put("DEBUG: Extended Op-Code Read:");Dummy := tohex(OPsop,1);putline("");
719 END IF;
720 WHEN JMP_rel_short =>
721 IF (InstQueueWr_Addr - InstQueueRd_Addr) >= 3 THEN
722 IF Debug OR Inst THEN
723 put("DEBUG: Executing JMP-Rel-Short from:");Dummy := tohex(InstAddrPointer,4);
724 END IF;
725 IF InstQueue(InstQueueRd_Addr+1,7) = '1' THEN -- Negative Offset
726 PhyAddrPointer := InstAddrPointer + 1 - (16#FF# - integer(extendum(InstQueue(InstQueueRd_Addr+1),32)));
727 InstAddrPointer := PhyAddrPointer;
728 IF Debug OR Inst THEN
729 put(" (-)To:");Dummy := tohex(PhyAddrPointer,4);putline("");
730 END IF;
731 ELSE -- Positive Offset
732 PhyAddrPointer := InstAddrPointer + 2 + integer(extendum(InstQueue(InstQueueRd_Addr+1),32));
733 InstAddrPointer := PhyAddrPointer;
734 IF Debug OR Inst THEN
735 put(" (+)To:");Dummy := tohex(PhyAddrPointer,4);putline("");
736 END IF;
737 END IF;
738 Flush := TRUE;
739 More := FALSE;
740 ELSE
741 Flush := FALSE;
742 More := TRUE;
743 END IF;
744 WHEN JMP_rel_near =>
745 IF (InstQueueWr_Addr - InstQueueRd_Addr) >= 5 THEN
746 IF Debug OR Inst THEN
747 put("DEBUG: Executing JMP-Rel-Near from:");Dummy := tohex(InstAddrPointer,4);
748 END IF;
749 PhyAddrPointer := InstAddrPointer + 5 + integer(extendum(InstQueue(InstQueueRd_Addr+1),32));
750 InstAddrPointer := PhyAddrPointer;
751 IF Debug OR Inst THEN
752 put(" To:");Dummy := tohex(PhyAddrPointer,4);putline("");
753 END IF;
754 Flush := TRUE;
755 More := FALSE;
756 ELSE
757 Flush := FALSE;
758 More := TRUE;
759 END IF;
760 WHEN JMP_intseg_immed =>
761-- To be Implemented (mad/8-23-1988)
762 IF Debug OR Inst THEN
763 putline("DEBUG: {TBD} Executing JMP-IntSeg-Immed from:",InstAddrPointer);
764 END IF;
765 InstAddrPointer := InstAddrPointer + 1;
766 InstQueueRd_Addr := InstQueueRd_Addr + 1;
767 Flush := FALSE;
768 More := FALSE;
769 WHEN MOV_al_b =>
770-- To be Implemented (mad/8-23-1988)
771 IF Debug OR Inst THEN
772 putline("DEBUG: {TBD} Executing MOV-al<-byte");
773 END IF;
774 InstAddrPointer := InstAddrPointer + 1;
775 InstQueueRd_Addr := InstQueueRd_Addr + 1;
776 Flush := FALSE;
777 More := FALSE;
778 WHEN MOV_eax_dw =>
779 IF (InstQueueWr_Addr - InstQueueRd_Addr) >= 5 THEN
780 IF Debug OR Inst THEN
781 put("DEBUG: Executing MOV-eax<-dw");
782 END IF;
783 -- Note Word position is swaped
784 EAX <= InstQueue(InstQueueRd_Addr+4) & InstQueue(InstQueueRd_Addr+3)
785 & InstQueue(InstQueueRd_Addr+2) & InstQueue(InstQueueRd_Addr+1);
786 WAIT FOR 1;
787 IF Debug OR Inst THEN
788 put(" of:");Dummy := tohex(integer(EAX),4);putline("");
789 END IF;
790 More := FALSE;
791 Flush := FALSE;
792 InstAddrPointer := InstAddrPointer + 5;
793 InstQueueRd_Addr := InstQueueRd_Addr + 5;
794 ELSE
795 Flush := FALSE;
796 More := TRUE;
797 IF Debug THEN
798 putline("DEBUG: Executing MOV-eax<-dw but ...");
799 putline("DEBUG: all of the immediate data is not in queue.");
800 END IF;
801 END IF;
802 WHEN MOV_ebx_dw =>
803 IF (InstQueueWr_Addr - InstQueueRd_Addr) >= 5 THEN
804 IF Debug OR Inst THEN
805 put("DEBUG: Executing MOV-ebx<-dw");
806 END IF;
807 -- Note Word position is swaped
808 EBX <= InstQueue(InstQueueRd_Addr+4) & InstQueue(InstQueueRd_Addr+3)
809 & InstQueue(InstQueueRd_Addr+2) & InstQueue(InstQueueRd_Addr+1);
810 WAIT FOR 1;
811 IF Debug OR Inst THEN
812 put(" of:");Dummy := tohex(integer(EBX),4);putline("");
813 END IF;
814 More := FALSE;
815 Flush := FALSE;
816 InstAddrPointer := InstAddrPointer + 5;
817 InstQueueRd_Addr := InstQueueRd_Addr + 5;
818 ELSE
819 Flush := FALSE;
820 More := TRUE;
821 IF Debug THEN
822 putline("DEBUG: Executing MOV-ebx<-dw but ...");
823 putline("DEBUG: all of the immediate data is not in queue.");
824 END IF;
825 END IF;
826 WHEN MOV_eax_ebx => -- Read at [ebx] to eax register
827 IF (InstQueueWr_Addr - InstQueueRd_Addr) >= 2 THEN
828 IF Debug OR Inst THEN
829 put("DEBUG: Executing MOV-eax,[ebx]");
830 END IF;
831 IF Debug OR Inst THEN
832 put(" at address:");Dummy := tohex(integer(EBX),4);putline("");
833 END IF;
834 rEIP <= EBX;
835 RequestPending <= Pending;
836 ReadRequest <= Pending;
837 MemoryFetch <= Pending;
838 CodeFetch <= NotPending;
839 WAIT UNTIL pfalling(READY_n);
840 RequestPending <= NotPending;
841 WAIT UNTIL pfalling(CLK);
842 uWord := Data(15 downto 0);
843 IF StateBS16 = '1' THEN
844 lWord := Data(31 downto 16);
845 ELSE
846 rEIP <= vlbit_vector(integer(rEIP) + 2);
847 WAIT FOR 1;
848 IF Debug THEN
849 put("DEBUG: Reading Second Word at Addr=");Dummy := tohex(integer(rEIP),4);putline("");
850 END IF;
851 WAIT UNTIL prising(CLK);
852 RequestPending <= Pending;
853 WAIT UNTIL pfalling(READY_n);
854 RequestPending <= NotPending;
855 WAIT UNTIL pfalling(CLK);
856 lWord := Data(15 downto 0);
857 END IF;
858 EAX <= uWord & lWord;
859 WAIT FOR 1;
860 IF Debug OR Inst THEN
861 put("DEBUG: Data=");Dummy := tohex(integer(EAX),4);putline("");
862 END IF;
863 More := FALSE;
864 Flush := FALSE;
865 InstAddrPointer := InstAddrPointer + 2;
866 InstQueueRd_Addr := InstQueueRd_Addr + 2;
867 ELSE
868 Flush := FALSE;
869 More := TRUE;
870 END IF;
871 WHEN MOV_ebx_eax => -- Write at [ebx] from eax register
872 IF (InstQueueWr_Addr - InstQueueRd_Addr) >= 2 THEN
873 IF Debug OR Inst THEN
874 put("DEBUG: Executing MOV-[ebx],eax");
875 END IF;
876 IF Debug OR Inst THEN
877 put(" at address:");Dummy := tohex(integer(EBX),4);putline("");
878 END IF;
879 rEIP <= EBX;
880 lWord := EAX(15 downto 0);
881 uWord := EAX(31 downto 16);
882 IF Debug OR Inst THEN
883 put("DEBUG: Data=");Dummy := tohex(integer(EAX),4);putline("");
884 END IF;
885 RequestPending <= Pending;
886 ReadRequest <= NotPending;
887 MemoryFetch <= Pending;
888 CodeFetch <= NotPending;
889 IF Debug THEN
890 put("DEBUG: Writing First Word at Addr=");Dummy := tohex(integer(EBX),4);putline("");
891 END IF;
892 WAIT UNTIL (integer(State) = StateT1 OR integer(State) = StateT1P);
893 WAIT UNTIL prising(CLK);
894 Data <= (uWord & lWord) after 480;
895 WAIT UNTIL pfalling(READY_n);
896 RequestPending <= NotPending;
897 WAIT UNTIL prising(CLK);
898 Data <= X"ZZZZZZZZ" after 480;
899 WAIT FOR 1;
900 IF StateBS16 = '0' THEN
901 IF Debug THEN
902 put("DEBUG: Writing Second Word at Addr=");Dummy := tohex(integer(EBX),4);putline("");
903 END IF;
904 rEIP <= vlbit_vector(integer(rEIP) + 2);
905 RequestPending <= Pending;
906 ReadRequest <= NotPending;
907 MemoryFetch <= Pending;
908 CodeFetch <= NotPending;
909 WAIT UNTIL (integer(State) = StateT1 OR integer(State) = StateT1P);
910 WAIT UNTIL prising(CLK);
911 Data <= (uWord & lWord) after 480;
912 WAIT UNTIL pfalling(READY_n);
913 RequestPending <= NotPending;
914 WAIT UNTIL prising(CLK);
915 Data <= X"ZZZZZZZZ" after 480;
916 WAIT FOR 1;
917 END IF;
918 More := FALSE;
919 Flush := FALSE;
920 InstAddrPointer := InstAddrPointer + 2;
921 InstQueueRd_Addr := InstQueueRd_Addr + 2;
922 ELSE
923 Flush := FALSE;
924 More := TRUE;
925 END IF;
926 WHEN IN_al =>
927 IF (InstQueueWr_Addr - InstQueueRd_Addr) >= 2 THEN
928 IF Debug OR Inst THEN
929 put("DEBUG: Executing IN-al");
930 END IF;
931 rEIP <= extendum(InstQueue(InstQueueRd_Addr+1),32);
932 WAIT FOR 1;
933 IF Debug OR Inst THEN
934 put(" from:");Dummy := tohex(integer(rEIP),4);
935 END IF;
936 RequestPending <= Pending;
937 ReadRequest <= Pending;
938 MemoryFetch <= NotPending;
939 CodeFetch <= NotPending;
940 WAIT UNTIL pfalling(READY_n);
941 RequestPending <= NotPending;
942 WAIT UNTIL pfalling(CLK);
943 EAX(7 downto 0) <= Data(7 downto 0);
944 WAIT FOR 1;
945 IF Debug OR Inst THEN
946 put(" Data=");Dummy := tohex(integer(EAX(7 downto 0)),1);putline("");
947 END IF;
948 InstAddrPointer := InstAddrPointer + 2;
949 InstQueueRd_Addr := InstQueueRd_Addr + 2;
950 Flush := FALSE;
951 More := FALSE;
952 ELSE
953 Flush := FALSE;
954 More := TRUE;
955 IF Debug THEN
956 putline("DEBUG: Executing IN-al but ...");
957 putline("DEBUG: the immediate Address is not in queue.");
958 END IF;
959 END IF;
960 WHEN OUT_al =>
961 IF (InstQueueWr_Addr - InstQueueRd_Addr) >= 2 THEN
962 IF Debug OR Inst THEN
963 put("DEBUG: Executing OUT-al");
964 END IF;
965 rEIP <= extendum(InstQueue(InstQueueRd_Addr+1),32);
966 WAIT FOR 1;
967 IF Debug OR Inst THEN
968 put(" to:");Dummy := tohex(integer(rEIP),4);
969 END IF;
970 RequestPending <= Pending;
971 ReadRequest <= NotPending;
972 MemoryFetch <= NotPending;
973 CodeFetch <= NotPending;
974 IF Debug OR Inst THEN
975 put(" Data=");Dummy := tohex(integer(EAX(7 downto 0)),1);putline("");
976 END IF;
977 WAIT UNTIL (integer(State) = StateT1 OR integer(State) = StateT1P);
978 WAIT UNTIL prising(CLK);
979 fWord := X"ZZZZZZ" & EAX(7 downto 0);
980 Data <= fWord after 480;
981 WAIT UNTIL pfalling(READY_n);
982 RequestPending <= NotPending;
983 WAIT UNTIL prising(CLK);
984 Data <= X"ZZZZZZZZ" after 480;
985 WAIT FOR 1;
986 InstAddrPointer := InstAddrPointer + 2;
987 InstQueueRd_Addr := InstQueueRd_Addr + 2;
988 Flush := FALSE;
989 More := FALSE;
990 ELSE
991 Flush := FALSE;
992 More := TRUE;
993 IF Debug THEN
994 putline("DEBUG: Executing OUT-al but ...");
995 putline("DEBUG: the immediate Address is not in queue.");
996 END IF;
997 END IF;
998 WHEN ADD_al_b =>
999-- To be Implemented (mad/8-23-1988)
1000 IF Debug OR Inst THEN
1001 putline("DEBUG: {TBD} Executing ADD-al to byte:");
1002 END IF;
1003 InstAddrPointer := InstAddrPointer + 1;
1004 InstQueueRd_Addr := InstQueueRd_Addr + 1;
1005 Flush := FALSE;
1006 More := FALSE;
1007 WHEN ADD_ax_w =>
1008-- To be Implemented (mad/8-23-1988)
1009 IF Debug OR Inst THEN
1010 putline("DEBUG: {TBD} Executing ADD-ax to word:");
1011 END IF;
1012 InstAddrPointer := InstAddrPointer + 1;
1013 InstQueueRd_Addr := InstQueueRd_Addr + 1;
1014 Flush := FALSE;
1015 More := FALSE;
1016 WHEN ROL_al_1 =>
1017-- To be Implemented (mad/8-23-1988)
1018 IF Debug OR Inst THEN
1019 putline("DEBUG: {TBD} Executing ROL-al left one bit");
1020 END IF;
1021 InstAddrPointer := InstAddrPointer + 2;
1022 InstQueueRd_Addr := InstQueueRd_Addr + 2;
1023 Flush := FALSE;
1024 More := FALSE;
1025 WHEN ROL_al_n =>
1026-- To be Implemented (mad/8-23-1988)
1027 IF Debug OR Inst THEN
1028 putline("DEBUG: {TBD} Executing ROL-al by:");
1029 END IF;
1030 InstAddrPointer := InstAddrPointer + 2;
1031 InstQueueRd_Addr := InstQueueRd_Addr + 2;
1032 Flush := FALSE;
1033 More := FALSE;
1034 WHEN INC_eax =>
1035 EAX <= vlbit_vector(integer(EAX) + 1);
1036 WAIT FOR 1;
1037 IF Debug OR Inst THEN
1038 put("DEBUG: Executing INC-eax by 1 to:");Dummy := tohex(integer(EAX),4);putline("");
1039 END IF;
1040 InstAddrPointer := InstAddrPointer + 1;
1041 InstQueueRd_Addr := InstQueueRd_Addr + 1;
1042 Flush := FALSE;
1043 More := FALSE;
1044 WHEN INC_ebx =>
1045 EBX <= vlbit_vector(integer(EBX) + 1);
1046 WAIT FOR 1;
1047 IF Debug OR Inst THEN
1048 put("DEBUG: Executing INC-ebx by 1 to:");Dummy := tohex(integer(EBX),4);putline("");
1049 END IF;
1050 InstAddrPointer := InstAddrPointer + 1;
1051 InstQueueRd_Addr := InstQueueRd_Addr + 1;
1052 Flush := FALSE;
1053 More := FALSE;
1054 WHEN OTHERS =>
1055 put("ERROR: Invalid Instruction=");Dummy := tohex(integer(InstQueue(InstQueueRd_Addr)),1);putline("");
1056 InstAddrPointer := InstAddrPointer + 1;
1057 InstQueueRd_Addr := InstQueueRd_Addr + 1;
1058 Flush := FALSE;
1059 More := FALSE;
1060 END CASE;
1061 EXIT WHEN ((InstQueueLimit - InstQueueRd_Addr) < 4) OR Flush OR More;
1062 END LOOP Decode;
1063 IF Flush THEN
1064 InstQueueRd_Addr := 1;
1065 InstQueueWr_Addr := 1;
1066 fWord := vlbit_vector(InstAddrPointer);
1067 IF fWord(0) = '1' THEN
1068 InstQueueRd_Addr := InstQueueRd_Addr + integer(extendum(fWord(1 downto 0),32));
1069 END IF;
1070 IF Debug THEN
1071 putline("DEBUG: Flushing Instruction Queue");
1072 END IF;
1073 END IF;
1074 IF (InstQueueLimit - InstQueueRd_Addr) < 3 THEN -- The queue is about to be bounded.
1075 -- This section implements the circular queue.
1076 IF Debug THEN
1077 putline("DEBUG: Instruction Queue Length Execeeded");
1078 putline("DEBUG: Implementing Circular Queue");
1079 END IF;
1080 InstQueueWr_Addr := 1;
1081 Circular: WHILE InstQueueRd_Addr <= InstQueueLimit LOOP
1082 InstQueue(InstQueueWr_Addr) := InstQueue(InstQueueRd_Addr);
1083 InstQueueRd_Addr := InstQueueRd_Addr + 1;
1084 InstQueueWr_Addr := InstQueueWr_Addr + 1;
1085 END LOOP Circular;
1086 InstQueueRd_Addr := 1;
1087 END IF;
1088 IF Debug THEN
1089 putline("DEBUG: Request Pending, filling Queue at:",InstQueueWr_Addr);
1090 END IF;
1091 rEIP <= vlbit_vector(PhyAddrPointer);
1092 WAIT UNTIL prising(CLK);
1093 end PROCESS InstDecode;
1094 -- Instruction Pre-Fetch, Decode and Execution Unit Begin
1095
1096 -- ByteEnables Begin
1097 GenByteEnables: PROCESS (rEIP)
1098 BEGIN
1099 CASE integer(DataWidth) is
1100 WHEN WidthByte =>
1101 CASE integer(rEIP(1 downto 0)) is -- A[1:0]
1102 WHEN 0 =>
1103 ByteEnable <= B"1110";
1104 WHEN 1 =>
1105 ByteEnable <= B"1101";
1106 WHEN 2 =>
1107 ByteEnable <= B"1011";
1108 WHEN 3 =>
1109 ByteEnable <= B"0111";
1110 WHEN OTHERS => NULL;
1111 END CASE;
1112 WHEN WidthWord =>
1113 CASE integer(rEIP(1 downto 0)) is -- A[1:0]
1114 WHEN 0 =>
1115 ByteEnable <= B"1100";
1116 NonAligned <= NotPending;
1117 WHEN 1 =>
1118 ByteEnable <= B"1001";
1119 NonAligned <= NotPending;
1120 WHEN 2 =>
1121 ByteEnable <= B"0011";
1122 NonAligned <= NotPending;
1123 WHEN 3 =>
1124 IF Debug THEN
1125 putline("DEBUG: Non-Aligned Word");
1126 END IF;
1127 ByteEnable <= B"0111";
1128 NonAligned <= Pending;
1129 WHEN OTHERS => NULL;
1130 END CASE;
1131 WHEN WidthDword =>
1132 CASE integer(rEIP(1 downto 0)) is -- A[1:0]
1133 WHEN 0 =>
1134 ByteEnable <= B"0000";
1135 NonAligned <= NotPending;
1136 WHEN 1 =>
1137 IF Debug THEN
1138 putline("DEBUG: Non-Aligned Dword");
1139 END IF;
1140 ByteEnable <= B"0001";
1141 NonAligned <= Pending;
1142 WHEN 2 =>
1143 IF Debug THEN
1144 putline("DEBUG: Non-Aligned Dword");
1145 END IF;
1146 NonAligned <= Pending;
1147 ByteEnable <= B"0011";
1148 WHEN 3 =>
1149 IF Debug THEN
1150 putline("DEBUG: Non-Aligned Dword");
1151 END IF;
1152 NonAligned <= Pending;
1153 ByteEnable <= B"0111";
1154 WHEN OTHERS => NULL;
1155 END CASE;
1156 WHEN OTHERS =>
1157 putline("MODEL ERROR: Data Path Width Fault: DataWidth");
1158 putline("MODEL ERROR: Width Selected was:",integer(DataWidth));
1159 END CASE;
1160 end PROCESS GenByteEnables;
1161 -- ByteEnables End
1162
1163 -- Bus Interface Unit Begin
1164 GenBusIntf: PROCESS (State)
1165 BEGIN
1166 CASE integer(State) is
1167 WHEN StateT1 | StateT2P =>
1168 Address <= rEIP(31 downto 2) after 40ns;
1169 IF Debug THEN
1170-- putline("DEBUG: Next Address=",rEIP);
1171 END IF;
1172 BE_n <= ByteEnable after 30ns;
1173 M_IO_n <= MemoryFetch;
1174 IF ReadRequest = Pending THEN
1175 W_R_n <= '0' after 30ns;
1176 ELSE
1177 W_R_n <= '1' after 30ns;
1178 END IF;
1179 IF CodeFetch = Pending THEN
1180 D_C_n <= '0' after 30ns;
1181 ELSE
1182 D_C_n <= '1' after 30ns;
1183 END IF;
1184 WHEN OTHERS => NULL;
1185 END CASE;
1186 CASE integer(State) is
1187 WHEN StateT1 => ADS_n <= '0' after 25ns;
1188 WHEN StateT2 => ADS_n <= '1' after 25ns;
1189 WHEN StateT1P => ADS_n <= '1' after 25ns;
1190 WHEN StateT2P => ADS_n <= '0' after 25ns;
1191 WHEN OTHERS => NULL;
1192 END CASE;
1193 end PROCESS GenBusIntf;
1194
1195 BS16: PROCESS
1196 BEGIN
1197 WAIT UNTIL integer(State) = StateT2 OR integer(State) = StateT1P;
1198 WHILE integer(State) = StateT2 OR integer(State) = StateT1P LOOP
1199 WAIT UNTIL prising(CLK);
1200 StateBS16 <= BS16_n;
1201 IF BS16_n = '0' THEN
1202 DataWidth <= vlbit_vector(Widthword); -- WidthByte, WidthWord, WidthDword
1203 ELSE
1204 DataWidth <= vlbit_vector(WidthDword);
1205 END IF;
1206 END LOOP;
1207 end PROCESS BS16;
1208
1209 NA: PROCESS
1210 BEGIN
1211 WAIT UNTIL integer(State) = StateT2 OR integer(State) = StateT1P;
1212 WAIT UNTIL prising(CLK);
1213 StateNA <= NA_n;
1214 end PROCESS NA;
1215
1216 -- Bus Interface Unit End
1217-- End Behavioral Blocks
1218
1219end behavior;