1 |
2 |
jsauermann |
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
|
2 |
|
|
"http://www.w3.org/TR/html4/strict.dtd">
|
3 |
|
|
<HTML>
|
4 |
|
|
<HEAD>
|
5 |
|
|
<TITLE>html/Listing_of_opc_deco.vhd</TITLE>
|
6 |
|
|
<META NAME="generator" CONTENT="HTML::TextToHTML v2.46">
|
7 |
|
|
<LINK REL="stylesheet" TYPE="text/css" HREF="lecture.css">
|
8 |
|
|
</HEAD>
|
9 |
|
|
<BODY>
|
10 |
|
|
<P><table class="ttop"><th class="tpre"><a href="17_Listing_of_io.vhd.html">Previous Lesson</a></th><th class="ttop"><a href="toc.html">Table of Content</a></th><th class="tnxt"><a href="19_Listing_of_opc_fetch.vhd.html">Next Lesson</a></th></table>
|
11 |
|
|
<hr>
|
12 |
|
|
|
13 |
|
|
<H1><A NAME="section_1">18 Listing of opc_deco.vhd</A></H1>
|
14 |
|
|
|
15 |
|
|
<pre class="vhdl">
|
16 |
|
|
|
17 |
|
|
1 -------------------------------------------------------------------------------
|
18 |
|
|
2 --
|
19 |
|
|
3 -- Copyright (C) 2009, 2010 Dr. Juergen Sauermann
|
20 |
|
|
4 --
|
21 |
|
|
5 -- This code is free software: you can redistribute it and/or modify
|
22 |
|
|
6 -- it under the terms of the GNU General Public License as published by
|
23 |
|
|
7 -- the Free Software Foundation, either version 3 of the License, or
|
24 |
|
|
8 -- (at your option) any later version.
|
25 |
|
|
9 --
|
26 |
|
|
10 -- This code is distributed in the hope that it will be useful,
|
27 |
|
|
11 -- but WITHOUT ANY WARRANTY; without even the implied warranty of
|
28 |
|
|
12 -- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
29 |
|
|
13 -- GNU General Public License for more details.
|
30 |
|
|
14 --
|
31 |
|
|
15 -- You should have received a copy of the GNU General Public License
|
32 |
|
|
16 -- along with this code (see the file named COPYING).
|
33 |
|
|
17 -- If not, see http://www.gnu.org/licenses/.
|
34 |
|
|
18 --
|
35 |
|
|
19 -------------------------------------------------------------------------------
|
36 |
|
|
20 -------------------------------------------------------------------------------
|
37 |
|
|
21 --
|
38 |
|
|
22 -- Module Name: opc_deco - Behavioral
|
39 |
|
|
23 -- Create Date: 16:05:16 10/29/2009
|
40 |
|
|
24 -- Description: the opcode decoder of a CPU.
|
41 |
|
|
25 --
|
42 |
|
|
26 -------------------------------------------------------------------------------
|
43 |
|
|
27 --
|
44 |
|
|
28 library IEEE;
|
45 |
|
|
29 use IEEE.STD_LOGIC_1164.ALL;
|
46 |
|
|
30 use IEEE.STD_LOGIC_ARITH.ALL;
|
47 |
|
|
31 use IEEE.STD_LOGIC_UNSIGNED.ALL;
|
48 |
|
|
32
|
49 |
|
|
33 use work.common.ALL;
|
50 |
|
|
34
|
51 |
|
|
35 entity opc_deco is
|
52 |
|
|
36 port ( I_CLK : in std_logic;
|
53 |
|
|
37
|
54 |
|
|
38 I_OPC : in std_logic_vector(31 downto 0);
|
55 |
|
|
39 I_PC : in std_logic_vector(15 downto 0);
|
56 |
|
|
40 I_T0 : in std_logic;
|
57 |
|
|
41
|
58 |
|
|
42 Q_ALU_OP : out std_logic_vector( 4 downto 0);
|
59 |
|
|
43 Q_AMOD : out std_logic_vector( 5 downto 0);
|
60 |
|
|
44 Q_BIT : out std_logic_vector( 3 downto 0);
|
61 |
|
|
45 Q_DDDDD : out std_logic_vector( 4 downto 0);
|
62 |
|
|
46 Q_IMM : out std_logic_vector(15 downto 0);
|
63 |
|
|
47 Q_JADR : out std_logic_vector(15 downto 0);
|
64 |
|
|
48 Q_OPC : out std_logic_vector(15 downto 0);
|
65 |
|
|
49 Q_PC : out std_logic_vector(15 downto 0);
|
66 |
|
|
50 Q_PC_OP : out std_logic_vector( 2 downto 0);
|
67 |
|
|
51 Q_PMS : out std_logic; -- program memory select
|
68 |
|
|
52 Q_RD_M : out std_logic;
|
69 |
|
|
53 Q_RRRRR : out std_logic_vector( 4 downto 0);
|
70 |
|
|
54 Q_RSEL : out std_logic_vector( 1 downto 0);
|
71 |
|
|
55 Q_WE_01 : out std_logic;
|
72 |
|
|
56 Q_WE_D : out std_logic_vector( 1 downto 0);
|
73 |
|
|
57 Q_WE_F : out std_logic;
|
74 |
|
|
58 Q_WE_M : out std_logic_vector( 1 downto 0);
|
75 |
|
|
59 Q_WE_XYZS : out std_logic);
|
76 |
|
|
60 end opc_deco;
|
77 |
|
|
61
|
78 |
|
|
62 architecture Behavioral of opc_deco is
|
79 |
|
|
63
|
80 |
|
|
64 begin
|
81 |
|
|
65
|
82 |
|
|
66 process(I_CLK)
|
83 |
|
|
67 begin
|
84 |
|
|
68 if (rising_edge(I_CLK)) then
|
85 |
|
|
69 --
|
86 |
|
|
70 -- set the most common settings as default.
|
87 |
|
|
71 --
|
88 |
|
|
72 Q_ALU_OP <= ALU_D_MV_Q;
|
89 |
|
|
73 Q_AMOD <= AMOD_ABS;
|
90 |
|
|
74 Q_BIT <= I_OPC(10) & I_OPC(2 downto 0);
|
91 |
|
|
75 Q_DDDDD <= I_OPC(8 downto 4);
|
92 |
|
|
76 Q_IMM <= X"0000";
|
93 |
|
|
77 Q_JADR <= I_OPC(31 downto 16);
|
94 |
|
|
78 Q_OPC <= I_OPC(15 downto 0);
|
95 |
|
|
79 Q_PC <= I_PC;
|
96 |
|
|
80 Q_PC_OP <= PC_NEXT;
|
97 |
|
|
81 Q_PMS <= '0';
|
98 |
|
|
82 Q_RD_M <= '0';
|
99 |
|
|
83 Q_RRRRR <= I_OPC(9) & I_OPC(3 downto 0);
|
100 |
|
|
84 Q_RSEL <= RS_REG;
|
101 |
|
|
85 Q_WE_D <= "00";
|
102 |
|
|
86 Q_WE_01 <= '0';
|
103 |
|
|
87 Q_WE_F <= '0';
|
104 |
|
|
88 Q_WE_M <= "00";
|
105 |
|
|
89 Q_WE_XYZS <= '0';
|
106 |
|
|
90
|
107 |
|
|
91 case I_OPC(15 downto 10) is
|
108 |
|
|
92 when "000000" =>
|
109 |
|
|
93 case I_OPC(9 downto 8) is
|
110 |
|
|
94 when "00" =>
|
111 |
|
|
95 --
|
112 |
|
|
96 -- 0000 0000 0000 0000 - NOP
|
113 |
|
|
97 -- 0000 0000 001v vvvv - INTERRUPT
|
114 |
|
|
98 --
|
115 |
|
|
99 if (I_T0 and I_OPC(5)) = '1' then -- interrupt
|
116 |
|
|
100 Q_ALU_OP <= ALU_INTR;
|
117 |
|
|
101 Q_AMOD <= AMOD_ddSP;
|
118 |
|
|
102 Q_JADR <= "0000000000" & I_OPC(4 downto 0) & "0";
|
119 |
|
|
103 Q_PC_OP <= PC_LD_I;
|
120 |
|
|
104 Q_WE_F <= '1';
|
121 |
|
|
105 Q_WE_M <= "11";
|
122 |
|
|
106 end if;
|
123 |
|
|
107
|
124 |
|
|
108 when "01" =>
|
125 |
|
|
109 --
|
126 |
|
|
110 -- 0000 0001 dddd rrrr - MOVW
|
127 |
|
|
111 --
|
128 |
|
|
112 Q_DDDDD <= I_OPC(7 downto 4) & "0";
|
129 |
|
|
113 Q_RRRRR <= I_OPC(3 downto 0) & "0";
|
130 |
|
|
114 Q_ALU_OP <= ALU_MV_16;
|
131 |
|
|
115 Q_WE_D <= "11";
|
132 |
|
|
116
|
133 |
|
|
117 when "10" =>
|
134 |
|
|
118 --
|
135 |
|
|
119 -- 0000 0010 dddd rrrr - MULS
|
136 |
|
|
120 --
|
137 |
|
|
121 Q_DDDDD <= "1" & I_OPC(7 downto 4);
|
138 |
|
|
122 Q_RRRRR <= "1" & I_OPC(3 downto 0);
|
139 |
|
|
123 Q_ALU_OP <= ALU_MULT;
|
140 |
|
|
124 Q_IMM(7 downto 5) <= MULT_SS;
|
141 |
|
|
125 Q_WE_01 <= '1';
|
142 |
|
|
126 Q_WE_F <= '1';
|
143 |
|
|
127
|
144 |
|
|
128 when others =>
|
145 |
|
|
129 --
|
146 |
|
|
130 -- 0000 0011 0ddd 0rrr - MULSU SU "010"
|
147 |
|
|
131 -- 0000 0011 0ddd 1rrr - FMUL UU "100"
|
148 |
|
|
132 -- 0000 0011 1ddd 0rrr - FMULS SS "111"
|
149 |
|
|
133 -- 0000 0011 1ddd 1rrr - FMULSU SU "110"
|
150 |
|
|
134 --
|
151 |
|
|
135 Q_DDDDD(4 downto 3) <= "10"; -- regs 16 to 23
|
152 |
|
|
136 Q_RRRRR(4 downto 3) <= "10"; -- regs 16 to 23
|
153 |
|
|
137 Q_ALU_OP <= ALU_MULT;
|
154 |
|
|
138 if I_OPC(7) = '0' then
|
155 |
|
|
139 if I_OPC(3) = '0' then
|
156 |
|
|
140 Q_IMM(7 downto 5) <= MULT_SU;
|
157 |
|
|
141 else
|
158 |
|
|
142 Q_IMM(7 downto 5) <= MULT_FUU;
|
159 |
|
|
143 end if;
|
160 |
|
|
144 else
|
161 |
|
|
145 if I_OPC(3) = '0' then
|
162 |
|
|
146 Q_IMM(7 downto 5) <= MULT_FSS;
|
163 |
|
|
147 else
|
164 |
|
|
148 Q_IMM(7 downto 5) <= MULT_FSU;
|
165 |
|
|
149 end if;
|
166 |
|
|
150 end if;
|
167 |
|
|
151 Q_WE_01 <= '1';
|
168 |
|
|
152 Q_WE_F <= '1';
|
169 |
|
|
153 end case;
|
170 |
|
|
154
|
171 |
|
|
155 when "000001" | "000010" =>
|
172 |
|
|
156 --
|
173 |
|
|
157 -- 0000 01rd dddd rrrr - CPC = SBC without Q_WE_D
|
174 |
|
|
158 -- 0000 10rd dddd rrrr - SBC
|
175 |
|
|
159 --
|
176 |
|
|
160 Q_ALU_OP <= ALU_SBC;
|
177 |
|
|
161 Q_WE_D <= '0' & I_OPC(11); -- write Rd if SBC.
|
178 |
|
|
162 Q_WE_F <= '1';
|
179 |
|
|
163
|
180 |
|
|
164 when "000011" =>
|
181 |
|
|
165 --
|
182 |
|
|
166 -- 0000 11rd dddd rrrr - ADD
|
183 |
|
|
167 --
|
184 |
|
|
168 Q_ALU_OP <= ALU_ADD;
|
185 |
|
|
169 Q_WE_D <= "01";
|
186 |
|
|
170 Q_WE_F <= '1';
|
187 |
|
|
171
|
188 |
|
|
172 when "000100" => -- CPSE
|
189 |
|
|
173 Q_ALU_OP <= ALU_SUB;
|
190 |
|
|
174 Q_PC_OP <= PC_SKIP_Z;
|
191 |
|
|
175
|
192 |
|
|
176 when "000101" | "000110" =>
|
193 |
|
|
177 --
|
194 |
|
|
178 -- 0001 01rd dddd rrrr - CP = SUB without Q_WE_D
|
195 |
|
|
179 -- 0000 10rd dddd rrrr - SUB
|
196 |
|
|
180 --
|
197 |
|
|
181 Q_ALU_OP <= ALU_SUB;
|
198 |
|
|
182 Q_WE_D <= '0' & I_OPC(11); -- write Rd if SUB.
|
199 |
|
|
183 Q_WE_F <= '1';
|
200 |
|
|
184
|
201 |
|
|
185 when "000111" =>
|
202 |
|
|
186 --
|
203 |
|
|
187 -- 0001 11rd dddd rrrr - ADC
|
204 |
|
|
188 --
|
205 |
|
|
189 Q_ALU_OP <= ALU_ADC;
|
206 |
|
|
190 Q_WE_D <= "01";
|
207 |
|
|
191 Q_WE_F <= '1';
|
208 |
|
|
192
|
209 |
|
|
193 when "001000" =>
|
210 |
|
|
194 --
|
211 |
|
|
195 -- 0010 00rd dddd rrrr - AND
|
212 |
|
|
196 --
|
213 |
|
|
197 Q_ALU_OP <= ALU_AND;
|
214 |
|
|
198 Q_WE_D <= "01";
|
215 |
|
|
199 Q_WE_F <= '1';
|
216 |
|
|
200
|
217 |
|
|
201 when "001001" =>
|
218 |
|
|
202 --
|
219 |
|
|
203 -- 0010 01rd dddd rrrr - EOR
|
220 |
|
|
204 --
|
221 |
|
|
205 Q_ALU_OP <= ALU_EOR;
|
222 |
|
|
206 Q_WE_D <= "01";
|
223 |
|
|
207 Q_WE_F <= '1';
|
224 |
|
|
208
|
225 |
|
|
209 when "001010" => -- OR
|
226 |
|
|
210 --
|
227 |
|
|
211 -- 0010 10rd dddd rrrr - OR
|
228 |
|
|
212 --
|
229 |
|
|
213 Q_ALU_OP <= ALU_OR;
|
230 |
|
|
214 Q_WE_D <= "01";
|
231 |
|
|
215 Q_WE_F <= '1';
|
232 |
|
|
216
|
233 |
|
|
217 when "001011" =>
|
234 |
|
|
218 --
|
235 |
|
|
219 -- 0010 11rd dddd rrrr - MOV
|
236 |
|
|
220 --
|
237 |
|
|
221 Q_ALU_OP <= ALU_R_MV_Q;
|
238 |
|
|
222 Q_WE_D <= "01";
|
239 |
|
|
223
|
240 |
|
|
224 when "001100" | "001101" | "001110" | "001111"
|
241 |
|
|
225 | "010100" | "010101" | "010110" | "010111" =>
|
242 |
|
|
226 --
|
243 |
|
|
227 -- 0011 KKKK dddd KKKK - CPI
|
244 |
|
|
228 -- 0101 KKKK dddd KKKK - SUBI
|
245 |
|
|
229 --
|
246 |
|
|
230 Q_ALU_OP <= ALU_SUB;
|
247 |
|
|
231 Q_IMM(7 downto 0) <= I_OPC(11 downto 8) & I_OPC(3 downto 0);
|
248 |
|
|
232 Q_RSEL <= RS_IMM;
|
249 |
|
|
233 Q_DDDDD(4) <= '1'; -- Rd = 16...31
|
250 |
|
|
234 Q_WE_D <= '0' & I_OPC(14);
|
251 |
|
|
235 Q_WE_F <= '1';
|
252 |
|
|
236
|
253 |
|
|
237 when "010000" | "010001" | "010010" | "010011" =>
|
254 |
|
|
238 --
|
255 |
|
|
239 -- 0100 KKKK dddd KKKK - SBCI
|
256 |
|
|
240 --
|
257 |
|
|
241 Q_ALU_OP <= ALU_SBC;
|
258 |
|
|
242 Q_IMM(7 downto 0) <= I_OPC(11 downto 8) & I_OPC(3 downto 0);
|
259 |
|
|
243 Q_RSEL <= RS_IMM;
|
260 |
|
|
244 Q_DDDDD(4) <= '1'; -- Rd = 16...31
|
261 |
|
|
245 Q_WE_D <= "01";
|
262 |
|
|
246 Q_WE_F <= '1';
|
263 |
|
|
247
|
264 |
|
|
248
|
265 |
|
|
249
|
266 |
|
|
250 when "011000" | "011001" | "011010" | "011011" =>
|
267 |
|
|
251 --
|
268 |
|
|
252 -- 0110 KKKK dddd KKKK - ORI
|
269 |
|
|
253 --
|
270 |
|
|
254 Q_ALU_OP <= ALU_OR;
|
271 |
|
|
255 Q_IMM(7 downto 0) <= I_OPC(11 downto 8) & I_OPC(3 downto 0);
|
272 |
|
|
256 Q_RSEL <= RS_IMM;
|
273 |
|
|
257 Q_DDDDD(4) <= '1'; -- Rd = 16...31
|
274 |
|
|
258 Q_WE_D <= "01";
|
275 |
|
|
259 Q_WE_F <= '1';
|
276 |
|
|
260
|
277 |
|
|
261 when "011100" | "011101" | "011110" | "011111" =>
|
278 |
|
|
262 --
|
279 |
|
|
263 -- 0111 KKKK dddd KKKK - ANDI
|
280 |
|
|
264 --
|
281 |
|
|
265 Q_ALU_OP <= ALU_AND;
|
282 |
|
|
266 Q_IMM(7 downto 0) <= I_OPC(11 downto 8) & I_OPC(3 downto 0);
|
283 |
|
|
267 Q_RSEL <= RS_IMM;
|
284 |
|
|
268 Q_DDDDD(4) <= '1'; -- Rd = 16...31
|
285 |
|
|
269 Q_WE_D <= "01";
|
286 |
|
|
270 Q_WE_F <= '1';
|
287 |
|
|
271
|
288 |
|
|
272 when "100000" | "100001" | "100010" | "100011"
|
289 |
|
|
273 | "101000" | "101001" | "101010" | "101011" =>
|
290 |
|
|
274 --
|
291 |
|
|
275 -- LDD (Y + q) == LD(y) if q == 0
|
292 |
|
|
276 -- 10q0 qq0d dddd 1qqq LDD (Y + q)
|
293 |
|
|
277 -- 10q0 qq0d dddd 0qqq LDD (Z + q)
|
294 |
|
|
278 -- 10q0 qq1d dddd 1qqq SDD (Y + q)
|
295 |
|
|
279 -- 10q0 qq1d dddd 0qqq SDD (Z + q)
|
296 |
|
|
280 -- L/ Z/
|
297 |
|
|
281 -- S Y
|
298 |
|
|
282 --
|
299 |
|
|
283 -- device specific
|
300 |
|
|
284 --
|
301 |
|
|
285 Q_IMM(5 downto 0) <= I_OPC(13) & I_OPC(11 downto 10)
|
302 |
|
|
286 & I_OPC(2 downto 0);
|
303 |
|
|
287
|
304 |
|
|
288 if (I_OPC(3) = '0') then Q_AMOD <= AMOD_Zq;
|
305 |
|
|
289 else Q_AMOD <= AMOD_Yq;
|
306 |
|
|
290 end if;
|
307 |
|
|
291
|
308 |
|
|
292 Q_RD_M <= not I_OPC(9); -- '1' if LDD
|
309 |
|
|
293 Q_WE_M <= '0' & I_OPC(9); -- "01" if STD
|
310 |
|
|
294
|
311 |
|
|
295 when "100100" =>
|
312 |
|
|
296 Q_IMM <= I_OPC(31 downto 16); -- for LDS/STS
|
313 |
|
|
297 if (I_OPC(9) = '0') then -- LDD / POP
|
314 |
|
|
298 --
|
315 |
|
|
299 -- 1001 00-0d dddd 0000 - LDS
|
316 |
|
|
300 -- 1001 00-0d dddd 0001 - LD Rd, Z+
|
317 |
|
|
301 -- 1001 00-0d dddd 0010 - LD Rd, -Z
|
318 |
|
|
302 -- 1001 00-0d dddd 0100 - (ii) LPM Rd, (Z)
|
319 |
|
|
303 -- 1001 00-0d dddd 0101 - (iii) LPM Rd, (Z+)
|
320 |
|
|
304 -- 1001 00-0d dddd 0110 - ELPM Z --- not mega8
|
321 |
|
|
305 -- 1001 00-0d dddd 0111 - ELPM Z+ --- not mega8
|
322 |
|
|
306 -- 1001 00-0d dddd 1001 - LD Rd, Y+
|
323 |
|
|
307 -- 1001 00-0d dddd 1010 - LD Rd, -Y
|
324 |
|
|
308 -- 1001 00-0d dddd 1100 - LD Rd, X
|
325 |
|
|
309 -- 1001 00-0d dddd 1101 - LD Rd, X+
|
326 |
|
|
310 -- 1001 00-0d dddd 1110 - LD Rd, -X
|
327 |
|
|
311 -- 1001 00-0d dddd 1111 - POP Rd
|
328 |
|
|
312 --
|
329 |
|
|
313 Q_ALU_OP <= ALU_R_MV_Q;
|
330 |
|
|
314 Q_RSEL <= RS_DIN;
|
331 |
|
|
315 Q_RD_M <= I_T0;
|
332 |
|
|
316 Q_WE_D <= '0' & not I_T0;
|
333 |
|
|
317 Q_WE_XYZS <= not I_T0;
|
334 |
|
|
318 Q_PMS <= (not I_OPC(3)) and I_OPC(2) and (not I_OPC(1));
|
335 |
|
|
319 case I_OPC(3 downto 0) is
|
336 |
|
|
320 when "0000" => Q_AMOD <= AMOD_ABS; Q_WE_XYZS <= '0';
|
337 |
|
|
321 when "0001" => Q_AMOD <= AMOD_Zi;
|
338 |
|
|
322 when "0100" => Q_AMOD <= AMOD_Z; Q_WE_XYZS <= '0';
|
339 |
|
|
323 when "0101" => Q_AMOD <= AMOD_Zi;
|
340 |
|
|
324 when "1001" => Q_AMOD <= AMOD_Yi;
|
341 |
|
|
325 when "1010" => Q_AMOD <= AMOD_dY;
|
342 |
|
|
326 when "1100" => Q_AMOD <= AMOD_X; Q_WE_XYZS <= '0';
|
343 |
|
|
327 when "1101" => Q_AMOD <= AMOD_Xi;
|
344 |
|
|
328 when "1110" => Q_AMOD <= AMOD_dX;
|
345 |
|
|
329 when "1111" => Q_AMOD <= AMOD_SPi;
|
346 |
|
|
330 when others => Q_WE_XYZS <= '0';
|
347 |
|
|
331 end case;
|
348 |
|
|
332 else -- STD / PUSH
|
349 |
|
|
333 --
|
350 |
|
|
334 -- 1001 00-1r rrrr 0000 - STS
|
351 |
|
|
335 -- 1001 00-1r rrrr 0001 - ST Z+. Rr
|
352 |
|
|
336 -- 1001 00-1r rrrr 0010 - ST -Z. Rr
|
353 |
|
|
337 -- 1001 00-1r rrrr 1000 - ST Y. Rr
|
354 |
|
|
338 -- 1001 00-1r rrrr 1001 - ST Y+. Rr
|
355 |
|
|
339 -- 1001 00-1r rrrr 1010 - ST -Y. Rr
|
356 |
|
|
340 -- 1001 00-1r rrrr 1100 - ST X. Rr
|
357 |
|
|
341 -- 1001 00-1r rrrr 1101 - ST X+. Rr
|
358 |
|
|
342 -- 1001 00-1r rrrr 1110 - ST -X. Rr
|
359 |
|
|
343 -- 1001 00-1r rrrr 1111 - PUSH Rr
|
360 |
|
|
344 --
|
361 |
|
|
345 Q_ALU_OP <= ALU_D_MV_Q;
|
362 |
|
|
346 Q_WE_M <= "01";
|
363 |
|
|
347 Q_WE_XYZS <= '1';
|
364 |
|
|
348 case I_OPC(3 downto 0) is
|
365 |
|
|
349 when "0000" => Q_AMOD <= AMOD_ABS; Q_WE_XYZS <= '0';
|
366 |
|
|
350 when "0001" => Q_AMOD <= AMOD_Zi;
|
367 |
|
|
351 when "0010" => Q_AMOD <= AMOD_dZ;
|
368 |
|
|
352 when "1001" => Q_AMOD <= AMOD_Yi;
|
369 |
|
|
353 when "1010" => Q_AMOD <= AMOD_dY;
|
370 |
|
|
354 when "1100" => Q_AMOD <= AMOD_X; Q_WE_XYZS <= '0';
|
371 |
|
|
355 when "1101" => Q_AMOD <= AMOD_Xi;
|
372 |
|
|
356 when "1110" => Q_AMOD <= AMOD_dX;
|
373 |
|
|
357 when "1111" => Q_AMOD <= AMOD_dSP;
|
374 |
|
|
358 when others =>
|
375 |
|
|
359 end case;
|
376 |
|
|
360 end if;
|
377 |
|
|
361
|
378 |
|
|
362 when "100101" =>
|
379 |
|
|
363 if (I_OPC(9) = '0') then
|
380 |
|
|
364 if (I_OPC(3) = '0') then
|
381 |
|
|
365 --
|
382 |
|
|
366 -- 1001 010d dddd 0000 - COM
|
383 |
|
|
367 -- 1001 010d dddd 0001 - NEG
|
384 |
|
|
368 -- 1001 010d dddd 0010 - SWAP
|
385 |
|
|
369 -- 1001 010d dddd 0011 - INC
|
386 |
|
|
370 -- 1001 010d dddd 0101 - ASR
|
387 |
|
|
371 -- 1001 010d dddd 0110 - LSR
|
388 |
|
|
372 -- 1001 010d dddd 0111 - ROR
|
389 |
|
|
373 --
|
390 |
|
|
374 case I_OPC(2 downto 0) is
|
391 |
|
|
375 when "000" => Q_ALU_OP <= ALU_COM;
|
392 |
|
|
376 when "001" => Q_ALU_OP <= ALU_NEG;
|
393 |
|
|
377 when "010" => Q_ALU_OP <= ALU_SWAP;
|
394 |
|
|
378 when "011" => Q_ALU_OP <= ALU_INC;
|
395 |
|
|
379 when "101" => Q_ALU_OP <= ALU_ASR;
|
396 |
|
|
380 when "110" => Q_ALU_OP <= ALU_LSR;
|
397 |
|
|
381 when "111" => Q_ALU_OP <= ALU_ROR;
|
398 |
|
|
382 when others =>
|
399 |
|
|
383 end case;
|
400 |
|
|
384 Q_WE_D <= "01";
|
401 |
|
|
385 Q_WE_F <= '1';
|
402 |
|
|
386 else
|
403 |
|
|
387 case I_OPC(2 downto 0) is
|
404 |
|
|
388 when "000" =>
|
405 |
|
|
389 if (I_OPC(8)) = '0' then
|
406 |
|
|
390 --
|
407 |
|
|
391 -- 1001 0100 0sss 1000 - BSET
|
408 |
|
|
392 -- 1001 0100 1sss 1000 - BCLR
|
409 |
|
|
393 --
|
410 |
|
|
394 Q_BIT(3 downto 0) <= I_OPC(7 downto 4);
|
411 |
|
|
395 Q_ALU_OP <= ALU_SREG;
|
412 |
|
|
396 Q_WE_F <= '1';
|
413 |
|
|
397 else
|
414 |
|
|
398 --
|
415 |
|
|
399 -- 1001 0101 0000 1000 - RET
|
416 |
|
|
400 -- 1001 0101 0001 1000 - RETI
|
417 |
|
|
401 -- 1001 0101 1000 1000 - SLEEP
|
418 |
|
|
402 -- 1001 0101 1001 1000 - BREAK
|
419 |
|
|
403 -- 1001 0101 1100 1000 - LPM [ R0,(Z) ]
|
420 |
|
|
404 -- 1001 0101 1101 1000 - ELPM not mega8
|
421 |
|
|
405 -- 1001 0101 1110 1000 - SPM
|
422 |
|
|
406 -- 1001 0101 1111 1000 - SPM #2
|
423 |
|
|
407 -- 1001 0101 1010 1000 - WDR
|
424 |
|
|
408 --
|
425 |
|
|
409 case I_OPC(7 downto 4) is
|
426 |
|
|
410 when "0000" => -- RET
|
427 |
|
|
411 Q_AMOD <= AMOD_SPii;
|
428 |
|
|
412 if (I_T0 = '1') then
|
429 |
|
|
413 Q_RD_M <= '1';
|
430 |
|
|
414 else
|
431 |
|
|
415 Q_PC_OP <= PC_LD_S;
|
432 |
|
|
416 Q_WE_XYZS <= not I_T0;
|
433 |
|
|
417 end if;
|
434 |
|
|
418
|
435 |
|
|
419 when "0001" => -- RETI
|
436 |
|
|
420 Q_ALU_OP <= ALU_INTR;
|
437 |
|
|
421 Q_IMM(6) <= '1';
|
438 |
|
|
422 Q_AMOD <= AMOD_SPii;
|
439 |
|
|
423 if (I_T0 = '1') then
|
440 |
|
|
424 Q_RD_M <= '1';
|
441 |
|
|
425 else
|
442 |
|
|
426 Q_PC_OP <= PC_LD_S;
|
443 |
|
|
427 Q_WE_XYZS <= not I_T0;
|
444 |
|
|
428 end if;
|
445 |
|
|
429
|
446 |
|
|
430 when "1000" => -- (i) LPM R0, (Z)
|
447 |
|
|
431 Q_DDDDD <= "00000";
|
448 |
|
|
432 Q_AMOD <= AMOD_Z;
|
449 |
|
|
433 Q_PMS <= '1';
|
450 |
|
|
434 Q_WE_D <= '0' & not I_T0;
|
451 |
|
|
435
|
452 |
|
|
436 when "1110" => -- SPM
|
453 |
|
|
437 Q_DDDDD <= "00000";
|
454 |
|
|
438 Q_AMOD <= AMOD_Z;
|
455 |
|
|
439 Q_PMS <= '1';
|
456 |
|
|
440 Q_WE_M <= "01";
|
457 |
|
|
441
|
458 |
|
|
442 when "1111" => -- SPM #2
|
459 |
|
|
443 -- page write: not su[pported
|
460 |
|
|
444
|
461 |
|
|
445 when others =>
|
462 |
|
|
446 end case;
|
463 |
|
|
447 end if;
|
464 |
|
|
448
|
465 |
|
|
449 when "001" =>
|
466 |
|
|
450 --
|
467 |
|
|
451 -- 1001 0100 0000 1001 IJMP
|
468 |
|
|
452 -- 1001 0100 0001 1001 EIJMP -- not mega8
|
469 |
|
|
453 -- 1001 0101 0000 1001 ICALL
|
470 |
|
|
454 -- 1001 0101 0001 1001 EICALL -- not mega8
|
471 |
|
|
455 --
|
472 |
|
|
456 Q_PC_OP <= PC_LD_Z;
|
473 |
|
|
457 if (I_OPC(8) = '1') then -- ICALL
|
474 |
|
|
458 Q_ALU_OP <= ALU_PC_1;
|
475 |
|
|
459 Q_AMOD <= AMOD_ddSP;
|
476 |
|
|
460 Q_WE_M <= "11";
|
477 |
|
|
461 Q_WE_XYZS <= '1';
|
478 |
|
|
462 end if;
|
479 |
|
|
463
|
480 |
|
|
464 when "010" =>
|
481 |
|
|
465 --
|
482 |
|
|
466 -- 1001 010d dddd 1010 - DEC
|
483 |
|
|
467 --
|
484 |
|
|
468 Q_ALU_OP <= ALU_DEC;
|
485 |
|
|
469 Q_WE_D <= "01";
|
486 |
|
|
470 Q_WE_F <= '1';
|
487 |
|
|
471
|
488 |
|
|
472 when "011" =>
|
489 |
|
|
473 --
|
490 |
|
|
474 -- 1001 0100 KKKK 1011 - DES -- not mega8
|
491 |
|
|
475 --
|
492 |
|
|
476
|
493 |
|
|
477 when "100" | "101" =>
|
494 |
|
|
478 --
|
495 |
|
|
479 -- 1001 010k kkkk 110k - JMP (k = 0 for 16 bit)
|
496 |
|
|
480 -- kkkk kkkk kkkk kkkk
|
497 |
|
|
481 --
|
498 |
|
|
482 Q_PC_OP <= PC_LD_I;
|
499 |
|
|
483
|
500 |
|
|
484 when "110" | "111" =>
|
501 |
|
|
485 --
|
502 |
|
|
486 -- 1001 010k kkkk 111k - CALL (k = 0)
|
503 |
|
|
487 -- kkkk kkkk kkkk kkkk
|
504 |
|
|
488 --
|
505 |
|
|
489 Q_ALU_OP <= ALU_PC_2;
|
506 |
|
|
490 Q_AMOD <= AMOD_ddSP;
|
507 |
|
|
491 Q_PC_OP <= PC_LD_I;
|
508 |
|
|
492 Q_WE_M <= "11"; -- both PC bytes
|
509 |
|
|
493 Q_WE_XYZS <= '1';
|
510 |
|
|
494
|
511 |
|
|
495 when others =>
|
512 |
|
|
496 end case;
|
513 |
|
|
497 end if;
|
514 |
|
|
498 else
|
515 |
|
|
499 --
|
516 |
|
|
500 -- 1001 0110 KKdd KKKK - ADIW
|
517 |
|
|
501 -- 1001 0111 KKdd KKKK - SBIW
|
518 |
|
|
502 --
|
519 |
|
|
503 if (I_OPC(8) = '0') then Q_ALU_OP <= ALU_ADIW;
|
520 |
|
|
504 else Q_ALU_OP <= ALU_SBIW;
|
521 |
|
|
505 end if;
|
522 |
|
|
506 Q_IMM(5 downto 4) <= I_OPC(7 downto 6);
|
523 |
|
|
507 Q_IMM(3 downto 0) <= I_OPC(3 downto 0);
|
524 |
|
|
508 Q_RSEL <= RS_IMM;
|
525 |
|
|
509 Q_DDDDD <= "11" & I_OPC(5 downto 4) & "0";
|
526 |
|
|
510
|
527 |
|
|
511 Q_WE_D <= "11";
|
528 |
|
|
512 Q_WE_F <= '1';
|
529 |
|
|
513 end if; -- I_OPC(9) = 0/1
|
530 |
|
|
514
|
531 |
|
|
515 when "100110" =>
|
532 |
|
|
516 --
|
533 |
|
|
517 -- 1001 1000 AAAA Abbb - CBI
|
534 |
|
|
518 -- 1001 1001 AAAA Abbb - SBIC
|
535 |
|
|
519 -- 1001 1010 AAAA Abbb - SBI
|
536 |
|
|
520 -- 1001 1011 AAAA Abbb - SBIS
|
537 |
|
|
521 --
|
538 |
|
|
522 Q_ALU_OP <= ALU_BIT_CS;
|
539 |
|
|
523 Q_AMOD <= AMOD_ABS;
|
540 |
|
|
524 Q_BIT(3) <= I_OPC(9); -- set/clear
|
541 |
|
|
525
|
542 |
|
|
526 -- IMM = AAAAAA + 0x20
|
543 |
|
|
527 --
|
544 |
|
|
528 Q_IMM(4 downto 0) <= I_OPC(7 downto 3);
|
545 |
|
|
529 Q_IMM(6 downto 5) <= "01";
|
546 |
|
|
530
|
547 |
|
|
531 Q_RD_M <= I_T0;
|
548 |
|
|
532 Q_WE_M <= "00";
|
549 |
|
|
533 if ((I_OPC(8) = '0') ) then -- CBI or SBI
|
550 |
|
|
534 Q_WE_M(0) <= '1';
|
551 |
|
|
535 else -- SBIC or SBIS
|
552 |
|
|
536 if (I_T0 = '0') then
|
553 |
|
|
537 Q_PC_OP <= PC_SKIP_T;
|
554 |
|
|
538 end if;
|
555 |
|
|
539 end if;
|
556 |
|
|
540
|
557 |
|
|
541 when "100111" => -- MUL
|
558 |
|
|
542 --
|
559 |
|
|
543 -- 1001 11rd dddd rrrr - MUL
|
560 |
|
|
544 --
|
561 |
|
|
545 Q_ALU_OP <= ALU_MULT;
|
562 |
|
|
546 Q_IMM(7 downto 5) <= "000"; -- -MUL UU;
|
563 |
|
|
547 Q_WE_01 <= '1';
|
564 |
|
|
548 Q_WE_F <= '1';
|
565 |
|
|
549
|
566 |
|
|
550 when "101100" | "101101" =>
|
567 |
|
|
551 --
|
568 |
|
|
552 -- 1011 0AAd dddd AAAA - IN
|
569 |
|
|
553 --
|
570 |
|
|
554 Q_ALU_OP <= ALU_R_MV_Q;
|
571 |
|
|
555 Q_RSEL <= RS_DIN;
|
572 |
|
|
556 Q_AMOD <= AMOD_ABS;
|
573 |
|
|
557
|
574 |
|
|
558 -- IMM = AAAAAA
|
575 |
|
|
559 -- + 010000 (0x20)
|
576 |
|
|
560 Q_IMM(3 downto 0) <= I_OPC(3 downto 0);
|
577 |
|
|
561 Q_IMM(4) <= I_OPC(9);
|
578 |
|
|
562 Q_IMM(6 downto 5) <= "01" + ('0' & I_OPC(10 downto 10));
|
579 |
|
|
563
|
580 |
|
|
564 Q_WE_D <= "01";
|
581 |
|
|
565
|
582 |
|
|
566 when "101110" | "101111" =>
|
583 |
|
|
567 --
|
584 |
|
|
568 -- 1011 1AAr rrrr AAAA - OUT
|
585 |
|
|
569 --
|
586 |
|
|
570 Q_ALU_OP <= ALU_D_MV_Q;
|
587 |
|
|
571 Q_AMOD <= AMOD_ABS;
|
588 |
|
|
572
|
589 |
|
|
573 -- IMM = AAAAAA
|
590 |
|
|
574 -- + 010000 (0x20)
|
591 |
|
|
575 --
|
592 |
|
|
576 Q_IMM(3 downto 0) <= I_OPC(3 downto 0);
|
593 |
|
|
577 Q_IMM(4) <= I_OPC(9);
|
594 |
|
|
578 Q_IMM(6 downto 5) <= "01" + ('0' & I_OPC(10 downto 10));
|
595 |
|
|
579 Q_WE_M <= "01";
|
596 |
|
|
580
|
597 |
|
|
581 when "110000" | "110001" | "110010" | "110011" =>
|
598 |
|
|
582 --
|
599 |
|
|
583 -- 1100 kkkk kkkk kkkk - RJMP
|
600 |
|
|
584 --
|
601 |
|
|
585 Q_JADR <= I_PC + (I_OPC(11) & I_OPC(11) & I_OPC(11) & I_OPC(11)
|
602 |
|
|
586 & I_OPC(11 downto 0)) + X"0001";
|
603 |
|
|
587 Q_PC_OP <= PC_LD_I;
|
604 |
|
|
588
|
605 |
|
|
589 when "110100" | "110101" | "110110" | "110111" =>
|
606 |
|
|
590 --
|
607 |
|
|
591 -- 1101 kkkk kkkk kkkk - RCALL
|
608 |
|
|
592 --
|
609 |
|
|
593 Q_JADR <= I_PC + (I_OPC(11) & I_OPC(11) & I_OPC(11) & I_OPC(11)
|
610 |
|
|
594 & I_OPC(11 downto 0)) + X"0001";
|
611 |
|
|
595 Q_ALU_OP <= ALU_PC_1;
|
612 |
|
|
596 Q_AMOD <= AMOD_ddSP;
|
613 |
|
|
597 Q_PC_OP <= PC_LD_I;
|
614 |
|
|
598 Q_WE_M <= "11"; -- both PC bytes
|
615 |
|
|
599 Q_WE_XYZS <= '1';
|
616 |
|
|
600
|
617 |
|
|
601 when "111000" | "111001" | "111010" | "111011" => -- LDI
|
618 |
|
|
602 --
|
619 |
|
|
603 -- 1110 KKKK dddd KKKK - LDI Rd, K
|
620 |
|
|
604 --
|
621 |
|
|
605 Q_ALU_OP <= ALU_R_MV_Q;
|
622 |
|
|
606 Q_DDDDD <= '1' & I_OPC(7 downto 4); -- 16..31
|
623 |
|
|
607 Q_IMM(7 downto 0) <= I_OPC(11 downto 8) & I_OPC(3 downto 0);
|
624 |
|
|
608 Q_RSEL <= RS_IMM;
|
625 |
|
|
609 Q_WE_D <= "01";
|
626 |
|
|
610
|
627 |
|
|
611 when "111100" | "111101" =>
|
628 |
|
|
612 --
|
629 |
|
|
613 -- 1111 00kk kkkk kbbb - BRBS
|
630 |
|
|
614 -- 1111 01kk kkkk kbbb - BRBC
|
631 |
|
|
615 -- v
|
632 |
|
|
616 -- bbb: status register bit
|
633 |
|
|
617 -- v: value (set/cleared) of status register bit
|
634 |
|
|
618 --
|
635 |
|
|
619 Q_JADR <= I_PC + (I_OPC(9) & I_OPC(9) & I_OPC(9) & I_OPC(9)
|
636 |
|
|
620 & I_OPC(9) & I_OPC(9) & I_OPC(9) & I_OPC(9)
|
637 |
|
|
621 & I_OPC(9) & I_OPC(9 downto 3)) + X"0001";
|
638 |
|
|
622 Q_PC_OP <= PC_BCC;
|
639 |
|
|
623
|
640 |
|
|
624 when "111110" =>
|
641 |
|
|
625 --
|
642 |
|
|
626 -- 1111 100d dddd 0bbb - BLD
|
643 |
|
|
627 -- 1111 101d dddd 0bbb - BST
|
644 |
|
|
628 --
|
645 |
|
|
629 if I_OPC(9) = '0' then -- BLD: T flag to register
|
646 |
|
|
630 Q_ALU_OP <= ALU_BLD;
|
647 |
|
|
631 Q_WE_D <= "01";
|
648 |
|
|
632 else -- BST: register to T flag
|
649 |
|
|
633 Q_AMOD <= AMOD_ABS;
|
650 |
|
|
634 Q_BIT(3) <= I_OPC(10);
|
651 |
|
|
635 Q_IMM(4 downto 0) <= I_OPC(8 downto 4);
|
652 |
|
|
636 Q_ALU_OP <= ALU_BIT_CS;
|
653 |
|
|
637 Q_WE_F <= '1';
|
654 |
|
|
638 end if;
|
655 |
|
|
639
|
656 |
|
|
640 when "111111" =>
|
657 |
|
|
641 --
|
658 |
|
|
642 -- 1111 110r rrrr 0bbb - SBRC
|
659 |
|
|
643 -- 1111 111r rrrr 0bbb - SBRS
|
660 |
|
|
644 --
|
661 |
|
|
645 -- like SBIC, but and general purpose regs instead of I/O regs.
|
662 |
|
|
646 --
|
663 |
|
|
647 Q_ALU_OP <= ALU_BIT_CS;
|
664 |
|
|
648 Q_AMOD <= AMOD_ABS;
|
665 |
|
|
649 Q_BIT(3) <= I_OPC(9); -- set/clear bit
|
666 |
|
|
650 Q_IMM(4 downto 0) <= I_OPC(8 downto 4);
|
667 |
|
|
651 if (I_T0 = '0') then
|
668 |
|
|
652 Q_PC_OP <= PC_SKIP_T;
|
669 |
|
|
653 end if;
|
670 |
|
|
654
|
671 |
|
|
655 when others =>
|
672 |
|
|
656 end case;
|
673 |
|
|
657 end if;
|
674 |
|
|
658 end process;
|
675 |
|
|
659
|
676 |
|
|
660 end Behavioral;
|
677 |
|
|
661
|
678 |
|
|
<pre class="filename">
|
679 |
|
|
src/opc_deco.vhd
|
680 |
|
|
</pre></pre>
|
681 |
|
|
<P>
|
682 |
|
|
|
683 |
|
|
<P><hr><BR>
|
684 |
|
|
<table class="ttop"><th class="tpre"><a href="17_Listing_of_io.vhd.html">Previous Lesson</a></th><th class="ttop"><a href="toc.html">Table of Content</a></th><th class="tnxt"><a href="19_Listing_of_opc_fetch.vhd.html">Next Lesson</a></th></table>
|
685 |
|
|
</BODY>
|
686 |
|
|
</HTML>
|