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

Subversion Repositories m65c02

[/] [m65c02/] [trunk/] [Src/] [RTL/] [M65C02_MPCv4.v] - Blame information for rev 3

Go to most recent revision | 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:     08:02:40 03/01/2013 
45
// Design Name:     Microprogram Controller (Version 4)
46
// Module Name:     MPCv4.v
47
// Project Name:    C:\XProjects\VerilogComponents\MPCv4
48
// Target Devices:  Generic SRAM-based FPGA
49
// Tool versions:   Xilinx ISE 10.1i SP3
50
// 
51
// Description:
52
//
53
// This module implements a simple microprogram sequencer based on the Fair-
54
// child F9408. The sequencer provides:
55
//
56
//          (1) 4-bit instruction input
57
//          (2) four-level LIFO stack;
58
//          (3) program counter and incrementer;
59
//          (4) 4-bit registered test input;
60
//          (5) 8-way multi-way branch control input;
61
//          (6) branch address input;
62
//          (7) 4-way branch address select output;
63
//          (8) next address output.
64
//
65
// These elements provide a relatively flexible general purpose microprogram
66
// controller without a complex instruction set. The sixteen instructions can
67
// be categorized into three classes: (1) fetch, (2) unconditional branches,
68
// and (3) conditional branches. The fetch instruction class, consisting of a 
69
// single instruction class, simply increments the program counter and outputs
70
// the current value of the program counter on the next address bus. The uncon-
71
// ditional branch instruction class provides instructions to select the next
72
// instruction using the Via[1:0] outputs and output that value on the next
73
// address bus and simultaneously load the program counter. The unconditional
74
// branch instruction class also provides for 8-way multiway branching using an
75
// external (priority) encoder/branch selector, and microprogram subroutine call
76
// and return instructions.
77
//
78
// The instruction encodings of the F9408, as provided in "Principles of Firm-
79
// ware Engineering in Microprogram Control" by Michael Andrews. The instruc-
80
// tion set and operation map for the implementation is given below:
81
//
82
//  I[3:0] MNEM Definition       T[3:0]      MA[m:0]      Via Inh  Operation
83
//   0000  RTS  Return            xxxx      TOS[m:0]       00  0  PC<=MA;Pop
84
//   0001  BSR  Call Subroutine   xxxx       BA[m:0]       00  1  PC<=MA;Push
85
//   0010  FTCH Next Instruction  xxxx        PC+1         00  0  PC<=MA[m:0]
86
//   0011  BMW  Multi-way Branch  xxxx  {BA[m:3],MW[2:0]}  00  1  PC<=MA[m:0]
87
//   0100  BRV0 Branch Via 0      xxxx       BA[m:0]       00  1  PC<=MA[m:0]
88
//   0101  BRV1 Branch Via 1      xxxx       BA[m:0]       01  1  PC<=MA[m:0]
89
//   0110  BRV2 Branch Via 2      xxxx       BA[m:0]       10  1  PC<=MA[m:0]
90
//   0111  BRV3 Branch Via 3      xxxx       BA[m:0]       11  1  PC<=MA[m:0]
91
//   1000  BTH0 Branch T0 High    xxx1  {T0?BA[m:0]:PC+1}  00  1  PC<=MA[m:0]
92
//   1001  BTH1 Branch T1 High    xx1x  {T1?BA[m:0]:PC+1}  00  1  PC<=MA[m:0]
93
//   1010  BTH2 Branch T2 High    x1xx  {T2?BA[m:0]:PC+1}  00  1  PC<=MA[m:0]
94
//   1011  BTH3 Branch T3 High    1xxx  {T2?BA[m:0]:PC+1}  00  1  PC<=MA[m:0]
95
//   1100  BTL0 Branch T0 Low     xxx0  {T0?PC+1:BA[m:0]}  00  1  PC<=MA[m:0]
96
//   1101  BTL1 Branch T1 Low     xx0x  {T1?PC+1:BA[m:0]}  00  1  PC<=MA[m:0]
97
//   1110  BTL2 Branch T2 Low     x0xx  {T2?PC+1:BA[m:0]}  00  1  PC<=MA[m:0]
98
//   1111  BTL3 Branch T3 Low     0xxx  {T3?PC+1:BA[m:0]}  00  1  PC<=MA[m:0]
99
//
100
// Dependencies:    none.
101
//
102
// Revision: 
103
//
104
//  0.01    12J28   MAM     File Created
105
//
106
//  1.00    12K12   MAM     Modified MA multiplexer to either present next
107
//                          address or hold current address. This is required
108
//                          when the next microcycle has a length greater than
109
//                          one. To perform this adjustment/extension of the
110
//                          microcycle, two signals track the current and next
111
//                          microcycle length: CurLenZ, and NxtLenZ. Also, added
112
//                          register MPC_En to control the MPC registers and
113
//                          MA multiplexer. Removed non-pipelined mode control
114
//                          input because the typical usage of the MPC is with
115
//                          Block RAM, which will only work with the pipelined
116
//                          mode.
117
//
118
//  1.10    12K20   MAM     Changed reset for the microcycle length controller
119
//                          portion from MPC_Rst to Rst, which releases the
120
//                          microcycle length controller one cycle ahead of the
121
//                          MPC logic of the module. This is required to ensure
122
//                          that MPC_En and the microcycle length controller SM
123
//                          are properly conditioned before the start of micro-
124
//                          program execution. Removed the multiplexer on MA.
125
//                          The multiplexer was used to hold the address of the
126
//                          MPC when a delay cycle was required. It was put into
127
//                          implementation to correct an issue with BCD instruc-
128
//                          tions during testing with single cycle memory. The
129
//                          same issue reappeared when multi-cycle microcycles
130
//                          were tested. The issue was corrected by removing the
131
//                          MA multiplexer, and properly conditioning the PSW,
132
//                          interrupt handler update and the microprogram ROMs
133
//                          with the Rdy signal. The original fix, adding the MA
134
//                          multiplexer, fixed the issue because the PSW ISR
135
//                          update logic and microprogram ROMs were not condi-
136
//                          tioned with Rdy. The multiplexer added a microcycle
137
//                          delay which couldn't be sustained for multi-cycle
138
//                          microcycles; the required microprogram address delay
139
//                          could only be sustained for one cycle without adding
140
//                          the enable, i.e. Rdy, to the microprogram ROM.
141
//
142
//  1.20    13C01   MAM     Changed microcycle length controller to fixed length
143
//                          controller of 4 clocks per microcycle. However, add-
144
//                          ed two states to support synchronous wait state in-
145
//                          sertion. If Rdy not asserted during C3 (MC==1), then
146
//                          a wait state of 4 clock cycles is added by inserting
147
//                          two states which return to C2 (MC==3). In these two
148
//                          new cycles, Phi1O should be asserted, and then when
149
//                          the cycle returns to C2 and C3 again, Phi2O is re-
150
//                          asserted high. If on C3, Rdy is not asserted, the
151
//                          wait state cycles resume. If on C3, Rdy is asserted,
152
//                          the the memory cycle terminates, input data is cap-
153
//                          tured, and the microcyle moves to C4 to complete.
154
//
155
// Additional Comments: 
156
//
157
//  The Version 4 Microprogram Controller (MPCv4) is based on the Fairchild
158
//  F9408 MPC. It extends that microprogram controller by incorporating a micro-
159
//  cycle controller and wait state generator directly into the module. The
160
//  microcycle controller sets the length of the microcycle to 4 clock cycles.
161
//  Although the MPC is able to execute a microprogram in single cycle mode, the
162
//  version 4 MPC is intended to ease the implementation of processors which use
163
//  an external memory interface. A four cycle microcycle is about as short an
164
//  external memory cycle can be implemented to allow reasonably priced devices
165
//  to be used.
166
//
167
//  The wait state generator function has been built into the microcycle length
168
//  controller. The typical 4 cycle microcycle will expect that external memory
169
//  has completed the requested read or write cycle at the end of cycle 3. The
170
//  expectation is that the address, data, and control signals (A, DB, nOE, and
171
//  nWr) are asserted as required during cycle 2. The remainder of cycle 2, and
172
//  cycle 3 are used to read or write external memory. The bus control signals
173
//  will be deasserted, along with the data bus if a write operation is being
174
//  performed, at the end of cycle 3/start of cycle 4. This means that read data
175
//  from memory is registered at the start of cycle 4. 
176
//
177
//  If the external address decode logic, after decoding the address, determines
178
//  that a delay is required, then it must assert the Wait request such that the
179
//  microcycle controller detects it as asserted at the end of cycle 3 Istart of
180
//  cycle 4). If Wait is asserted in cycle 3, then the microcycle controller in-
181
//  serts a 4 cycle wait state cycle. The Wait signal is resampled during the
182
//  3rd wait state cycle, and if not asserted, the normal microcycle continues.
183
//  Otherwise, another 4 cycle wait state is inserted, and this process conti-
184
//  nues until Wait is not asserted during the 3rd cycle of the wait state se-
185
//  quence.
186
//
187
////////////////////////////////////////////////////////////////////////////////
188
 
189
module M65C02_MPCv4 #(
190
    parameter pAddrWidth = 10,          // Original F9408 => 10-bit Address
191
    parameter pRst_Addrs = 0            // Reset Address
192
)(
193
    input   Rst,                        // Module Reset (Synchronous)
194
    input   Clk,                        // Module Clock
195
 
196
    input   Wait,                       // Microcycle Wait State Request Input
197
 
198
    output  reg [2:0] MC,               // Microcycle State outputs
199
 
200
    input   [3:0] I,                    // Instruction (see description)
201
    input   [3:0] T,                    // Conditional Test Inputs
202
    input   [2:0] MW,                   // Multi-way Branch Address Select
203
    input   [(pAddrWidth-1):0] BA,      // Microprogram Branch Address Field
204
    output  [1:0] Via,                  // Unconditional Branch Address Select
205
 
206
 
207
    output  [(pAddrWidth-1):0] MA       // Microprogram Address
208
);
209
 
210
////////////////////////////////////////////////////////////////////////////////
211
////////////////////////////////////////////////////////////////////////////////
212
//
213
//  Local Parameters
214
//
215
 
216
localparam pRTS  =  0;  // Return from Subroutine
217
localparam pBSR  =  1;  // Branch to Subroutine
218
localparam pFTCH =  2;  // Fetch Next Instruction
219
localparam pBMW  =  3;  // Multi-way Branch
220
localparam pBRV0 =  4;  // Branch Via External Branch Address Source #0
221
localparam pBRV1 =  5;  // Branch Via External Branch Address Source #1
222
localparam pBRV2 =  6;  // Branch Via External Branch Address Source #2
223
localparam pBRV3 =  7;  // Branch Via External Branch Address Source #3
224
localparam pBTH0 =  8;  // Branch if T[0] is Logic 1, else fetch next instr.
225
localparam pBTH1 =  9;  // Branch if T[1] is Logic 1, else fetch next instr.
226
localparam pBTH2 = 10;  // Branch if T[2] is Logic 1, else fetch next instr.
227
localparam pBTH3 = 11;  // Branch if T[3] is Logic 1, else fetch next instr.
228
localparam pBTL0 = 12;  // Branch if T[0] is Logic 0, else fetch next instr.
229
localparam pBTL1 = 13;  // Branch if T[1] is Logic 0, else fetch next instr.
230
localparam pBTL2 = 14;  // Branch if T[2] is Logic 0, else fetch next instr.
231
localparam pBTL3 = 15;  // Branch if T[3] is Logic 0, else fetch next instr.
232
 
233
///////////////////////////////////////////////////////////////////////////////
234
///////////////////////////////////////////////////////////////////////////////
235
//
236
//  Declarations
237
//
238
 
239
reg     MPC_En;                             // MPC register enable
240
 
241
wire    [(pAddrWidth - 1):0] Next;          // Output Program Counter Increm.
242
reg     [(pAddrWidth - 1):0] PC_In;         // Input to Program Counter
243
reg     [(pAddrWidth - 1):0] PC;            // Program Counter
244
 
245
//reg     [(pAddrWidth - 1):0] A, B, C, D;    // LIFO Stack Registers
246
reg     [(pAddrWidth - 1):0] A;             // LIFO Stack Registers
247
 
248
reg     dRst;                               // Reset stretcher
249
wire    MPC_Rst;                            // Internal MPC Reset signal
250
 
251
////////////////////////////////////////////////////////////////////////////////
252
////////////////////////////////////////////////////////////////////////////////
253
//
254
//  Implementation
255
//
256
 
257
//  Implement module reset generator
258
 
259
always @(posedge Clk)
260
begin
261
    if(Rst)
262
        dRst <= #1 1;
263
    else
264
        dRst <= #1 0;
265
end
266
 
267
assign MPC_Rst = (Rst | dRst);
268
 
269
//
270
//  Embedded Microcycle Controller and Wait State Generator 
271
//
272
//  The microcycle length is fixed to 4 clock cycles in length when Wait is not
273
//  asserted in C3. If Wait is asserted in C3, then a 4 cycle wait sequence is
274
//  inserted. This behavior allows external logic to extend the microcycle
275
//  length in multiples of 4 clock cycles.
276
 
277
always @(posedge Clk)
278
begin
279
    if(Rst)
280
        MC <= #1 6;
281
    else
282
        case(MC)
283
            // Normal Operation
284
            4 : MC <= #1 6;                 // 4th cycle of microcycle (Phi1O)
285
            6 : MC <= #1 7;                 // 1st cycle of microcycle (Phi1O)
286
            7 : MC <= #1 5;                 // 2nd cycle of microcycle (Phi2O)
287
            5 : MC <= #1 ((Wait) ? 0 : 4);  // 3rd cycle of microcycle (Phi2O) 
288
            //  Wait State Operation
289
 
290
            2 : MC <= #1 3;                 // 1st cycle of microcycle (Phi1O)
291
            3 : MC <= #1 1;                 // 2nd cycle of microcycle (Phi2O)
292
            1 : MC <= #1 ((Wait) ? 0 : 4);  // 3rd cycle of microcycle (Phi2O)
293
        endcase
294
end
295
 
296
//  Determine the MPC Enable signal
297
 
298
always @(posedge Clk) MPC_En <= #1 ((Rst) ? 0 : (~Wait & (MC[1:0] == 1)));
299
 
300
////  Implement 4-Level LIFO Stack
301
//
302
//always @(posedge Clk)
303
//begin
304
//    if(MPC_Rst)
305
//        {A, B, C, D} <= #1 0;
306
//    else if(MPC_En)
307
//        if(I == BSR)
308
//            {A, B, C, D} <= #1 {Next, A, B, C};
309
//        else if(I == RTS)
310
//            {A, B, C, D} <= #1 {B, C, D, {pAddrWidth{1'b0}}};
311
//end
312
 
313
//  Implement 1-Level LIFO Stack
314
 
315
always @(posedge Clk)
316
begin
317
    if(MPC_Rst)
318
        A <= #1 0;
319
    else if(MPC_En)
320
        if(I == pBSR)
321
            A <= #1 Next;
322
        else if(I == pRTS)
323
            A <= #1 {pAddrWidth{1'b0}};
324
end
325
 
326
//  Program Counter Incrementer
327
 
328
assign Next = PC + 1;
329
 
330
//  Generate Unconditional Branch Address Select
331
 
332
assign Via = {((I == pBRV2) | (I == pBRV3)), ((I == pBRV3) | (I == pBRV1))};
333
 
334
//  Generate Program Counter Input Signal
335
 
336
always @(*)
337
begin
338
    case({MPC_Rst, I})
339
        pRTS    : PC_In <=  A;
340
        pBSR    : PC_In <=  BA;
341
        pFTCH   : PC_In <=  Next;
342
        pBMW    : PC_In <=  {BA[(pAddrWidth - 1):3], MW};
343
        //
344
        pBRV0   : PC_In <=  BA;
345
        pBRV1   : PC_In <=  BA;
346
        pBRV2   : PC_In <=  BA;
347
        pBRV3   : PC_In <=  BA;
348
        //
349
        pBTH0   : PC_In <=  (T[0] ? BA   : Next);
350
        pBTH1   : PC_In <=  (T[1] ? BA   : Next);
351
        pBTH2   : PC_In <=  (T[2] ? BA   : Next);
352
        pBTH3   : PC_In <=  (T[3] ? BA   : Next);
353
        //
354
        pBTL0   : PC_In <=  (T[0] ? Next : BA  );
355
        pBTL1   : PC_In <=  (T[1] ? Next : BA  );
356
        pBTL2   : PC_In <=  (T[2] ? Next : BA  );
357
        pBTL3   : PC_In <=  (T[3] ? Next : BA  );
358
        default : PC_In <=  pRst_Addrs;
359
    endcase
360
end
361
 
362
//  Generate Microprogram Address (Program Counter)
363
 
364
always @(posedge Clk)
365
begin
366
    if(MPC_Rst)
367
        PC <= #1 pRst_Addrs;
368
    else if(MPC_En)
369
        PC <= #1 PC_In;
370
end
371
 
372
//  Assign Memory Address Bus
373
 
374
assign MA = PC_In;
375
 
376
endmodule

powered by: WebSVN 2.1.0

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