OpenCores
URL https://opencores.org/ocsvn/p16c5x/p16c5x/trunk

Subversion Repositories p16c5x

[/] [p16c5x/] [trunk/] [RTL/] [P16C5x_IDec.v] - Blame information for rev 2

Details | Compare with Previous | View Log

Line No. Rev Author Line
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

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.