w11 - vhd 0.794
W11 CPU core and support modules
Loading...
Searching...
No Matches
pdp11_aunit.vhd
Go to the documentation of this file.
1-- $Id: pdp11_aunit.vhd 1203 2019-08-19 21:41:03Z mueller $
2-- SPDX-License-Identifier: GPL-3.0-or-later
3-- Copyright 2006-2019 by Walter F.J. Mueller <W.F.J.Mueller@gsi.de>
4--
5------------------------------------------------------------------------------
6-- Module Name: pdp11_aunit - syn
7-- Description: pdp11: arithmetic unit for data (aunit)
8--
9-- Dependencies: -
10-- Test bench: tb/tb_pdp11_core (implicit)
11-- Target Devices: generic
12-- Tool versions: ise 8.2-14.7; viv 2014.4-2019.1; ghdl 0.18-0.36
13-- Revision History:
14-- Date Rev Version Comment
15-- 2019-08-17 1203 1.1.2 fix for ghdl V0.36 -Whide warnings
16-- 2014-08-10 581 1.1.1 use c_cc_f_*
17-- 2010-09-18 300 1.1 renamed from abox
18-- 2007-06-14 56 1.0.1 Use slvtypes.all
19-- 2007-05-12 26 1.0 Initial version
20------------------------------------------------------------------------------
21
22library ieee;
23use ieee.std_logic_1164.all;
24use ieee.std_logic_arith.all;
25use ieee.std_logic_unsigned.all;
26
27use work.slvtypes.all;
28use work.pdp11.all;
29
30-- ----------------------------------------------------------------------------
31
32-- arithmetic unit for data, usage:
33-- ADD: SRC + DST + 0 (dst+src)
34-- SUB: ~SRC + DST + 1 (dst-src)
35-- ADC: 0 + DST + CI (dst+ci)
36-- SBC: ~0 + DST + ~CI (dst-ci)
37-- CMP: SRC + ~DST + 1 (src-dst)
38-- COM: 0 + ~DST + 0 (~dst)
39-- NEG: 0 + ~DST + 1 (-dst)
40-- INC: 0 + DST + 1 (dst+1)
41-- DEC: ~0 + DST + 0 (dst-1)
42-- CLR: 0 + 0 + 0 (0)
43-- SOB: SRC + ~0 + 0 (src-1)
44
45entity pdp11_aunit is -- arithmetic unit for data (aunit)
46 port (
47 DSRC : in slv16; -- 'src' data in
48 DDST : in slv16; -- 'dst' data in
49 CI : in slbit; -- carry flag in
50 SRCMOD : in slv2; -- src modifier mode
51 DSTMOD : in slv2; -- dst modifier mode
52 CIMOD : in slv2; -- ci modifier mode
53 CC1OP : in slbit; -- use cc modes (1 op instruction)
54 CCMODE : in slv3; -- cc mode
55 BYTOP : in slbit; -- byte operation
56 DOUT : out slv16; -- data output
57 CCOUT : out slv4 -- condition codes out
58 );
59end pdp11_aunit;
60
61architecture syn of pdp11_aunit is
62
63-- --------------------------------------
64
65begin
66
67 process (DSRC, DDST, CI, CIMOD, CC1OP, CCMODE, SRCMOD, DSTMOD, BYTOP)
68
69 variable msrc : slv16 := (others=>'0'); -- effective src data
70 variable mdst : slv16 := (others=>'0'); -- effective dst data
71 variable mci : slbit := '0'; -- effective ci
72 variable sum : slv16 := (others=>'0'); -- sum
73 variable co8 : slbit := '0'; -- co 8 bit
74 variable co16 : slbit := '0'; -- co 16 bit
75
76 variable nno : slbit := '0'; -- local no
77 variable nzo : slbit := '0'; -- local zo
78 variable nvo : slbit := '0'; -- local vo
79 variable nco : slbit := '0'; -- local co
80
81 variable src_msb : slbit := '0'; -- msb from src (bit 15 or 7)
82 variable dst_msb : slbit := '0'; -- msb from dst (bit 15 or 7)
83 variable sum_msb : slbit := '0'; -- msb from sum (bit 15 or 7)
84
85 alias NO : slbit is CCOUT(c_cc_f_n);
86 alias ZO : slbit is CCOUT(c_cc_f_z);
87 alias VO : slbit is CCOUT(c_cc_f_v);
88 alias CO : slbit is CCOUT(c_cc_f_c);
89
90 -- procedure do_add8_ci_co: 8 bit adder with carry in and carry out
91 -- implemented following the recommended pattern for XST ISE V8.1
92
93 procedure do_add8_ci_co (
94 variable pa : in slv8; -- input a
95 variable pb : in slv8; -- input b
96 variable pci : in slbit; -- carry in
97 variable psum : out slv8; -- sum out
98 variable pco : out slbit -- carry out
99 ) is
100
101 variable tmp: slv9;
102
103 begin
104
105 tmp := conv_std_logic_vector((conv_integer(pa) + conv_integer(pb) +
106 conv_integer(pci)),9);
107 psum := tmp(7 downto 0);
108 pco := tmp(8);
109
110 end procedure do_add8_ci_co;
111
112 begin
113
114 case SRCMOD is
115 when c_aunit_mod_pass => msrc := DSRC;
116 when c_aunit_mod_inv => msrc := not DSRC;
117 when c_aunit_mod_zero => msrc := (others=>'0');
118 when c_aunit_mod_one => msrc := (others=>'1');
119 when others => null;
120 end case;
121
122 case DSTMOD is
123 when c_aunit_mod_pass => mdst := DDST;
124 when c_aunit_mod_inv => mdst := not DDST;
125 when c_aunit_mod_zero => mdst := (others=>'0');
126 when c_aunit_mod_one => mdst := (others=>'1');
127 when others => null;
128 end case;
129
130 case CIMOD is
131 when c_aunit_mod_pass => mci := CI;
132 when c_aunit_mod_inv => mci := not CI;
133 when c_aunit_mod_zero => mci := '0';
134 when c_aunit_mod_one => mci := '1';
135 when others => null;
136 end case;
137
138 do_add8_ci_co(msrc(7 downto 0), mdst(7 downto 0), mci,
139 sum(7 downto 0), co8);
140 do_add8_ci_co(msrc(15 downto 8), mdst(15 downto 8), co8,
141 sum(15 downto 8), co16);
142
143 DOUT <= sum;
144
145-- V ('overflow) bit set if
146-- ADD : both operants of same sign but has result opposite sign
147-- SUB : both operants of opposide sign and sign source equals sign result
148-- CMP : both operants of opposide sign and sign dest. equals sign result
149
150 nno := '0';
151 nzo := '0';
152 nvo := '0';
153 nco := '0';
154
155 if BYTOP = '1' then
156 nno := sum(7);
157 if unsigned(sum(7 downto 0)) = 0 then
158 nzo := '1';
159 else
160 nzo := '0';
161 end if;
162 nco := co8;
163
164 src_msb := DSRC(7);
165 dst_msb := DDST(7);
166 sum_msb := sum(7);
167
168 else
169 nno := sum(15);
170 if unsigned(sum) = 0 then
171 nzo := '1';
172 else
173 nzo := '0';
174 end if;
175 nco := co16;
176
177 src_msb := DSRC(15);
178 dst_msb := DDST(15);
179 sum_msb := sum(15);
180 end if;
181
182 -- the logic for 2 operand V+C is ugly. It is reverse engineered from
183 -- the MOD's the operation type.
184
185 if CC1OP = '0' then -- 2 operand cases
186 if unsigned(CIMOD) = unsigned(c_aunit_mod_zero) then -- case ADD
187 nvo := not(src_msb xor dst_msb) and (src_msb xor sum_msb);
188 else
189 if unsigned(SRCMOD) = unsigned(c_aunit_mod_inv) then -- case SUB
190 nvo := (src_msb xor dst_msb) and not (src_msb xor sum_msb);
191 else -- case CMP
192 nvo := (src_msb xor dst_msb) and not (dst_msb xor sum_msb);
193 end if;
194 nco := not nco; -- invert C for SUB and CMP
195 end if;
196
197 else -- 1 operand cases
198 case CCMODE is
199 when c_aunit_ccmode_clr|c_aunit_ccmode_tst =>
200 nvo := '0'; -- force v=0 for tst and clr
201 nco := '0'; -- force c=0 for tst and clr
202
203 when c_aunit_ccmode_com =>
204 nvo := '0'; -- force v=0 for com
205 nco := '1'; -- force c=1 for com
206
207 when c_aunit_ccmode_inc =>
208 nvo := sum_msb and not dst_msb;
209 nco := CI; -- C not affected for INC
210
211 when c_aunit_ccmode_dec =>
212 nvo := not sum_msb and dst_msb;
213 nco := CI; -- C not affected for DEC
214
215 when c_aunit_ccmode_neg =>
216 nvo := sum_msb and dst_msb;
217 nco := not nzo;
218
219 when c_aunit_ccmode_adc =>
220 nvo := sum_msb and not dst_msb;
221
222 when c_aunit_ccmode_sbc =>
223 nvo := not sum_msb and dst_msb;
224 nco := not nco;
225
226 when others => null;
227 end case;
228 end if;
229
230 NO <= nno;
231 ZO <= nzo;
232 VO <= nvo;
233 CO <= nco;
234
235 end process;
236
237end syn;
do_add8_ci_copa,pb,pci,psum,pco,
Definition: pdp11_aunit.vhd:93
out CCOUT slv4
Definition: pdp11_aunit.vhd:58
in CC1OP slbit
Definition: pdp11_aunit.vhd:53
in SRCMOD slv2
Definition: pdp11_aunit.vhd:50
in DDST slv16
Definition: pdp11_aunit.vhd:48
in CCMODE slv3
Definition: pdp11_aunit.vhd:54
in CI slbit
Definition: pdp11_aunit.vhd:49
in DSTMOD slv2
Definition: pdp11_aunit.vhd:51
in CIMOD slv2
Definition: pdp11_aunit.vhd:52
in BYTOP slbit
Definition: pdp11_aunit.vhd:55
in DSRC slv16
Definition: pdp11_aunit.vhd:47
out DOUT slv16
Definition: pdp11_aunit.vhd:56
Definition: pdp11.vhd:123
std_logic_vector( 3 downto 0) slv4
Definition: slvtypes.vhd:36
std_logic_vector( 2 downto 0) slv3
Definition: slvtypes.vhd:35
std_logic_vector( 8 downto 0) slv9
Definition: slvtypes.vhd:41
std_logic_vector( 15 downto 0) slv16
Definition: slvtypes.vhd:48
std_logic slbit
Definition: slvtypes.vhd:30
std_logic_vector( 7 downto 0) slv8
Definition: slvtypes.vhd:40
std_logic_vector( 1 downto 0) slv2
Definition: slvtypes.vhd:34