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

Subversion Repositories m16c5x

[/] [m16c5x/] [trunk/] [RTL/] [Src/] [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
//  1.30    13J20   MAM     Added direct decode of instruction into a bit maks.
127
//                          Bit mask is registered along with other instruction
128
//                          decode components.
129
//
130
// Additional Comments:
131
//
132
//  This instruction decoder is based on the combinatorial instruction decoder
133
//  developed for the original implementation of this processor. That decoder
134
//  is included as comments in this module as a reference for the correct
135
//  implementation of this module using ROMs and multiplexers.
136
//
137
//  ALU_Op[11:0] Mapping
138
//
139
//  ALU_Op[1:0] = ALU Unit Operation Code
140
//
141
//      Arithmetic Unit (AU): 00 => Y = A +  B; 
142
//                            01 => Y = A +  B + 1;
143
//                            10 => Y = A + ~B     = A - B - 1;
144
//                            11 => Y = A + ~B + 1 = A - B;
145
//
146
//      Logic Unit (LU):      00 => V = ~A; 
147
//                            01 => V =  A | B;
148
//                            10 => V =  A & B;
149
//                            11 => V =  A ^ B;
150
//
151
//      Shift Unit (SU):      00 => S = W;                // MOVWF
152
//                            01 => S = {A[3:0], A[7:4]}; // SWAPF
153
//                            10 => S = {C, A[7:1]};      // RRF
154
//                            11 => S = {A[6:0], C};      // RLF
155
//
156
//  ALU_Op[3:2] = ALU Operand: 
157
//                  A      B
158
//          00 =>  File    0 
159
//          01 =>  File    W
160
//          10 => Literal  0
161
//          11 => Literal  W;
162
//
163
//  ALU Operations - Bit Processor (BP)
164
//
165
//  ALU_Op[2:0] = Bit Select: 000 => Bit 0; 
166
//                            001 => Bit 1;
167
//                            010 => Bit 2;
168
//                            011 => Bit 3;
169
//                            100 => Bit 4; 
170
//                            101 => Bit 5;
171
//                            110 => Bit 6;
172
//                            111 => Bit 7;
173
//
174
//  ALU_Op[3] = Set: 0 - Clr Selected Bit;
175
//                   1 - Set Selected Bit;
176
//
177
//  ALU_Op[5:4] = Status Flag Update Select
178
//          
179
//          00 => None
180
//          01 => C
181
//          10 => Z
182
//          11 => Z,DC,C
183
//
184
//  ALU_Op[7:6] = ALU Output Data Multiplexer
185
//
186
//          00 => AU
187
//          01 => LU
188
//          10 => SU
189
//          11 => BP
190
//
191
//  ALU_Op[8]  = Tst: 0 - Normal Operation
192
//                    1 - Test: INCFSZ/DECFSZ/BTFSC/BTFSS
193
//
194
//  ALU_Op[9]  = Write Enable Working Register (W)
195
//
196
//  ALU_Op[10] = Indirect Register, INDF, Selected
197
//
198
//  ALU_Op[11] = Write Enable File {RAM | Special Function Registers}
199
//
200
///////////////////////////////////////////////////////////////////////////////
201
 
202
module P16C5x_IDec(
203
    input   Rst,
204
    input   Clk,
205
    input   CE,
206
 
207
    input   [11:0] DI,
208
    input   Skip,
209
 
210
    output  reg [ 9:0] dIR,
211
    output  reg [11:0] ALU_Op,
212
    output  reg [ 8:0] KI,
213
    output  reg [ 7:0] Msk,
214
 
215
    output  reg Err
216
);
217
 
218
//
219
///////////////////////////////////////////////////////////////////////////////
220
//
221
//  Unused Opcodes - PIC16C5x Family
222
//
223
//localparam pOP_RSVD01 = 12'b0000_0000_0001;   // Reserved - Unused Opcode
224
//
225
//localparam pOP_RSVD08 = 12'b0000_0000_1000;   // Reserved - Unused Opcode
226
//localparam pOP_RSVD09 = 12'b0000_0000_1001;   // Reserved - Unused Opcode
227
//localparam pOP_RSVD10 = 12'b0000_0000_1010;   // Reserved - Unused Opcode
228
//localparam pOP_RSVD11 = 12'b0000_0000_1011;   // Reserved - Unused Opcode
229
//localparam pOP_RSVD12 = 12'b0000_0000_1100;   // Reserved - Unused Opcode
230
//localparam pOP_RSVD13 = 12'b0000_0000_1101;   // Reserved - Unused Opcode
231
//localparam pOP_RSVD14 = 12'b0000_0000_1110;   // Reserved - Unused Opcode
232
//localparam pOP_RSVD15 = 12'b0000_0000_1111;   // Reserved - Unused Opcode
233
//
234
//localparam pOP_RSVD16 = 12'b0000_0001_0000;   // Reserved - Unused Opcode
235
//localparam pOP_RSVD17 = 12'b0000_0001_0001;   // Reserved - Unused Opcode
236
//localparam pOP_RSVD18 = 12'b0000_0001_0010;   // Reserved - Unused Opcode
237
//localparam pOP_RSVD19 = 12'b0000_0001_0011;   // Reserved - Unused Opcode
238
//localparam pOP_RSVD20 = 12'b0000_0001_0100;   // Reserved - Unused Opcode
239
//localparam pOP_RSVD21 = 12'b0000_0001_0101;   // Reserved - Unused Opcode
240
//localparam pOP_RSVD22 = 12'b0000_0001_0110;   // Reserved - Unused Opcode
241
//localparam pOP_RSVD23 = 12'b0000_0001_0111;   // Reserved - Unused Opcode
242
//localparam pOP_RSVD24 = 12'b0000_0001_1000;   // Reserved - Unused Opcode
243
//localparam pOP_RSVD25 = 12'b0000_0001_1001;   // Reserved - Unused Opcode
244
//localparam pOP_RSVD26 = 12'b0000_0001_1010;   // Reserved - Unused Opcode
245
//localparam pOP_RSVD27 = 12'b0000_0001_1011;   // Reserved - Unused Opcode
246
//localparam pOP_RSVD28 = 12'b0000_0001_1100;   // Reserved - Unused Opcode
247
//localparam pOP_RSVD29 = 12'b0000_0001_1101;   // Reserved - Unused Opcode
248
//localparam pOP_RSVD30 = 12'b0000_0001_1110;   // Reserved - Unused Opcode
249
//localparam pOP_RSVD31 = 12'b0000_0001_1111;   // Reserved - Unused Opcode
250
//
251
//localparam pOP_RSVD65 = 12'b0000_0100_0001;   // Reserved - Unused Opcode
252
//localparam pOP_RSVD66 = 12'b0000_0100_0010;   // Reserved - Unused Opcode
253
//localparam pOP_RSVD67 = 12'b0000_0100_0011;   // Reserved - Unused Opcode
254
//localparam pOP_RSVD68 = 12'b0000_0100_0100;   // Reserved - Unused Opcode
255
//localparam pOP_RSVD69 = 12'b0000_0100_0101;   // Reserved - Unused Opcode
256
//localparam pOP_RSVD70 = 12'b0000_0100_0110;   // Reserved - Unused Opcode
257
//localparam pOP_RSVD71 = 12'b0000_0100_0111;   // Reserved - Unused Opcode
258
//localparam pOP_RSVD72 = 12'b0000_0100_1000;   // Reserved - Unused Opcode
259
//localparam pOP_RSVD73 = 12'b0000_0100_1001;   // Reserved - Unused Opcode
260
//localparam pOP_RSVD74 = 12'b0000_0100_1010;   // Reserved - Unused Opcode
261
//localparam pOP_RSVD75 = 12'b0000_0100_1011;   // Reserved - Unused Opcode
262
//localparam pOP_RSVD76 = 12'b0000_0100_1100;   // Reserved - Unused Opcode
263
//localparam pOP_RSVD77 = 12'b0000_0100_1101;   // Reserved - Unused Opcode
264
//localparam pOP_RSVD78 = 12'b0000_0100_1110;   // Reserved - Unused Opcode
265
//localparam pOP_RSVD79 = 12'b0000_0100_1111;   // Reserved - Unused Opcode
266
//
267
//localparam pOP_RSVD80 = 12'b0000_0101_0000;   // Reserved - Unused Opcode
268
//localparam pOP_RSVD81 = 12'b0000_0101_0001;   // Reserved - Unused Opcode
269
//localparam pOP_RSVD82 = 12'b0000_0101_0010;   // Reserved - Unused Opcode
270
//localparam pOP_RSVD83 = 12'b0000_0101_0011;   // Reserved - Unused Opcode
271
//localparam pOP_RSVD84 = 12'b0000_0101_0100;   // Reserved - Unused Opcode
272
//localparam pOP_RSVD85 = 12'b0000_0101_0101;   // Reserved - Unused Opcode
273
//localparam pOP_RSVD86 = 12'b0000_0101_0110;   // Reserved - Unused Opcode
274
//localparam pOP_RSVD87 = 12'b0000_0101_0111;   // Reserved - Unused Opcode
275
//localparam pOP_RSVD88 = 12'b0000_0101_1000;   // Reserved - Unused Opcode
276
//localparam pOP_RSVD89 = 12'b0000_0101_1001;   // Reserved - Unused Opcode
277
//localparam pOP_RSVD90 = 12'b0000_0101_1010;   // Reserved - Unused Opcode
278
//localparam pOP_RSVD91 = 12'b0000_0101_1011;   // Reserved - Unused Opcode
279
//localparam pOP_RSVD92 = 12'b0000_0101_1100;   // Reserved - Unused Opcode
280
//localparam pOP_RSVD93 = 12'b0000_0101_1101;   // Reserved - Unused Opcode
281
//localparam pOP_RSVD94 = 12'b0000_0101_1110;   // Reserved - Unused Opcode
282
//localparam pOP_RSVD95 = 12'b0000_0101_1111;   // Reserved - Unused Opcode
283
//
284
///////////////////////////////////////////////////////////////////////////////
285
//
286
//  PIC16C5x Family Opcodes
287
//
288
//localparam pOP_NOP    = 12'b0000_0000_0000;   // No Operation 
289
//localparam pOP_OPTION = 12'b0000_0000_0010;   // Set Option Register
290
//localparam pOP_SLEEP  = 12'b0000_0000_0011;   // Set Sleep Register
291
//localparam pOP_CLRWDT = 12'b0000_0000_0100;   // Clear Watchdog Timer
292
//localparam pOP_TRISA  = 12'b0000_0000_0101;   // Set Port A Tristate Ctrl Reg
293
//localparam pOP_TRISB  = 12'b0000_0000_0110;   // Set Port B Tristate Ctrl Reg
294
//localparam pOP_TRISC  = 12'b0000_0000_0111;   // Set Port C Tristate Ctrl Reg
295
//localparam pOP_MOVWF  =  7'b0000_001;         // F = W;
296
//localparam pOP_CLRW   = 12'b0000_0100_0000;   // W = 0; Z;
297
//localparam pOP_CLRF   =  7'b0000_011; // F = 0; Z;
298
//localparam pOP_SUBWF  =  6'b0000_10;  // D ? F = F - W : W = F - W; Z, C, DC;
299
//localparam pOP_DECF   =  6'b0000_11;  // D ? F = F - 1 : W = F - 1; Z;
300
////
301
//localparam pOP_IORWF  =  6'b0001_00;  // D ? F = F | W : W = F | W; Z; 
302
//localparam pOP_ANDWF  =  6'b0001_01;  // D ? F = F & W : W = F & W; Z;
303
//localparam pOP_XORWF  =  6'b0001_10;  // D ? F = F ^ W : W = F ^ W; Z;
304
//localparam pOP_ADDWF  =  6'b0001_11;  // D ? F = F + W : W = F + W; Z, C, DC;
305
////
306
//localparam pOP_MOVF   =  6'b0010_00;  // D ? F = F     : W = F    ; Z;
307
//localparam pOP_COMF   =  6'b0010_01;  // D ? F = ~F    : W = ~F   ; Z;
308
//localparam pOP_INCF   =  6'b0010_10;  // D ? F = F + 1 : W = F + 1; Z;
309
//localparam pOP_DECFSZ =  6'b0010_11;  // D ? F = F - 1 : W = F - 1; skip if Z
310
////
311
//localparam pOP_RRF    =  6'b0011_00;  // D ? F = {C, F[7:1]}
312
////                                         : W = {C, F[7:1]}; C = F[0]; 
313
//localparam pOP_RLF    =  6'b0011_01;  // D ? F = {F[6:0], C}
314
////                                         : W = {F[6:0], C}; C = F[7];
315
//localparam pOP_SWAPF  =  6'b0011_10;  // D ? F = t
316
////                                         : W = t; t = {F[3:0], F[7:4]}; 
317
//localparam pOP_INCFSZ =  6'b0011_11;  // D ? F = F - 1 : W = F - 1; skip if Z
318
////
319
//localparam pOP_BCF    =  4'b0100;     // F = F & ~(1 << bit);
320
//localparam pOP_BSF    =  4'b0101;     // F = F |  (1 << bit);
321
//localparam pOP_BTFSC  =  4'b0110;     // skip if F[bit] == 0;
322
//localparam pOP_BTFSS  =  4'b0111;     // skip if F[bit] == 1;
323
////
324
//localparam pOP_RETLW  =  4'b1000;     // W = L; Pop(PC = TOS, TOS = NOS);
325
//localparam pOP_CALL   =  4'b1001;     // Push(TOS = PC + 1);
326
////                                       PC = {PA[2:0], 0, L[7:0]};
327
//localparam pOP_GOTO   =  3'b101;      // PC = {PA[2:0], L[8:0]};
328
//localparam pOP_MOVLW  =  4'b1100;     // W = L[7:0];
329
//localparam pOP_IORLW  =  4'b1101;     // W = L[7:0] | W; Z;
330
//localparam pOP_ANDLW  =  4'b1110;     // W = L[7:0] & W; Z;
331
//localparam pOP_XORLW  =  4'b1111;     // W = L[7:0] ^ W; Z;
332
//
333
///////////////////////////////////////////////////////////////////////////////
334
///////////////////////////////////////////////////////////////////////////////
335
//
336
//  Variable Declarations
337
//
338
 
339
reg     [ 9:0] ROM1;            // Decode ROM1: 16x10
340
wire    [ 3:0] ROM1_Addr;       // ROM1 Address
341
reg     [11:0] ROM2;            // Decode ROM2: 16x12
342
wire    [ 3:0] ROM2_Addr;       // ROM2 Address (equals ROM1_Addr)
343
reg     [11:0] ROM3;            // Decode ROM3: 64x12
344
wire    [ 5:0] ROM3_Addr;       // ROM3 Address
345
 
346
wire    ROM1_Valid;             // ROM1 Output Valid: 1 - if ROM1 decode valid
347
 
348
wire    dErr;                   // Invalid/Reserved Instruction Decode Signal
349
wire    [11:0] dALU_Op;         // Combined ROM2, ROM3 ALU Pipeline Vector
350
 
351
///////////////////////////////////////////////////////////////////////////////
352
///////////////////////////////////////////////////////////////////////////////
353
//
354
//  Instruction Decoder Implementation
355
//
356
//  ROM1 => dIR, decoded Instruction Register, is used to flag instructions
357
//          that require special processing in the execution stage.
358
 
359
assign ROM1_Addr = {DI[11], (DI[11] ? DI[10:8] : DI[2:0])};
360
 
361
always @(*)
362
begin
363
    case(ROM1_Addr)
364
        4'b0000 : ROM1 <= 10'b0_0_0000_0000;   // NOP
365
        4'b0001 : ROM1 <= 10'b0_0_0000_0000;   // Reserved
366
        4'b0010 : ROM1 <= 10'b0_1_0000_0000;   // OPTION
367
        4'b0011 : ROM1 <= 10'b0_0_0000_1000;   // SLEEP
368
        4'b0100 : ROM1 <= 10'b0_0_0001_0000;   // CLRWDT
369
        4'b0101 : ROM1 <= 10'b0_0_0010_0000;   // TRISA
370
        4'b0110 : ROM1 <= 10'b0_0_0100_0000;   // TRISB
371
        4'b0111 : ROM1 <= 10'b0_0_1000_0000;   // TRISC
372
        4'b1000 : ROM1 <= 10'b1_0_0000_0100;   // RETLW
373
        4'b1001 : ROM1 <= 10'b1_0_0000_0010;   // CALL
374
        4'b1010 : ROM1 <= 10'b1_0_0000_0001;   // GOTO
375
        4'b1011 : ROM1 <= 10'b1_0_0000_0001;   // GOTO
376
        4'b1100 : ROM1 <= 10'b1_0_0000_0000;   // MOVLW
377
        4'b1101 : ROM1 <= 10'b1_0_0000_0000;   // IORLW
378
        4'b1110 : ROM1 <= 10'b1_0_0000_0000;   // ANDLW
379
        4'b1111 : ROM1 <= 10'b1_0_0000_0000;   // XORLW
380
    endcase
381
end
382
 
383
assign ROM1_Valid = (DI[11] ? DI[11] : ~|DI[10:3]);
384
 
385
//  ROM2 => Input to ALU_Op for instructions decoded using ROM1_Addr
386
 
387
assign ROM2_Addr = {DI[11], (DI[11] ? DI[10:8] : DI[2:0])};
388
 
389
always @(*)
390
begin
391
    case(ROM2_Addr)
392
        4'b0000 : ROM2 <= 12'b0000_00_00_00_00;   // NOP
393
        4'b0001 : ROM2 <= 12'b0000_00_00_00_00;   // Reserved
394
        4'b0010 : ROM2 <= 12'b0000_00_00_00_00;   // OPTION
395
        4'b0011 : ROM2 <= 12'b0000_00_00_00_00;   // SLEEP
396
        4'b0100 : ROM2 <= 12'b0000_00_00_00_00;   // CLRWDT
397
        4'b0101 : ROM2 <= 12'b0000_00_00_00_00;   // TRISA
398
        4'b0110 : ROM2 <= 12'b0000_00_00_00_00;   // TRISB
399
        4'b0111 : ROM2 <= 12'b0000_00_00_00_00;   // TRISC
400
        4'b1000 : ROM2 <= 12'b0010_00_00_10_00;   // RETLW
401
        4'b1001 : ROM2 <= 12'b0000_00_00_10_00;   // CALL
402
        4'b1010 : ROM2 <= 12'b0000_00_00_00_00;   // GOTO
403
        4'b1011 : ROM2 <= 12'b0000_00_00_00_00;   // GOTO
404
        4'b1100 : ROM2 <= 12'b0010_00_00_10_00;   // MOVLW
405
        4'b1101 : ROM2 <= 12'b0010_01_10_11_01;   // IORLW
406
        4'b1110 : ROM2 <= 12'b0010_01_10_11_10;   // ANDLW
407
        4'b1111 : ROM2 <= 12'b0010_01_10_11_11;   // XORLW
408
    endcase
409
end
410
 
411
//  ROM3 - decode for remaining instructions
412
 
413
assign ROM3_Addr = DI[10:5];
414
 
415
always @(*)
416
begin
417
    case(ROM3_Addr)
418
        6'b000000 : ROM3 <= 12'b0000_00_00_00_00;   // Reserved
419
 
420
        6'b000001 : ROM3 <= 12'b1100_10_00_01_00;   // MOVWF
421
        6'b000010 : ROM3 <= 12'b0010_10_00_00_00;   // CLRW
422
        6'b000011 : ROM3 <= 12'b1100_10_00_00_00;   // CLRF
423
 
424
        6'b000100 : ROM3 <= 12'b0110_00_11_01_11;   // SUBWF  F,0
425
        6'b000101 : ROM3 <= 12'b1100_00_11_01_11;   // SUBWF  F,1
426
        6'b000110 : ROM3 <= 12'b0110_00_10_00_10;   // DECF   F,0
427
        6'b000111 : ROM3 <= 12'b1100_00_10_00_10;   // DECF   F,1
428
 
429
        6'b001000 : ROM3 <= 12'b0110_01_10_01_01;   // IORWF  F,0
430
        6'b001001 : ROM3 <= 12'b1100_01_10_01_01;   // IORWF  F,1
431
        6'b001010 : ROM3 <= 12'b0110_01_10_01_10;   // ANDWF  F,0
432
        6'b001011 : ROM3 <= 12'b1100_01_10_01_10;   // ANDWF  F,1
433
        6'b001100 : ROM3 <= 12'b0110_01_10_01_11;   // XORWF  F,0
434
        6'b001101 : ROM3 <= 12'b1100_01_10_01_11;   // XORWF  F,1
435
        6'b001110 : ROM3 <= 12'b0110_00_11_01_00;   // ADDWF  F,0
436
        6'b001111 : ROM3 <= 12'b1100_00_11_01_00;   // ADDWF  F,1
437
 
438
        6'b010000 : ROM3 <= 12'b0110_00_10_00_00;   // MOVF   F,0
439
        6'b010001 : ROM3 <= 12'b1100_00_10_00_00;   // MOVF   F,1
440
        6'b010010 : ROM3 <= 12'b0110_01_00_00_00;   // COMF   F,0
441
        6'b010011 : ROM3 <= 12'b1100_01_00_00_00;   // COMF   F,1
442
        6'b010100 : ROM3 <= 12'b0110_00_10_00_01;   // INCF   F,0
443
        6'b010101 : ROM3 <= 12'b1100_00_10_00_01;   // INCF   F,1
444
        6'b010110 : ROM3 <= 12'b0111_00_00_00_10;   // DECFSZ F,0
445
        6'b010111 : ROM3 <= 12'b1101_00_00_00_10;   // DECFSZ F,1
446
 
447
        6'b011000 : ROM3 <= 12'b0110_10_01_00_10;   // RRF    F,0
448
        6'b011001 : ROM3 <= 12'b1100_10_01_00_10;   // RRF    F,1
449
        6'b011010 : ROM3 <= 12'b0110_10_01_00_11;   // RLF    F,0
450
        6'b011011 : ROM3 <= 12'b1001_10_01_00_11;   // RLF    F,1
451
        6'b011100 : ROM3 <= 12'b0110_10_00_00_01;   // SWAPF  F,0
452
        6'b011101 : ROM3 <= 12'b1100_10_00_00_01;   // SWAPF  F,1
453
        6'b011110 : ROM3 <= 12'b0111_00_00_00_01;   // INCFSZ F,0
454
        6'b011111 : ROM3 <= 12'b1101_00_00_00_01;   // INCFSZ F,1
455
 
456
        6'b100000 : ROM3 <= 12'b1100_11_00_0_000;   // BCF    F,0
457
        6'b100001 : ROM3 <= 12'b1100_11_00_0_001;   // BCF    F,1
458
        6'b100010 : ROM3 <= 12'b1100_11_00_0_010;   // BCF    F,2
459
        6'b100011 : ROM3 <= 12'b1100_11_00_0_011;   // BCF    F,3
460
        6'b100100 : ROM3 <= 12'b1100_11_00_0_100;   // BCF    F,4
461
        6'b100101 : ROM3 <= 12'b1100_11_00_0_101;   // BCF    F,5
462
        6'b100110 : ROM3 <= 12'b1100_11_00_0_110;   // BCF    F,6
463
        6'b100111 : ROM3 <= 12'b1100_11_00_0_111;   // BCF    F,7
464
 
465
        6'b101000 : ROM3 <= 12'b1100_11_00_1_000;   // BSF    F,0
466
        6'b101001 : ROM3 <= 12'b1100_11_00_1_001;   // BSF    F,1
467
        6'b101010 : ROM3 <= 12'b1100_11_00_1_010;   // BSF    F,2
468
        6'b101011 : ROM3 <= 12'b1100_11_00_1_011;   // BSF    F,3
469
        6'b101100 : ROM3 <= 12'b1100_11_00_1_100;   // BSF    F,4
470
        6'b101101 : ROM3 <= 12'b1100_11_00_1_101;   // BSF    F,5
471
        6'b101110 : ROM3 <= 12'b1100_11_00_1_110;   // BSF    F,6
472
        6'b101111 : ROM3 <= 12'b1100_11_00_1_111;   // BSF    F,7
473
 
474
        6'b110000 : ROM3 <= 12'b0101_11_00_0_000;   // BTFSC  F,0
475
        6'b110001 : ROM3 <= 12'b0101_11_00_0_001;   // BTFSC  F,1
476
        6'b110010 : ROM3 <= 12'b0101_11_00_0_010;   // BTFSC  F,2
477
        6'b110011 : ROM3 <= 12'b0101_11_00_0_011;   // BTFSC  F,3
478
        6'b110100 : ROM3 <= 12'b0101_11_00_0_100;   // BTFSC  F,4
479
        6'b110101 : ROM3 <= 12'b0101_11_00_0_101;   // BTFSC  F,5
480
        6'b110110 : ROM3 <= 12'b0101_11_00_0_110;   // BTFSC  F,6
481
        6'b110111 : ROM3 <= 12'b0101_11_00_0_111;   // BTFSC  F,7
482
 
483
        6'b111000 : ROM3 <= 12'b0101_11_00_1_000;   // BTFSS  F,0
484
        6'b111001 : ROM3 <= 12'b0101_11_00_1_001;   // BTFSS  F,1
485
        6'b111010 : ROM3 <= 12'b0101_11_00_1_010;   // BTFSS  F,2
486
        6'b111011 : ROM3 <= 12'b0101_11_00_1_011;   // BTFSS  F,3
487
        6'b111100 : ROM3 <= 12'b0101_11_00_1_100;   // BTFSS  F,4
488
        6'b111101 : ROM3 <= 12'b0101_11_00_1_101;   // BTFSS  F,5
489
        6'b111110 : ROM3 <= 12'b0101_11_00_1_110;   // BTFSS  F,6
490
        6'b111111 : ROM3 <= 12'b0101_11_00_1_111;   // BTFSS  F,7
491
    endcase
492
end
493
 
494
//  Invalid/Reserved Instruction Decode
495
 
496
assign dErr =   (~|DI[11:1] & DI[0])                        // (IR == 1)
497
              | (~|DI[11:4] & DI[3])                        // ( 8 <= IR <= 16)
498
              | (~|DI[11:5] & DI[4])                        // (16 <= IR <= 31)
499
              | (~|DI[11:7] & DI[6] & ~|DI[5:4] & |DI[3:0]) // (65 <= IR <= 79)
500
              | (~|DI[11:7] & DI[6] & ~DI[5] & DI[4]);      // (80 <= IR <= 95)
501
 
502
///////////////////////////////////////////////////////////////////////////////
503
///////////////////////////////////////////////////////////////////////////////
504
//
505
//  Instruction Pipeline Registers
506
//
507
//  Decoded Instruction Register
508
 
509
always @(posedge Clk)
510
begin
511
    if(Rst)
512
        dIR <= #1 0;
513
    else if(CE)
514
        dIR <= #1 ((Skip) ? 0
515
                          : ((ROM1_Valid) ? ROM1 : 0));
516
end
517
 
518
//  ALU Operation Pipeline Register
519
 
520
assign dALU_Op = (ROM1_Valid ? ROM2
521
                             : {ROM3[11],(ROM3[10] & ~|DI[4:0]), ROM3[9:0]});
522
 
523
always @(posedge Clk)
524
begin
525
    if(Rst)
526
        ALU_Op <= #1 0;
527
    else if(CE)
528
        ALU_Op <= #1 ((Skip | dErr) ? 0 : dALU_Op);
529
end
530
 
531
//  Literal Operand Pipeline Register
532
 
533
always @(posedge Clk)
534
begin
535
    if(Rst)
536
        KI <= #1 0;
537
    else if(CE)
538
        KI <= #1 ((Skip) ? KI : DI[8:0]);
539
end
540
 
541
//  Bit Mask
542
 
543
always @(posedge Clk)
544
begin
545
    if(Rst)
546
        Msk <= #1 8'hFF;
547
    else
548
        case(DI[7:5])
549
            3'b000 : Msk <= #1 8'b00000001;
550
            3'b001 : Msk <= #1 8'b00000010;
551
            3'b010 : Msk <= #1 8'b00000100;
552
            3'b011 : Msk <= #1 8'b00001000;
553
            3'b100 : Msk <= #1 8'b00010000;
554
            3'b101 : Msk <= #1 8'b00100000;
555
            3'b110 : Msk <= #1 8'b01000000;
556
            3'b111 : Msk <= #1 8'b10000000;
557
        endcase
558
end
559
 
560
//  Unimplemented Instruction Error Register
561
 
562
always @(posedge Clk)
563
begin
564
    if(Rst)
565
        Err <= #1 0;
566
    else if(CE)
567
        Err <= #1 dErr;
568
end
569
 
570
endmodule

powered by: WebSVN 2.1.0

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