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

Subversion Repositories m65c02

[/] [m65c02/] [trunk/] [Src/] [RTL/] [M65C02_AddrGen.v] - Blame information for rev 2

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 2 MichaelA
////////////////////////////////////////////////////////////////////////////////
2
//
3
//  Copyright 2012-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:     09:15:23 11/03/2012 
45
// Design Name:     WDC W65C02 Microprocessor Re-Implementation
46
// Module Name:     M65C02_AddrGen.v
47
// Project Name:    C:\XProjects\ISE10.1i\MAM65C02 
48
// Target Devices:  Generic SRAM-based FPGA 
49
// Tool versions:   Xilinx ISE10.1i SP3
50
//
51
// Description:
52
//
53
//  This file provides the M65C02_Core module's address generator function. This
54
//  module is taken from the address generator originally included in the
55
//  M65C02_Core module. The only difference is the addition of an explicit sig-
56
//  nal which generates relative offset for conditional branches, Rel.
57
//
58
// Dependencies:    none 
59
//
60
// Revision: 
61
//
62
//  0.00    12K03   MAM     Initial File Creation
63
//
64
//  1.00    12K03   MAM     Added Mod256 input to control Zero Page addressing.
65
//                          Reconfigured the stack pointer logic to reduce the
66
//                          number of adders used in its implementation. Opti-
67
//                          mized the PC logic using the approach used for the
68
//                          next address logic, NA.
69
//
70
//  1.10    12K12   MAM     Changed name of input signal Mod256 to ZP. When ZP
71
//                          is asserted, AO is computed modulo 256.
72
//
73
//  2.00    13H04   MAM     Modified operand multiplexers into one-hot decoded
74
//                          OR busses. Changed adder structures slightly so a
75
//                          16-bit, two operand adder with carry input was syn-
76
//                          thesized. Changed zero page % 256 logic to use an
77
//                          AND gate with either 0x00FF or 0xFFFF as the mask.
78
//
79
// Additional Comments: 
80
//
81
////////////////////////////////////////////////////////////////////////////////
82
 
83
module M65C02_AddrGen(
84
    input   Rst,                    // System Reset
85
    input   Clk,                    // System Clock
86
 
87
    input   [15:0] Vector,          // Interrupt/Trap Vector
88
 
89
    input   [3:0] NA_Op,            // Next Address Operation
90
    input   [1:0] PC_Op,            // Program Counter Operation
91
    input   [1:0] Stk_Op,           // Stack Pointer Operation
92
 
93
    input   ZP,                     // Modulo 256 Control Input
94
 
95
    input   CC,                     // Conditional Branch Input Flag
96
    input   BRV3,                   // Interrupt or Next Instruction Select
97
    input   Int,                    // Unmasked Interrupt Request Input
98
 
99
    input   Rdy,                    // Ready Input
100
 
101
    input   [7:0] DI,               // Memory Data Input
102
    input   [7:0] OP1,              // Operand Register 1 Input
103
    input   [7:0] OP2,              // Operand Register 2 Input
104
    input   [7:0] StkPtr,           // Stack Pointer Input
105
 
106
    input   [7:0] X,                // X Index Register Input
107
    input   [7:0] Y,                // Y Index Register Input
108
 
109
    output  reg [15:0] AO,          // Address Output
110
 
111
    output  reg [15:0] AL,          // Address Generator Left Operand
112
    output  reg [15:0] AR,          // Address Generator Right Operand
113
    output  reg [15:0] NA,          // Address Generator Output - Next Address
114
    output  reg [15:0] MAR,         // Memory Address Register
115
    output  reg [15:0] PC,          // Program Counter
116
    output  reg [15:0] dPC          // Delayed Program Counter - Interrupt Adr
117
);
118
 
119
////////////////////////////////////////////////////////////////////////////////
120
//
121
//  Local Parameters
122
//
123
 
124
localparam  pNA_Inc  = 4'h1;    // NA <= PC + 1
125
localparam  pNA_MAR  = 4'h2;    // NA <= MAR + 0
126
localparam  pNA_Nxt  = 4'h3;    // NA <= MAR + 1
127
localparam  pNA_Stk  = 4'h4;    // NA <= SP + 0
128
localparam  pNA_DPN  = 4'h5;    // NA <= {0, OP1} + 0
129
localparam  pNA_DPX  = 4'h6;    // NA <= {0, OP1} + {0, X}
130
localparam  pNA_DPY  = 4'h7;    // NA <= {0, OP1} + {0, Y}
131
localparam  pNA_LDA  = 4'h8;    // NA <= {OP2, OP1} + 0
132
//
133
//
134
//
135
//
136
//
137
localparam  pNA_LDAX = 4'hE;    // NA <= {OP2, OP1} + {0, X}
138
localparam  pNA_LDAY = 4'hF;    // NA <= {OP2, OP1} + {0, Y}
139
 
140
////////////////////////////////////////////////////////////////////////////////
141
//
142
//  Module Declarations
143
//
144
 
145
reg     [ 6:0] Op_Sel;          // ROM Decoder for Next Address Operation
146
wire    CE_MAR;                 // Memory Address Register Clock Enable
147
 
148
reg     [ 4:0] PC_Sel;          // ROM Decoder for Program Counter Updates
149
wire    [15:0] Rel;             // Branch Address Sign-Extended Offset
150
reg     [15:0] PCL, PCR;        // Program Counter Left and Right Operands
151
wire    CE_PC;                  // Program Counter Clock Enable
152
 
153
////////////////////////////////////////////////////////////////////////////////
154
//
155
//  Implementation
156
//
157
 
158
//  Next Address Generator
159
 
160
always @(*)                 // PMSO XY C
161
begin                       // CAtP    0
162
    case(NA_Op)             //  Rk
163
        4'b0000 : Op_Sel <= 7'b1000_00_0;   // NA <= PC                  + 0
164
        4'b0001 : Op_Sel <= 7'b1000_00_1;   // NA <= PC                  + 1
165
        4'b0010 : Op_Sel <= 7'b0100_00_0;   // NA <= MAR                 + 0
166
        4'b0011 : Op_Sel <= 7'b0100_00_1;   // NA <= MAR                 + 1
167
        4'b0100 : Op_Sel <= 7'b0010_00_0;   // NA <= {  1, SP }          + 0
168
        4'b0101 : Op_Sel <= 7'b0001_00_0;   // NA <= {  0, OP1}          + 0
169
        4'b0110 : Op_Sel <= 7'b0001_10_0;   // NA <= {  0, OP1} + {0, X} + 0
170
        4'b0111 : Op_Sel <= 7'b0001_01_0;   // NA <= {  0, OP1} + {0, Y} + 0
171
        4'b1000 : Op_Sel <= 7'b0001_00_0;   // NA <= {OP2, OP1}          + 0
172
        4'b1001 : Op_Sel <= 7'b0001_00_0;   // NA <= {OP2, OP1}          + 0
173
        4'b1010 : Op_Sel <= 7'b0001_00_0;   // NA <= {OP2, OP1}          + 0
174
        4'b1011 : Op_Sel <= 7'b0001_00_0;   // NA <= {OP2, OP1}          + 0
175
        4'b1100 : Op_Sel <= 7'b0001_00_0;   // NA <= {OP2, OP1}          + 0
176
        4'b1101 : Op_Sel <= 7'b0001_00_0;   // NA <= {OP2, OP1}          + 0
177
        4'b1110 : Op_Sel <= 7'b0001_10_0;   // NA <= {OP2, OP1} + {0, X} + 0
178
        4'b1111 : Op_Sel <= 7'b0001_01_0;   // NA <= {OP2, OP1} + {0, Y} + 0
179
    endcase
180
end
181
 
182
//  Generate Left Address Operand
183
 
184
always @(*) AL <= (  ((Op_Sel[ 6]) ? PC              : 0)
185
                   | ((Op_Sel[ 5]) ? MAR             : 0)
186
                   | ((Op_Sel[ 4]) ? {8'h01, StkPtr} : 0)
187
                   | ((Op_Sel[ 3]) ? {OP2  , OP1   } : 0));
188
 
189
//  Generate Right Address Operand
190
 
191
always @(*) AR <= (  ((Op_Sel[ 2]) ? {8'h00, X}      : 0)
192
                   | ((Op_Sel[ 1]) ? {8'h00, Y}      : 0));
193
 
194
//  Compute Next Address
195
 
196
always @(*) NA <= (AL + AR + Op_Sel[0]);
197
 
198
//  Generate Address Output - Truncate Next Address when ZP asserted
199
 
200
always @(*) AO <= NA & ((ZP) ? 16'h00FF : 16'hFFFF);
201
 
202
//  Memory Address Register
203
 
204
assign CE_MAR = (|NA_Op) & Rdy;
205
 
206
always @(posedge Clk)
207
begin
208
    if(Rst)
209
        MAR <= #1 Vector;
210
    else if(CE_MAR)
211
        MAR <= #1 AO;
212
end
213
 
214
//  Program Counter
215
 
216
assign CE_PC = ((BRV3) ? ((|PC_Op) & ~Int) : (|PC_Op)) & Rdy;
217
 
218
//  Generate Relative Address
219
 
220
assign Rel = ((CC) ? {{8{DI[7]}}, DI} : 0);
221
 
222
//  Determine the operands for Program Counter updates
223
 
224
always @(*)                 // PDO R C
225
begin                       // PIP e 0
226
    case({PC_Op, Stk_Op})   //   2 l
227
        4'b0000 : PC_Sel <= 5'b100_0_0; // NOP: PC      PC <= PC         + 0
228
        4'b0001 : PC_Sel <= 5'b100_0_0; // NOP: PC      PC <= PC         + 0
229
        4'b0010 : PC_Sel <= 5'b100_0_0; // NOP: PC      PC <= PC         + 0
230
        4'b0011 : PC_Sel <= 5'b100_0_0; // NOP: PC      PC <= PC         + 0
231
        4'b0100 : PC_Sel <= 5'b100_0_1; // Pls: PC + 1  PC <= PC         + 1
232
        4'b0101 : PC_Sel <= 5'b100_0_1; // Pls: PC + 1  PC <= PC         + 1
233
        4'b0110 : PC_Sel <= 5'b100_0_1; // Pls: PC + 1  PC <= PC         + 1
234
        4'b0111 : PC_Sel <= 5'b100_0_1; // Pls: PC + 1  PC <= PC         + 1
235
        4'b1000 : PC_Sel <= 5'b010_0_0; // Jmp: JMP     PC <= { DI, OP1} + 0
236
        4'b1001 : PC_Sel <= 5'b010_0_0; // Jmp: JMP     PC <= { DI, OP1} + 0
237
        4'b1010 : PC_Sel <= 5'b001_0_0; // Jmp: JSR     PC <= {OP2, OP1} + 0
238
        4'b1011 : PC_Sel <= 5'b010_0_1; // Jmp: RTS/RTI PC <= { DI, OP1} + 1
239
        4'b1100 : PC_Sel <= 5'b100_1_1; // Rel: Bcc     PC <= PC + Rel   + 1
240
        4'b1101 : PC_Sel <= 5'b100_1_1; // Rel: Bcc     PC <= PC + Rel   + 1
241
        4'b1110 : PC_Sel <= 5'b100_1_1; // Rel: Bcc     PC <= PC + Rel   + 1
242
        4'b1111 : PC_Sel <= 5'b100_1_1; // Rel: Bcc     PC <= PC + Rel   + 1
243
    endcase
244
end
245
 
246
always @(*) PCL <= (  ((PC_Sel[4]) ? PC         : 0)
247
                    | ((PC_Sel[3]) ? { DI, OP1} : 0)
248
                    | ((PC_Sel[2]) ? {OP2, OP1} : 0));
249
 
250
always @(*) PCR <=    ((PC_Sel[1]) ? Rel        : 0);
251
 
252
//  Implement Program Counter
253
 
254
always @(posedge Clk)
255
begin
256
    if(Rst)
257
        PC <= #1 Vector;
258
    else if(CE_PC)
259
        PC <= #1 (PCL + PCR + PC_Sel[0]);
260
end
261
 
262
//  Track past values of the PC for interrupt handling
263
//      past value of PC required to correctly determine the address of the
264
//      instruction at which the interrupt trap was taken. The automatic incre-
265
//      ment of the return address following RTS/RTI will advance the address 
266
//      so that it points to the correct instruction.
267
 
268
always @(posedge Clk)
269
begin
270
    if(Rst)
271
        dPC <= #1 Vector;
272
    else if(CE_PC)
273
        dPC <= #1 PC;
274
end
275
 
276
endmodule

powered by: WebSVN 2.1.0

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