1 |
2 |
MichaelA |
////////////////////////////////////////////////////////////////////////////////
|
2 |
|
|
//
|
3 |
|
|
// Copyright 2009-2013 by Michael A. Morris, dba M. A. Morris & Associates
|
4 |
|
|
//
|
5 |
|
|
// All rights reserved. The source code contained herein is publicly released
|
6 |
|
|
// under the terms and conditions of the GNU Lesser Public License. No part of
|
7 |
|
|
// this source code may be reproduced or transmitted in any form or by any
|
8 |
|
|
// means, electronic or mechanical, including photocopying, recording, or any
|
9 |
|
|
// information storage and retrieval system in violation of the license under
|
10 |
|
|
// which the source code is released.
|
11 |
|
|
//
|
12 |
|
|
// The source code contained herein is free; it may be redistributed and/or
|
13 |
|
|
// modified in accordance with the terms of the GNU Lesser General Public
|
14 |
|
|
// License as published by the Free Software Foundation; either version 2.1 of
|
15 |
|
|
// the GNU Lesser General Public License, or any later version.
|
16 |
|
|
//
|
17 |
|
|
// The source code contained herein is freely released WITHOUT ANY WARRANTY;
|
18 |
|
|
// without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
|
19 |
|
|
// PARTICULAR PURPOSE. (Refer to the GNU Lesser General Public License for
|
20 |
|
|
// more details.)
|
21 |
|
|
//
|
22 |
|
|
// A copy of the GNU Lesser General Public License should have been received
|
23 |
|
|
// along with the source code contained herein; if not, a copy can be obtained
|
24 |
|
|
// by writing to:
|
25 |
|
|
//
|
26 |
|
|
// Free Software Foundation, Inc.
|
27 |
|
|
// 51 Franklin Street, Fifth Floor
|
28 |
|
|
// Boston, MA 02110-1301 USA
|
29 |
|
|
//
|
30 |
|
|
// Further, no use of this source code is permitted in any form or means
|
31 |
|
|
// without inclusion of this banner prominently in any derived works.
|
32 |
|
|
//
|
33 |
|
|
// Michael A. Morris
|
34 |
|
|
// Huntsville, AL
|
35 |
|
|
//
|
36 |
|
|
////////////////////////////////////////////////////////////////////////////////
|
37 |
|
|
|
38 |
|
|
`timescale 1ns / 1ps
|
39 |
|
|
|
40 |
|
|
///////////////////////////////////////////////////////////////////////////////
|
41 |
|
|
// Company: M. A. Morris & Associates
|
42 |
|
|
// Engineer: Michael A. Morris
|
43 |
|
|
//
|
44 |
|
|
// Create Date: 18:05:57 08/18/2009
|
45 |
|
|
// Design Name: PIC16C5x Verilog Processor Model
|
46 |
|
|
// Module Name: C:/ISEProjects/ISE10.1i/F16C5x/PIC16C5x_IDecode
|
47 |
|
|
// Project Name: C:/ISEProjects/ISE10.1i/F16C5x.ise
|
48 |
|
|
// Target Devices: N/A
|
49 |
|
|
// Tool versions: ISE 10.1i SP3
|
50 |
|
|
//
|
51 |
|
|
// Description:
|
52 |
|
|
//
|
53 |
|
|
// Module implements a pipelined instruction decoder for the PIC16C5x family
|
54 |
|
|
// of processors. The decoder utilizes three decode ROMs to reduce the number
|
55 |
|
|
// of logic levels in the decode path. All PIC16C5x instructions are decoded,
|
56 |
|
|
// and registered decoded instruction outputs for certain instructions and a
|
57 |
|
|
// registered ALU Operation output is also provided. A decode error output is
|
58 |
|
|
// also provided. The inputs required are the Instruction Register, IR, and a
|
59 |
|
|
// instruction skip, i.e. pipeline flush/delay, signal.
|
60 |
|
|
//
|
61 |
|
|
// ROM1 is used to decode instructions in the range of 0x000-0x007 and 0x800-
|
62 |
|
|
// 0xFFF. ROM1 outputs data that is multiplexed into the dIR, decoded IR FFs,
|
63 |
|
|
// based on whether the instruction actually fits into this range. A 4-bit
|
64 |
|
|
// address is used to access the ROM. Thus, DI[11] is the most significant
|
65 |
|
|
// address bit, and either DI[10:8] or DI[2:0] is used for the lower three
|
66 |
|
|
// bits of the ROM1 address. DI[11] is used to select which set of the lower
|
67 |
|
|
// three addresses are used. In the event that DI[11] is a logic 0, DI[2:0] is
|
68 |
|
|
// decoded by ROM1, but the decode is incomplete. Thus, if DI[11] == 0, then
|
69 |
|
|
// ROM1's output is valid only if DI[10:3] == 0 as well. This comparison and
|
70 |
|
|
// DI[10:3] <> 0 is used to select the value registered by dDI[8:0].
|
71 |
|
|
//
|
72 |
|
|
// ROM2 is also used to decode the same range of instructions as ROM1. Its
|
73 |
|
|
// 12-bit output is multiplexed with the 12-bit output of ROM3. ROM2 is a 16
|
74 |
|
|
// location ROM with a 12-bit output used to drive ALU_Op[11:0], and it shares
|
75 |
|
|
// its address generator with ROM1. Instead of using a single 22-bit wide ROM,
|
76 |
|
|
// two ROMs were used with a common address generator in order to avoid the
|
77 |
|
|
// assignment of the two fields to two different multiplexers for dIR and
|
78 |
|
|
// ALU_Op. ROM2 provides the registered ALU operation for the instruction for
|
79 |
|
|
// instructions that deal primarily with special processor functions and
|
80 |
|
|
// registers, 0x000-0x007, and for instructions that deal with literal opera-
|
81 |
|
|
// tions, 0x800-0xFFF. As such, ROM2's ALU_Op outputs are fairly sparse.
|
82 |
|
|
//
|
83 |
|
|
// ROM3 is used to decode a significantly larger number of IR bits. It decodes
|
84 |
|
|
// DI[10:5] so it covers the remaining instructions not decoded by ROM2/ROM1.
|
85 |
|
|
// ROM3's output drives the ALU_Op multiplexer like ROM2. The instructions
|
86 |
|
|
// decoded by ROM3 support indirect access of the register file through the
|
87 |
|
|
// Indirect File, INDF, access register. The address of INDF is 0, and if
|
88 |
|
|
// DI[4:0] refers to INDF, then the address provided to the register file
|
89 |
|
|
// address bus should come from the FSR, File Select Register. To achieve a
|
90 |
|
|
// compact decode of the instructions in this region, a 64 x 12 ROM is used,
|
91 |
|
|
// but the indirect addressing function requires a combinatorial signal to
|
92 |
|
|
// be generated between the ROM and the ALU_Op multiplexer.
|
93 |
|
|
//
|
94 |
|
|
// Where possible, a full decode of the instruction set is performed. Err is
|
95 |
|
|
// is generated to properly indicate that the IR contains a reserved op code.
|
96 |
|
|
// If dErr is asserted, a NOP operation is loaded into the ALU_Op, dIR, and
|
97 |
|
|
// the Err output is asserted.
|
98 |
|
|
//
|
99 |
|
|
// Dependencies: None
|
100 |
|
|
//
|
101 |
|
|
// Revision:
|
102 |
|
|
//
|
103 |
|
|
// 0.00 09H18 MAM File Created
|
104 |
|
|
//
|
105 |
|
|
// 1.00 13F23 MAM Changed input data port from IR to DI. When com-
|
106 |
|
|
// bined with the resulting changes to the upper level
|
107 |
|
|
// module, the result is to advance the decoding of the
|
108 |
|
|
// instruction being read from a synchronous ROM to the
|
109 |
|
|
// point in time when the data out of the ROM is valid
|
110 |
|
|
// as indicated by CE, i.e. Clock Enable.
|
111 |
|
|
//
|
112 |
|
|
// 1.10 13F23 MAM Determined that WE_F bit, ALU_Op[11], was being set
|
113 |
|
|
// during BTFSC and BTFSS instructions. Changed ROM3 to
|
114 |
|
|
// clear ROM3[11] (loaded into ALU_Op[11]) when these
|
115 |
|
|
// instructions are found.
|
116 |
|
|
//
|
117 |
|
|
// 1.20 13F23 MAM Added an additional bit to ROM1. New bit defines
|
118 |
|
|
// when literal operations are being performed. This is
|
119 |
|
|
// to be used to create the WE and RE signals for the
|
120 |
|
|
// various I/O ports supported by the core. Realigned
|
121 |
|
|
// ROM2 and ROM3 such the ROM2/ROM3 bit 9 and bit 10
|
122 |
|
|
// are swapped. These two bits are not used within the
|
123 |
|
|
// ALU, but are used in the P16C5x module. Change is
|
124 |
|
|
// cosmetic.
|
125 |
|
|
//
|
126 |
|
|
// Additional Comments:
|
127 |
|
|
//
|
128 |
|
|
// This instruction decoder is based on the combinatorial instruction decoder
|
129 |
|
|
// developed for the original implementation of this processor. That decoder
|
130 |
|
|
// is included as comments in this module as a reference for the correct
|
131 |
|
|
// implementation of this module using ROMs and multiplexers.
|
132 |
|
|
//
|
133 |
|
|
// ALU_Op[11:0] Mapping
|
134 |
|
|
//
|
135 |
|
|
// ALU_Op[1:0] = ALU Unit Operation Code
|
136 |
|
|
//
|
137 |
|
|
// Arithmetic Unit (AU): 00 => Y = A + B;
|
138 |
|
|
// 01 => Y = A + B + 1;
|
139 |
|
|
// 10 => Y = A + ~B = A - B - 1;
|
140 |
|
|
// 11 => Y = A + ~B + 1 = A - B;
|
141 |
|
|
//
|
142 |
|
|
// Logic Unit (LU): 00 => V = ~A;
|
143 |
|
|
// 01 => V = A | B;
|
144 |
|
|
// 10 => V = A & B;
|
145 |
|
|
// 11 => V = A ^ B;
|
146 |
|
|
//
|
147 |
|
|
// Shift Unit (SU): 00 => S = W; // MOVWF
|
148 |
|
|
// 01 => S = {A[3:0], A[7:4]}; // SWAPF
|
149 |
|
|
// 10 => S = {C, A[7:1]}; // RRF
|
150 |
|
|
// 11 => S = {A[6:0], C}; // RLF
|
151 |
|
|
//
|
152 |
|
|
// ALU_Op[3:2] = ALU Operand:
|
153 |
|
|
// A B
|
154 |
|
|
// 00 => File 0
|
155 |
|
|
// 01 => File W
|
156 |
|
|
// 10 => Literal 0
|
157 |
|
|
// 11 => Literal W;
|
158 |
|
|
//
|
159 |
|
|
// ALU Operations - Bit Processor (BP)
|
160 |
|
|
//
|
161 |
|
|
// ALU_Op[2:0] = Bit Select: 000 => Bit 0;
|
162 |
|
|
// 001 => Bit 1;
|
163 |
|
|
// 010 => Bit 2;
|
164 |
|
|
// 011 => Bit 3;
|
165 |
|
|
// 100 => Bit 4;
|
166 |
|
|
// 101 => Bit 5;
|
167 |
|
|
// 110 => Bit 6;
|
168 |
|
|
// 111 => Bit 7;
|
169 |
|
|
//
|
170 |
|
|
// ALU_Op[3] = Set: 0 - Clr Selected Bit;
|
171 |
|
|
// 1 - Set Selected Bit;
|
172 |
|
|
//
|
173 |
|
|
// ALU_Op[5:4] = Status Flag Update Select
|
174 |
|
|
//
|
175 |
|
|
// 00 => None
|
176 |
|
|
// 01 => C
|
177 |
|
|
// 10 => Z
|
178 |
|
|
// 11 => Z,DC,C
|
179 |
|
|
//
|
180 |
|
|
// ALU_Op[7:6] = ALU Output Data Multiplexer
|
181 |
|
|
//
|
182 |
|
|
// 00 => AU
|
183 |
|
|
// 01 => LU
|
184 |
|
|
// 10 => SU
|
185 |
|
|
// 11 => BP
|
186 |
|
|
//
|
187 |
|
|
// ALU_Op[8] = Tst: 0 - Normal Operation
|
188 |
|
|
// 1 - Test: INCFSZ/DECFSZ/BTFSC/BTFSS
|
189 |
|
|
//
|
190 |
|
|
// ALU_Op[9] = Write Enable Working Register (W)
|
191 |
|
|
//
|
192 |
|
|
// ALU_Op[10] = Indirect Register, INDF, Selected
|
193 |
|
|
//
|
194 |
|
|
// ALU_Op[11] = Write Enable File {RAM | Special Function Registers}
|
195 |
|
|
//
|
196 |
|
|
///////////////////////////////////////////////////////////////////////////////
|
197 |
|
|
|
198 |
|
|
module P16C5x_IDec(
|
199 |
|
|
input Rst,
|
200 |
|
|
input Clk,
|
201 |
|
|
input CE,
|
202 |
|
|
|
203 |
|
|
input [11:0] DI,
|
204 |
|
|
input Skip,
|
205 |
|
|
|
206 |
|
|
output reg [ 9:0] dIR,
|
207 |
|
|
output reg [11:0] ALU_Op,
|
208 |
|
|
output reg [ 8:0] KI,
|
209 |
|
|
|
210 |
|
|
output reg Err
|
211 |
|
|
);
|
212 |
|
|
|
213 |
|
|
//
|
214 |
|
|
///////////////////////////////////////////////////////////////////////////////
|
215 |
|
|
//
|
216 |
|
|
// Unused Opcodes - PIC16C5x Family
|
217 |
|
|
//
|
218 |
|
|
//localparam pOP_RSVD01 = 12'b0000_0000_0001; // Reserved - Unused Opcode
|
219 |
|
|
//
|
220 |
|
|
//localparam pOP_RSVD08 = 12'b0000_0000_1000; // Reserved - Unused Opcode
|
221 |
|
|
//localparam pOP_RSVD09 = 12'b0000_0000_1001; // Reserved - Unused Opcode
|
222 |
|
|
//localparam pOP_RSVD10 = 12'b0000_0000_1010; // Reserved - Unused Opcode
|
223 |
|
|
//localparam pOP_RSVD11 = 12'b0000_0000_1011; // Reserved - Unused Opcode
|
224 |
|
|
//localparam pOP_RSVD12 = 12'b0000_0000_1100; // Reserved - Unused Opcode
|
225 |
|
|
//localparam pOP_RSVD13 = 12'b0000_0000_1101; // Reserved - Unused Opcode
|
226 |
|
|
//localparam pOP_RSVD14 = 12'b0000_0000_1110; // Reserved - Unused Opcode
|
227 |
|
|
//localparam pOP_RSVD15 = 12'b0000_0000_1111; // Reserved - Unused Opcode
|
228 |
|
|
//
|
229 |
|
|
//localparam pOP_RSVD16 = 12'b0000_0001_0000; // Reserved - Unused Opcode
|
230 |
|
|
//localparam pOP_RSVD17 = 12'b0000_0001_0001; // Reserved - Unused Opcode
|
231 |
|
|
//localparam pOP_RSVD18 = 12'b0000_0001_0010; // Reserved - Unused Opcode
|
232 |
|
|
//localparam pOP_RSVD19 = 12'b0000_0001_0011; // Reserved - Unused Opcode
|
233 |
|
|
//localparam pOP_RSVD20 = 12'b0000_0001_0100; // Reserved - Unused Opcode
|
234 |
|
|
//localparam pOP_RSVD21 = 12'b0000_0001_0101; // Reserved - Unused Opcode
|
235 |
|
|
//localparam pOP_RSVD22 = 12'b0000_0001_0110; // Reserved - Unused Opcode
|
236 |
|
|
//localparam pOP_RSVD23 = 12'b0000_0001_0111; // Reserved - Unused Opcode
|
237 |
|
|
//localparam pOP_RSVD24 = 12'b0000_0001_1000; // Reserved - Unused Opcode
|
238 |
|
|
//localparam pOP_RSVD25 = 12'b0000_0001_1001; // Reserved - Unused Opcode
|
239 |
|
|
//localparam pOP_RSVD26 = 12'b0000_0001_1010; // Reserved - Unused Opcode
|
240 |
|
|
//localparam pOP_RSVD27 = 12'b0000_0001_1011; // Reserved - Unused Opcode
|
241 |
|
|
//localparam pOP_RSVD28 = 12'b0000_0001_1100; // Reserved - Unused Opcode
|
242 |
|
|
//localparam pOP_RSVD29 = 12'b0000_0001_1101; // Reserved - Unused Opcode
|
243 |
|
|
//localparam pOP_RSVD30 = 12'b0000_0001_1110; // Reserved - Unused Opcode
|
244 |
|
|
//localparam pOP_RSVD31 = 12'b0000_0001_1111; // Reserved - Unused Opcode
|
245 |
|
|
//
|
246 |
|
|
//localparam pOP_RSVD65 = 12'b0000_0100_0001; // Reserved - Unused Opcode
|
247 |
|
|
//localparam pOP_RSVD66 = 12'b0000_0100_0010; // Reserved - Unused Opcode
|
248 |
|
|
//localparam pOP_RSVD67 = 12'b0000_0100_0011; // Reserved - Unused Opcode
|
249 |
|
|
//localparam pOP_RSVD68 = 12'b0000_0100_0100; // Reserved - Unused Opcode
|
250 |
|
|
//localparam pOP_RSVD69 = 12'b0000_0100_0101; // Reserved - Unused Opcode
|
251 |
|
|
//localparam pOP_RSVD70 = 12'b0000_0100_0110; // Reserved - Unused Opcode
|
252 |
|
|
//localparam pOP_RSVD71 = 12'b0000_0100_0111; // Reserved - Unused Opcode
|
253 |
|
|
//localparam pOP_RSVD72 = 12'b0000_0100_1000; // Reserved - Unused Opcode
|
254 |
|
|
//localparam pOP_RSVD73 = 12'b0000_0100_1001; // Reserved - Unused Opcode
|
255 |
|
|
//localparam pOP_RSVD74 = 12'b0000_0100_1010; // Reserved - Unused Opcode
|
256 |
|
|
//localparam pOP_RSVD75 = 12'b0000_0100_1011; // Reserved - Unused Opcode
|
257 |
|
|
//localparam pOP_RSVD76 = 12'b0000_0100_1100; // Reserved - Unused Opcode
|
258 |
|
|
//localparam pOP_RSVD77 = 12'b0000_0100_1101; // Reserved - Unused Opcode
|
259 |
|
|
//localparam pOP_RSVD78 = 12'b0000_0100_1110; // Reserved - Unused Opcode
|
260 |
|
|
//localparam pOP_RSVD79 = 12'b0000_0100_1111; // Reserved - Unused Opcode
|
261 |
|
|
//
|
262 |
|
|
//localparam pOP_RSVD80 = 12'b0000_0101_0000; // Reserved - Unused Opcode
|
263 |
|
|
//localparam pOP_RSVD81 = 12'b0000_0101_0001; // Reserved - Unused Opcode
|
264 |
|
|
//localparam pOP_RSVD82 = 12'b0000_0101_0010; // Reserved - Unused Opcode
|
265 |
|
|
//localparam pOP_RSVD83 = 12'b0000_0101_0011; // Reserved - Unused Opcode
|
266 |
|
|
//localparam pOP_RSVD84 = 12'b0000_0101_0100; // Reserved - Unused Opcode
|
267 |
|
|
//localparam pOP_RSVD85 = 12'b0000_0101_0101; // Reserved - Unused Opcode
|
268 |
|
|
//localparam pOP_RSVD86 = 12'b0000_0101_0110; // Reserved - Unused Opcode
|
269 |
|
|
//localparam pOP_RSVD87 = 12'b0000_0101_0111; // Reserved - Unused Opcode
|
270 |
|
|
//localparam pOP_RSVD88 = 12'b0000_0101_1000; // Reserved - Unused Opcode
|
271 |
|
|
//localparam pOP_RSVD89 = 12'b0000_0101_1001; // Reserved - Unused Opcode
|
272 |
|
|
//localparam pOP_RSVD90 = 12'b0000_0101_1010; // Reserved - Unused Opcode
|
273 |
|
|
//localparam pOP_RSVD91 = 12'b0000_0101_1011; // Reserved - Unused Opcode
|
274 |
|
|
//localparam pOP_RSVD92 = 12'b0000_0101_1100; // Reserved - Unused Opcode
|
275 |
|
|
//localparam pOP_RSVD93 = 12'b0000_0101_1101; // Reserved - Unused Opcode
|
276 |
|
|
//localparam pOP_RSVD94 = 12'b0000_0101_1110; // Reserved - Unused Opcode
|
277 |
|
|
//localparam pOP_RSVD95 = 12'b0000_0101_1111; // Reserved - Unused Opcode
|
278 |
|
|
//
|
279 |
|
|
///////////////////////////////////////////////////////////////////////////////
|
280 |
|
|
//
|
281 |
|
|
// PIC16C5x Family Opcodes
|
282 |
|
|
//
|
283 |
|
|
//localparam pOP_NOP = 12'b0000_0000_0000; // No Operation
|
284 |
|
|
//localparam pOP_OPTION = 12'b0000_0000_0010; // Set Option Register
|
285 |
|
|
//localparam pOP_SLEEP = 12'b0000_0000_0011; // Set Sleep Register
|
286 |
|
|
//localparam pOP_CLRWDT = 12'b0000_0000_0100; // Clear Watchdog Timer
|
287 |
|
|
//localparam pOP_TRISA = 12'b0000_0000_0101; // Set Port A Tristate Ctrl Reg
|
288 |
|
|
//localparam pOP_TRISB = 12'b0000_0000_0110; // Set Port B Tristate Ctrl Reg
|
289 |
|
|
//localparam pOP_TRISC = 12'b0000_0000_0111; // Set Port C Tristate Ctrl Reg
|
290 |
|
|
//localparam pOP_MOVWF = 7'b0000_001; // F = W;
|
291 |
|
|
//localparam pOP_CLRW = 12'b0000_0100_0000; // W = 0; Z;
|
292 |
|
|
//localparam pOP_CLRF = 7'b0000_011; // F = 0; Z;
|
293 |
|
|
//localparam pOP_SUBWF = 6'b0000_10; // D ? F = F - W : W = F - W; Z, C, DC;
|
294 |
|
|
//localparam pOP_DECF = 6'b0000_11; // D ? F = F - 1 : W = F - 1; Z;
|
295 |
|
|
////
|
296 |
|
|
//localparam pOP_IORWF = 6'b0001_00; // D ? F = F | W : W = F | W; Z;
|
297 |
|
|
//localparam pOP_ANDWF = 6'b0001_01; // D ? F = F & W : W = F & W; Z;
|
298 |
|
|
//localparam pOP_XORWF = 6'b0001_10; // D ? F = F ^ W : W = F ^ W; Z;
|
299 |
|
|
//localparam pOP_ADDWF = 6'b0001_11; // D ? F = F + W : W = F + W; Z, C, DC;
|
300 |
|
|
////
|
301 |
|
|
//localparam pOP_MOVF = 6'b0010_00; // D ? F = F : W = F ; Z;
|
302 |
|
|
//localparam pOP_COMF = 6'b0010_01; // D ? F = ~F : W = ~F ; Z;
|
303 |
|
|
//localparam pOP_INCF = 6'b0010_10; // D ? F = F + 1 : W = F + 1; Z;
|
304 |
|
|
//localparam pOP_DECFSZ = 6'b0010_11; // D ? F = F - 1 : W = F - 1; skip if Z
|
305 |
|
|
////
|
306 |
|
|
//localparam pOP_RRF = 6'b0011_00; // D ? F = {C, F[7:1]}
|
307 |
|
|
//// : W = {C, F[7:1]}; C = F[0];
|
308 |
|
|
//localparam pOP_RLF = 6'b0011_01; // D ? F = {F[6:0], C}
|
309 |
|
|
//// : W = {F[6:0], C}; C = F[7];
|
310 |
|
|
//localparam pOP_SWAPF = 6'b0011_10; // D ? F = t
|
311 |
|
|
//// : W = t; t = {F[3:0], F[7:4]};
|
312 |
|
|
//localparam pOP_INCFSZ = 6'b0011_11; // D ? F = F - 1 : W = F - 1; skip if Z
|
313 |
|
|
////
|
314 |
|
|
//localparam pOP_BCF = 4'b0100; // F = F & ~(1 << bit);
|
315 |
|
|
//localparam pOP_BSF = 4'b0101; // F = F | (1 << bit);
|
316 |
|
|
//localparam pOP_BTFSC = 4'b0110; // skip if F[bit] == 0;
|
317 |
|
|
//localparam pOP_BTFSS = 4'b0111; // skip if F[bit] == 1;
|
318 |
|
|
////
|
319 |
|
|
//localparam pOP_RETLW = 4'b1000; // W = L; Pop(PC = TOS, TOS = NOS);
|
320 |
|
|
//localparam pOP_CALL = 4'b1001; // Push(TOS = PC + 1);
|
321 |
|
|
//// PC = {PA[2:0], 0, L[7:0]};
|
322 |
|
|
//localparam pOP_GOTO = 3'b101; // PC = {PA[2:0], L[8:0]};
|
323 |
|
|
//localparam pOP_MOVLW = 4'b1100; // W = L[7:0];
|
324 |
|
|
//localparam pOP_IORLW = 4'b1101; // W = L[7:0] | W; Z;
|
325 |
|
|
//localparam pOP_ANDLW = 4'b1110; // W = L[7:0] & W; Z;
|
326 |
|
|
//localparam pOP_XORLW = 4'b1111; // W = L[7:0] ^ W; Z;
|
327 |
|
|
//
|
328 |
|
|
///////////////////////////////////////////////////////////////////////////////
|
329 |
|
|
///////////////////////////////////////////////////////////////////////////////
|
330 |
|
|
//
|
331 |
|
|
// Variable Declarations
|
332 |
|
|
//
|
333 |
|
|
|
334 |
|
|
reg [ 9:0] ROM1; // Decode ROM1: 16x10
|
335 |
|
|
wire [ 3:0] ROM1_Addr; // ROM1 Address
|
336 |
|
|
reg [11:0] ROM2; // Decode ROM2: 16x12
|
337 |
|
|
wire [ 3:0] ROM2_Addr; // ROM2 Address (equals ROM1_Addr)
|
338 |
|
|
reg [11:0] ROM3; // Decode ROM3: 64x12
|
339 |
|
|
wire [ 5:0] ROM3_Addr; // ROM3 Address
|
340 |
|
|
|
341 |
|
|
wire ROM1_Valid; // ROM1 Output Valid: 1 - if ROM1 decode valid
|
342 |
|
|
|
343 |
|
|
wire dErr; // Invalid/Reserved Instruction Decode Signal
|
344 |
|
|
wire [11:0] dALU_Op; // Combined ROM2, ROM3 ALU Pipeline Vector
|
345 |
|
|
|
346 |
|
|
///////////////////////////////////////////////////////////////////////////////
|
347 |
|
|
///////////////////////////////////////////////////////////////////////////////
|
348 |
|
|
//
|
349 |
|
|
// Instruction Decoder Implementation
|
350 |
|
|
//
|
351 |
|
|
// ROM1 => dIR, decoded Instruction Register, is used to flag instructions
|
352 |
|
|
// that require special processing in the execution stage.
|
353 |
|
|
|
354 |
|
|
assign ROM1_Addr = {DI[11], (DI[11] ? DI[10:8] : DI[2:0])};
|
355 |
|
|
|
356 |
|
|
always @(*)
|
357 |
|
|
begin
|
358 |
|
|
case(ROM1_Addr)
|
359 |
|
|
4'b0000 : ROM1 <= 10'b0_0_0000_0000; // NOP
|
360 |
|
|
4'b0001 : ROM1 <= 10'b0_0_0000_0000; // Reserved
|
361 |
|
|
4'b0010 : ROM1 <= 10'b0_1_0000_0000; // OPTION
|
362 |
|
|
4'b0011 : ROM1 <= 10'b0_0_0000_1000; // SLEEP
|
363 |
|
|
4'b0100 : ROM1 <= 10'b0_0_0001_0000; // CLRWDT
|
364 |
|
|
4'b0101 : ROM1 <= 10'b0_0_0010_0000; // TRISA
|
365 |
|
|
4'b0110 : ROM1 <= 10'b0_0_0100_0000; // TRISB
|
366 |
|
|
4'b0111 : ROM1 <= 10'b0_0_1000_0000; // TRISC
|
367 |
|
|
4'b1000 : ROM1 <= 10'b1_0_0000_0100; // RETLW
|
368 |
|
|
4'b1001 : ROM1 <= 10'b1_0_0000_0010; // CALL
|
369 |
|
|
4'b1010 : ROM1 <= 10'b1_0_0000_0001; // GOTO
|
370 |
|
|
4'b1011 : ROM1 <= 10'b1_0_0000_0001; // GOTO
|
371 |
|
|
4'b1100 : ROM1 <= 10'b1_0_0000_0000; // MOVLW
|
372 |
|
|
4'b1101 : ROM1 <= 10'b1_0_0000_0000; // IORLW
|
373 |
|
|
4'b1110 : ROM1 <= 10'b1_0_0000_0000; // ANDLW
|
374 |
|
|
4'b1111 : ROM1 <= 10'b1_0_0000_0000; // XORLW
|
375 |
|
|
endcase
|
376 |
|
|
end
|
377 |
|
|
|
378 |
|
|
assign ROM1_Valid = (DI[11] ? DI[11] : ~|DI[10:3]);
|
379 |
|
|
|
380 |
|
|
// ROM2 => Input to ALU_Op for instructions decoded using ROM1_Addr
|
381 |
|
|
|
382 |
|
|
assign ROM2_Addr = {DI[11], (DI[11] ? DI[10:8] : DI[2:0])};
|
383 |
|
|
|
384 |
|
|
always @(*)
|
385 |
|
|
begin
|
386 |
|
|
case(ROM2_Addr)
|
387 |
|
|
4'b0000 : ROM2 <= 12'b0000_00_00_00_00; // NOP
|
388 |
|
|
4'b0001 : ROM2 <= 12'b0000_00_00_00_00; // Reserved
|
389 |
|
|
4'b0010 : ROM2 <= 12'b0000_00_00_00_00; // OPTION
|
390 |
|
|
4'b0011 : ROM2 <= 12'b0000_00_00_00_00; // SLEEP
|
391 |
|
|
4'b0100 : ROM2 <= 12'b0000_00_00_00_00; // CLRWDT
|
392 |
|
|
4'b0101 : ROM2 <= 12'b0000_00_00_00_00; // TRISA
|
393 |
|
|
4'b0110 : ROM2 <= 12'b0000_00_00_00_00; // TRISB
|
394 |
|
|
4'b0111 : ROM2 <= 12'b0000_00_00_00_00; // TRISC
|
395 |
|
|
4'b1000 : ROM2 <= 12'b0010_00_00_10_00; // RETLW
|
396 |
|
|
4'b1001 : ROM2 <= 12'b0000_00_00_10_00; // CALL
|
397 |
|
|
4'b1010 : ROM2 <= 12'b0000_00_00_00_00; // GOTO
|
398 |
|
|
4'b1011 : ROM2 <= 12'b0000_00_00_00_00; // GOTO
|
399 |
|
|
4'b1100 : ROM2 <= 12'b0010_00_00_10_00; // MOVLW
|
400 |
|
|
4'b1101 : ROM2 <= 12'b0010_01_10_11_01; // IORLW
|
401 |
|
|
4'b1110 : ROM2 <= 12'b0010_01_10_11_10; // ANDLW
|
402 |
|
|
4'b1111 : ROM2 <= 12'b0010_01_10_11_11; // XORLW
|
403 |
|
|
endcase
|
404 |
|
|
end
|
405 |
|
|
|
406 |
|
|
// ROM3 - decode for remaining instructions
|
407 |
|
|
|
408 |
|
|
assign ROM3_Addr = DI[10:5];
|
409 |
|
|
|
410 |
|
|
always @(*)
|
411 |
|
|
begin
|
412 |
|
|
case(ROM3_Addr)
|
413 |
|
|
6'b000000 : ROM3 <= 12'b0000_00_00_00_00; // Reserved
|
414 |
|
|
|
415 |
|
|
6'b000001 : ROM3 <= 12'b1100_10_00_01_00; // MOVWF
|
416 |
|
|
6'b000010 : ROM3 <= 12'b0010_10_00_00_00; // CLRW
|
417 |
|
|
6'b000011 : ROM3 <= 12'b1100_10_00_00_00; // CLRF
|
418 |
|
|
|
419 |
|
|
6'b000100 : ROM3 <= 12'b0110_00_11_01_11; // SUBWF F,0
|
420 |
|
|
6'b000101 : ROM3 <= 12'b1100_00_11_01_11; // SUBWF F,1
|
421 |
|
|
6'b000110 : ROM3 <= 12'b0110_00_10_00_10; // DECF F,0
|
422 |
|
|
6'b000111 : ROM3 <= 12'b1100_00_10_00_10; // DECF F,1
|
423 |
|
|
|
424 |
|
|
6'b001000 : ROM3 <= 12'b0110_01_10_01_01; // IORWF F,0
|
425 |
|
|
6'b001001 : ROM3 <= 12'b1100_01_10_01_01; // IORWF F,1
|
426 |
|
|
6'b001010 : ROM3 <= 12'b0110_01_10_01_10; // ANDWF F,0
|
427 |
|
|
6'b001011 : ROM3 <= 12'b1100_01_10_01_10; // ANDWF F,1
|
428 |
|
|
6'b001100 : ROM3 <= 12'b0110_01_10_01_11; // XORWF F,0
|
429 |
|
|
6'b001101 : ROM3 <= 12'b1100_01_10_01_11; // XORWF F,1
|
430 |
|
|
6'b001110 : ROM3 <= 12'b0110_00_11_01_00; // ADDWF F,0
|
431 |
|
|
6'b001111 : ROM3 <= 12'b1100_00_11_01_00; // ADDWF F,1
|
432 |
|
|
|
433 |
|
|
6'b010000 : ROM3 <= 12'b0110_00_10_00_00; // MOVF F,0
|
434 |
|
|
6'b010001 : ROM3 <= 12'b1100_00_10_00_00; // MOVF F,1
|
435 |
|
|
6'b010010 : ROM3 <= 12'b0110_01_00_00_00; // COMF F,0
|
436 |
|
|
6'b010011 : ROM3 <= 12'b1100_01_00_00_00; // COMF F,1
|
437 |
|
|
6'b010100 : ROM3 <= 12'b0110_00_10_00_01; // INCF F,0
|
438 |
|
|
6'b010101 : ROM3 <= 12'b1100_00_10_00_01; // INCF F,1
|
439 |
|
|
6'b010110 : ROM3 <= 12'b0111_00_00_00_10; // DECFSZ F,0
|
440 |
|
|
6'b010111 : ROM3 <= 12'b1101_00_00_00_10; // DECFSZ F,1
|
441 |
|
|
|
442 |
|
|
6'b011000 : ROM3 <= 12'b0110_10_01_00_10; // RRF F,0
|
443 |
|
|
6'b011001 : ROM3 <= 12'b1100_10_01_00_10; // RRF F,1
|
444 |
|
|
6'b011010 : ROM3 <= 12'b0110_10_01_00_11; // RLF F,0
|
445 |
|
|
6'b011011 : ROM3 <= 12'b1001_10_01_00_11; // RLF F,1
|
446 |
|
|
6'b011100 : ROM3 <= 12'b0110_10_00_00_01; // SWAPF F,0
|
447 |
|
|
6'b011101 : ROM3 <= 12'b1100_10_00_00_01; // SWAPF F,1
|
448 |
|
|
6'b011110 : ROM3 <= 12'b0111_00_00_00_01; // INCFSZ F,0
|
449 |
|
|
6'b011111 : ROM3 <= 12'b1101_00_00_00_01; // INCFSZ F,1
|
450 |
|
|
|
451 |
|
|
6'b100000 : ROM3 <= 12'b1100_11_00_0_000; // BCF F,0
|
452 |
|
|
6'b100001 : ROM3 <= 12'b1100_11_00_0_001; // BCF F,1
|
453 |
|
|
6'b100010 : ROM3 <= 12'b1100_11_00_0_010; // BCF F,2
|
454 |
|
|
6'b100011 : ROM3 <= 12'b1100_11_00_0_011; // BCF F,3
|
455 |
|
|
6'b100100 : ROM3 <= 12'b1100_11_00_0_100; // BCF F,4
|
456 |
|
|
6'b100101 : ROM3 <= 12'b1100_11_00_0_101; // BCF F,5
|
457 |
|
|
6'b100110 : ROM3 <= 12'b1100_11_00_0_110; // BCF F,6
|
458 |
|
|
6'b100111 : ROM3 <= 12'b1100_11_00_0_111; // BCF F,7
|
459 |
|
|
|
460 |
|
|
6'b101000 : ROM3 <= 12'b1100_11_00_1_000; // BSF F,0
|
461 |
|
|
6'b101001 : ROM3 <= 12'b1100_11_00_1_001; // BSF F,1
|
462 |
|
|
6'b101010 : ROM3 <= 12'b1100_11_00_1_010; // BSF F,2
|
463 |
|
|
6'b101011 : ROM3 <= 12'b1100_11_00_1_011; // BSF F,3
|
464 |
|
|
6'b101100 : ROM3 <= 12'b1100_11_00_1_100; // BSF F,4
|
465 |
|
|
6'b101101 : ROM3 <= 12'b1100_11_00_1_101; // BSF F,5
|
466 |
|
|
6'b101110 : ROM3 <= 12'b1100_11_00_1_110; // BSF F,6
|
467 |
|
|
6'b101111 : ROM3 <= 12'b1100_11_00_1_111; // BSF F,7
|
468 |
|
|
|
469 |
|
|
6'b110000 : ROM3 <= 12'b0101_11_00_0_000; // BTFSC F,0
|
470 |
|
|
6'b110001 : ROM3 <= 12'b0101_11_00_0_001; // BTFSC F,1
|
471 |
|
|
6'b110010 : ROM3 <= 12'b0101_11_00_0_010; // BTFSC F,2
|
472 |
|
|
6'b110011 : ROM3 <= 12'b0101_11_00_0_011; // BTFSC F,3
|
473 |
|
|
6'b110100 : ROM3 <= 12'b0101_11_00_0_100; // BTFSC F,4
|
474 |
|
|
6'b110101 : ROM3 <= 12'b0101_11_00_0_101; // BTFSC F,5
|
475 |
|
|
6'b110110 : ROM3 <= 12'b0101_11_00_0_110; // BTFSC F,6
|
476 |
|
|
6'b110111 : ROM3 <= 12'b0101_11_00_0_111; // BTFSC F,7
|
477 |
|
|
|
478 |
|
|
6'b111000 : ROM3 <= 12'b0101_11_00_1_000; // BTFSS F,0
|
479 |
|
|
6'b111001 : ROM3 <= 12'b0101_11_00_1_001; // BTFSS F,1
|
480 |
|
|
6'b111010 : ROM3 <= 12'b0101_11_00_1_010; // BTFSS F,2
|
481 |
|
|
6'b111011 : ROM3 <= 12'b0101_11_00_1_011; // BTFSS F,3
|
482 |
|
|
6'b111100 : ROM3 <= 12'b0101_11_00_1_100; // BTFSS F,4
|
483 |
|
|
6'b111101 : ROM3 <= 12'b0101_11_00_1_101; // BTFSS F,5
|
484 |
|
|
6'b111110 : ROM3 <= 12'b0101_11_00_1_110; // BTFSS F,6
|
485 |
|
|
6'b111111 : ROM3 <= 12'b0101_11_00_1_111; // BTFSS F,7
|
486 |
|
|
endcase
|
487 |
|
|
end
|
488 |
|
|
|
489 |
|
|
// Invalid/Reserved Instruction Decode
|
490 |
|
|
|
491 |
|
|
assign dErr = (~|DI[11:1] & DI[0]) // (IR == 1)
|
492 |
|
|
| (~|DI[11:4] & DI[3]) // ( 8 <= IR <= 16)
|
493 |
|
|
| (~|DI[11:5] & DI[4]) // (16 <= IR <= 31)
|
494 |
|
|
| (~|DI[11:7] & DI[6] & ~|DI[5:4] & |DI[3:0]) // (65 <= IR <= 79)
|
495 |
|
|
| (~|DI[11:7] & DI[6] & ~DI[5] & DI[4]); // (80 <= IR <= 95)
|
496 |
|
|
|
497 |
|
|
///////////////////////////////////////////////////////////////////////////////
|
498 |
|
|
///////////////////////////////////////////////////////////////////////////////
|
499 |
|
|
//
|
500 |
|
|
// Instruction Pipeline Registers
|
501 |
|
|
//
|
502 |
|
|
// Decoded Instruction Register
|
503 |
|
|
|
504 |
|
|
always @(posedge Clk)
|
505 |
|
|
begin
|
506 |
|
|
if(Rst)
|
507 |
|
|
dIR <= #1 0;
|
508 |
|
|
else if(CE)
|
509 |
|
|
dIR <= #1 ((Skip) ? 0
|
510 |
|
|
: ((ROM1_Valid) ? ROM1 : 0));
|
511 |
|
|
end
|
512 |
|
|
|
513 |
|
|
// ALU Operation Pipeline Register
|
514 |
|
|
|
515 |
|
|
assign dALU_Op = (ROM1_Valid ? ROM2
|
516 |
|
|
: {ROM3[11],(ROM3[10] & ~|DI[4:0]), ROM3[9:0]});
|
517 |
|
|
|
518 |
|
|
always @(posedge Clk)
|
519 |
|
|
begin
|
520 |
|
|
if(Rst)
|
521 |
|
|
ALU_Op <= #1 0;
|
522 |
|
|
else if(CE)
|
523 |
|
|
ALU_Op <= #1 ((Skip | dErr) ? 0 : dALU_Op);
|
524 |
|
|
end
|
525 |
|
|
|
526 |
|
|
// Literal Operand Pipeline Register
|
527 |
|
|
|
528 |
|
|
always @(posedge Clk)
|
529 |
|
|
begin
|
530 |
|
|
if(Rst)
|
531 |
|
|
KI <= #1 0;
|
532 |
|
|
else if(CE)
|
533 |
|
|
KI <= #1 ((Skip) ? KI : DI[8:0]);
|
534 |
|
|
end
|
535 |
|
|
|
536 |
|
|
// Unimplemented Instruction Error Register
|
537 |
|
|
|
538 |
|
|
always @(posedge Clk)
|
539 |
|
|
begin
|
540 |
|
|
if(Rst)
|
541 |
|
|
Err <= #1 0;
|
542 |
|
|
else if(CE)
|
543 |
|
|
Err <= #1 dErr;
|
544 |
|
|
end
|
545 |
|
|
|
546 |
|
|
endmodule
|