William F. Richardson UUCS-95-021 Department of Computer Science University of Utah

advertisement
The Fred VHDL Model
William F. Richardson
UUCS-95-021
Department of Computer Science
University of Utah
Salt Lake City, UT 84112 USA
November 21, 1995
Abstract
This is the companion document to my dissertation. It contains 47 pages of schematics,
and 163 pages of VHDL code. It is pretty meaningless without the dissertation, and it only
exists because I felt that I should archive this information somewhere.
Contents
1 Schematic Heirarchy
5
2 VHDL Source Code
9
2.1
2.2
2.3
2.4
2.5
2.6
2.7
2.8
2.9
2.10
2.11
2.12
2.13
2.14
2.15
2.16
2.17
2.18
2.19
2.20
2.21
2.22
2.23
2.24
2.25
2.26
2.27
2.28
2.29
arbiter which.vhd
arith unit.vhd
branch unit.vhd
control unit.vhd
cpx128.vhd
cpx18.vhd
cpx32.vhd
cpx3op.vhd
cpx4op.vhd
cpx5.vhd
cpx88.vhd
cpx96.vhd
delaytap.vhd
dispatch.vhd
logic unit.vhd
memory unit.vhd
p arith.vhd
p constants.vhd
p dispatch.vhd
p memory unit.vhd
p output.vhd
qop.vhd
registers.vhd
regselect.vhd
scoreboard.vhd
vdelay.vhd
verify address.vhd
zdelay.vhd
zxor.vhd
: : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : :
: : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : :
: : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : :
: : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : :
: : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : :
: : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : :
: : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : :
: : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : :
: : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : :
: : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : :
: : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : :
: : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : :
: : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : :
: : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : :
: : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : :
: : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : :
: : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : :
: : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : :
: : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : :
: : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : :
: : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : :
: : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : :
: : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : :
: : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : :
: : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : :
: : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : :
: : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : :
: : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : :
: : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : :
1
9
12
22
30
37
40
43
46
49
52
55
58
61
63
106
114
125
127
131
142
145
147
148
154
162
165
166
170
171
2
3 Schematic Diagrams
CONTENTS
173
List of Figures
3.1
3.2
3.3
3.4
3.5
3.6
3.7
3.8
3.9
3.10
3.11
3.12
3.13
3.14
3.15
3.16
3.17
3.18
3.19
3.20
3.21
3.22
3.23
3.24
3.25
3.26
3.27
3.28
3.29
3.30
3.31
3.32
3.33
arbcall
arbcallx88
buf32
buf4
buf8
callx32
cp-delay
delaychain
distributor
ex-unit1
ex-unit2
fo-32
fo-36
fred-memory
fred-with-mem
fred1
fred2
fred3
fu-arith
fu-branch
fu-control
fu-logic
fu-memory
gate
if-unit1
if-unit2
memory-latches
mux2x30
mux2x32
mux2x4
mux2x5
mux2x8
pipe-nx128
: : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : :
: : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : :
: : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : :
: : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : :
: : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : :
: : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : :
: : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : :
: : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : :
: : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : :
: : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : :
: : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : :
: : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : :
: : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : :
: : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : :
: : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : :
: : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : :
: : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : :
: : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : :
: : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : :
: : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : :
: : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : :
: : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : :
: : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : :
: : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : :
: : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : :
: : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : :
: : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : :
: : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : :
: : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : :
: : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : :
: : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : :
: : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : :
: : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : :
3
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
LIST OF FIGURES
4
3.34
3.35
3.36
3.37
3.38
3.39
3.40
3.41
3.42
3.43
3.44
3.45
3.46
3.47
pipe-nx18
pipe-nx32
pipe-nx3op
pipe-nx4op
pipe-nx5
pipe-nx88
pipe-nx96
qop-even
qop-odd
ram-byte-order
ram16kx32
rf-unit
tlnt-32
zerox32
: : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : :
: : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : :
: : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : :
: : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : :
: : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : :
: : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : :
: : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : :
: : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : :
: : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : :
: : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : :
: : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : :
: : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : :
: : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : :
: : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : :
207
208
209
210
211
212
213
214
215
216
217
218
219
220
Chapter 1
Schematic Heirarchy
This is the schematic hierarchy. \fred-with-mem" is the top level schematic. The elements listed in parentheses are VHDL modules. Any schematics not listed in this hierarchy are standard library modules.
fred-with-mem
fred.1
if_unit.1
(dispatch)
gate
qflop_even
(qflop)
qflop_odd
(qflop)
if_unit.2
(scoreboard)
arbcall
(arbiter_which)
mux2x5
pipe_nx128
(cpx128)
delaychain
(delaytap zxor)
cp_delay
pipe_nx18
(cpx18)
delaychain
(delaytap zxor)
cp_delay
fred.2
pipe_nx5
(cpx5)
delaychain
(delaytap zxor)
cp_delay
pipe_nx96
(cpx96)
delaychain
(delaytap zxor)
cp_delay
rf_unit
(registers regselect)
fred.3
ex_unit
5
CHAPTER 1. SCHEMATIC HEIRARCHY
6
distributor
fu_arith
(arith_unit)
pipe_nx3op
(cpx3op)
delaychain
(delaytap zxor)
cp_delay
fu_control
(control_unit)
pipe_nx4op
(cpx4op)
delaychain
(delaytap zxor)
cp_delay
fu_logic
(logic_unit)
pipe_nx3op
(cpx3op)
delaychain
(delaytap zxor)
cp_delay
mux2x32
zerox32
buf8
ex_unit.2
arbcallx88
(arbiter_which vdelay)
mux2x32
mux2x8
callx32
(vdelay)
mux2x32
fu_branch
(branch_unit)
pipe_nx4op
(cpx4op)
delaychain
(delaytap zxor)
cp_delay
fu_memory
(memory_unit)
pipe_nx4op
(cpx4op)
delaychain
(delaytap zxor)
cp_delay
pipe_nx32
(cpx32)
delaychain
(delaytap zxor)
cp_delay
pipe_nx88
(cpx88)
delaychain
(delaytap zxor)
cp_delay
fred-memory
(arbiter_which verify_address zdelay)
7
memory_latches
(vdelay)
buf32
buf4
fifo-32
tlnt-32
fifo-36
tlnt-32
mux2x30
mux2x4
ram16kx32
(ram16kx8 vdelay)
ram_byte_order
8
CHAPTER 1. SCHEMATIC HEIRARCHY
Chapter 2
VHDL Source Code
2.1 arbiter which.vhd
-------------
This models an arbiter with an extra level output to indicate which choice
it made. It uses a state machine with 5 states. There is no provision
for stopping or resetting it, and it assumes that the inputs are
well-behaved.
---- The "w" output changes instantly, as soon as it can. The grant signal is
---- subject to a delay (default .1ns), changeable with a DELAY attribute.
ENTITY arbiter_which IS
GENERIC( delay: TIME := 100 PS)
PORT (SIGNAL clr
:IN
VLBIT
SIGNAL r0
:IN
VLBIT
SIGNAL r1
:IN
VLBIT
SIGNAL d0
:IN
VLBIT
SIGNAL d1
:IN
VLBIT
SIGNAL g0
:OUT
VLBIT := '0'
SIGNAL g1
:OUT
VLBIT := '0'
SIGNAL w
:OUT
VLBIT := '0')
END arbiter_which
ARCHITECTURE state_behavior OF arbiter_which IS
TYPE states IS (wait_any,wait_d0,wait_d1,wait_d0_d1,wait_d1_d0)
BEGIN
main : PROCESS ( r0, r1, d0, d1 )
VARIABLE state
: states := wait_any
BEGIN
IF (clr
g0 <=
g1 <=
w <=
state
/= '1') THEN
'0'
'0'
'0'
:= wait_any
ELSE
CASE state IS
9
CHAPTER 2. VHDL SOURCE CODE
10
WHEN wait_any =>
IF (r0'EVENT AND r1'EVENT) THEN
w <= '0'
g0 <= r0 AFTER delay
state := wait_d0_d1
ELSIF (r0'EVENT) THEN
w <= '0'
g0 <= r0 AFTER delay
state := wait_d0
ELSIF (r1'EVENT) THEN
w <= '1'
g1 <= r1 AFTER delay
state := wait_d1
ELSE
putline("*** Illegal Input to Arbiter
END IF
WHEN wait_d0 =>
IF (d0'EVENT AND r1'EVENT) THEN
w <= '1'
g1 <= r1 AFTER delay
state := wait_d1
ELSIF (d0'EVENT) THEN
state := wait_any
ELSIF (r1'EVENT) THEN
state := wait_d0_d1
ELSE
putline("*** Illegal Input to Arbiter
END IF
WHEN wait_d1 =>
IF (d1'EVENT AND r0'EVENT) THEN
w <= '0'
g0 <= r0 AFTER delay
state := wait_d0
ELSIF (d1'EVENT) THEN
state := wait_any
ELSIF (r0'EVENT) THEN
state := wait_d1_d0
ELSE
putline("*** Illegal Input to Arbiter
END IF
-- waiting for any request
-- got both
-- do r0 first
-- else got r0 only
-- or got r1 only
-- no other choice
in state WAIT_ANY ***")
-- waiting for d0 or r1
-- got both
-- assume d0 first
-- got d0, go back to start
-- else got r1
in state WAIT_D0 ***")
-- waiting for d1 or r0
-- got both
-- assume d1 first
-- got d1, go back to start
-- else got r0
in state WAIT_D1 ***")
WHEN wait_d0_d1 =>
-- waiting for d0, r1 in queue
IF (d0'EVENT) THEN
w <= '1'
-- d0 is only acceptible event
g1 <= r1 AFTER delay
state := wait_d1
ELSE
putline("*** Illegal Input to Arbiter in state WAIT_D0_D1 ***")
END IF
WHEN wait_d1_d0 =>
-- waiting for d1, r0 in queue
2.1. ARBITER WHICH.VHD
11
IF (d1'EVENT) THEN
w <= '0'
-- d0 is only acceptible event
g0 <= r0 AFTER delay
state := wait_d0
ELSE
putline("*** Illegal Input to Arbiter in state WAIT_D1_D0 ***")
END IF
END CASE
END IF
END PROCESS main
END state_behavior
--
state
CHAPTER 2. VHDL SOURCE CODE
12
2.2 arith unit.vhd
USE work.p_constants.ALL
USE work.p_arith.ALL
USE work.p_output.ALL
---- This unit handles the arithmetic instructions. Currently, there is only
---- one of these units. More could be used, but a separate carry bit is
---- maintained internally to each unit.
----------------------
The EXTRA input was added to provide last-result-reuse and to eliminate
zero values of op_a for immediate instructions. The bit usage is:
EXTRA(0)
EXTRA(1)
EXTRA(2)
EXTRA(3)
=
=
=
=
reuseA
reuseB
reuseD
zeroA (unused)
ENTITY arith_unit IS
GENERIC( delay: TIME := 100 ps )
PORT( SIGNAL clr
: IN
SIGNAL rin
: IN
SIGNAL ain
: OUT
SIGNAL tellme
: IN
SIGNAL tag
: IN
SIGNAL dest
: IN
SIGNAL opcode
: IN
SIGNAL op_a
: IN
SIGNAL op_b
: IN
SIGNAL d_req
: OUT
SIGNAL d_ack
: IN
SIGNAL done
: OUT
SIGNAL rout
: OUT
SIGNAL aout
: IN
SIGNAL res
: OUT
SIGNAL rq_req
: OUT
SIGNAL rq_ack
: IN
SIGNAL rq
: OUT
SIGNAL extra
: IN
END arith_unit
VLBIT
VLBIT
VLBIT
VLBIT
VLBIT_1D
VLBIT_1D
VLBIT_1D
VLBIT_1D
VLBIT_1D
VLBIT
VLBIT
VLBIT_1D
VLBIT
VLBIT
VLBIT_1D
VLBIT
VLBIT
VLBIT_1D
VLBIT_1D
(7 DOWNTO 0)
(4 DOWNTO 0)
(31 DOWNTO 0)
(31 DOWNTO 0)
(31 DOWNTO 0)
(87 DOWNTO 0)
(36 DOWNTO 0)
(31 DOWNTO 0)
(3 DOWNTO 0) )
ARCHITECTURE behavior OF arith_unit IS
BEGIN
main : PROCESS
VARIABLE debug
: BOOLEAN := FALSE -- display everything
--- factors affecting response time
VARIABLE
VARIABLE
VARIABLE
VARIABLE
delay_add
delay_sub
delay_cmp
delay_div
:
:
:
:
TIME
TIME
TIME
TIME
:=
:=
:=
:=
100
100
100
100
ps
ps
ps
ps
2.2. ARITH UNIT.VHD
13
VARIABLE delay_mul
: TIME := 100 ps
VARIABLE delay_to_use
: TIME
-- scratch for culumative time
--- constants
CONSTANT MINOR_add
CONSTANT MINOR_sub
CONSTANT MINOR_div
: INTEGER := 1
: INTEGER := 2
: INTEGER := 3
--- output variables
VARIABLE v_rout
VARIABLE v_rq_req
VARIABLE v_d_req
: VLBIT
: VLBIT
: VLBIT
--- internal variables
VARIABLE index
VARIABLE status
VARIABLE minor
: INTEGER
: INTEGER
: INTEGER
VARIABLE
VARIABLE
VARIABLE
VARIABLE
VARIABLE
:
:
:
:
:
Av
Bv
result
lastresult
bigresult
VLBIT_1D
VLBIT_1D
VLBIT_1D
VLBIT_1D
VLBIT_1D
VARIABLE Ai
VARIABLE Bi
VARIABLE Ri
: INTEGER
: INTEGER
: INTEGER
VARIABLE carry
: VLBIT
(31
(31
(31
(31
(33
DOWNTO
DOWNTO
DOWNTO
DOWNTO
DOWNTO
0)
0)
0)
0)
0)
--- scratch variables
VARIABLE use_carry_in
VARIABLE use_carry_out
: BOOLEAN
: BOOLEAN
VARIABLE
VARIABLE
VARIABLE
VARIABLE
:
:
:
:
tmpi
tmpv
arg1
arg2
INTEGER
VLBIT_1D (31 DOWNTO 0)
VLBIT_1D (31 DOWNTO 0)
VLBIT_1D (31 DOWNTO 0)
--- statistics
VARIABLE s_arith_rin
VARIABLE s_mul
VARIABLE s_div
: INTEGER
: INTEGER
: INTEGER
CHAPTER 2. VHDL SOURCE CODE
14
BEGIN
--- If clear is asserted, reset everything and stick here.
IF clr /= '1' THEN
-- reset to beginning
v_rout := '0'
v_rq_req := '0'
v_d_req := '0'
carry := '0'
arg1 := ZERO(31 DOWNTO 0)
arg2 := ZERO(31 DOWNTO 0)
ain <= '0'
d_req <= v_d_req
done <= ZERO(87 DOWNTO 0)
rout <= v_rout
res <= ZERO(36 DOWNTO 0)
rq_req <= v_rq_req
rq <= ZERO(31 DOWNTO 0)
s_arith_rin := 0
s_mul := 0
s_div := 0
WAIT UNTIL clr = '1'
ELSE
-- only wakeup event is RIN
status := STATUS_done
minor := 0
---------
-- assume it will work
This stuff had to be encoded by hand. I could have written a Perl
script to do it, but it would have taken longer than doing it
manually. This stuff shouldn't change that much (I hope). I also made
some assumptions about unused bits, which is probably okay.
delay_to_use := delay
-- default is one gate
--- I don't bother to compute anything if I'm just going to throw the
--- result away.
IF dest /= REG_R0 THEN -- only if worth doing
s_arith_rin := s_arith_rin + 1
index := op2index( opcode )
-- identify instruction
2.2. ARITH UNIT.VHD
15
--- determine operand sources
IF extra(0)='1' THEN
Av := lastresult
ELSE
Av := op_a
END IF
IF index <= 31 THEN
-- immediate
--- All Immediate operands are zero-extended (this could change).
Bv := ZERO(31 DOWNTO 16) & opcode(15 DOWNTO 0)
ELSE
-- triadic
IF extra(1)='1' THEN
Bv := lastresult
ELSE
Bv := op_b
END IF
END IF
Ai := v1d2int( Av )
Bi := v1d2int( Bv )
--- determine carry usage
use_carry_in := FALSE
use_carry_out := FALSE
IF ( index = 40 OR
-index = 41 OR
-index = 46 OR
-index = 47 )
-THEN
use_carry_in := vlb2boo( opcode(9) )
use_carry_out := vlb2boo( opcode(8) )
END IF
add rd,ra,rb
addu rd,ra,rb
sub rd,ra,rb
subu rd,ra,rb
IF debug THEN
puthexline("op_a is ",Ai)
puthexline("op_b is ",Bi)
putline("use_carry_in is ",use_carry_in)
putline("use_carry_out is ",use_carry_out)
END IF
--- now, do the operation
CASE index IS
WHEN 8 | 40 =>
IF debug THEN
-- add
CHAPTER 2. VHDL SOURCE CODE
16
putline("ADD")
END IF
delay_to_use := delay_add
IF use_carry_in THEN
bigresult := add32( Av, Bv, carry )
ELSE
bigresult := add32( Av, Bv, '0' )
END IF
--- Overflow is possible, so check for it.
IF bigresult(33) = '1' THEN
status := STATUS_overflow
minor := MINOR_add
arg1 := Av
arg2 := Bv
ELSE
-- overflow exception
-- report it
-- no exception
IF use_carry_out THEN
carry := bigresult(32)
END IF
-- save carry if enabled
result := bigresult(31 DOWNTO 0)
END IF
WHEN 9 | 41
=>
-- addu
IF debug THEN
putline("ADDU")
END IF
delay_to_use := delay_add
--- Just do it.
No faults.
IF use_carry_in THEN
bigresult := add32( Av, Bv, carry )
ELSE
bigresult := add32( Av, Bv, '0' )
END IF
IF use_carry_out THEN
carry := bigresult(32)
END IF
result := bigresult(31 DOWNTO 0)
-- save carry if enabled
2.2. ARITH UNIT.VHD
WHEN 10 | 42 =>
17
-- div
s_div := s_div + 1
IF debug THEN
putline("DIV")
END IF
delay_to_use := delay_div
--- Signed divide. Overflow is possible only for NEGMAX / -1.
--- DivByZero is possible.
IF Bi = 0 THEN
-- divide by zero
status := STATUS_int_div
minor := MINOR_div
arg1 := Av
arg2 := Bv
ELSIF Bi = -1 AND Av = NEGMAX THEN
-- overflow
status := STATUS_overflow
minor := MINOR_div
arg1 := Av
arg2 := Bv
ELSE
Ri := Ai / Bi
result := int2v1d( Ri )
-- just do it
-- do it
-- save it
END IF
WHEN 11 | 43 =>
-- divu
s_div := s_div + 1
IF debug THEN
putline("DIVU")
END IF
delay_to_use := delay_div
--- Unsigned divide. DivByZero is possible, but overflow is not.
IF Bi = 0 THEN
status := STATUS_int_div
minor := MINOR_div
-- divide by zero
CHAPTER 2. VHDL SOURCE CODE
18
arg1 := Av
arg2 := Bv
ELSE
-- just do it
result := divum( Av, Bv )
-- treat as unsigned values
END IF
WHEN 12 | 44 =>
-- mul
s_mul := s_mul + 1
IF debug THEN
putline("MUL")
END IF
delay_to_use := delay_mul
--- Just do it.
No faults.
--- Shouldn't this be pipelined?
How deep?
Ri := Ai * Bi
result := int2v1d( Ri )
WHEN 13 | 45 =>
-- cmp
IF debug THEN
putline("CMP")
END IF
delay_to_use := delay_cmp
--- Do all sorts of comparisons. No faults.
result := ZERO(31 DOWNTO 0)
-- initialize
result(11) := boo2vlb( Av >= Bv )
result(10) := boo2vlb( Av < Bv )
result(9) := boo2vlb( Av <= Bv )
result(8) := boo2vlb( Av > Bv )
-----
hs
lo
ls
hi
result(7)
result(6)
result(5)
result(4)
result(3)
result(2)
-------
ge
lt
le
gt
ne
eq
:=
:=
:=
:=
:=
:=
boo2vlb(
boo2vlb(
boo2vlb(
boo2vlb(
boo2vlb(
boo2vlb(
Ai
Ai
Ai
Ai
Ai
Ai
>= Bi )
< Bi )
<= Bi )
> Bi )
/= Bi )
= Bi )
2.2. ARITH UNIT.VHD
19
WHEN 14 | 46 =>
-- sub
IF debug THEN
putline("SUB")
END IF
delay_to_use := delay_sub
IF use_carry_in THEN
bigresult := sub32( Av, Bv, carry )
ELSE
bigresult := sub32( Av, Bv, '1' )
END IF
--- Overflow is possible, so check for it.
IF bigresult(33) = '1' THEN
status := STATUS_overflow
minor := MINOR_sub
arg1 := Av
arg2 := Bv
ELSE
-- overflow exception
-- report it
-- no exception
IF use_carry_out THEN
carry := bigresult(32)
END IF
-- save carry if enabled
result := bigresult(31 DOWNTO 0)
END IF
WHEN 15 | 47 =>
-- subu
IF debug THEN
putline("SUBU")
END IF
delay_to_use := delay_sub
--- Just do it.
No faults.
IF use_carry_in THEN
bigresult := sub32( Av, Bv, carry )
ELSE
bigresult := sub32( Av, Bv, '1' )
END IF
IF use_carry_out THEN
CHAPTER 2. VHDL SOURCE CODE
20
carry := bigresult(32)
END IF
-- save carry if enabled
result := bigresult(31 DOWNTO 0)
WHEN OTHERS =>
-- anything else
putline("*** Illegal Opcode for Arith Unit ***")
END CASE
--- write output if any was produced.
IF status = STATUS_done THEN
IF debug THEN
tmpi := v1d2int(result)
puthexline("Result is ",tmpi)
END IF
IF dest = REG_R1 THEN
rq <= result
v_rq_req := NOT v_rq_req
rq_req <= v_rq_req AFTER delay_to_use
WAIT ON rq_ack
ELSE
res <= dest & result
lastresult := result
IF debug THEN
puthexline("latched ",tmpi)
END IF
v_rout := NOT v_rout
rout <= v_rout AFTER delay_to_use
-- write it out
WAIT ON aout
END IF
END IF
END IF
-- produce a result
--- signal completion of this instruction
IF tellme = '1' THEN
-- only if needed
2.2. ARITH UNIT.VHD
21
tmpi := status + 256 * minor
tmpv := int2v1d( tmpi )
done <= arg1 & arg2 & tmpv(15 DOWNTO 0) & tag
IF debug THEN
puthexline("Sending status ",tmpi)
END IF
v_d_req := NOT v_d_req
d_req <= v_d_req AFTER delay
WAIT ON d_ack
END IF
ain <= rin AFTER delay
-- done with this event
IF debug THEN
putline("Done with this instruction")
END IF
END IF
-- clr not asserted
WAIT ON clr, rin
-- wait for next event
END PROCESS main
END behavior
CHAPTER 2. VHDL SOURCE CODE
22
2.3 branch unit.vhd
USE work.p_constants.ALL
USE work.p_output.ALL
---- The branch_unit computes branch targets for the IF Unit. It may place the
---- result in either the Branch Queue or the Exception Branch Queue. If the
---- branch will be taken, it places the address on the Prefetch Queue.
-------------------------------
The EXTRA input was added to provide last-result-reuse and to elminate
zero values of op_a for immediate instructions. The bit usage is:
EXTRA(0)
EXTRA(1)
EXTRA(2)
EXTRA(3)
=
=
=
=
reuseA
reuseB
reuseD
zeroA (unused)
The branch unit doesn't need it for anything, since it doesn't generate
results for the register file.
ENTITY branch_unit IS
GENERIC( delay: TIME := 100 ps )
PORT( SIGNAL clr
: IN
SIGNAL rin
: IN
SIGNAL ain
: OUT
SIGNAL tellme
: IN
SIGNAL tag
: IN
SIGNAL dest
: IN
SIGNAL pc
: IN
SIGNAL opcode
: IN
SIGNAL op_a
: IN
SIGNAL op_b
: IN
SIGNAL cr0
: IN
SIGNAL d_req
: OUT
SIGNAL d_ack
: IN
SIGNAL done
: OUT
SIGNAL br_req
: OUT
SIGNAL br_ack
: IN
SIGNAL br
: OUT
SIGNAL xbr_req
: OUT
SIGNAL xbr_ack
: IN
SIGNAL xbr
: OUT
SIGNAL pf_req
: OUT
SIGNAL pf_ack
: IN
SIGNAL pf
: OUT
SIGNAL extra
: IN
END branch_unit
VLBIT
VLBIT
VLBIT
VLBIT
VLBIT_1D
VLBIT_1D
VLBIT_1D
VLBIT_1D
VLBIT_1D
VLBIT_1D
VLBIT_1D
VLBIT
VLBIT
VLBIT_1D
VLBIT
VLBIT
VLBIT_1D
VLBIT
VLBIT
VLBIT_1D
VLBIT
VLBIT
VLBIT_1D
VLBIT_1D
ARCHITECTURE behavior OF branch_unit IS
BEGIN
(7 DOWNTO 0)
(4 DOWNTO 0)
(31 DOWNTO 0)
(31 DOWNTO 0)
(31 DOWNTO 0)
(31 DOWNTO 0)
(31 DOWNTO 0)
(87 DOWNTO 0)
(31 DOWNTO 0)
(31 DOWNTO 0)
(31 DOWNTO 0)
(3 DOWNTO 0) )
2.3. BRANCH UNIT.VHD
23
main : PROCESS
VARIABLE debug
: BOOLEAN := FALSE -- display everything
--- factors affecting response time
VARIABLE
VARIABLE
VARIABLE
VARIABLE
delay_abs
delay_rel
delay_cond_abs
delay_cond_rel
VARIABLE delay_to_use
:
:
:
:
TIME
TIME
TIME
TIME
:=
:=
:=
:=
100
100
100
100
: TIME
ps
ps
ps
ps
-- scratch for culumative time
--- output variables
VARIABLE
VARIABLE
VARIABLE
VARIABLE
v_pf_req
v_d_req
v_br_req
v_xbr_req
:
:
:
:
VLBIT
VLBIT
VLBIT
VLBIT
:
:
:
:
:
INTEGER
INTEGER
INTEGER
VLBIT_1D( 30 DOWNTO 0)
BOOLEAN
--- internal variables
VARIABLE
VARIABLE
VARIABLE
VARIABLE
VARIABLE
index
A
B
addr
taken
--- scratch variables
VARIABLE tmpv
VARIABLE tmpi
VARIABLE tmpb
: VLBIT_1D( 31 DOWNTO 0)
: INTEGER
: VLBIT
--- statistics
VARIABLE
VARIABLE
VARIABLE
VARIABLE
s_branch_rin
s_taken
s_relative
s_indirect
:
:
:
:
INTEGER
INTEGER
INTEGER
INTEGER
BEGIN
--- If clear is asserted, reset everything and stick here.
IF clr /= '1' THEN
v_pf_req := '0'
v_d_req := '0'
-- reset to beginning
CHAPTER 2. VHDL SOURCE CODE
24
v_br_req := '0'
v_xbr_req := '0'
ain <= '0'
pf_req <= v_pf_req
pf <= ZERO(31 DOWNTO 0)
d_req <= v_d_req
tmpv := ZERO(31 DOWNTO 0)
done <= ZERO(87 DOWNTO 0)
br_req <= v_br_req
br <= ZERO(31 DOWNTO 0)
xbr_req <= v_xbr_req
xbr <= ZERO(31 DOWNTO 0)
s_branch_rin := 0
s_taken := 0
s_indirect := 0
s_relative := 0
WAIT UNTIL clr = '1'
ELSE
-- only wakeup event is RIN
s_branch_rin := s_branch_rin + 1
---------
This stuff had to be encoded by hand. I could have written a Perl
script to do it, but it would have taken longer than doing it
manually. This stuff shouldn't change that much (I hope). I also made
some assumptions about unused bits, which is probably okay.
delay_to_use := delay
IF debug THEN
tmpi := v1d2int(op_a)
puthexline("op_a is ",tmpi)
END IF
index := op2index( opcode )
IF index = 87 THEN
-- LDBR is special
IF debug THEN
tmpi := 4 * v1d2int(op_a(31 DOWNTO 2))
puthex("LDBR <= ",tmpi)
tmpb := op_a(1)
putline(" ",tmpb)
END IF
br <= op_a
v_br_req := NOT v_br_req
br_req <= v_br_req AFTER delay
-- always use Branch Queue
IF op_a(1) = '1' THEN
-- do prefetch as well
-- write it
2.3. BRANCH UNIT.VHD
pf <= op_a
v_pf_req := NOT v_pf_req
pf_req <= v_pf_req AFTER delay
25
-- write it out
-- and wait for both ACKs
WAIT UNTIL pf_ack = v_pf_req AND br_ack = v_br_req
ELSE
WAIT ON br_ack
-- no prefetch
-- just wait on BR_ACK
END IF
ELSE
-- other instructions
CASE index IS
WHEN 16 =>
-- bb0 n,ra,imm16
s_relative := s_relative + 1
delay_to_use := delay_cond_rel
--- see if it's taken
tmpi := v1d2int( opcode(25 DOWNTO 21) ) -- which bit
taken := NOT vlb2boo( op_a(tmpi) )
-- is it set?
--- compute word address
addr := add2c( pc(31 DOWNTO 2), opcode( 15 DOWNTO 0) )
WHEN 17 =>
-- bb1 n,ra,imm16
s_relative := s_relative + 1
delay_to_use := delay_cond_rel
--- see if it's taken
tmpi := v1d2int( opcode(25 DOWNTO 21) ) -- which bit
taken := vlb2boo( op_a(tmpi) )
-- is it set?
--- compute word address
addr := add2c( pc(31 DOWNTO 2), opcode( 15 DOWNTO 0) )
WHEN 18 =>
-- bxx ra,imm16
CHAPTER 2. VHDL SOURCE CODE
26
s_relative := s_relative + 1
delay_to_use := delay_cond_rel
--- see if it's taken
tmpi := v1d2int( op_a )
-- get ra
IF ( ( (opcode(21) = '1') AND (tmpi > 0 ) ) OR
( (opcode(22) = '1') AND (tmpi = 0 ) ) OR
( (opcode(23) = '1') AND (tmpi < 0 ) ) )
THEN
taken := TRUE
ELSE
taken := FALSE
END IF
--- compute word address
addr := add2c( pc(31 DOWNTO 2), opcode( 15 DOWNTO 0) )
WHEN 19 =>
-- br imm26
s_relative := s_relative + 1
delay_to_use := delay_rel
--- it's always taken
taken := TRUE
--- compute word address
addr := add2c( pc(31 DOWNTO 2), opcode( 25 DOWNTO 0) )
WHEN 48 =>
-- bb0 n,ra,rb
s_indirect := s_indirect + 1
delay_to_use := delay_cond_abs
--- see if it's taken
tmpi := v1d2int( opcode(25 DOWNTO 21) ) -- which bit
taken := NOT vlb2boo( op_a(tmpi) )
-- is it set?
--- compute word address
addr := '0' & op_b( 31 DOWNTO 2 )
WHEN 49 =>
-- bb1 n,ra,rb
2.3. BRANCH UNIT.VHD
27
s_indirect := s_indirect + 1
delay_to_use := delay_cond_abs
--- see if it's taken
tmpi := v1d2int( opcode(25 DOWNTO 21) ) -- which bit
taken := vlb2boo( op_a(tmpi) )
-- is it set?
--- compute word address
addr := '0' & op_b( 31 DOWNTO 2 )
WHEN 50 =>
-- bxx ra,rb
s_indirect := s_indirect + 1
delay_to_use := delay_cond_abs
--- see if it's taken
tmpi := v1d2int( op_a )
-- get ra
IF ( ( (opcode(21) = '1') AND (tmpi > 0 ) ) OR
( (opcode(22) = '1') AND (tmpi = 0 ) ) OR
( (opcode(23) = '1') AND (tmpi < 0 ) ) )
THEN
taken := TRUE
ELSE
taken := FALSE
END IF
--- compute word address
addr := '0' & op_b( 31 DOWNTO 2 )
WHEN 51 =>
s_indirect := s_indirect + 1
delay_to_use := delay_abs
--- it's always taken
taken := TRUE
--- compute word address
addr := '0' & op_b( 31 DOWNTO 2 )
-- br rb
CHAPTER 2. VHDL SOURCE CODE
28
WHEN OTHERS =>
-- anything else
putline("*** Illegal Opcode for Branch Unit ***")
END CASE
--- write output on correct branch queue
tmpb := boo2vlb( taken )
tmpv := (addr(29 DOWNTO 0) & tmpb & '0') -- compute branch target
IF taken THEN
-- do prefetch if needed
s_taken := s_taken + 1
pf <= tmpv
v_pf_req := NOT v_pf_req
pf_req <= v_pf_req AFTER delay_to_use -- write it
END IF
-------------------------
I had to modify the tag meaning slightly. Originally, all branch
instructions simply used the current value of cr0(Excp_Enable) to
determine which Branch queue to place the target in. However,
branch instructions do not fault, so if an interrupt is noticed
after the branch has been issued but before it has completed, the
target goes down the wrong pipe. Rather than add another bit to
the existing FIFOs, I just modified the tag value so that bit 7 is
used to indicate the queue in use when the instruction was issued.
This doesn't affect the memory unit since it always has to report
its status and the dispatch unit will wait for it to do so before
handling exceptions. Only the branch unit uses the new tag bit for
anything.
IF tag(7) = '1' THEN
-- use normal branch queue
IF debug THEN
tmpi := 4 * v1d2int(tmpv(31 DOWNTO 2))
puthex("BR <= ",tmpi)
putline(" ",tmpb)
END IF
br <= tmpv
v_br_req := NOT v_br_req
br_req <= v_br_req AFTER delay_to_use
IF taken THEN
-- must ACK both
WAIT UNTIL pf_ack = v_pf_req AND br_ack = v_br_req
ELSE
WAIT ON br_ack
-- just BR_ACK
END IF
2.3. BRANCH UNIT.VHD
ELSE
29
-- use exception branch queue
IF debug THEN
tmpi := 4 * v1d2int(tmpv(31 DOWNTO 2))
puthex("XBR <= ",tmpi)
putline(" ",tmpb)
END IF
xbr <= tmpv
v_xbr_req := NOT v_xbr_req
xbr_req <= v_xbr_req AFTER delay_to_use
IF taken THEN
-- must ACK both
WAIT UNTIL pf_ack = v_pf_req AND xbr_ack = v_xbr_req
ELSE
WAIT ON xbr_ack
-- just XBR_ACK
END IF
END IF
END IF
-- not LDBR instruction
--- signal completion of this instruction
IF tellme = '1' THEN
-- only if needed
tmpv := int2v1d( STATUS_done )
done(15 DOWNTO 0) <= tmpv(7 DOWNTO 0) & '0' & tag(6 DOWNTO 0)
v_d_req := NOT v_d_req
d_req <= v_d_req AFTER delay
WAIT ON d_ack
END IF
ain <= rin AFTER delay
-- done with this event
END IF
-- clr not asserted
WAIT ON clr, rin
-- wait for next event
END PROCESS main
END behavior
CHAPTER 2. VHDL SOURCE CODE
30
2.4 control unit.vhd
USE work.p_constants.ALL
USE work.p_output.ALL
---- The control_unit handles those few instructions which don't really fit
---- anywhere else. Control register access is done here, as is read access
---- for the Branch Queue and PC value.
----------------------
The EXTRA input was added to provide last-result-reuse and to elminate
zero values of op_a for immediate instructions. The bit usage is:
EXTRA(0)
EXTRA(1)
EXTRA(2)
EXTRA(3)
=
=
=
=
reuseA
reuseB
reuseD
zeroA (unused)
ENTITY control_unit IS
GENERIC( delay: TIME := 100 ps )
PORT( SIGNAL clr
: IN
SIGNAL rin
: IN
SIGNAL ain
: OUT
SIGNAL tellme
: IN
SIGNAL tag
: IN
SIGNAL dest
: IN
SIGNAL pc
: IN
SIGNAL opcode
: IN
SIGNAL op_a
: IN
SIGNAL op_b
: IN
SIGNAL d_req
: OUT
SIGNAL d_ack
: IN
SIGNAL done
: OUT
SIGNAL rout
: OUT
SIGNAL aout
: IN
SIGNAL res
: OUT
SIGNAL rq_req
: OUT
SIGNAL rq_ack
: IN
SIGNAL rq
: OUT
SIGNAL putcr_req
: OUT
SIGNAL putcr_ack
: IN
SIGNAL putcr
: OUT
SIGNAL cr_num
: OUT
SIGNAL getcr_req
: OUT
SIGNAL getcr_ack
: IN
SIGNAL getcr
: IN
SIGNAL extra
: IN
END control_unit
VLBIT
VLBIT
VLBIT
VLBIT
VLBIT_1D
VLBIT_1D
VLBIT_1D
VLBIT_1D
VLBIT_1D
VLBIT_1D
VLBIT
VLBIT
VLBIT_1D
VLBIT
VLBIT
VLBIT_1D
VLBIT
VLBIT
VLBIT_1D
VLBIT
VLBIT
VLBIT_1D
VLBIT_1D
VLBIT
VLBIT
VLBIT_1D
VLBIT_1D
ARCHITECTURE behavior OF control_unit IS
BEGIN
main : PROCESS
(7 DOWNTO 0)
(4 DOWNTO 0)
(31 DOWNTO 0)
(31 DOWNTO 0)
(31 DOWNTO 0)
(31 DOWNTO 0)
(87 DOWNTO 0)
(36 DOWNTO 0)
(31 DOWNTO 0)
(31 DOWNTO 0)
(9 DOWNTO 0)
(31 DOWNTO 0)
(3 DOWNTO 0) )
2.4. CONTROL UNIT.VHD
VARIABLE debug
31
: BOOLEAN := FALSE
--- factors affecting response time
VARIABLE delay_mvpc
: TIME := 100 ps -- this is the only hard one
--- output variables
VARIABLE
VARIABLE
VARIABLE
VARIABLE
VARIABLE
v_rout
v_rq_req
v_d_req
v_putcr_req
v_getcr_req
:
:
:
:
:
VLBIT
VLBIT
VLBIT
VLBIT
VLBIT
:
:
:
:
INTEGER
VLBIT_1D(31 DOWNTO 0)
VLBIT_1D(31 DOWNTO 0)
VLBIT_1D(31 DOWNTO 0)
--- internal variables
VARIABLE
VARIABLE
VARIABLE
VARIABLE
index
op_aa
op_bb
lastresult
--- scratch variables
VARIABLE tmpi
VARIABLE tmpv
: INTEGER
: VLBIT_1D (31 DOWNTO 0)
--- statistics
VARIABLE
VARIABLE
VARIABLE
VARIABLE
s_mvpc
s_getcr
s_putcr
s_mvbr
:
:
:
:
INTEGER
INTEGER
INTEGER
INTEGER
BEGIN
--- If clear is asserted, reset everything and stick here.
IF clr /= '1' THEN
v_rout := '0'
v_rq_req := '0'
v_d_req := '0'
v_putcr_req := '0'
v_getcr_req := '0'
ain <= '0'
d_req <= v_d_req
done <= ZERO(87 DOWNTO 0)
-- reset to beginning
CHAPTER 2. VHDL SOURCE CODE
32
rout <= v_rout
res <= ZERO(36 DOWNTO 0)
rq_req <= v_rq_req
rq <= ZERO(31 DOWNTO 0)
putcr_req <= v_putcr_req
putcr <= ZERO(31 DOWNTO 0)
cr_num <= ZERO(9 DOWNTO 0)
getcr_req <= v_getcr_req
s_mvpc := 0
s_putcr := 0
s_getcr := 0
s_mvbr := 0
WAIT UNTIL clr = '1'
ELSE
---------
-- only wakeup event is RIN
This stuff had to be encoded by hand. I could have written a Perl
script to do it, but it would have taken longer than doing it
manually. This stuff shouldn't change that much (I hope). I also made
some assumptions about unused bits, which is probably okay.
IF extra(0)='1' THEN
op_aa := lastresult
ELSE
op_aa := op_a
END IF
-- reuse op_a result
IF extra(1)='1' THEN
op_bb := lastresult
ELSE
op_bb := op_b
END IF
-- reuse op_b
IF debug THEN
tmpi := v1d2int(op_aa)
puthexline("op_a is ",tmpi)
tmpi := v1d2int(op_bb)
puthexline("op_b is ",tmpi)
END IF
index := op2index( opcode )
CASE index IS
WHEN 20 =>
-- mvpc rd,imm16
2.4. CONTROL UNIT.VHD
33
IF dest /= REG_R0 THEN -- if worth doing
s_mvpc := s_mvpc + 1
--- compute word address
tmpv(30 DOWNTO 0) := add2c( pc(31 DOWNTO 2), opcode( 15 DOWNTO 0) )
IF dest = REG_R1 THEN
rq <= tmpv(29 DOWNTO 0) & ('0','0')
v_rq_req := NOT v_rq_req
-- write it out
rq_req <= v_rq_req AFTER delay_mvpc
WAIT ON rq_ack
ELSE
res <= dest & tmpv(29 DOWNTO 0) & ('0','0')
lastresult := tmpv(29 DOWNTO 0) & ('0','0')
IF debug THEN
tmpi := v1d2int(lastresult)
puthexline("latched ",tmpi)
END IF
v_rout := NOT v_rout
rout <= v_rout AFTER delay_mvpc
-- write it out
WAIT ON aout
END IF
END IF
WHEN 92 | 93 =>
IF dest /= REG_R0 THEN
-- done with it
-- getcr rd,cr
-- if worth doing
s_getcr := s_getcr + 1
IF index = 92 THEN
-- direct cr number
cr_num <= opcode(9 DOWNTO 0)
ELSE
cr_num <= op_bb(9 DOWNTO 0)
-- indirect control register
END IF
v_getcr_req := NOT v_getcr_req
getcr_req <= v_getcr_req AFTER delay
WAIT ON getcr_ack
CHAPTER 2. VHDL SOURCE CODE
34
--- NOTE: This would normally need to be four-phase, but since this
--- is the only unit which can read the control registers, it should
--- work fine.
--- write it out
IF dest = REG_R1 THEN
rq <= getcr
v_rq_req := NOT v_rq_req
rq_req <= v_rq_req AFTER delay
-- write it out
WAIT ON rq_ack
ELSE
res <= dest & getcr
lastresult := getcr
IF debug THEN
tmpi := v1d2int(lastresult)
puthexline("latched ",tmpi)
END IF
v_rout := NOT v_rout
rout <= v_rout AFTER delay
-- write it out
WAIT ON aout
END IF
END IF
WHEN 94 | 95 =>
-- done with it
-- putcr cr,ra
s_putcr := s_putcr + 1
putcr <= op_aa
IF index = 94 THEN
cr_num <= opcode(9 DOWNTO 0)
ELSE
cr_num <= op_bb(9 DOWNTO 0)
END IF
v_putcr_req := NOT v_putcr_req
putcr_req <= v_putcr_req AFTER delay
-- write out data
-- direct cr number
-- indirect control register
WAIT ON putcr_ack
WHEN 86 =>
-- mvbr rd
2.4. CONTROL UNIT.VHD
35
IF dest /= REG_R0 THEN -- if worth doing
s_mvbr := s_mvbr + 1
IF dest = REG_R1 THEN
rq <= pc
v_rq_req := NOT v_rq_req
rq_req <= v_rq_req AFTER delay
-- write it out
WAIT ON rq_ack
ELSE
res <= dest & pc
lastresult := pc
IF debug THEN
tmpi := v1d2int(lastresult)
puthexline("latched ",tmpi)
END IF
v_rout := NOT v_rout
rout <= v_rout AFTER delay
-- write it out
WAIT ON aout
END IF
END IF
-- done with it
WHEN OTHERS =>
-- anything else
putline("*** Illegal Opcode for Control Unit ***")
END CASE
--- signal completion of this instruction
IF tellme = '1' THEN
-- only if needed
tmpv := int2v1d( STATUS_done )
done <= ZERO(87 DOWNTO 16) & tmpv(7 DOWNTO 0) & tag
v_d_req := NOT v_d_req
d_req <= v_d_req AFTER delay
WAIT ON d_ack
END IF
CHAPTER 2. VHDL SOURCE CODE
36
ain <= rin AFTER delay
-- done with this event
END IF
-- clr not asserted
WAIT ON clr, rin
-- wait for next event
END PROCESS main
END behavior
2.5. CPX128.VHD
37
2.5 cpx128.vhd
USE work.p_constants.ALL
----------------------
This is used to capture the data for a large FIFO. This is just a ViewSim
performance hack. Passing the data through several latches uses an
incredible number of signals and nets, so I use this VHDL program to store
the data, and I use an external delay chain to model the time behavior.
While this models the C/CD P/PD interface, the CD and PD pins are absent.
This unit takes zero time. External delays must be used to model the done
responses.
ENTITY cpx128 IS
PORT (SIGNAL clr
SIGNAL c
SIGNAL p
SIGNAL i
SIGNAL o
END cpx128
:IN
:IN
:IN
:IN
:OUT
VLBIT
VLBIT
VLBIT
VLBIT_1D(127 DOWNTO 0)
VLBIT_1D(127 DOWNTO 0))
ARCHITECTURE behavior OF cpx128 IS
BEGIN
main : PROCESS
CONSTANT MaxDepth
: INTEGER := 16
TYPE pipe_type IS ARRAY( 0 TO MaxDepth ) OF VLBIT_1D(127 DOWNTO 0)
VARIABLE pipe
: pipe_type
VARIABLE head
VARIABLE tail
VARIABLE count
: INTEGER
: INTEGER
: INTEGER
VARIABLE v_cd
VARIABLE v_pd
: VLBIT
: VLBIT
VARIABLE s_maxusage : INTEGER
VARIABLE s_total_count : INTEGER
VARIABLE s_total_times : INTEGER
BEGIN
IF (clr /= '1') THEN
s_maxusage := 0
s_total_count := 0
s_total_times := 0
head := 0
tail := 0
count := 0
-- only for error checking
-- not for output
-- for statistics
CHAPTER 2. VHDL SOURCE CODE
38
v_cd := '0'
v_pd := '0'
o <= ZERO(127 DOWNTO 0)
WAIT UNTIL clr = '1'
ELSE
IF c'EVENT THEN
-- data coming in
IF c = v_cd THEN
putline("*** Handshake violation on Capture ***")
END IF
IF ( count < MaxDepth ) THEN
-- latch incoming data
pipe(tail) := i
tail := tail + 1
IF tail >= MaxDepth THEN
tail := 0
END IF
count := count + 1
s_total_count := s_total_count + count
s_total_times := s_total_times + 1
IF count > s_maxusage THEN
s_maxusage := count
END IF
-- keep track of maxium
v_cd := NOT v_cd
-- remember this event
END IF
END IF
IF p'EVENT THEN
-- want data on output
IF count = 0 OR p = v_pd THEN
putline("*** Handshake violation on Pass ***")
END IF
head := head + 1
IF head >= MaxDepth THEN
head := 0
END IF
count := count - 1
-- so I can get rid of it
2.5. CPX128.VHD
v_pd := NOT v_pd
39
-- remember this event
END IF
IF count = 0 THEN
pipe(head) := i
END IF
-- copy through if nothing
o <= pipe(head)
-- show latest data
END IF
WAIT ON clr, c, p
END PROCESS main
END behavior
-- clr not asserted
CHAPTER 2. VHDL SOURCE CODE
40
2.6 cpx18.vhd
USE work.p_constants.ALL
----------------------
This is used to capture the data for a large FIFO. This is just a ViewSim
performance hack. Passing the data through several latches uses an
incredible number of signals and nets, so I use this VHDL program to store
the data, and I use an external delay chain to model the time behavior.
While this models the C/CD P/PD interface, the CD and PD pins are absent.
This unit takes zero time. External delays must be used to model the done
responses.
ENTITY cpx18 IS
PORT (SIGNAL clr
SIGNAL c
SIGNAL p
SIGNAL i
SIGNAL o
END cpx18
:IN
:IN
:IN
:IN
:OUT
VLBIT
VLBIT
VLBIT
VLBIT_1D(17 DOWNTO 0)
VLBIT_1D(17 DOWNTO 0))
ARCHITECTURE behavior OF cpx18 IS
BEGIN
main : PROCESS
CONSTANT MaxDepth
: INTEGER := 16
TYPE pipe_type IS ARRAY( 0 TO MaxDepth ) OF VLBIT_1D(17 DOWNTO 0)
VARIABLE pipe
: pipe_type
VARIABLE head
VARIABLE tail
VARIABLE count
: INTEGER
: INTEGER
: INTEGER
VARIABLE v_cd
VARIABLE v_pd
: VLBIT
: VLBIT
VARIABLE s_maxusage : INTEGER
VARIABLE s_total_count : INTEGER
VARIABLE s_total_times : INTEGER
BEGIN
IF (clr /= '1') THEN
s_maxusage := 0
s_total_count := 0
s_total_times := 0
head := 0
tail := 0
count := 0
-- only for error checking
-- not for output
-- for statistics
2.6. CPX18.VHD
41
v_cd := '0'
v_pd := '0'
o <= ZERO(17 DOWNTO 0)
WAIT UNTIL clr = '1'
ELSE
IF c'EVENT THEN
-- data coming in
IF c = v_cd THEN
putline("*** Handshake violation on Capture ***")
END IF
IF ( count < MaxDepth ) THEN
-- latch incoming data
pipe(tail) := i
tail := tail + 1
IF tail >= MaxDepth THEN
tail := 0
END IF
count := count + 1
s_total_count := s_total_count + count
s_total_times := s_total_times + 1
IF count > s_maxusage THEN
s_maxusage := count
END IF
-- keep track of maxium
v_cd := NOT v_cd
-- remember this event
END IF
END IF
IF p'EVENT THEN
-- want data on output
IF count = 0 OR p = v_pd THEN
putline("*** Handshake violation on Pass ***")
END IF
head := head + 1
IF head >= MaxDepth THEN
head := 0
END IF
count := count - 1
-- so I can get rid of it
CHAPTER 2. VHDL SOURCE CODE
42
v_pd := NOT v_pd
-- remember this event
END IF
IF count = 0 THEN
pipe(head) := i
END IF
-- copy through if nothing
o <= pipe(head)
-- show latest data
END IF
WAIT ON clr, c, p
END PROCESS main
END behavior
-- clr not asserted
2.7. CPX32.VHD
43
2.7 cpx32.vhd
USE work.p_constants.ALL
----------------------
This is used to capture the data for a large FIFO. This is just a ViewSim
performance hack. Passing the data through several latches uses an
incredible number of signals and nets, so I use this VHDL program to store
the data, and I use an external delay chain to model the time behavior.
While this models the C/CD P/PD interface, the CD and PD pins are absent.
This unit takes zero time. External delays must be used to model the done
responses.
ENTITY cpx32 IS
PORT (SIGNAL clr
SIGNAL c
SIGNAL p
SIGNAL i
SIGNAL o
END cpx32
:IN
:IN
:IN
:IN
:OUT
VLBIT
VLBIT
VLBIT
VLBIT_1D(31 DOWNTO 0)
VLBIT_1D(31 DOWNTO 0))
ARCHITECTURE behavior OF cpx32 IS
BEGIN
main : PROCESS
CONSTANT MaxDepth
: INTEGER := 16
TYPE pipe_type IS ARRAY( 0 TO MaxDepth ) OF VLBIT_1D(31 DOWNTO 0)
VARIABLE pipe
: pipe_type
VARIABLE head
VARIABLE tail
VARIABLE count
: INTEGER
: INTEGER
: INTEGER
VARIABLE v_cd
VARIABLE v_pd
: VLBIT
: VLBIT
VARIABLE s_maxusage : INTEGER
VARIABLE s_total_count : INTEGER
VARIABLE s_total_times : INTEGER
BEGIN
IF (clr /= '1') THEN
s_maxusage := 0
s_total_count := 0
s_total_times := 0
head := 0
tail := 0
count := 0
-- only for error checking
-- not for output
-- for statistics
CHAPTER 2. VHDL SOURCE CODE
44
v_cd := '0'
v_pd := '0'
o <= ZERO(31 DOWNTO 0)
WAIT UNTIL clr = '1'
ELSE
IF c'EVENT THEN
-- data coming in
IF c = v_cd THEN
putline("*** Handshake violation on Capture ***")
END IF
IF ( count < MaxDepth ) THEN
-- latch incoming data
pipe(tail) := i
tail := tail + 1
IF tail >= MaxDepth THEN
tail := 0
END IF
count := count + 1
s_total_count := s_total_count + count
s_total_times := s_total_times + 1
IF count > s_maxusage THEN
s_maxusage := count
END IF
-- keep track of maxium
v_cd := NOT v_cd
-- remember this event
END IF
END IF
IF p'EVENT THEN
-- want data on output
IF count = 0 OR p = v_pd THEN
putline("*** Handshake violation on Pass ***")
END IF
head := head + 1
IF head >= MaxDepth THEN
head := 0
END IF
count := count - 1
-- so I can get rid of it
2.7. CPX32.VHD
v_pd := NOT v_pd
45
-- remember this event
END IF
IF count = 0 THEN
pipe(head) := i
END IF
-- copy through if nothing
o <= pipe(head)
-- show latest data
END IF
WAIT ON clr, c, p
END PROCESS main
END behavior
-- clr not asserted
CHAPTER 2. VHDL SOURCE CODE
46
2.8 cpx3op.vhd
USE work.p_constants.ALL
----------------------
This is used to capture the data for a large FIFO. This is just a ViewSim
performance hack. Passing the data through several latches uses an
incredible number of signals and nets, so I use this VHDL program to store
the data, and I use an external delay chain to model the time behavior.
While this models the C/CD P/PD interface, the CD and PD pins are absent.
This unit takes zero time. External delays must be used to model the done
responses.
ENTITY cpx3op IS
PORT (SIGNAL clr
SIGNAL c
SIGNAL p
SIGNAL i
SIGNAL o
END cpx3op
:IN
:IN
:IN
:IN
:OUT
VLBIT
VLBIT
VLBIT
VLBIT_1D(113 DOWNTO 0)
VLBIT_1D(113 DOWNTO 0))
ARCHITECTURE behavior OF cpx3op IS
BEGIN
main : PROCESS
CONSTANT MaxDepth
: INTEGER := 16
TYPE pipe_type IS ARRAY( 0 TO MaxDepth ) OF VLBIT_1D(113 DOWNTO 0)
VARIABLE pipe
: pipe_type
VARIABLE head
VARIABLE tail
VARIABLE count
: INTEGER
: INTEGER
: INTEGER
VARIABLE v_cd
VARIABLE v_pd
: VLBIT
: VLBIT
VARIABLE s_maxusage : INTEGER
VARIABLE s_total_count : INTEGER
VARIABLE s_total_times : INTEGER
BEGIN
IF (clr /= '1') THEN
s_maxusage := 0
s_total_count := 0
s_total_times := 0
head := 0
tail := 0
count := 0
-- only for error checking
-- not for output
-- for statistics
2.8. CPX3OP.VHD
47
v_cd := '0'
v_pd := '0'
o <= ZERO(113 DOWNTO 0)
WAIT UNTIL clr = '1'
ELSE
IF c'EVENT THEN
-- data coming in
IF c = v_cd THEN
putline("*** Handshake violation on Capture ***")
END IF
IF ( count < MaxDepth ) THEN
-- latch incoming data
pipe(tail) := i
tail := tail + 1
IF tail >= MaxDepth THEN
tail := 0
END IF
count := count + 1
s_total_count := s_total_count + count
s_total_times := s_total_times + 1
IF count > s_maxusage THEN
s_maxusage := count
END IF
-- keep track of maxium
v_cd := NOT v_cd
-- remember this event
END IF
END IF
IF p'EVENT THEN
-- want data on output
IF count = 0 OR p = v_pd THEN
putline("*** Handshake violation on Pass ***")
END IF
head := head + 1
IF head >= MaxDepth THEN
head := 0
END IF
count := count - 1
-- so I can get rid of it
CHAPTER 2. VHDL SOURCE CODE
48
v_pd := NOT v_pd
-- remember this event
END IF
IF count = 0 THEN
pipe(head) := i
END IF
-- copy through if nothing
o <= pipe(head)
-- show latest data
END IF
WAIT ON clr, c, p
END PROCESS main
END behavior
-- clr not asserted
2.9. CPX4OP.VHD
49
2.9 cpx4op.vhd
USE work.p_constants.ALL
----------------------
This is used to capture the data for a large FIFO. This is just a ViewSim
performance hack. Passing the data through several latches uses an
incredible number of signals and nets, so I use this VHDL program to store
the data, and I use an external delay chain to model the time behavior.
While this models the C/CD P/PD interface, the CD and PD pins are absent.
This unit takes zero time. External delays must be used to model the done
responses.
ENTITY cpx4op IS
PORT (SIGNAL clr
SIGNAL c
SIGNAL p
SIGNAL i
SIGNAL o
END cpx4op
:IN
:IN
:IN
:IN
:OUT
VLBIT
VLBIT
VLBIT
VLBIT_1D(145 DOWNTO 0)
VLBIT_1D(145 DOWNTO 0))
ARCHITECTURE behavior OF cpx4op IS
BEGIN
main : PROCESS
CONSTANT MaxDepth
: INTEGER := 16
TYPE pipe_type IS ARRAY( 0 TO MaxDepth ) OF VLBIT_1D(145 DOWNTO 0)
VARIABLE pipe
: pipe_type
VARIABLE head
VARIABLE tail
VARIABLE count
: INTEGER
: INTEGER
: INTEGER
VARIABLE v_cd
VARIABLE v_pd
: VLBIT
: VLBIT
VARIABLE s_maxusage : INTEGER
VARIABLE s_total_count : INTEGER
VARIABLE s_total_times : INTEGER
BEGIN
IF (clr /= '1') THEN
s_maxusage := 0
s_total_count := 0
s_total_times := 0
head := 0
tail := 0
count := 0
-- only for error checking
-- not for output
-- for statistics
CHAPTER 2. VHDL SOURCE CODE
50
v_cd := '0'
v_pd := '0'
o <= ZERO(145 DOWNTO 0)
WAIT UNTIL clr = '1'
ELSE
IF c'EVENT THEN
-- data coming in
IF c = v_cd THEN
putline("*** Handshake violation on Capture ***")
END IF
IF ( count < MaxDepth ) THEN
-- latch incoming data
pipe(tail) := i
tail := tail + 1
IF tail >= MaxDepth THEN
tail := 0
END IF
count := count + 1
s_total_count := s_total_count + count
s_total_times := s_total_times + 1
IF count > s_maxusage THEN
s_maxusage := count
END IF
-- keep track of maxium
v_cd := NOT v_cd
-- remember this event
END IF
END IF
IF p'EVENT THEN
-- want data on output
IF count = 0 OR p = v_pd THEN
putline("*** Handshake violation on Pass ***")
END IF
head := head + 1
IF head >= MaxDepth THEN
head := 0
END IF
count := count - 1
-- so I can get rid of it
2.9. CPX4OP.VHD
v_pd := NOT v_pd
51
-- remember this event
END IF
IF count = 0 THEN
pipe(head) := i
END IF
-- copy through if nothing
o <= pipe(head)
-- show latest data
END IF
WAIT ON clr, c, p
END PROCESS main
END behavior
-- clr not asserted
CHAPTER 2. VHDL SOURCE CODE
52
2.10 cpx5.vhd
USE work.p_constants.ALL
----------------------
This is used to capture the data for a large FIFO. This is just a ViewSim
performance hack. Passing the data through several latches uses an
incredible number of signals and nets, so I use this VHDL program to store
the data, and I use an external delay chain to model the time behavior.
While this models the C/CD P/PD interface, the CD and PD pins are absent.
This unit takes zero time. External delays must be used to model the done
responses.
ENTITY cpx5 IS
PORT (SIGNAL
SIGNAL
SIGNAL
SIGNAL
SIGNAL
END cpx5
clr
c
p
i
o
:IN
:IN
:IN
:IN
:OUT
VLBIT
VLBIT
VLBIT
VLBIT_1D(4 DOWNTO 0)
VLBIT_1D(4 DOWNTO 0))
ARCHITECTURE behavior OF cpx5 IS
BEGIN
main : PROCESS
CONSTANT MaxDepth
: INTEGER := 16
TYPE pipe_type IS ARRAY( 0 TO MaxDepth ) OF VLBIT_1D(4 DOWNTO 0)
VARIABLE pipe
: pipe_type
VARIABLE head
VARIABLE tail
VARIABLE count
: INTEGER
: INTEGER
: INTEGER
VARIABLE v_cd
VARIABLE v_pd
: VLBIT
: VLBIT
VARIABLE s_maxusage : INTEGER
VARIABLE s_total_count : INTEGER
VARIABLE s_total_times : INTEGER
BEGIN
IF (clr /= '1') THEN
s_maxusage := 0
s_total_count := 0
s_total_times := 0
head := 0
tail := 0
count := 0
-- only for error checking
-- not for output
-- for statistics
2.10. CPX5.VHD
53
v_cd := '0'
v_pd := '0'
o <= ZERO(4 DOWNTO 0)
WAIT UNTIL clr = '1'
ELSE
IF c'EVENT THEN
-- data coming in
IF c = v_cd THEN
putline("*** Handshake violation on Capture ***")
END IF
IF ( count < MaxDepth ) THEN
-- latch incoming data
pipe(tail) := i
tail := tail + 1
IF tail >= MaxDepth THEN
tail := 0
END IF
count := count + 1
s_total_count := s_total_count + count
s_total_times := s_total_times + 1
IF count > s_maxusage THEN
s_maxusage := count
END IF
-- keep track of maxium
v_cd := NOT v_cd
-- remember this event
END IF
END IF
IF p'EVENT THEN
-- want data on output
IF count = 0 OR p = v_pd THEN
putline("*** Handshake violation on Pass ***")
END IF
head := head + 1
IF head >= MaxDepth THEN
head := 0
END IF
count := count - 1
-- so I can get rid of it
CHAPTER 2. VHDL SOURCE CODE
54
v_pd := NOT v_pd
-- remember this event
END IF
IF count = 0 THEN
pipe(head) := i
END IF
-- copy through if nothing
o <= pipe(head)
-- show latest data
END IF
WAIT ON clr, c, p
END PROCESS main
END behavior
-- clr not asserted
2.11. CPX88.VHD
55
2.11 cpx88.vhd
USE work.p_constants.ALL
----------------------
This is used to capture the data for a large FIFO. This is just a ViewSim
performance hack. Passing the data through several latches uses an
incredible number of signals and nets, so I use this VHDL program to store
the data, and I use an external delay chain to model the time behavior.
While this models the C/CD P/PD interface, the CD and PD pins are absent.
This unit takes zero time. External delays must be used to model the done
responses.
ENTITY cpx88 IS
PORT (SIGNAL clr
SIGNAL c
SIGNAL p
SIGNAL i
SIGNAL o
END cpx88
:IN
:IN
:IN
:IN
:OUT
VLBIT
VLBIT
VLBIT
VLBIT_1D(87 DOWNTO 0)
VLBIT_1D(87 DOWNTO 0))
ARCHITECTURE behavior OF cpx88 IS
BEGIN
main : PROCESS
CONSTANT MaxDepth
: INTEGER := 16
TYPE pipe_type IS ARRAY( 0 TO MaxDepth ) OF VLBIT_1D(87 DOWNTO 0)
VARIABLE pipe
: pipe_type
VARIABLE head
VARIABLE tail
VARIABLE count
: INTEGER
: INTEGER
: INTEGER
VARIABLE v_cd
VARIABLE v_pd
: VLBIT
: VLBIT
VARIABLE s_maxusage : INTEGER
VARIABLE s_total_count : INTEGER
VARIABLE s_total_times : INTEGER
BEGIN
IF (clr /= '1') THEN
s_maxusage := 0
s_total_count := 0
s_total_times := 0
head := 0
tail := 0
count := 0
-- only for error checking
-- not for output
-- for statistics
CHAPTER 2. VHDL SOURCE CODE
56
v_cd := '0'
v_pd := '0'
o <= ZERO(87 DOWNTO 0)
WAIT UNTIL clr = '1'
ELSE
IF c'EVENT THEN
-- data coming in
IF c = v_cd THEN
putline("*** Handshake violation on Capture ***")
END IF
IF ( count < MaxDepth ) THEN
-- latch incoming data
pipe(tail) := i
tail := tail + 1
IF tail >= MaxDepth THEN
tail := 0
END IF
count := count + 1
s_total_count := s_total_count + count
s_total_times := s_total_times + 1
IF count > s_maxusage THEN
s_maxusage := count
END IF
-- keep track of maxium
v_cd := NOT v_cd
-- remember this event
END IF
END IF
IF p'EVENT THEN
-- want data on output
IF count = 0 OR p = v_pd THEN
putline("*** Handshake violation on Pass ***")
END IF
head := head + 1
IF head >= MaxDepth THEN
head := 0
END IF
count := count - 1
-- so I can get rid of it
2.11. CPX88.VHD
v_pd := NOT v_pd
57
-- remember this event
END IF
IF count = 0 THEN
pipe(head) := i
END IF
-- copy through if nothing
o <= pipe(head)
-- show latest data
END IF
WAIT ON clr, c, p
END PROCESS main
END behavior
-- clr not asserted
CHAPTER 2. VHDL SOURCE CODE
58
2.12 cpx96.vhd
USE work.p_constants.ALL
----------------------
This is used to capture the data for a large FIFO. This is just a ViewSim
performance hack. Passing the data through several latches uses an
incredible number of signals and nets, so I use this VHDL program to store
the data, and I use an external delay chain to model the time behavior.
While this models the C/CD P/PD interface, the CD and PD pins are absent.
This unit takes zero time. External delays must be used to model the done
responses.
ENTITY cpx96 IS
PORT (SIGNAL clr
SIGNAL c
SIGNAL p
SIGNAL i
SIGNAL o
END cpx96
:IN
:IN
:IN
:IN
:OUT
VLBIT
VLBIT
VLBIT
VLBIT_1D(95 DOWNTO 0)
VLBIT_1D(95 DOWNTO 0))
ARCHITECTURE behavior OF cpx96 IS
BEGIN
main : PROCESS
CONSTANT MaxDepth
: INTEGER := 16
TYPE pipe_type IS ARRAY( 0 TO MaxDepth ) OF VLBIT_1D(95 DOWNTO 0)
VARIABLE pipe
: pipe_type
VARIABLE head
VARIABLE tail
VARIABLE count
: INTEGER
: INTEGER
: INTEGER
VARIABLE v_cd
VARIABLE v_pd
: VLBIT
: VLBIT
VARIABLE s_maxusage : INTEGER
VARIABLE s_total_count : INTEGER
VARIABLE s_total_times : INTEGER
BEGIN
IF (clr /= '1') THEN
s_maxusage := 0
s_total_count := 0
s_total_times := 0
head := 0
tail := 0
count := 0
-- only for error checking
-- not for output
-- for statistics
2.12. CPX96.VHD
59
v_cd := '0'
v_pd := '0'
o <= ZERO(95 DOWNTO 0)
WAIT UNTIL clr = '1'
ELSE
IF c'EVENT THEN
-- data coming in
IF c = v_cd THEN
putline("*** Handshake violation on Capture ***")
END IF
IF ( count < MaxDepth ) THEN
-- latch incoming data
pipe(tail) := i
tail := tail + 1
IF tail >= MaxDepth THEN
tail := 0
END IF
count := count + 1
s_total_count := s_total_count + count
s_total_times := s_total_times + 1
IF count > s_maxusage THEN
s_maxusage := count
END IF
-- keep track of maxium
v_cd := NOT v_cd
-- remember this event
END IF
END IF
IF p'EVENT THEN
-- want data on output
IF count = 0 OR p = v_pd THEN
putline("*** Handshake violation on Pass ***")
END IF
head := head + 1
IF head >= MaxDepth THEN
head := 0
END IF
count := count - 1
-- so I can get rid of it
CHAPTER 2. VHDL SOURCE CODE
60
v_pd := NOT v_pd
-- remember this event
END IF
IF count = 0 THEN
pipe(head) := i
END IF
-- copy through if nothing
o <= pipe(head)
-- show latest data
END IF
WAIT ON clr, c, p
END PROCESS main
END behavior
-- clr not asserted
2.13. DELAYTAP.VHD
61
2.13 delaytap.vhd
USE work.p_constants.ALL
----------------
This taps into a 16-element FIFO at a given point, so that the effective
length of the FIFO can be adjusted dynamically. It just passes the REQ
and ACK signals, without touching the data. It is strictly a performance
hack to avoid altering the FIFO circuit just to change its length. It
does not check or enforce correct handshaking.
ENTITY delaytap IS
PORT ( SIGNAL clr
SIGNAL rin
SIGNAL ain
SIGNAL rx
SIGNAL ax
END delaytap
:IN
:IN
:OUT
:OUT
:IN
VLBIT
VLBIT
VLBIT
VLBIT_1D(15 DOWNTO 0)
VLBIT_1D(15 DOWNTO 0) )
ARCHITECTURE behavior OF delaytap IS
BEGIN
main : PROCESS
VARIABLE tap
: INTEGER := 8
VARIABLE v_rx
VARIABLE v_ax
: VLBIT_1D(15 DOWNTO 0)
: VLBIT_1D(15 DOWNTO 0)
BEGIN
IF (clr /= '1') THEN
ain <= '0'
v_rx := ZERO(15 DOWNTO 0)
v_ax := ZERO(15 DOWNTO 0)
rx <= v_rx
WAIT UNTIL clr = '1'
ELSE
IF rin'EVENT THEN
v_rx(tap) := NOT v_rx(tap)
rx <= v_rx
ELSE
IF ax(tap) /= v_ax(tap) THEN
-- request new data
-- toggle output request
-- else must be AX event
-- wait for just mine
v_ax := ax
-- remember vector
ain <= rin
-- ack it
END IF
-- that's all
CHAPTER 2. VHDL SOURCE CODE
62
END IF
END IF
WAIT ON clr, rin, ax
END PROCESS main
END behavior
-- clr not asserted
2.14. DISPATCH.VHD
63
2.14 dispatch.vhd
USE work.p_constants.ALL
USE work.p_dispatch.ALL
USE work.p_output.ALL
---- The dispatch module is the heart of the IF Unit. The IF Unit is what
---- the rest of the processor connects to, but the dispatch module has
---- slightly different interfaces and behavior.
ENTITY dispatch IS
GENERIC( delay
: TIME :=
start_addr : INTEGER
init_cr0
: INTEGER
PORT( SIGNAL clr
SIGNAL sb
SIGNAL sb_num
SIGNAL sb_r_d
SIGNAL sb_r_g
SIGNAL sb_r_r
SIGNAL sb_set
SIGNAL sb_w_r
SIGNAL sb_w_a
SIGNAL br
SIGNAL br_ack
SIGNAL br_p
SIGNAL br_p_ack
SIGNAL br_p_req
SIGNAL cr_num
SIGNAL done
SIGNAL done_ack
SIGNAL done_req
SIGNAL ex
SIGNAL ex_p
SIGNAL ex_p_ack
SIGNAL ex_p_req
SIGNAL ex_req
SIGNAL external_int
SIGNAL fault_pending
SIGNAL getcr
SIGNAL getcr_ack
SIGNAL getcr_req
SIGNAL i_addr
SIGNAL i_data
SIGNAL i_status
SIGNAL inst_ack
SIGNAL inst_ack_ack
SIGNAL inst_req
SIGNAL putcr
SIGNAL putcr_ack
SIGNAL putcr_req
SIGNAL reply_hazy
SIGNAL rf
100 ps
:= 0
:= 112 )
: IN VLBIT
: IN VLBIT_1D
: OUT VLBIT_1D
: OUT VLBIT
: IN VLBIT
: OUT VLBIT
: OUT VLBIT
: OUT VLBIT
: IN VLBIT
: IN VLBIT_1D
: OUT VLBIT
: IN VLBIT
: IN VLBIT
: OUT VLBIT
: IN VLBIT_1D
: IN VLBIT_1D
: OUT VLBIT
: IN VLBIT
: OUT VLBIT_1D
: IN VLBIT
: IN VLBIT
: OUT VLBIT
: OUT VLBIT
: IN VLBIT
: OUT VLBIT
: OUT VLBIT_1D
: OUT VLBIT
: IN VLBIT
: OUT VLBIT_1D
: IN VLBIT_1D
: IN VLBIT_1D
: IN VLBIT
: OUT VLBIT
: OUT VLBIT
: IN VLBIT_1D
: OUT VLBIT
: IN VLBIT
: OUT VLBIT
: OUT VLBIT_1D
-- handshaking
-- initial PC value
-- Exceptions, Ints, Supervisor
(31 DOWNTO 0)
(4 DOWNTO 0)
(31 DOWNTO 0)
(9 DOWNTO 0)
(87 DOWNTO 0)
(127 DOWNTO 0)
(31 DOWNTO 0)
(31 DOWNTO 0)
(31 DOWNTO 0)
(3 DOWNTO 0)
(31 DOWNTO 0)
(17 DOWNTO 0)
CHAPTER 2. VHDL SOURCE CODE
64
SIGNAL
SIGNAL
SIGNAL
SIGNAL
SIGNAL
SIGNAL
SIGNAL
SIGNAL
SIGNAL
SIGNAL
SIGNAL
SIGNAL
SIGNAL
SIGNAL
SIGNAL
END dispatch
rf_p
rf_p_ack
rf_p_req
rf_req
sync_ack
sync_nack
sync_req
x_cr0
xbr
xbr_ack
xbr_p
xbr_p_ack
xbr_p_req
pf_debug
x_debug
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
IN
IN
OUT
OUT
IN
IN
OUT
OUT
IN
OUT
IN
IN
OUT
OUT
OUT
VLBIT
VLBIT
VLBIT
VLBIT
VLBIT
VLBIT
VLBIT
VLBIT_1D (31 DOWNTO 0)
VLBIT_1D (31 DOWNTO 0)
VLBIT
VLBIT
VLBIT
VLBIT
VLBIT
VLBIT)
-- for debugging only
ARCHITECTURE behavior OF dispatch IS
BEGIN
main : PROCESS
VARIABLE
VARIABLE
VARIABLE
VARIABLE
VARIABLE
VARIABLE
VARIABLE
VARIABLE
VARIABLE
VARIABLE
debug
debug_reuse
trace_dispatch
trace_iw
trace_excp
all_tellme
no_tellme
reuse_result
skip_r0_ops
out_of_order
:
:
:
:
:
:
:
:
:
:
BOOLEAN
BOOLEAN
BOOLEAN
BOOLEAN
BOOLEAN
BOOLEAN
BOOLEAN
BOOLEAN
BOOLEAN
BOOLEAN
:=
:=
:=
:=
:=
:=
:=
:=
:=
:=
FALSE -- display everything
FALSE -- display reuse stuff
FALSE -- display dispatches
FALSE -- display IW loads
FALSE -- display IW loads
FALSE -- for debugging only
FALSE -- for debugging only
TRUE -- reuse last results
TRUE -- speed up OP rD,r0,imm16
TRUE -- issue insts out of order
--- Necessary constants and type definitions.
VARIABLE
VARIABLE
VARIABLE
VARIABLE
IW_tap
BR_Max
XBR_Max
R1_Max
:
:
:
:
INTEGER
INTEGER
INTEGER
INTEGER
:=
:=
:=
:=
IW_Max
8
8
8
-----
useful IW size
Branch Queue size
Exception Branch Queue size
R1 Queue size
--- factors affecting response time
VARIABLE
VARIABLE
VARIABLE
VARIABLE
VARIABLE
VARIABLE
VARIABLE
VARIABLE
VARIABLE
VARIABLE
delay_decode
delay_doit
delay_done_req
delay_getcr
delay_inst_ack
delay_iw_search
delay_putcr
delay_rte
delay_save_state
delay_sync_ack
:
:
:
:
:
:
:
:
:
:
TIME
TIME
TIME
TIME
TIME
TIME
TIME
TIME
TIME
TIME
:=
:=
:=
:=
:=
:=
:=
:=
:=
:=
100
100
100
100
100
100
100
100
100
100
ps
ps
ps
ps
ps
ps
ps
ps
ps
ps
-----------
dispatch output signals
handle DOIT instruction
update IW on done
read CR
put new inst in IW
look for inst to dispatch
write CR
restore state on RTE
save state on fault
respond to SYNC_ACK
2.14. DISPATCH.VHD
VARIABLE delay_sync_nack
VARIABLE delay_to_use
65
: TIME := 100 ps -- respond to SYNC_NACK
: TIME
-- scratch for culumative time
--- constant definitions
CONSTANT Tag_Max_Value
: INTEGER := 127
CONSTANT
CONSTANT
CONSTANT
CONSTANT
CONSTANT
CONSTANT
CONSTANT
CONSTANT
:
:
:
:
:
:
:
:
ICR_Saved_Control
ICR_Fault_Status
ICR_Fault_Address
ICR_Next_PC
ICR_BR_Count
ICR_R1_Count
ICR_IW_Count
ICR_IW_Faults
INTEGER
INTEGER
INTEGER
INTEGER
INTEGER
INTEGER
INTEGER
INTEGER
:=
:=
:=
:=
:=
:=
:=
:=
1
2
3
4
5
6
7
8
--- These control registers are not affected by anything. They're just here
--- for scratch storage in supervisor mode.
CONSTANT
CONSTANT
CONSTANT
CONSTANT
ICR_S1
ICR_S2
ICR_S3
ICR_S4
:
:
:
:
INTEGER
INTEGER
INTEGER
INTEGER
:=
:=
:=
:=
9
10
11
12
--- type definitions
TYPE tag_sb_type IS ARRAY ( 0 TO Tag_Max_Value ) OF BOOLEAN
TYPE cr_type IS ARRAY ( IF_ICR_Min TO IF_ICR_Max ) OF INTEGER
TYPE siw_type IS ARRAY ( IF_SIW_Min TO IF_SIW_Max ) OF INTEGER
TYPE pflag_type IS ARRAY ( 0 TO 31 ) OF BOOLEAN
TYPE lfu_type IS ARRAY ( 0 TO 4 ) OF INTEGER
--- control register 0 is located here.
VARIABLE cr0
: VLBIT_1D (31 DOWNTO 0)
--- internal variables
VARIABLE
VARIABLE
VARIABLE
VARIABLE
VARIABLE
VARIABLE
VARIABLE
iw
: iw_type
iw_bottom
: INTEGER
wat_flag
: BOOLEAN
single_flag
: BOOLEAN
pc
: INTEGER
faulting_instruction : iw_slot
doit_instruction : iw_slot
--------
instruction window
next available slot
wait at top scoreboard bit
single instruction flag
program counter
remembers who caused fault
where DOIT came from
CHAPTER 2. VHDL SOURCE CODE
66
VARIABLE
VARIABLE
VARIABLE
VARIABLE
VARIABLE
VARIABLE
VARIABLE
VARIABLE
VARIABLE
VARIABLE
VARIABLE
VARIABLE
VARIABLE
VARIABLE
VARIABLE
out_count
br_count
new_br_count
xbr_count
new_xbr_count
r1_count
new_r1_count
r1_pending
new_r1_pending
tag_value
tag_sb
waiting_for_inst
cr
siw
scoreboard
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
INTEGER
-- number of incomplete insts.
INTEGER
-- entries in Branch Queue
INTEGER
INTEGER
-- entries in X Branch Queue
INTEGER
INTEGER
-- entries in R1 Queue
INTEGER
-- used to decrement r1_count
INTEGER
INTEGER
INTEGER
-- assign tags to insts.
tag_sb_type
-- prevent multiple tag use
BOOLEAN
-- controls INST_REQ
cr_type
-- internal control regs
siw_type
-- shadow IW slots
VLBIT_1D(31 DOWNTO 0) -- internal copy only
--- Variables for use in dispatching out-of-order, reusing last results,
--- and skipping r0 operands.
VARIABLE
VARIABLE
VARIABLE
VARIABLE
VARIABLE
VARIABLE
VARIABLE
VARIABLE
VARIABLE
VARIABLE
VARIABLE
VARIABLE
VARIABLE
VARIABLE
pload
pstore
pbranch
pcarry
pdest
psrc
ldest
fu_num
reuseA
reuseB
reuseD
zeroA
latched_in_fu
got_probes
VARIABLE try_dispatch
VARIABLE done_dispatch
VARIABLE done_ex_dispatch
---------
:
:
:
:
:
:
:
:
:
:
:
:
:
:
BOOLEAN
BOOLEAN
BOOLEAN
BOOLEAN
pflag_type
pflag_type
pflag_type
INTEGER
BOOLEAN
BOOLEAN
BOOLEAN
BOOLEAN
lfu_type
BOOLEAN
: BOOLEAN
: BOOLEAN
: BOOLEAN
---------------
have I
have I
have I
have I
have I
have I
have I
number
flag
flag
flag
flag
tracks
have I
seen a prior load?
seen a prior store?
seen a prior branch?
seen a prior carry?
seen prior dest regs?
seen prior src regs?
seen issued dests?
of dest FU
latched values
probed queues?
-- hack to dispatch more often
-- hack to do it only once
-- hack to do it only once
Input signal event variables. These are the events which wake up this
process, for various reasons. The first four are externally
arbitrated. The control register operations don't have to be, since
control registers are only written here under quiescent conditions.
VARIABLE
VARIABLE
VARIABLE
VARIABLE
VARIABLE
l_inst_ack
l_done_req
l_external_int
l_getcr_req
l_putcr_req
:
:
:
:
:
VLBIT
VLBIT
VLBIT
VLBIT
VLBIT
--- output signal value variables
VARIABLE v_br_ack
: VLBIT
------
arbitrated
arbitrated
arbitrated
can be done at any time
only done by PUTCR inst.
2.14. DISPATCH.VHD
VARIABLE
VARIABLE
VARIABLE
VARIABLE
VARIABLE
VARIABLE
VARIABLE
VARIABLE
VARIABLE
VARIABLE
VARIABLE
VARIABLE
VARIABLE
VARIABLE
VARIABLE
VARIABLE
VARIABLE
VARIABLE
VARIABLE
v_br_p_req
v_done_ack
v_ex
v_ex_p_req
v_ex_req
v_fault_pending
v_i_addr
v_inst_req
v_reply_hazy
v_rf
v_rf_p_req
v_rf_req
v_sb_r_r
v_sb_w_r
v_sync_req
v_xbr_ack
v_xbr_p_req
v_x_debug
v_pf_debug
67
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
VLBIT
VLBIT
VLBIT_1D (127 DOWNTO 0)
VLBIT
VLBIT
VLBIT
VLBIT_1D (31 DOWNTO 0)
VLBIT
VLBIT
VLBIT_1D (17 DOWNTO 0)
VLBIT
VLBIT
VLBIT
VLBIT
VLBIT
VLBIT
VLBIT
VLBIT
VLBIT
--- scratch variables
VARIABLE
VARIABLE
VARIABLE
VARIABLE
VARIABLE
tmpi
tmpb1
tmpb2
tmpv
tmpmvbr
:
:
:
:
:
INTEGER
BOOLEAN
BOOLEAN
VLBIT_1D (31 DOWNTO 0)
VLBIT_1D (31 DOWNTO 0)
VARIABLE
VARIABLE
VARIABLE
VARIABLE
VARIABLE
VARIABLE
VARIABLE
VARIABLE
VARIABLE
VARIABLE
iw_index
vA, vB, vD
srcA, srcB, srcD
dest
op_type
status
single, wat
tellme
found_one
icount
:
:
:
:
:
:
:
:
:
:
INTEGER
BOOLEAN
INTEGER
INTEGER
INTEGER
INTEGER
BOOLEAN
BOOLEAN
BOOLEAN
INTEGER
-----------
temp for searching IW
valid flags for operands
source operand registers
destination register
decode instruction type
status of decoded inst.
flags for decoded inst.
flags for decoded inst.
found inst to issue
count issued insts in IW
:
:
:
:
:
:
:
:
:
:
:
INTEGER
INTEGER
INTEGER
INTEGER
INTEGER
INTEGER
INTEGER
INTEGER
INTEGER
INTEGER
INTEGER
------------
got new instruction for IW
cumulative sum of IW count
maximum IW fullness
reported done status
tried to dispatch
actually did it (not doit)
same, but only for faults
inst. needed operands
done status is faulty
invoked exception handler
count zeroA times
--- statistics
VARIABLE
VARIABLE
VARIABLE
VARIABLE
VARIABLE
VARIABLE
VARIABLE
VARIABLE
VARIABLE
VARIABLE
VARIABLE
s_inst_ack
s_iw_total
s_iw_max
s_done_req
s_dispatch_req
s_did_dispatch
s_excp_dispatch
s_need_operands
s_excp_status
s_did_excp
s_zeroA
VARIABLE s_reuse_result
: INTEGER
-- count last-result-reuse
CHAPTER 2. VHDL SOURCE CODE
68
VARIABLE
VARIABLE
VARIABLE
VARIABLE
s_reuse_helps
s_iw_ooo_count
s_iw_ooo_total
s_iw_ooo_max
:
:
:
:
INTEGER
INTEGER
INTEGER
INTEGER
-----
count when it helps
out-of-order insts issued
how far out-of-order total
maximum out-of-order dist
--- other stuff
CONSTANT EX_PADDING : VLBIT_1D(127 DOWNTO 0) :=
( '0','0','0','0','0','0','0','0',
'0','0','0','0','0','0','0','0',
'0','0','0','0','0','0','0','0',
'0','0','0','0','0','0','0','0',
'0','0','0','0','0','0','0','0',
'0','0','0','0','0','0','0','0',
'0','0','0','0','0','0','0','0',
'0','0','0','0','0','0','0','0',
'0','0','0','0','0','0','0','0',
'0','0','0','0','0','0','0','0',
'0','0','0','0','0','0','0','0',
'0','0','0','0','0','0','0','0',
'0','0','0','0','0','0','0','0',
'0','0','0','0','0','0','0','0',
'0','0','0','0','0','0','0','0',
'0','0','0','0','0','0','0','0' )
BEGIN
----- If clear is asserted, reset everything and stick here.
--IF clr /= '1' THEN
cr0 := int2v1d( init_cr0 )
x_cr0 <= cr0
FOR i IN 0 TO (IW_Max - 1) LOOP
iw(i).valid := FALSE
END LOOP
iw_bottom := 0
FOR i IN 0 TO Tag_Max_Value LOOP
tag_sb(i) := FALSE
END LOOP
wat_flag := FALSE
single_flag := FALSE
pc := start_addr
tag_value := 0
out_count := 0
br_count := 0
-- reset to beginning
-- init CR0
-- clear IW
-- clear the tag scoreboard
2.14. DISPATCH.VHD
69
xbr_count := 0
r1_count := 0
new_r1_count := 0
r1_pending := 0
new_r1_pending := 0
waiting_for_inst := FALSE
done_dispatch := FALSE
done_ex_dispatch := FALSE
l_inst_ack := '0'
l_done_req := '0'
l_external_int := '0'
l_getcr_req := '0'
l_putcr_req := '0'
v_br_ack := '0'
v_br_p_req := '0'
v_done_ack := '0'
v_ex_p_req := '0'
v_ex_req := '0'
v_fault_pending := '0'
v_inst_req := '0'
v_reply_hazy := '0'
v_rf_p_req := '0'
v_rf_req := '0'
v_sb_r_r := '0'
v_sb_w_r := '0'
v_sync_req := '0'
v_xbr_ack := '0'
v_xbr_p_req := '0'
br_ack <= v_br_ack
br_p_req <= v_br_p_req
done_ack <= v_done_ack
ex <= EX_PADDING
ex_p_req <= v_ex_p_req
ex_req <= v_ex_req
fault_pending <= v_fault_pending
getcr <= ZERO(31 DOWNTO 0)
getcr_ack <= '0'
inst_ack_ack <= '0'
inst_req <= v_inst_req
putcr_ack <= '0'
reply_hazy <= v_reply_hazy
rf <= ZERO( 17 DOWNTO 0 )
rf_p_req <= v_rf_p_req
rf_req <= v_rf_req
sb_num <= ('0','0','0','0','0')
sb_r_r <= v_sb_r_r
sb_r_d <= v_sb_r_r
sb_set <= '0'
sb_w_r <= v_sb_w_r
sync_req <= v_sync_req
xbr_ack <= v_xbr_ack
-- now set outputs
CHAPTER 2. VHDL SOURCE CODE
70
xbr_p_req <= v_xbr_p_req
v_i_addr := int2v1d(pc)
i_addr <= (v_i_addr(31 DOWNTO 2) & '0' & '0') -- just for now
v_x_debug := '0'
x_debug <= v_x_debug
v_pf_debug := '0'
pf_debug <= v_pf_debug
--- clear statistics
s_inst_ack := 0
s_iw_total := 0
s_iw_max := 0
s_done_req := 0
s_dispatch_req := 0
s_did_dispatch := 0
s_excp_dispatch := 0
s_need_operands := 0
s_excp_status := 0
s_did_excp := 0
s_zeroA := 0
s_reuse_result := 0
s_reuse_helps := 0
s_iw_ooo_count := 0
s_iw_ooo_total := 0
s_iw_ooo_max := 0
WAIT UNTIL clr = '1'
-- wait till ready to run
--- Send out first instruction request to start things off.
v_i_addr := int2v1d(pc)
-- get 32-bit PC value
i_addr <= (v_i_addr(31 DOWNTO 2) & cr0(Supervisor) & '0')
v_inst_req := NOT v_inst_req
inst_req <= v_inst_req AFTER delay
waiting_for_inst := TRUE
IF debug THEN
puthexline("sent out INST_REQ for address ",pc)
END IF
ELSE
-- unit is running
---- Normal running condition
--- The process loses events if I'm busy elsewhere, so I need to make my
--- own virtual wait statement, instead of relying on the actual wait
--- from VHDL. I'll just sample by hand, and only wait if there are no
2.14. DISPATCH.VHD
71
--- pending requests. Since the REQ/ACK is paired, this will work fine.
--- The critical signals are externally arbitrated, so I can respond to
--- any that I see here.
got_probes := FALSE
try_dispatch := TRUE
done_dispatch := FALSE
IF ex_p = '0' THEN
done_ex_dispatch := FALSE
END IF
WHILE ( inst_ack /= l_inst_ack OR
try_dispatch OR
done_req /= l_done_req OR
external_int /= l_external_int OR
getcr_req /= l_getcr_req OR
putcr_req /= l_putcr_req )
LOOP
IF debug THEN
putline("Top of event loop")
END IF
-----------
Requests to read and write internal control registers must always
be handled, but don't need to be arbitrated, since the internal
control registers are only changed when starting and ending
exception processing (when everything has stopped), and by PUTCR
instructions (when everything has also stopped).
IF getcr_req /= l_getcr_req THEN
-- request to read control reg
l_getcr_req := getcr_req
tmpi := v1d2int( cr_num )
-- which register
IF debug THEN
putline("handling GETCR request for CR",tmpi)
END IF
--- NOTE: This would normally need to be four-phase, but since there
--- is only one unit which can read the control registers, it should
--- work fine.
IF tmpi >=
getcr <=
ELSIF tmpi
getcr <=
ELSIF tmpi
getcr <=
ELSE
getcr <=
IF_ICR_Min AND tmpi <= IF_ICR_Max THEN
int2v1d( cr(tmpi) )
-- actual register value
>= IF_SIW_Min AND tmpi <= IF_SIW_Max THEN
int2v1d( siw(tmpi) )
-- shadow IW
= 0 THEN
cr0
-- this isn't necessary
ZERO(31 DOWNTO 0)
-- no register here, use zero
CHAPTER 2. VHDL SOURCE CODE
72
END IF
getcr_ack <= getcr_req AFTER delay_getcr
END IF
-- getcr_req
--- Reading and writing can't happen at the same time, since PUTCR is
--- a SINGLE instruction, which must be the only one active.
IF putcr_req /= l_putcr_req THEN
-- request to write control reg
l_putcr_req := putcr_req
tmpi := v1d2int( cr_num )
-- which register to write
IF debug THEN
putline("handling PUTCR request for CR",tmpi)
END IF
IF (tmpi >= IF_ICR_Min AND tmpi <= IF_ICR_Max) THEN -- control reg
cr(tmpi) := v1d2int( putcr )
ELSIF (tmpi >= IF_SIW_Min AND tmpi <= IF_SIW_Max) THEN -- shadow IW
siw(tmpi) := v1d2int( putcr )
ELSIF tmpi = 0 THEN
-- cr0
cr0 := putcr
x_cr0 <= cr0
END IF
putcr_ack <= putcr_req AFTER delay_putcr
END IF
-- putcr_req
IF inst_ack /= l_inst_ack THEN
-- new operand has arrived
l_inst_ack := inst_ack
s_inst_ack := s_inst_ack + 1
IF debug THEN
putline("got INST_ACK event")
END IF
waiting_for_inst := FALSE
--- Is there room?
There had better be!
IF ((IW_tap - iw_bottom) >= 1) THEN -- yes, there's room
--- see if it really arrived, or if there was a memory fault
tmpi := STATUS_none
-- assume there's not
2.14. DISPATCH.VHD
73
--- check for memory faults
IF ( ( i_status(0) = '1'
( i_status(1) = '1'
( i_status(2) = '1'
( i_status(3) = '1'
THEN
tmpi := STATUS_imem
END IF
AND
AND
AND
AND
cr0(Imem0)
cr0(Imem1)
cr0(Imem2)
cr0(Imem3)
=
=
=
=
'1'
'1'
'1'
'1'
)
)
)
)
OR
OR
OR
)
iw(iw_bottom).status := tmpi
-- save status
iw(iw_bottom).valid := TRUE
-- mark it valid
iw(iw_bottom).address := v1d2int( v_i_addr )
iw(iw_bottom).issued := FALSE
IF tmpi /= STATUS_none THEN
-- yes, there's a fault
IF debug THEN
putline("found a memory fault")
END IF
IF v_fault_pending = '0' THEN
-- might need to signal it
faulting_instruction.status := tmpi
faulting_instruction.address := v1d2int( v_i_addr )
v_fault_pending := '1'
-- do so
fault_pending <= v_fault_pending
v_x_debug := NOT v_x_debug
x_debug <= v_x_debug
IF trace_excp THEN
putline("IMem exception: out_count = ",out_count)
END IF
END IF
ELSE
-- no fault
-------------
Just stick the new instructions in the IW. They will be
decoded at dispatch time. This simplifies the return from
exceptions, since I don't have to do anything special to
the IW, other than to just reload it with nothing
dispatched. Well, that's not quite true: I will need to set
the single_flag again.
---------
I do need to set the single_flag now, so that I don't fetch
anything that I don't need. I could just throw away all
instructions after the SINGLE instruction, but that would
be messier.
tmpi := v1d2int( i_data )
IF tmpi /= OPCODE_doit THEN
-- get opcode
CHAPTER 2. VHDL SOURCE CODE
74
iw(iw_bottom).opcode := tmpi
IF debug OR trace_iw THEN
put("IW(",iw_bottom)
puthex(") got opcode ",iw(iw_bottom).opcode)
puthexline(" from address ",iw(iw_bottom).address)
END IF
IF is_single( i_data ) THEN
-- see if it's single
iw(iw_bottom).single := TRUE
single_flag := TRUE
IF debug THEN
putline("single flag is now ",single_flag)
END IF
END IF
iw_bottom := iw_bottom + 1
-- next slot
s_iw_total := s_iw_total + iw_bottom
IF iw_bottom > s_iw_max THEN
s_iw_max := iw_bottom
END IF
ELSE
cr0(Doit) := '1'
single_flag := TRUE
-- explicit doit
-- set Doit flag
doit_instruction.address := v1d2int( v_i_addr )
doit_instruction.opcode := tmpi
IF debug OR trace_iw THEN
put("IW(-) ")
puthex("got opcode ",iw(iw_bottom).opcode)
puthexline(" from address ",iw(iw_bottom).address)
END IF
IF debug THEN
putline("single flag is now ",single_flag)
END IF
--- signal desire for normal branch target
IF cr0(Excp_Enable) = '1' THEN
v_pf_debug := NOT v_pf_debug
pf_debug <= v_pf_debug
END IF
END IF
IF i_data(31) = '1' THEN
-- add implicit doit
2.14. DISPATCH.VHD
cr0(Doit) := '1'
single_flag := TRUE
75
-- set Doit flag
doit_instruction.address := v1d2int( v_i_addr )
doit_instruction.opcode := tmpi
IF debug OR trace_iw THEN
putline("got implicit DOIT")
END IF
IF debug THEN
putline("single flag is now ",single_flag)
END IF
--- signal desire for normal branch target
IF cr0(Excp_Enable) = '1' THEN
v_pf_debug := NOT v_pf_debug
pf_debug <= v_pf_debug
END IF
END IF
---------------
I can go ahead and increment the program counter now,
because if I just added a SINGLE instruction, the PC won't
be used until the instruction has finished, at which time
the PC will have been changed if it needs to be. NOTE: This
means that the DOIT instruction must either replace the PC
or leave it alone. It shouldn't increment it. Same for RTE,
and PUTCR only affects the user/supervisor mode bit.
pc := pc + 4
-- increment program counter
IF debug THEN
puthexline("PC advanced to ",pc)
END IF
END IF
END IF
-- (no memory fault)
-- (there's room in the IW)
inst_ack_ack <= inst_ack AFTER delay_inst_ack
IF debug THEN
putline("done with this event")
END IF
END IF
IF done_req /= l_done_req THEN
l_done_req := done_req
-- inst_ack
-- instruction has completed
CHAPTER 2. VHDL SOURCE CODE
76
s_done_req := s_done_req + 1
IF debug THEN
putline("got DONE_REQ event")
END IF
--- Find instruction associated with the tag.
tmpi := v1d2int( done(7 DOWNTO 0) )
-- get tag
IF debug THEN
putline("looking for tag ",tmpi)
END IF
iw_index := -1
FOR i IN 0 TO (iw_bottom - 1) LOOP
-- it will do 0 to 0
IF iw(i).valid AND iw(i).issued AND iw(i).tag = tmpi THEN -- got it
iw_index := i
EXIT
END IF
END LOOP
--- If tag wasn't found, crash and burn.
ASSERT iw_index /= -1 REPORT "Retiring Invalid Tag" SEVERITY FAILURE
IF debug THEN
putline("found it in slot ",iw_index)
END IF
--- We've heard from the instruction. Count it off.
out_count := out_count - 1
IF debug THEN
putline("now out_count = ",out_count)
END IF
--- Mark the tag as not in use. This is safe, because if the
--- instruction is faulty, nothing more will be dispatched until
--- the fault is handled. Right?
tag_sb(tmpi) := FALSE
--- now handle reported status
tmpi := v1d2int( done(15 DOWNTO 8) ) -- get major status
IF debug THEN
putline("major status is ",tmpi)
2.14. DISPATCH.VHD
77
END IF
IF tmpi = STATUS_done THEN
IF iw(iw_index).dest == 1 THEN
r1_count := r1_count + 1
r1_pending := r1_pending - 1
-- No fault. Remove it.
-- produced r1 value
-- so count it,
-- since it succeeded
--- clear scoreboard for R1
sb_set <= '0'
sb_num <= REG_R1
v_sb_w_r := NOT v_sb_w_r
sb_w_r <= v_sb_w_r AFTER delay
WAIT ON sb_w_a
IF debug THEN
putline("r1_count is now ",r1_count)
putline("r1_pending is now ",r1_pending)
putline("clearing scoreboard bit ",iw(iw_index).dest)
END IF
END IF
iw_remove( iw_index, iw, iw_bottom, wat_flag, single_flag )
IF debug THEN
putline("wat_flag is now ",wat_flag)
putline("single_flag is now ",single_flag)
END IF
ELSE
-- faulty instruction
s_excp_status := s_excp_status + 1
-----------
Save minor status as well as major. In this register, the minor
status is the upper 16 bits, while the major status is the
lower 16 bits. Only 8 bits of each are actually returned from
execution units, but the internally generated major status is
actually 9 bits wide, so we split the register this way.
tmpi := tmpi + 65536 * v1d2int( done(23 DOWNTO 16) )
iw(iw_index).status := tmpi
-- save status with instruction
--- save other reported values
iw(iw_index).arg1 := v1d2int( done(87 DOWNTO 56) )
iw(iw_index).arg2 := v1d2int( done(55 DOWNTO 23) )
IF iw(iw_index).dest >= 1 THEN
-- clear scoreboard bit if set
IF debug THEN
putline("clearing scoreboard bit ",iw(iw_index).dest)
END IF
CHAPTER 2. VHDL SOURCE CODE
78
sb_set <= '0'
tmpv := int2v1d( iw(iw_index).dest
sb_num <= tmpv(4 DOWNTO 0)
v_sb_w_r := NOT v_sb_w_r
sb_w_r <= v_sb_w_r AFTER delay
WAIT ON sb_w_a
) -- IDIOTIC ViewLogic crap
END IF
IF v_fault_pending = '0' THEN
-- need to signal fault
faulting_instruction := iw(iw_index) -- remember who did it
v_fault_pending := '1'
-- do so
fault_pending <= v_fault_pending
v_x_debug := NOT v_x_debug
x_debug <= v_x_debug
IF trace_excp THEN
putline("faulty status: out_count = ",out_count)
END IF
END IF
END IF
v_done_ack := NOT v_done_ack
done_ack <= v_done_ack AFTER delay_done_req
IF debug THEN
putline("done with this event")
END IF
END IF
-- done_req
IF external_int /= l_external_int THEN
-- guess what
IF debug THEN
putline("got EXTERNAL_INT event")
END IF
l_external_int := external_int
--- decide whether to postpone the INT or not. If it's
--- disabled, or if I'm in the process of switching to an
--- exception handler already, then put it off until later.
IF cr0(Int_Enable) = '0' OR v_fault_pending = '1' THEN
v_reply_hazy := NOT v_reply_hazy
reply_hazy <= v_reply_hazy
-- ask again later
IF debug THEN
putline("reply hazy - ask again later")
2.14. DISPATCH.VHD
79
END IF
ELSE
-- I can do it now
faulting_instruction.status := STATUS_int
v_fault_pending := '1'
-- do so
fault_pending <= v_fault_pending
v_x_debug := NOT v_x_debug
x_debug <= v_x_debug
IF trace_excp THEN
putline("interrupt: out_count = ",out_count)
END IF
try_dispatch := FALSE
END IF
IF debug THEN
putline("done with this event")
END IF
END IF
-- external_int
IF NOT done_dispatch AND try_dispatch THEN -- try to dispatch something
try_dispatch := FALSE
s_dispatch_req := s_dispatch_req + 1
IF debug THEN
putline("got try_dispatch signal")
END IF
---------------
Now try to dispatch an instruction from the IW. All decoding,
fault detection, tag assignments, etc. is done here to simplify
returning from exceptions. I don't have to preload anything, just
start dispatching again. If it's dispatched externally, increment
out_count DOITs are a special case, since they are handled
entirely within this module, and don't produce a done_req
signal. MVPC and MVBR must provide operands to the instruction.
delay_to_use := delay
found_one := FALSE
-- looking for one
IF ( v_fault_pending = '0' and
NOT wat_flag )
THEN
-- no dispatch while faults
-- no dispatch until cleared
CHAPTER 2. VHDL SOURCE CODE
80
IF debug THEN
putline("Looking for something to dispatch")
END IF
delay_to_use := delay_iw_search
-- time to find valid inst.
--- set up data structures for loop
pload := FALSE
pstore := FALSE
pbranch := FALSE
pcarry := FALSE
pdest := ( FALSE,FALSE,FALSE,FALSE,FALSE,FALSE,FALSE,FALSE,
FALSE,FALSE,FALSE,FALSE,FALSE,FALSE,FALSE,FALSE,
FALSE,FALSE,FALSE,FALSE,FALSE,FALSE,FALSE,FALSE,
FALSE,FALSE,FALSE,FALSE,FALSE,FALSE,FALSE,FALSE )
psrc := ( FALSE,FALSE,FALSE,FALSE,FALSE,FALSE,FALSE,FALSE,
FALSE,FALSE,FALSE,FALSE,FALSE,FALSE,FALSE,FALSE,
FALSE,FALSE,FALSE,FALSE,FALSE,FALSE,FALSE,FALSE,
FALSE,FALSE,FALSE,FALSE,FALSE,FALSE,FALSE,FALSE )
ldest := ( FALSE,FALSE,FALSE,FALSE,FALSE,FALSE,FALSE,FALSE,
FALSE,FALSE,FALSE,FALSE,FALSE,FALSE,FALSE,FALSE,
FALSE,FALSE,FALSE,FALSE,FALSE,FALSE,FALSE,FALSE,
FALSE,FALSE,FALSE,FALSE,FALSE,FALSE,FALSE,FALSE )
icount := 0
FOR i IN 0 TO (iw_bottom - 1) LOOP
IF ( NOT iw(i).valid ) THEN
-- check each slot for valid
-- stop when I run out
IF debug THEN
putline("end of IW entries")
END IF
EXIT
END IF
IF debug THEN
putline("looking at iw slot ",i)
put(" valid = ",iw(i).valid)
put(" issued = ",iw(i).issued)
putline(" tag = ",iw(i).tag)
puthexline(" status = ",iw(i).status)
puthexline(" address = ",iw(i).address)
puthexline(" opcode = ",iw(i).opcode)
END IF
IF iw(i).issued THEN
icount := icount + 1
-- count issued insts in IW
2.14. DISPATCH.VHD
81
--- Keep track of all the currently pending destinations in
--- case I want to reuse them.
IF reuse_result THEN
IF debug_reuse OR debug THEN
putline("setting ldest ",iw(i).dest)
END IF
ldest(iw(i).dest) := TRUE
END IF
NEXT
-- skip issued instructions
END IF
--- Now, I'm looking at a valid, non-issued instruction. Decode
--- it and see if I can issue it.
tmpb1 := vlb2boo( cr0(Supervisor) ) -- stupid Viewlogic crap
tmpb2 := vlb2boo( cr0(Excp_Enable) ) -- stupid Viewlogic crap
decode( BR_Max, XBR_Max, R1_Max, -- queue length inputs
iw(i).opcode, tmpb1, tmpb2, -- inputs
r1_count, r1_pending, br_count, xbr_count, -- inputs
new_r1_count, new_r1_pending, -- outputs
new_br_count, new_xbr_count, -- outputs
status, op_type, single, wat, tellme, -- outputs
vA, srcA, vB, srcB, vD, srcD, dest) -- outputs
IF all_tellme THEN
tellme := TRUE
ELSIF no_tellme THEN
tellme := FALSE
END IF
iw(i).single := single
iw(i).wat := wat
iw(i).status := status
iw(i).dest := dest
-- for debugging only
-- used for starting exceptions
IF debug THEN
putline("found a non-issued instruction in slot ",i)
END IF
IF status /= STATUS_none THEN
faulting_instruction := iw(i)
-- need to signal fault
-- remember who did it
v_fault_pending := '1'
-- do so
fault_pending <= v_fault_pending
v_x_debug := NOT v_x_debug
CHAPTER 2. VHDL SOURCE CODE
82
x_debug <= v_x_debug
IF debug THEN
puthexline("but it's faulty. Status = 0x",status)
END IF
IF trace_excp THEN
put("invalid instruction:")
puthex(" op ",iw(i).opcode)
puthexline(" addr ",iw(i).address)
putline("invalid instruction: out_count = ",out_count)
END IF
EXIT
-- skip out of loop
END IF
IF wat AND i /= 0 THEN
-- only dispatch WAT at top
IF debug THEN
putline("can't dispatch it: WAT")
END IF
EXIT
END IF
-------------
-- jump out to prevent more
Check for out-of-order dependencies. I need to do all the
tests first, then go to the next slot if it's not valid, so
that I can update the flags for this slot after I've
considered the instruction. This stuff is only considered
based on non-issued instructions. The scoreboard handles
interaction between issued instructions.
tmpb1 := TRUE
-- is it valid? assume so.
IF ( pdest(dest) OR
psrc(dest) OR
( vA AND pdest(srcA) ) OR
( vB AND pdest(srcB) ) OR
( vD AND pdest(srcD) ) )
THEN
------
destination is prior dest
destination is prior source
sourceA is prior dest
sourceB is prior dest
sourceD is prior dest
IF debug THEN
putline("can't dispatch it: out-of-order dependency")
END IF
tmpb1 := FALSE
END IF
--- instructions writing to the branch queue must be sequential
2.14. DISPATCH.VHD
IF ( op_type = OP_branch OR op_type = OP_ldbr ) AND pbranch THEN
IF debug THEN
putline("can't dispatch it: prior branches")
END IF
tmpb1 := FALSE
END IF
---------
Instructions using the carry bit must be sequential. This is
a bit of cheating using the opcodes to watch for instructions
which use the carry bit. I should do this in p_dispatch, but
I'm in a hurry.
tmpv := int2v1d( iw(i).opcode )
tmpi := op2index( tmpv )
IF ( ( tmpi = 40 OR tmpi = 41 OR tmpi = 46 OR tmpi = 47 ) AND
( tmpv(8) = '1' OR tmpv(9) = '1' ) AND pcarry )
THEN
IF debug THEN
putline("can't dispatch it: prior carry")
END IF
tmpb1 := FALSE
END IF
--- also check for MEM unit dependencies
--- I can reorder loads unless I've seen a store.
IF op_type = OP_load AND pstore THEN
IF debug THEN
putline("can't dispatch it: prior stores")
END IF
tmpb1 := FALSE
END IF
--- I can't reorder stores at all.
IF ( ( op_type = OP_store OR op_type = OP_xmem ) AND
( pload OR pstore ) )
THEN
IF debug THEN
putline("can't dispatch it: prior memory instructions")
83
CHAPTER 2. VHDL SOURCE CODE
84
END IF
tmpb1 := FALSE
END IF
--- Now update the out-of-order data structures for this slot,
--- and then skip out if it's not valid.
IF dest /= 0 THEN
pdest(dest) := TRUE
IF debug THEN
putline("setting pdest ",dest)
END IF
END IF
IF vA AND srcA /= 0 THEN
psrc(srcA) := TRUE
IF debug THEN
putline("setting psrc ",srcA)
END IF
END IF
IF vB AND srcB /= 0 THEN
psrc(srcB) := TRUE
IF debug THEN
putline("setting psrc ",srcB)
END IF
END IF
IF vD AND srcD /= 0 THEN
psrc(srcD) := TRUE
IF debug THEN
putline("setting psrc ",srcD)
END IF
END IF
IF op_type = OP_branch OR op_type = OP_ldbr THEN
pbranch := TRUE
IF debug THEN
putline("setting pbranch")
END IF
END IF
IF ( ( tmpi = 40 OR tmpi = 41 OR tmpi = 46 OR tmpi = 47 ) AND
( tmpv(8) = '1' OR tmpv(9) = '1' ) )
THEN
pcarry := TRUE
IF debug THEN
putline("setting pcarry")
END IF
END IF
IF op_type = OP_load THEN
pload := TRUE
2.14. DISPATCH.VHD
85
IF debug THEN
putline("setting pload")
END IF
END IF
IF op_type = OP_store OR op_type = OP_xmem THEN
pstore := TRUE
IF debug THEN
putline("setting pstore")
END IF
END IF
NEXT WHEN NOT tmpb1
--------------------------------------------------------------------------------------------------
-- go to next IW slot
Check to see if queues are ready. I could just probe the
queues that I'm interested in, but since I might want them
all, and it's pretty likely to take longer to probe each one
as needed instead of probing them all, I'll just probe them
now.
IF NOT got_probes THEN
v_ex_p_req := NOT v_ex_p_req
-- probe EX queue
ex_p_req <= v_ex_p_req AFTER delay
v_rf_p_req := NOT v_rf_p_req
-- probe RF queue
rf_p_req <= v_rf_p_req AFTER delay
v_br_p_req := NOT v_br_p_req
-- probe BR queue (for MVBR)
br_p_req <= v_br_p_req AFTER delay
v_sb_r_r := NOT v_sb_r_r
-- read the scoreboard
sb_r_r <= v_sb_r_r AFTER delay
--- I need to wait for all four signals to acknowledge.
WAIT UNTIL ( ex_p_ack
rf_p_ack
br_p_ack
sb_r_g =
= v_ex_p_req AND
= v_rf_p_req AND
= v_br_p_req AND
v_sb_r_r )
scoreboard := sb
sb_r_d <= sb_r_g
-- grab a copy
-- unlock scoreboard
got_probes := TRUE
-- only do this once
END IF
CHAPTER 2. VHDL SOURCE CODE
86
--- Now use the queue information to determine whether I can
--- dispatch or not.
--- This is not quite right, since RTE and SYNC don't use the EX
--- queue, but those don't happen very often, especially when the
--- queue isn't ready.
IF ex_p = '0' OR done_ex_dispatch THEN -- room to issue new inst?
IF debug THEN
putline("EX queue isn't ready")
END IF
NEXT
END IF
IF ( vA OR vB OR vD ) AND rf_p = '0' THEN -- need RF operands
IF debug THEN
putline("RF queue isn't ready")
END IF
NEXT
END IF
IF op_type = OP_mvbr AND br_p = '0' THEN -- need branch target
--- Can't dispatch if there's no branch target there. It must
--- come from the normal Branch Queue, regardless of which
--- queue is active.
IF debug THEN
putline("BR queue not ready (MVBR instruction)")
END IF
NEXT
END IF
-------------
Before I check the scoreboard, see if I can reuse the last
result from a particular functional unit. I can only do this
if I haven't seen the particular destination register used as
a destination in the currently executing instructions in the
IW, so that I know that the result will be valid when I use
it.
IF reuse_result THEN
-- see where I can reuse values
2.14. DISPATCH.VHD
87
--- to which unit is this instruction going?
CASE op_type IS
WHEN OP_arith =>
-- unit 0
fu_num := OP_arith
WHEN OP_logic =>
-- unit 1
fu_num := OP_logic
WHEN OP_ctrl | OP_mvbr =>
-- unit 2
fu_num := OP_ctrl
WHEN OP_load | OP_store | OP_xmem => -- unit 3
fu_num := OP_load
WHEN OP_branch | OP_ldbr =>
-- unit 4
fu_num := OP_branch
WHEN OTHERS =>
-- not implemented
fu_num := OP_branch
-- does not latch
END CASE
--- can I use the last value that's there?
reuseA := ( vA AND srcA /= 0 AND srcA /=
NOT ldest(srcA) AND
latched_in_fu(fu_num) = srcA
reuseB := ( vB AND srcB /= 0 AND srcB /=
NOT ldest(srcB) AND
latched_in_fu(fu_num) = srcB
reuseD := ( vD AND srcD /= 0 AND srcD /=
NOT ldest(srcD) AND
latched_in_fu(fu_num) = srcD
ELSE
1 AND
)
1 AND
)
1 AND
)
-- last-result-reuse disabled
reuseA := FALSE
reuseB := FALSE
reuseD := FALSE
END IF
--- Modify vA, vB, vD according to reuse policy, since these are
--- used to request operands. I can ignore scoreboard conflicts
--- if I'm reusing the last result for that operand.
zeroA := skip_r0_ops AND vA AND (srcA = 0)
vA := vA AND NOT reuseA AND NOT zeroA
vB := vB AND NOT reuseB
vD := vD AND NOT reuseD
--- Now check scoreboard conflicts.
IF ( (vA AND scoreboard(srcA)='1') OR
(vB AND scoreboard(srcB)='1') OR
CHAPTER 2. VHDL SOURCE CODE
88
(vD AND scoreboard(srcD)='1') OR
scoreboard(dest)='1' )
-- also prevent WAW
THEN
IF debug THEN
putline("can't dispatch it: scoreboard")
END IF
NEXT
END IF
--- If I get this far, then the current instruction is a valid
--- one to dispatch. The only thing that could prevent dispatch
--- is if I don't allow out-of-order issue.
--- See if I'm allowed to issue out-of-order.
tmpi := i - icount
IF tmpi > 0 THEN
-- out-of-order distance
IF NOT out_of_order THEN
IF debug THEN
putline("can't dispatch it: no out-of-order")
END IF
EXIT
END IF
--- Okay, everything is ready.
Gather some stats on it.
s_iw_ooo_count := s_iw_ooo_count + 1
s_iw_ooo_total := s_iw_ooo_total + tmpi
IF tmpi > s_iw_ooo_max THEN
s_iw_ooo_max := tmpi
END IF
END IF
IF debug THEN
putline("Found a dispatchable instruction in IW slot ",i)
END IF
--- remember destination reg & unit for reuse later
IF ( reuse_result AND
dest /= 0 AND dest /= 1 )
THEN
FOR k IN 0 TO 4 LOOP
-- enabled
-- valid register
-- valid destination to latch
2.14. DISPATCH.VHD
89
IF latched_in_fu(k) = dest THEN -- found it somewhere else
latched_in_fu(k) := 0
END IF
END LOOP
latched_in_fu(fu_num) := dest
-- remember who has it
END IF
--- gather some more statistics
IF zeroA THEN
IF (NOT vB) AND (NOT vD) THEN
s_zeroA := s_zeroA + 1
END IF
-- just count useful ones
IF debug THEN
putline("zeroA")
END IF
END IF
IF reuseA OR reuseB OR reuseD THEN
s_reuse_result := s_reuse_result + 1 -- could reuse result
IF ( (reuseA AND scoreboard(srcA)='1') OR
(reuseB AND scoreboard(srcB)='1') OR
(reuseD AND scoreboard(srcD)='1') )
THEN
s_reuse_helps := s_reuse_helps + 1 -- it actually helps
END IF
IF debug OR debug_reuse THEN
putline("reuseA is ",reuseA)
putline("reuseB is ",reuseB)
putline("reuseD is ",reuseD)
END IF
END IF
found_one := TRUE
iw_index := i
EXIT
END LOOP
-- hop out and dispatch it
-- end of look-for-instruction
--- If I have something to dispatch, the loop below does the
--- dispatch, but doesn't actually loop. It just provides a
--- convenient way to abort for any reason.
CHAPTER 2. VHDL SOURCE CODE
90
WHILE found_one LOOP
---------
-- iw_index says which one
Now, do different things, depending on the instruction. Some
are executed entirely in this module, and are not actually
dispatched through external queues. DOITs are handled later,
and should no longer appear in the IW at all.
IF op_type = OP_rte THEN
-- rte instruction
IF trace_dispatch THEN
put("Dispatch IW(",iw_index)
put("/",icount)
puthex("): op ",iw(iw_index).opcode)
puthex(" addr ",iw(iw_index).address)
putline(" RTE")
END IF
IF debug THEN
putline("type OP_rte. restore status")
END IF
--- The RTE instruction is replaced by the new IW contents, so
--- it doesn't need to be removed explicitly.
--- restore internal counters and flags
-----------
The queue counts are NOT updated, since they should always
be accurate. They are only provided so that the handler can
empty the R1 Queue and Branch Queues. Loading these queues
is visible by the dispatch unit, since it is done with
normal instructions.
pc
:= cr(ICR_Next_PC)
iw_bottom := cr(ICR_IW_Count)
IF iw_bottom > IW_tap THEN
iw_bottom := IW_tap
END IF
IF debug THEN
putline(" IW_Count = ",iw_bottom)
END IF
single_flag
wat_flag
tag_value
:= FALSE
:= FALSE
:= 0
-- RTE set it, so clear it
-- RTE set it, so clear it
--- out_count should be zero, since RTE is WAT and SINGLE
---------
The tag_scoreboard should already be clear, since we've now
heard from every outstanding instruction. The register
scoreboard may not be clear, but it can take care of
itself. Since we clear the destination bit for faulty
2.14. DISPATCH.VHD
91
--- instructions, it will eventually clear.
-----------------
Reload IW with all non-issued instructions. Note that
although this sets the single_flag appropriately, it does
NOT insert implicit DOIT instructions. If the IW was saved
from a previous thread, it should already have the DOIT in
there. Otherwise, if you want a DOIT, you have to put it in
yourself via software. Be careful, though. Because DOITs
are SINGLE instructions, having more than one in the IW at
a time can cause a LOT of confusion.
FOR k IN 0 TO iw_bottom - 1 LOOP
iw(k).valid := TRUE
iw(k).address := siw(IW_CRNUM*k+IF_SIW_Min+IW_CR_ADDR)
iw(k).opcode := siw(IW_CRNUM*k+IF_SIW_Min+IW_CR_OPCD)
iw(k).wat := FALSE
iw(k).single := FALSE
tmpv := int2v1d( iw(k).opcode ) -- IDIOTIC ViewLogic crap
IF is_single( tmpv ) THEN
iw(k).single := TRUE
single_flag := TRUE
END IF
iw(k).issued := FALSE
iw(k).status := STATUS_none
IF debug THEN
putline("IW slot ",k)
put(" valid = ",iw(k).valid)
put(" issued = ",iw(k).issued)
putline(" tag = ",iw(k).tag)
puthexline(" status = ",iw(k).status)
puthexline(" address = ",iw(k).address)
puthexline(" opcode = ",iw(k).opcode)
END IF
END LOOP
FOR k IN iw_bottom TO IW_Max - 1 LOOP
iw(k).valid := FALSE
END LOOP
--- Now replace CR0 with the Saved Control value
cr0 := int2v1d( cr(ICR_Saved_Control) )
x_cr0 <= cr0
IF cr0(Doit) = '1' THEN
single_flag := TRUE
END IF
IF debug THEN
puthexline(" CR0 = ",cr(ICR_Saved_Control))
puthexline("pc is now ",pc)
putline("single_flag is now ",single_flag)
tmpb1 := vlb2boo( cr0(Doit) ) -- stupid Viewlogic crap
CHAPTER 2. VHDL SOURCE CODE
92
putline("doit_flag is now ",tmpb1)
END IF
--- That's it. The RTE has been replaced by the new IW
--- contents, and everything is ready to continue dispatching.
--- The SINGLE flag has been cleared if appropriate.
---------
Now, I need to go back and try to dispatch all over again.
Since the RTE was the only remaining instruction in the IW
when I started, there's no external event to wake up the
dispatch cycle again. I'll have to generate one.
try_dispatch := TRUE
done_dispatch := FALSE
EXIT
-- do it again
-- don't count RTE
-- hop out of dispatch loop
delay_to_use := delay_to_use + delay_rte -- time to do RTE
s_did_dispatch := s_did_dispatch + 1 -- count it
ELSIF op_type = OP_sync THEN
-- sync instruction
IF trace_dispatch THEN
put("Dispatch IW(",iw_index)
put("/",icount)
puthex("): op ",iw(iw_index).opcode)
puthex(" addr ",iw(iw_index).address)
putline(" SYNC")
END IF
--- This is complete, just by getting to the top. Remove it
--- from the IW. Doesn't affect queue counts. It takes
--- essentially no extra time.
tmpi := iw_index
iw_remove( tmpi, iw, iw_bottom, wat_flag, single_flag )
IF debug THEN
putline("type OP_sync. Done by default.")
putline("wat_flag is now ",wat_flag)
putline("single_flag is now ",single_flag)
END IF
s_did_dispatch := s_did_dispatch + 1 -- count it
ELSIF op_type = OP_sync_x THEN
-- sync.x instruction
IF trace_dispatch THEN
put("Dispatch IW(",iw_index)
put("/",icount)
puthex("): op ",iw(iw_index).opcode)
2.14. DISPATCH.VHD
93
puthex(" addr ",iw(iw_index).address)
putline(" SYNC.X")
END IF
--- Wait for external sync. Not interruptible.
--- Doesn't affect queue counts.
Is that bad?
IF debug THEN
putline("type OP_sync_x")
END IF
v_sync_req := NOT v_sync_req
sync_req <= v_sync_req AFTER delay_to_use
WAIT ON sync_ack, sync_nack
-- might work, might not
s_did_dispatch := s_did_dispatch + 1 -- either way it counts
IF sync_ack'EVENT THEN
-- did it
--- Done. Remove this instruction from the IW.
tmpi := iw_index
iw_remove( tmpi, iw, iw_bottom, wat_flag, single_flag )
IF debug THEN
putline("done with SYNC.X")
putline("wat_flag is now ",wat_flag)
putline("single_flag is now ",single_flag)
END IF
delay_to_use := delay_sync_ack
ELSE
-- didn't sync
IF debug THEN
putline("SYNC.X failed.")
END IF
iw(iw_index).status := STATUS_sync
faulting_instruction := iw(iw_index) -- remember who did it
IF v_fault_pending = '0' THEN -- need to signal fault
v_fault_pending := '1'
-- do so
fault_pending <= v_fault_pending
v_x_debug := NOT v_x_debug
x_debug <= v_x_debug
END IF
delay_to_use := delay_sync_nack
END IF
CHAPTER 2. VHDL SOURCE CODE
94
ELSE
-- any other instruction
IF debug THEN
putline("type OP_other")
END IF
---------------------------
Pick tag to assign to instruction. Note: It's possible to
issue enough instructions that a tag would be reused before
its first use has completed. For example, an instruction
which uses R1 as a destination might take a VERY long time
to get the result while a large number of much faster
instructions complete. This could be a problem, unless some
means of determining tag usage is provided. For the
simulator, I'm just going to use a scoreboard to keep track
of 8-bit tags, and if I can't find a free tag it means that
I can't dispatch. In a real implementation I might use a
different method (I really only need the same number of
unique tags as there are slots in the IW, so a unary
encoding would do).
--- But wait! If the instruction doesn't report its DONE
--- status, then I don't need to assign it a tag, because I'll
--- remove it from the IW as soon as it goes out.
---------------------------
I had to modify the tag meaning slightly. Originally, all
branch instructions simply used the current value of
cr0(Excp_Enable) to determine which Branch queue to place
the target in. However, branch instructions do not fault,
so if an interrupt is noticed after the branch has been
issued but before it has completed, the target goes down
the wrong pipe. Rather than add another bit to the
existing FIFOs, I just modified the tag value so that bit 7
is used to indicate the queue in use when the instruction
was issued. This doesn't affect the memory unit since it
always has to report its status and the dispatch unit will
wait for it to do so before handling exceptions. Only the
branch unit uses the new tag bit for anything.
IF tellme
THEN
-- assign tags
tag_value := tag_value + 1
IF tag_value > Tag_Max_Value THEN
tag_value := 0
END IF
IF tag_sb(tag_value) THEN
-- this tag is still in use
--- try to find one that's not being used
FOR j IN 1 TO Tag_Max_Value LOOP
2.14. DISPATCH.VHD
95
tmpi := j + tag_value
-- determine tag to try
IF tmpi > Tag_Max_Value THEN
tmpi := tmpi - Tag_Max_Value
END IF
IF NOT tag_sb(tmpi) THEN
tag_value := tmpi
EXIT
END IF
-- if free, use it
END LOOP
--- if tag_sb(tag_value) is false, there are no free tags!
ASSERT NOT tag_sb(tag_value) REPORT "Tag" SEVERITY FAILURE
END IF
-- finding tag
tag_sb(tag_value) := TRUE
-- mark tag in use
END IF
-- assigning tag
--- We got a tag, so let's dispatch the instruction.
iw(iw_index).tag := tag_value
iw(iw_index).issued := TRUE
-- only needed if tellme=TRUE
-- ditto
IF op_type = OP_mvbr THEN
-- need branch target
tmpmvbr := br
v_br_ack := NOT v_br_ack
br_ack <= v_br_ack
-- grab branch target data
-- eat branch target from queue
-- ack branch data
IF trace_dispatch THEN
put("Dispatch IW(",iw_index)
put("/",icount)
puthex("): op ",iw(iw_index).opcode)
puthex(" addr ",iw(iw_index).address)
putline(" MVBR")
END IF
ELSE
IF trace_dispatch THEN
put("Dispatch IW(",iw_index)
put("/",icount)
puthex("): op ",iw(iw_index).opcode)
puthexline(" addr ",iw(iw_index).address)
END IF
END IF
CHAPTER 2. VHDL SOURCE CODE
96
IF ( ( debug OR debug_reuse ) AND
reuse_result AND dest /= 0 AND dest /= 1 )
THEN
put("unit ",fu_num)
putline(" will latch register ",dest)
END IF
---------
The operand requests and scoreboard
quickly, since this information was
we were checking for scoreboard for
The instruction information is what
IF dest >= 1 THEN
setting can go out
determined earlier when
dispatch conditions.
takes additional time.
-- set scoreboard bit
IF debug THEN
putline("setting scoreboard bit ",dest)
END IF
sb_set <= '1'
tmpv := int2v1d( dest )
-- IDIOTIC ViewLogic crap
sb_num <= tmpv(4 DOWNTO 0)
v_sb_w_r := NOT v_sb_w_r
sb_w_r <= v_sb_w_r AFTER delay_to_use
WAIT ON sb_w_a
END IF
s_did_dispatch := s_did_dispatch + 1
IF cr0(Excp_Enable) = '0' THEN -- only count in exceptions
s_excp_dispatch := s_excp_dispatch + 1
END IF
IF vA OR vB OR vD THEN
-- send operand request to RF
s_need_operands := s_need_operands + 1
v_rf := rf_encode( vA, srcA, vB, srcB, vD, srcD )
rf <= v_rf
v_rf_req := NOT v_rf_req
rf_req <= v_rf_req AFTER delay_to_use
--- I know it's ready, so I don't have to wait for the ACK
END IF
IF wat THEN
-- also wat_flag if applicable
wat_flag := TRUE
IF debug THEN
putline("wat_flag is now ",wat_flag)
END IF
END IF
2.14. DISPATCH.VHD
br_count := new_br_count
xbr_count := new_xbr_count
r1_count := new_r1_count
r1_pending := new_r1_pending
97
-- update queue counts
-- this only decrements
-- this only increments
IF debug THEN
putline("br_count is now ",br_count)
putline("xbr_count is now ",xbr_count)
putline("r1_count is now ",r1_count)
putline("r1_pending is now ",r1_pending)
END IF
--- Send dispatch information
ex <= EX_PADDING
-- clear all bits first
ex(90) <= boo2vlb( zeroA )
--- bits 89-87 are operand reuse bits
ex(89) <= boo2vlb( reuseD )
ex(88) <= boo2vlb( reuseB )
ex(87) <= boo2vlb( reuseA )
--- bit 86 is set if instruction should report DONE status
IF tellme THEN
ex(86) <= '1'
out_count := out_count + 1
-- I might have to wait for it
IF debug THEN
putline("now out_count = ",out_count)
putline("tag = ",iw(iw_index).tag)
END IF
ELSE
ex(86) <= '0'
END IF
--- bit 85 is set if operands are needed from the RF Unit
IF vA OR vB OR vD THEN
ex(85) <= '1'
ELSE
ex(85) <= '0'
END IF
--- bit 76 is part of the tag field containing the current
--- value of cr0(Excp_Enable) but only for branch unit, so set
--- the default now.
ex(76) <= '0'
--- bits 84-77 are select lines for functional units
CASE op_type IS
WHEN OP_arith =>
-- unit 0
ex(84 DOWNTO 77) <= ('0','0','0','0','0','0','0','1')
CHAPTER 2. VHDL SOURCE CODE
98
WHEN OP_logic =>
-- unit 1
ex(84 DOWNTO 77) <= ('0','0','0','0','0','0','1','0')
WHEN OP_ctrl | OP_mvbr =>
-- unit 2
ex(84 DOWNTO 77) <= ('0','0','0','0','0','1','0','0')
WHEN OP_load | OP_store | OP_xmem => -- unit 3
ex(84 DOWNTO 77) <= ('0','0','0','0','1','0','0','0')
WHEN OP_branch | OP_ldbr =>
-- unit 4
ex(84 DOWNTO 77) <= ('0','0','0','1','0','0','0','0')
--- bit 76 is current value of cr0(Excp_Enable)
ex(76) <= cr0(Excp_Enable)
WHEN OTHERS =>
-- not implemented
ex(84 DOWNTO 77) <= ('0','0','0','0','0','0','0','0')
END CASE
--- bits 75-69 are for instruction tag
tmpv := int2v1d(tag_value)
ex(75 DOWNTO 69) <= tmpv(6 DOWNTO 0)
--- bits 68-64 is destination register (not always valid)
tmpv := int2v1d(dest)
ex(68 DOWNTO 64) <= tmpv(4 DOWNTO 0)
--- bits 63-32 are usually PC, but may hold Branch Queue data
IF op_type = OP_mvbr THEN
ex(63 DOWNTO 32) <= tmpmvbr
ELSE
ex(63 DOWNTO 32) <= int2v1d( iw(iw_index).address )
END IF
--- bits 31-0 are original opcode
ex(31 DOWNTO 0) <= int2v1d( iw(iw_index).opcode )
v_ex_req := NOT v_ex_req
ex_req <= v_ex_req AFTER delay_to_use
done_ex_dispatch := TRUE
IF debug THEN
putline("instruction dispatched")
END IF
--- If the instruction isn't going to report its DONE status,
--- then I need to remove it from the IW now, because otherwise
--- it will never happen.
IF NOT tellme THEN
-- remove it
tmpi := iw_index
iw_remove( tmpi, iw, iw_bottom, wat_flag, single_flag )
IF debug THEN
putline("instruction won't report -- removed from IW")
END IF
2.14. DISPATCH.VHD
99
END IF
END IF
-----------
-- any other instruction
Now, I've dispatched one instruction. I can't do more than
one at a time, so I should quit the loop. I don't really
need the loop at all once I've found a potential instruction,
but it's convenient as a way to abort the whole dispatch
process.
done_dispatch := TRUE
-- done one
EXIT
-- hop out of dispatch loop
END LOOP
END IF
-- dispatching loop
-- can I even try to dispatch
IF debug THEN
putline("done with this event")
END IF
END IF
-----------
-- dispatch_req
Now I should try to consume a DOIT, if there's one pending.
Obviously, I can't do this if faults are pending or I'm otherwise
prevented. I don't have to do this in any particular order. This
isn't really a loop, it's just a convenient way to jump out if I
want to.
WHILE ( cr0(Doit) = '1' AND
v_fault_pending = '0' )
LOOP
-----------------
Check for deadlock condition. If the Doit flag is set, no
the IW is empty and nothing is in the Branch Queue, then I'm
waiting for a branch that will never arrive. Note that I won't
notice deadlock at the same time that I notice external
interrupts, since there is only one status register to indicate
the cause of the exception. However, when handling any other
exception, this deadlock condition can be detected by software
by checking for the same conditions.
IF ( iw_bottom = 0 AND
( (cr0(Excp_Enable) = '1' AND br_count = 0) OR
(cr0(Excp_Enable) = '0' AND xbr_count = 0) ) )
THEN
faulting_instruction := doit_instruction
faulting_instruction.status := STATUS_lock_b0
CHAPTER 2. VHDL SOURCE CODE
100
v_fault_pending := '1'
-- do so
fault_pending <= v_fault_pending
v_x_debug := NOT v_x_debug
x_debug <= v_x_debug
IF trace_excp THEN
putline("deadlock exception")
END IF
EXIT
-- jump out
END IF
IF cr0(Excp_Enable) = '1' THEN
-- use normal Branch Queue
IF debug THEN
putline("Probing BR queue")
END IF
----------
v_br_p_req := NOT v_br_p_req
br_p_req <= v_br_p_req AFTER delay
WAIT ON br_p_ack
IF br_p = '0' THEN
IF debug THEN
putline("BR queue isn't ready")
END IF
EXIT
END IF
IF br(1) = '1' THEN
-- if condition code
pc := 4 * v1d2int(br(31 DOWNTO 2)) -- take branch
END IF
v_br_ack := NOT v_br_ack
br_ack <= v_br_ack
-- eat branch target from queue
-- ack branch data
br_count := br_count - 1
ELSE
-- use X Branch Queue
IF debug THEN
putline("Probing XBR queue")
END IF
----------
v_xbr_p_req := NOT v_xbr_p_req
xbr_p_req <= v_xbr_p_req AFTER delay
WAIT ON xbr_p_ack
IF xbr_p = '0' THEN
2.14. DISPATCH.VHD
101
IF debug THEN
putline("XBR queue isn't ready")
END IF
EXIT
END IF
IF xbr(1) = '1' THEN
-- if condition code
pc := 4 * v1d2int(xbr(31 DOWNTO 2)) -- take branch
END IF
v_xbr_ack := NOT v_xbr_ack -- eat branch target from queue
xbr_ack <= v_xbr_ack
-- ack branch data
xbr_count := xbr_count - 1
END IF
-- done consuming targets
IF debug THEN
puthexline("PC is now ",pc)
END IF
--- Done. Clear the Doit and single flags, and let a new
--- instruction be requested.
cr0(Doit) := '0'
single_flag := FALSE
IF debug THEN
putline("Did a DOIT")
putline("single_flag is now ",single_flag)
putline("br_count is now ",br_count)
putline("xbr_count is now ",xbr_count)
END IF
IF trace_dispatch THEN
put("Dispatch IW(-/-): ")
puthex("op ",doit_instruction.opcode)
puthex(" addr ",doit_instruction.address)
putline(" DOIT")
END IF
EXIT
-- exit the loop now
END LOOP
-- looking for DOITs
-----------
Deal with faults. If a fault has been signaled, all outstanding
instructions must either complete or fault. Deadlock cannot
occur, since we prevent that by counting producer/consumer pairs
as they are dispatched. We don't have to lock the IW data
structures, since we won't do anything until the entire chip is
CHAPTER 2. VHDL SOURCE CODE
102
--- quiescent, and therefore we are the only ones using the IW.
IF v_fault_pending = '1' THEN
-- do nothing until all done
IF debug THEN
putline("fault is pending. sit and wait")
putline("out_count = ",out_count)
END IF
---------------
Wait until we've heard from all outstanding instructions, then do
interrupt handling stuff. I don't have to worry that all results
have arrived at their destinations, provided I know that all
instructions have completed. Anything that needs the results will
just have to wait for them. I do have to wait for any
outstanding instruction fetches, since those have to be put in
the IW.
IF ( out_count = 0 AND NOT waiting_for_inst ) THEN
s_did_excp := s_did_excp + 1
IF debug THEN
putline("everything has stopped. save status")
END IF
IF trace_excp THEN
putline("iw_bottom = ",iw_bottom)
putline("br_count = ",br_count)
putline("r1_count = ",r1_count)
END IF
--- clear IW, WAT, SINGLE, scoreboard, etc.
tmpi := 0
FOR i IN 0 TO (IW_Max - 1) LOOP
-- save (internal) and clear IW
IF iw(i).valid AND iw(i).status /= STATUS_none THEN
tmpi := tmpi + 1
END IF
siw(IW_CRNUM*i+IF_SIW_Min+IW_CR_STAT)
siw(IW_CRNUM*i+IF_SIW_Min+IW_CR_ADDR)
siw(IW_CRNUM*i+IF_SIW_Min+IW_CR_OPCD)
siw(IW_CRNUM*i+IF_SIW_Min+IW_CR_ARG1)
siw(IW_CRNUM*i+IF_SIW_Min+IW_CR_ARG2)
iw(i).valid := FALSE
:=
:=
:=
:=
:=
iw(i).status
iw(i).address
iw(i).opcode
iw(i).arg1
iw(i).arg2
IF debug THEN
putline("IW slot ",i)
put(" valid = ",iw(i).valid)
put(" issued = ",iw(i).issued)
putline(" tag = ",iw(i).tag)
puthexline(" status = ",iw(i).status)
puthexline(" address = ",iw(i).address)
2.14. DISPATCH.VHD
puthexline("
puthexline("
puthexline("
END IF
103
opcode = ",iw(i).opcode)
arg1 = ",iw(i).arg1)
arg2 = ",iw(i).arg2)
END LOOP
-----------
Save exception status in (internal) control registers.
The r1_count and br_count values are needed to know how to
empty and save the R1 and Branch Queues. This is done with
normal instructions, so the counts do not need to be reloaded
when the exception is over.
cr(ICR_Saved_Control) := v1d2int(cr0)
cr(ICR_Fault_Status) := faulting_instruction.status
cr(ICR_Fault_Address) := faulting_instruction.address
cr(ICR_Next_PC)
:= pc
cr(ICR_BR_Count)
:= br_count
cr(ICR_R1_Count)
:= r1_count
cr(ICR_IW_Count)
:= iw_bottom
cr(ICR_IW_Faults)
:= tmpi
IF debug THEN
puthexline(" ICR_Saved_Control = ",cr(ICR_Saved_Control))
puthexline(" ICR_Fault_Status = ",cr(ICR_Fault_Status))
puthexline(" ICR_Fault_Address = ",cr(ICR_Fault_Address))
puthexline(" ICR_Next_PC = ",cr(ICR_Next_PC))
putline(" ICR_BR_Count = ",cr(ICR_BR_Count))
putline(" ICR_R1_Count = ",cr(ICR_R1_Count))
putline(" ICR_IW_Count = ",cr(ICR_IW_Count))
putline(" ICR_IW_Faults = ",cr(ICR_IW_Faults))
END IF
iw_bottom := 0
-- IW is now empty
FOR i IN 0 TO Tag_Max_Value LOOP
tag_sb(i) := FALSE
END LOOP
-- clear the tag scoreboard
wat_flag := FALSE
single_flag := FALSE
tag_value := 0
out_count := 0
--- turn off interrupts, exceptions, etc.
--- Excp_Enable bit controls queue
--- set supervisor mode.
tmpv := ZERO(31 DOWNTO 0)
tmpv(Supervisor) := '1'
cr0 := tmpv
x_cr0 <= cr0
-- change CR0
CHAPTER 2. VHDL SOURCE CODE
104
--- clear fault_pending after interrupts are disabled
v_fault_pending := '0'
fault_pending <= v_fault_pending AFTER delay
--- If exceptions were already disabled, take error vector.
tmpv := int2v1d( cr(ICR_Saved_Control) ) -- convert to vlbit
IF tmpv(Excp_Enable) = '0' THEN
faulting_instruction.status := STATUS_error
END IF
--- Set PC to interrupt handler address. Each exception vector
--- has four status values available to it, so the status code
--- can be truncated to determine the vector address.
tmpv :=
tmpi :=
IF tmpi
pc :=
ELSE
pc :=
END IF
int2v1d(faulting_instruction.status)
v1d2int(tmpv(15 DOWNTO 0)) -- get major status
>= STATUS_trap THEN
4 * v1d2int( tmpv( 7 DOWNTO 0) )
4 * v1d2int( tmpv( 7 DOWNTO 2) )
--- Now everything is ready to go. Let INST_REQ go out below.
IF debug OR trace_dispatch THEN
puthexline("faulting status is ",faulting_instruction.status)
puthexline("ready for vector. PC is now ",pc)
END IF
--- We can just sit and wait here, since nothing else should be
--- going on anyway.
WAIT FOR delay_save_state
END IF
END IF
-----------
-- time to save state
-- outstanding insts
-- fault pending
Send out a request for more instructions to dispatch. If there's
a fault pending, we don't request any new instructions until the
PC has been set to the exception handler. Otherwise, if there's
room for another instruction in the IW, and the SINGLE flag isn't
set, and we haven't already, then request the next instruction.
IF v_fault_pending = '1' THEN
-- skip back to top of loop
IF debug THEN
putline("no inst reqs while faults are pending")
2.14. DISPATCH.VHD
105
END IF
NEXT
END IF
IF ((IW_tap - iw_bottom) >= 1 ) AND NOT single_flag THEN
IF waiting_for_inst THEN
-- skip back to top of loop
IF debug THEN
putline("already requested an instruction")
END IF
NEXT
END IF
v_i_addr := int2v1d(pc)
-- get 32-bit PC value
i_addr <= (v_i_addr(31 DOWNTO 2) & cr0(Supervisor) & '0')
v_inst_req := NOT v_inst_req
inst_req <= v_inst_req AFTER delay
IF debug THEN
puthexline("sent out INST_REQ for address ",pc)
END IF
waiting_for_inst := TRUE
END IF
END LOOP
END IF
-----------
-- main process loop
-- CLR not asserted
Wait for something new to happen. The four main events are arbitrated,
so that data structures can be shared. The control register requests do
not need arbitration, since control registers are only written when
everything else is quiet. The other events just awaken the dispatch
process.
IF debug THEN
putline("wait for something to happen")
END IF
WAIT ON clr, inst_ack, done_req, external_int, getcr_req,
putcr_req, br_p, xbr_p, rf_p, ex_p, sb
END PROCESS main
END behavior
CHAPTER 2. VHDL SOURCE CODE
106
2.15 logic unit.vhd
USE work.p_constants.ALL
USE work.p_output.ALL
---- This unit handles the logic instructions. Currently, there is only
---- one of these units, and it is very simple. It could be expanded to do
---- split transactions, reordering memory operations, etc.
----------------------
The EXTRA input was added to provide last-result-reuse and to elminate
zero values of op_a for immediate instructions. The bit usage is:
EXTRA(0)
EXTRA(1)
EXTRA(2)
EXTRA(3)
=
=
=
=
reuseA
reuseB
reuseD
zeroA (unused)
ENTITY logic_unit IS
GENERIC( delay: TIME := 100 ps )
PORT( SIGNAL clr
: IN
SIGNAL rin
: IN
SIGNAL ain
: OUT
SIGNAL tellme
: IN
SIGNAL tag
: IN
SIGNAL dest
: IN
SIGNAL opcode
: IN
SIGNAL op_a
: IN
SIGNAL op_b
: IN
SIGNAL d_req
: OUT
SIGNAL d_ack
: IN
SIGNAL done
: OUT
SIGNAL rout
: OUT
SIGNAL aout
: IN
SIGNAL res
: OUT
SIGNAL rq_req
: OUT
SIGNAL rq_ack
: IN
SIGNAL rq
: OUT
SIGNAL extra
: IN
END logic_unit
VLBIT
VLBIT
VLBIT
VLBIT
VLBIT_1D
VLBIT_1D
VLBIT_1D
VLBIT_1D
VLBIT_1D
VLBIT
VLBIT
VLBIT_1D
VLBIT
VLBIT
VLBIT_1D
VLBIT
VLBIT
VLBIT_1D
VLBIT_1D
(7 DOWNTO 0)
(4 DOWNTO 0)
(31 DOWNTO 0)
(31 DOWNTO 0)
(31 DOWNTO 0)
(87 DOWNTO 0)
(36 DOWNTO 0)
(31 DOWNTO 0)
(3 DOWNTO 0) )
ARCHITECTURE behavior OF logic_unit IS
BEGIN
main : PROCESS
VARIABLE debug
: BOOLEAN := FALSE
--- factors affecting response time
VARIABLE delay_boolean
VARIABLE delay_barrel
VARIABLE delay_ff
: TIME := 100 ps -- boolean operations
: TIME := 100 ps -- need barrel shifter
: TIME := 100 ps -- find first bit stuff
2.15. LOGIC UNIT.VHD
VARIABLE delay_to_use
107
: TIME
-- scratch for culumative time
--- output variables
VARIABLE v_rout
VARIABLE v_rq_req
VARIABLE v_d_req
: VLBIT
: VLBIT
: VLBIT
--- internal variables
VARIABLE index
: INTEGER
VARIABLE
VARIABLE
VARIABLE
VARIABLE
VARIABLE
VARIABLE
:
:
:
:
:
:
Av
Bv
Wi
Oi
result
lastresult
VLBIT_1D
VLBIT_1D
INTEGER
INTEGER
VLBIT_1D
VLBIT_1D
(31 DOWNTO 0)
(31 DOWNTO 0)
(31 DOWNTO 0)
(31 DOWNTO 0)
--- scratch variables
VARIABLE tmpv
VARIABLE tmpb
VARIABLE tmpi
: VLBIT_1D (31 DOWNTO 0)
: VLBIT
: INTEGER
--- statistics
VARIABLE s_logic_rin
VARIABLE s_barrel
VARIABLE s_ff
: INTEGER
: INTEGER
: INTEGER
BEGIN
--- If clear is asserted, reset everything and stick here.
IF clr /= '1' THEN
v_rout := '0'
v_rq_req := '0'
v_d_req := '0'
ain <= '0'
d_req <= v_d_req
done <= ZERO(87 DOWNTO 0)
rout <= v_rout
res <= ZERO(36 DOWNTO 0)
rq_req <= v_rq_req
rq <= ZERO(31 DOWNTO 0)
-- reset to beginning
CHAPTER 2. VHDL SOURCE CODE
108
s_logic_rin := 0
s_barrel := 0
s_ff := 0
WAIT UNTIL clr = '1'
ELSE
---------
-- only wakeup event is RIN
This stuff had to be encoded by hand. I could have written a Perl
script to do it, but it would have taken longer than doing it
manually. This stuff shouldn't change that much (I hope). I also made
some assumptions about unused bits, which is probably okay.
--- I don't bother to compute anything if I'm just going to throw the
--- result away.
IF dest /= REG_R0 THEN
-- only if worth doing
s_logic_rin := s_logic_rin + 1
delay_to_use := delay_boolean
-- assume simple case
index := op2index( opcode )
-- identify instruction
--- determine operands
IF extra(0)='1' THEN
Av := lastresult
ELSE
Av := op_a
END IF
IF index <= 31 OR (index >= 72 AND index <= 77) THEN -- immediate
--- All Immediate operands are zero-extended (this could change).
Bv := ZERO(31 DOWNTO 16) & opcode(15 DOWNTO 0)
ELSE
-- triadic
IF extra(1)='1' THEN
Bv := lastresult
ELSE
Bv := op_b
END IF
END IF
IF debug THEN
tmpi := v1d2int(Av)
puthexline("op_a is ",tmpi)
tmpi := v1d2int(Bv)
puthexline("op_b is ",tmpi)
END IF
2.15. LOGIC UNIT.VHD
109
--- get W and O fields just in case.
Wi := v1d2int( Bv(9 DOWNTO 5) )
IF Wi = 0 THEN
Wi := 32
END IF
Oi := v1d2int( Bv(4 DOWNTO 0) )
--- now, do the operation
CASE index IS
WHEN 0 =>
-- and rd,ra,imm16
tmpv := Av AND Bv
result := Av(31 DOWNTO 16) & tmpv(15 DOWNTO 0)
WHEN 1 =>
-- and.u rd,ra,imm16
Bv := Bv(15 DOWNTO 0) & Bv(15 DOWNTO 0)
tmpv := Av AND Bv
result := tmpv(31 DOWNTO 16) & Av(15 DOWNTO 0)
WHEN 2 =>
-- mask rd,ra,imm16
tmpv := Av AND Bv
result := ZERO(31 DOWNTO 16) & tmpv(15 DOWNTO 0)
WHEN 3 =>
-- mask.u rd,ra,imm16
Bv := Bv(15 DOWNTO 0) & Bv(15 DOWNTO 0)
tmpv := Av AND Bv
result := tmpv(31 DOWNTO 16) & ZERO(15 DOWNTO 0)
WHEN 4 =>
-- or rd,ra,imm16
tmpv := Av OR Bv
result := Av(31 DOWNTO 16) & tmpv(15 DOWNTO 0)
WHEN 5 =>
-- or.u rd,ra,imm16
Bv := Bv(15 DOWNTO 0) & Bv(15 DOWNTO 0)
tmpv := Av OR Bv
result := tmpv(31 DOWNTO 16) & Av(15 DOWNTO 0)
WHEN 6 =>
-- xor rd,ra,imm16
tmpv := Av XOR Bv
result := Av(31 DOWNTO 16) & tmpv(15 DOWNTO 0)
WHEN 7 =>
-- xor.u rd,ra,imm16
CHAPTER 2. VHDL SOURCE CODE
110
Bv := Bv(15 DOWNTO 0) & Bv(15 DOWNTO 0)
tmpv := Av XOR Bv
result := tmpv(31 DOWNTO 16) & Av(15 DOWNTO 0)
WHEN 32 =>
-- and rd,ra,rb
result := Av AND Bv
WHEN 33 =>
-- and.c rd,ra,rb
result := Av AND NOT Bv
WHEN 36 =>
-- or rd,ra,rb
result := Av OR Bv
WHEN 37 =>
-- or.c rd,ra,rb
result := Av OR NOT Bv
WHEN 38 =>
-- xor rd,ra,rb
result := Av XOR Bv
WHEN 39 =>
-- xor.c rd,ra,rb
result := Av XOR NOT Bv
WHEN 64 | 72 =>
-- clr
s_barrel := s_barrel + 1
delay_to_use := delay_barrel
FOR k IN 0 TO 31
IF k >= Oi AND
result(k) :=
ELSE
result(k) :=
END IF
END LOOP
LOOP
k < (Oi + Wi) THEN
'0'
-- in range
Av(k)
WHEN 65 | 73 =>
-- set
s_barrel := s_barrel + 1
delay_to_use := delay_barrel
FOR k IN 0 TO 31
IF k >= Oi AND
result(k) :=
ELSE
result(k) :=
END IF
LOOP
k < (Oi + Wi) THEN
'1'
Av(k)
-- in range
2.15. LOGIC UNIT.VHD
111
END LOOP
WHEN 66 | 74 =>
-- ext
s_barrel := s_barrel + 1
delay_to_use := delay_barrel
tmpi := Wi + Oi - 1
IF tmpi > 31 THEN
tmpb := Av(31)
ELSE
tmpb := Av(tmpi)
END IF
FOR k IN 0 TO 31 LOOP
IF k < Wi AND k+Oi <= 31 THEN
result(k) := Av(k+Oi)
ELSE
result(k) := tmpb
END IF
END LOOP
WHEN 67 | 75 =>
-- determine sign bit
-- copy sign bit
-- extu
s_barrel := s_barrel + 1
delay_to_use := delay_barrel
FOR k IN 0 TO 31 LOOP
IF k < Wi AND k+Oi <= 31 THEN
result(k) := Av(k+Oi)
ELSE
result(k) := '0'
END IF
END LOOP
WHEN 68 | 76 =>
-- mak
s_barrel := s_barrel + 1
delay_to_use := delay_barrel
FOR k IN 0 TO 31
IF k >= Oi AND
result(k) :=
ELSE
result(k) :=
END IF
END LOOP
LOOP
k < (Oi + Wi) THEN
Av(k-Oi)
-- in range
'0'
WHEN 69 | 77 =>
s_barrel := s_barrel + 1
-- rot
CHAPTER 2. VHDL SOURCE CODE
112
delay_to_use := delay_barrel
FOR k IN 0 TO 31 LOOP
IF k+Oi <= 31 THEN
result(k) := Av(k+Oi)
ELSE
result(k) := Av(K+Oi-32)
END IF
END LOOP
WHEN 70 =>
-- ff0 rd,rb
s_ff := s_ff + 1
delay_to_use := delay_ff
tmpi := 32
FOR k IN 31 DOWNTO 0 LOOP
IF Bv(k) = '0' THEN
tmpi := k
EXIT
END IF
END LOOP
result := int2v1d(tmpi)
WHEN 71 =>
-- ff1 rd,rb
s_ff := s_ff + 1
delay_to_use := delay_ff
tmpi := 32
FOR k IN 31 DOWNTO 0 LOOP
IF Bv(k) = '1' THEN
tmpi := k
EXIT
END IF
END LOOP
result := int2v1d(tmpi)
WHEN OTHERS =>
-- anything else
putline("*** Illegal Opcode for Logic Unit ***")
END CASE
--- write output
IF dest = REG_R1 THEN
rq <= result
v_rq_req := NOT v_rq_req
rq_req <= v_rq_req AFTER delay_to_use
2.15. LOGIC UNIT.VHD
113
WAIT ON rq_ack
ELSE
res <= dest & result
lastresult := result
IF debug THEN
tmpi := v1d2int(lastresult)
puthexline("latched ",tmpi)
END IF
v_rout := NOT v_rout
rout <= v_rout AFTER delay_to_use
-- write it out
WAIT ON aout
END IF
END IF
-- produce a result
--- signal completion of this instruction
IF tellme = '1' THEN
-- only if needed
tmpv := int2v1d( STATUS_done )
done <= ZERO(87 DOWNTO 24) & tmpv(15 DOWNTO 0) & tag
v_d_req := NOT v_d_req
d_req <= v_d_req AFTER delay
WAIT ON d_ack
END IF
ain <= rin AFTER delay
-- done with this event
END IF
-- clr not asserted
WAIT ON clr, rin
-- wait for next event
END PROCESS main
END behavior
CHAPTER 2. VHDL SOURCE CODE
114
2.16 memory unit.vhd
USE work.p_constants.ALL
USE work.p_memory_unit.ALL
USE work.p_output.ALL
---- The memory_unit module provides the interface to the external data memory.
----------------------
The EXTRA input was added to provide last-result-reuse and to elminate
zero values of op_a for immediate instructions. The bit usage is:
EXTRA(0)
EXTRA(1)
EXTRA(2)
EXTRA(3)
=
=
=
=
reuseA
reuseB
reuseD
zeroA (unused)
ENTITY memory_unit IS
GENERIC( delay: TIME := 100 ps )
PORT( SIGNAL clr
: IN
SIGNAL rin
: IN
SIGNAL ain
: OUT
SIGNAL tellme
: IN
SIGNAL tag
: IN
SIGNAL dest
: IN
SIGNAL opcode
: IN
SIGNAL op_s
: IN
SIGNAL op_a
: IN
SIGNAL op_b
: IN
SIGNAL data_req
: OUT
SIGNAL data_ack
: IN
SIGNAL data_ack_ack
: OUT
SIGNAL read
: OUT
SIGNAL byte_strobe
: OUT
SIGNAL d_addr
: OUT
SIGNAL d_read
: IN
SIGNAL d_status
: IN
SIGNAL d_write
: OUT
SIGNAL cr0
: IN
SIGNAL d_req
: OUT
SIGNAL d_ack
: IN
SIGNAL done
: OUT
SIGNAL reg_q_req
: OUT
SIGNAL reg_q_ack
: IN
SIGNAL reg_q
: OUT
SIGNAL r1_q_req
: OUT
SIGNAL r1_q_ack
: IN
SIGNAL r1_q
: OUT
SIGNAL extra
: IN
END memory_unit
VLBIT
VLBIT
VLBIT
VLBIT
VLBIT_1D
VLBIT_1D
VLBIT_1D
VLBIT_1D
VLBIT_1D
VLBIT_1D
VLBIT
VLBIT
VLBIT
VLBIT
VLBIT_1D
VLBIT_1D
VLBIT_1D
VLBIT_1D
VLBIT_1D
VLBIT_1D
VLBIT
VLBIT
VLBIT_1D
VLBIT
VLBIT
VLBIT_1D
VLBIT
VLBIT
VLBIT_1D
VLBIT_1D
ARCHITECTURE behavior OF memory_unit IS
BEGIN
(7 DOWNTO 0)
(4 DOWNTO 0)
(31 DOWNTO 0)
(31 DOWNTO 0)
(31 DOWNTO 0)
(31 DOWNTO 0)
(3 DOWNTO 0)
(31 DOWNTO 0)
(31 DOWNTO 0)
(3 DOWNTO 0)
(31 DOWNTO 0)
(31 DOWNTO 0)
(87 DOWNTO 0)
(36 DOWNTO 0)
(31 DOWNTO 0)
(3 DOWNTO 0) )
2.16. MEMORY UNIT.VHD
115
main : PROCESS
VARIABLE debug
: BOOLEAN := FALSE
--- Minor status code values. The minor field is actually
--- "operation + opsize". Opsize is currently only 1, 2, or 4.
--- I'm leaving room for size 8.
CONSTANT MINOR_load
CONSTANT MINOR_store
CONSTANT MINOR_xmem
: INTEGER := 16
: INTEGER := 32
: INTEGER := MINOR_load + MINOR_store
--- factors affecting response time
VARIABLE delay_decode
: TIME := 100 ps -- decode & compute address
--- internal variables
VARIABLE
VARIABLE
VARIABLE
VARIABLE
lastresult
op_aa
op_bb
op_ss
:
:
:
:
VLBIT_1D(31
VLBIT_1D(31
VLBIT_1D(31
VLBIT_1D(31
DOWNTO
DOWNTO
DOWNTO
DOWNTO
0)
0)
0)
0)
VARIABLE opA
VARIABLE opB
VARIABLE addr
: INTEGER
: INTEGER
: INTEGER
VARIABLE
VARIABLE
VARIABLE
VARIABLE
VARIABLE
VARIABLE
VARIABLE
imm
opsize
scaled
do_sign_ext
force_usr_mode
do_load
do_store
:
:
:
:
:
:
:
BOOLEAN
INTEGER
BOOLEAN
BOOLEAN
BOOLEAN
BOOLEAN
BOOLEAN
VARIABLE
VARIABLE
VARIABLE
VARIABLE
VARIABLE
read_result
status
minor
arg1
arg2
:
:
:
:
:
VLBIT_1D (31 DOWNTO 0)
INTEGER
INTEGER
INTEGER
INTEGER
--- output signal value variables
VARIABLE
VARIABLE
VARIABLE
VARIABLE
VARIABLE
VARIABLE
v_byte_strobe
v_d_addr
v_data_req
v_d_req
v_r1_q_req
v_reg_q_req
:
:
:
:
:
:
VLBIT_1D (3 DOWNTO 0)
VLBIT_1D (31 DOWNTO 0)
VLBIT
VLBIT
VLBIT
VLBIT
--- scratch variables
VARIABLE tmpi
: INTEGER
CHAPTER 2. VHDL SOURCE CODE
116
VARIABLE tmpv
VARIABLE DoTheLoop
: VLBIT_1D (31 DOWNTO 0)
: BOOLEAN
--- statistics
VARIABLE
VARIABLE
VARIABLE
VARIABLE
VARIABLE
VARIABLE
VARIABLE
VARIABLE
s_memory_rin
s_lda
s_load_word
s_load_half
s_load_byte
s_store_word
s_store_half
s_store_byte
:
:
:
:
:
:
:
:
INTEGER
INTEGER
INTEGER
INTEGER
INTEGER
INTEGER
INTEGER
INTEGER
BEGIN
--- If clear is asserted, reset everything and stick here.
IF clr /= '1' THEN
v_byte_strobe := ('0','0','0','0')
v_d_addr := ZERO(31 DOWNTO 0)
v_data_req := '0'
v_d_req := '0'
v_r1_q_req := '0'
v_reg_q_req := '0'
ain <= '0'
byte_strobe <= v_byte_strobe
d_addr <= v_d_addr
d_write <= ZERO(31 DOWNTO 0)
data_req <= v_data_req
data_ack_ack <= '0'
d_req <= v_d_req
done <= ZERO(87 DOWNTO 0)
r1_q <= ZERO(31 DOWNTO 0)
r1_q_req <= v_r1_q_req
read <= '0'
reg_q <= ZERO(36 DOWNTO 0)
reg_q_req <= v_reg_q_req
s_memory_rin := 0
s_lda := 0
s_load_word := 0
s_load_half := 0
s_load_byte := 0
s_store_word := 0
s_store_half := 0
s_store_byte := 0
WAIT UNTIL clr = '1'
-- reset to beginning
2.16. MEMORY UNIT.VHD
ELSE
117
-- only wakeup event is RIN
s_memory_rin := s_memory_rin + 1
--- Determine what operands to use.
IF extra(0)='1' THEN
op_aa := lastresult
ELSE
op_aa := op_a
END IF
IF extra(1)='1' THEN
op_bb := lastresult
ELSE
op_bb := op_b
END IF
IF extra(2)='1' THEN
op_ss := lastresult
ELSE
op_ss := op_s
END IF
IF debug THEN
puthexline("op_a is ",tmpi)
tmpi := v1d2int(op_bb)
puthexline("op_b is ",tmpi)
tmpi := v1d2int(op_ss)
puthexline("op_s is ",tmpi)
END IF
---------
There are number of sequential steps, which I need to abort if I
get a fault at any point. This loop lets me jump immediately to
the end of the sequence when I detect a fault. It doesn't really
loop.
DoTheLoop := TRUE
WHILE DoTheLoop LOOP
DoTheLoop := FALSE
status := STATUS_done
arg1 := 0
arg2 := 0
-- do it
-- here it is
-- no, don't do it
-- assume it will work
--- Determine what to do.
mem_decode( opcode,
imm,
-- boolean
CHAPTER 2. VHDL SOURCE CODE
118
opsize,
scaled,
do_sign_ext,
force_usr_mode,
do_load,
do_store )
-------
integer
boolean
boolean
boolean
boolean
boolean
--- Compute address
opA := v1d2int( op_aa )
IF imm THEN
-- use imm16 value
opB := v1d2int( opcode( 15 DOWNTO 0 ) )
ELSE
-- use register value
opB := v1d2int( op_bb )
IF scaled THEN
-- scale factor
opB := opB * opsize
END IF
END IF
addr := opA + opB
-- add 'em together
--- Model this computation time. I can just wait, because there is only
--- one possible wake-up event, and it isn't in parallel with anything.
WAIT FOR delay_decode
--- deal with lda instructions as a special case
IF ( NOT do_load ) AND ( NOT do_store ) THEN -- lda instruction
s_lda := s_lda + 1
read_result := int2v1d( addr )
IF dest = REG_R1 THEN
-- dest is R1 Queue
r1_q <= read_result
v_r1_q_req := NOT v_r1_q_req
r1_q_req <= v_r1_q_req AFTER delay
WAIT ON r1_q_ack
ELSIF dest /= REG_R0 THEN
reg_q <= dest & read_result
lastresult := read_result
-- dest is not R0
2.16. MEMORY UNIT.VHD
119
IF debug THEN
tmpi := v1d2int(lastresult)
puthexline("latched ",tmpi)
END IF
v_reg_q_req := NOT v_reg_q_req
reg_q_req <= v_reg_q_req AFTER delay
WAIT ON reg_q_ack
END IF
EXIT
END IF
-- jump out here
-- lda instruction
--- make sure address alignment is okay for operation size
IF (addr MOD opsize) /= 0 THEN
-- misalignment
status := STATUS_align
IF do_load AND do_store THEN
minor := MINOR_xmem + opsize
ELSIF do_load THEN
minor := MINOR_load + opsize
ELSE
minor := MINOR_store + opsize
END IF
arg1 := addr
arg2 := v1d2int( op_ss )
-- that's a fault
EXIT
-- jump to end
-- just in case
END IF
--- set supervisor bit as desired
tmpv := int2v1d( addr )
IF force_usr_mode THEN
v_d_addr := (tmpv(31 DOWNTO 2) & '0' & '0')
ELSE
v_d_addr := (tmpv(31 DOWNTO 2) & cr0(Supervisor) & '0')
END IF
--- determine byte strobe values
IF opsize = 4 THEN
v_byte_strobe := ('1','1','1','1')
ELSIF opsize = 2 THEN
IF (addr MOD 4) = 0 THEN
-- word
-- half-word
-- lower half
CHAPTER 2. VHDL SOURCE CODE
120
v_byte_strobe := ('0','0','1','1')
ELSE
v_byte_strobe := ('1','1','0','0')
END IF
ELSE
tmpi := addr MOD 4
IF tmpi = 0 THEN
v_byte_strobe := ('0','0','0','1')
ELSIF tmpi = 1 THEN
v_byte_strobe := ('0','0','1','0')
ELSIF tmpi = 2 THEN
v_byte_strobe := ('0','1','0','0')
ELSE
v_byte_strobe := ('1','0','0','0')
END IF
END IF
-- upper half
-- byte
-- byte 0
-- byte 1
-- byte 2
-- byte 3
--- Do read operation if requested
IF do_load THEN
IF opsize = 4 THEN
s_load_word := s_load_word + 1
ELSIF opsize = 2 THEN
s_load_half := s_load_half + 1
ELSE
s_load_byte := s_load_byte + 1
END IF
read <= '1'
byte_strobe <= v_byte_strobe
d_addr <= v_d_addr
v_data_req := NOT v_data_req
data_req <= v_data_req AFTER delay
-- send read request
WAIT ON data_ack
-- wait for response
--- check for memory fault
IF ( ( d_status(0) = '1'
( d_status(1) = '1'
( d_status(2) = '1'
( d_status(3) = '1'
THEN
status := STATUS_dmem
ELSE
AND
AND
AND
AND
cr0(Dmem0)
cr0(Dmem1)
cr0(Dmem2)
cr0(Dmem3)
=
=
=
=
'1'
'1'
'1'
'1'
)
)
)
)
OR
OR
OR
)
--- sign-extend or zero-extend the result according to size
read_result := d_read
-- get result
2.16. MEMORY UNIT.VHD
121
IF opsize = 2 THEN
IF do_sign_ext AND d_read(15) = '1' THEN
read_result(31 DOWNTO 16) := ('1','1','1','1','1','1','1','1',
'1','1','1','1','1','1','1','1')
ELSE
read_result(31 DOWNTO 16) := ZERO(31 DOWNTO 16)
END IF
ELSIF opsize = 1 THEN
IF do_sign_ext AND d_read(7) = '1' THEN
read_result(31 DOWNTO 8) := ('1','1','1','1','1','1','1','1',
'1','1','1','1','1','1','1','1',
'1','1','1','1','1','1','1','1')
ELSE
read_result(31 DOWNTO 8) := ZERO(31 DOWNTO 8)
END IF
END IF
END IF
--- now acknowledge receipt of status and data
data_ack_ack <= data_ack AFTER delay
IF status /= STATUS_done THEN
-- found a fault
IF do_store THEN
minor := MINOR_xmem + opsize
ELSE
minor := MINOR_load + opsize
END IF
arg1 := addr
arg2 := v1d2int( op_ss )
-- this is xmem instruction
EXIT
-- jump to end
END IF
END IF
--- Do write operation if requested
IF do_store THEN
IF opsize = 4 THEN
s_store_word := s_store_word + 1
ELSIF opsize = 2 THEN
-- of do_load
CHAPTER 2. VHDL SOURCE CODE
122
s_store_half := s_store_half + 1
ELSE
s_store_byte := s_store_byte + 1
END IF
read <= '0'
byte_strobe <= v_byte_strobe
d_addr <= v_d_addr
--- align and shift the output data correctly
IF opsize = 4 THEN
-- full word at once
d_write <= op_ss
ELSIF opsize = 2 THEN
-- half word
d_write( 31 DOWNTO 16 ) <= op_ss( 15 DOWNTO 0)
d_write( 15 DOWNTO 0 ) <= op_ss( 15 DOWNTO 0)
ELSE
-- byte
d_write( 31 DOWNTO 24 ) <= op_ss( 7 DOWNTO 0)
d_write( 23 DOWNTO 16 ) <= op_ss( 7 DOWNTO 0)
d_write( 15 DOWNTO 8 ) <= op_ss( 7 DOWNTO 0)
d_write( 7 DOWNTO 0 ) <= op_ss( 7 DOWNTO 0)
END IF
v_data_req := NOT v_data_req
data_req <= v_data_req AFTER delay
-- send read request
WAIT ON data_ack
-- wait for response
--- check for memory fault
IF ( ( d_status(0) = '1'
( d_status(1) = '1'
( d_status(2) = '1'
( d_status(3) = '1'
THEN
status := STATUS_dmem
END IF
AND
AND
AND
AND
cr0(Dmem0)
cr0(Dmem1)
cr0(Dmem2)
cr0(Dmem3)
=
=
=
=
'1'
'1'
'1'
'1'
)
)
)
)
OR
OR
OR
)
--- now acknowledge receipt of status
data_ack_ack <= data_ack AFTER delay
IF status /= STATUS_done THEN
IF do_load THEN
minor := MINOR_xmem + opsize
ELSE
minor := MINOR_store + opsize
END IF
arg1 := addr
-- found a fault
-- this is xmem instruction
2.16. MEMORY UNIT.VHD
123
arg2 := v1d2int( op_ss )
EXIT
-- jump to end
END IF
END IF
-- of do_store
--- Everything was successful. Put any read result out the queue.
IF do_load THEN
IF dest = REG_R1 THEN
-- if load operation
-- dest is R1 Queue
r1_q <= read_result
v_r1_q_req := NOT v_r1_q_req
r1_q_req <= v_r1_q_req AFTER delay
WAIT ON r1_q_ack
ELSIF dest /= REG_R0 THEN
-- dest is not R0
reg_q <= dest & read_result
lastresult := read_result
IF debug THEN
tmpi := v1d2int(lastresult)
puthexline("latched ",tmpi)
END IF
v_reg_q_req := NOT v_reg_q_req
reg_q_req <= v_reg_q_req AFTER delay
WAIT ON reg_q_ack
END IF
END IF
END LOOP
-- here's the jump-out point
--- Send completion status.
IF tellme = '1' THEN
-- only if needed
tmpi := status + 256 * minor
tmpv := int2v1d( tmpi )
done <= int2v1d(arg1) & int2v1d(arg2) & tmpv(15 DOWNTO 0) & tag
CHAPTER 2. VHDL SOURCE CODE
124
v_d_req := NOT v_d_req
d_req <= v_d_req AFTER delay
WAIT ON d_ack
END IF
ain <= rin AFTER delay
-- done with this event
END IF
-- clr not asserted
WAIT ON clr, rin
-- wait for next event
END PROCESS main
END behavior
2.17. P ARITH.VHD
2.17 p arith.vhd
PACKAGE p_arith IS
-----------
Stupid ViewLogic VHDL doesn't implement addum correctly for 32 bits. I
have to write my own. Bunch of idiots. Not only that, but it's
impossible to make these functions work generically for any vector
length, because you can't put expressions in the range of variable
declarations.
FUNCTION add32( Av, Bv : VLBIT_1D Cin : VLBIT ) RETURN VLBIT_1D
FUNCTION sub32( Av, Bv : VLBIT_1D Cin : VLBIT ) RETURN VLBIT_1D
END p_arith
PACKAGE BODY p_arith IS
--- Compute sum of two 32-bit vectors (A + B). The result is two bits longer
--- than the input vectors. Bit 33 of the result is the overflow bit, bit 32
--- is the carry out.
FUNCTION add32( Av, Bv : VLBIT_1D Cin : VLBIT )
RETURN VLBIT_1D IS
VARIABLE res : VLBIT_1D( 33 DOWNTO 0 )
VARIABLE carry : VLBIT
BEGIN
carry := Cin
FOR k IN 0 TO 31 LOOP
res(k) := Av(k) XOR Bv(k) XOR carry
carry := (Av(k) AND Bv(k)) OR (carry AND (Av(k) OR Bv(k)))
END LOOP
res(32) := carry
-- carry out
--- overflow bit
res(33) := ( (Bv(Bv'left) AND Av(Av'left) AND NOT res(Av'left)) OR
(NOT Bv(Bv'left) AND NOT Av(Av'left) AND res(Av'left)) )
RETURN res
END add32
--- Compute difference of two 32-bit vectors (A - B). The result is two bits
--- longer than the input vectors. Bit 33 of the result is the overflow bit,
--- bit 32 is the carry out.
FUNCTION sub32( Av, Bv : VLBIT_1D Cin : VLBIT )
125
CHAPTER 2. VHDL SOURCE CODE
126
RETURN VLBIT_1D IS
VARIABLE res : VLBIT_1D(33 DOWNTO 0)
VARIABLE carry : VLBIT
BEGIN
carry := Cin
FOR k IN 0 TO 31 LOOP
res(k) := Av(k) XOR (NOT Bv(k)) XOR carry
carry := (Av(k) AND (NOT Bv(k))) OR (carry AND (Av(k) OR (NOT Bv(k))))
END LOOP
res(32) := carry
-- carry out
--- overflow bit
res(33) := ( (NOT Bv(Bv'left) AND Av(Av'left) AND NOT res(Av'left)) OR
(Bv(Bv'left) AND NOT Av(Av'left) AND res(Av'left)) )
RETURN res
END sub32
END p_arith
2.18. P CONSTANTS.VHD
127
2.18 p constants.vhd
--- Constants used in place of magic numbers, where possible.
PACKAGE p_constants IS
---- Misc. useful constants.
CONSTANT REG_R1: VLBIT_1D(4 DOWNTO 0) := ('0','0','0','0','1')
CONSTANT REG_R0: VLBIT_1D(4 DOWNTO 0) := ('0','0','0','0','0')
CONSTANT ZERO : VLBIT_1D(151 DOWNTO 0) := ('0','0','0','0','0','0','0','0',
'0','0','0','0','0','0','0','0',
'0','0','0','0','0','0','0','0',
'0','0','0','0','0','0','0','0',
'0','0','0','0','0','0','0','0',
'0','0','0','0','0','0','0','0',
'0','0','0','0','0','0','0','0',
'0','0','0','0','0','0','0','0',
'0','0','0','0','0','0','0','0',
'0','0','0','0','0','0','0','0',
'0','0','0','0','0','0','0','0',
'0','0','0','0','0','0','0','0',
'0','0','0','0','0','0','0','0',
'0','0','0','0','0','0','0','0',
'0','0','0','0','0','0','0','0',
'0','0','0','0','0','0','0','0',
'0','0','0','0','0','0','0','0',
'0','0','0','0','0','0','0','0',
'0','0','0','0','0','0','0','0')
CONSTANT NEGMAX : VLBIT_1D(31 DOWNTO 0) := ('1','0','0','0','0','0','0','0',
'0','0','0','0','0','0','0','0',
'0','0','0','0','0','0','0','0',
'0','0','0','0','0','0','0','0')
---- Control register 0 bits.
CONSTANT
CONSTANT
CONSTANT
CONSTANT
CONSTANT
CONSTANT
CONSTANT
CONSTANT
CONSTANT
CONSTANT
CONSTANT
CONSTANT
Imem0
Imem1
Imem2
Imem3
Supervisor
Int_Enable
Excp_Enable
Doit
Dmem0
Dmem1
Dmem2
Dmem3
:
:
:
:
:
:
:
:
:
:
:
:
INTEGER
INTEGER
INTEGER
INTEGER
INTEGER
INTEGER
INTEGER
INTEGER
INTEGER
INTEGER
INTEGER
INTEGER
:=
:=
:=
:=
:=
:=
:=
:=
:=
:=
:=
:=
0
1
2
3
4
5
6
7
8
9
10
11
---- Number of Instruction Window slots
CHAPTER 2. VHDL SOURCE CODE
128
CONSTANT IW_Max
: INTEGER := 16
---- Number of control registers for each IW slot
CONSTANT IW_CRNUM
: INTEGER := 5
CONSTANT
CONSTANT
CONSTANT
CONSTANT
CONSTANT
:
:
:
:
:
IW_CR_STAT
IW_CR_ADDR
IW_CR_OPCD
IW_CR_ARG1
IW_CR_ARG2
INTEGER
INTEGER
INTEGER
INTEGER
INTEGER
:=
:=
:=
:=
:=
0
1
2
3
4
-- what they mean
---- Location of control registers. These are the registers which are not
---- normally visible. CR0 is a special case, since it is visible everywhere.
--- IF Unit registers
CONSTANT IF_ICR_Min
CONSTANT IF_ICR_Max
CONSTANT IF_SIW_Min
CONSTANT IF_SIW_Max
:
:
:
:
INTEGER
INTEGER
INTEGER
INTEGER
:=
:=
:=
:=
1
-- normal registers
12
100
-- shadow IW registers
IF_SIW_Min + IW_CRNUM*IW_Max - 1
---- Exception vector numbers
CONSTANT
CONSTANT
CONSTANT
CONSTANT
CONSTANT
CONSTANT
VECTOR_reset
VECTOR_imem
VECTOR_dmem
VECTOR_illegal
VECTOR_error
VECTOR_int
:
:
:
:
:
:
INTEGER
INTEGER
INTEGER
INTEGER
INTEGER
INTEGER
:=
:=
:=
:=
:=
:=
0
1
2
3
4
5
---- Status code values.
CONSTANT STATUS_none
CONSTANT STATUS_done
: INTEGER := 0
: INTEGER := 1
-----
no status yet
completed successfully
undecided
undecided
CONSTANT STATUS_imem
: INTEGER := 4
-----
imem fault
undecided
undecided
undecided
CONSTANT STATUS_dmem
CONSTANT STATUS_align
: INTEGER := 8
: INTEGER := 9
-----
dmem fault
misaligned data access
undecided
undecided
CONSTANT STATUS_illegal
CONSTANT STATUS_user
: INTEGER := 12
: INTEGER := 13
-----
unimplemented opcode
user mode violation
undecided
undecided
2.18. P CONSTANTS.VHD
129
CONSTANT STATUS_error
: INTEGER := 16
-----
unrecoverable error
undecided
undecided
undecided
CONSTANT STATUS_int
CONSTANT STATUS_sync
: INTEGER := 20
: INTEGER := 21
-----
external interrupt
sync.x aborted externally
undecided
undecided
CONSTANT
CONSTANT
CONSTANT
CONSTANT
:
:
:
:
24
25
26
27
-----
deadlock
deadlock
deadlock
deadlock
CONSTANT STATUS_overflow : INTEGER := 28
-----
integer overflow
undecided
undecided
undecided
CONSTANT STATUS_int_div
-----
integer divide error
undecided
undecided
undecided
-------------
STATUS_lock_b0
STATUS_lock_b1
STATUS_lock_r0
STATUS_lock_r1
INTEGER
INTEGER
INTEGER
INTEGER
:=
:=
:=
:=
: INTEGER := 32
on
on
on
on
BR
BR
R1
R1
Queue
Queue
Queue
Queue
empty
full
empty
full
Trap code values. When bit 8 of the status is set, it indicates that
the vector was taken as the result of a trap instruction. In the dispatch
unit, the major and minor status codes are each 16 bits wide, but only 8
bits are returned from the various units.
CONSTANT STATUS_trap
: INTEGER := 256
-- bits 7-0 are vector number
---- Returns the index number of the given opcode. Useful for decoding by
---- functional units.
FUNCTION op2index( opcode: VLBIT_1D(31 DOWNTO 0) ) RETURN INTEGER
END p_constants
PACKAGE BODY p_constants IS
---- Returns the index number of the given opcode. Useful for decoding by
---- functional units.
FUNCTION op2index( opcode: VLBIT_1D(31 DOWNTO 0) ) RETURN INTEGER IS
CHAPTER 2. VHDL SOURCE CODE
130
VARIABLE major : INTEGER
VARIABLE minor : INTEGER
VARIABLE index : INTEGER
BEGIN
major := v1d2int( opcode( 30 DOWNTO 26 ) ) -- ignore bit 31
minor := v1d2int( opcode( 15 DOWNTO 10 ) )
IF major = 23 THEN
index := 32 + minor
ELSE
index := major
END IF
RETURN index
END op2index
END p_constants
2.19. P DISPATCH.VHD
131
2.19 p dispatch.vhd
USE work.p_constants.ALL
PACKAGE p_dispatch IS
-- package declaration
CONSTANT OPCODE_doit : INTEGER := 16#5c005c00# -- plain doit opcode
--- These are EX Unit functional units.
CONSTANT OP_arith : INTEGER := 0
CONSTANT OP_logic : INTEGER := 1
CONSTANT OP_ctrl
: INTEGER := 2
CONSTANT OP_branch : INTEGER := 3
CONSTANT OP_load
: INTEGER := 4
--- These are handled inside
CONSTANT OP_doit
: INTEGER
CONSTANT OP_rte
: INTEGER
CONSTANT OP_sync
: INTEGER
CONSTANT OP_sync_x : INTEGER
--- These are used
CONSTANT OP_trap
CONSTANT OP_ill
CONSTANT OP_mvbr
CONSTANT OP_ldbr
CONSTANT OP_store
CONSTANT OP_xmem
the IF Unit.
:= 100
:= 101
:= 102
:= 103
mostly for decoding.
: INTEGER := 200
: INTEGER := 201
: INTEGER := 202
: INTEGER := 203
: INTEGER := 204
: INTEGER := 205
TYPE iw_slot IS RECORD
valid
: BOOLEAN
tag
: INTEGER
address
: INTEGER
opcode
: INTEGER
wat
: BOOLEAN
single
: BOOLEAN
issued
: BOOLEAN
status
: INTEGER
dest
: INTEGER
arg1
: INTEGER
arg2
: INTEGER
END RECORD
-- mem unit
-----
ctrl unit
branch unit
mem unit
mem unit
------------
slot is filled
dispatch tag
instruction address
instruction opcode
is a WAT instruction
is a SINGLE instruction
has been issued
completion status
dest reg for SB checking
for fault recovery
for fault recovery
TYPE iw_type IS ARRAY ( 0 TO IW_Max - 1 ) OF iw_slot
--- This function returns TRUE if the opcode is a SINGLE type.
--FUNCTION is_single( opcode : VLBIT_1D(31 DOWNTO 0) ) RETURN BOOLEAN
CHAPTER 2. VHDL SOURCE CODE
132
--- This removes the specified
--PROCEDURE iw_remove ( VARIABLE
VARIABLE
VARIABLE
VARIABLE
VARIABLE
instruction from the IW.
iw_index : INOUT INTEGER -- which to remove
iw : INOUT iw_type -- IW
iw_bottom : INOUT INTEGER -- iw_bottom
wat_flag : INOUT BOOLEAN -- wat flag
single_flag : INOUT BOOLEAN ) -- single flag
--- determines decode information needed to
--PROCEDURE decode ( VARIABLE BR_Max
VARIABLE XBR_Max
VARIABLE R1_Max
CONSTANT iopcode
VARIABLE supervisor_mode
VARIABLE exceptions_ok
VARIABLE r1_count
VARIABLE r1_pending
VARIABLE br_count
VARIABLE xbr_count
VARIABLE new_r1_count
VARIABLE new_r1_pending
VARIABLE new_br_count
VARIABLE new_xbr_count
VARIABLE status
VARIABLE op_type
VARIABLE single
VARIABLE wat
VARIABLE tellme
VARIABLE vA
VARIABLE srcA
VARIABLE vB
VARIABLE srcB
VARIABLE vD
VARIABLE srcD
VARIABLE dest
dispatch instructions
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
IN INTEGER
IN INTEGER
IN INTEGER
IN INTEGER
IN BOOLEAN
IN BOOLEAN
IN INTEGER
IN INTEGER
IN INTEGER
IN INTEGER
INOUT INTEGER
INOUT INTEGER
INOUT INTEGER
INOUT INTEGER
INOUT INTEGER
INOUT INTEGER
INOUT BOOLEAN
INOUT BOOLEAN
INOUT BOOLEAN
INOUT BOOLEAN
INOUT INTEGER
INOUT BOOLEAN
INOUT INTEGER
INOUT BOOLEAN
INOUT INTEGER
INOUT INTEGER )
--- packs variable values into RF operand request vector
----17
operand S requested
--- 16-12
operand S register number
--11
operand A requested
--- 10-6
operand A register number
--5
operand B requested
--4-0
operand B register number
--FUNCTION rf_encode ( CONSTANT vA
: BOOLEAN
CONSTANT srcA : INTEGER
CONSTANT vB
: BOOLEAN
CONSTANT srcB : INTEGER
CONSTANT vD
: BOOLEAN
CONSTANT srcD : INTEGER )
RETURN VLBIT_1D
2.19. P DISPATCH.VHD
133
END p_dispatch
-- end of package declaration
PACKAGE BODY p_dispatch IS
-- package body is here
---------------
Define a table to help with decoding. This table is produced from the
opcodes.tex file in the write-up, by running it through a Perl script. It
doesn't need to mention the .d variants, since they are never decoded.
Instead, when instructions are fetched from memory, the .d is used to
insert a DOIT in the IW. If the IW is changed by an exception handler,
any .d instructions must be explicitly expanded into two IW slots by
software.
---- Start of insertion.
CONSTANT
CONSTANT
CONSTANT
CONSTANT
INDEX_doit
INDEX_rte
INDEX_putcr
INDEX_putcr1
CONSTANT T
CONSTANT F
:
:
:
:
INTEGER
INTEGER
INTEGER
INTEGER
:=
:=
:=
:=
55
80
94
95
: BOOLEAN := TRUE
: BOOLEAN := FALSE
TYPE decode_table_entry IS RECORD
bp
: BOOLEAN
bc
: BOOLEAN
rcd
: BOOLEAN
rca
: BOOLEAN
rcb
: BOOLEAN
dr
: BOOLEAN
wat
: BOOLEAN
single : BOOLEAN
usr
: BOOLEAN
tellme : BOOLEAN
op_type : INTEGER
END RECORD
TYPE decode_table_type IS ARRAY ( 0 TO 95
CONSTANT decode_table : decode_table_type
--- Fields are: BP BC RP RCd RCa RCb DR
(F,F,F,T,F,T,F,F,F,F,OP_logic ),
-(F,F,F,T,F,T,F,F,F,F,OP_logic ),
-(F,F,F,T,F,T,F,F,F,F,OP_logic ),
-(F,F,F,T,F,T,F,F,F,F,OP_logic ),
-(F,F,F,T,F,T,F,F,F,F,OP_logic ),
-(F,F,F,T,F,T,F,F,F,F,OP_logic ),
-(F,F,F,T,F,T,F,F,F,F,OP_logic ),
-(F,F,F,T,F,T,F,F,F,F,OP_logic ),
-(F,F,F,T,F,T,F,F,F,T,OP_arith ),
-(F,F,F,T,F,T,F,F,F,F,OP_arith ),
--
------------
branch producer
branch consumer
r1 consumer (dest reg)
r1 consumer (src reg A)
r1 consumer (src reg B)
destination register
wait-at-top instruction
single instruction
user instruction only
should report DONE status
type of instruction
) OF decode_table_entry
:= (
WAT SGL USR TELLME TYPE
0 and rd,ra,imm16
1 and.u rd,ra,imm16
2 mask rd,ra,imm16
3 mask.u rd,ra,imm16
4 or rd,ra,imm16
5 or.u rd,ra,imm16
6 xor rd,ra,imm16
7 xor.u rd,ra,imm16
8 add rd,ra,imm16
9 addu rd,ra,imm16
CHAPTER 2. VHDL SOURCE CODE
134
(F,F,F,T,F,T,F,F,F,T,OP_arith ),
(F,F,F,T,F,T,F,F,F,T,OP_arith ),
(F,F,F,T,F,T,F,F,F,F,OP_arith ),
(F,F,F,T,F,T,F,F,F,F,OP_arith ),
(F,F,F,T,F,T,F,F,F,T,OP_arith ),
(F,F,F,T,F,T,F,F,F,F,OP_arith ),
(T,F,F,T,F,F,F,F,F,F,OP_branch),
(T,F,F,T,F,F,F,F,F,F,OP_branch),
(T,F,F,T,F,F,F,F,F,F,OP_branch),
(T,F,F,F,F,F,F,F,F,F,OP_branch),
(F,F,F,F,F,T,F,F,F,F,OP_ctrl ),
(F,F,F,F,F,F,F,F,F,F,OP_trap ),
(F,F,T,T,F,T,F,F,F,T,OP_xmem ),
(F,F,F,F,F,F,F,F,F,F,OP_ill
),
(F,F,F,T,F,T,F,F,F,T,OP_load ),
(F,F,F,T,F,T,F,F,F,T,OP_load ),
(F,F,F,T,F,T,F,F,F,T,OP_load ),
(F,F,F,T,F,T,F,F,F,T,OP_load ),
(F,F,F,T,F,T,F,F,F,T,OP_load ),
(F,F,T,T,F,F,F,F,F,T,OP_store ),
(F,F,T,T,F,F,F,F,F,T,OP_store ),
(F,F,T,T,F,F,F,F,F,T,OP_store ),
(F,F,F,T,T,T,F,F,F,F,OP_logic ),
(F,F,F,T,T,T,F,F,F,F,OP_logic ),
(F,F,F,F,F,F,F,F,F,F,OP_ill
),
(F,F,F,F,F,F,F,F,F,F,OP_ill
),
(F,F,F,T,T,T,F,F,F,F,OP_logic ),
(F,F,F,T,T,T,F,F,F,F,OP_logic ),
(F,F,F,T,T,T,F,F,F,F,OP_logic ),
(F,F,F,T,T,T,F,F,F,F,OP_logic ),
(F,F,F,T,T,T,F,F,F,T,OP_arith ),
(F,F,F,T,T,T,F,F,F,F,OP_arith ),
(F,F,F,T,T,T,F,F,F,T,OP_arith ),
(F,F,F,T,T,T,F,F,F,T,OP_arith ),
(F,F,F,T,T,T,F,F,F,F,OP_arith ),
(F,F,F,T,T,T,F,F,F,F,OP_arith ),
(F,F,F,T,T,T,F,F,F,T,OP_arith ),
(F,F,F,T,T,T,F,F,F,F,OP_arith ),
(T,F,F,T,T,F,F,F,F,F,OP_branch),
(T,F,F,T,T,F,F,F,F,F,OP_branch),
(T,F,F,T,T,F,F,F,F,F,OP_branch),
(T,F,F,F,T,F,F,F,F,F,OP_branch),
(F,F,F,F,F,F,F,F,F,F,OP_ill
),
(F,F,F,F,F,F,F,F,F,F,OP_ill
),
(F,F,T,T,T,T,F,F,T,T,OP_xmem ),
(F,T,F,F,F,F,F,T,F,F,OP_doit ),
(F,F,F,T,T,T,F,F,T,T,OP_load ),
(F,F,F,T,T,T,F,F,F,F,OP_load ),
(F,F,F,T,T,T,F,F,F,F,OP_load ),
(F,F,F,F,F,F,F,F,F,F,OP_ill
),
(F,F,T,T,T,F,F,F,T,T,OP_store ),
(F,F,F,F,F,F,F,F,F,F,OP_ill
),
(F,F,F,F,F,F,F,F,F,F,OP_ill
),
(F,F,F,F,F,F,F,F,F,F,OP_ill
),
-------------------------------------------------------
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
div rd,ra,imm16
divu rd,ra,imm16
mul rd,ra,imm16
cmp rd,ra,imm16
sub rd,ra,imm16
subu rd,ra,imm16
bb0 n,ra,imm16
bb1 n,ra,imm16
ble ra,imm16
br imm26
mvpc rd,imm16
trap imm8
xmem rs,ra,imm16
ld.bu rd,ra,imm16
ld.b rd,ra,imm16
ld.hu rd,ra,imm16
ld.h rd,ra,imm16
ld rd,ra,imm16
st.b rs,ra,imm16
st.h rs,ra,imm16
st rs,ra,imm16
and rd,ra,rb
and.c rd,ra,rb
or rd,ra,rb
or.c rd,ra,rb
xor rd,ra,rb
xor.c rd,ra,rb
add.io rd,ra,rb
addu.io rd,ra,rb
div rd,ra,rb
divu rd,ra,rb
mul rd,ra,rb
cmp rd,ra,rb
sub.io rd,ra,rb
subu.io rd,ra,rb
bb0 n,ra,rb
bb1 n,ra,rb
ble ra,rb
br rb
xmem.usr rs,rarb]
doit
ld.h.usr rd,rarb]
lda rd,rarb]
lda.h rd,rarb]
st.h.usr rs,rarb]
2.19. P DISPATCH.VHD
(F,F,F,T,T,T,F,F,F,F,OP_logic ),
(F,F,F,T,T,T,F,F,F,F,OP_logic ),
(F,F,F,T,T,T,F,F,F,F,OP_logic ),
(F,F,F,T,T,T,F,F,F,F,OP_logic ),
(F,F,F,T,T,T,F,F,F,F,OP_logic ),
(F,F,F,T,T,T,F,F,F,F,OP_logic ),
(F,F,F,F,T,T,F,F,F,F,OP_logic ),
(F,F,F,F,T,T,F,F,F,F,OP_logic ),
(F,F,F,T,F,T,F,F,F,F,OP_logic ),
(F,F,F,T,F,T,F,F,F,F,OP_logic ),
(F,F,F,T,F,T,F,F,F,F,OP_logic ),
(F,F,F,T,F,T,F,F,F,F,OP_logic ),
(F,F,F,T,F,T,F,F,F,F,OP_logic ),
(F,F,F,T,F,T,F,F,F,F,OP_logic ),
(F,F,F,F,F,F,F,F,F,F,OP_ill
),
(F,F,F,F,F,F,F,F,F,F,OP_ill
),
(F,F,F,F,F,F,T,T,T,F,OP_rte
),
(F,F,F,F,F,F,F,F,F,F,OP_ill
),
(F,F,F,F,F,F,F,F,F,F,OP_ill
),
(F,F,F,F,F,F,F,F,F,F,OP_ill
),
(F,F,F,F,F,F,T,F,F,F,OP_sync ),
(F,F,F,F,F,F,T,F,T,F,OP_sync_x),
(F,T,F,F,F,T,F,F,F,F,OP_mvbr ),
(T,F,F,T,F,F,F,F,F,F,OP_ldbr ),
(F,F,F,F,F,F,F,F,F,F,OP_ill
),
(F,F,F,F,F,F,F,F,F,F,OP_ill
),
(F,F,F,F,F,F,F,F,F,F,OP_ill
),
(F,F,F,F,F,F,F,F,F,F,OP_ill
),
(F,F,F,F,F,T,F,F,T,F,OP_ctrl ),
(F,F,F,F,T,T,F,F,T,F,OP_ctrl ),
(F,F,F,T,F,F,T,T,T,T,OP_ctrl ),
(F,F,F,T,T,F,T,T,T,T,OP_ctrl ))
135
---------------------------------
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
clr rd,ra,rb
set rd,ra,rb
ext rd,ra,rb
extu rd,ra,rb
mak rd,ra,rb
rot rd,ra,rb
ff0 rd,rb
ff1 rd,rb
clr rd,ra,w5<o5>
set rd,ra,w5<o5>
ext rd,ra,w5<o5>
extu rd,ra,w5<o5>
mak rd,ra,w5<o5>
rot rd,ra,<o5>
rte
sync
sync.x
mvbr rd
ldbr ra
getcr
getcr
putcr
putcr
rd,cr
rd,rb
cr,ra
rb,ra
---- End of insertion.
--- This function returns TRUE if the opcode is a SINGLE type.
--FUNCTION is_single( opcode : VLBIT_1D(31 DOWNTO 0) ) RETURN BOOLEAN IS
VARIABLE index : INTEGER
BEGIN
index := op2index( opcode )
RETURN decode_table(index).single
END is_single
--- This removes the specified instruction from the IW.
--PROCEDURE iw_remove ( VARIABLE iw_index : INOUT INTEGER -- which to remove
CHAPTER 2. VHDL SOURCE CODE
136
VARIABLE
VARIABLE
VARIABLE
VARIABLE
iw : INOUT iw_type -- IW
iw_bottom : INOUT INTEGER -- iw_bottom
wat_flag : INOUT BOOLEAN -- wat flag
single_flag : INOUT BOOLEAN ) -- single flag
IS
BEGIN
IF iw(iw_index).wat THEN
wat_flag := FALSE
END IF
-- clear WAT if appropriate
IF iw(iw_index).single THEN
single_flag := FALSE
END IF
-- clear SINGLE if appropriate
--- remove this instruction from the IW, and shift the others up
FOR i IN (iw_index + 1) TO (iw_bottom - 1) LOOP
iw(i-1) := iw(i)
-- copy 'em upward
END LOOP
iw_bottom := iw_bottom - 1
-- change last pointer
iw(iw_bottom).valid := FALSE
-- zap old last entry
END iw_remove
--- determines decode information needed to
--PROCEDURE decode ( VARIABLE BR_Max
VARIABLE XBR_Max
VARIABLE R1_Max
CONSTANT iopcode
VARIABLE supervisor_mode
VARIABLE exceptions_ok
VARIABLE r1_count
VARIABLE r1_pending
VARIABLE br_count
VARIABLE xbr_count
VARIABLE new_r1_count
VARIABLE new_r1_pending
VARIABLE new_br_count
VARIABLE new_xbr_count
VARIABLE status
VARIABLE op_type
VARIABLE single
VARIABLE wat
VARIABLE tellme
VARIABLE vA
VARIABLE srcA
VARIABLE vB
VARIABLE srcB
VARIABLE vD
VARIABLE srcD
dispatch instructions
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
IN INTEGER
IN INTEGER
IN INTEGER
IN INTEGER
IN BOOLEAN
IN BOOLEAN
IN INTEGER
IN INTEGER
IN INTEGER
IN INTEGER
INOUT INTEGER
INOUT INTEGER
INOUT INTEGER
INOUT INTEGER
INOUT INTEGER
INOUT INTEGER
INOUT BOOLEAN
INOUT BOOLEAN
INOUT BOOLEAN
INOUT BOOLEAN
INOUT INTEGER
INOUT BOOLEAN
INOUT INTEGER
INOUT BOOLEAN
INOUT INTEGER
2.19. P DISPATCH.VHD
137
VARIABLE dest
IS
VARIABLE index
VARIABLE opcode
VARIABLE tmpi
BEGIN
: INOUT INTEGER )
: INTEGER
: VLBIT_1D( 31 DOWNTO 0 )
: INTEGER
opcode := int2v1d( iopcode )
index := op2index( opcode )
--- set up default values for outputs
new_r1_count := r1_count
new_r1_pending := r1_pending
new_br_count := br_count
new_xbr_count := xbr_count
status := STATUS_none
op_type := decode_table(index).op_type
single := decode_table(index).single
wat := decode_table(index).wat
tellme := decode_table(index).tellme
vA := decode_table(index).rca
vB := decode_table(index).rcb
vD := decode_table(index).rcd
srcA := v1d2int( opcode(20 DOWNTO 16) )
srcB := v1d2int( opcode(4 DOWNTO 0) )
srcD := v1d2int( opcode(25 DOWNTO 21) )
-- operand A
-- operand B
-- operand D
IF decode_table(index).dr THEN
dest := srcD
ELSE
dest := 0
END IF
--- do the easy ones first
IF decode_table(index).op_type = OP_ill THEN -- unimplemented opcode
status := STATUS_illegal
RETURN
-- so quit
END IF
IF ( opcode(31) = '1' AND
( index = INDEX_doit OR
index = INDEX_rte OR
index = INDEX_putcr OR
index = INDEX_putcr1 ) )
THEN
status := STATUS_illegal
RETURN
END IF
-- inserts extra DOIT
-- but that's not allowed for
-- these instructions!
-- so quit
CHAPTER 2. VHDL SOURCE CODE
138
--- test for user mode violations
IF (NOT supervisor_mode) AND decode_table(index).usr THEN
---------
Memory instructions may or may not be user mode instructions. The
.usr flag is encoded with bit 9 of the opcode. It's only a user mode
violation if that bit is set for a memory operation. If it's not a
memory operation, then it is a user mode violation.
IF ( ( decode_table(index).op_type /= OP_load AND -- not memory operation
decode_table(index).op_type /= OP_store AND
decode_table(index).op_type /= OP_xmem ) OR
opcode(9) = '1' )
-- or is mem, and not user
THEN
status := STATUS_user
-- users can't do this
RETURN
END IF
END IF
IF decode_table(index).op_type = OP_trap THEN
tmpi := v1d2int( opcode(7 DOWNTO 0) )
-- find trap number
IF (NOT supervisor_mode) AND tmpi < 128 THEN
status := STATUS_user
-- users only trap above 127
RETURN
END IF
status := STATUS_trap + tmpi
RETURN
-- indicate trap
END IF
--- check deadlock problems
IF decode_table(index).bc THEN
-IF ( exceptions_ok OR
decode_table(index).op_type = OP_mvbr )
THEN
-new_br_count := new_br_count - 1
IF new_br_count < 0 THEN
-status := STATUS_lock_b0
new_br_count := br_count
new_xbr_count := xbr_count
RETURN
END IF
ELSE
-new_xbr_count := new_xbr_count - 1
IF new_xbr_count < 0 THEN
-status := STATUS_lock_b0
branch consumer (0 or 1)
using normal Branch Queue
deadlock
using X Branch Queue
deadlock
2.19. P DISPATCH.VHD
139
new_br_count := br_count
new_xbr_count := xbr_count
RETURN
END IF
END IF
END IF
IF decode_table(index).bp THEN
-IF ( exceptions_ok OR
decode_table(index).op_type = OP_ldbr )
THEN
-new_br_count := new_br_count + 1
IF new_br_count > BR_Max THEN
-status := STATUS_lock_b1
new_br_count := br_count
new_xbr_count := xbr_count
RETURN
END IF
ELSE
-new_xbr_count := new_xbr_count + 1
IF new_xbr_count > XBR_Max THEN
-status := STATUS_lock_b1
new_br_count := br_count
new_xbr_count := xbr_count
RETURN
END IF
END IF
END IF
branch producer (0 or 1)
using normal Branch Queue
deadlock
using X Branch Queue
deadlock
--- Must look at three fields to determine R1 consumer counts.
IF vA AND srcA
new_r1_count
END IF
IF vB AND srcB
new_r1_count
END IF
IF vD AND srcD
new_r1_count
END IF
= 1 THEN
:= new_r1_count - 1
= 1 THEN
:= new_r1_count - 1
= 1 THEN
:= new_r1_count - 1
IF new_r1_count + r1_pending < 0 THEN
status := STATUS_lock_r0
new_br_count := br_count
new_xbr_count := xbr_count
new_r1_count := r1_count
RETURN
END IF
-- deadlock
IF decode_table(index).dr AND dest = 1 THEN -- R1 producer
tellme := TRUE
-- need to know when done
new_r1_pending := r1_pending + 1
CHAPTER 2. VHDL SOURCE CODE
140
--- Should I check r1_count or new_r1_count to determine deadlock? I
--- think I can check new_r1_count, since nothing can actually issue
--- until the pipeline has cleared, and the R1 sources get used before
--- the new destinations are produced.
IF new_r1_count + new_r1_pending > R1_Max THEN -- deadlock
status := STATUS_lock_r1
new_br_count := br_count
new_xbr_count := xbr_count
new_r1_count := r1_count
new_r1_pending := r1_pending
RETURN
END IF
END IF
---------------
Now, if the R1 Queue can satisfy the operand requirements NOW, without
having to wait for pending operations to complete (because they might
not be successful), then I want to go ahead and dispatch instead of
blocking on the R1 scoreboard bit. I do this by clearing vA, vB, or vD
as needed, so that the scoreboard is not checked by the dispatch
routine. This doesn't affect the blocking due to the destination
register, which must take place if needed.
IF new_r1_count >=
IF vA AND srcA =
vA := FALSE
END IF
IF vB AND srcB =
vB := FALSE
END IF
IF vD AND srcD =
vD := FALSE
END IF
END IF
0 THEN
1 THEN
1 THEN
1 THEN
--- By getting this far, I've decoded everything with no faults.
END decode
--- packs variable values into RF operand request vector
----17
operand S requested
--- 16-12
operand S register number
--11
operand A requested
--- 10-6
operand A register number
--5
operand B requested
--4-0
operand B register number
--FUNCTION rf_encode ( CONSTANT vA
: BOOLEAN
CONSTANT srcA : INTEGER
CONSTANT vB
: BOOLEAN
2.19. P DISPATCH.VHD
141
CONSTANT srcB
CONSTANT vD
CONSTANT srcD
: INTEGER
: BOOLEAN
: INTEGER )
RETURN VLBIT_1D IS
VARIABLE result : VLBIT_1D( 17 DOWNTO 0 )
VARIABLE tmpv : VLBIT_1D( 31 DOWNTO 0 )
BEGIN
result( 17 ) := boo2vlb( vD )
tmpv := int2v1d( srcD )
result( 16 DOWNTO 12 ) := tmpv( 4 DOWNTO 0 )
result( 11 ) := boo2vlb( vA )
tmpv := int2v1d( srcA )
result( 10 DOWNTO 6 ) := tmpv( 4 DOWNTO 0 )
result( 5 ) := boo2vlb( vB )
tmpv := int2v1d( srcB )
result( 4 DOWNTO 0 ) := tmpv( 4 DOWNTO 0 )
RETURN result
END rf_encode
END p_dispatch
CHAPTER 2. VHDL SOURCE CODE
142
2.20 p memory unit.vhd
USE work.p_constants.ALL
PACKAGE p_memory_unit IS
PROCEDURE mem_decode( opcode
imm
opsize
scaled
do_sign_ext
force_usr_mode
do_load
do_store
:
:
:
:
:
:
:
:
IN VLBIT_1D (31 DOWNTO 0)
INOUT BOOLEAN
INOUT INTEGER
INOUT BOOLEAN
INOUT BOOLEAN
INOUT BOOLEAN
INOUT BOOLEAN
INOUT BOOLEAN )
:
:
:
:
:
:
:
:
IN VLBIT_1D (31 DOWNTO 0)
INOUT BOOLEAN
INOUT INTEGER
INOUT BOOLEAN
INOUT BOOLEAN
INOUT BOOLEAN
INOUT BOOLEAN
INOUT BOOLEAN )
END p_memory_unit
PACKAGE BODY p_memory_unit IS
PROCEDURE mem_decode( opcode
imm
opsize
scaled
do_sign_ext
force_usr_mode
do_load
do_store
IS
TYPE retval_type IS RECORD
imm
: BOOLEAN
opsize
: INTEGER
scaled
: BOOLEAN
do_sign_ext
: BOOLEAN
force_usr_mode
: BOOLEAN
do_load
: BOOLEAN
do_store
: BOOLEAN
END RECORD
VARIABLE retval
VARIABLE index
BEGIN
: retval_type
: INTEGER
index := op2index( opcode )
---------
This stuff had to be encoded by hand. I could have written a Perl
script to do it, but it would have taken longer than doing it manually.
This stuff shouldn't change that much (I hope). I also made some
assumptions about unused bits, which is probably okay.
CASE index IS
2.20. P MEMORY UNIT.VHD
WHEN 22 =>
retval :=
WHEN 24 =>
retval :=
WHEN 25 =>
retval :=
WHEN 26 =>
retval :=
WHEN 27 =>
retval :=
WHEN 28 =>
retval :=
WHEN 29 =>
retval :=
WHEN 30 =>
retval :=
WHEN 31 =>
retval :=
-- xmem rs,ra,imm16
( TRUE, 4, FALSE, FALSE, FALSE, TRUE, TRUE )
-- ld.bu rd,ra,imm16
( TRUE, 1, FALSE, FALSE, FALSE, TRUE, FALSE )
-- ld.b rd,ra,imm16
( TRUE, 1, FALSE, TRUE, FALSE, TRUE, FALSE )
-- ld.hu rd,ra,imm1
( TRUE, 2, FALSE, FALSE, FALSE, TRUE, FALSE )
-- ld.h rd,ra,imm16
( TRUE, 2, FALSE, TRUE, FALSE, TRUE, FALSE )
-- ld rd,ra,imm16
( TRUE, 4, FALSE, FALSE, FALSE, TRUE, FALSE )
-- st.b rs,ra,imm16
( TRUE, 1, FALSE, FALSE, FALSE, FALSE, TRUE )
-- st.h rs,ra,imm16
( TRUE, 2, FALSE, FALSE, FALSE, FALSE, TRUE )
-- st rs,ra,imm16
( TRUE, 4, FALSE, FALSE, FALSE, FALSE, TRUE )
WHEN 54 =>
-- xmem.usr] rs,ra,rb
retval := ( FALSE, 4, FALSE, FALSE, FALSE, TRUE, TRUE )
retval.scaled := vlb2boo( opcode(5) )
IF opcode(9) = '1' THEN
retval.force_usr_mode := TRUE
END IF
WHEN 56 =>
-- flavors of triadic load
retval.imm := FALSE
retval.force_usr_mode := vlb2boo( opcode(9) )
retval.scaled := vlb2boo( opcode(5) )
retval.opsize := 4
-- default size
IF opcode(8) = '1' THEN
-- half
retval.opsize := 2
END IF
IF opcode(7) = '1' THEN
-- byte overrides half
retval.opsize := 1
END IF
retval.do_sign_ext := vlb2boo( opcode(6) ) -- doesn't matter for word
retval.do_load := TRUE
retval.do_store := FALSE
WHEN 57 =>
-- lda rd,rarb]
retval := ( FALSE, 4, TRUE, FALSE, FALSE, FALSE, FALSE )
WHEN 58 =>
-- lda.h rd,rarb]
retval := ( FALSE, 2, TRUE, FALSE, FALSE, FALSE, FALSE )
WHEN 60 =>
-- flavors of triadic store
retval.imm := FALSE
retval.force_usr_mode := vlb2boo( opcode(9) )
retval.scaled := vlb2boo( opcode(5) )
retval.opsize := 4
-- default size
IF opcode(8) = '1' THEN
-- half
retval.opsize := 2
143
CHAPTER 2. VHDL SOURCE CODE
144
END IF
IF opcode(7) = '1' THEN
retval.opsize := 1
END IF
retval.do_sign_ext := FALSE
retval.do_load := FALSE
retval.do_store := TRUE
-- byte overrides half
WHEN OTHERS =>
putline("*** Illegal Opcode for Memory Unit ***")
retval := ( FALSE, 0, FALSE, FALSE, FALSE, FALSE, FALSE )
END CASE
imm := retval.imm
opsize := retval.opsize
scaled := retval.scaled
do_sign_ext := retval.do_sign_ext
force_usr_mode := retval.force_usr_mode
do_load := retval.do_load
do_store := retval.do_store
END mem_decode
END p_memory_unit
2.21. P OUTPUT.VHD
145
2.21 p output.vhd
---------------------------------------------------------------------------------- output utilities
-------------------------------------------------------------------------------
PACKAGE p_output IS
-- package declaration
--- function to print 32-bit integer values in hex
PROCEDURE puthex ( stuff : IN character_1d val : IN INTEGER )
--- function to print 32-bit integer values in hex followed by newline
PROCEDURE puthexline ( stuff : IN character_1d val : IN INTEGER )
END p_output
-- end of package declaration
------------------------------------------------------------------------------------------------------------------------------------------------------------PACKAGE BODY p_output IS
-- package body is here
--- local function to print one hex digit
--PROCEDURE puthexdigit (VARIABLE val : IN vlbit_vector( 3 DOWNTO 0) ) IS
VARIABLE dummy : INTEGER
BEGIN
dummy := v1d2int(val)
CASE dummy IS
WHEN 0 => put("0")
WHEN 1 => put("1")
WHEN 2 => put("2")
WHEN 3 => put("3")
WHEN 4 => put("4")
WHEN 5 => put("5")
WHEN 6 => put("6")
WHEN 7 => put("7")
WHEN 8 => put("8")
WHEN 9 => put("9")
WHEN 10 => put("A")
WHEN 11 => put("B")
WHEN 12 => put("C")
WHEN 13 => put("D")
WHEN 14 => put("E")
WHEN 15 => put("F")
WHEN OTHERS => put("?")
END CASE
END puthexdigit
--- package function to print integers as hex values
---
146
CHAPTER 2. VHDL SOURCE CODE
PROCEDURE puthex ( stuff : IN character_1d val : IN INTEGER ) IS
VARIABLE dummy : vlbit_vector (31 DOWNTO 0)
VARIABLE stupid : vlbit_vector (3 DOWNTO 0)
BEGIN
put(stuff)
dummy := int2v1d( val )
stupid := dummy(31 DOWNTO 28)
-- this is stupid, but it
puthexdigit( stupid )
-- complains if I don't do it.
stupid := dummy(27 DOWNTO 24)
puthexdigit( stupid )
stupid := dummy(23 DOWNTO 20)
puthexdigit( stupid )
stupid := dummy(19 DOWNTO 16)
puthexdigit( stupid )
stupid := dummy(15 DOWNTO 12)
puthexdigit( stupid )
stupid := dummy(11 DOWNTO 8)
puthexdigit( stupid )
stupid := dummy(7 DOWNTO 4)
puthexdigit( stupid )
stupid := dummy(3 DOWNTO 0)
puthexdigit( stupid )
END puthex
--- package function to print integers as hex values, followed by newline
--PROCEDURE puthexline ( stuff : IN character_1d val : IN INTEGER ) IS
VARIABLE dummy : vlbit_vector (31 DOWNTO 0)
VARIABLE stupid : vlbit_vector (3 DOWNTO 0)
BEGIN
put(stuff)
dummy := int2v1d( val )
stupid := dummy(31 DOWNTO 28)
-- this is stupid, but it
puthexdigit( stupid )
-- complains if I don't do it.
stupid := dummy(27 DOWNTO 24)
puthexdigit( stupid )
stupid := dummy(23 DOWNTO 20)
puthexdigit( stupid )
stupid := dummy(19 DOWNTO 16)
puthexdigit( stupid )
stupid := dummy(15 DOWNTO 12)
puthexdigit( stupid )
stupid := dummy(11 DOWNTO 8)
puthexdigit( stupid )
stupid := dummy(7 DOWNTO 4)
puthexdigit( stupid )
stupid := dummy(3 DOWNTO 0)
puthexdigit( stupid )
putline("")
END puthexline
END p_output
2.22. QFLOP.VHD
147
2.22 qop.vhd
-------------
A Q-flop allows a signal to be sampled on request. It generates an
acknowledge when the signal is no longer metastable. This implementation
is a little sloppy, but it will work for VHDL, since VHDL doesn't have
metastability problems. This cheats in some ways, since the input is
passed straight through to the output. That means you don't have to probe
if you don't want to.
ENTITY qflop IS
GENERIC( delay: TIME := 100 ps )
PORT (SIGNAL r
: IN VLBIT
SIGNAL a
: OUT VLBIT
SIGNAL i
: IN VLBIT
SIGNAL o
: OUT VLBIT)
END qflop
ARCHITECTURE behavior OF qflop IS
BEGIN
main : PROCESS
BEGIN
IF bitunknown(r) THEN
a <= '0'
ELSIF r'EVENT THEN
-- probe request
IF bitunknown(i) THEN
WAIT UNTIL NOT bitunknown(i)
END IF
o <= i
a <= r AFTER delay
ELSE
o <= i
END IF
WAIT ON r,i
END PROCESS main
END behavior
-- input change
CHAPTER 2. VHDL SOURCE CODE
148
2.23 registers.vhd
USE work.p_output.ALL
-------------
This implements the register bank. Incoming values are updated on the
outputs, and the scoreboard is cleared. I don't have to worry about
arbitration, since the scoreboard will prevent any outstanding registers
from being read.
ENTITY registers IS
GENERIC( delay: TIME := 100 ps )
PORT( SIGNAL clr
: IN
SIGNAL clr_sb
: OUT
SIGNAL clr_sb_ack
: IN
SIGNAL clr_sb_req
: OUT
SIGNAL r02
: OUT
SIGNAL r03
: OUT
SIGNAL r04
: OUT
SIGNAL r05
: OUT
SIGNAL r06
: OUT
SIGNAL r07
: OUT
SIGNAL r08
: OUT
SIGNAL r09
: OUT
SIGNAL r10
: OUT
SIGNAL r11
: OUT
SIGNAL r12
: OUT
SIGNAL r13
: OUT
SIGNAL r14
: OUT
SIGNAL r15
: OUT
SIGNAL r16
: OUT
SIGNAL r17
: OUT
SIGNAL r18
: OUT
SIGNAL r19
: OUT
SIGNAL r20
: OUT
SIGNAL r21
: OUT
SIGNAL r22
: OUT
SIGNAL r23
: OUT
SIGNAL r24
: OUT
SIGNAL r25
: OUT
SIGNAL r26
: OUT
SIGNAL r27
: OUT
SIGNAL r28
: OUT
SIGNAL r29
: OUT
SIGNAL r30
: OUT
SIGNAL r31
: OUT
SIGNAL rt0_a
: OUT
SIGNAL rt0_r
: IN
SIGNAL rt0_v
: IN
SIGNAL rt1_a
: OUT
SIGNAL rt1_r
: IN
SIGNAL rt1_v
: IN
SIGNAL rt2_a
: OUT
SIGNAL rt2_r
: IN
VLBIT
VLBIT_1D
VLBIT
VLBIT
VLBIT_1D
VLBIT_1D
VLBIT_1D
VLBIT_1D
VLBIT_1D
VLBIT_1D
VLBIT_1D
VLBIT_1D
VLBIT_1D
VLBIT_1D
VLBIT_1D
VLBIT_1D
VLBIT_1D
VLBIT_1D
VLBIT_1D
VLBIT_1D
VLBIT_1D
VLBIT_1D
VLBIT_1D
VLBIT_1D
VLBIT_1D
VLBIT_1D
VLBIT_1D
VLBIT_1D
VLBIT_1D
VLBIT_1D
VLBIT_1D
VLBIT_1D
VLBIT_1D
VLBIT_1D
VLBIT
VLBIT
VLBIT_1D
VLBIT
VLBIT
VLBIT_1D
VLBIT
VLBIT
(4 DOWNTO 0)
(31
(31
(31
(31
(31
(31
(31
(31
(31
(31
(31
(31
(31
(31
(31
(31
(31
(31
(31
(31
(31
(31
(31
(31
(31
(31
(31
(31
(31
(31
DOWNTO
DOWNTO
DOWNTO
DOWNTO
DOWNTO
DOWNTO
DOWNTO
DOWNTO
DOWNTO
DOWNTO
DOWNTO
DOWNTO
DOWNTO
DOWNTO
DOWNTO
DOWNTO
DOWNTO
DOWNTO
DOWNTO
DOWNTO
DOWNTO
DOWNTO
DOWNTO
DOWNTO
DOWNTO
DOWNTO
DOWNTO
DOWNTO
DOWNTO
DOWNTO
0)
0)
0)
0)
0)
0)
0)
0)
0)
0)
0)
0)
0)
0)
0)
0)
0)
0)
0)
0)
0)
0)
0)
0)
0)
0)
0)
0)
0)
0)
(36 DOWNTO 0)
(36 DOWNTO 0)
2.23. REGISTERS.VHD
SIGNAL
SIGNAL
SIGNAL
SIGNAL
END registers
149
rt2_v
rt3_a
rt3_r
rt3_v
:
:
:
:
IN
OUT
IN
IN
VLBIT_1D (36 DOWNTO 0)
VLBIT
VLBIT
VLBIT_1D (36 DOWNTO 0))
ARCHITECTURE behavior OF registers IS
BEGIN
main : PROCESS
--- type definitions
TYPE register_type IS ARRAY ( 0 TO 31 ) OF VLBIT_1D (31 DOWNTO 0)
--- internal variables
VARIABLE reg
: register_type -- registers
VARIABLE debug
VARIABLE trace
: BOOLEAN := FALSE
: BOOLEAN := FALSE
--- Input signal event variables. These are the events which wake up this
--- process, for various reasons.
VARIABLE
VARIABLE
VARIABLE
VARIABLE
l_rt0_r
l_rt1_r
l_rt2_r
l_rt3_r
:
:
:
:
VLBIT
VLBIT
VLBIT
VLBIT
--- output signal value variables
VARIABLE v_clr_sb_req
: VLBIT
--- scratch variables
VARIABLE
VARIABLE
VARIABLE
VARIABLE
VARIABLE
which_result
dest
stuff
tmpv
tmpi
:
:
:
:
:
INTEGER
INTEGER
VLBIT_1D (36 DOWNTO 0)
VLBIT_1D (31 DOWNTO 0)
INTEGER
BEGIN
----- If clear is asserted, reset everything and stick here.
--IF clr /= '1' THEN
FOR i IN 0 TO 31 LOOP
reg(i) := int2v1d( 0 )
-- reset to beginning
-- clear registers
CHAPTER 2. VHDL SOURCE CODE
150
END LOOP
which_result := 0
l_rt0_r := '0'
l_rt1_r := '0'
l_rt2_r := '0'
l_rt3_r := '0'
v_clr_sb_req := '0'
clr_sb_req <= v_clr_sb_req
clr_sb <= ('0','0','0','0','0')
rt0_a <= '0'
rt1_a <= '0'
rt2_a <= '0'
rt3_a <= '0'
r02
r03
r04
r05
r06
r07
r08
r09
r10
r11
r12
r13
r14
r15
r16
r17
r18
r19
r20
r21
r22
r23
r24
r25
r26
r27
r28
r29
r30
r31
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
reg(2)
reg(3)
reg(4)
reg(5)
reg(6)
reg(7)
reg(8)
reg(9)
reg(10)
reg(11)
reg(12)
reg(13)
reg(14)
reg(15)
reg(16)
reg(17)
reg(18)
reg(19)
reg(20)
reg(21)
reg(22)
reg(23)
reg(24)
reg(25)
reg(26)
reg(27)
reg(28)
reg(29)
reg(30)
reg(31)
WAIT UNTIL clr = '1'
ELSE
---- Normal running condition
-- wait till ready to run
-- unit is running
2.23. REGISTERS.VHD
-----------
151
The process loses events if I'm busy elsewhere, so I need to make
my own virtual wait statement, instead of relying on the actual
wait from VHDL. I'll just sample by hand, and only wait if there
are no pending requests. Since the REQ/ACK is paired, this will
work fine.
WHILE ( rt0_r
rt1_r
rt2_r
rt3_r
LOOP
/=
/=
/=
/=
l_rt0_r
l_rt1_r
l_rt2_r
l_rt3_r
OR
OR
OR
)
--- All result queues have this format:
----- 36-32
destination register
--- 31-0
value
--IF rt0_r /= l_rt0_r THEN
l_rt0_r := rt0_r
stuff := rt0_v
which_result := 0
ELSIF rt1_r /= l_rt1_r THEN
l_rt1_r := rt1_r
stuff := rt1_v
which_result := 1
ELSIF rt2_r /= l_rt2_r THEN
l_rt2_r := rt2_r
stuff := rt2_v
which_result := 2
ELSIF rt3_r /= l_rt3_r THEN
l_rt3_r := rt3_r
stuff := rt3_v
which_result := 3
ELSE
putline("*** What Happened? ***")
END IF
dest := v1d2int( stuff(36 DOWNTO 32) ) -- see where it goes
IF dest /= 0 AND dest /= 1 THEN
tmpv := stuff(31 DOWNTO 0)
reg(dest) := tmpv
IF debug OR trace THEN
tmpi := v1d2int(tmpv)
put("R",dest)
puthexline(" <= ",tmpi)
END IF
-- ignore writes to r0 and r1
-- write the new value
CHAPTER 2. VHDL SOURCE CODE
152
CASE dest IS
WHEN 2 =>
r02 <= tmpv
WHEN 3 =>
r03 <= tmpv
WHEN 4 =>
r04 <= tmpv
WHEN 5 =>
r05 <= tmpv
WHEN 6 =>
r06 <= tmpv
WHEN 7 =>
r07 <= tmpv
WHEN 8 =>
r08 <= tmpv
WHEN 9 =>
r09 <= tmpv
WHEN 10 =>
r10 <= tmpv
WHEN 11 =>
r11 <= tmpv
WHEN 12 =>
r12 <= tmpv
WHEN 13 =>
r13 <= tmpv
WHEN 14 =>
r14 <= tmpv
WHEN 15 =>
r15 <= tmpv
WHEN 16 =>
r16 <= tmpv
WHEN 17 =>
r17 <= tmpv
WHEN 18 =>
r18 <= tmpv
WHEN 19 =>
r19 <= tmpv
WHEN 20 =>
r20 <= tmpv
WHEN 21 =>
r21 <= tmpv
WHEN 22 =>
r22 <= tmpv
WHEN 23 =>
r23 <= tmpv
WHEN 24 =>
r24 <= tmpv
WHEN 25 =>
r25 <= tmpv
WHEN 26 =>
r26 <= tmpv
WHEN 27 =>
r27 <= tmpv
WHEN 28 =>
2.23. REGISTERS.VHD
153
r28 <= tmpv
WHEN 29 =>
r29 <= tmpv
WHEN 30 =>
r30 <= tmpv
WHEN 31 =>
r31 <= tmpv
WHEN OTHERS =>
NULL
END CASE
--- clear the scoreboard
IF debug THEN
tmpi := v1d2int(stuff(36 DOWNTO 32))
putline("clearing scoreboard bit ",tmpi)
END IF
clr_sb <= stuff(36 DOWNTO 32)
v_clr_sb_req := NOT v_clr_sb_req
clr_sb_req <= v_clr_sb_req AFTER delay
WAIT ON clr_sb_ack
END IF
IF which_result = 0 THEN
rt0_a <= rt0_r AFTER delay
ELSIF which_result = 1 THEN
rt1_a <= rt1_r AFTER delay
ELSIF which_result = 2 THEN
rt2_a <= rt2_r AFTER delay
ELSIF which_result = 3 THEN
rt3_a <= rt3_r AFTER delay
ELSE
putline("*** What Happened? ***")
END IF
END LOOP
END IF
WAIT ON clr, rt0_r, rt1_r, rt2_r, rt3_r
END PROCESS main
END behavior
-- main process loop
-- CLR not asserted
CHAPTER 2. VHDL SOURCE CODE
154
2.24 regselect.vhd
USE work.p_constants.ALL
USE work.p_output.ALL
---- This module puts together the operands for the EX Unit in response to the
---- requests from the IF Unit. If R1 operands are requested, I need to gather
---- them in the correct order.
ENTITY regselect IS
GENERIC( delay: TIME := 100 ps )
PORT( SIGNAL clr
: IN
SIGNAL op
: OUT
SIGNAL op_ack
: IN
SIGNAL op_req
: OUT
SIGNAL r1_q_ack
: OUT
SIGNAL r1_q
: IN
SIGNAL r1_q_req
: IN
SIGNAL rf
: IN
SIGNAL rf_ack
: OUT
SIGNAL rf_req
: IN
SIGNAL r02
: IN
SIGNAL r03
: IN
SIGNAL r04
: IN
SIGNAL r05
: IN
SIGNAL r06
: IN
SIGNAL r07
: IN
SIGNAL r08
: IN
SIGNAL r09
: IN
SIGNAL r10
: IN
SIGNAL r11
: IN
SIGNAL r12
: IN
SIGNAL r13
: IN
SIGNAL r14
: IN
SIGNAL r15
: IN
SIGNAL r16
: IN
SIGNAL r17
: IN
SIGNAL r18
: IN
SIGNAL r19
: IN
SIGNAL r20
: IN
SIGNAL r21
: IN
SIGNAL r22
: IN
SIGNAL r23
: IN
SIGNAL r24
: IN
SIGNAL r25
: IN
SIGNAL r26
: IN
SIGNAL r27
: IN
SIGNAL r28
: IN
SIGNAL r29
: IN
SIGNAL r30
: IN
SIGNAL r31
: IN
END regselect
VLBIT
VLBIT_1D
VLBIT
VLBIT
VLBIT
VLBIT_1D
VLBIT
VLBIT_1D
VLBIT
VLBIT
VLBIT_1D
VLBIT_1D
VLBIT_1D
VLBIT_1D
VLBIT_1D
VLBIT_1D
VLBIT_1D
VLBIT_1D
VLBIT_1D
VLBIT_1D
VLBIT_1D
VLBIT_1D
VLBIT_1D
VLBIT_1D
VLBIT_1D
VLBIT_1D
VLBIT_1D
VLBIT_1D
VLBIT_1D
VLBIT_1D
VLBIT_1D
VLBIT_1D
VLBIT_1D
VLBIT_1D
VLBIT_1D
VLBIT_1D
VLBIT_1D
VLBIT_1D
VLBIT_1D
VLBIT_1D
(95 DOWNTO 0)
(31 DOWNTO 0)
(17 DOWNTO 0)
(31
(31
(31
(31
(31
(31
(31
(31
(31
(31
(31
(31
(31
(31
(31
(31
(31
(31
(31
(31
(31
(31
(31
(31
(31
(31
(31
(31
(31
(31
DOWNTO
DOWNTO
DOWNTO
DOWNTO
DOWNTO
DOWNTO
DOWNTO
DOWNTO
DOWNTO
DOWNTO
DOWNTO
DOWNTO
DOWNTO
DOWNTO
DOWNTO
DOWNTO
DOWNTO
DOWNTO
DOWNTO
DOWNTO
DOWNTO
DOWNTO
DOWNTO
DOWNTO
DOWNTO
DOWNTO
DOWNTO
DOWNTO
DOWNTO
DOWNTO
0)
0)
0)
0)
0)
0)
0)
0)
0)
0)
0)
0)
0)
0)
0)
0)
0)
0)
0)
0)
0)
0)
0)
0)
0)
0)
0)
0)
0)
0) )
2.24. REGSELECT.VHD
155
ARCHITECTURE behavior OF regselect IS
BEGIN
main : PROCESS
--- output signal value variables
VARIABLE v_op_req
VARIABLE v_r1_q_ack
: VLBIT
: VLBIT
--- scratch variables
VARIABLE
VARIABLE
VARIABLE
VARIABLE
VARIABLE
VARIABLE
sel
tmpi
tmpv
op_a
op_b
op_s
:
:
:
:
:
:
INTEGER
INTEGER
VLBIT_1D
VLBIT_1D
VLBIT_1D
VLBIT_1D
(31
(31
(31
(31
DOWNTO
DOWNTO
DOWNTO
DOWNTO
0)
0)
0)
0)
--- internal variables
VARIABLE debug
: BOOLEAN := FALSE
BEGIN
----- If clear is asserted, reset everything and stick here.
--IF clr /= '1' THEN
-- reset to beginning
v_op_req := '0'
v_r1_q_ack := '0'
rf_ack <= '0'
op_req <= v_op_req
r1_q_ack <= v_r1_q_ack
op_s := ZERO(31 DOWNTO 0)
op_a := ZERO(31 DOWNTO 0)
op_b := ZERO(31 DOWNTO 0)
op <= ( op_s & op_a & op_b )
WAIT UNTIL clr = '1'
ELSE
-- wait till ready to run
-- unit is running
---- Normal running condition
--- RF operand request queue has this format:
----17
operand S requested
--- 16-12
operand S register number
CHAPTER 2. VHDL SOURCE CODE
156
-----------
11
10-6
5
4-0
operand
operand
operand
operand
A
A
B
B
requested
register number
requested
register number
--- Operand A.
IF rf(11) = '1' THEN
sel := v1d2int( rf(10 DOWNTO 6) )
CASE sel IS
WHEN 1 =>
IF r1_q_req = v_r1_q_ack THEN
WAIT UNTIL r1_q_req /= v_r1_q_ack
END IF
op_a := r1_q
v_r1_q_ack := r1_q_req
r1_q_ack <= v_r1_q_ack AFTER delay
WHEN 2 =>
op_a := r02
WHEN 3 =>
op_a := r03
WHEN 4 =>
op_a := r04
WHEN 5 =>
op_a := r05
WHEN 6 =>
op_a := r06
WHEN 7 =>
op_a := r07
WHEN 8 =>
op_a := r08
WHEN 9 =>
op_a := r09
WHEN 10 =>
op_a := r10
WHEN 11 =>
op_a := r11
WHEN 12 =>
op_a := r12
WHEN 13 =>
op_a := r13
WHEN 14 =>
op_a := r14
WHEN 15 =>
op_a := r15
WHEN 16 =>
op_a := r16
WHEN 17 =>
op_a := r17
WHEN 18 =>
op_a := r18
-- wait for it to be available
-- get it
-- ack it
2.24. REGSELECT.VHD
157
WHEN 19 =>
op_a := r19
WHEN 20 =>
op_a := r20
WHEN 21 =>
op_a := r21
WHEN 22 =>
op_a := r22
WHEN 23 =>
op_a := r23
WHEN 24 =>
op_a := r24
WHEN 25 =>
op_a := r25
WHEN 26 =>
op_a := r26
WHEN 27 =>
op_a := r27
WHEN 28 =>
op_a := r28
WHEN 29 =>
op_a := r29
WHEN 30 =>
op_a := r30
WHEN 31 =>
op_a := r31
WHEN OTHERS =>
op_a := ZERO(31 DOWNTO 0)
END CASE
IF debug THEN
put("op_a <= r",sel)
tmpi := v1d2int(op_a)
puthexline(" = ",tmpi)
END IF
END IF
--- Operand B.
IF rf(5) = '1' THEN
sel := v1d2int( rf(4 DOWNTO 0) )
CASE sel IS
WHEN 1 =>
IF r1_q_req = v_r1_q_ack THEN
WAIT UNTIL r1_q_req /= v_r1_q_ack
END IF
op_b := r1_q
v_r1_q_ack := r1_q_req
r1_q_ack <= v_r1_q_ack AFTER delay
WHEN 2 =>
-- wait for it to be available
-- get it
-- ack it
CHAPTER 2. VHDL SOURCE CODE
158
op_b := r02
WHEN 3 =>
op_b := r03
WHEN 4 =>
op_b := r04
WHEN 5 =>
op_b := r05
WHEN 6 =>
op_b := r06
WHEN 7 =>
op_b := r07
WHEN 8 =>
op_b := r08
WHEN 9 =>
op_b := r09
WHEN 10 =>
op_b := r10
WHEN 11 =>
op_b := r11
WHEN 12 =>
op_b := r12
WHEN 13 =>
op_b := r13
WHEN 14 =>
op_b := r14
WHEN 15 =>
op_b := r15
WHEN 16 =>
op_b := r16
WHEN 17 =>
op_b := r17
WHEN 18 =>
op_b := r18
WHEN 19 =>
op_b := r19
WHEN 20 =>
op_b := r20
WHEN 21 =>
op_b := r21
WHEN 22 =>
op_b := r22
WHEN 23 =>
op_b := r23
WHEN 24 =>
op_b := r24
WHEN 25 =>
op_b := r25
WHEN 26 =>
op_b := r26
WHEN 27 =>
op_b := r27
WHEN 28 =>
op_b := r28
WHEN 29 =>
2.24. REGSELECT.VHD
159
op_b := r29
WHEN 30 =>
op_b := r30
WHEN 31 =>
op_b := r31
WHEN OTHERS =>
op_b := ZERO(31 DOWNTO 0)
END CASE
IF debug THEN
put("op_b <= r",sel)
tmpi := v1d2int(op_b)
puthexline(" = ",tmpi)
END IF
END IF
--- Operand S.
IF rf(17) = '1' THEN
sel := v1d2int( rf(16 DOWNTO 12) )
CASE sel IS
WHEN 1 =>
IF r1_q_req = v_r1_q_ack THEN
WAIT UNTIL r1_q_req /= v_r1_q_ack
END IF
op_s := r1_q
v_r1_q_ack := r1_q_req
r1_q_ack <= v_r1_q_ack AFTER delay
WHEN 2 =>
op_s := r02
WHEN 3 =>
op_s := r03
WHEN 4 =>
op_s := r04
WHEN 5 =>
op_s := r05
WHEN 6 =>
op_s := r06
WHEN 7 =>
op_s := r07
WHEN 8 =>
op_s := r08
WHEN 9 =>
op_s := r09
WHEN 10 =>
op_s := r10
WHEN 11 =>
op_s := r11
WHEN 12 =>
op_s := r12
WHEN 13 =>
-- wait for it to be available
-- get it
-- ack it
CHAPTER 2. VHDL SOURCE CODE
160
op_s := r13
WHEN 14 =>
op_s := r14
WHEN 15 =>
op_s := r15
WHEN 16 =>
op_s := r16
WHEN 17 =>
op_s := r17
WHEN 18 =>
op_s := r18
WHEN 19 =>
op_s := r19
WHEN 20 =>
op_s := r20
WHEN 21 =>
op_s := r21
WHEN 22 =>
op_s := r22
WHEN 23 =>
op_s := r23
WHEN 24 =>
op_s := r24
WHEN 25 =>
op_s := r25
WHEN 26 =>
op_s := r26
WHEN 27 =>
op_s := r27
WHEN 28 =>
op_s := r28
WHEN 29 =>
op_s := r29
WHEN 30 =>
op_s := r30
WHEN 31 =>
op_s := r31
WHEN OTHERS =>
op_s := ZERO(31 DOWNTO 0)
END CASE
IF debug THEN
put("op_s <= r",sel)
tmpi := v1d2int(op_s)
puthexline(" = ",tmpi)
END IF
END IF
op <= ( op_s & op_a & op_b )
v_op_req := NOT v_op_req
op_req <= v_op_req AFTER delay
-- send operands out
2.24. REGSELECT.VHD
161
WAIT ON op_ack
-- wait for ACK
rf_ack <= rf_req AFTER delay
-- done with this event
END IF
WAIT ON clr, rf_req
END PROCESS main
END behavior
-- CLR not asserted
CHAPTER 2. VHDL SOURCE CODE
162
2.25 scoreboard.vhd
-------------------------------------
The scoreboard is a shared resource, so it is necessary for read and write
access to be mutually exclusive. This module contains the scoreboard
values, and enforces the exclusion.
Read operations are three-phase: a transition on RD_R requests a lock on
the register, and is granted by a transition on RD_G, indicating that the
OUT data is valid. The lock is released by a transition on RD_D. While
the read lock is granted, the BITS output is stable and valid.
Write operations are two-phase. The bit number of placed on the NUM input
bus, the value is placed on the SET port, and a transition is sent to
WR_R. A transition on WR_A indicates that the write is completed.
ENTITY scoreboard IS
GENERIC(delay: TIME := 100 ps )
PORT( SIGNAL clr
: IN VLBIT
SIGNAL rd_r
: IN VLBIT
SIGNAL rd_g
: OUT VLBIT
SIGNAL rd_d
: IN VLBIT
SIGNAL wr_r
: IN VLBIT
SIGNAL wr_a
: OUT VLBIT
SIGNAL set
: IN VLBIT
SIGNAL num
: IN VLBIT_1D (4 DOWNTO 0)
SIGNAL bits
: OUT VLBIT_1D (31 DOWNTO 0))
END scoreboard
ARCHITECTURE state_behavior OF scoreboard IS
TYPE states IS (wait_any,wait_done,wait_done_write)
BEGIN
main : PROCESS ( rd_r, wr_r, rd_d, clr )
VARIABLE state
: states := wait_any
VARIABLE v_bits
: VLBIT_1D (31 DOWNTO 0)
VARIABLE tmpi
: INTEGER
VARIABLE s_reads
: INTEGER
VARIABLE s_sets
: INTEGER
VARIABLE s_clears
: INTEGER
VARIABLE s_conflicts : INTEGER
BEGIN
IF ( clr /= '1' ) THEN
state := wait_any
v_bits := ( '0','0','0','0','0','0','0','0',
'0','0','0','0','0','0','0','0',
'0','0','0','0','0','0','0','0',
'0','0','0','0','0','0','0','0' )
bits <= v_bits
rd_g <= '0'
wr_a <= '0'
2.25. SCOREBOARD.VHD
163
s_reads := 0
s_sets := 0
s_clears := 0
s_conflicts := 0
ELSE
CASE state IS
WHEN wait_any =>
IF (rd_r'EVENT AND wr_r'EVENT) THEN
rd_g <= rd_r AFTER delay
state := wait_done_write
s_reads := s_reads + 1
s_conflicts := s_conflicts + 1
ELSIF (rd_r'EVENT) THEN
rd_g <= rd_r AFTER delay
state := wait_done
s_reads := s_reads + 1
ELSIF (wr_r'EVENT) THEN
tmpi := v1d2int(num)
v_bits(tmpi) := set
bits <= v_bits
wr_a <= wr_r AFTER delay
IF ( set = '1' ) THEN
s_sets := s_sets + 1
ELSE
s_clears := s_clears + 1
END IF
END IF
WHEN wait_done =>
IF (rd_d'EVENT AND wr_r'EVENT) THEN
tmpi := v1d2int(num)
v_bits(tmpi) := set
bits <= v_bits
wr_a <= wr_r AFTER delay
state := wait_any
IF ( set = '1' ) THEN
s_sets := s_sets + 1
ELSE
s_clears := s_clears + 1
END IF
ELSIF (rd_d'EVENT) THEN
state := wait_any
ELSIF (wr_r'EVENT) THEN
state := wait_done_write
s_conflicts := s_conflicts + 1
END IF
WHEN wait_done_write =>
IF (rd_d'EVENT) THEN
tmpi := v1d2int(num)
v_bits(tmpi) := set
-----
waiting for any request
got both, do read first
grant read permission
and wait for it to finish
-- else got rd_r only
-- send grant signal
-- wait for release
------
or got wr_r only
see which bit to write
change it
and update output
and return ack
--------
waiting for rd_d
got both, done with read
see which bit to write
change it
and update output
and return ack
wait for more stuff
-----
else
wait
else
wait
-----
wait for rd_d, then write
got rd_d, done with read
see which bit to write
change it
got
for
got
for
rd_d only
more stuff
wr_r only
release
CHAPTER 2. VHDL SOURCE CODE
164
bits <= v_bits
wr_a <= wr_r AFTER delay
state := wait_any
IF ( set = '1' ) THEN
s_sets := s_sets + 1
ELSE
s_clears := s_clears + 1
END IF
END IF
END CASE
END IF
END PROCESS main
END state_behavior
-- and update output
-- and return ack
-- wait for more stuff
--
state
2.26. VDELAY.VHD
2.26 vdelay.vhd
ENTITY vdelay IS
GENERIC( delay: TIME := 100 PS )
PORT (SIGNAL i :IN
VLBIT
SIGNAL o :OUT
VLBIT := '0')
END vdelay
ARCHITECTURE behavior OF vdelay IS
BEGIN
main : PROCESS ( i )
BEGIN
o <= i AFTER delay
END PROCESS main
END behavior
165
CHAPTER 2. VHDL SOURCE CODE
166
2.27 verify address.vhd
--- This verifies memory addresses. All it does it check to see if the
--- byte-address is greater than the limit, and if so it sets bit 0 in
--- the status output.
----- In an actual memory system, this could signal cache misses, write
--- protection, segment violation, and lots of other things. For my
--- purposes I just need some kind of memory fault to test.
----- Actually, there is some special behavior. This unit intercepts memory
--- requests, so that it can implement some special I/O functions. Any memory
--- access with address bit 31 set is used for some special I/O behavior. This
--- behavior is not part of the Fred architecture. I just added it so that I'd
--- have a simple way to generate circuit events from within an assembly
--- language program. I can use this to read and write from files, or to
--- wiggle a debugging pin.
--ENTITY verify_address IS
GENERIC( delay: TIME := 100 PS
maxaddr: INTEGER := 65535 )
PORT (SIGNAL clr
:IN
VLBIT
SIGNAL reqi
:IN
VLBIT
SIGNAL addr
:IN
VLBIT_VECTOR (31 downto 2)
SIGNAL acki
:IN
VLBIT
SIGNAL reqo
:OUT
VLBIT
SIGNAL acko
:OUT
VLBIT := '0'
SIGNAL s
:OUT
VLBIT_VECTOR (3 downto 0) := ('0','0','0','0')
SIGNAL wdata
:IN
VLBIT_1D(31 DOWNTO 0) -- write input data
SIGNAL read
:IN
VLBIT
-- read/write direction
SIGNAL mdata
:IN
VLBIT_1D(31 DOWNTO 0) -- memory read data in
SIGNAL xdata
:OUT
VLBIT_1D(31 DOWNTO 0) -- memory read data out
SIGNAL x_debug :OUT
VLBIT
-- for debugging only
SIGNAL y_debug :OUT
VLBIT)
-- for debugging only
END verify_address
ARCHITECTURE behavior OF verify_address IS
BEGIN
main : PROCESS
VARIABLE num
: INTEGER := 0
VARIABLE tmpi
: INTEGER
VARIABLE v_reqo
: VLBIT
VARIABLE v_x_debug
: VLBIT
VARIABLE v_y_debug
: VLBIT
VARIABLE bo
: BOOLEAN
VARIABLE rt
: TIME
FILE
stdin
: TEXT IS IN "Stdin.dat"
FILE
stdout
: TEXT IS OUT "Stdout.dat"
FILE
rtdelay
: TEXT IS IN "Random.dat"
VARIABLE trace_out
: BOOLEAN := FALSE -- display output
VARIABLE trace_in
: BOOLEAN := FALSE -- display output
BEGIN
IF clr /= '1' THEN
-- clear is asserted
2.27. VERIFY ADDRESS.VHD
167
num := 0
acko <= '0'
v_reqo := '0'
reqo <= v_reqo
s <= ('0','0','0','0')
v_x_debug := '0'
x_debug <= v_x_debug
v_y_debug := '0'
y_debug <= v_y_debug
-- reset outputs
WAIT ON reqi, acki, clr
-- wait for inputs
ELSE
-- running normally
WAIT ON reqi
-- wait for REQI event
num := v1d2int( addr ) * 4
-- get byte-address value
IF addr(31) = '1' THEN
-- special syscall behavior
num := v1d2int( addr(31 DOWNTO 28) ) -- get syscall number
CASE num IS
WHEN 8 =>
v_x_debug := NOT v_x_debug
x_debug <= v_x_debug
WHEN 9 =>
---------
-- 0x80000000 is times()
-- just wiggle a pin
-- 0x90000000 is interrupts
Anything to this address will generate an external interrupt
after an amount of time determined by reading the delay from
an external file. There should be enough random numbers in the
file to account for the needs of any simulation run.
freadline( rtdelay, tmpi, bo )
-- try to read it
ASSERT bo REPORT "Couldn't read random.dat" SEVERITY FAILURE
rt := 1 NS * tmpi
-- determine the time
putline("generating interrupt in ",rt)
v_y_debug := NOT v_y_debug
y_debug <= v_y_debug AFTER rt
WHEN 12 =>
-- 0xC0000000 is file I/O
--- The data that is read or written appears in the file as decimal
--- integers, one per line. The value read is a signed 32-bit
CHAPTER 2. VHDL SOURCE CODE
168
--- quantity. I ignore the byte strobes and read or write the
--- entire 32-bit value. I essentially treat the file access as
--- the implementation of the getc() and putc() functions.
IF read = '1' THEN
-- read a byte from the file
freadline( stdin, tmpi, bo )
-- try to read it
IF bo THEN
xdata <= int2v1d( tmpi )
ELSE
xdata <= int2v1d( -1 )
END IF
-- it worked
-- so return the byte value
-- return EOF on failure
IF (trace_in) THEN
putline("STDIN = ",tmpi)
END IF
ELSE
-- write a byte to the file
tmpi := v1d2int( wdata(7 DOWNTO 0) ) -- this value
fwriteline( stdout, tmpi, bo )
-- write it and make sure
ASSERT bo REPORT "Couldn't write stdout" SEVERITY FAILURE
IF (trace_out) THEN
putline("STDOUT = ",tmpi)
END IF
END IF
WHEN OTHERS =>
putline("Unimplemented system call ",num)
END CASE
s <= ('0','0','0','0')
-- memory status is okay
acko <= reqi AFTER delay
-- send ACKO
ELSIF ( num > maxaddr ) THEN
-- invalid address
s <= ('0','0','0','1')
acko <= reqi AFTER delay
ELSE
-- report memory status
-- valid address
--- Pass request on to memory immediately. The zero delay is not
--- realistic, but there's already enough delay in the memory system
2.27. VERIFY ADDRESS.VHD
169
--- so that this doesn't make any difference.
v_reqo := NOT v_reqo
reqo <= v_reqo
s <= ('0','0','0','0')
-- memory status is okay
WAIT ON acki
-- wait for ACKI
xdata <= mdata
-- pass data through, too
--- This would be the perfect place to put in some unexpected random
--- delay to model a cache miss.
acko <= reqi
END IF
END IF
END PROCESS main
END behavior
-- send ACKO
CHAPTER 2. VHDL SOURCE CODE
170
2.28 zdelay.vhd
------- This is a simple delay module. The delay time can be changed at
---- simulation run-time. The default delay is zero.
---ENTITY zdelay IS
PORT (SIGNAL i :IN
SIGNAL o :OUT
END zdelay
VLBIT
VLBIT := '0')
ARCHITECTURE behavior OF zdelay IS
BEGIN
main : PROCESS ( i )
VARIABLE delay : TIME := 0 NS
BEGIN
o <= i AFTER delay
END PROCESS main
END behavior
2.29. ZXOR.VHD
171
2.29 zxor.vhd
------- This is an XOR with no delay.
---- wire-or.
---ENTITY zxor IS
PORT (SIGNAL a :IN
SIGNAL b :IN
SIGNAL y :OUT
END zxor
It is the self-timed equivalent of a
VLBIT
VLBIT
VLBIT := '0')
ARCHITECTURE behavior OF zxor IS
BEGIN
main : PROCESS ( a, b )
VARIABLE delay : TIME := 0 NS
BEGIN
y <= a XOR b AFTER delay
END PROCESS main
END behavior
172
CHAPTER 2. VHDL SOURCE CODE
Chapter 3
Schematic Diagrams
173
174
A1
R1
CLR
CLR
G1
R1
D1
A1
G0
R2
D0
A2
Figure 3.1: arbcall
R1
Arb
ARBITER
RS
RS
AS
AS
Call
R0
W
W
R0
A0
Processor
William
F.
Design
Richardson
Arbitrated
Call
Element
CHAPTER 3. SCHEMATIC DIAGRAMS
Fred
A1
R1
CLR
CLR
G1
R1
D1
A1
G0
R2
D0
A2
AS
RS
AS
Y[79:64]
R0
A[15:0]
W
W
X[79:64]
R0
A0
OUT[15:0]
O
Vdelay
Call
B[15:0]
I
RS
ARBITER
Z[79:64]
SEL
Arb
MUX-2x16
R1
Figure 3.2: arbcallx88
X[87:0]
S
Y[87:0]
Y[87:80]
B[7:0]
Y[7:0]
Z[87:80]
Z[87:0]
MUX2x8
X[87:80]
A[7:0]
Y[63:32]
B[31:0]
S
Y[31:0]
Z[63:32]
MUX2x32
X[63:32]
A[31:0]
S
Y[31:0]
B[31:0]
Y[31:0]
Z[31:0]
MUX2x32
X[31:0]
Fred
Processor
William
F.
Design
Richardson
A[31:0]
Arbitrated
Call
with
88-bit
Data
175
176
I31
A
I30
A
I29
A
Y
O31
Y
O30
Y
O29
Y
O28
Y
O27
Y
O26
Y
O25
Y
O24
Y
O23
Y
O22
Y
O21
Y
O20
Y
O19
Y
O18
Y
O17
Y
O16
Y
O15
Y
O14
Y
O13
Y
O12
Y
O11
Y
O10
Y
O9
Y
O8
Y
O7
Y
O6
Y
O5
Y
O4
Y
O3
Y
O2
Y
O1
Y
O0
BUF
BUF
BUF
I28
A
I27
A
I26
A
I25
A
I24
A
BUF
BUF
BUF
BUF
I[31:0]
O[31:0]
BUF
I23
A
I22
A
I21
A
I20
A
I19
A
BUF
BUF
BUF
BUF
BUF
Figure 3.3: buf32
I18
A
I17
A
I16
A
I15
A
I14
A
BUF
BUF
BUF
BUF
BUF
A
I12
A
I11
A
I10
A
I9
A
BUF
BUF
BUF
BUF
BUF
I8
A
I7
A
I6
A
I5
A
I4
A
BUF
BUF
BUF
BUF
BUF
Fred
Processor
William
F.
Design
Richardson
I3
A
I2
A
I1
A
I0
A
32-bit
BUF
BUF
BUF
BUF
buffer
[for
aliasing]
CHAPTER 3. SCHEMATIC DIAGRAMS
I13
I[3:0]
Figure 3.4: buf4
I3
A
I2
A
I1
A
I0
A
Y
O3
Y
O2
Y
O1
Y
O0
BUF
BUF
BUF
O[3:0]
Fred
Processor
William
F.
Design
Richardson
4-bit
buffer
BUF
[for
aliasing]
177
178
I7
A
I6
A
I5
A
I4
A
I3
A
I2
A
I1
A
I0
A
Y
O7
Y
O6
Y
O5
Y
O4
Y
O3
Y
O2
Y
O1
Y
O0
BUF
BUF
BUF
BUF
I[7:0]
BUF
Figure 3.5: buf8
BUF
BUF
O[7:0]
Processor
William
F.
Design
Richardson
8-bit
buffer
[for
aliasing]
CHAPTER 3. SCHEMATIC DIAGRAMS
Fred
BUF
R1
R1
A1
A1
RS
Call
I
O
Vdelay
R2
A0
A2
RS
AS
AS
R0
A
B
Figure 3.6: callx32
XOR
Y
S
Y[31:0]
B[31:0]
Y[31:0]
Z[31:0]
MUX2x32
X[31:0]
Fred
Processor
William
F.
Design
Richardson
A[31:0]
Non-Arbitrated
Call
with
32-bit
Data
179
180
RI
RO
A
B
CLR
Delay1 OUT
IN
OUT Delay1
IN
OUT
MC
C
Figure 3.7: cp-delay
AO
AI
This
Fred
Processor
William
F.
Design
Richardson
is
does
used
not
to
model
actually
Capture-Pass
the
delay
of
latch
any
data
latch
a
Capture/Pass
on
delay
its
latch.
own.
circuit.
CHAPTER 3. SCHEMATIC DIAGRAMS
It
RX14
RX13
CLR
CLR
A
RX15
RI
RO
AX15
AI
AO
RX12
B
Z
CLR
A
Y
RI
RO
AI
AO
B
AX14
Z
A
Y
RI
RO
AI
AO
B
AX13
Z
Y
AX12
CLR
TAP
CLR
Delay
Tap
RX11
RIN
RIN
RX[15:0]
RX[15:0]
AIN
AIN
AX[15:0]
AX[15:1],AOUT
RX10
CLR
CLR
A
Figure 3.8: delaychain
RI
RO
AI
AO
B
Z
Y
RI
RO
AI
AO
B
RX7
AI
AO
B
Z
RI
RO
AI
AO
B
Z
Processor
William
F.
Design
Richardson
Delay
Chain
for
RI
RO
AI
AO
A
Y
RI
RO
AI
AO
B
Z
RI
RO
AI
AO
B
Z
A
Y
RI
RO
AI
AO
AX5
AX2
RI
RO
AI
AO
Z
Y
RX0
CLR
A
Y
B
AX4
CLR
Z
Y
RX4
RX1
B
Z
CLR
A
Y
B
AX8
RX5
A
Y
Z
AX9
CLR
AX3
Fred
AO
RX2
A
AO
AI
B
AX6
CLR
AI
RO
CLR
A
Y
RX3
RO
RI
RX6
AX7
RI
Y
CLR
A
RO
Z
CLR
A
AX10
CLR
RX8
CLR
A
AX11
RI
RX9
B
Z
A
Y
RI
RO
AI
AO
B
Z
Y
ROUT
AOUT
AX1
FIFO
181
182
REQ
S0
S4
SEL
SEL
A
OUTF
B
SELECT
XOR
Y
Y
A
XOR
OUTF
B
SELECT
IN
IN
OUTT
OUTT
CLR
CLR
R0
A0
A
CLR
B
A
C
OUT
OUT
C
A4
R4
CLR
B
S1
S5
SEL
SEL
B
XOR
Y
Y
A
XOR
OUTF
B
SELECT
IN
IN
OUTT
OUTT
CLR
CLR
R1
A1
A5
R5
CLR
CLR
A
B
A
C
OUT
OUT
C
B
S2
S6
SEL
SEL
XOR
Y
A
B
B
A
OUTF
Y
A
XOR
OUTF
B
SELECT
C
SELECT
IN
IN
OUT
OUTT
CLR
R2
A2
OUTT
CLR
A
CLR
B
A
C
OUT
OUT
C
A6
R6
CLR
B
S3
S7
SEL
OUTF
A
SELECT
B
XOR
Y
Y
XOR
A
SEL
OUTF
B
SELECT
ACK
IN
IN
OUTT
OUTT
CLR
CLR
R3
A3
A7
CLR
Fred
Processor
William
F.
Design
Richardson
Distributor
R7
CLR
Circuit
CHAPTER 3. SCHEMATIC DIAGRAMS
Figure 3.9: distributor
A
OUTF
SELECT
EX[127:0]
OP[95:0]
FU_A
CLR
CLR
FU_arith
D_REQ
DT0_R
D_ACK
DT0_A
RIN
AIN
DONE[87:0]
EX[90:87]
EX86
Operand
DT0_T[87:0]
EXTRA[3:0]
TELLME
EX[76:69]
TAG[7:0]
EX[68:64]
DEST[4:0]
Select
ROUT
RT0_R
AOUT
RT0_A
RES[36:0]
EX[31:0]
RT0_V[36:0]
OPCODE[31:0]
EX85
XOP[63:32]
RQ_REQ
RQ0_R
RQ_ACK
RQ0_A
OP_A[31:0]
OP[31:0]
OP_B[31:0]
RQ[31:0]
RQ0_V[31:0]
CLR
SEL
OUTF
R1
FU_L
CLR
SELECT
EX_REQ
CLR
CLR
A1
IN
RS
REQ
R0
AS
ACK
A0
FU_logic
Call
OUTT
A
CLR
C
B
OUT
R2
Figure 3.10: ex-unit1
CLR
OP_REQ
Functional
OP_ACK
EX_ACK
EX77
EX78
EX79
S0
S1
S2
Unit
EX80
S3
EX81
S4
EX82
S5
EX83
S6
EX84
S7
Distributor
A2
R1
RIN
A1
AIN
D_REQ
DT1_R
D_ACK
DT1_A
DONE[87:0]
R2
EX[90:87]
A2
EX86
TELLME
R3
MEM_UNIT_REQ
EX[76:69]
TAG[7:0]
A3
MEM_UNIT_ACK
EX[68:64]
DEST[4:0]
R4
BR_UNIT_REQ
EX[31:0]
A4
BR_UNIT_ACK
XOP[63:32]
OP_A[31:0]
OP[31:0]
OP_B[31:0]
ROUT
RT1_R
AOUT
RT1_A
RES[36:0]
R5
DT1_T[87:0]
EXTRA[3:0]
RT1_V[36:0]
OPCODE[31:0]
RQ_REQ
RQ1_R
RQ_ACK
RQ1_A
RQ[31:0]
RQ1_V[31:0]
A5
R6
A6
FU_C
CLR
CLR
R7
FU_control
A7
ZeroA
RIN
D_REQ
DT2_R
AIN
D_ACK
DT2_A
EX90
EX[90:87]
ZZZOP[63:32]
S
EX86
B[31:0]
Zerox32
Y[31:0]
DONE[87:0]
EX[76:69]
TAG[7:0]
EX[68:64]
DEST[4:0]
EX[63:32]
PC[31:0]
ROUT
RT2_R
AOUT
RT2_A
EX[31:0]
A[31:0]
RES[36:0]
Processor
William
F.
Design
Richardson
Execution
Unit
Dispatching
RT2_V[36:0]
OPCODE[31:0]
RQ_REQ
RQ2_R
XOP[63:32]
OP_A[31:0]
RQ_ACK
RQ2_A
OP[31:0]
OP_B[31:0]
RQ[31:0]
RQ2_V[31:0]
PUTCR_REQ
PUTCR_REQ
PUTCR_ACK
PUTCR_ACK
PUTCR[31:0]
PUTCR[31:0]
CR_NUM[9:0]
CR_NUM[9:0]
GETCR_REQ
GETCR_REQ
GETCR_ACK
GETCR_ACK
GETCR[31:0]
Fred
DT2_T[87:0]
TELLME
XOP[63:32]
MUX2x32
OP[63:32]
EXTRA[3:0]
GETCR[31:0]
Logic
183
184
CLR
FU_M
CLR
CLR
CLR
DT0_R
R1
DT0_A
A1
DT0_T[87:0]
Y
DT1_R
R0
DT1_A
A0
DT1_T[87:0]
X
FU_memory
MEM_UNIT_REQ
RIN
MEM_UNIT_ACK
AIN
Arb
Call
x88
RS
AS
EX[90:87]
EX86
EXTRA[3:0]
Z
CLR
TELLME
EX[76:69]
TAG[7:0]
EX[68:64]
DEST[4:0]
CR0[31:0]
CR0[31:0]
CLR
R1
W
EX[31:0]
OPCODE[31:0]
OP[95:64]
OP_S[31:0]
XOP[63:32]
OP_A[31:0]
OP[31:0]
OP_B[31:0]
A1
AA[87:0]
R0
D_REQ
DT3_R
DT3_A
DATA_REQ
DATA_REQ
D_ACK
DATA_ACK
DATA_ACK
DONE[87:0]
DATA_ACK_ACK
READ
CLR
Figure 3.11: ex-unit2
D_WRITE[31:0]
READ
REG_Q_REQ
RT3_R
BYTE_STROBE[3:0]
REG_Q_ACK
RT3_A
R1
DT2_A
A1
DT2_T[87:0]
Y
CLR
D_ADDR[31:0]
REG_Q[36:0]
RT3_V[36:0]
DONE[87:0]
W
Arb
Call
x88
D_WRITE[31:0]
R1_Q_REQ
RQ3_R
D_READ[31:0]
R1_Q_ACK
RQ3_A
D_STATUS[3:0]
R1_Q[31:0]
RS
AS
Arb
Y Call
x88
R0
D_STATUS[3:0]
DONE_ACK
Z
A0
CLR
DT2_R
RS
R0
Z
Z
A0
AS
D_READ[31:0]
DONE_REQ
AS
BB[87:0]X
CLR
DT3_T[87:0]
A1
D_ADDR[31:0]
RS
DATA_ACK_ACK
R1
BYTE_STROBE[3:0]
Arb
Y Call
x88
CC[87:0]
X
RQ3_V[31:0]
A0
W
X
W
FU_B
CLR
CLR
FU_branch
BR_UNIT_REQ
RIN
BR_UNIT_ACK
AIN
EX[90:87]
EXTRA[3:0]
TAG[7:0]
EX[68:64]
DEST[4:0]
EX[63:32]
PC[31:0]
RQ0_R
R1
D_REQ
DT4_R
RQ0_A
A1
D_ACK
DT4_A
RQ0_V[31:0]
Y
The
DONE[87:0]
EX[31:0]
CR0[31:0]
TELLME
EX[76:69]
Call
x32
DT4_T[87:0]
OP_A[31:0]
OP[31:0]
OP_B[31:0]
Queue
arbitrated,
doesn’t
since
have
to
be
that
is
done
by
RS
R1_Q_REQ
AS
R1_Q_ACK
Z
R1_Q[31:0]
AS
OPCODE[31:0]
XOP[63:32]
R1
RS
the
RQ1_R
R0
BR_REQ
BR_REQ
RQ1_A
A0
BR_ACK
BR_ACK
RQ1_V[31:0]
X
Dispatch
Unit.
Z
R1
BR[31:0]
BR[31:0]
A1
PREFETCH_REQ
PF_REQ
XBR_REQ
XBR_REQ
PREFETCH_ACK
PF_ACK
XBR_ACK
XBR_ACK
PREFETCH[31:0]
Fred
Processor
William
F.
Design
Richardson
PF[31:0]
XBR[31:0]
Execution
Unit
RQ2_R
R1
RQ2_A
A1
RQ2_V[31:0]
Y
AAR1_Q[31:0] Y
Call
x32
XBR[31:0]
Completion
Routing
RQ3_R
R0
RQ3_A
A0
RQ3_V[31:0]
X
Call
x32
RS
R0
AS
A0
Z
BBR1_Q[31:0]
X
CHAPTER 3. SCHEMATIC DIAGRAMS
CR0[31:0]
EX86
RIN
OUT Delay2 IN
MC
OUT
OUT Delay1
C
AIN
A
B
CLR
AOUT
IN
Rin fanin is 1
Ain drives 0
ROUT
P
Aout fanin is 5
OUT[31:0]
C
IN[31:0]
IN[31:0]
TLNT
Figure 3.12: fo-32
Rout drives 0
OUT[31:0]
Clr fanin is 1
In fanin is 2
Out drives 2
Total Modules: 47
Fred
Processor
William
F.
Design
Richardson
32-bit
FIFO
185
186
RIN
OUT Delay2
MC
OUT
OUT Delay1
C
AIN
A
B
CLR
AOUT
IN
IN
ROUT
IN35
IN[35:32]
D
Q
TLNT
C
OUT35
P
Figure 3.13: fo-36
OUT[35:32]
IN34
D
Q
TLNT
C
OUT34
P
IN33
D
Q
TLNT
C
OUT33
P
IN32
D
Q
TLNT
C
OUT32
Processor
William
F.
Design
Richardson
36-bit
FIFO,
divided
into
P
a
OUT[31:0]
C
Fred
TLNT
IN[31:0]
IN[31:0]
OUT[31:0]
32-bit
input
and
a
4-bit
input
CHAPTER 3. SCHEMATIC DIAGRAMS
P
VERIFY_ADDRESS
VHDL=VERIFY_ADDRESS
MAXADDR=65535
Y_DEBUG
Y_DEBUG
X_DEBUG
X_DEBUG
Memory
Latches
S[3:0]
XSTATUS[3:0]
XI_A
INST_REQ
REQO
REQI
ACKI
ACKO
INST_REQ
OUT Delay1 IN
XI_AA
I
INST_ACK
O
IDELAY
INST_ACK
CLR
RAM
INST_ACK_ACK
INST_ACK_ACK
I_ADDR[31:0]
I_ADDR[31:0]
I_DATA[31:0]
I_DATA[31:0]
MDATA[31:0]
RAM 64K
(16Kx32)
CLR
XDATA[31:0]
XDATA[31:0]
WDATA[31:0]
XD_WRITE[31:0]
R1
G1
A1
D1
R2
G0
A2
D0
R1
READ
XI_R
Arb
RS
Call
AS
REQ
ADDR[31:2]
I_STATUS[3:0]
CLR
R0
ACK
I_STATUS[3:0]
XD_R
W
READ[31:0]
MDATA[31:0]
CLR
DATA_REQ
DATA_REQ
ADDR[31:2]
MEM_ARBITER
RD
XD_AA
I
DATA_ACK
O
DDELAY
DATA_ACK
BYTES[3:0]
Figure 3.14: fred-memory
XD_A
WRITE[31:0]
DATA_ACK_ACK
DATA_ACK_ACK
XD_WRITE[31:0]
S
READ
B[31:2]
READ
XI_ADDR[31:2]
BYTE_STROBE[3:0]
BYTE_STROBE[3:0]
Y[31:2]
XI_ADDR[31:0]
A[31:2]
XIA[31:0]
D_ADDR[31:0]
MUX2x30
XD_ADDR[31:0]
A[31:2]
D_ADDR[31:0]
XDA[31:0]
XD_ADDR[31:2]
D_WRITE[31:0]
XSTATUS[3:0]
D_WRITE[31:0]
XS[3:0]
D_READ[31:0]
XDATA[31:0]
D_READ[31:0]
XDATA[31:0]
D_STATUS[3:0]
D_STATUS[3:0]
VDD
XD_WRITE[31:0]
B
XDW[31:0]
MX2
Y
XREAD
A
S
XBS[3:0]
CLR
S
VDD,VDD,VDD,VDD
B[3:0]
CLR
Y[3:0]
B[3:0]
MUX2x4
XBYTE_STROBE[3:0]
A[3:0]
The
prefetch
since
data
the
controller
the
Delay
Address
times:
Minimum
memory
Increase
IDELAY
delay
and
delay
with
DDELAY
is
2ns.
variable
Bits
inside
modules.
best
is
not
used,
memory
is
fast.
A
would
be
needed
to
use
of
OUT Delay1
IN
the
prefetch
cache
make
data.
bits:
are
the
word
Bit
1
31-2
is
used
for
the
Bit
0
is
currently
address.
User/Supervisor
unused.
PREFETCH_REQ
mode.
PREFETCH_ACK
PREFETCH[31:0]
Fred
Processor
William
F.
Design
Richardson
System
Memory
187
188
MEMORY
FRED
Memory
Fred Processor
INST_REQ
INST_REQ
INST_REQ
INST_ACK
INST_ACK
INST_ACK
INST_ACK_ACK
INST_ACK_ACK
INST_ACK_ACK
I_ADDR[31:0]
I_ADDR[31:0]
I_ADDR[31:0]
I_DATA[31:0]
I_DATA[31:0]
I_DATA[31:0]
I_STATUS[3:0]
I_STATUS[3:0]
I_STATUS[3:0]
Figure 3.15: fred-with-mem
PREFETCH_REQ
PREFETCH_REQ
PREFETCH_REQ
PREFETCH_ACK
PREFETCH_ACK
PREFETCH_ACK
PREFETCH[31:0]
purposes.
PREFETCH[31:0]
PREFETCH[31:0]
Y_DEBUG
DATA_REQ
DATA_REQ
DATA_REQ
DATA_ACK
DATA_ACK
DATA_ACK
testing
DATA_ACK_ACK
DATA_ACK_ACK
READ
READ
DATA_ACK_ACK
READ
BYTE_STROBE[3:0]
BYTE_STROBE[3:0]
BYTE_STROBE[3:0]
D_ADDR[31:0]
D_ADDR[31:0]
D_WRITE[31:0]
just
D_WRITE[31:0]
D_WRITE[31:0]
D_READ[31:0]
D_READ[31:0]
D_READ[31:0]
D_STATUS[3:0]
D_STATUS[3:0]
D_STATUS[3:0]
This
is
CLR
INT
CLR
A
B
XOR
CLR
Y
INT
SYNC_REQ
SYNC_REQ
SYNC_ACK
SYNC_ACK
SYNC_NACK
Fred
Processor
William
F.
SYNC_NACK
Design
Richardson
Complete
Fred
System
with
Memory
CHAPTER 3. SCHEMATIC DIAGRAMS
for
D_ADDR[31:0]
CLR
IF_UNIT
CLR
IF
INST_REQ
INST_REQ
INST_ACK
INST_ACK
Unit
CR0[31:0]
CR0[31:0]
PUTCR_REQ
PUTCR_REQ
PUTCR_ACK
PUTCR_ACK
PUTCR[31:0]
PUTCR[31:0]
CR_NUM[9:0]
CR_NUM[9:0]
GETCR_REQ
GETCR_REQ
GETCR_ACK
GETCR_ACK
GETCR[31:0]
INST_ACK_ACK
INST_ACK_ACK
I_ADDR[31:0]
I_ADDR[31:0]
I_DATA[31:0]
I_DATA[31:0]
I_STATUS[3:0]
GETCR[31:0]
I_STATUS[3:0]
Figure 3.16: fred1
INT
CLR_SB_REQ
CLR_SB_REQ
CLR_SB_ACK
CLR_SB_ACK
INT
CLR_SB[4:0]
CLR_SB[4:0]
CLR
PIPE_RF
SYNC_REQ
SYNC_REQ
SYNC_ACK
SYNC_ACK
SYNC_NACK
CLR
RF_REQ
RIN
RF_ACK
AIN
PIPE_Nx18
ROUT
RF_REQ
AOUT
RF_ACK
SYNC_NACK
RF[17:0]
BR_REQ
BR_REQ
BR_ACK
BR_ACK
O[17:0]
RF[17:0]
AAARF[17:0]
XBR_ACK
XBR_ACK
XBR[31:0]
XBR[31:0]
EX[127:0]
XBR_REQ
EX_ACK
BR[31:0]
XBR_REQ
EX_REQ
BR[31:0]
I[17:0]
DONE_REQ
DONE_REQ
DONE_ACK
DONE_ACK
DONE[87:0]
DONE[87:0]
CLR
PIPE_EX
CLR
EX_REQ
ROUT
EX_ACK
AOUT
EX[127:0]
RIN
PIPE_Nx128
O[127:0]
AIN
I[127:0]
AAAEX[127:0]
Fred
Processor
William
F.
Design
Richardson
Instruction
Fetch
Unit.
189
190
CLR
RF_UNIT
CLR
CLR
Register
File
PIPE_CLR
CLR
CLR_SB_REQ
ROUT
CLR_SB_ACK
AOUT
CLR_SB[4:0]
RIN
PIPE_Nx5
O[4:0]
CLR_SB_REQ
AIN
I[4:0]
CLR_SB_ACK
AAACLR_SB[4:0]
CLR_SB[4:0]
RF_REQ
RF_REQ
RF_ACK
RF_ACK
CLR
RF[17:0]
RF[17:0]
PIPE_OP
CLR
OP_REQ
RIN
Figure 3.17: fred2
OP_ACK
RT0_R
RT0_R
RT0_A
RT0_A
RT0_V[36:0]
RT1_A
RT1_A
RT1_R
RT2_A
RT2_A
RT2_R
Processor
William
F.
Design
Richardson
Register
File
ROUT
OP_REQ
AOUT
OP_ACK
O[95:0]
OP[95:0]
RT3_R
RT3_V[36:0]
R1_Q_REQ
R1_Q_REQ
R1_Q_ACK
R1_Q_ACK
R1_Q[31:0]
CHAPTER 3. SCHEMATIC DIAGRAMS
RT3_A
RT3_A
R1_Q[31:0]
Fred
RT2_V[36:0]
RT3_R
RT3_V[36:0]
PIPE_Nx96
I[95:0]
RT1_V[36:0]
RT2_R
RT2_V[36:0]
AIN
AAAOP[95:0]
RT0_V[36:0]
RT1_R
RT1_V[36:0]
OP[95:0]
CLR
EX_UNIT
CLR
Execute
Unit
CR0[31:0]
CR0[31:0]
EX_REQ
EX_REQ
OP_REQ
OP_REQ
EX_ACK
EX_ACK
OP_ACK
OP_ACK
EX[127:0]
EX[127:0]
CLR
Figure 3.18: fred3
PIPE_BR
OP[95:0]
OP[95:0]
PUTCR_REQ
PUTCR_REQ
PUTCR_ACK
PUTCR_ACK
PUTCR[31:0]
PUTCR[31:0]
CR_NUM[9:0]
CR_NUM[9:0]
GETCR_REQ
GETCR_REQ
GETCR_ACK
GETCR_ACK
GETCR[31:0]
GETCR[31:0]
CLR
BR_REQ
ROUT
BR_ACK
AOUT
CLR
PIPE_Nx32
RIN
BR_REQ
AIN
BR_ACK
PIPE_DONE
BR[31:0]
O[31:0]
I[31:0]
AAABR[31:0]
BR[31:0]
CLR
CLR
DONE_REQ
RIN
DONE_ACK
AIN
DONE[87:0]
AAADONE[87:0]
PIPE_Nx88
I[87:0]
ROUT
DONE_REQ
AOUT
DONE_ACK
O[87:0]
DONE[87:0]
PIPE_XBR
CLR
XBR_REQ
ROUT
XBR_ACK
AOUT
XBR[31:0]
RIN
AIN
PIPE_Nx32
O[31:0]
XBR_REQ
I[31:0]
XBR_ACK
AAAXBR[31:0]
XBR[31:0]
RT0_R
RT0_R
RT0_A
RT0_A
RT0_V[36:0]
RT0_V[36:0]
PREFETCH_REQ
PREFETCH_REQ
RT1_R
RT1_R
PREFETCH_ACK
PREFETCH_ACK
RT1_A
RT1_A
PREFETCH[31:0]
PREFETCH[31:0]
RT1_V[36:0]
RT2_R
RT2_A
RT2_A
RT2_V[36:0]
DATA_REQ
DATA_REQ
DATA_ACK
DATA_ACK
DATA_ACK_ACK
READ
BYTE_STROBE[3:0]
D_ADDR[31:0]
DATA_ACK_ACK
READ
RT1_V[36:0]
RT2_R
RT2_V[36:0]
RT3_R
RT3_R
RT3_A
RT3_A
RT3_V[36:0]
RT3_V[36:0]
CLR
BYTE_STROBE[3:0]
D_ADDR[31:0]
PIPE_R1
CLR
D_WRITE[31:0]
D_READ[31:0]
D_STATUS[3:0]
Fred
Processor
William
F.
Design
Richardson
Execute
D_WRITE[31:0]
D_READ[31:0]
D_STATUS[3:0]
R1_Q_REQ
RIN
R1_Q_ACK
R1_Q[31:0]
AIN
AAR1Q[31:0]
PIPE_Nx32
I[31:0]
ROUT
R1_Q_REQ
AOUT
R1_Q_ACK
O[31:0]
R1_Q[31:0]
Unit
191
192
ARITH
CLR
CLR
Arith
CLR
Unit
VHDL=ARITH_UNIT
Figure 3.19: fu-arith
PIPE
D_REQ
D_REQ
RIN
RIN
ROUT
RIN
D_ACK
D_ACK
AIN
AIN
PIPE_Nx3op AOUT
AIN
DONE[87:0]
CLR
EXTRA[3:0]
TELLME
Processor
William
F.
Design
Richardson
TMIN
EOUT[3:0]
AAE[3:0]
TMOUT
TAG[7:0]
TIN[7:0]
TOUT[7:0]
AATAG[7:0]
DEST[4:0]
DIN[4:0]
DOUT[4:0]
AADEST[4:0]
OPCODE[31:0]
WI[31:0]
WO[31:0]
AAOPCODE[31:0]
OP_A[31:0]
XI[31:0]
XO[31:0]
OP_B[31:0]
YI[31:0]
YO[31:0]
Arithmetic
Unit
DONE[87:0]
EXTRA[3:0]
TELLME
ROUT
ROUT
TAG[7:0]
AOUT
AOUT
DEST[4:0]
RES[36:0]
RES[36:0]
OPCODE[31:0]
RQ_REQ
RQ_REQ
AAOP_A[31:0]
OP_A[31:0]
RQ_ACK
RQ_ACK
AAOP_B[31:0]
OP_B[31:0]
RQ[31:0]
RQ[31:0]
CHAPTER 3. SCHEMATIC DIAGRAMS
Fred
EIN[3:0]
BRANCH
CLR
CLR
CLR
Branch
Unit
VHDL=BRANCH_UNIT
PIPE
CLR
RIN
RIN
ROUT
AIN
AIN
PIPE_Nx4op AOUT
EXTRA[3:0]
EIN[3:0]
EOUT[3:0]
RIN
AIN
AAE[3:0]
EXTRA[3:0]
CR0[31:0]
TELLME
TMIN
TMOUT
Figure 3.20: fu-branch
TAG[7:0]
TIN[7:0]
TOUT[7:0]
AATAG[7:0]
DEST[4:0]
DIN[4:0]
DOUT[4:0]
AADEST[4:0]
PC[31:0]
WI[31:0]
WO[31:0]
AAPC[31:0]
TAG[7:0]
D_REQ
D_REQ
D_ACK
D_ACK
DEST[4:0]
PC[31:0]
DONE[87:0]
OPCODE[31:0]
XI[31:0]
XO[31:0]
AAOPCODE[31:0]
OP_A[31:0]
YI[31:0]
YO[31:0]
AAOP_A[31:0]
OP_A[31:0]
OP_B[31:0]
ZI[31:0]
ZO[31:0]
AAOP_B[31:0]
OP_B[31:0]
BR_REQ
BR_REQ
BR_ACK
BR_ACK
Processor
F.
Design
Richardson
Branch
BR[31:0]
PF_REQ
PF_REQ
XBR_REQ
XBR_REQ
PF_ACK
PF_ACK
XBR_ACK
XBR_ACK
PF[31:0]
William
DONE[87:0]
OPCODE[31:0]
BR[31:0]
Fred
CR0[31:0]
TELLME
PF[31:0]
XBR[31:0]
XBR[31:0]
Unit
193
194
CTRL
CLR
CLR
Control
CLR
Unit
VHDL=CONTROL_UNIT
PIPE
D_REQ
D_REQ
ROUT
RIN
D_ACK
D_ACK
AOUT
AIN
DONE[87:0]
CLR
RIN
RIN
AIN
AIN
TELLME
EIN[3:0]
TMIN
EOUT[3:0]
AAE[3:0]
TMOUT
TELLME
TAG[7:0]
TIN[7:0]
TOUT[7:0]
AATAG[7:0]
DEST[4:0]
DIN[4:0]
DOUT[4:0]
AADEST[4:0]
TAG[7:0]
PC[31:0]
WI[31:0]
WO[31:0]
AAPC[31:0]
OPCODE[31:0]
XI[31:0]
XO[31:0]
AAOPCODE[31:0]
OP_A[31:0]
YI[31:0]
YO[31:0]
AAOP_A[31:0]
OP_A[31:0]
OP_B[31:0]
ZI[31:0]
ZO[31:0]
AAOP_B[31:0]
OP_B[31:0]
DEST[4:0]
ROUT
ROUT
AOUT
AOUT
RES[36:0]
Processor
William
F.
Design
Richardson
Control
Unit
RES[36:0]
PC[31:0]
RQ_REQ
RQ_REQ
OPCODE[31:0]
RQ_ACK
RQ_ACK
RQ[31:0]
RQ[31:0]
PUTCR_REQ
PUTCR_REQ
PUTCR_ACK
PUTCR_ACK
PUTCR[31:0]
PUTCR[31:0]
CR_NUM[9:0]
CR_NUM[9:0]
GETCR_REQ
GETCR_REQ
GETCR_ACK
GETCR_ACK
GETCR[31:0]
Fred
DONE[87:0]
EXTRA[3:0]
GETCR[31:0]
CHAPTER 3. SCHEMATIC DIAGRAMS
Figure 3.21: fu-control
EXTRA[3:0]
PIPE_Nx4op
LOGIC
CLR
CLR
Logic
CLR
Unit
VHDL=LOGIC_UNIT
PIPE
D_REQ
D_REQ
RIN
D_ACK
D_ACK
AIN
DONE[87:0]
CLR
Figure 3.22: fu-logic
RIN
RIN
ROUT
AIN
AIN
PIPE_Nx3op AOUT
EXTRA[3:0]
TELLME
Fred
Processor
William
F.
Design
Richardson
Logic
EIN[3:0]
TMIN
EOUT[3:0]
AAE[3:0]
TMOUT
TAG[7:0]
TIN[7:0]
TOUT[7:0]
AATAG[7:0]
DEST[4:0]
DIN[4:0]
DOUT[4:0]
AADEST[4:0]
OPCODE[31:0]
WI[31:0]
WO[31:0]
AAOPCODE[31:0]
OP_A[31:0]
XI[31:0]
XO[31:0]
AAOP_A[31:0]
OP_B[31:0]
YI[31:0]
YO[31:0]
AAOP_B[31:0]
DONE[87:0]
EXTRA[3:0]
TELLME
ROUT
ROUT
TAG[7:0]
AOUT
AOUT
DEST[4:0]
OPCODE[31:0]
RES[36:0]
RES[36:0]
RQ_REQ
RQ_REQ
OP_A[31:0]
RQ_ACK
RQ_ACK
OP_B[31:0]
RQ[31:0]
RQ[31:0]
Unit
195
196
CLR
MEM
CLR
CLR
Memory
PIPE
Unit
CLR
RIN
RIN
ROUT
RIN
AIN
AIN
PIPE_Nx4op AOUT
AIN
EXTRA[3:0]
TELLME
EIN[3:0]
TMIN
EOUT[3:0]
AAE[3:0]
TMOUT
TOUT[7:0]
AATAG[7:0]
DEST[4:0]
DIN[4:0]
DOUT[4:0]
AADEST[4:0]
OPCODE[31:0]
WI[31:0]
WO[31:0]
AAOPCODE[31:0]
OP_S[31:0]
XI[31:0]
XO[31:0]
AAOP_S[31:0]
OP_S[31:0]
OP_A[31:0]
YI[31:0]
YO[31:0]
AAOP_A[31:0]
OP_A[31:0]
OP_B[31:0]
ZI[31:0]
ZO[31:0]
AAOP_B[31:0]
OP_B[31:0]
D_REQ
D_ACK
D_ACK
DATA_ACK
DATA_ACK
DONE[87:0]
D_READ[31:0]
D_STATUS[3:0]
Design
Memory
Unit
OPCODE[31:0]
D_REQ
D_WRITE[31:0]
Richardson
CR0[31:0]
DATA_REQ
D_ADDR[31:0]
F.
CR0[31:0]
DEST[4:0]
DATA_REQ
BYTE_STROBE[3:0]
Processor
TAG[7:0]
DONE[87:0]
DATA_ACK_ACK
READ
REG_Q_REQ
REG_Q_REQ
BYTE_STROBE[3:0]
REG_Q_ACK
REG_Q_ACK
D_ADDR[31:0]
D_WRITE[31:0]
D_READ[31:0]
D_STATUS[3:0]
REG_Q[36:0]
REG_Q[36:0]
R1_Q_REQ
R1_Q_REQ
R1_Q_ACK
R1_Q_ACK
R1_Q[31:0]
R1_Q[31:0]
CHAPTER 3. SCHEMATIC DIAGRAMS
Figure 3.23: fu-memory
TIN[7:0]
READ
William
EXTRA[3:0]
TELLME
TAG[7:0]
DATA_ACK_ACK
Fred
VHDL=MEMORY_UNIT
CLR
Figure 3.24: gate
GND
G
S1 S0
D0
D1
MX4
D2
I
Fred
Processor
William
F.
Design
Richardson
When
G
is
high,
When
G
is
low,
A
gated
the
the
Y
O
D3
input
input
passes
is
directly
to
the
output.
latched.
latch.
197
198
CLR
DISPATCH
CLR
Dispatch
VHDL=DISPATCH
X_DEBUG
SYNC_REQ
SYNC_REQ
SYNC_ACK
SYNC_ACK
SYNC_NACK
X_DEBUG
PF_DEBUG
SYNC_NACK
PF_DEBUG
X_CR0[31:0]
CR0[31:0]
PUTCR_REQ
PUTCR_REQ
PUTCR_ACK
PUTCR_ACK
SB_R_R
SB_R_R
PUTCR[31:0]
PUTCR[31:0]
SB_R_G
SB_R_G
CR_NUM[9:0]
CR_NUM[9:0]
SB_R_D
SB_R_D
GETCR_REQ
GETCR_REQ
SB[31:0]
GETCR_ACK
GETCR_ACK
SB[31:0]
GETCR[31:0]
Figure 3.25: if-unit1
SB_W_R
SB_W_R
SB_W_A
SB_W_A
SB_SET
SB_SET
GETCR[31:0]
BR_P_REQ
R
BR_REQ
SB_NUM[4:0]
SB_NUM[4:0]
BR_P
Q
BR_P_ACK
A
BR_ACK
INST_REQ
INST_REQ
INST_ACK
INST_ACK
BR_ACK
BR[31:0]
BR[31:0]
XBR_P_REQ
INST_ACK_ACK
INST_ACK_ACK
I_ADDR[31:0]
I_ADDR[31:0]
I_DATA[31:0]
I_DATA[31:0]
R
XBR_REQ
XBR_P
Q
XBR_P_ACK
A
XBR_ACK
I_STATUS[3:0]
XBR_ACK
I_STATUS[3:0]
XBR[31:0]
XBR[31:0]
RF_REQ
DONE_REQ
RF_P_REQ
DONE_ACK
DONE_ACK
RF_P
DONE[87:0]
DONE[87:0]
RF_REQ
R
Q
RF_ACK
RF_P_ACK
A
RF[17:0]
RF[17:0]
EX_REQ
EX_REQ
EX_P_REQ
INT
A
B
XOR
Y
EXTERNAL_INT
REPLY_HAZY
R
EX_P
REPLY_HAZY
Q
EX_ACK
EX_P_ACK
A
CLR
FAULT_PENDING
FAULT_PENDING
EX[127:0]
EX[127:0]
CLR
O
Gate
I
G
A
Y
Fred
Processor
William
F.
Design
Richardson
Dispatch
AND2A
Unit,
B
with
This
signal
INTs
are
is
tied
to
the
CR0’s
INT
enable
bit.
CR05
FIFOs
disabled
and
while
exceptions
arbiter.
are
in
progress.
CHAPTER 3. SCHEMATIC DIAGRAMS
DONE_REQ
The
CLR_SB_REQ
can
be
pipelined,
but
setting or reading the Scoreboard can’t,
or the Dispatch Unit might see the wrong
value.
CLR
CLR
CLR
SB_W_R
R1
SB_W_A
A1
SCOREBOARD
CLR
Figure 3.26: if-unit2
Arb
Call
CLR_SB_REQ
R0
CLR_SB_ACK
A0
RS
WR_R
AS
WR_A
Scoreboard
RD_R
SB_R_R
SET
RD_G
SB_R_G
NUM[4:0]
RD_D
SB_R_D
BITS[31:0]
W
NUM[4:0]
SB[31:0]
GND
A
SB_SET
B
S
Y
Fred
Processor
William
F.
Design
Richardson
Scoreboard
and
SEL
OUT[4:0]
MUX-2x5
SB_NUM[4:0]
B[4:0]
CLR_SB[4:0]
A[4:0]
MX2
wake-up
arbitration
for
Dispatch
Unit.
199
200
CLR
FIFO-32
XI_R
R
INST_REQ
A
XIA[31:0]
D
I_ADDR[31:0]
XI_A
CLR
A
XDATA[31:0]
I
FIFO-36
R
XI_AA
INST_ACK
DELAY=4
total
I_DATA[31:0]
D32
XS[3:0]
O
Vdelay
INST_ACK_ACK
is
1.6
+
Figure 3.27: memory-latches
0.1
*
DELAY
(ns)
0.1
*
DELAY
(ns)
I_STATUS[3:0]
D4
CLR
FIFO-32
XD_R
R
DATA_REQ
A
XDA[31:0]
D
D_ADDR[31:0]
XD_A
CLR
A
XREAD
BYTE_STROBE[3:0]
4
Y
Imem
this
D_WRITE[31:0]
A
READ
BUF
Processor
William
F.
Design
Richardson
Memory
1.6
Latches
to
allow
and Dmem
does not
requests
+
from
reads are independent, but
handle multiple outstanding
each.
the address REQ,
Dmem write data.
own
Fred
is
D_STATUS[3:0]
32
XBS[3:0]
total
D_READ[31:0]
D4
XDW[31:0]
DATA_ACK
DELAY=4
D32
XS[3:0]
O
Vdelay
DATA_ACK_ACK
There
and no
Write
risk!
interleaved
memory
access.
is
no
ACK
for
buffering of the
to Imem at your
CHAPTER 3. SCHEMATIC DIAGRAMS
XDATA[31:0]
I
FIFO-36
R
XD_AA
S
A31
A
A30
S
MX2
Figure 3.28: mux2x30
A22
S
MX2
A
S
MX2
A14
S
MX2
A21
A
S
MX2
B
B15
A
S
MX2
MX2
A
A20
MX2
A
S
MX2
A12
A19
A
MX2
A
S
MX2
A11
A18
A
MX2
A
S
MX2
A10
A17
A
MX2
A
S
MX2
A9
A16
A
Y Y17
S
MX2
Y Y16
B
A
A8
S
MX2
A
Y Y9
S
MX2
B
B9
Y Y24
B16
Y Y10
B10
S
MX2
B
S
A
B
B17
Y Y11
A24
Y Y25
B24
Y Y18
B
B11
S
MX2
B
S
A
B
B18
Y Y12
A25
Y Y26
B25
Y Y19
B
B12
S
MX2
B
S
A
B
B19
Y Y13
A26
Y Y27
B26
Y Y20
B
B13
S
MX2
B
S
A
B27
Y Y21
B
B14
A27
Y Y28
B
B20
Y Y14
B
S
B28
Y Y22
A13
A
B
B21
Y Y15
A28
Y Y29
B
B22
A
MX2
B
B23
S
B29
Y Y23
B
A
B
B30
A
A29
Y Y30
B
B31
A15
S
MX2
B
A23
A
Y Y31
Y Y8
B
B8
A[31:2]
B[31:2]
A7
A
A6
S
MX2
Processor
William
F.
Design
Richardson
A
Y Y6
A4
S
MX2
B
B6
MUX
A5
S
MX2
B
B7
Fred
A
Y Y7
A3
S
MX2
B
B5
A
Y Y5
A2
S
MX2
B
B4
A
Y Y4
S
MX2
B
B3
A
Y Y3
B
Y Y2
Y[31:2]
B2
2x30
201
202
S
A31
A
A30
S
MX2
B
A
A22
S
A
S
A14
MX2
A
S
MX2
A6
S
MX2
A20
S
MX2
A
A
MX2
A12
A5
A
Processor
William
F.
Design
Richardson
MUX
2x32
MX2
A
A4
B5
S
MX2
A11
A
A18
S
MX2
A10
B4
A
MX2
A2
A
Y[31:0]
A24
A17
A9
A
S
MX2
A16
A
A8
S
S
MX2
Y Y16
A
Y Y9
S
MX2
Y Y8
B
B8
A
A0
S
MX2
A
Y Y1
S
MX2
B
B1
Y Y24
B
MX2
Y Y2
B
A
Y Y17
B
A1
MX2
B16
Y Y10
S
S
B
B9
A
A
Y Y25
B24
Y Y18
S
MX2
B2
MX2
B
MX2
Y Y3
B
S
B17
Y Y11
S
B3
B[31:0]
S
B
MX2
B
A
B10
Y Y4
A
B25
B
B11
A3
A25
Y Y26
B
B18
Y Y12
S
S
MX2
Y Y19
B
MX2
B
A
Y Y20
S
A
B26
B
MX2
A
A26
Y Y27
B
B19
Y Y5
A[31:0]
Fred
A19
S
B
MX2
B
A
Y Y13
S
MX2
B27
B12
Y Y6
S
B
B
S
A
Y Y28
B20
Y Y14
S
MX2
Y Y21
B
MX2
B6
A
B13
Y Y7
B
B7
A13
A27
S
B
B
B14
A
A21
A
Y Y29
B28
Y Y22
B
B15
MX2
B21
Y Y15
B
A28
S
B
B0
Y Y0
CHAPTER 3. SCHEMATIC DIAGRAMS
Figure 3.29: mux2x32
MX2
B22
S
A
B
B
B23
A
A29
Y Y30
B29
Y Y23
B
A7
MX2
B30
MX2
A15
S
B
B31
A23
A
Y Y31
B[3:0]
A[3:0]
Y[3:0]
S
A3
Figure 3.30: mux2x4
A
A2
S
Y
A
B3
Fred
Processor
William
F.
Design
Richardson
Mux
B
A1
S
Y3
Y
MX2
A
B2
B
A0
S
Y2
Y
MX2
A
B1
B
S
Y1
Y
MX2
Y0
MX2
B0
B
2x4
203
204
B[4:0]
B4
B3
B2
B1
B0
A[4:0]
A4
A3
A2
A1
A0
SEL
A
Y
BUF
A
MX2
S
MX2
S
Y
Y
OUT1
B
A
Y
OUT2
B
MX2
S
OUT0
OUT[4:0]
CHAPTER 3. SCHEMATIC DIAGRAMS
mux
A
bit
OUT3
B
5
Y
Design
Richardson
MX2
F.
S
Y
Processor
William
A
MX2
S
Fred
B
A
B
Figure 3.31: mux2x5
OUT4
B[7:0]
A[7:0]
Y[7:0]
Figure 3.32: mux2x8
S
A7
A
A6
S
Y
A
B7
A3
Y
B6
A2
S
Y
Fred
Processor
William
F.
Design
Richardson
Mux
B
Y
A
B5
A1
S
Y3
Y
B
A
Y
A
A0
S
Y
B
A
B
S
Y1
Y
MX2
B1
Y4
MX2
B4
Y2
S
Y5
B
MX2
B2
A4
S
MX2
B
MX2
B3
A
Y6
MX2
B
A
A5
S
Y7
MX2
Y0
MX2
B0
B
2x8
205
206
CLR
DC
CLR
Figure 3.33: pipe-nx128
RIN
RIN
AIN
AIN
Delay
Chain
ROUT
ROUT
AOUT
AOUT
CLR
CP
CLR
C
P
CPx128
I[127:0]
Processor
William
F.
Design
Richardson
Variable-length
FIFO
pipeline
O[127:0]
O[127:0]
CHAPTER 3. SCHEMATIC DIAGRAMS
Fred
I[127:0]
CLR
DC
CLR
Figure 3.34: pipe-nx18
RIN
RIN
AIN
AIN
Delay
Chain
ROUT
ROUT
AOUT
AOUT
CLR
CP
CLR
C
P
CPx18
I[17:0]
Fred
Processor
William
F.
Design
Richardson
Variable-length
FIFO
I[17:0]
O[17:0]
O[17:0]
pipeline
207
208
CLR
DC
CLR
Figure 3.35: pipe-nx32
RIN
RIN
AIN
AIN
Delay
Chain
ROUT
ROUT
AOUT
AOUT
CLR
CP
CLR
C
P
CPx32
I[31:0]
Processor
William
F.
Design
Richardson
Variable-length
FIFO
pipeline
O[31:0]
O[31:0]
CHAPTER 3. SCHEMATIC DIAGRAMS
Fred
I[31:0]
EIN[3:0]
EOUT[3:0]
TIN[7:0]
TOUT[7:0]
DIN[4:0]
DOUT[4:0]
WI[31:0]
CLR
XI[31:0]
WO[31:0]
DC
XO[31:0]
CLR
Figure 3.36: pipe-nx3op
RIN
RIN
AIN
AIN
ROUT
ROUT
AOUT
AOUT
YI[31:0]
YO[31:0]
Delay
Chain
CLR
CP
CLR
C
P
CPx3op
EIN[3:0],TMIN,TIN[7:0],DIN[4:0],WI[31:0],XI[31:0],YI[31:0]
I[113:0]
TMIN
Fred
Processor
William
F.
Design
Richardson
Variable-length
FIFO
EOUT[3:0],TMOUT,TOUT[7:0],DOUT[4:0],WO[31:0],XO[31:0],YO[31:0]
O[113:0]
TMOUT
pipeline
209
210
EIN[3:0]
EOUT[3:0]
TIN[7:0]
TOUT[7:0]
DIN[4:0]
DOUT[4:0]
WI[31:0]
CLR
XI[31:0]
WO[31:0]
DC
XO[31:0]
CLR
RIN
RIN
AIN
AIN
ROUT
ROUT
AOUT
AOUT
Figure 3.37: pipe-nx4op
YI[31:0]
YO[31:0]
Delay
Chain
ZI[31:0]
ZO[31:0]
CLR
CP
CLR
C
P
CPx4op
EIN[3:0],TMIN,TIN[7:0],DIN[4:0],WI[31:0],XI[31:0],YI[31:0],ZI[31:0]
EOUT[3:0],TMOUT,TOUT[7:0],DOUT[4:0],WO[31:0],XO[31:0],YO[31:0],ZO[31:0]
I[145:0]
TMIN
Processor
William
F.
Design
Richardson
Variable-length
FIFO
pipeline
TMOUT
CHAPTER 3. SCHEMATIC DIAGRAMS
Fred
O[145:0]
CLR
DC
CLR
Figure 3.38: pipe-nx5
RIN
RIN
AIN
AIN
Delay
Chain
ROUT
ROUT
AOUT
AOUT
CLR
CP
CLR
P
C
CPx5
I[4:0]
Fred
Processor
William
F.
Design
Richardson
Variable-length
FIFO
I[4:0]
O[4:0]
O[4:0]
pipeline
211
212
CLR
DC
CLR
Figure 3.39: pipe-nx88
RIN
RIN
AIN
AIN
Delay
Chain
ROUT
ROUT
AOUT
AOUT
CLR
CP
CLR
C
P
CPx88
I[87:0]
Processor
William
F.
Design
Richardson
Variable-length
FIFO
pipeline
O[87:0]
O[87:0]
CHAPTER 3. SCHEMATIC DIAGRAMS
Fred
I[87:0]
CLR
DC
CLR
Figure 3.40: pipe-nx96
RIN
RIN
AIN
AIN
Delay
Chain
ROUT
ROUT
AOUT
AOUT
CLR
CP
CLR
C
P
CPx96
I[95:0]
Fred
Processor
William
F.
Design
Richardson
Variable-length
FIFO
I[95:0]
O[95:0]
O[95:0]
pipeline
213
214
O
A
Fred
Processor
William
F.
Design
Richardson
Returns
1
when
both
R
Q
Y
XNOR
A
I0
B
I1
A
inputs
are
equal.
CHAPTER 3. SCHEMATIC DIAGRAMS
Figure 3.41: qop-even
R
Figure 3.42: qop-odd
R
O
A
Fred
Processor
William
F.
Design
Richardson
Returns
1
when
R
Q
Y
XOR
A
I0
B
I1
A
inputs
are
different.
215
B1
A
B0
B
B0
A
B2
B
B1
A
B3
B
B0
A
B1
B
B3
C
OR2
OR2
Processor
William
F.
Design
Richardson
Y
Y
NOR2
Y
OA1B
Byte
Order
for
Memory
Read
B[3:0]
OUT[31:0]
C[7:0] D[7:0]
OUT[7:0]
MUX - 4x8
OUT[7:0]
S1
IN[7:0]
S0
OUT[7:0]
IN[15:8]
A[7:0] B[7:0]
C[7:0] D[7:0]
OUT[15:8]
Y
IN[31:0]
Fred
IN[23:16]
S1
IN[7:0]
MUX - 4x8
OUT[7:0]
IN[15:8]
IN[31:24]
S0
C[7:0] D[7:0]
OUT[23:16]
A[7:0] B[7:0]
S1
IN[7:0]
IN[23:16]
S1
IN[15:8]
MUX - 4x8
OUT[31:24]
S0
OUT[7:0]
IN[23:16]
IN[31:24]
CHAPTER 3. SCHEMATIC DIAGRAMS
Figure 3.43: ram-byte-order
IN[7:0]
MUX - 4x8
IN[15:8]
S0
A[7:0] B[7:0]
IN[23:16]
IN[31:24]
A[7:0] B[7:0]
C[7:0] D[7:0]
216
IN[31:24]
This
determines
The
Don’t
It
is
RAM
change
tuned
for
system
models
memory
have
the
memory
the
delay
response
zero
delay
delay
here,
of
the
time
though.
calling
circuit.
This
I
REQ
O
ACK
Vdelay
ADDR[31:2]
orders
the
bytes
according
Delay
is
about
to
the
byte
strobes
3ns
TMP[31:0]
IN[31:0]
DELAY=5
Byte
order
READ[31:0]
OUT[31:0]
BYTES[3:0]
WRITE[31:0]
This
delay
Read
outputs
is
only
for
writes
B[3:0]
IN
are
always
Delay4 OUT
A
active
Q
B
XOR2
B
RD
AND2A
Y
A
BYTES1
DSBL
DO7
DO6
DO5
DO4
DO3
DO2
DO1
DO0
TMP23
TMP22
TMP21
TMP20
TMP19
TMP18
TMP17
TMP16
WRITE15
WRITE14
WRITE13
WRITE12
WRITE11
WRITE10
WRITE9
WRITE8
R/W*
ADDR15
ADDR14
ADDR13
ADDR12
ADDR11
ADDR10
ADDR9
ADDR8
ADDR7
ADDR6
ADDR5
ADDR4
ADDR3
ADDR2
16Kx8
A13
A12
A11
SEG1
A10
A9
A8 MODEL=RAM
A7
A6
A5 WIDTH=8
A4
LENGTH=16384
A3
A2
A1
A0
DI7
DI6
DI5
DI4
DI3
DI2
DI1
DI0
DSBL
QN
A2
A1
A0
DI7
DI6
DI5
DI4
DI3
DI2
DI1
DI0
NAND2
R/W*
ADDR15
ADDR14
ADDR13
ADDR12
ADDR11
ADDR10
ADDR9
ADDR8
ADDR7
ADDR6
ADDR5
ADDR4
ADDR3
ADDR2
16Kx8
A13
A12
A11
SEG2
A10
A9
A8 MODEL=RAM
A7
A6
A5 WIDTH=8
A4
LENGTH=16384
A3
A
WRITE23
WRITE22
WRITE21
WRITE20
WRITE19
WRITE18
WRITE17
WRITE16
B
DO7
DO6
DO5
DO4
DO3
DO2
DO1
DO0
TMP31
TMP30
TMP29
TMP28
TMP27
TMP26
TMP25
TMP24
BYTES3
QN
NAND2
DSBL
B
A2
A1
A0
DI7
DI6
DI5
DI4
DI3
DI2
DI1
DI0
QN
NAND2
QN
NAND2
R/W*
ADDR15
ADDR14
ADDR13
ADDR12
ADDR11
ADDR10
ADDR9
ADDR8
ADDR7
ADDR6
ADDR5
ADDR4
ADDR3
ADDR2
16Kx8
A13
A12
A11
SEG3
A10
A9
A8 MODEL=RAM
A7
A6
A5 WIDTH=8
A4
LENGTH=16384
A3
WRITE31
WRITE30
WRITE29
WRITE28
WRITE27
WRITE26
WRITE25
WRITE24
A
B
A
B
R/W*
ADDR15
ADDR14
ADDR13
ADDR12
ADDR11
ADDR10
ADDR9
ADDR8
ADDR7
ADDR6
ADDR5
ADDR4
ADDR3
ADDR2
BYTES2
A
Figure 3.44: ram16kx32
BYTES0
DO7
DO6
DO5
DO4
DO3
DO2
DO1
DO0
TMP15
TMP14
TMP13
TMP12
TMP11
TMP10
TMP9
TMP8
WRITE7
WRITE6
WRITE5
WRITE4
WRITE3
WRITE2
WRITE1
WRITE0
16Kx8
A13
A12
A11
SEG0
A10
A9
A8 MODEL=RAM
A7
A6
A5 WIDTH=8
A4
LENGTH=16384
A3
A2
A1
A0
DI7
DI6
DI5
DI4
DI3
DI2
DI1
DI0
DSBL
DO7
DO6
DO5
DO4
DO3
DO2
DO1
DO0
TMP7
TMP6
TMP5
TMP4
TMP3
TMP2
TMP1
TMP0
GND
Fred
Processor
William
F.
Design
Richardson
32-bit
RAM,
Req/Ack
model
217
218
CLR
CLR
REGISTERS
REGSELECT
CLR
CLR
Registers
Reg
VHDL=REGSELECT
VHDL=REGISTERS
Figure 3.45: rf-unit
R05[31:0]
RF_REQ
RF_REQ
CLR_SB_ACK
R06[31:0]
R06[31:0]
R06[31:0]
RF_ACK
RF_ACK
CLR_SB[4:0]
R07[31:0]
R07[31:0]
R07[31:0]
RF[17:0]
R08[31:0]
R08[31:0]
R08[31:0]
R09[31:0]
R09[31:0]
R09[31:0]
RF[17:0]
R10[31:0]
R10[31:0]
R10[31:0]
RT0_R
RT0_R
R11[31:0]
R11[31:0]
R11[31:0]
OP_REQ
OP_REQ
RT0_A
RT0_A
R12[31:0]
R12[31:0]
R12[31:0]
OP_ACK
OP_ACK
RT0_V[36:0]
R13[31:0]
R13[31:0]
R13[31:0]
OP[95:0]
OP[95:0]
R14[31:0]
R14[31:0]
R14[31:0]
RT1_R
RT1_A
R15[31:0]
R15[31:0]
R15[31:0]
RT1_A
RT1_R
R16[31:0]
R16[31:0]
R16[31:0]
RT1_V[36:0]
R17[31:0]
R17[31:0]
R17[31:0]
R1_Q_REQ
R1_Q_REQ
R18[31:0]
R18[31:0]
R18[31:0]
R1_Q_ACK
R1_Q_ACK
R1_Q[31:0]
RT2_R
RT2_A
R19[31:0]
R19[31:0]
R19[31:0]
RT2_A
RT2_R
R20[31:0]
R20[31:0]
R20[31:0]
RT2_V[36:0]
R21[31:0]
R21[31:0]
R21[31:0]
R22[31:0]
R22[31:0]
R22[31:0]
RT3_R
RT3_A
R23[31:0]
R23[31:0]
R23[31:0]
RT3_A
RT3_R
R24[31:0]
R24[31:0]
R24[31:0]
RT3_V[36:0]
R25[31:0]
R25[31:0]
R25[31:0]
R26[31:0]
R26[31:0]
R26[31:0]
R27[31:0]
R27[31:0]
R27[31:0]
R28[31:0]
R28[31:0]
R28[31:0]
R29[31:0]
R29[31:0]
R29[31:0]
R30[31:0]
R30[31:0]
R30[31:0]
R31[31:0]
R31[31:0]
R31[31:0]
Register
Bank
Implementation
R1_Q[31:0]
CHAPTER 3. SCHEMATIC DIAGRAMS
Design
R04[31:0]
CLR_SB_ACK
RT3_V[36:0]
Richardson
R03[31:0]
R04[31:0]
R05[31:0]
RT2_V[36:0]
F.
R02[31:0]
R03[31:0]
R04[31:0]
R05[31:0]
RT1_V[36:0]
Processor
R02[31:0]
R03[31:0]
CLR_SB_REQ
RT0_V[36:0]
William
R02[31:0]
CLR_SB_REQ
CLR_SB[4:0]
Fred
Select
IN[31:0]
IN[31:24]
IN[23:16]
IN[7:0]
C
C
Figure 3.46: tlnt-32
P
P
IN[15:8]
IN[7:0]
C
TLNT
OUT[7:0]
OUT[31:24]
P
IN[7:0]
IN[7:0]
C
TLNT
OUT[7:0]
OUT[23:16]
P
IN[7:0]
C
TLNT
OUT[7:0]
OUT[15:8]
P
TLNT
OUT[7:0]
OUT[7:0]
OUT[31:0]
C fanin is 8
P fanin is 4
In fanin is 2
Out drives 2
Total Modules: 44
Fred
Processor
William
F.
Design
Richardson
32-bit
TLNT
219
220
Z[31:0]
GND,GND,GND,GND,GND,GND,GND,GND
GND,GND,GND,GND,GND,GND,GND,GND
Figure 3.47: zerox32
GND,GND,GND,GND,GND,GND,GND,GND
GND,GND,GND,GND,GND,GND,GND,GND
Processor
William
F.
Design
Richardson
Zero
bus
8
8
8
Z[7:0]
Z[15:8]
Z[23:16]
Z[31:24]
CHAPTER 3. SCHEMATIC DIAGRAMS
Fred
8
Download