├── Docs ├── 1004-0001 M65C02 Design Description.doc ├── Images │ ├── FSM-BubbleDiagram.JPG │ ├── M65C02 Timing Diagram.JPG │ ├── M65C02-TestBoard-20130703.JPG │ ├── M65C02_ALU.JPG │ ├── M65C02_Core.JPG │ ├── M65C02_FlowControl_Immediate_Cycles.JPG │ ├── M65C02_Implicit_Accumulator_Cycles.JPG │ ├── M65C02_MPC.JPG │ ├── M65C02_RMW_zp_zpX_abs_absX_Cycles.JPG │ ├── M65C02_abs_absX_absY_Cycles.JPG │ ├── M65C02_zpI_zpXI_zpIY_Cycles.JPG │ └── M65C02_zp_zpX_Cycles.JPG ├── M65C02-Notes.pdf └── M65C02-Notes.xls ├── README.md ├── Sim ├── M65C02.xwv ├── M65C02A.xwv ├── M65C02B.xwv ├── M65C02_ALU.xwv ├── M65C02_BCD.xwv ├── M65C02_Core.xwv ├── M65C02_Hist_File.txt ├── M65C02_Mnemonics.txt ├── M65C02_SV_Output.txt ├── tb_M65C02.v ├── tb_M65C02_ALU.v ├── tb_M65C02_AddrGen.v ├── tb_M65C02_BCD.v ├── tb_M65C02_Core.v └── tb_M65C02_RAM.v ├── Src ├── M65C02-Test-Programs │ ├── Klaus2m5_Functional_Tests │ │ ├── 65C02_FT.a65 │ │ ├── 65c02_ft.bat │ │ ├── 65c02_ft.bin │ │ └── 65c02_ft.lst │ ├── M65C02.TXT │ ├── M65C02_Tst.a65 │ ├── M65C02_Tst3.a65 │ ├── M65C02_Tst5.a65 │ ├── m65c02.bin │ ├── m65c02_tst3.lst │ ├── m65c02_tst5.lst │ ├── m65c02v5.bat │ └── m65c02v7.bat ├── Memory-Images │ ├── 65C02_ft.txt │ ├── M65C02_Decoder_ROM.coe │ ├── M65C02_RAM.txt │ ├── M65C02_Tst3.txt │ ├── M65C02_Tst5.txt │ ├── M65C02_uPgm_V3.coe │ └── M65C02_uPgm_V3a.coe ├── Microprogram-Sources │ ├── M65C02_Decoder_ROM.out │ ├── M65C02_Decoder_ROM.txt │ ├── M65C02_uPgm_V3.out │ ├── M65C02_uPgm_V3.txt │ ├── M65C02_uPgm_V3a.out │ └── M65C02_uPgm_V3a.txt ├── README.md ├── RTL │ ├── ClkGen.xaw │ ├── M65C02.tcl │ ├── M65C02.ucf │ ├── M65C02.v │ ├── M65C02_ALU.v │ ├── M65C02_AddrGen.v │ ├── M65C02_BCD.v │ ├── M65C02_BIN.v │ ├── M65C02_Base.ucf │ ├── M65C02_Base.v │ ├── M65C02_ClkGen.v │ ├── M65C02_Core.ucf │ ├── M65C02_Core.v │ ├── M65C02_IntHndlr.v │ ├── M65C02_MPC.v │ ├── M65C02_MPCv3.v │ ├── M65C02_MPCv4.v │ ├── M65C02_RAM.txt │ ├── M65C02_RAM.v │ └── fedet.v └── Settings │ └── M65C02.tcl └── Utils ├── BIN2TXT.C ├── BIN2TXT.EXE ├── README.md ├── SMRT_tool.zip └── m65c02.bat /Docs/1004-0001 M65C02 Design Description.doc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MorrisMA/MAM65C02-Processor-Core/dabbc3f44616cdb0898375d68b9f36e11fd21081/Docs/1004-0001 M65C02 Design Description.doc -------------------------------------------------------------------------------- /Docs/Images/FSM-BubbleDiagram.JPG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MorrisMA/MAM65C02-Processor-Core/dabbc3f44616cdb0898375d68b9f36e11fd21081/Docs/Images/FSM-BubbleDiagram.JPG -------------------------------------------------------------------------------- /Docs/Images/M65C02 Timing Diagram.JPG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MorrisMA/MAM65C02-Processor-Core/dabbc3f44616cdb0898375d68b9f36e11fd21081/Docs/Images/M65C02 Timing Diagram.JPG -------------------------------------------------------------------------------- /Docs/Images/M65C02-TestBoard-20130703.JPG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MorrisMA/MAM65C02-Processor-Core/dabbc3f44616cdb0898375d68b9f36e11fd21081/Docs/Images/M65C02-TestBoard-20130703.JPG -------------------------------------------------------------------------------- /Docs/Images/M65C02_ALU.JPG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MorrisMA/MAM65C02-Processor-Core/dabbc3f44616cdb0898375d68b9f36e11fd21081/Docs/Images/M65C02_ALU.JPG -------------------------------------------------------------------------------- /Docs/Images/M65C02_Core.JPG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MorrisMA/MAM65C02-Processor-Core/dabbc3f44616cdb0898375d68b9f36e11fd21081/Docs/Images/M65C02_Core.JPG -------------------------------------------------------------------------------- /Docs/Images/M65C02_FlowControl_Immediate_Cycles.JPG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MorrisMA/MAM65C02-Processor-Core/dabbc3f44616cdb0898375d68b9f36e11fd21081/Docs/Images/M65C02_FlowControl_Immediate_Cycles.JPG -------------------------------------------------------------------------------- /Docs/Images/M65C02_Implicit_Accumulator_Cycles.JPG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MorrisMA/MAM65C02-Processor-Core/dabbc3f44616cdb0898375d68b9f36e11fd21081/Docs/Images/M65C02_Implicit_Accumulator_Cycles.JPG -------------------------------------------------------------------------------- /Docs/Images/M65C02_MPC.JPG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MorrisMA/MAM65C02-Processor-Core/dabbc3f44616cdb0898375d68b9f36e11fd21081/Docs/Images/M65C02_MPC.JPG -------------------------------------------------------------------------------- /Docs/Images/M65C02_RMW_zp_zpX_abs_absX_Cycles.JPG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MorrisMA/MAM65C02-Processor-Core/dabbc3f44616cdb0898375d68b9f36e11fd21081/Docs/Images/M65C02_RMW_zp_zpX_abs_absX_Cycles.JPG -------------------------------------------------------------------------------- /Docs/Images/M65C02_abs_absX_absY_Cycles.JPG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MorrisMA/MAM65C02-Processor-Core/dabbc3f44616cdb0898375d68b9f36e11fd21081/Docs/Images/M65C02_abs_absX_absY_Cycles.JPG -------------------------------------------------------------------------------- /Docs/Images/M65C02_zpI_zpXI_zpIY_Cycles.JPG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MorrisMA/MAM65C02-Processor-Core/dabbc3f44616cdb0898375d68b9f36e11fd21081/Docs/Images/M65C02_zpI_zpXI_zpIY_Cycles.JPG -------------------------------------------------------------------------------- /Docs/Images/M65C02_zp_zpX_Cycles.JPG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MorrisMA/MAM65C02-Processor-Core/dabbc3f44616cdb0898375d68b9f36e11fd21081/Docs/Images/M65C02_zp_zpX_Cycles.JPG -------------------------------------------------------------------------------- /Docs/M65C02-Notes.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MorrisMA/MAM65C02-Processor-Core/dabbc3f44616cdb0898375d68b9f36e11fd21081/Docs/M65C02-Notes.pdf -------------------------------------------------------------------------------- /Docs/M65C02-Notes.xls: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MorrisMA/MAM65C02-Processor-Core/dabbc3f44616cdb0898375d68b9f36e11fd21081/Docs/M65C02-Notes.xls -------------------------------------------------------------------------------- /Sim/M65C02.xwv: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MorrisMA/MAM65C02-Processor-Core/dabbc3f44616cdb0898375d68b9f36e11fd21081/Sim/M65C02.xwv -------------------------------------------------------------------------------- /Sim/M65C02A.xwv: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MorrisMA/MAM65C02-Processor-Core/dabbc3f44616cdb0898375d68b9f36e11fd21081/Sim/M65C02A.xwv -------------------------------------------------------------------------------- /Sim/M65C02B.xwv: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MorrisMA/MAM65C02-Processor-Core/dabbc3f44616cdb0898375d68b9f36e11fd21081/Sim/M65C02B.xwv -------------------------------------------------------------------------------- /Sim/M65C02_ALU.xwv: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MorrisMA/MAM65C02-Processor-Core/dabbc3f44616cdb0898375d68b9f36e11fd21081/Sim/M65C02_ALU.xwv -------------------------------------------------------------------------------- /Sim/M65C02_BCD.xwv: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MorrisMA/MAM65C02-Processor-Core/dabbc3f44616cdb0898375d68b9f36e11fd21081/Sim/M65C02_BCD.xwv -------------------------------------------------------------------------------- /Sim/M65C02_Core.xwv: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MorrisMA/MAM65C02-Processor-Core/dabbc3f44616cdb0898375d68b9f36e11fd21081/Sim/M65C02_Core.xwv -------------------------------------------------------------------------------- /Sim/M65C02_Hist_File.txt: -------------------------------------------------------------------------------- 1 | 2 | 00000000 : 0002 0007 0003 0017 0006 0006 0003 0004 0005 0018 0005 0008 0006 003e 0009 000e 3 | 00000001 : 0001 0001 0001 0001 0001 0001 0001 0001 0001 0001 0002 0001 0001 0003 0001 0001 4 | 00000002 : 0001 0001 0001 0001 0001 0001 0001 0001 0001 0001 0007 0002 0001 0001 0001 0001 5 | 00000003 : 0001 0001 0001 0001 0001 0001 0001 0001 0001 0001 0001 0001 0001 0001 0001 0001 6 | 00000004 : 0001 0001 0001 0001 0001 0001 000a 0001 0001 0001 0002 0001 0001 0001 0001 0001 7 | 00000005 : 0001 0001 0001 0001 0001 0001 0001 0001 000d 0005 0001 0005 0002 0001 0001 0001 8 | 00000006 : 0001 0001 0001 0001 0001 0001 0001 0001 0001 0003 0002 0003 0002 0001 0001 0001 9 | 00000007 : 0001 0001 0001 0001 0001 0001 0001 0002 0001 0001 0001 0001 0001 0001 0001 0001 10 | 00000008 : 000a 000c 0008 0008 000e 0004 0010 0004 0005 0004 0006 0005 0007 0003 000a 0003 11 | 00000009 : 0002 0001 0004 0001 0003 0001 0004 0003 000e 0001 0021 0001 000e 0001 0005 0001 12 | 0000000a : 0009 0001 0002 0003 0009 0001 0001 0001 0004 0001 0005 0001 0005 0001 0013 0001 13 | 0000000b : 0001 0001 0001 0001 0001 0001 0001 0001 0001 0001 0001 0001 0003 0000 0001 0001 14 | 0000000c : 0001 0001 0001 0001 0002 0001 0001 0001 0002 000b 0003 0001 0001 0001 0001 0001 15 | 0000000d : 0001 0001 0001 0001 0001 0001 0001 0001 0005 0003 0001 0001 0001 0001 0001 0001 16 | 0000000e : 0001 0001 0001 0001 0001 0001 0001 0001 0002 0001 0003 0001 0001 0001 0001 0001 17 | 0000000f : 0001 0001 0001 0001 0001 0001 0001 0002 0001 0001 0001 0001 0001 0001 0001 0002 -------------------------------------------------------------------------------- /Sim/tb_M65C02.v: -------------------------------------------------------------------------------- 1 | //////////////////////////////////////////////////////////////////////////////// 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: 15:34:45 02/22/2013 45 | // Design Name: M65C02 46 | // Module Name: C:/XProjects/ISE10.1i/M65C02/tb_M65C02.v 47 | // Project Name: M65C02 48 | // Target Device: Xilinx Spartan-3A FPGA - XC3S50A-4VQ100 49 | // Tool versions: ISE 10.1i SP3 50 | // 51 | // Description: 52 | // 53 | // Verilog Test Fixture created by ISE for module: M65C02 54 | // 55 | // Dependencies: 56 | // 57 | // Revision: 58 | // 59 | // 0.01 13B22 MAM File Created 60 | // 61 | // 1.00 14B24 MAM Initial release 62 | // 63 | // 1.10 13B26 MAM Changed to support M65C02 with internal 2kB Boot ROM 64 | // 65 | // Additional Comments: 66 | // 67 | //////////////////////////////////////////////////////////////////////////////// 68 | 69 | module tb_M65C02; 70 | 71 | parameter pRAM_AddrWidth = 14; 72 | parameter pSim_Loop = 16'h0400; 73 | 74 | // UUT Signal Declarations 75 | 76 | reg nRst; 77 | tri1 nRstO; 78 | 79 | reg ClkIn; 80 | 81 | wire Phi1O; 82 | wire Phi2O; 83 | 84 | tri1 nSO; 85 | tri1 nNMI; 86 | tri1 nIRQ; 87 | tri1 nVP; 88 | 89 | reg BE_In; 90 | tri1 Rdy; 91 | tri0 Sync; 92 | tri1 nML; 93 | wire nWait; 94 | 95 | tri1 [3:0] nCE; 96 | tri1 RnW; 97 | tri1 nOE; 98 | tri1 nWr; 99 | tri1 [ 3:0] XA; 100 | tri1 [15:0] A; 101 | tri1 [ 7:0] DB; 102 | 103 | wire [4:0] LED; 104 | 105 | // Define simulation variables 106 | 107 | reg Sim_nSO, Sim_nNMI, Sim_nIRQ; 108 | reg [ 7:0] TestNum; 109 | reg [17:0] chkdad, chkadd; 110 | 111 | integer cycle_cnt = 0; 112 | integer instr_cnt = 0; 113 | 114 | integer Loop_Start = 0; 115 | 116 | integer Hist_File = 0; // File handle for instruction histogram 117 | 118 | reg [31:0] Hist [255:0]; // Instruction Histogram array 119 | reg [31:0] val; // Instruction Histogram variable 120 | reg [31:0] i, j; // loop counters 121 | 122 | // Instantiate the Unit Under Test (UUT) 123 | 124 | M65C02 #( 125 | .pBootROM_File("Src/M65C02_Tst5.txt") 126 | ) uut ( 127 | .nRst(nRst), 128 | .nRstO(nRstO), 129 | 130 | .ClkIn(ClkIn), 131 | 132 | .Phi1O(Phi1O), 133 | .Phi2O(Phi2O), 134 | 135 | .nNMI(nNMI), 136 | .nIRQ(nIRQ), 137 | .nVP(nVP), 138 | 139 | .BE_In(BE_In), 140 | .Sync(Sync), 141 | .nML(nML), 142 | 143 | .nCE(nCE), 144 | .RnW(RnW), 145 | .nOE(nOE), 146 | .nWE(nWr), 147 | .Rdy(Rdy), 148 | .XA(XA), 149 | .A(A), 150 | .DB(DB), 151 | 152 | .nWP_In(1'b0), 153 | 154 | .nWait(nWait), 155 | 156 | .LED(LED) 157 | 158 | // .LED(LED), 159 | // 160 | // .nSel(nSel), 161 | // .SCk(SCk), 162 | // .MOSI(MOSI), 163 | // .MISO(MISO) 164 | ); 165 | 166 | // Instantiate RAM Module 167 | 168 | wire [7:0] RAM_DO; 169 | reg RAM_WE; 170 | 171 | M65C02_RAM #( 172 | .pAddrSize(pRAM_AddrWidth), 173 | .pDataSize(8), 174 | .pFileName("Src/65C02_FT.txt") 175 | ) RAM ( 176 | .Clk(~Phi2O), 177 | // .Ext(1'b1), // 4 cycle memory 178 | // .ZP(1'b0), 179 | // .Ext(1'b0), // 2 cycle memory 180 | // .ZP(1'b0), 181 | .Ext(1'b0), // 1 cycle memory 182 | .ZP(1'b1), 183 | .WE(RAM_WE), 184 | .AI(A[(pRAM_AddrWidth - 1):0]), 185 | .DI(DB), 186 | .DO(RAM_DO) 187 | ); 188 | 189 | initial begin 190 | // Initialize Inputs 191 | nRst = 0; 192 | ClkIn = 1; 193 | Sim_nSO = 0; 194 | Sim_nNMI = 0; 195 | Sim_nIRQ = 0; 196 | BE_In = 1; 197 | TestNum = 0; 198 | chkdad = 0; 199 | chkadd = 0; 200 | 201 | // Intialize Simulation Time Format 202 | 203 | $timeformat (-9, 3, " ns", 12); 204 | 205 | // Initialize Instruction Execution Histogram array 206 | 207 | for(cycle_cnt = 0; cycle_cnt < 256; cycle_cnt = cycle_cnt + 1) 208 | Hist[cycle_cnt] = 0; 209 | cycle_cnt = 0; 210 | 211 | Hist_File = $fopen("M65C02_Hist_File.txt", "w"); 212 | 213 | // Wait 100 ns for global reset to finish 214 | 215 | #101 nRst = 1; 216 | 217 | // Start the Simulation Loop 218 | 219 | wait(A == pSim_Loop); 220 | @(posedge Phi1O); 221 | 222 | // Test WAI w/ IRQ_Mask set 223 | 224 | fork 225 | begin 226 | @(negedge nWait); 227 | for(i = 0; i < 4; i = i + 1) @(posedge Phi1O); 228 | Sim_nIRQ = 1; 229 | @(posedge nWait); 230 | @(posedge Phi1O) Sim_nIRQ = 0; 231 | end 232 | 233 | begin 234 | while(1) begin 235 | @(posedge Phi1O); 236 | if(A == pSim_Loop) begin 237 | @(posedge Phi1O); 238 | @(posedge Phi1O); 239 | @(posedge Phi1O); 240 | 241 | $display("\n\tTest Loop Complete\n"); 242 | $display("\tEnd of Simulation-Looping to Start detected\n"); 243 | $display("\t\tSuccess - All enabled tests passed.\n"); 244 | 245 | $fclose(Hist_File); 246 | 247 | $stop; 248 | end 249 | end 250 | end 251 | join 252 | end 253 | 254 | //////////////////////////////////////////////////////////////////////////////// 255 | // 256 | // Clocks 257 | // 258 | 259 | //always #20.000 ClkIn = ~ClkIn; 260 | //always #27.127 ClkIn = ~ClkIn; 261 | always #33.908 ClkIn = ~ClkIn; 262 | //always #12.500 ClkIn = ~ClkIn; 263 | 264 | //////////////////////////////////////////////////////////////////////////////// 265 | // 266 | // Test Structures 267 | // 268 | 269 | always @(posedge nWr) 270 | begin 271 | TestNum = ((A == 16'h0200) ? DB : TestNum); 272 | end 273 | 274 | always @(posedge nOE) 275 | begin 276 | chkdad = ((A == 16'h3405) ? (chkdad + 1) : chkdad); 277 | end 278 | 279 | always @(posedge nOE) 280 | begin 281 | chkadd = ((A == 16'h354E) ? (chkadd + 1) : chkadd); 282 | end 283 | 284 | // Connect ROM/RAM to M65C02 memory bus 285 | 286 | always @(*) RAM_WE <= Phi2O & ~A[15] & ~nWr; 287 | 288 | assign DB = ((~nOE) ? RAM_DO : {8{1'bZ}}); 289 | 290 | // Generate Simulate nIRQ signal based on writes by test program to address 291 | // 0xFFF8 (assert nIRQ) or 0xFFF9 (deassert nIRQ) 292 | 293 | always @(posedge nWr or negedge nRstO) 294 | begin 295 | if(~nRstO) 296 | Sim_nIRQ <= 0; 297 | else 298 | Sim_nIRQ <= ((A[15:1] == 15'b1111_1111_1111_100) ? ~A[0] : Sim_nIRQ); 299 | end 300 | 301 | // Drive nSO, nNMI, and nIRQ using simulation controlled signals 302 | 303 | assign nSO = ((Sim_nSO) ? 0 : 1'bZ); 304 | assign nNMI = ((Sim_nNMI) ? 0 : 1'bZ); 305 | assign nIRQ = ((Sim_nIRQ) ? 0 : 1'bZ); 306 | 307 | // Count number of cycles and the number of instructions between between 308 | // 0x0210 and the repeat at 0x0210 309 | 310 | always @(posedge uut.ClkGen.Clk) 311 | begin 312 | if((uut.ClkGen.Rst | ~uut.ClkGen.nRst)) 313 | cycle_cnt = 0; 314 | else if(Phi1O & uut.Rdy) 315 | cycle_cnt = ((A == 16'h0400) ? 1 : (cycle_cnt + 1)); 316 | end 317 | 318 | always @(posedge uut.ClkGen.Clk) 319 | begin 320 | if((uut.ClkGen.Rst | ~uut.ClkGen.nRst)) 321 | instr_cnt = 0; 322 | else if(Sync & Phi1O & uut.Rdy) 323 | instr_cnt = ((A == 16'h0400) ? 1 : (instr_cnt + 1)); 324 | end 325 | 326 | // Perform Instruction Histogramming for coverage puposes 327 | 328 | always @(posedge uut.ClkGen.Clk) 329 | begin 330 | if(~(uut.ClkGen.Rst | ~uut.ClkGen.nRst)) begin 331 | if(uut.Rdy & uut.uP.CE_IR) begin 332 | if((A == pSim_Loop)) begin 333 | if((Loop_Start == 1)) begin 334 | for(i = 0; i < 16; i = i + 1) begin // lower nibble 335 | for(j = 0; j < 16; j = j + 1) begin // upper nibble 336 | val = Hist[(j * 16) + i]; 337 | Hist[(j * 16) + i] = 0; 338 | if((j == 0) || (j == 8)) 339 | $fwrite(Hist_File, "\n%h : %d", (j*16)+i, val); 340 | else 341 | $fwrite(Hist_File, " %d", val); 342 | end 343 | end 344 | end else begin 345 | Loop_Start = 1; 346 | end 347 | end 348 | val = Hist[uut.uP.DI]; 349 | Hist[uut.uP.DI] = val + 1; 350 | end 351 | end 352 | end 353 | 354 | endmodule 355 | 356 | -------------------------------------------------------------------------------- /Sim/tb_M65C02_BCD.v: -------------------------------------------------------------------------------- 1 | /////////////////////////////////////////////////////////////////////////////// 2 | // 3 | // Copyright 2009-2012 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: 12/06/2009 45 | // Design Name: WDC W65C02 Microprocessor Re-Implementation 46 | // Module Name: M65C02_BCD 47 | // Project Name: C:\XProjects\ISE10.1i\MAM6502 48 | // Target Devices: Generic SRAM-based FPGA 49 | // Tool versions: Xilinx ISE10.1i SP3 50 | // 51 | // Description: 52 | // 53 | // Verilog Test Fixture created by ISE for module: M65C02_BCD.v 54 | // 55 | // Revision: 56 | // 57 | // 0.01 09L06 MAM Initial coding 58 | // 59 | // 1.00 12D28 MAM Modified to support release version of the BCD 60 | // adder module, which is separate from the binary 61 | // adder module. 62 | // 63 | // Additional Comments: 64 | // 65 | /////////////////////////////////////////////////////////////////////////////// 66 | 67 | module tb_W65C02_BCD; 68 | 69 | // System Interface 70 | 71 | reg Rst; 72 | reg Clk; 73 | 74 | // Inputs 75 | 76 | reg En; 77 | reg Sub; 78 | 79 | reg [7:0] A; 80 | reg [7:0] B; 81 | reg Ci; 82 | 83 | // Outputs 84 | 85 | wire [7:0] Sum; 86 | wire Co; 87 | wire OV; 88 | wire Valid; 89 | 90 | // Simulation Variables 91 | 92 | integer i, j, k; 93 | 94 | reg [4:0] LSN, MSN; 95 | reg C3, C7; 96 | reg [7:0] ALU; 97 | reg N, V, Z, C; 98 | 99 | // Instantiate the Unit Under Test (UUT) 100 | 101 | M65C02_BCD uut ( 102 | .Rst(Rst), 103 | .Clk(Clk), 104 | .En(En), 105 | 106 | .Op(Sub), 107 | 108 | .A(A), 109 | .B(B), 110 | .Ci(Ci), 111 | .Out({Co, Sum}), 112 | .OV(OV), 113 | .Valid(Valid) 114 | ); 115 | 116 | initial begin 117 | Rst = 1; 118 | Clk = 1; 119 | 120 | En = 0; 121 | Sub = 0; 122 | A = 0; 123 | B = 0; 124 | Ci = 0; 125 | 126 | i = 0; j = 0; k = 0; 127 | LSN = 0; MSN = 0; C3 = 0; C7 = 0; ALU = 0; {N,V,Z,C} = 0; 128 | 129 | // Wait 100 ns for global reset to finish 130 | 131 | #101 Rst = 0; 132 | 133 | $display("Begin Adder Tests"); 134 | 135 | // BCD Tests 136 | 137 | $display("Start Decimal Mode Addition Test"); 138 | 139 | Sub = 0; // ADC Test 140 | 141 | for(i = 0; i < 100; i = i + 1) begin 142 | k = (i / 10); 143 | A = (k * 16) + (i - (k * 10)); 144 | for(j = 0; j < 100; j = j + 1) begin 145 | k = (j / 10); 146 | B = (k * 16) + (j - (k * 10)); 147 | Ci = 0; 148 | En = 1; 149 | @(posedge Clk) #0.9 En = 0; 150 | @(posedge Valid) #0.1; 151 | if((Sum != ALU) || (Co != C) || (OV != V)) begin 152 | $display("Error: Incorrect Result"); 153 | $display("\tA: 0x%2h, B: 0x%2h, Ci: %b", A, B, Ci); 154 | $display("\t\t{NVZC, ALU}: %b%b%b%b, 0x%2h", N, V, Z, C, ALU); 155 | $display("\t\t{-V-C, Sum}: -%b-%b, 0x%2h", OV, Co, Sum); 156 | $display("End Decimal Mode Addition Test: Fail"); 157 | $stop; 158 | end 159 | @(posedge Clk) #1; 160 | Ci = 1; 161 | En = 1; 162 | @(posedge Clk) #0.9 En = 0; 163 | @(posedge Valid) #0.1; 164 | if((Sum != ALU) || (Co != C) || (OV != V)) begin 165 | $display("Error: Incorrect Result"); 166 | $display("\tA: 0x%2h, B: 0x%2h, Ci: %b", A, B, Ci); 167 | $display("\t\t{NVZC, ALU}: %b%b%b%b, 0x%2h", N, V, Z, C, ALU); 168 | $display("\t\t{-V-C, Sum}: -%b-%b, 0x%2h", OV, Co, Sum); 169 | $display("End Decimal Mode Addition Test: Fail"); 170 | $stop; 171 | end 172 | @(posedge Clk) #1; 173 | end 174 | end 175 | 176 | $display("End Decimal Mode Addition Test: Pass"); 177 | 178 | // SBC Test 179 | 180 | $display("Start Decimal Mode Subtraction Test"); 181 | 182 | Sub = 1; // SBC Test 183 | 184 | for(i = 0; i < 100; i = i + 1) begin 185 | k = (i / 10); 186 | A = (k * 16) + (i - (k * 10)); 187 | for(j = 0; j < 100; j = j + 1) begin 188 | k = (j / 10); 189 | B = ~((k * 16) + (j - (k * 10))); 190 | Ci = 1; 191 | En = 1; 192 | @(posedge Clk) #0.9 En = 0; 193 | @(posedge Valid) #0.1; 194 | if((Sum != ALU) || (Co != C) || (OV != V)) begin 195 | $display("Error: Incorrect Result"); 196 | $display("\tA: 0x%2h, B: 0x%2h, Ci: %b", A, B, Ci); 197 | $display("\t\t{NVZC, ALU}: %b%b%b%b, 0x%2h", N, V, Z, C, ALU); 198 | $display("\t\t{-V-C, Sum}: -%b-%b, 0x%2h", OV, Co, Sum); 199 | $display("End Decimal Mode Subtraction Test: Fail"); 200 | $stop; 201 | end 202 | @(posedge Clk) #1; 203 | Ci = 0; 204 | En = 1; 205 | @(posedge Clk) #0.9 En = 0; 206 | @(posedge Valid) #0.1; 207 | if((Sum != ALU) || (Co != C) || (OV != V)) begin 208 | $display("Error: Incorrect Result"); 209 | $display("\tA: 0x%2h, B: 0x%2h, Ci: %b", A, B, Ci); 210 | $display("\t\t{NVZC, ALU}: %b%b%b%b, 0x%2h", N, V, Z, C, ALU); 211 | $display("\t\t{-V-C, Sum}: -%b-%b, 0x%2h", OV, Co, Sum); 212 | $display("End Decimal Mode Subtraction Test: Fail"); 213 | $stop; 214 | end 215 | @(posedge Clk) #1; 216 | end 217 | end 218 | 219 | $display("End Decimal Mode Subtraction Test: Pass"); 220 | 221 | // // Binary Tests 222 | // 223 | // $display("Start Binary Mode Addition Test"); 224 | // 225 | // En = 0; Op = 0; // ADC Test 226 | // 227 | // for(i = 0; i < 256; i = i + 1) begin 228 | // A = i; 229 | // for(j = 0; j < 256; j = j + 1) begin 230 | // B = j; 231 | // Ci = 0; 232 | // #5; 233 | // if((Sum != ALU) || (Co != C) || (OV != V)) begin 234 | // $display("Error: Incorrect Result"); 235 | // $display("\tQ: 0x%2h, R: 0x%2h, Ci: %b", Q, R, Ci); 236 | // $display("\t\t{NVZC, ALU}: %b%b%b%b, 0x%2h", N, V, Z, C, ALU); 237 | // $display("\t\t{-V-C, Sum}: -%b-%b, 0x%2h", OV, Co, Sum); 238 | // $display("End Binary Mode Addition Test: Fail"); 239 | // $stop; 240 | // end 241 | // #5; 242 | // Ci = 1; 243 | // #5; 244 | // if((Sum != ALU) || (Co != C) || (OV != V)) begin 245 | // $display("Error: Incorrect Result"); 246 | // $display("\tQ: 0x%2h, R: 0x%2h, Ci: %b", Q, R, Ci); 247 | // $display("\t\t{NVZC, ALU}: %b%b%b%b, 0x%2h", N, V, Z, C, ALU); 248 | // $display("\t\t{-V-C, Sum}: -%b-%b, 0x%2h", OV, Co, Sum); 249 | // $display("End Decimal Mode Addition Test: Fail"); 250 | // $stop; 251 | // end 252 | // #5; 253 | // end 254 | // end 255 | // 256 | // $display("End Binary Mode Addition Test: Pass"); 257 | // 258 | // // Binary Mode 259 | // 260 | // $display("Start Binary Mode Subtraction Test"); 261 | // 262 | // En = 0; Op = 1; // SBC Test 263 | // 264 | // for(i = 0; i < 256; i = i + 1) begin 265 | // A = i; 266 | // for(j = 0; j < 256; j = j + 1) begin 267 | // B = ~j; 268 | // Ci = 1; 269 | // #5; 270 | // if((Sum != ALU) || (Co != C) || (OV != V)) begin 271 | // $display("Error: Incorrect Result"); 272 | // $display("\tQ: 0x%2h, R: 0x%2h, Ci: %b", Q, R, Ci); 273 | // $display("\t\t{NVZC, ALU}: %b%b%b%b, 0x%2h", N, V, Z, C, ALU); 274 | // $display("\t\t{-V-C, Sum}: -%b-%b, 0x%2h", OV, Co, Sum); 275 | // $display("End Binary Mode Subtraction Test: Fail"); 276 | // $stop; 277 | // end 278 | // #5; 279 | // Ci = 0; 280 | // #5; 281 | // if((Sum != ALU) || (Co != C) || (OV != V)) begin 282 | // $display("Error: Incorrect Result"); 283 | // $display("\tQ: 0x%2h, R: 0x%2h, Ci: %b", Q, R, Ci); 284 | // $display("\t\t{NVZC, ALU}: %b%b%b%b, 0x%2h", N, V, Z, C, ALU); 285 | // $display("\t\t{-V-C, Sum}: -%b-%b, 0x%2h", OV, Co, Sum); 286 | // $display("End Decimal Mode Subtraction Test: Fail"); 287 | // $stop; 288 | // end 289 | // #5; 290 | // end 291 | // end 292 | // 293 | // $display("End Binary Mode Subtraction Test: Pass"); 294 | // 295 | // $display("End Adder Tests: Pass"); 296 | 297 | $stop; 298 | 299 | end 300 | 301 | /////////////////////////////////////////////////////////////////////////////// 302 | // 303 | // System Clk 304 | 305 | always #5 Clk = ~Clk; 306 | 307 | /////////////////////////////////////////////////////////////////////////////// 308 | // 309 | // BCD Mode Adder Model 310 | // 311 | 312 | always @(*) 313 | begin 314 | // if(D) begin 315 | if(Sub) begin 316 | LSN[4:0] <= {1'b0, A[3:0]} + {1'b0, B[3:0]} + {4'b0, Ci}; 317 | C3 <= LSN[4] & ~(LSN[3] & (LSN[2] | LSN[1])); 318 | ALU[3:0] <= ((C3) ? (LSN[3:0] + 0) : (LSN[3:0] + 10)); 319 | 320 | MSN[4:0] <= {1'b0, A[7:4]} + {1'b0, B[7:4]} + {4'b0, C3}; 321 | C7 <= MSN[4] & ~(MSN[3] & (MSN[2] | MSN[1])); 322 | ALU[7:4] <= ((C7) ? (MSN[3:0] + 0) : (MSN[3:0] + 10)); 323 | end else begin 324 | LSN[4:0] <= {1'b0, A[3:0]} + {1'b0, B[3:0]} + {4'b0, Ci}; 325 | C3 <= LSN[4] | (LSN[3] & (LSN[2] | LSN[1])); 326 | ALU[3:0] <= ((C3) ? (LSN[3:0] + 6) : (LSN[3:0] + 0)); 327 | 328 | MSN[4:0] <= {1'b0, A[7:4]} + {1'b0, B[7:4]} + {4'b0, C3}; 329 | C7 <= MSN[4] | (MSN[3] & (MSN[2] | MSN[1])); 330 | ALU[7:4] <= ((C7) ? (MSN[3:0] + 6) : (MSN[3:0] + 0)); 331 | end 332 | 333 | N <= ALU[7]; V <= ((Sub) ? ~C7 : C7); Z <= ~|ALU; C <= C7; 334 | // end else begin 335 | // LSN[4:0] <= {1'b0, A[3:0]} + {1'b0, B[3:0]} + {4'b0, Ci}; 336 | // C3 <= LSN[4]; 337 | // ALU[3:0] <= LSN[3:0]; 338 | // 339 | // MSN[3:0] <= {1'b0, A[6:4]} + {1'b0, B[6:4]} + {4'b0, C3}; 340 | // MSN[4] <= (MSN[3] & (A[7] ^ B[7]) | (A[7] & B[7])); 341 | // C7 <= MSN[4]; 342 | // ALU[7:4] <= {A[7] ^ B[7] ^ MSN[3], MSN[2:0]}; 343 | // 344 | // N <= ALU[7]; V <= (MSN[4] ^ MSN[3]); Z <= ~|ALU; C <= C7; 345 | // end 346 | end 347 | 348 | endmodule 349 | 350 | -------------------------------------------------------------------------------- /Sim/tb_M65C02_RAM.v: -------------------------------------------------------------------------------- 1 | /////////////////////////////////////////////////////////////////////////////// 2 | // 3 | // Copyright 2006-2012 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 an 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 & Assoc. 42 | // Engineer: Michael A. Morris 43 | // 44 | // Create Date: 23:07:42 02/04/2012 45 | // Design Name: M65C02_RAM 46 | // Module Name: C:/XProjects/ISE10.1i/MAM6502/tb_M65C02_RAM.v 47 | // Project Name: MAM6502 48 | // Target Device: Generic functional simulation of various RAM technologies 49 | // Tool versions: ISE 10.1i SP3 50 | // 51 | // Description: 52 | // 53 | // Verilog Test Fixture created by ISE for module: M65C02_RAM 54 | // 55 | // Dependencies: 56 | // 57 | // Revision: 58 | // 59 | // 1.00 12B04 MAM File Created 60 | // 61 | // 2.00 12K18 MAM Modified to support new version of the M65C02_RAM 62 | // module which emulates Asynchronous LUT-based RAM, 63 | // Synchronous, flow-through RAM (Block RAM), and 64 | // Synchronous, pipelined RAM (SynchSRAM). 65 | // 66 | // Additional Comments: 67 | // 68 | //////////////////////////////////////////////////////////////////////////////// 69 | 70 | module tb_M65C02_RAM; 71 | 72 | reg Rst; 73 | reg Clk; 74 | 75 | reg WE; 76 | wire [10:0] AI; 77 | reg [ 7:0] DI; 78 | wire [ 7:0] DO; 79 | 80 | // Simulation Variables 81 | 82 | reg [10:0] Cntr; 83 | wire TC_Cntr; 84 | reg Ext, ZP; 85 | 86 | // Instantiate the Unit Under Test (UUT) 87 | 88 | M65C02_RAM #( 89 | .pAddrSize(11), 90 | .pDataSize(8), 91 | .pFileName("M65C02_Tst2.txt") 92 | ) RAM ( 93 | .Clk(Clk), 94 | 95 | .Ext(Ext), 96 | .ZP(ZP), 97 | 98 | .WE(WE), 99 | .AI(Cntr), 100 | .DI(DI), 101 | .DO(DO) 102 | ); 103 | 104 | initial begin 105 | // Initialize Inputs 106 | Rst = 1; 107 | Clk = 1; 108 | WE = 0; 109 | DI = 0; 110 | 111 | // Wait 100 ns for global reset to finish 112 | #101 Rst = 0; 113 | 114 | // Add stimulus here 115 | 116 | end 117 | 118 | /////////////////////////////////////////////////////////////////////////////// 119 | // 120 | // Clocks 121 | 122 | always #5 Clk = ~Clk; 123 | 124 | /////////////////////////////////////////////////////////////////////////////// 125 | 126 | always @(posedge Clk) 127 | begin 128 | if(Rst | TC_Cntr) 129 | Cntr = #1 0; 130 | else 131 | Cntr = #1 Cntr + 1; 132 | end 133 | 134 | assign TC_Cntr = (Cntr == 11'h661); // Last used location in test program 135 | 136 | assign AI = Cntr; 137 | 138 | // Cycle through the various modes 139 | 140 | always @(posedge Clk) 141 | begin 142 | if(Rst) 143 | {Ext, ZP} <= #1 1; 144 | else if(TC_Cntr) 145 | {Ext, ZP} <= #1 ({Ext, ZP} + 1); 146 | end 147 | 148 | endmodule 149 | 150 | -------------------------------------------------------------------------------- /Src/M65C02-Test-Programs/Klaus2m5_Functional_Tests/65c02_ft.bat: -------------------------------------------------------------------------------- 1 | ..\as65\as65 -cmntvw132h58z -l -o65c02_ft.bin 65c02_ft 2 | bin2txt 65c02_ft.bin 65c02_ft.txt 3 | copy 65c02_ft.txt c:\XProjects\ISE10.1i\M65C02A\Pgms\65C02_ft.txt /y 4 | -------------------------------------------------------------------------------- /Src/M65C02-Test-Programs/Klaus2m5_Functional_Tests/65c02_ft.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MorrisMA/MAM65C02-Processor-Core/dabbc3f44616cdb0898375d68b9f36e11fd21081/Src/M65C02-Test-Programs/Klaus2m5_Functional_Tests/65c02_ft.bin -------------------------------------------------------------------------------- /Src/M65C02-Test-Programs/M65C02_Tst.a65: -------------------------------------------------------------------------------- 1 | ; #------------------------------------------------------------------------# 2 | ; | | 3 | ; | MAM6502_Tst.A65 | 4 | ; | | 5 | ; | Test program for MAM6502_Core.v | 6 | ; | | 7 | ; | Copyright 2012, Michael A. Morris | 8 | ; | | 9 | ; #------------------------------------------------------------------------# 10 | ; 11 | ; File created 11-Feb-2012 12 | 13 | title "AS65 test source - MAM6502_Core" 14 | 15 | data 16 | org 0 17 | 18 | Jmp_AbsI dw AbsI_Dst 19 | Jmp_AbsXI dw AbsXI_Dst 20 | 21 | bss 22 | org 256 23 | 24 | code 25 | org 16 26 | Start jmp Abs_Dst 27 | Return rts 28 | Abs_Dst jmp (Jmp_AbsI) 29 | AbsI_Dst jmp (Jmp_AbsXI, x) 30 | AbsXI_Dst jsr Return 31 | nop 32 | ora #$AA 33 | pha 34 | pla 35 | tax 36 | eor #$55 37 | tay 38 | phy 39 | plx 40 | txa 41 | pha 42 | phx 43 | phy 44 | lda #0 45 | tax 46 | tay 47 | jmp Start 48 | 49 | end Start -------------------------------------------------------------------------------- /Src/M65C02-Test-Programs/M65C02_Tst5.a65: -------------------------------------------------------------------------------- 1 | BROM_Start equ $F800 2 | 3 | SPI_CR equ $F7FF 4 | 5 | ZP_LED_Cntr equ $00FD 6 | ZP_Cntr_Lo equ $00FE 7 | ZP_Cntr_Hi equ $00FF 8 | 9 | bss 10 | ;; 11 | Zero_Page: org $0000 12 | ;; 13 | Stack_Page: org $0100 14 | ;; 15 | RAM_Start: org $0200 16 | ;; 17 | code 18 | org BROM_Start 19 | ;; 20 | Start: lda #$00 ;; load initial value to control register 21 | sta ZP_LED_Cntr 22 | sta SPI_CR ;; update LEDs 23 | ;; 24 | Delay_Loop: ldy #$04 ;; load outer delay loop counter 25 | sty ZP_Cntr_Hi 26 | ;; 27 | Delay_Lp1: ldx #$00 ;; load inner delay loop counter 28 | stx ZP_Cntr_Lo 29 | ;; 30 | ;Delay_Lp2: dex ;; decrement inner loop counter 31 | Delay_Lp2: dec ZP_Cntr_Lo ;; decrement inner loop counter 32 | bne Delay_Lp2 ;; loop until inner loop counter is zero 33 | ;; 34 | ; dey ;; decrement external loop counter 35 | dec ZP_Cntr_Hi 36 | bne Delay_Lp1 ;; loop until outer loop counter is zero 37 | ;; 38 | ; dec a ;; decrement accumulator 39 | dec ZP_LED_Cntr 40 | lda ZP_LED_Cntr 41 | sta SPI_CR ;; update LEDs 42 | 43 | bra Delay_Loop ;; Loop Continously 44 | ;; 45 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 46 | ;; 47 | Last_Addrs: 48 | ;; 49 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 50 | ;; 51 | ;; Vector Table 52 | ;; 53 | Vect_Table: org $FFFA 54 | ;; 55 | dw Start ;; NMI Interrupt Vector 56 | dw Start ;; Reset Vector 57 | dw Start ;; IRQ/BRK Interrupt Vector 58 | ;; 59 | end Start 60 | -------------------------------------------------------------------------------- /Src/M65C02-Test-Programs/m65c02.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MorrisMA/MAM65C02-Processor-Core/dabbc3f44616cdb0898375d68b9f36e11fd21081/Src/M65C02-Test-Programs/m65c02.bin -------------------------------------------------------------------------------- /Src/M65C02-Test-Programs/m65c02_tst5.lst: -------------------------------------------------------------------------------- 1 | AS65 Assembler for R6502 [1.42]. Copyright 1994-2007, Frank A. Kingswood Page 1 2 | --------------------------------------------------------- m65c02_tst5.a65 --------------------------------------------------------- 3 | 4 | ---------------------------------------------------------- Symbol Table ----------------------------------------------------------- 5 | 6 | Symbol Value Decimal 7 | 8 | BROM_Start : $f800 63488 9 | Delay_Loop : $f807 63495 10 | Delay_Lp1 : $f80b 63499 11 | Delay_Lp2 : $f80f 63503 12 | Last_Addrs : $f820 63520 13 | SPI_CR : $f7ff 63487 14 | Start : $f800 63488 15 | ZP_Cntr_Hi : $00ff 255 16 | ZP_Cntr_Lo : $00fe 254 17 | ZP_LED_Cntr : $00fd 253 18 | __65SC02__ : $0001 1 19 | 20 | 11 labels used 21 | 22 | 59 lines read, no errors in pass 1. 23 | AS65 Assembler for R6502 [1.42]. Copyright 1994-2007, Frank A. Kingswood Page 2 24 | --------------------------------------------------------- m65c02_tst5.a65 --------------------------------------------------------- 25 | 26 | f800 = BROM_Start equ $F800 27 | 28 | f7ff = SPI_CR equ $F7FF 29 | 30 | 00fd = ZP_LED_Cntr equ $00FD 31 | 00fe = ZP_Cntr_Lo equ $00FE 32 | 00ff = ZP_Cntr_Hi equ $00FF 33 | 34 | bss 35 | ;; 36 | 0000 = Zero_Page: org $0000 37 | ;; 38 | 0100 = Stack_Page: org $0100 39 | ;; 40 | 0200 = RAM_Start: org $0200 41 | ;; 42 | code 43 | f800 = org BROM_Start 44 | ;; 45 | f800 : a900 [ 2] Start: lda #$00 ;; load initial value to control register 46 | f802 : 85fd [ 3] sta ZP_LED_Cntr 47 | f804 : 8dfff7 [ 4] sta SPI_CR ;; update LEDs 48 | ;; 49 | f807 : a004 [ 2] Delay_Loop: ldy #$04 ;; load outer delay loop counter 50 | f809 : 84ff [ 3] sty ZP_Cntr_Hi 51 | ;; 52 | f80b : a200 [ 2] Delay_Lp1: ldx #$00 ;; load inner delay loop counter 53 | f80d : 86fe [ 3] stx ZP_Cntr_Lo 54 | ;; 55 | ;Delay_Lp2: dex ;; decrement inner loop counter 56 | f80f : c6fe [ 5] Delay_Lp2: dec ZP_Cntr_Lo ;; decrement inner loop counter 57 | f811 : d0fc [ 3] bne Delay_Lp2 ;; loop until inner loop counter is zero 58 | ;; 59 | ; dey ;; decrement external loop counter 60 | f813 : c6ff [ 5] dec ZP_Cntr_Hi 61 | f815 : d0f4 [ 3] bne Delay_Lp1 ;; loop until outer loop counter is zero 62 | ;; 63 | ; dec a ;; decrement accumulator 64 | f817 : c6fd [ 5] dec ZP_LED_Cntr 65 | f819 : a5fd [ 3] lda ZP_LED_Cntr 66 | f81b : 8dfff7 [ 4] sta SPI_CR ;; update LEDs 67 | 68 | f81e : 80e7 [ 3] bra Delay_Loop ;; Loop Continously 69 | ;; 70 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 71 | ;; 72 | f820 : Last_Addrs: 73 | ;; 74 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 75 | ;; 76 | ;; Vector Table 77 | ;; 78 | fffa = Vect_Table: org $FFFA 79 | ;; 80 | fffa : 00f8 dw Start ;; NMI Interrupt Vector 81 | AS65 Assembler for R6502 [1.42]. Copyright 1994-2007, Frank A. Kingswood Page 3 82 | --------------------------------------------------------- m65c02_tst5.a65 --------------------------------------------------------- 83 | 84 | fffc : 00f8 dw Start ;; Reset Vector 85 | fffe : 00f8 dw Start ;; IRQ/BRK Interrupt Vector 86 | ;; 87 | fffa = end Start 88 | 89 | No errors in pass 2. 90 | Wrote binary from address $f800 through $ffff. 91 | Total size 2048 bytes. 92 | Program start address is at $f800 (63488). 93 | -------------------------------------------------------------------------------- /Src/M65C02-Test-Programs/m65c02v5.bat: -------------------------------------------------------------------------------- 1 | ..\as65\as65 -cmntvw132h58xz -l -om65c02.bin m65c02_tst3 2 | bin2txt m65c02.bin m65c02.txt 3 | copy m65c02.txt c:\XProjects\ISE10.1i\M65C02\M65C02_Tst3.txt 4 | -------------------------------------------------------------------------------- /Src/M65C02-Test-Programs/m65c02v7.bat: -------------------------------------------------------------------------------- 1 | ..\as65\as65 -cmntvw132h58xz -l -om65c02.bin m65c02_tst5 2 | bin2txt m65c02.bin m65c02v5.txt 3 | copy m65c02v5.txt c:\XProjects\ISE10.1i\M65C02\M65C02_Tst5.txt 4 | -------------------------------------------------------------------------------- /Src/Memory-Images/M65C02_Decoder_ROM.coe: -------------------------------------------------------------------------------- 1 | 01000000000001100001011100000000 2 | 11000010000000010001100100000001 3 | 00100000000000000000000000000010 4 | 00100000000000000000000000000011 5 | 11011110000001100001100000000100 6 | 11000010000000010001100100000101 7 | 11011000010001100001101000000110 8 | 11010000010000000000010111111110 9 | 10000000000000001100000000001000 10 | 11000010000000010001100100001001 11 | 10101000000000010001101000001010 12 | 00100000000000000000000000001011 13 | 11011110000001100001100000001100 14 | 11000010000000010001100100001101 15 | 11011000010001100001101000001110 16 | 01100000010000000000011100000001 17 | 01100000000000000000111000010000 18 | 11000010000000010001100100010001 19 | 11000010000000010001100100010010 20 | 00100000000000000000000000010011 21 | 11011101010001100001100000010100 22 | 11000010000000010001100100010101 23 | 11011000010001100001101000010110 24 | 11010000010000000000010111111101 25 | 10100000000001100001000000011000 26 | 11000010000000010001100100011001 27 | 10100110001010010001100100011010 28 | 00100000000000000000000000011011 29 | 11011101000001100001100000011100 30 | 11000010000000010001100100011101 31 | 11011000010001100001101000011110 32 | 01100000010000000000011100000010 33 | 01100000000000000000000000100000 34 | 11000001000000010001100100100001 35 | 00100000000000000000000000100010 36 | 00100000000000000000000000100011 37 | 11001100000001100001101100100100 38 | 11000001000000010001100100100101 39 | 11011010010001100001101000100110 40 | 11010000010000000000010111111011 41 | 10000000000001100001111100101000 42 | 11000001000000010001100100101001 43 | 10101010000000010001101000101010 44 | 00100000000000000000000000101011 45 | 11001100000001100001101100101100 46 | 11000001000000010001100100101101 47 | 11011010010001100001101000101110 48 | 01100000010000000000011100000100 49 | 01100000000000000000111100110000 50 | 11000001000000010001100100110001 51 | 11000001000000010001100100110010 52 | 00100000000000000000000000110011 53 | 11001100000001100001101100110100 54 | 11000001000000010001100100110101 55 | 11011010010001100001101000110110 56 | 11010000010000000000010111110111 57 | 10100001000001100001000100111000 58 | 11000001000000010001100100111001 59 | 10100111001110010001100100111010 60 | 00100000000000000000000000111011 61 | 11001100000001100001101100111100 62 | 11000001000000010001100100111101 63 | 11011010010001100001101000111110 64 | 01100000010000000000011100001000 65 | 01100000000001100001111101000000 66 | 11000011000000010001100101000001 67 | 00100000000000000000000001000010 68 | 00100000000000000000000001000011 69 | 00100000000000000000000001000100 70 | 11000011000000010001100101000101 71 | 11011001010001100001101001000110 72 | 11010000010000000000010111101111 73 | 10000000000000000010000001001000 74 | 11000011000000010001100101001001 75 | 10101001000000010001101001001010 76 | 00100000000000000000000001001011 77 | 01100000000000000000000001001100 78 | 11000011000000010001100101001101 79 | 11011001010001100001101001001110 80 | 01100000010000000000011100010000 81 | 01100000000000000000110001010000 82 | 11000011000000010001100101010001 83 | 11000011000000010001100101010010 84 | 00100000000000000000000001010011 85 | 00100000000000000000000001010100 86 | 11000011000000010001100101010101 87 | 11011001010001100001101001010110 88 | 11010000010000000000010111011111 89 | 10100000000001100001001001011000 90 | 11000011000000010001100101011001 91 | 10000000000000000110000001011010 92 | 00100000000000000000000001011011 93 | 00100000000000000000000001011100 94 | 11000011000000010001100101011101 95 | 11011001010001100001101001011110 96 | 01100000010000000000011100100000 97 | 01100000000000000000000001100000 98 | 11000100000000010001110001100001 99 | 00100000000000000000000001100010 100 | 00100000000000000000000001100011 101 | 11000000000000001000000001100100 102 | 11000100000000010001110001100101 103 | 11011011010001100001101001100110 104 | 00110000010000000000010110111111 105 | 10000000000000010001100101101000 106 | 11000100000000010001110001101001 107 | 11001011000000010001101001101010 108 | 00100000000000000000000001101011 109 | 01100000000000000000000001101100 110 | 11000100000000010001110001101101 111 | 11011011010001100001101001101110 112 | 01100000010000000000011101000000 113 | 01100000000000000000110101110000 114 | 11000100000000010001110001110001 115 | 11000100000000010001110001110010 116 | 00100000000000000000000001110011 117 | 11000000000000001000000001110100 118 | 11000100000000010001110001110101 119 | 11011011010001100001101001110110 120 | 11010000010000000000010101111111 121 | 10100000000001100001001101111000 122 | 11000100000000010001110001111001 123 | 10000000010000110001100101111010 124 | 00100000000000000000000001111011 125 | 01100000000000000000000001111100 126 | 11000100000000010001110001111101 127 | 11011011010001100001101001111110 128 | 01100000010000000000011110000000 129 | 01100000000000000000000010000000 130 | 11000000000000000010000010000001 131 | 00100000000000000000000010000010 132 | 00100000000000000000000010000011 133 | 11000000000000000110000010000100 134 | 11000000000000000010000010000101 135 | 11000000000000000100000010000110 136 | 11010000010000000000010000000001 137 | 10100111111110110111100110001000 138 | 11001100000001100001100010001001 139 | 10100000000000010101100110001010 140 | 00100000000000000000000010001011 141 | 11000000000000000110000010001100 142 | 11000000000000000010000010001101 143 | 11000000000000000100000010001110 144 | 01100000010000000000011000000001 145 | 01100000000000000000100010010000 146 | 11000000000000000010000010010001 147 | 11000000000000000010000010010010 148 | 00100000000000000000000010010011 149 | 11000000000000000110000010010100 150 | 11000000000000000010000010010101 151 | 11000000000000000100000010010110 152 | 11010000010000000000010000000010 153 | 10100000000000010111100110011000 154 | 11000000000000000010000010011001 155 | 10100000000001010100000010011010 156 | 00100000000000000000000010011011 157 | 11000000000000001000000010011100 158 | 11000000000000000010000010011101 159 | 11000000000000001000000010011110 160 | 01100000010000000000011000000010 161 | 11000000000000110001100110100000 162 | 11000000000000010001100110100001 163 | 11000000000000100001100110100010 164 | 00100000000000000000000010100011 165 | 11000000000000110001100110100100 166 | 11000000000000010001100110100101 167 | 11000000000000100001100110100110 168 | 11010000010000000000010000000100 169 | 10100000000000110011100110101000 170 | 11000000000000010001100110101001 171 | 10100000000000100011100110101010 172 | 00100000000000000000000010101011 173 | 11000000000000110001100110101100 174 | 11000000000000010001100110101101 175 | 11000000000000100001100110101110 176 | 01100000010000000000011000000100 177 | 01100000000000000000100110110000 178 | 11000000000000010001100110110001 179 | 11000000000000010001100110110010 180 | 00100000000000000000000010110011 181 | 11000000000000110001100110110100 182 | 11000000000000010001100110110101 183 | 11000000000000100001100110110110 184 | 11010000010000000000010000001000 185 | 10100000000001100001011010111000 186 | 11000000000000010001100110111001 187 | 10100000000000101011100110111010 188 | 00100000000000000000000010111011 189 | 11000000000000110001100110111100 190 | 11000000000000010001100110111101 191 | 11000000000000100001100110111110 192 | 01100000010000000000011000001000 193 | 11001111110111100001101011000000 194 | 11001111000111100001101011000001 195 | 00100000000000000000000011000010 196 | 00100000000000000000000011000011 197 | 11001111110111100001101011000100 198 | 11001111000111100001101011000101 199 | 11010111011111100001100111000110 200 | 11010000010000000000010000010000 201 | 10100110111010110001100111001000 202 | 11001111000111100001101011001001 203 | 10100111101110100001100111001010 204 | 11100000000000000000000011001011 205 | 11001111110111100001101011001100 206 | 11001111000111100001101011001101 207 | 11010111011111100001100111001110 208 | 01100000010000000000011000010000 209 | 01100000000000000000101011010000 210 | 11001111000111100001101011010001 211 | 11001111000111100001101011010010 212 | 00100000000000000000000011010011 213 | 00100000000000000000000011010100 214 | 11001111000111100001101011010101 215 | 11010111011111100001100111010110 216 | 11010000010000000000010000100000 217 | 10100000000001100001010011011000 218 | 11001111000111100001101011011001 219 | 10000000000000000100000011011010 220 | 00000000000000000000000011011011 221 | 00100000000000000000000011011100 222 | 11001111000111100001101011011101 223 | 11010111011111100001100111011110 224 | 01100000010000000000011000100000 225 | 11001111100111100001101011100000 226 | 11000101000100010001110011100001 227 | 00100000000000000000000011100010 228 | 00100000000000000000000011100011 229 | 11001111100111100001101011100100 230 | 11000101000100010001110011100101 231 | 11010110011011100001100111100110 232 | 11010000010000000000010001000000 233 | 10100110101010100001100111101000 234 | 11000101000100010001110011101001 235 | 10100000000000000000000011101010 236 | 00100000000000000000000011101011 237 | 11001111100111100001101011101100 238 | 11000101000100010001110011101101 239 | 11010110011011100001100111101110 240 | 01100000010000000000011001000000 241 | 01100000000000000000101111110000 242 | 11000101000100010001110011110001 243 | 11000101000100010001110011110010 244 | 00100000000000000000000011110011 245 | 00100000000000000000000011110100 246 | 11000101000100010001110011110101 247 | 11010110011011100001100111110110 248 | 11010000010000000000010010000000 249 | 10100000000001100001010111111000 250 | 11000101000100010001110011111001 251 | 10000000010000100001100111111010 252 | 00100000000000000000000011111011 253 | 00100000000000000000000011111100 254 | 11000101000100010001110011111101 255 | 11010110011011100001100111111110 256 | 01100000010000000000011010000000 257 | -------------------------------------------------------------------------------- /Src/Memory-Images/M65C02_uPgm_V3.coe: -------------------------------------------------------------------------------- 1 | 01100000000011010000001100000000 2 | 00100000000011000000001010000000 3 | 00100000000101000011101001000000 4 | 01010000000111010000011111000000 5 | 00000000000000000000000000000000 6 | 00000000000000000000000000000000 7 | 00000000000000000000000000000000 8 | 00000000000000000000000000000000 9 | 00000000000000000000000000000000 10 | 00000000000000000000000000000000 11 | 00000000000000000000000000000000 12 | 00000000000000000000000000000000 13 | 00000000000000000000000000000000 14 | 00000000000000000000000000000000 15 | 00000000000000000000000000000000 16 | 00000000000000000000000000000000 17 | 00000000000000000000000000000000 18 | 00000000000000000000000000000000 19 | 00000000000000000000000000000000 20 | 00000000000000000000000000000000 21 | 00000000000000000000000000000000 22 | 00000000000000000000000000000000 23 | 00000000000000000000000000000000 24 | 00000000000000000000000000000000 25 | 00000000000000000000000000000000 26 | 00000000000000000000000000000000 27 | 00000000000000000000000000000000 28 | 00000000000000000000000000000000 29 | 00000000000000000000000000000000 30 | 00000000000000000000000000000000 31 | 00000000000000000000000000000000 32 | 00000000000000000000000000000000 33 | 01010001000001010000011111001000 34 | 01100001000101010100000101101000 35 | 00100001000101000100000110100000 36 | 00100001000111000100100111100001 37 | 00100001001001001000001010000000 38 | 00100001001011000011101001000000 39 | 01010001001101010000011111000000 40 | 00100001001111000000001101000000 41 | 00100001010001000100000101100000 42 | 01000001000001000100100110100000 43 | 00100001010101000100001010111100 44 | 00100001010111000100101001110000 45 | 01010001011001010000011111000000 46 | 01000001000001000100101001110000 47 | 01000001000001000000101101000000 48 | 00100001011111000000011101000000 49 | 00100001100001001000001010000000 50 | 01000001000001000011101001000000 51 | 00100001100101000000011101000000 52 | 00100001100111001110001010000000 53 | 01000001000001000011101001000000 54 | 00110001000001000101001010000000 55 | 00110001000001000110001010000000 56 | 00110001000001000111001010000000 57 | 00100001110001000101001010000000 58 | 00100001110011000011001001000000 59 | 00110001000001001000001010000000 60 | 00100001110111000110001010000000 61 | 00100001111001000011001001000000 62 | 00110001000001001000001010000000 63 | 00100001111101000101001010000000 64 | 00100001111111000011001001000000 65 | 00110001000001001111001010000000 66 | 00100010000011000000011101000000 67 | 00110001000001001000001010000000 68 | 00100010000111000000011101000000 69 | 00110001000001001110001010000000 70 | 00100010001011000000011101000000 71 | 00110001000001001111001010000000 72 | 00110001000001000101000100000000 73 | 00110001000001000110000100000000 74 | 00110001000001000111000100000000 75 | 00100010010101000101001010000000 76 | 00100010010111000011001001000000 77 | 00110001000001001000000100000000 78 | 00100010011011000110001010000000 79 | 00100010011101000011001001000000 80 | 00110001000001001000000100000000 81 | 00100010100001000101001010000000 82 | 00100010100011000011001001000000 83 | 00110001000001001111000100000000 84 | 00100010100111000000011101000000 85 | 00110001000001001000000100000000 86 | 00100010101011000000011101000000 87 | 00110001000001001110000100000000 88 | 00100010101111000000011101000000 89 | 00110001000001001111000100000000 90 | 00000000000000000000000000000000 91 | 00000000000000000000000000000000 92 | 00000000000000000000000000000000 93 | 00000000000000000000000000000000 94 | 00000000000000000000000000000000 95 | 00000000000000000000000000000000 96 | 00000000000000000000000000000000 97 | 01010011000001010000011111000000 98 | 01100001000101010100000101100000 99 | 00100011000101000101001010000000 100 | 00110011000001000010000100001000 101 | 00100011001001000110001010000000 102 | 00110011000001000010000100001000 103 | 00100011001101000111001010000000 104 | 00110011000001000010000100001000 105 | 00100011010001000000011101000000 106 | 00100011010011001000001010000000 107 | 00110011000001000010000100001000 108 | 00100011010111000000011101000000 109 | 00100011011001001110001010000000 110 | 00110011000001000010000100001000 111 | 00100011011101000000011101000000 112 | 00100011011111001111001010000000 113 | 00110011000001000010000100001000 114 | 00100011100011000101001010000000 115 | 01000001000001000000111110000000 116 | 00000000000000000000000000000000 117 | 00000000000000000000000000000000 118 | 00000000000000000000000000000000 119 | 00000000000000000000000000000000 120 | 00000000000000000000000000000000 121 | 00000000000000000000000000000000 122 | 00000000000000000000000000000000 123 | 00000000000000000000000000000000 124 | 00000000000000000000000000000000 125 | 00000000000000000000000000000000 126 | 00000000000000000000000000000000 127 | 00000000000000000000000000000000 128 | 00000000000000000000000000000000 129 | 00000000000000000000000000000000 130 | 00000000000000000000000000000000 131 | 00000000000000000000000000000000 132 | 00000000000000000000000000000000 133 | 00000000000000000000000000000000 134 | 00000000000000000000000000000000 135 | 00000000000000000000000000000000 136 | 00000000000000000000000000000000 137 | 00000000000000000000000000000000 138 | 00000000000000000000000000000000 139 | 00000000000000000000000000000000 140 | 00000000000000000000000000000000 141 | 00000000000000000000000000000000 142 | 00000000000000000000000000000000 143 | 00000000000000000000000000000000 144 | 00000000000000000000000000000000 145 | 00000000000000000000000000000000 146 | 00000000000000000000000000000000 147 | 00000000000000000000000000000000 148 | 00000000000000000000000000000000 149 | 00000000000000000000000000000000 150 | 00000000000000000000000000000000 151 | 00000000000000000000000000000000 152 | 00000000000000000000000000000000 153 | 00000000000000000000000000000000 154 | 00000000000000000000000000000000 155 | 00000000000000000000000000000000 156 | 00000000000000000000000000000000 157 | 00000000000000000000000000000000 158 | 00000000000000000000000000000000 159 | 00000000000000000000000000000000 160 | 00000000000000000000000000000000 161 | 00000000000000000000000000000000 162 | 00000000000000000000000000000000 163 | 00000000000000000000000000000000 164 | 00000000000000000000000000000000 165 | 00000000000000000000000000000000 166 | 00000000000000000000000000000000 167 | 00000000000000000000000000000000 168 | 00000000000000000000000000000000 169 | 00000000000000000000000000000000 170 | 00000000000000000000000000000000 171 | 00000000000000000000000000000000 172 | 00000000000000000000000000000000 173 | 00000000000000000000000000000000 174 | 00000000000000000000000000000000 175 | 00000000000000000000000000000000 176 | 00000000000000000000000000000000 177 | 00000000000000000000000000000000 178 | 00000000000000000000000000000000 179 | 00000000000000000000000000000000 180 | 00000000000000000000000000000000 181 | 00000000000000000000000000000000 182 | 00000000000000000000000000000000 183 | 00000000000000000000000000000000 184 | 00000000000000000000000000000000 185 | 00000000000000000000000000000000 186 | 00000000000000000000000000000000 187 | 00000000000000000000000000000000 188 | 00000000000000000000000000000000 189 | 00000000000000000000000000000000 190 | 00000000000000000000000000000000 191 | 00000000000000000000000000000000 192 | 00000000000000000000000000000000 193 | 00000000000000000000000000000000 194 | 00000000000000000000000000000000 195 | 00000000000000000000000000000000 196 | 00000000000000000000000000000000 197 | 00000000000000000000000000000000 198 | 00000000000000000000000000000000 199 | 00000000000000000000000000000000 200 | 00000000000000000000000000000000 201 | 00000000000000000000000000000000 202 | 00000000000000000000000000000000 203 | 00000000000000000000000000000000 204 | 00000000000000000000000000000000 205 | 00000000000000000000000000000000 206 | 00000000000000000000000000000000 207 | 00000000000000000000000000000000 208 | 00000000000000000000000000000000 209 | 00000000000000000000000000000000 210 | 00000000000000000000000000000000 211 | 00000000000000000000000000000000 212 | 00000000000000000000000000000000 213 | 00000000000000000000000000000000 214 | 00000000000000000000000000000000 215 | 00000000000000000000000000000000 216 | 00000000000000000000000000000000 217 | 00000000000000000000000000000000 218 | 00000000000000000000000000000000 219 | 00000000000000000000000000000000 220 | 00000000000000000000000000000000 221 | 00000000000000000000000000000000 222 | 00000000000000000000000000000000 223 | 00000000000000000000000000000000 224 | 00000000000000000000000000000000 225 | 00000000000000000000000000000000 226 | 00000000000000000000000000000000 227 | 00000000000000000000000000000000 228 | 00000000000000000000000000000000 229 | 00000000000000000000000000000000 230 | 00000000000000000000000000000000 231 | 00000000000000000000000000000000 232 | 00000000000000000000000000000000 233 | 00000000000000000000000000000000 234 | 00000000000000000000000000000000 235 | 00000000000000000000000000000000 236 | 00000000000000000000000000000000 237 | 00000000000000000000000000000000 238 | 00000000000000000000000000000000 239 | 00000000000000000000000000000000 240 | 00000000000000000000000000000000 241 | 00000000000000000000000000000000 242 | 00000000000000000000000000000000 243 | 00000000000000000000000000000000 244 | 00000000000000000000000000000000 245 | 00000000000000000000000000000000 246 | 00000000000000000000000000000000 247 | 00000000000000000000000000000000 248 | 00000000000000000000000000000000 249 | 00000000000000000000000000000000 250 | 00000000000000000000000000000000 251 | 00000000000000000000000000000000 252 | 00000000000000000000000000000000 253 | 00110111111001000000000000000000 254 | 01000001000011000000000000000000 255 | 01000001000001000000000000000000 256 | 01000001000011000000000000000000 257 | 01100001000101010100000101101100 258 | 01000001000001000000111110000000 259 | 01000001001111000000011110000000 260 | 01000001000001000000111110000000 261 | 01000001010101000100001010110000 262 | 01000001000001000000111110000000 263 | 01000001011011000100001010110000 264 | 01000001000001000000111110000000 265 | 01000001000001000000111110000000 266 | 01000001000001000000111110000000 267 | 00110001000001000000011110000000 268 | 01000001000001000000111110000000 269 | 00110001000001000000011110000000 270 | 01000001000001000000111110000000 271 | 00110001000001000000011110000000 272 | 01000001000001000000111110000000 273 | 01000001110111000000011110000000 274 | 01000001111101000000011110000000 275 | 01000001110111000000011110000000 276 | 01000001111101000000011110000000 277 | 01000001110111000000011110000000 278 | 01000001111101000000011110000000 279 | 01000001110111000000011110000000 280 | 01000001111101000000011110000000 281 | 01000010011011000000011110000000 282 | 01000010100001000000011110000000 283 | 01000001110111000000011110000000 284 | 01000001111101000000011110000000 285 | 01000001110111000000011110000000 286 | 01000001111101000000011110000000 287 | 01000001110111000000011110000000 288 | 01000001111101000000011110000000 289 | 01111001000001110000011111000000 290 | 01000001110001000000011110000000 291 | 01111001000101110000011111000000 292 | 01000001110001000000011110000000 293 | 01111001001001110000011111000000 294 | 01000001110001000000011110000000 295 | 01111001001101110000011111000000 296 | 01000001110001000000011110000000 297 | 01111001010001110000011111000000 298 | 01000010010101000000011110000000 299 | 00110001000001000000011110000000 300 | 01000001110001000000011110000000 301 | 01111001011001110000011111000000 302 | 01000001110001000000011110000000 303 | 01111001011101110000011111000000 304 | 01000001110001000000011110000000 305 | 01111001100001110000011111000000 306 | 01111001100011110000011111000000 307 | 01111001100101110000011111000000 308 | 01111001100111110000011111000000 309 | 01111001101001110000011111000000 310 | 01111001101011110000011111000000 311 | 01111001101101110000011111000000 312 | 01111001101111110000011111000000 313 | 01111001110001110000011111000000 314 | 01111001110011110000011111000000 315 | 01111001110101110000011111000000 316 | 01111001110111110000011111000000 317 | 01111001111001110000011111000000 318 | 01111001111011110000011111000000 319 | 01111001111101110000011111000000 320 | 01111001111111110000011111000000 321 | 01000011000101000000011110000000 322 | 01000011000101000000011110000000 323 | 01000001101011000000011110000000 324 | 01000001101101000000011110000000 325 | 01111010001001110000011111000000 326 | 01111010001011110000011111000000 327 | 01000010001111000000011110000000 328 | 01000010010001000000011110000000 329 | 01000010001111000000011110000000 330 | 01000010010001000000011110000000 331 | 01000001101011000000011110000000 332 | 01000001101101000000011110000000 333 | 01000001101011000000011110000000 334 | 01111010011011110000011111000000 335 | 01000001101011000000011110000000 336 | 01111010011111110000011111000000 337 | 01000001101011000000011110000000 338 | 01000001101101000000011110000000 339 | 01000001101011000000011110000000 340 | 01000001101101000000011110000000 341 | 01000001101011000000011110000000 342 | 01000001101101000000011110000000 343 | 01000001101011000000011110000000 344 | 01000001101101000000011110000000 345 | 01000010001111000000011110000000 346 | 01000010010001000000011110000000 347 | 01000001101011000000011110000000 348 | 01000001101101000000011110000000 349 | 01000001101011000000011110000000 350 | 01000001101101000000011110000000 351 | 01000001101011000000011110000000 352 | 01000001101101000000011110000000 353 | 01000011000101000000011110000000 354 | 01000011001001000000011110000000 355 | 01000011000101000000011110000000 356 | 01000011001001000000011110000000 357 | 01000011000101000000011110000000 358 | 01000011001001000000011110000000 359 | 01000011000101000000011110000000 360 | 01000011001001000000011110000000 361 | 01000010001111000000011110000000 362 | 01000010010011000000011110000000 363 | 01000001101011000000011110000000 364 | 01000001101111000000011110000000 365 | 01000011000101000000011110000000 366 | 01000011001001000000011110000000 367 | 01000011000101000000011110000000 368 | 01000011001001000000011110000000 369 | 01000011000101000000011110000000 370 | 01000011000101000000011110000000 371 | 01000011000101000000011110000000 372 | 01000011000101000000011110000000 373 | 01000011000101000000011110000000 374 | 01000011000101000000011110000000 375 | 01000011000101000000011110000000 376 | 01000011000101000000011110000000 377 | 01000011000101000000011110000000 378 | 01000011000101000000011110000000 379 | 01000011000101000000011110000000 380 | 01000011000101000000011110000000 381 | 01000011000101000000011110000000 382 | 01000011000101000000011110000000 383 | 01000011000101000000011110000000 384 | 01000011000101000000011110000000 385 | 01000001000001000100000100100000 386 | 01111100000011110000011111001100 387 | 01000001000001000100001010110000 388 | 01111100000111110000011111001100 389 | 01000001000001000100000100100000 390 | 01011100001011010000011111001100 391 | 01000001000001000100001010110000 392 | 01011100001111010000011111001100 393 | 01111100010001110000011111000110 394 | 01111100010011110000011111000010 395 | 01111100010101110000011111000110 396 | 01111100010111110000011111001100 397 | 01111100011001110000011111000110 398 | 01111100011011110000011111001100 399 | 01111100011101110000011111000100 400 | 01111100011111110000011111001100 401 | 00110001000001000000011110000000 402 | 01000010001011000000011110000000 403 | 00110001000001000000011110000000 404 | 01000010001011000000011110000000 405 | 00110001000001000000011110000000 406 | 01000010001011000000011110000000 407 | 00110001000001000000011110000000 408 | 01000010001011000000011110000000 409 | 00110001000001000000011110000000 410 | 01000010101111000000011110000000 411 | 00110001000001000000011110000000 412 | 01000010001011000000011110000000 413 | 00110001000001000000011110000000 414 | 01000010001011000000011110000000 415 | 00110001000001000000011110000000 416 | 01000010001011000000011110000000 417 | 01111101000001110000011111000010 418 | 01111101000011110000011111000010 419 | 01111101000101110000011111000010 420 | 01111101000111110000011111000010 421 | 01111101001001110000011111000010 422 | 01000001000001000100000100100000 423 | 01111101001101110000011111000010 424 | 01000001000001000100001010110000 425 | 01111101010001110000011111000010 426 | 01111101010011110000011111001010 427 | 01111101010101110000011111000100 428 | 01111101010111110000011111000100 429 | 01111101011001110000011111000100 430 | 01000001000001000100000100100000 431 | 01111101011101110000011111000000 432 | 01000001000001000100001010110000 433 | 01111101100001110000011111000000 434 | 01111101100011110000011111000000 435 | 01111101100101110000011111000000 436 | 01111101100111110000011111000000 437 | 01111101101001110000011111000000 438 | 01111101101011110000011111000000 439 | 01111101101101110000011111000000 440 | 01111101101111110000011111000000 441 | 01111101110001110000011111000000 442 | 01111101110011110000011111000000 443 | 01111101110101110000011111000000 444 | 01111101110111110000011111000000 445 | 01000111111001000000000000000000 446 | 01001101111010000000000000000000 447 | 01111101111101110000011111000000 448 | 01111101111111110000011111000000 449 | 01000011010001000000011110000000 450 | 01000011010001000000011110000000 451 | 01000010000011000000011110000000 452 | 01000010000111000000011110000000 453 | 01000001011101000000011110000000 454 | 01111110001011110000011111000000 455 | 01000001011111000000011110000000 456 | 01000001100101000000011110000000 457 | 01000010100111000000011110000000 458 | 01000010100111000000011110000000 459 | 01000010000011000000011110000000 460 | 01000010000111000000011110000000 461 | 01000010000011000000011110000000 462 | 01111110011011110000011111000000 463 | 01000010000011000000011110000000 464 | 01111110011111110000011111000000 465 | 01000010000011000000011110000000 466 | 01000010000111000000011110000000 467 | 01000010000011000000011110000000 468 | 01000010000111000000011110000000 469 | 01000010000011000000011110000000 470 | 01000010000111000000011110000000 471 | 01000010000011000000011110000000 472 | 01000010000111000000011110000000 473 | 01000010100111000000011110000000 474 | 01000010101011000000011110000000 475 | 01000010000011000000011110000000 476 | 01000010000111000000011110000000 477 | 01000010000011000000011110000000 478 | 01000010000111000000011110000000 479 | 01000010000011000000011110000000 480 | 01000010000111000000011110000000 481 | 01000011010001000000011110000000 482 | 01000011010111000000011110000000 483 | 01000011010001000000011110000000 484 | 01000011010111000000011110000000 485 | 01000011010001000000011110000000 486 | 01000011010111000000011110000000 487 | 01000011010001000000011110000000 488 | 01000011010111000000011110000000 489 | 01000010100111000000011110000000 490 | 01000010101011000000011110000000 491 | 01000010000011000000011110000000 492 | 01000010001011000000011110000000 493 | 01000011010001000000011110000000 494 | 01000011010111000000011110000000 495 | 01000011010001000000011110000000 496 | 01000011010111000000011110000000 497 | 01000011100011000000011110000000 498 | 01000011100011000000011110000000 499 | 01000011100011000000011110000000 500 | 01000011100011000000011110000000 501 | 01000011100011000000011110000000 502 | 01000011100011000000011110000000 503 | 01000011100011000000011110000000 504 | 01000011100011000000011110000000 505 | 01000011100011000000011110000000 506 | 01000011100011000000011110000000 507 | 01000011100011000000011110000000 508 | 01000011100011000000011110000000 509 | 01000011100011000000011110000000 510 | 01000011100011000000011110000000 511 | 01000011100011000000011110000000 512 | 01000011100011000000011110000000 513 | -------------------------------------------------------------------------------- /Src/README.md: -------------------------------------------------------------------------------- 1 | M65C02 Processor Core Source Files 2 | ================================== 3 | 4 | Copyright (C) 2012, Michael A. Morris . 5 | All Rights Reserved. 6 | 7 | Released under LGPL. 8 | 9 | Organization 10 | ------------ 11 | 12 | The source files are provided in subdirectories: 13 | 14 | M65C02-Test-Programs 15 | Memory-Images 16 | Microprogram-Sources 17 | RTL 18 | Settings 19 | 20 | The contents of each of the subdirectories is provided below. 21 | 22 | The M65C02 test programs as assembler programs. Two test programs are 23 | provided. The first program was a simple program used to test the operation of 24 | jumps, branches, stack operations, and register transfers. With this test 25 | program, a major part of the microprogram was tested and verified. 26 | 27 | The second test program is a more complete program. All instructions, i.e. all 28 | 256 opcodes, are tested using the second program. The operation of the 29 | interrupt logic and the automatic wait state inserted during decimal (BCD) 30 | mode addition and subtraction (ADC/SBC) are also tested with the second test 31 | program. It is not a comprehensive diagnostics program. Examination of the 32 | simulation output was used to test the operation of many of the M65C02's 33 | instructions. However, the second test program does contain some self-checks, 34 | and those were used to speed the process of testing each instruction and each 35 | addressing mode. (The most recent release of the core, Release 2.2, exposed an 36 | issue that affected the PSW on entry into the ISR. Proper adjustment of the 37 | PSW in the PSW was not being tested within the simulated ISR. The problem was 38 | detected further into the test program when and BCD arithmetic failed. Since 39 | this is a critical behavior, the ISR has been modified to include checks that 40 | verify that the BCD mode (PSW.D) is not set, and that interrupt mask is set 41 | (PSW.I) when the ISR is entered.) 42 | 43 | The M65C02 is a microprogrammed implementation. There are two microprogram 44 | memories used. The first, M65C02_Decoder_ROM, provides the control of the ALU 45 | during the execute phase. The second, M65C02_uPgm_V3, provides the control of 46 | the core. That is, the second microprogram implements each addressing mode, 47 | deals with interrupts and BRK, and controls the fetching and execution of all 48 | instructions. Both microprogram ROMs include an instruction decoder. When the 49 | instruction is present on the input data bus, it is captured into the 50 | instruction register, IR, but it is simultaneously applied to the address bus 51 | of the two microprogram ROMs. 52 | 53 | In the Decoder ROM, the opcode is applied in a normal fashion, so the Decoder 54 | ROM is organized linearly. In the uPgm ROM, the opcode is applied to the 55 | address bus with the opcode's nibbles swapped. Thus, the instruction decoder 56 | in the uPgm ROM is best thought of as being organized by the rows in the 57 | opcode matrix of the M65C02. 58 | 59 | There are three memory image files provided in the corresponding subdirectory. 60 | One is for the M65C02 test program, and the other two are for the microprogram 61 | ROMs. The microprogram ROMs are implemented using Block RAMs, whose contents 62 | are initialized by the contents of the two microprogram ROM image files. 63 | 64 | The RTL source files are provided along with a user constraint file (UCF) that 65 | was used during development to optimize the implementation times of the core. 66 | The UCF does provide the PERIOD constraint used during development to judge 67 | whether the operating speed objective would be met by the M65C02. The LOCing 68 | of the pins was done to aid the implementation tools, and is not reflective of 69 | any implementation constraints inherent in the M65C02 core logic. 70 | 71 | The project, synthesis, and implementation settings were captured in a TCL 72 | file. That file allows the duplication of the exact settings used to 73 | synthesize and implement it in a Spartan-3AN FPGA. 74 | 75 | M65C02-Test-Programs 76 | -------------------- 77 | 78 | M65C02_Tst3.a65 - Kingswood A65 assembler source code test program 79 | M65C02.bin - M65C02_Tst2.a65 output of the Kingswood assembler 80 | M65C02.txt - M65C02_Tst2.a65 ASCII hex output of bin2txt.exe 81 | M65C02_Tst.A65 - First test pgm: jmps, branches, stk ops, transfers 82 | 83 | Memory-Images 84 | ------------- 85 | 86 | M65C02_Decoder_ROM.coe - M65C02 core microprogram ALU control fields 87 | M65C02_uPgm_V3a.coe - M65C02 core microprogram (Addressing mode control) 88 | M65C02_Tst3.txt - Memory initialization file for M65C02 test program 89 | 90 | Microprogram-Sources 91 | -------------------- 92 | 93 | M65C02_Decoder_ROM.txt - M65C02 core microprogram ALU control fields 94 | M65C02_Decoder_ROM.out - Listing file 95 | M65C02_uPgm_V3a.txt - M65C02 core microprogram (sequence control) 96 | M65C02_uPgm_V3a.out - Listing file 97 | 98 | RTL 99 | ------------- 100 | 101 | The implementation of the core provided consists of five Verilog source files: 102 | 103 | M65C02_Core.v - Top level module 104 | M65C02_MPCv3.v - Microprogram Controller (Fairchild F9408 MPC) 105 | M65C02_AddrGen.v - M65C02 Address Generator module 106 | M65C02_ALU.v - M65C02 ALU module 107 | M65C02_BIN.v - M65C02 Binary Mode Adder module 108 | M65C02_BCD.v - M65C02 Decimal Mode Adder module 109 | M65C02.ucf - User Constraints File: period and pin LOCs 110 | 111 | In addition to the above files, the directory also contains another core. This 112 | core is the base core and is based on the original release, but includes the 113 | corrections needed to perform all zero page addressing modes correctly. The 114 | solution employed for this version of the core is implemented in logic instead 115 | of in the microprogram. The results are the same, but less flexible. Thus, if 116 | this core would be extended to support additional instructions, then the 117 | solution used for correctly supporting zero page addressing modes may require 118 | modification, and it can impose limits on the microprogram. This core has been 119 | maintained while the new core is being migrated to support LUT, BRAM, and 120 | external SynchRAM using a microcycle length controller in the microprogram 121 | controller instead of an asynchronous wait state inserter in the microprogram 122 | controller. The files for the base (original) core are: 123 | 124 | M65C02_Base.v - Top level module 125 | M65C02_MPC.v - Microprogram Controller (Fairchild F9408 MPC) 126 | M65C02_AddrGen.v - M65C02 Address Generator module 127 | M65C02_ALU.v - M65C02 ALU module 128 | M65C02_BIN.v - M65C02 Binary Mode Adder module 129 | M65C02_BCD.v - M65C02 Decimal Mode Adder module 130 | M65C02.ucf - User Constraints File: period and pin LOCs 131 | 132 | As can be seen, only the core logic file and the microprogram controller are 133 | different between the two implementations. The fixed portion of the 134 | microprogram (which implements the ALU control word) is also common, but the 135 | variable microprogram (which implements the addressing modes, instruction 136 | sequences, and trap handling) are different. For this base (original) core, 137 | the microprogram files are the following: 138 | 139 | M65C02_Decoder_ROM.txt - M65C02 core microprogram ALU control fields 140 | M65C02_Decoder_ROM.out - Listing file 141 | M65C02_uPgm_V3.txt - M65C02 core microprogram (sequence control) 142 | M65C02_uPgm_V3.out - Listing file 143 | 144 | Settings 145 | ------------- 146 | 147 | M65C02.tcl - Project settings file 148 | 149 | Status 150 | ------ 151 | 152 | All files are current. -------------------------------------------------------------------------------- /Src/RTL/ClkGen.xaw: -------------------------------------------------------------------------------- 1 | XILINX-XDB 0.1 STUB 0.1 ASCII 2 | XILINX-XDM V1.4e 3 | $`6x5>6339$;:95?.6:2?41<99$:"==7;04$lF6?8?1:4#:<20916>4_92>=78:!2415?25)?;2<7L\LHVKY52=FZ^PTCCBV_BCPGDBNFNUH@F?7;@PT^ZIIDPUH@FGA_DZWAWHFD8?0M_YU_NLO]ZEKC@DTZLBZE0`8EWQ]WFDGURJLM^QTMQEOAGMTOAE>0:CQS_YHFESTHI\PC133?DTPRVEE@TQKDS]@5475:CQS_YHFEST^H]JT^NLCLE602KY[WQ@NM[\RDJNLVNM_RC@DDc8EVUHKV]BXEh4AVX\GIME]O^R\H?i;@UY[FJLJ\L_U]K=179BS_YDDBH^JYW_E3]MK@BN\890MZTPCMI\KPRW]]U_U]Kl;@UY[CJH_]S[I55NW[]SEWRc3H]QS^WATIVLKI281;8GIM5PVH^Jk5LLJ0[[GSAOVCE_Y74CMI1\ZIR\<1H@F7?5:AOOAPd3JF@H[QKIWKGA0=DDBLI46MCKG@\MK33JF@JUQMUGd8GIMAPVH^JJQFNRV`?FJLNQUOE[GKEd9@HN@_WD_GXD^CY89@HN@_WF__96MCKHL25>EKC@DTHDXFDD]A]Z4e3JF@ECQFBTDD55=DDBCESDLZFF]JJVRa3JF@ECQFBTDD[JSS02IGGD@PIOa8GIMNFVZN^DAKe:AOOLHX[[ITXT^J139@HNIR\VZCM^KPSIKEPf=DDBUMIHJMABI:?FIJE@^_II94CSGBP@B63M<0HNCPSQ`8@FKX[YUBB^Zk;EGPO@QXIM@^_Y?=;EDP[CTBY\OEOTQBOEGb?AJKWHDOSKV>2:FOHZ@UMX_NBNWPMNFF1>BT[LD:96JZTX]@]FJBWJEY^HM[INL4?AYQIE_N46KWTDPMEIg@C02LO=RGASU;8BA7XYVE^X55ID3]JJVR>3ON9S\Q@UU:8BA5XAGY_56HK3^S\KPR43ONX46HKS^KMWQ?LN\]OYS[OCUD48HJGCMM<0@BMDEEc8HJELMMUDYY=4LNU0?HN]j2GTMCJPD^QWV2=JW_KGYH94NDVTKWM33GEEI<5@8:ME@ATDXL90C_<7;NP1[LHT\:1D^>64OS1\MKUS12EY?RAPOTVa?UNF[LUXDDH[9:RJJMGTJ\Yj7]GAIREM@@B?3YCE[DJ[H99SVLKSQYO:<6^]OQ]SMKOTIJ^BZH;4PRAOO3=W[MEEI95_SDL;?UUNFJNNO<5^3:PPP3=U[]UBB<5\b:QJC@^SM[DJ@;5\IOEOAf=T\HX_Y]QXAHV5?VRF\\Y:>6]VSUGN[V_IKAXDBB[\3:VLT1=SZ\Oi7X]JR^PPPZOI02_XIRLZFF;8QVCXJ\LL_85YIDU2f>^F_V\N^^G@N0f8\LJNFQ'SHO.?.0"PPPD'8';+M^MFI29[WQ0]729W>7V>57\68ewq};2nhao5yesqjkk&6&9>0zejce:z`7v37i$>}}<>?}ABs2`=GHq8>6K4n:0yP0=<>n3k:6<=<28c;>617;;qe5o4>;o;`>1=#1h0246s\468:b?g62898>4o7:2:1b6=T>l02j7o>:01064o7:2:b20=T>l02j7o>:01064o7:2:a76=T>l02j7o>:0106d7=9:995lo53614?V0b20l1m<4>320:f5<5m0=:7^:8:8d9e4<6;:82n=4=e85`?a?a290:64o7:25377=q\0<1<7?51;31V2?20l1m<4>320:e=<4?9997o7>:183>g<6:r.h6l>4$0d9e7=#:90j?6*=1;;:?!?02=1i8o4?:0194?6|,1818l5+d;11?!c=0m1/==4=6:&25?413-;96?o4$01963=#9=0<46*>5;:g?!712:1/=:486:&2"4;3=0(>o53:&0f??<,:o1985+428b?!232<90(9;5779'0f<>82.>>7=4$5f934=#"1j3=87)9;:89'3`<73-2n64<4$869=0=#n3<0(!>620n0(5=59398m62=83.3=77k;%:0><4<3`226=4+808:`>"?;33976g76;29 =7=1m1/4=462:9j<2<72-2:64j4$929=7=1<7*71;;g?!>720807d;?:18'<4<>l2.3<77=;:m12?6=,1;15i5+828:6>"6j38876a<1;29 =7=1m10c?o50;&;5??c32e9n7>5$939=a=l2.3?77=;%3`>75<,8n1:<54o3f94?"?933o76a<6;29 =7=1m1/4>462:&2f?4432e8;7>5$939=a=l2.3?77=;:m;1?6=,1;15i54}c63>5<5290;w)6=:7;8m33=83.3=77k;%:0><4<3f=<6=4+808:`>"?;33976sm2983>7<729q/4?4=3:k51?6=,1;15i5+828:6>=h?>0;6)6>:8f8 =5=1;10qo5<7s-296?=4i7794?"?933o7)6<:808?j10290/4<46d:&;7??532wi?44?:383>5}#0;09?6g95;29 =7=1m1/4>462:9l32<72-2:64j4$919=7=52>h0e;650;&;5??c3-2864<4;h44>5<#0802h6*73;;1?>o1>3:1(5?59e9'<6<>:21d;:4?:%:2>5<3290;w)6=:4g8m=d=83.3=77k;%:3><4<,1915?54i5;94?"?933o7)6?:808 =5=1;10e?:50;&;5??c3-2864<4;n:;>5<#0802h6*73;;1?>{e=10;6>4?:1y'<7<2?2c?57>5$939=a=#0:02>65f2583>!>620n0(5=59398k=>=83.3=77k;%:0><4<3th>m7>53;294~"?:3?<7d:6:18'<4<>l2.3?77=;:k10?6=,1;15i5+828:6>=h010;6)6>:8f8 =5=1;10qo;l:180>5<7s-296894i5;94?"?933o7)6<:808?l43290/4<46d:&;7??532e347>5$939=a=#0:02>65rb6c94?5=83:p(5<5789j22<72-2:64j4$919=7=420807b98:18'<4<>l2.3?77=;:p7c<72?q68o401?h5769'5d<482wx4l4?:3y>0g337e<5;l1:85rs2:94?4|5=h1?;5238851>{t?90;6"?k3=<7p};2;295~;383<>7)6l:778yv4>290:w0<7:658 =e=?>1v>m50;3x96?=?>1/4n487:p1<<72:q6;n498:?6?34?j6974}r7a>5<4s4=h6;94=4c9<==:=j0?56s|5e83>7}:?j0=:63:c;:;?xu0l3:1>v38c;54?81f2?=0q~8?:18183a21201865489~w<5=83;p1:o5679'm6=4>{|l64?6=9rwe9<4?:0y~j04=83;pqc;<:182xh2<3:1=vsa5483>4}zf<<1<7?t}o74>5<6std>47>51zm1<<728qvb8o50;3xyk3e290:wpsr}AB@3c=kko<9898}ABA5{GHYqvLM -------------------------------------------------------------------------------- /Src/RTL/M65C02.ucf: -------------------------------------------------------------------------------- 1 | CONFIG VCCAUX=3.3; 2 | # 3 | NET "Clk" TNM_NET = Clk; 4 | # 5 | #TIMESPEC TS_Clk = PERIOD "Clk" 16.954 ns HIGH 50%; # 58.9824 MHz 6 | #TIMESPEC TS_Clk = PERIOD "Clk" 16.667 ns HIGH 50%; # 60.000 MHz 7 | #TIMESPEC TS_Clk = PERIOD "Clk" 16.000 ns HIGH 50%; # 62.500 MHz 8 | #TIMESPEC TS_Clk = PERIOD "Clk" 15.625 ns HIGH 50%; # 64.000 MHz 9 | #TIMESPEC TS_Clk = PERIOD "Clk" 15.258 ns HIGH 50%; # 65.536 MHz 10 | #TIMESPEC TS_Clk = PERIOD "Clk" 15.150 ns HIGH 50%; # 66.006 MHz 11 | #TIMESPEC TS_Clk = PERIOD "Clk" 15.000 ns HIGH 50%; # 66.667 MHz 12 | TIMESPEC TS_Clk = PERIOD "Clk" 13.563 ns HIGH 50%; # 73.728 MHz 13 | #TIMESPEC TS_Clk = PERIOD "Clk" 13.250 ns HIGH 50%; # 75.472 MHz 14 | #TIMESPEC TS_Clk = PERIOD "Clk" 13.000 ns HIGH 50%; # 76.923 MHz 15 | #TIMESPEC TS_Clk = PERIOD "Clk" 12.500 ns HIGH 50%; # 80.000 MHz 16 | # 17 | #TIMESPEC TS_Clk = PERIOD "Clk" 10.000 ns HIGH 50%; # 100.000 MHz 18 | #TIMESPEC TS_Clk = PERIOD "Clk" 7.978 ns HIGH 50%; # 125.3376 MHz 19 | # 20 | NET "Buf_ClkIn" TNM_NET = Buf_ClkIn; 21 | # 22 | #TIMESPEC TS_ClkIn = PERIOD "Buf_ClkIn" 67.816 ns HIGH 50%; # 14.7456 MHz 23 | #TIMESPEC TS_ClkIn = PERIOD "Buf_ClkIn" 54.253 ns HIGH 50%; # 18.4320 MHz 24 | #TIMESPEC TS_ClkIn = PERIOD "Buf_ClkIn" 50.000 ns HIGH 50%; # 20.0000 MHz 25 | TIMESPEC TS_ClkIn = PERIOD "Buf_ClkIn" 4.000 ns HIGH 50%; # 250.0000 MHz 26 | # 27 | NET "DB<0>" LOC = "P52" | IOSTANDARD = "LVCMOS33"; 28 | NET "DB<1>" LOC = "P50" | IOSTANDARD = "LVCMOS33"; 29 | NET "DB<2>" LOC = "P49" | IOSTANDARD = "LVCMOS33"; 30 | NET "DB<3>" LOC = "P44" | IOSTANDARD = "LVCMOS33"; 31 | NET "DB<4>" LOC = "P43" | IOSTANDARD = "LVCMOS33"; 32 | NET "DB<5>" LOC = "P41" | IOSTANDARD = "LVCMOS33"; 33 | NET "DB<6>" LOC = "P40" | IOSTANDARD = "LVCMOS33"; 34 | NET "DB<7>" LOC = "P37" | IOSTANDARD = "LVCMOS33"; 35 | NET "A<0>" LOC = "P65" | IOSTANDARD = "LVCMOS33"; 36 | NET "A<1>" LOC = "P64" | IOSTANDARD = "LVCMOS33"; 37 | NET "A<2>" LOC = "P62" | IOSTANDARD = "LVCMOS33"; 38 | NET "A<3>" LOC = "P61" | IOSTANDARD = "LVCMOS33"; 39 | NET "A<4>" LOC = "P60" | IOSTANDARD = "LVCMOS33"; 40 | NET "A<5>" LOC = "P59" | IOSTANDARD = "LVCMOS33"; 41 | NET "A<6>" LOC = "P57" | IOSTANDARD = "LVCMOS33"; 42 | NET "A<7>" LOC = "P56" | IOSTANDARD = "LVCMOS33"; 43 | NET "A<8>" LOC = "P36" | IOSTANDARD = "LVCMOS33"; 44 | NET "A<9>" LOC = "P35" | IOSTANDARD = "LVCMOS33"; 45 | NET "A<10>" LOC = "P34" | IOSTANDARD = "LVCMOS33"; 46 | NET "A<11>" LOC = "P33" | IOSTANDARD = "LVCMOS33"; 47 | NET "A<12>" LOC = "P32" | IOSTANDARD = "LVCMOS33"; 48 | NET "A<13>" LOC = "P31" | IOSTANDARD = "LVCMOS33"; 49 | NET "A<14>" LOC = "P30" | IOSTANDARD = "LVCMOS33"; 50 | NET "A<15>" LOC = "P29" | IOSTANDARD = "LVCMOS33"; 51 | NET "XA<0>" LOC = "P28" | IOSTANDARD = "LVCMOS33"; 52 | NET "XA<1>" LOC = "P25" | IOSTANDARD = "LVCMOS33"; 53 | NET "XA<2>" LOC = "P24" | IOSTANDARD = "LVCMOS33"; 54 | NET "XA<3>" LOC = "P23" | IOSTANDARD = "LVCMOS33"; 55 | # 56 | NET "nCE<0>" LOC = "P70" | IOSTANDARD = "LVCMOS33" | SLEW = "FAST"; 57 | NET "nCE<1>" LOC = "P71" | IOSTANDARD = "LVCMOS33" | SLEW = "FAST"; 58 | NET "nCE<2>" LOC = "P72" | IOSTANDARD = "LVCMOS33" | SLEW = "FAST"; 59 | NET "nCE<3>" LOC = "P73" | IOSTANDARD = "LVCMOS33" | SLEW = "FAST"; 60 | # 61 | NET "RnW" LOC = "P10" | IOSTANDARD = "LVCMOS33"; 62 | NET "nOE" LOC = "P15" | IOSTANDARD = "LVCMOS33" | SLEW = "FAST"; 63 | NET "nWr" LOC = "P16" | IOSTANDARD = "LVCMOS33" | SLEW = "FAST"; 64 | NET "Sync" LOC = "P3" | IOSTANDARD = "LVCMOS33"; 65 | NET "nML" LOC = "P4" | IOSTANDARD = "LVCMOS33"; 66 | NET "Rdy" LOC = "P5" | IOSTANDARD = "LVCMOS33" | PULLUP; 67 | # 68 | NET "ClkIn" LOC = "P88" | IOSTANDARD = "LVCMOS33"; 69 | # 70 | NET "Phi1O" LOC = "P13" | IOSTANDARD = "LVCMOS33" | SLEW = "FAST"; 71 | NET "Phi2O" LOC = "P12" | IOSTANDARD = "LVCMOS33" | SLEW = "FAST"; 72 | # 73 | NET "nRst" LOC = "P82" | IOSTANDARD = "LVCMOS33" | PULLUP; 74 | NET "BE_In" LOC = "P68" | IOSTANDARD = "LVCMOS33" | PULLUP; 75 | NET "nSO" LOC = "P97" | IOSTANDARD = "LVCMOS33" | PULLUP; 76 | NET "nNMI" LOC = "P21" | IOSTANDARD = "LVCMOS33" | PULLUP; 77 | NET "nIRQ" LOC = "P7" | IOSTANDARD = "LVCMOS33" | PULLUP; 78 | NET "nVP" LOC = "P6" | IOSTANDARD = "LVCMOS33"; 79 | # 80 | NET "nWait" LOC = "P48" | IOSTANDARD = "LVCMOS33"; 81 | NET "nRstO" LOC = "P83" | IOSTANDARD = "LVCMOS33" | PULLUP; 82 | NET "nWP_In" LOC = "P39" | IOSTANDARD = "LVCMOS33" | PULLUP; 83 | # 84 | #NET "nCS<0>" LOC = "P27" | IOSTANDARD = "LVCMOS33"; 85 | #NET "nCS<1>" LOC = "P20" | IOSTANDARD = "LVCMOS33"; 86 | #NET "nCS<2>" LOC = "P19" | IOSTANDARD = "LVCMOS33"; 87 | ## 88 | #NET "SCK" LOC = "P53" | IOSTANDARD = "LVCMOS33"; 89 | #NET "MOSI" LOC = "P46" | IOSTANDARD = "LVCMOS33"; 90 | ## 91 | #NET "TxD_A" LOC = "P90" | IOSTANDARD = "LVCMOS33"; 92 | #NET "TxD_B" LOC = "P85" | IOSTANDARD = "LVCMOS33"; 93 | # 94 | NET "LED<4>" LOC = "P27" | IOSTANDARD = "LVCMOS33"; 95 | NET "LED<3>" LOC = "P20" | IOSTANDARD = "LVCMOS33"; 96 | NET "LED<2>" LOC = "P19" | IOSTANDARD = "LVCMOS33"; 97 | NET "LED<1>" LOC = "P90" | IOSTANDARD = "LVCMOS33"; 98 | NET "LED<0>" LOC = "P85" | IOSTANDARD = "LVCMOS33"; 99 | -------------------------------------------------------------------------------- /Src/RTL/M65C02_AddrGen.v: -------------------------------------------------------------------------------- 1 | //////////////////////////////////////////////////////////////////////////////// 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 277 | -------------------------------------------------------------------------------- /Src/RTL/M65C02_BCD.v: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MorrisMA/MAM65C02-Processor-Core/dabbc3f44616cdb0898375d68b9f36e11fd21081/Src/RTL/M65C02_BCD.v -------------------------------------------------------------------------------- /Src/RTL/M65C02_BIN.v: -------------------------------------------------------------------------------- 1 | /////////////////////////////////////////////////////////////////////////////// 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: 02/14/2012 45 | // Design Name: WDC W65C02 Microprocessor Re-Implementation 46 | // Module Name: M65C02_BIN 47 | // Project Name: C:\XProjects\ISE10.1i\MAM6502 48 | // Target Devices: Generic SRAM-based FPGA 49 | // Tool versions: Xilinx ISE10.1i SP3 50 | // 51 | // Description: 52 | // 53 | // Dependencies: None. 54 | // 55 | // Revision: 56 | // 57 | // 1.00 12B14 MAM Initial coding. Modified W65C02_Adder.v for binary- 58 | // only operation. MAM6502_BCD performs the same ops. 59 | // as a BCD-only add/sub. Removed Mode input. Deleted 60 | // second stage of the W6502_Adder module used for 61 | // BCD adjustment. 62 | // 63 | // 1.01 12B19 MAM Renamed module: MAM6502_BIN => M65C02_BIN. 64 | // 65 | // 1.10 13H04 MAM Made the output a 0 when enable not asserted. Makes 66 | // the module compatible with an OR bus. 67 | // 68 | // Additional Comments: 69 | // 70 | /////////////////////////////////////////////////////////////////////////////// 71 | 72 | module M65C02_BIN( 73 | input En, // ALU Enable 74 | 75 | input [7:0] A, // Adder Input A 76 | input [7:0] B, // Adder Input B 77 | input Ci, // Adder Carry In 78 | 79 | output reg [8:0] Out, // Adder Sum <= A + B + Ci 80 | output reg OV, // Adder Overflow 81 | output reg Valid // Adder Outputs Valid 82 | ); 83 | 84 | /////////////////////////////////////////////////////////////////////////////// 85 | // 86 | // Declarations 87 | // 88 | 89 | reg [7:0] S; // Intermediate Binary Sum: S <= A + B + Ci 90 | reg C6, C7; // Sum Carry Out from Bitx 91 | 92 | /////////////////////////////////////////////////////////////////////////////// 93 | // 94 | // Implementation 95 | // 96 | 97 | // Adder First Stage - Combinatorial; Binary Sums and Carries 98 | 99 | always @(*) 100 | begin 101 | // Binary Addition and Generate C6 and C7 Carries 102 | {C6, S[6:0]} <= ({1'b0, A[6:0]} + {1'b0, B[6:0]} + {7'b0, Ci}); 103 | {C7, S[7]} <= ({1'b0, A[7]} + {1'b0, B[7]} + {1'b0, C6}); 104 | end 105 | 106 | always @(*) 107 | begin 108 | Out <= ((En) ? {C7, S} : 0); 109 | OV <= ((En) ? (C7 ^ C6) : 0); 110 | Valid <= En; 111 | end 112 | 113 | endmodule 114 | -------------------------------------------------------------------------------- /Src/RTL/M65C02_Base.ucf: -------------------------------------------------------------------------------- 1 | NET "Clk" TNM_NET = Clk; 2 | #TIMESPEC TS_Clk = PERIOD "Clk" 6.000 ns HIGH 50%; #Virtex 5 LXT after removal ~|(reg) 3 | #TIMESPEC TS_Clk = PERIOD "Clk" 15 ns HIGH 50%; #Spartan II after removal ~|(reg) 4 | #TIMESPEC TS_Clk = PERIOD "Clk" 9.755 ns HIGH 50%; #Spartan 3AN before removal ~|(reg) 5 | #TIMESPEC TS_Clk = PERIOD "Clk" 9.091 ns HIGH 50%; #Spartan 3AN after removal ~|(reg) 6 | #TIMESPEC TS_Clk = PERIOD "Clk" 10.000 ns HIGH 50%; #Spartan 3AN after removal ~|(reg) 7 | #TIMESPEC TS_Clk = PERIOD "Clk" 9.500 ns HIGH 50%; #Spartan 3AN after removal ~|(reg) 8 | #TIMESPEC TS_Clk = PERIOD "Clk" 9.375 ns HIGH 50%; #Spartan 3AN after removal ~|(reg) 9 | TIMESPEC TS_Clk = PERIOD "Clk" 9.250 ns HIGH 50%; #Spartan 3AN after removal ~|(reg) 10 | #TIMESPEC TS_Clk = PERIOD "Clk" 9.150 ns HIGH 50%; #Spartan 3AN after removal ~|(reg) 11 | #pin2ucf - Sun Dec 09 10:41:51 2012 12 | #The following constraints were newly added 13 | #NET "IR<6>" LOC = A9 14 | NET "IR<6>" LOC = C4 | IOSTANDARD = "LVTTL"; 15 | #NET "DI<7>" LOC = E4 16 | NET "DI<7>" LOC = L2 | IOSTANDARD = "LVTTL"; 17 | #NET "PC<8>" LOC = A6 18 | NET "PC<8>" LOC = T10 | IOSTANDARD = "LVTTL"; 19 | #NET "Y<1>" LOC = H16 20 | NET "Y<1>" LOC = G1 | IOSTANDARD = "LVTTL"; 21 | #NET "OP2<3>" LOC = A11 22 | NET "OP2<3>" LOC = K3 | IOSTANDARD = "LVTTL"; 23 | #NET "AO<1>" LOC = M1 24 | NET "AO<1>" LOC = L13 | IOSTANDARD = "LVTTL"; 25 | #NET "IR<7>" LOC = E1 26 | NET "IR<7>" LOC = K14 | IOSTANDARD = "LVTTL"; 27 | #NET "Y<2>" LOC = M10 28 | NET "Y<2>" LOC = A5 | IOSTANDARD = "LVTTL"; 29 | #NET "Clk" LOC = D8 30 | NET "Clk" LOC = C10 | IOSTANDARD = "LVTTL"; 31 | #NET "PC<9>" LOC = F8 32 | NET "PC<9>" LOC = R3 | IOSTANDARD = "LVTTL"; 33 | #NET "OP2<4>" LOC = G4 34 | NET "OP2<4>" LOC = P1 | IOSTANDARD = "LVTTL"; 35 | #NET "IRQ_Msk" LOC = A13 36 | NET "IRQ_Msk" LOC = P11 | IOSTANDARD = "LVTTL"; 37 | #NET "AO<2>" LOC = N1 38 | NET "AO<2>" LOC = J16 | IOSTANDARD = "LVTTL"; 39 | #NET "Y<3>" LOC = P8 40 | NET "Y<3>" LOC = H4 | IOSTANDARD = "LVTTL"; 41 | #NET "AO<10>" LOC = T5 42 | NET "AO<10>" LOC = H15 | IOSTANDARD = "LVTTL"; 43 | #NET "OP2<5>" LOC = E3 44 | NET "OP2<5>" LOC = N3 | IOSTANDARD = "LVTTL"; 45 | #NET "RMW" LOC = C5 46 | NET "RMW" LOC = G2 | IOSTANDARD = "LVTTL"; 47 | #NET "AO<3>" LOC = R1 48 | NET "AO<3>" LOC = L14 | IOSTANDARD = "LVTTL"; 49 | #NET "PC<10>" LOC = B6 50 | NET "PC<10>" LOC = T8 | IOSTANDARD = "LVTTL"; 51 | #NET "Y<4>" LOC = K16 52 | NET "Y<4>" LOC = A6 | IOSTANDARD = "LVTTL"; 53 | #NET "AO<11>" LOC = T6 54 | NET "AO<11>" LOC = M16 | IOSTANDARD = "LVTTL"; 55 | #NET "OP2<6>" LOC = H6 56 | NET "OP2<6>" LOC = T2 | IOSTANDARD = "LVTTL"; 57 | #NET "S<0>" LOC = C12 58 | NET "S<0>" LOC = C7 | IOSTANDARD = "LVTTL"; 59 | #NET "AO<4>" LOC = N2 60 | NET "AO<4>" LOC = J12 | IOSTANDARD = "LVTTL"; 61 | #NET "PC<11>" LOC = G13 62 | NET "PC<11>" LOC = N9 | IOSTANDARD = "LVTTL"; 63 | #NET "Y<5>" LOC = K15 64 | NET "Y<5>" LOC = F1 | IOSTANDARD = "LVTTL"; 65 | #NET "AO<12>" LOC = R5 66 | NET "AO<12>" LOC = M14 | IOSTANDARD = "LVTTL"; 67 | #NET "OP2<7>" LOC = D3 68 | NET "OP2<7>" LOC = K4 | IOSTANDARD = "LVTTL"; 69 | #NET "S<1>" LOC = R11 70 | NET "S<1>" LOC = B6 | IOSTANDARD = "LVTTL"; 71 | #NET "AO<5>" LOC = M3 72 | NET "AO<5>" LOC = T11 | IOSTANDARD = "LVTTL"; 73 | NET "Ack_In" LOC = G14 | IOSTANDARD = "LVTTL"; 74 | #NET "PC<12>" LOC = E14 75 | NET "PC<12>" LOC = K1 | IOSTANDARD = "LVTTL"; 76 | #NET "Y<6>" LOC = M15 77 | NET "Y<6>" LOC = C9 | IOSTANDARD = "LVTTL"; 78 | #NET "AO<13>" LOC = P4 79 | NET "AO<13>" LOC = H16 | IOSTANDARD = "LVTTL"; 80 | #NET "S<2>" LOC = D14 81 | NET "S<2>" LOC = B15 | IOSTANDARD = "LVTTL"; 82 | #NET "P<0>" LOC = H13 83 | NET "P<0>" LOC = G3 | IOSTANDARD = "LVTTL"; 84 | #NET "AO<6>" LOC = K4 85 | NET "AO<6>" LOC = J14 | IOSTANDARD = "LVTTL"; 86 | #NET "PC<13>" LOC = B8 87 | NET "PC<13>" LOC = M4 | IOSTANDARD = "LVTTL"; 88 | #NET "Y<7>" LOC = J16 89 | NET "Y<7>" LOC = C6 | IOSTANDARD = "LVTTL"; 90 | #NET "AO<14>" LOC = N3 91 | NET "AO<14>" LOC = E14 | IOSTANDARD = "LVTTL"; 92 | #NET "S<3>" LOC = D11 93 | NET "S<3>" LOC = A12 | IOSTANDARD = "LVTTL"; 94 | #NET "P<1>" LOC = F13 95 | NET "P<1>" LOC = G4 | IOSTANDARD = "LVTTL"; 96 | #NET "AO<7>" LOC = L4 97 | NET "AO<7>" LOC = K15 | IOSTANDARD = "LVTTL"; 98 | #NET "PC<14>" LOC = A3 99 | NET "PC<14>" LOC = N2 | IOSTANDARD = "LVTTL"; 100 | #NET "AO<15>" LOC = P2 101 | NET "AO<15>" LOC = F14 | IOSTANDARD = "LVTTL"; 102 | #NET "S<4>" LOC = A12 103 | NET "S<4>" LOC = D15 | IOSTANDARD = "LVTTL"; 104 | NET "xNMI" LOC = D10 | IOSTANDARD = "LVTTL"; 105 | #NET "P<2>" LOC = A14 106 | NET "P<2>" LOC = C11 | IOSTANDARD = "LVTTL"; 107 | #NET "Rst" LOC = A7 108 | NET "Rst" LOC = L6 | IOSTANDARD = "LVTTL"; 109 | #NET "AO<8>" LOC = N6 110 | NET "AO<8>" LOC = M15 | IOSTANDARD = "LVTTL"; 111 | #NET "PC<15>" LOC = B12 112 | NET "PC<15>" LOC = K16 | IOSTANDARD = "LVTTL"; 113 | #NET "S<5>" LOC = M13 114 | NET "S<5>" LOC = B10 | IOSTANDARD = "LVTTL"; 115 | #NET "P<3>" LOC = E13 116 | NET "P<3>" LOC = C12 | IOSTANDARD = "LVTTL"; 117 | #NET "AO<9>" LOC = M4 118 | NET "AO<9>" LOC = J13 | IOSTANDARD = "LVTTL"; 119 | #NET "S<6>" LOC = N10 120 | NET "S<6>" LOC = A10 | IOSTANDARD = "LVTTL"; 121 | #NET "P<4>" LOC = C8 122 | NET "P<4>" LOC = H5 | IOSTANDARD = "LVTTL"; 123 | #NET "S<7>" LOC = H15 124 | NET "S<7>" LOC = B12 | IOSTANDARD = "LVTTL"; 125 | #NET "P<5>" LOC = D13 126 | NET "P<5>" LOC = C13 | IOSTANDARD = "LVTTL"; 127 | #NET "OP1<0>" LOC = T4 128 | NET "OP1<0>" LOC = C2 | IOSTANDARD = "LVTTL"; 129 | #NET "P<6>" LOC = F15 130 | NET "P<6>" LOC = C8 | IOSTANDARD = "LVTTL"; 131 | #NET "OP1<1>" LOC = T13 132 | NET "OP1<1>" LOC = E13 | IOSTANDARD = "LVTTL"; 133 | #NET "P<7>" LOC = E16 134 | NET "P<7>" LOC = A8 | IOSTANDARD = "LVTTL"; 135 | #NET "X<0>" LOC = K13 136 | NET "X<0>" LOC = E7 | IOSTANDARD = "LVTTL"; 137 | #NET "OP1<2>" LOC = J4 138 | NET "OP1<2>" LOC = D4 | IOSTANDARD = "LVTTL"; 139 | #NET "X<1>" LOC = M16 140 | NET "X<1>" LOC = F3 | IOSTANDARD = "LVTTL"; 141 | #NET "OP1<3>" LOC = P10 142 | NET "OP1<3>" LOC = B3 | IOSTANDARD = "LVTTL"; 143 | #NET "X<2>" LOC = L13 144 | NET "X<2>" LOC = F8 | IOSTANDARD = "LVTTL"; 145 | #NET "OP1<4>" LOC = N8 146 | NET "OP1<4>" LOC = A3 | IOSTANDARD = "LVTTL"; 147 | #NET "X<3>" LOC = T9 148 | NET "X<3>" LOC = B8 | IOSTANDARD = "LVTTL"; 149 | #NET "OP1<5>" LOC = T8 150 | NET "OP1<5>" LOC = B14 | IOSTANDARD = "LVTTL"; 151 | #NET "X<4>" LOC = L14 152 | NET "X<4>" LOC = C5 | IOSTANDARD = "LVTTL"; 153 | #NET "A<0>" LOC = G16 154 | NET "A<0>" LOC = D7 | IOSTANDARD = "LVTTL"; 155 | #NET "OP1<6>" LOC = T11 156 | NET "OP1<6>" LOC = H6 | IOSTANDARD = "LVTTL"; 157 | #NET "X<5>" LOC = J14 158 | NET "X<5>" LOC = D9 | IOSTANDARD = "LVTTL"; 159 | #NET "A<1>" LOC = P6 160 | NET "A<1>" LOC = D1 | IOSTANDARD = "LVTTL"; 161 | #NET "OP1<7>" LOC = D15 162 | NET "OP1<7>" LOC = A13 | IOSTANDARD = "LVTTL"; 163 | #NET "X<6>" LOC = K14 164 | NET "X<6>" LOC = A11 | IOSTANDARD = "LVTTL"; 165 | #NET "A<2>" LOC = J12 166 | NET "A<2>" LOC = F13 | IOSTANDARD = "LVTTL"; 167 | #NET "SC" LOC = A5 168 | NET "SC" LOC = P7 | IOSTANDARD = "LVTTL"; 169 | #NET "X<7>" LOC = H14 170 | NET "X<7>" LOC = B4 | IOSTANDARD = "LVTTL"; 171 | #NET "A<3>" LOC = J13 172 | NET "A<3>" LOC = D16 | IOSTANDARD = "LVTTL"; 173 | #NET "IO_Op<0>" LOC = D7 174 | NET "IO_Op<0>" LOC = R2 | IOSTANDARD = "LVTTL"; 175 | #NET "IO_Op<1>" LOC = D1 176 | NET "IO_Op<1>" LOC = J3 | IOSTANDARD = "LVTTL"; 177 | #NET "A<4>" LOC = N7 178 | NET "A<4>" LOC = A7 | IOSTANDARD = "LVTTL"; 179 | #NET "A<5>" LOC = F14 180 | NET "A<5>" LOC = A4 | IOSTANDARD = "LVTTL"; 181 | #NET "A<6>" LOC = L16 182 | NET "A<6>" LOC = E3 | IOSTANDARD = "LVTTL"; 183 | #NET "A<7>" LOC = F16 184 | NET "A<7>" LOC = D8 | IOSTANDARD = "LVTTL"; 185 | #NET "Vector<10>" LOC = J2 186 | NET "Vector<10>" LOC = N1 | IOSTANDARD = "LVTTL"; 187 | #NET "IntSvc" LOC = B14 188 | NET "IntSvc" LOC = D14 | IOSTANDARD = "LVTTL"; 189 | #NET "Vector<11>" LOC = H5 190 | NET "Vector<11>" LOC = L4 | IOSTANDARD = "LVTTL"; 191 | #NET "Mode<0>" LOC = A4 192 | NET "Mode<0>" LOC = T5 | IOSTANDARD = "LVTTL"; 193 | #NET "Vector<12>" LOC = H1 194 | NET "Vector<12>" LOC = L5 | IOSTANDARD = "LVTTL"; 195 | #NET "Mode<1>" LOC = B4 196 | NET "Mode<1>" LOC = N6 | IOSTANDARD = "LVTTL"; 197 | #NET "DO<0>" LOC = R7 198 | NET "DO<0>" LOC = R11 | IOSTANDARD = "LVTTL"; 199 | #NET "Vector<0>" LOC = F7 200 | NET "Vector<0>" LOC = T7 | IOSTANDARD = "LVTTL"; 201 | #NET "Vector<13>" LOC = F1 202 | NET "Vector<13>" LOC = N10 | IOSTANDARD = "LVTTL"; 203 | #NET "xIRQ" LOC = C11 204 | NET "xIRQ" LOC = P8 | IOSTANDARD = "LVTTL"; 205 | #NET "Mode<2>" LOC = D4 206 | NET "Mode<2>" LOC = H1 | IOSTANDARD = "LVTTL"; 207 | #NET "DO<1>" LOC = K1 208 | NET "DO<1>" LOC = H14 | IOSTANDARD = "LVTTL"; 209 | #NET "Vector<1>" LOC = H3 210 | NET "Vector<1>" LOC = P10 | IOSTANDARD = "LVTTL"; 211 | #NET "Vector<14>" LOC = G2 212 | NET "Vector<14>" LOC = K6 | IOSTANDARD = "LVTTL"; 213 | #NET "DO<2>" LOC = P9 214 | NET "DO<2>" LOC = G13 | IOSTANDARD = "LVTTL"; 215 | #NET "Vector<2>" LOC = F4 216 | NET "Vector<2>" LOC = M10 | IOSTANDARD = "LVTTL"; 217 | #NET "Vector<15>" LOC = H4 218 | NET "Vector<15>" LOC = P9 | IOSTANDARD = "LVTTL"; 219 | #NET "DO<3>" LOC = N9 220 | NET "DO<3>" LOC = F15 | IOSTANDARD = "LVTTL"; 221 | #NET "Vector<3>" LOC = F3 222 | NET "Vector<3>" LOC = K5 | IOSTANDARD = "LVTTL"; 223 | #NET "Done" LOC = E2 224 | NET "Done" LOC = P12 | IOSTANDARD = "LVTTL"; 225 | #NET "PC<0>" LOC = L3 226 | NET "PC<0>" LOC = R7 | IOSTANDARD = "LVTTL"; 227 | #NET "DO<4>" LOC = K3 228 | NET "DO<4>" LOC = G16 | IOSTANDARD = "LVTTL"; 229 | #NET "Vector<4>" LOC = G6 230 | NET "Vector<4>" LOC = M1 | IOSTANDARD = "LVTTL"; 231 | #NET "DI<0>" LOC = B10 232 | NET "DI<0>" LOC = G6 | IOSTANDARD = "LVTTL"; 233 | #NET "PC<1>" LOC = R2 234 | NET "PC<1>" LOC = R9 | IOSTANDARD = "LVTTL"; 235 | #NET "DO<5>" LOC = T10 236 | NET "DO<5>" LOC = D10 | IOSTANDARD = "LVTTL"; 237 | #NET "Vector<5>" LOC = J3 238 | NET "Vector<5>" LOC = T9 | IOSTANDARD = "LVTTL"; 239 | #NET "Rdy" LOC = B3 240 | NET "Rdy" LOC = D3 | IOSTANDARD = "LVTTL"; 241 | #NET "IR<0>" LOC = A10 242 | NET "IR<0>" LOC = E1 | IOSTANDARD = "LVTTL"; 243 | #NET "DI<1>" LOC = F9 244 | NET "DI<1>" LOC = G5 | IOSTANDARD = "LVTTL"; 245 | #NET "PC<2>" LOC = R3 246 | NET "PC<2>" LOC = P5 | IOSTANDARD = "LVTTL"; 247 | #NET "DO<6>" LOC = R9 248 | NET "DO<6>" LOC = E16 | IOSTANDARD = "LVTTL"; 249 | #NET "Vector<6>" LOC = E9 250 | NET "Vector<6>" LOC = N7 | IOSTANDARD = "LVTTL"; 251 | #NET "IR<1>" LOC = P7 252 | NET "IR<1>" LOC = E2 | IOSTANDARD = "LVTTL"; 253 | #NET "DI<2>" LOC = E6 254 | NET "DI<2>" LOC = H7 | IOSTANDARD = "LVTTL"; 255 | #NET "PC<3>" LOC = C6 256 | NET "PC<3>" LOC = A9 | IOSTANDARD = "LVTTL"; 257 | #NET "DO<7>" LOC = T7 258 | NET "DO<7>" LOC = H13 | IOSTANDARD = "LVTTL"; 259 | #NET "Vector<7>" LOC = G3 260 | NET "Vector<7>" LOC = L3 | IOSTANDARD = "LVTTL"; 261 | #NET "IR<2>" LOC = D5 262 | NET "IR<2>" LOC = G14 | IOSTANDARD = "LVTTL"; 263 | #NET "DI<3>" LOC = F10 264 | NET "DI<3>" LOC = J7 | IOSTANDARD = "LVTTL"; 265 | #NET "PC<4>" LOC = A8 266 | NET "PC<4>" LOC = L16 | IOSTANDARD = "LVTTL"; 267 | #NET "Int" LOC = D6 268 | NET "Int" LOC = L7 | IOSTANDARD = "LVTTL"; 269 | #NET "Vector<8>" LOC = G1 270 | NET "Vector<8>" LOC = M3 | IOSTANDARD = "LVTTL"; 271 | #NET "IR<3>" LOC = E10 272 | NET "IR<3>" LOC = F16 | IOSTANDARD = "LVTTL"; 273 | #NET "DI<4>" LOC = C1 274 | NET "DI<4>" LOC = N5 | IOSTANDARD = "LVTTL"; 275 | #NET "PC<5>" LOC = L2 276 | NET "PC<5>" LOC = N8 | IOSTANDARD = "LVTTL"; 277 | #NET "OP2<0>" LOC = E7 278 | NET "OP2<0>" LOC = P2 | IOSTANDARD = "LVTTL"; 279 | #NET "Vector<9>" LOC = H7 280 | NET "Vector<9>" LOC = J4 | IOSTANDARD = "LVTTL"; 281 | #NET "IR<4>" LOC = C2 282 | NET "IR<4>" LOC = N4 | IOSTANDARD = "LVTTL"; 283 | #NET "DI<5>" LOC = D9 284 | NET "DI<5>" LOC = J1 | IOSTANDARD = "LVTTL"; 285 | #NET "PC<6>" LOC = J6 286 | NET "PC<6>" LOC = P6 | IOSTANDARD = "LVTTL"; 287 | #NET "OP2<1>" LOC = J1 288 | NET "OP2<1>" LOC = L1 | IOSTANDARD = "LVTTL"; 289 | #NET "IR<5>" LOC = C10 290 | NET "IR<5>" LOC = J2 | IOSTANDARD = "LVTTL"; 291 | #NET "DI<6>" LOC = C9 292 | NET "DI<6>" LOC = D5 | IOSTANDARD = "LVTTL"; 293 | #NET "PC<7>" LOC = C7 294 | NET "PC<7>" LOC = E10 | IOSTANDARD = "LVTTL"; 295 | #NET "Y<0>" LOC = D16 296 | NET "Y<0>" LOC = H3 | IOSTANDARD = "LVTTL"; 297 | #NET "OP2<2>" LOC = L1 298 | NET "OP2<2>" LOC = T6 | IOSTANDARD = "LVTTL"; 299 | #NET "AO<0>" LOC = P1 300 | NET "AO<0>" LOC = K13 | IOSTANDARD = "LVTTL"; 301 | #pin2ucf - Thu Dec 13 23:13:32 2012 302 | #The following constraints were newly added 303 | NET "MC<0>" LOC = D11; 304 | NET "MC<1>" LOC = A14; 305 | NET "Wait" LOC = J6; 306 | NET "uLen<0>" LOC = E4; 307 | NET "uLen<1>" LOC = F4; 308 | NET "MemTyp<0>" LOC = R1; 309 | NET "MemTyp<1>" LOC = P4; 310 | -------------------------------------------------------------------------------- /Src/RTL/M65C02_ClkGen.v: -------------------------------------------------------------------------------- 1 | //////////////////////////////////////////////////////////////////////////////// 2 | // 3 | // Copyright 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: 20:32:33 06/15/2013 45 | // Design Name: M65C02 - WDC W65C02 Microprocessor Re-Implementation 46 | // Module Name: M65C02_ClkGen 47 | // Project Name: C:\XProjects\ISE10.1i\M65C02 48 | // Target Devices: RAM-based FPGAs: XC3S50A-xVQ100; XC3S200A-xVQ100 49 | // Tool versions: Xilinx ISE 10.1i SP3 50 | // 51 | // Description: 52 | // 53 | // This module combines an Architecture Wizard IP instatiation of a DCM_SP to 54 | // generate a 4x clock from an external crystal oscillator. It also generates 55 | // a reset signal to external logic, and a reset signal for internal logic and 56 | // the DCM. An external reset input is accepted, but buffered using a synchro- 57 | // nizer. 58 | // 59 | // Dependencies: ClkGen.xaw 60 | // 61 | // Revision: 62 | // 63 | // 0.01 13F15 MAM Creation Date 64 | // 65 | // 1.00 13F21 MAM Corrected error in the reset generation logic. An 66 | // AND reduction operator was applied to external reset 67 | // shift register. An OR reduction is necessary, and 68 | // is not applied. Asserting the external reset now 69 | // generates a reset pulse several clock cycles in 70 | // width to the internal logic. Added Clk_UART as an 71 | // output taken from the Clk2X output of DCM. Clk_UART 72 | // can noew be fixed at 2x ClkIn. 73 | // 74 | // 1.01 13H17 MAM Adapted for use with the M65C02 75 | // 76 | // Additional Comments: 77 | // 78 | //////////////////////////////////////////////////////////////////////////////// 79 | 80 | module M65C02_ClkGen( 81 | input nRst, // External Reset Input (active low) 82 | input ClkIn, // Reference Input Clk 83 | 84 | output Clk, // Internal Clk - (M/D) x ClkIn 85 | output Clk_UART, // 2x ClkIn 86 | output Buf_ClkIn, // Buffered ClkIn 87 | 88 | output reg Rst // Internal Reset 89 | ); 90 | 91 | //////////////////////////////////////////////////////////////////////////////// 92 | // 93 | // Declarations 94 | // 95 | 96 | wire DCM_Locked; // DCM Locked Status Signal 97 | 98 | reg [3:0] DCM_Rst; // Stretched DCM Reset (see Table 3-6 UG331) 99 | reg nRst_IFD; // Input FF for external Reset signal 100 | reg [3:0] xRst; // Stretched external reset (BufClkIn) 101 | wire Rst_M65C02; // Combination of DCM_Rst and xRst 102 | reg [3:0] Rst_Dly; // Stretched internal reset (BufClkIn) 103 | wire FE_Rst_Dly; // Falling edge of Rst_Dly (Clk) 104 | 105 | //////////////////////////////////////////////////////////////////////////////// 106 | // 107 | // Implementation 108 | // 109 | 110 | // Implement internal clock generator using DCM and DFS. DCM/DFS multiplies 111 | // external clock reference by 4. 112 | 113 | ClkGen ClkGen ( 114 | .USER_RST_IN(DCM_Rst[0]), // DCM Rst generated on FE Lock 115 | 116 | .CLKIN_IN(ClkIn), // ClkIn = 14.7456 MHz 117 | .CLKIN_IBUFG_OUT(Buf_ClkIn), // Buffered ClkIn = 14.7456 MHz 118 | 119 | .CLKFX_OUT(Clk), // DCM ClkFX_Out = 58.9824 MHz 120 | 121 | .CLK0_OUT(), // Clk0_Out unused 122 | .CLK2X_OUT(Clk_UART), // Clk2x_Out (FB) = 29.4912 MHz 123 | 124 | .LOCKED_OUT(DCM_Locked) // When 1, DCM Locked 125 | ); 126 | 127 | // Detect falling edge of DCM_Locked, and generate DCM reset pulse at least 4 128 | // ClkIn periods wide if a falling edge is detected. (see Table 3-6 UG331) 129 | 130 | fedet FE1 ( 131 | .rst(1'b0), // No reset required for this circuit 132 | .clk(Buf_ClkIn), // Buffered DCM input Clock 133 | .din(DCM_Locked), // DCM Locked signal 134 | .pls(FE_DCM_Locked) // Falling Edge of DCM_Locked signal 135 | ); 136 | 137 | always @(posedge Buf_ClkIn or posedge FE_DCM_Locked) 138 | begin 139 | if(FE_DCM_Locked) 140 | DCM_Rst <= #1 4'b1111; 141 | else 142 | DCM_Rst <= #1 {1'b0, DCM_Rst[3:1]}; 143 | end 144 | 145 | // Synchronize asynchronous external reset, nRst, to internal clock and 146 | // stretch (extend) by 16 clock cycles after external reset deasserted 147 | // 148 | // With Spartan 3A(N) FPGA family use synchronous reset for reset operations 149 | // per synthesis recommendations. so only these FFs will use asynchronous 150 | // reset, and the remainder of the design will use synchronous reset. 151 | 152 | always @(posedge Buf_ClkIn or negedge DCM_Locked) 153 | begin 154 | if(~DCM_Locked) 155 | nRst_IFD <= #1 0; 156 | else 157 | nRst_IFD <= #1 nRst; 158 | end 159 | 160 | always @(posedge Buf_ClkIn or negedge DCM_Locked) 161 | begin 162 | if(~DCM_Locked) 163 | xRst <= #1 ~0; 164 | else 165 | xRst <= #1 {~nRst_IFD, xRst[2:1]}; 166 | end 167 | 168 | assign Rst_M65C02 = ((|{~nRst_IFD, xRst}) | ~DCM_Locked); 169 | 170 | always @(posedge Buf_ClkIn or posedge Rst_M65C02) 171 | begin 172 | if (Rst_M65C02) 173 | Rst_Dly <= #1 ~0; 174 | else 175 | Rst_Dly <= #1 {1'b0, Rst_Dly[3:1]}; 176 | end 177 | 178 | // synchronize Rst to DCM/DFS output clock (if DCM Locked) 179 | 180 | fedet FE2 ( 181 | .rst(Rst_M65C02), 182 | .clk(Clk), // System Clock 183 | .din(|Rst_Dly), // System Reset Delay 184 | .pls(FE_Rst_Dly) // Falling Edge of Rst_Dly 185 | ); 186 | 187 | always @(posedge Clk or posedge Rst_M65C02) 188 | begin 189 | if(Rst_M65C02) 190 | Rst <= #1 1; 191 | else if(FE_Rst_Dly) 192 | Rst <= #1 0; 193 | end 194 | 195 | endmodule 196 | -------------------------------------------------------------------------------- /Src/RTL/M65C02_Core.ucf: -------------------------------------------------------------------------------- 1 | CONFIG VCCAUX=3.3; 2 | NET "Clk" TNM_NET = Clk; 3 | #TIMESPEC TS_Clk = PERIOD "Clk" 6.000 ns HIGH 50%; #Virtex 5 LXT after removal ~|(reg) 4 | #TIMESPEC TS_Clk = PERIOD "Clk" 15 ns HIGH 50%; #Spartan II after removal ~|(reg) 5 | #TIMESPEC TS_Clk = PERIOD "Clk" 9.755 ns HIGH 50%; #Spartan 3AN before removal ~|(reg) 6 | #TIMESPEC TS_Clk = PERIOD "Clk" 9.091 ns HIGH 50%; #Spartan 3AN after removal ~|(reg) 7 | TIMESPEC TS_Clk = PERIOD "Clk" 10.000 ns HIGH 50%; #Spartan 3AN after removal ~|(reg) 8 | #TIMESPEC TS_Clk = PERIOD "Clk" 9.500 ns HIGH 50%; #Spartan 3AN after removal ~|(reg) 9 | #TIMESPEC TS_Clk = PERIOD "Clk" 9.375 ns HIGH 50%; #Spartan 3AN after removal ~|(reg) 10 | #TIMESPEC TS_Clk = PERIOD "Clk" 9.250 ns HIGH 50%; #Spartan 3AN after removal ~|(reg) 11 | #TIMESPEC TS_Clk = PERIOD "Clk" 9.150 ns HIGH 50%; #Spartan 3AN after removal ~|(reg) 12 | NET "MemTyp<0>" IOSTANDARD = "LVTTL"; 13 | NET "MemTyp<1>" IOSTANDARD = "LVTTL"; 14 | NET "MC<0>" IOSTANDARD = "LVTTL"; 15 | NET "MC<1>" IOSTANDARD = "LVTTL"; 16 | NET "uLen<0>" IOSTANDARD = "LVTTL"; 17 | NET "uLen<1>" IOSTANDARD = "LVTTL"; 18 | NET "xIRQ" IOSTANDARD = "LVTTL"; 19 | NET "SC" IOSTANDARD = "LVTTL"; 20 | NET "Vector<0>" IOSTANDARD = "LVTTL"; 21 | NET "Vector<1>" IOSTANDARD = "LVTTL"; 22 | NET "Vector<2>" IOSTANDARD = "LVTTL"; 23 | NET "Vector<3>" IOSTANDARD = "LVTTL"; 24 | NET "Vector<4>" IOSTANDARD = "LVTTL"; 25 | NET "Vector<5>" IOSTANDARD = "LVTTL"; 26 | NET "Vector<6>" IOSTANDARD = "LVTTL"; 27 | NET "Vector<7>" IOSTANDARD = "LVTTL"; 28 | NET "Vector<8>" IOSTANDARD = "LVTTL"; 29 | NET "Vector<9>" IOSTANDARD = "LVTTL"; 30 | NET "Vector<10>" IOSTANDARD = "LVTTL"; 31 | NET "Vector<11>" IOSTANDARD = "LVTTL"; 32 | NET "Vector<12>" IOSTANDARD = "LVTTL"; 33 | NET "Vector<13>" IOSTANDARD = "LVTTL"; 34 | NET "Vector<14>" IOSTANDARD = "LVTTL"; 35 | NET "Vector<15>" IOSTANDARD = "LVTTL"; 36 | NET "A<0>" IOSTANDARD = "LVTTL"; 37 | NET "A<1>" IOSTANDARD = "LVTTL"; 38 | NET "A<2>" IOSTANDARD = "LVTTL"; 39 | NET "A<3>" IOSTANDARD = "LVTTL"; 40 | NET "A<4>" IOSTANDARD = "LVTTL"; 41 | NET "A<5>" IOSTANDARD = "LVTTL"; 42 | NET "A<6>" IOSTANDARD = "LVTTL"; 43 | NET "A<7>" IOSTANDARD = "LVTTL"; 44 | NET "Wait" IOSTANDARD = "LVTTL"; 45 | NET "Clk" IOSTANDARD = "LVTTL"; 46 | NET "IR<0>" IOSTANDARD = "LVTTL"; 47 | NET "IR<1>" IOSTANDARD = "LVTTL"; 48 | NET "IR<2>" IOSTANDARD = "LVTTL"; 49 | NET "IR<3>" IOSTANDARD = "LVTTL"; 50 | NET "IR<4>" IOSTANDARD = "LVTTL"; 51 | NET "IR<5>" IOSTANDARD = "LVTTL"; 52 | NET "IR<6>" IOSTANDARD = "LVTTL"; 53 | NET "IR<7>" IOSTANDARD = "LVTTL"; 54 | NET "Int" IOSTANDARD = "LVTTL"; 55 | NET "OP1<0>" IOSTANDARD = "LVTTL"; 56 | NET "OP1<1>" IOSTANDARD = "LVTTL"; 57 | NET "OP1<2>" IOSTANDARD = "LVTTL"; 58 | NET "OP1<3>" IOSTANDARD = "LVTTL"; 59 | NET "OP1<4>" IOSTANDARD = "LVTTL"; 60 | NET "OP1<5>" IOSTANDARD = "LVTTL"; 61 | NET "OP1<6>" IOSTANDARD = "LVTTL"; 62 | NET "OP1<7>" IOSTANDARD = "LVTTL"; 63 | NET "OP2<0>" IOSTANDARD = "LVTTL"; 64 | NET "OP2<1>" IOSTANDARD = "LVTTL"; 65 | NET "OP2<2>" IOSTANDARD = "LVTTL"; 66 | NET "OP2<3>" IOSTANDARD = "LVTTL"; 67 | NET "OP2<4>" IOSTANDARD = "LVTTL"; 68 | NET "OP2<5>" IOSTANDARD = "LVTTL"; 69 | NET "OP2<6>" IOSTANDARD = "LVTTL"; 70 | NET "OP2<7>" IOSTANDARD = "LVTTL"; 71 | NET "P<0>" IOSTANDARD = "LVTTL"; 72 | NET "P<1>" IOSTANDARD = "LVTTL"; 73 | NET "P<2>" IOSTANDARD = "LVTTL"; 74 | NET "P<3>" IOSTANDARD = "LVTTL"; 75 | NET "P<4>" IOSTANDARD = "LVTTL"; 76 | NET "P<5>" IOSTANDARD = "LVTTL"; 77 | NET "P<6>" IOSTANDARD = "LVTTL"; 78 | NET "P<7>" IOSTANDARD = "LVTTL"; 79 | NET "PC<0>" IOSTANDARD = "LVTTL"; 80 | NET "PC<1>" IOSTANDARD = "LVTTL"; 81 | NET "PC<2>" IOSTANDARD = "LVTTL"; 82 | NET "PC<3>" IOSTANDARD = "LVTTL"; 83 | NET "PC<4>" IOSTANDARD = "LVTTL"; 84 | NET "PC<5>" IOSTANDARD = "LVTTL"; 85 | NET "PC<6>" IOSTANDARD = "LVTTL"; 86 | NET "PC<7>" IOSTANDARD = "LVTTL"; 87 | NET "PC<8>" IOSTANDARD = "LVTTL"; 88 | NET "PC<9>" IOSTANDARD = "LVTTL"; 89 | NET "PC<10>" IOSTANDARD = "LVTTL"; 90 | NET "PC<11>" IOSTANDARD = "LVTTL"; 91 | NET "PC<12>" IOSTANDARD = "LVTTL"; 92 | NET "PC<13>" IOSTANDARD = "LVTTL"; 93 | NET "PC<14>" IOSTANDARD = "LVTTL"; 94 | NET "PC<15>" IOSTANDARD = "LVTTL"; 95 | NET "Rst" IOSTANDARD = "LVTTL"; 96 | NET "S<0>" IOSTANDARD = "LVTTL"; 97 | NET "S<1>" IOSTANDARD = "LVTTL"; 98 | NET "S<2>" IOSTANDARD = "LVTTL"; 99 | NET "S<3>" IOSTANDARD = "LVTTL"; 100 | NET "S<4>" IOSTANDARD = "LVTTL"; 101 | NET "S<5>" IOSTANDARD = "LVTTL"; 102 | NET "S<6>" IOSTANDARD = "LVTTL"; 103 | NET "S<7>" IOSTANDARD = "LVTTL"; 104 | NET "X<0>" IOSTANDARD = "LVTTL"; 105 | NET "X<1>" IOSTANDARD = "LVTTL"; 106 | NET "X<2>" IOSTANDARD = "LVTTL"; 107 | NET "X<3>" IOSTANDARD = "LVTTL"; 108 | NET "X<4>" IOSTANDARD = "LVTTL"; 109 | NET "X<5>" IOSTANDARD = "LVTTL"; 110 | NET "X<6>" IOSTANDARD = "LVTTL"; 111 | NET "X<7>" IOSTANDARD = "LVTTL"; 112 | NET "AO<0>" IOSTANDARD = "LVTTL"; 113 | NET "AO<1>" IOSTANDARD = "LVTTL"; 114 | NET "AO<2>" IOSTANDARD = "LVTTL"; 115 | NET "AO<3>" IOSTANDARD = "LVTTL"; 116 | NET "AO<4>" IOSTANDARD = "LVTTL"; 117 | NET "AO<5>" IOSTANDARD = "LVTTL"; 118 | NET "AO<6>" IOSTANDARD = "LVTTL"; 119 | NET "AO<7>" IOSTANDARD = "LVTTL"; 120 | NET "AO<8>" IOSTANDARD = "LVTTL"; 121 | NET "AO<9>" IOSTANDARD = "LVTTL"; 122 | NET "AO<10>" IOSTANDARD = "LVTTL"; 123 | NET "AO<11>" IOSTANDARD = "LVTTL"; 124 | NET "AO<12>" IOSTANDARD = "LVTTL"; 125 | NET "AO<13>" IOSTANDARD = "LVTTL"; 126 | NET "AO<14>" IOSTANDARD = "LVTTL"; 127 | NET "AO<15>" IOSTANDARD = "LVTTL"; 128 | NET "DI<0>" IOSTANDARD = "LVTTL"; 129 | NET "DI<1>" IOSTANDARD = "LVTTL"; 130 | NET "DI<2>" IOSTANDARD = "LVTTL"; 131 | NET "DI<3>" IOSTANDARD = "LVTTL"; 132 | NET "DI<4>" IOSTANDARD = "LVTTL"; 133 | NET "DI<5>" IOSTANDARD = "LVTTL"; 134 | NET "DI<6>" IOSTANDARD = "LVTTL"; 135 | NET "DI<7>" IOSTANDARD = "LVTTL"; 136 | NET "DO<0>" IOSTANDARD = "LVTTL"; 137 | NET "DO<1>" IOSTANDARD = "LVTTL"; 138 | NET "DO<2>" IOSTANDARD = "LVTTL"; 139 | NET "DO<3>" IOSTANDARD = "LVTTL"; 140 | NET "DO<4>" IOSTANDARD = "LVTTL"; 141 | NET "DO<5>" IOSTANDARD = "LVTTL"; 142 | NET "DO<6>" IOSTANDARD = "LVTTL"; 143 | NET "DO<7>" IOSTANDARD = "LVTTL"; 144 | NET "Y<0>" IOSTANDARD = "LVTTL"; 145 | NET "Y<1>" IOSTANDARD = "LVTTL"; 146 | NET "Y<2>" IOSTANDARD = "LVTTL"; 147 | NET "Y<3>" IOSTANDARD = "LVTTL"; 148 | NET "Y<4>" IOSTANDARD = "LVTTL"; 149 | NET "Y<5>" IOSTANDARD = "LVTTL"; 150 | NET "Y<6>" IOSTANDARD = "LVTTL"; 151 | NET "Y<7>" IOSTANDARD = "LVTTL"; 152 | NET "RMW" IOSTANDARD = "LVTTL"; 153 | NET "IRQ_Msk" IOSTANDARD = "LVTTL"; 154 | NET "Mode<0>" IOSTANDARD = "LVTTL"; 155 | NET "Mode<1>" IOSTANDARD = "LVTTL"; 156 | NET "Mode<2>" IOSTANDARD = "LVTTL"; 157 | NET "Done" IOSTANDARD = "LVTTL"; 158 | NET "IO_Op<0>" IOSTANDARD = "LVTTL"; 159 | NET "IO_Op<1>" IOSTANDARD = "LVTTL"; 160 | NET "SC" SLEW = FAST; 161 | NET "Y<7>" SLEW = FAST; 162 | NET "Y<6>" SLEW = FAST; 163 | NET "Y<5>" SLEW = FAST; 164 | NET "Y<4>" SLEW = FAST; 165 | NET "Y<3>" SLEW = FAST; 166 | NET "Y<2>" SLEW = FAST; 167 | NET "Y<1>" SLEW = FAST; 168 | NET "Y<0>" SLEW = FAST; 169 | NET "DO<7>" SLEW = FAST; 170 | NET "DO<6>" SLEW = FAST; 171 | NET "DO<5>" SLEW = FAST; 172 | NET "DO<4>" SLEW = FAST; 173 | NET "DO<3>" SLEW = FAST; 174 | NET "DO<2>" SLEW = FAST; 175 | NET "DO<1>" SLEW = FAST; 176 | NET "DO<0>" SLEW = FAST; 177 | NET "DO<0>" DRIVE = 24; 178 | NET "DO<1>" DRIVE = 24; 179 | NET "DO<2>" DRIVE = 24; 180 | NET "DO<3>" DRIVE = 24; 181 | NET "DO<4>" DRIVE = 24; 182 | NET "DO<5>" DRIVE = 24; 183 | NET "DO<6>" DRIVE = 24; 184 | NET "DO<7>" DRIVE = 24; 185 | NET "AO<15>" SLEW = FAST; 186 | NET "AO<14>" SLEW = FAST; 187 | NET "AO<15>" DRIVE = 12; 188 | NET "AO<14>" DRIVE = 12; 189 | NET "AO<13>" DRIVE = 12; 190 | NET "AO<13>" SLEW = FAST; 191 | NET "AO<12>" DRIVE = 12; 192 | NET "AO<11>" DRIVE = 12; 193 | NET "AO<10>" DRIVE = 12; 194 | NET "AO<9>" DRIVE = 12; 195 | NET "AO<8>" DRIVE = 12; 196 | NET "AO<7>" DRIVE = 12; 197 | NET "AO<12>" SLEW = FAST; 198 | NET "AO<11>" SLEW = FAST; 199 | NET "AO<10>" SLEW = FAST; 200 | NET "AO<9>" SLEW = FAST; 201 | NET "AO<8>" SLEW = FAST; 202 | NET "AO<7>" SLEW = FAST; 203 | NET "AO<6>" DRIVE = 12; 204 | NET "AO<5>" DRIVE = 12; 205 | NET "AO<4>" DRIVE = 12; 206 | NET "AO<3>" DRIVE = 12; 207 | NET "AO<2>" DRIVE = 12; 208 | NET "AO<1>" DRIVE = 12; 209 | NET "AO<2>" SLEW = FAST; 210 | NET "AO<1>" SLEW = FAST; 211 | NET "AO<3>" SLEW = FAST; 212 | NET "AO<4>" SLEW = FAST; 213 | NET "AO<5>" SLEW = FAST; 214 | NET "AO<6>" SLEW = FAST; 215 | NET "X<1>" DRIVE = 4; 216 | NET "X<2>" DRIVE = 4; 217 | NET "X<3>" DRIVE = 4; 218 | NET "X<4>" DRIVE = 4; 219 | NET "X<5>" DRIVE = 4; 220 | NET "X<6>" DRIVE = 4; 221 | NET "X<7>" DRIVE = 4; 222 | NET "AO<0>" DRIVE = 12; 223 | NET "AO<0>" SLEW = FAST; 224 | NET "X<7>" SLEW = FAST; 225 | NET "X<6>" SLEW = FAST; 226 | NET "X<5>" SLEW = FAST; 227 | NET "X<4>" SLEW = FAST; 228 | NET "X<3>" SLEW = FAST; 229 | NET "X<2>" SLEW = FAST; 230 | NET "X<1>" SLEW = FAST; 231 | NET "Y<0>" DRIVE = 4; 232 | NET "Y<1>" DRIVE = 4; 233 | NET "Y<2>" DRIVE = 4; 234 | NET "Y<3>" DRIVE = 4; 235 | NET "Y<4>" DRIVE = 4; 236 | NET "Y<5>" DRIVE = 4; 237 | NET "Y<6>" DRIVE = 4; 238 | NET "Y<7>" DRIVE = 4; 239 | NET "X<0>" DRIVE = 4; 240 | NET "X<0>" SLEW = FAST; 241 | NET "S<0>" DRIVE = 4; 242 | NET "S<1>" DRIVE = 4; 243 | NET "S<2>" DRIVE = 4; 244 | NET "S<3>" DRIVE = 4; 245 | NET "S<4>" DRIVE = 4; 246 | NET "S<5>" DRIVE = 4; 247 | NET "S<6>" DRIVE = 4; 248 | NET "S<7>" DRIVE = 4; 249 | NET "S<0>" SLEW = FAST; 250 | NET "S<1>" SLEW = FAST; 251 | NET "S<2>" SLEW = FAST; 252 | NET "S<3>" SLEW = FAST; 253 | NET "S<4>" SLEW = FAST; 254 | NET "S<5>" SLEW = FAST; 255 | NET "S<6>" SLEW = FAST; 256 | NET "S<7>" SLEW = FAST; 257 | NET "PC<7>" DRIVE = 4; 258 | NET "PC<8>" DRIVE = 4; 259 | NET "PC<9>" DRIVE = 4; 260 | NET "PC<10>" DRIVE = 4; 261 | NET "PC<11>" DRIVE = 4; 262 | NET "PC<12>" DRIVE = 4; 263 | NET "PC<13>" DRIVE = 4; 264 | NET "PC<14>" DRIVE = 4; 265 | NET "PC<15>" DRIVE = 4; 266 | NET "PC<15>" SLEW = FAST; 267 | NET "PC<14>" SLEW = FAST; 268 | NET "PC<13>" SLEW = FAST; 269 | NET "PC<12>" SLEW = FAST; 270 | NET "PC<11>" SLEW = FAST; 271 | NET "PC<10>" SLEW = FAST; 272 | NET "PC<9>" SLEW = FAST; 273 | NET "PC<8>" SLEW = FAST; 274 | NET "PC<7>" SLEW = FAST; 275 | NET "PC<0>" DRIVE = 4; 276 | NET "PC<1>" DRIVE = 4; 277 | NET "PC<2>" DRIVE = 4; 278 | NET "PC<3>" DRIVE = 4; 279 | NET "PC<4>" DRIVE = 4; 280 | NET "PC<5>" DRIVE = 4; 281 | NET "PC<6>" DRIVE = 4; 282 | NET "PC<0>" SLEW = FAST; 283 | NET "PC<1>" SLEW = FAST; 284 | NET "PC<2>" SLEW = FAST; 285 | NET "PC<3>" SLEW = FAST; 286 | NET "PC<4>" SLEW = FAST; 287 | NET "PC<5>" SLEW = FAST; 288 | NET "PC<6>" SLEW = FAST; 289 | NET "P<7>" DRIVE = 4; 290 | NET "P<6>" DRIVE = 4; 291 | NET "P<5>" DRIVE = 4; 292 | NET "P<4>" DRIVE = 4; 293 | NET "P<3>" DRIVE = 4; 294 | NET "P<2>" DRIVE = 4; 295 | NET "P<1>" DRIVE = 4; 296 | NET "P<0>" DRIVE = 4; 297 | NET "P<0>" SLEW = FAST; 298 | NET "P<1>" SLEW = FAST; 299 | NET "P<2>" SLEW = FAST; 300 | NET "P<3>" SLEW = FAST; 301 | NET "P<4>" SLEW = FAST; 302 | NET "P<5>" SLEW = FAST; 303 | NET "P<6>" SLEW = FAST; 304 | NET "P<7>" SLEW = FAST; 305 | NET "OP2<7>" DRIVE = 4; 306 | NET "OP2<6>" DRIVE = 4; 307 | NET "OP2<5>" DRIVE = 4; 308 | NET "OP2<4>" DRIVE = 4; 309 | NET "OP2<3>" DRIVE = 4; 310 | NET "OP2<2>" DRIVE = 4; 311 | NET "OP2<1>" DRIVE = 4; 312 | NET "OP2<1>" SLEW = FAST; 313 | NET "OP2<2>" SLEW = FAST; 314 | NET "OP2<3>" SLEW = FAST; 315 | NET "OP2<4>" SLEW = FAST; 316 | NET "OP2<5>" SLEW = FAST; 317 | NET "OP2<6>" SLEW = FAST; 318 | NET "OP2<7>" SLEW = FAST; 319 | NET "OP2<0>" DRIVE = 4; 320 | NET "OP1<7>" DRIVE = 4; 321 | NET "OP1<6>" DRIVE = 4; 322 | NET "OP1<5>" DRIVE = 4; 323 | NET "OP1<4>" DRIVE = 4; 324 | NET "OP1<3>" DRIVE = 4; 325 | NET "OP1<2>" DRIVE = 4; 326 | NET "OP1<1>" DRIVE = 4; 327 | NET "OP1<0>" DRIVE = 4; 328 | NET "OP1<0>" SLEW = FAST; 329 | NET "OP1<1>" SLEW = FAST; 330 | NET "OP1<2>" SLEW = FAST; 331 | NET "OP1<3>" SLEW = FAST; 332 | NET "OP1<4>" SLEW = FAST; 333 | NET "OP1<5>" SLEW = FAST; 334 | NET "OP1<6>" SLEW = FAST; 335 | NET "OP1<7>" SLEW = FAST; 336 | NET "OP2<0>" SLEW = FAST; 337 | NET "IR<7>" DRIVE = 4; 338 | NET "IR<6>" DRIVE = 4; 339 | NET "IR<5>" DRIVE = 4; 340 | NET "IR<4>" DRIVE = 4; 341 | NET "IR<3>" DRIVE = 4; 342 | NET "IR<2>" DRIVE = 4; 343 | NET "IR<1>" DRIVE = 4; 344 | NET "IR<0>" DRIVE = 4; 345 | NET "IR<7>" SLEW = FAST; 346 | NET "IR<6>" SLEW = FAST; 347 | NET "IR<5>" SLEW = FAST; 348 | NET "IR<4>" SLEW = FAST; 349 | NET "IR<3>" SLEW = FAST; 350 | NET "IR<2>" SLEW = FAST; 351 | NET "IR<1>" SLEW = FAST; 352 | NET "IR<0>" SLEW = FAST; 353 | NET "A<0>" DRIVE = 4; 354 | NET "A<1>" DRIVE = 4; 355 | NET "A<2>" DRIVE = 4; 356 | NET "A<3>" DRIVE = 4; 357 | NET "A<4>" DRIVE = 4; 358 | NET "A<5>" DRIVE = 4; 359 | NET "A<6>" DRIVE = 4; 360 | NET "A<7>" DRIVE = 4; 361 | NET "A<0>" SLEW = FAST; 362 | NET "A<1>" SLEW = FAST; 363 | NET "A<2>" SLEW = FAST; 364 | NET "A<3>" SLEW = FAST; 365 | NET "A<4>" SLEW = FAST; 366 | NET "A<5>" SLEW = FAST; 367 | NET "A<6>" SLEW = FAST; 368 | NET "SC" DRIVE = 4; 369 | NET "RMW" DRIVE = 4; 370 | NET "RMW" SLEW = FAST; 371 | NET "IRQ_Msk" DRIVE = 4; 372 | NET "Mode<0>" DRIVE = 4; 373 | NET "Mode<1>" DRIVE = 4; 374 | NET "Mode<2>" DRIVE = 4; 375 | NET "IRQ_Msk" SLEW = FAST; 376 | NET "Mode<0>" SLEW = FAST; 377 | NET "Mode<1>" SLEW = FAST; 378 | NET "Mode<2>" SLEW = FAST; 379 | NET "Done" DRIVE = 4; 380 | NET "Done" SLEW = FAST; 381 | NET "IO_Op<0>" DRIVE = 4; 382 | NET "IO_Op<1>" DRIVE = 4; 383 | NET "IO_Op<0>" SLEW = FAST; 384 | NET "IO_Op<1>" SLEW = FAST; 385 | NET "A<7>" SLEW = FAST; 386 | NET "Rdy" IOSTANDARD = "LVTTL"; 387 | NET "Rdy" DRIVE = 4; 388 | NET "Rdy" SLEW = FAST; 389 | NET "IntSvc" IOSTANDARD = "LVTTL"; 390 | NET "IntSvc" DRIVE = 4; 391 | #pin2ucf - Thu Dec 13 23:31:12 2012 392 | #The following constraints were newly added 393 | NET "IR<6>" LOC = C4; 394 | NET "DI<7>" LOC = L2; 395 | NET "PC<8>" LOC = T10; 396 | NET "Y<1>" LOC = G1; 397 | NET "OP2<3>" LOC = K3; 398 | NET "AO<1>" LOC = L13; 399 | NET "IR<7>" LOC = K14; 400 | NET "Y<2>" LOC = A5; 401 | NET "Clk" LOC = C10; 402 | NET "PC<9>" LOC = R3; 403 | NET "OP2<4>" LOC = P1; 404 | NET "IRQ_Msk" LOC = P11; 405 | NET "AO<2>" LOC = J16; 406 | NET "Y<3>" LOC = H4; 407 | NET "AO<10>" LOC = H15; 408 | NET "OP2<5>" LOC = N3; 409 | NET "RMW" LOC = G2; 410 | NET "AO<3>" LOC = L14; 411 | NET "PC<10>" LOC = T8; 412 | NET "Y<4>" LOC = A6; 413 | NET "MC<0>" LOC = D11; 414 | NET "AO<11>" LOC = M16; 415 | NET "OP2<6>" LOC = T2; 416 | NET "S<0>" LOC = C7; 417 | NET "AO<4>" LOC = J12; 418 | NET "PC<11>" LOC = N9; 419 | NET "Y<5>" LOC = F1; 420 | NET "MC<1>" LOC = A14; 421 | NET "AO<12>" LOC = M14; 422 | NET "OP2<7>" LOC = K4; 423 | NET "S<1>" LOC = B6; 424 | NET "AO<5>" LOC = T11; 425 | NET "PC<12>" LOC = K1; 426 | NET "Y<6>" LOC = C9; 427 | NET "AO<13>" LOC = H16; 428 | NET "S<2>" LOC = B15; 429 | NET "P<0>" LOC = G3; 430 | NET "AO<6>" LOC = J14; 431 | NET "PC<13>" LOC = M4; 432 | NET "Y<7>" LOC = C6; 433 | NET "AO<14>" LOC = E14; 434 | NET "S<3>" LOC = A12; 435 | NET "P<1>" LOC = G4; 436 | NET "AO<7>" LOC = K15; 437 | NET "PC<14>" LOC = N2; 438 | NET "AO<15>" LOC = F14; 439 | NET "S<4>" LOC = D15; 440 | NET "P<2>" LOC = C11; 441 | NET "Rst" LOC = L6; 442 | NET "AO<8>" LOC = M15; 443 | NET "PC<15>" LOC = K16; 444 | NET "S<5>" LOC = B10; 445 | NET "P<3>" LOC = C12; 446 | NET "AO<9>" LOC = J13; 447 | NET "Wait" LOC = J6; 448 | NET "S<6>" LOC = A10; 449 | NET "P<4>" LOC = H5; 450 | NET "S<7>" LOC = B12; 451 | NET "P<5>" LOC = C13; 452 | NET "OP1<0>" LOC = C2; 453 | NET "P<6>" LOC = C8; 454 | NET "OP1<1>" LOC = E13; 455 | NET "P<7>" LOC = A8; 456 | NET "X<0>" LOC = E7; 457 | NET "OP1<2>" LOC = D4; 458 | NET "X<1>" LOC = F3; 459 | NET "OP1<3>" LOC = B3; 460 | NET "uLen<0>" LOC = E4; 461 | NET "X<2>" LOC = F8; 462 | NET "OP1<4>" LOC = A3; 463 | NET "uLen<1>" LOC = F4; 464 | NET "X<3>" LOC = B8; 465 | NET "OP1<5>" LOC = B14; 466 | NET "X<4>" LOC = C5; 467 | NET "A<0>" LOC = D7; 468 | NET "OP1<6>" LOC = H6; 469 | NET "X<5>" LOC = D9; 470 | NET "A<1>" LOC = D1; 471 | NET "OP1<7>" LOC = A13; 472 | NET "X<6>" LOC = A11; 473 | NET "A<2>" LOC = F13; 474 | NET "SC" LOC = P7; 475 | NET "X<7>" LOC = B4; 476 | NET "A<3>" LOC = D16; 477 | NET "IO_Op<0>" LOC = R2; 478 | NET "IO_Op<1>" LOC = J3; 479 | NET "A<4>" LOC = A7; 480 | NET "A<5>" LOC = A4; 481 | NET "MemTyp<0>" LOC = R1; 482 | NET "A<6>" LOC = E3; 483 | NET "MemTyp<1>" LOC = P4; 484 | NET "A<7>" LOC = D8; 485 | NET "Vector<10>" LOC = N1; 486 | NET "IntSvc" LOC = D14; 487 | NET "Vector<11>" LOC = L4; 488 | NET "Mode<0>" LOC = T5; 489 | NET "Vector<12>" LOC = L5; 490 | NET "Mode<1>" LOC = N6; 491 | NET "DO<0>" LOC = R11; 492 | NET "Vector<0>" LOC = T7; 493 | NET "Vector<13>" LOC = N10; 494 | NET "xIRQ" LOC = P8; 495 | NET "Mode<2>" LOC = H1; 496 | NET "DO<1>" LOC = H14; 497 | NET "Vector<1>" LOC = P10; 498 | NET "Vector<14>" LOC = K6; 499 | NET "DO<2>" LOC = G13; 500 | NET "Vector<2>" LOC = M10; 501 | NET "Vector<15>" LOC = P9; 502 | NET "DO<3>" LOC = F15; 503 | NET "Vector<3>" LOC = K5; 504 | NET "Done" LOC = P12; 505 | NET "PC<0>" LOC = R7; 506 | NET "DO<4>" LOC = G16; 507 | NET "Vector<4>" LOC = M1; 508 | NET "DI<0>" LOC = G6; 509 | NET "PC<1>" LOC = R9; 510 | NET "DO<5>" LOC = D10; 511 | NET "Vector<5>" LOC = T9; 512 | NET "Rdy" LOC = D3; 513 | NET "IR<0>" LOC = E1; 514 | NET "DI<1>" LOC = G5; 515 | NET "PC<2>" LOC = P5; 516 | NET "DO<6>" LOC = E16; 517 | NET "Vector<6>" LOC = N7; 518 | NET "IR<1>" LOC = E2; 519 | NET "DI<2>" LOC = H7; 520 | NET "PC<3>" LOC = A9; 521 | NET "DO<7>" LOC = H13; 522 | NET "Vector<7>" LOC = L3; 523 | NET "IR<2>" LOC = G14; 524 | NET "DI<3>" LOC = J7; 525 | NET "PC<4>" LOC = L16; 526 | NET "Int" LOC = L7; 527 | NET "Vector<8>" LOC = M3; 528 | NET "IR<3>" LOC = F16; 529 | NET "DI<4>" LOC = N5; 530 | NET "PC<5>" LOC = N8; 531 | NET "OP2<0>" LOC = P2; 532 | NET "Vector<9>" LOC = J4; 533 | NET "IR<4>" LOC = N4; 534 | NET "DI<5>" LOC = J1; 535 | NET "PC<6>" LOC = P6; 536 | NET "OP2<1>" LOC = L1; 537 | NET "IR<5>" LOC = J2; 538 | NET "DI<6>" LOC = D5; 539 | NET "PC<7>" LOC = E10; 540 | NET "Y<0>" LOC = H3; 541 | NET "OP2<2>" LOC = T6; 542 | NET "AO<0>" LOC = K13; 543 | -------------------------------------------------------------------------------- /Src/RTL/M65C02_IntHndlr.v: -------------------------------------------------------------------------------- 1 | //////////////////////////////////////////////////////////////////////////////// 2 | // 3 | // Copyright 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: 12:06:18 08/18/2013 45 | // Design Name: WDC W65C02 Microprocessor Re-Implementation 46 | // Module Name: M65C02_IntHndlr.v 47 | // Project Name: C:\XProjects\ISE10.1i\M65C02 48 | // Target Devices: SRAM-based FPGAs: XC3S50A-xVQ100I, XC3S200A-xVQ100I 49 | // Tool versions: Xilinx ISE 10.1i SP3 50 | // 51 | // Description: 52 | // 53 | // This module implements a simple interrupt handler for the M65C02 soft-core 54 | // microprocessor. It accepts external active low inputs for Non-Maskable 55 | // Interrupt request (nNMI) and maskable Interrupt ReQuest (nIRQ). It synchro- 56 | // nizes both inputs to the internal system clock (Clk), and generates internal 57 | // signals NMI and IRQ. NMI is falling edge sensitive, and IRQ is active low 58 | // level sensitive. The module also accepts the core's mode output (Mode) and 59 | // generates an internal BReaK software trap request (BRK). 60 | // 61 | // The non-maskable interrupt request, nNMI, has priority, followed by BRK, and 62 | // finally nIRQ. The core, from the I bit in the processor register, provides a 63 | // mask that prevents the generation of the internal IRQ signal. 64 | // 65 | // Vectors for each of the four interrupt/trap sources are set using para- 66 | // meters. The current implementation aims to maintain compatibility with the 67 | // WDC W65C02S processor, so IRQ and BRK share the same vector. A quick edit 68 | // of the parameters allows an independent vector location to be added for BRK. 69 | // Similarly, the vectors for any of the interrupt/trap sources can be moved 70 | // to any location in the memory space, if W65C02S compatibility is not desired 71 | // or required. 72 | // 73 | // Dependencies: fedet.v 74 | // 75 | // Revision: 76 | // 77 | // 0.01 13H18 MAM File Created 78 | // 79 | // Additional Comments: 80 | // 81 | /////////////////////////////////////////////////////////////////////////////// 82 | 83 | module M65C02_IntHndlr #( 84 | parameter pIRQ_Vector = 16'hFFFE, 85 | parameter pBRK_Vector = 16'hFFFE, 86 | parameter pRST_Vector = 16'hFFFC, 87 | parameter pNMI_Vector = 16'hFFFA, 88 | parameter pBRK = 3'b010 89 | )( 90 | input Rst, 91 | input Clk, 92 | 93 | input nNMI, 94 | input nIRQ, 95 | input [2:0] Mode, 96 | 97 | input IRQ_Msk, 98 | input IntSvc, 99 | 100 | output reg Int, 101 | output reg [15:0] Vector, 102 | 103 | output reg NMI, 104 | output reg IRQ, 105 | output reg Brk 106 | ); 107 | 108 | //////////////////////////////////////////////////////////////////////////////// 109 | // 110 | // Local Declarations 111 | // 112 | 113 | wire RE_NMI; 114 | wire CE_NMI; 115 | reg nIRQ_IFD; 116 | 117 | 118 | // Perform falling edge detection on the external non-maskable interrupt input 119 | 120 | fedet FE3 ( 121 | .rst(Rst), 122 | .clk(Clk), 123 | .din(nNMI), 124 | .pls(RE_NMI) 125 | ); 126 | 127 | // Capture and hold the rising edge pulse for NMI in NMI FF until serviced by 128 | // the processor. 129 | 130 | assign CE_NMI = (Rst | IntSvc | RE_NMI); 131 | always @(posedge Clk) NMI <= #1 ((CE_NMI) ? RE_NMI : 0); 132 | 133 | // Synchronize external IRQ input to Clk 134 | 135 | always @(posedge Clk or posedge Rst) 136 | begin 137 | if(Rst) begin 138 | nIRQ_IFD <= #1 1; 139 | IRQ <= #1 0; 140 | end else begin 141 | nIRQ_IFD <= #1 nIRQ; 142 | IRQ <= #1 ~nIRQ_IFD; 143 | end 144 | end 145 | 146 | //assign Brk = (Mode == pBRK); 147 | //assign Int = (NMI | (~IRQ_Msk & IRQ)); 148 | // 149 | //always @(*) Vector = ((Int) ? ((NMI) ? pNMI_Vector 150 | // : pIRQ_Vector) 151 | // : ((Brk) ? pBRK_Vector 152 | // : pRST_Vector)); 153 | 154 | always @(posedge Clk or posedge Rst) 155 | begin 156 | if(Rst) begin 157 | Brk <= #1 0; 158 | Int <= #1 0; 159 | Vector <= #1 pRST_Vector; 160 | end else begin 161 | Brk <= #1 (Mode == pBRK); 162 | Int <= #1 (NMI | (~IRQ_Msk & IRQ)); 163 | Vector <= #1 ((Int) ? ((NMI) ? pNMI_Vector 164 | : pIRQ_Vector) 165 | : ((Brk) ? pBRK_Vector 166 | : pRST_Vector)); 167 | end 168 | end 169 | 170 | endmodule 171 | -------------------------------------------------------------------------------- /Src/RTL/M65C02_MPC.v: -------------------------------------------------------------------------------- 1 | /////////////////////////////////////////////////////////////////////////////// 2 | // 3 | // Copyright 2009-2012 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: 10/30/2009 45 | // Design Name: WDC W65C02 Microprocessor Re-Implementation 46 | // Module Name: M65C02_MPC 47 | // Project Name: C:\XProjects\ISE10.1i\MAM6502 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, a single instruc- 69 | // tion class, simply increments the program counter and outputs the current 70 | // value of the program counter on the next address bus. The unconditional 71 | // branch instruction class provides instructions to select the next instruc- 72 | // tion using the Via[1:0] outputs and output that value on the next address 73 | // bus and simultaneously load the program counter. The unconditional branch 74 | // instruction class also provides for 8-way multiway branching using an exter- 75 | // nal (priority) encoder/branch selector, and microprogram subroutine call and 76 | // 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 09J30 MAM File Created 105 | // 106 | // 1.00 10G10 MAM Stack Pop operation modified to load StkD register 107 | // with 0 during subroutine returns. This will force 108 | // the microprogram to restart at 0 if the stack is 109 | // underflowed, or POPed, more the 4 times. Also made 110 | // a change to the Stack Push operation so that Next 111 | // is pushed instead of MA. 112 | // 113 | // 1.01 10G24 MAM Corrected typos in the instruction table. 114 | // 115 | // 1.02 10G25 MAM Removed Test Input Register, Strb input, and Inh 116 | // output. External logic required to provide synchro- 117 | // nized inputs for testing. 118 | // 119 | // 2.00 10H28 MAM Converted the BRV3 instruction into a conditional 120 | // branch to subroutine instruction. In this way the 121 | // BRV3, or CBSR, instruction can be used to take a 122 | // branch to an interrupt subroutine. The conditional 123 | // subroutine call is taken if T[3] is a logic 1. Like 124 | // the BSR instruction, the address of the subroutine 125 | // is provided by BA field. 126 | // 127 | // 2.10 11C05 Simplified return stack implementation. Removed 128 | // unused code, but retained code commented out that 129 | // reflects original implementation of BRV3 instruc- 130 | // tion. 131 | // 132 | // 2.11 11C20 Removed CBSR modification 133 | // 134 | // 3.00 11C21 Changed module and added support for pipelined op- 135 | // eration per the connections of the original F9408. 136 | // Included an internal Reset FF stretcher to insure 137 | // that an external registered PROM has time to fetch 138 | // the first microprogram word. Removed the MA_Sel 139 | // input because really should have been module reset. 140 | // Without tying MA to 0 with the internal reset, the 141 | // module in pipelined mode was not executing the same 142 | // microprogram as non-pipelined mode module and that 143 | // was unexpected. With these changes, the module per- 144 | // forms identically to the original F9408 MPC. 145 | // 146 | // 4.00 12A29 MAM Changing the behavior of BRV0, BRV1, BRV2, and BMW 147 | // so that they are all conditional on T0. If T0 is 148 | // not asserted, these instructions will wait at the 149 | // current location until T0 is asserted. Renamed the 150 | // module from F9408A_MPC.v to MAM6502_MPC.v. Para- 151 | // meterized the reset address. 152 | // 153 | // 4.10 12B03 MAM Restored the operation of the BRVx and BMW instruc- 154 | // tions, but added two inputs to allow the module to 155 | // respond to an external ready signal. In this manner 156 | // the module will operate as a single or multi-cycle 157 | // microprogram controller as determined by external 158 | // logic, or the microprogram. 159 | // 160 | // 4.11 12B19 MAM Renamed module: MAM6502_MPC => M65C02_MPC. 161 | // 162 | // Additional Comments: 163 | // 164 | // Since this component is expected to be used in a fully synchronous design, 165 | // the registering of the Test inputs with an external Strb signal and the Inh 166 | // signal is not desirable since it puts another delay in the signal path. The 167 | // effect will be to decrease the responsiveness of the system, and possibly 168 | // require that the test inputs be stretched so that pulsed signals are not 169 | // missed by the conditional tests in the microprogram. In the partially 170 | // synchronous design environment in which the original F9408 was used, incor- 171 | // porating a register internal to the device for the test inputs was very 172 | // much a requirement to reduce the risk of metastable behaviour of the micro- 173 | // program. To fully support the test inputs, the microprogram should include 174 | // an explicit enable for the test input logic in order to control the chang- 175 | // ing of the test inputs relative to the microroutines. 176 | // 177 | /////////////////////////////////////////////////////////////////////////////// 178 | 179 | module M65C02_MPC #( 180 | parameter pAddrWidth = 10, // Original F9408 => 10-bit Address 181 | parameter pRst_Addrs = 0 // Reset Address 182 | )( 183 | input Rst, // Module Reset (Synchronous) 184 | input Clk, // Module Clock 185 | input [3:0] I, // Instruction (see description) 186 | input [3:0] T, // Conditional Test Inputs 187 | input [2:0] MW, // Multi-way Branch Address Select 188 | input [(pAddrWidth-1):0] BA, // Microprogram Branch Address Field 189 | output [1:0] Via, // Unconditional Branch Address Select 190 | input En, // Enable Ready 191 | input Rdy, // Ready 192 | input PLS, // Pipeline Mode Select 193 | output reg [(pAddrWidth-1):0] MA // Microprogram Address 194 | ); 195 | 196 | /////////////////////////////////////////////////////////////////////////////// 197 | /////////////////////////////////////////////////////////////////////////////// 198 | // 199 | // Local Parameters 200 | // 201 | 202 | localparam RTS = 0; // Return from Subroutine 203 | localparam BSR = 1; // Branch to Subroutine 204 | localparam FTCH = 2; // Fetch Next Instruction 205 | localparam BMW = 3; // Multi-way Branch 206 | localparam BRV0 = 4; // Branch Via External Branch Address Source #0 207 | localparam BRV1 = 5; // Branch Via External Branch Address Source #1 208 | localparam BRV2 = 6; // Branch Via External Branch Address Source #2 209 | localparam BRV3 = 7; // Branch Via External Branch Address Source #3 210 | localparam BTH0 = 8; // Branch if T[0] is Logic 1, else fetch next instr. 211 | localparam BTH1 = 9; // Branch if T[1] is Logic 1, else fetch next instr. 212 | localparam BTH2 = 10; // Branch if T[2] is Logic 1, else fetch next instr. 213 | localparam BTH3 = 11; // Branch if T[3] is Logic 1, else fetch next instr. 214 | localparam BTL0 = 12; // Branch if T[0] is Logic 0, else fetch next instr. 215 | localparam BTL1 = 13; // Branch if T[1] is Logic 0, else fetch next instr. 216 | localparam BTL2 = 14; // Branch if T[2] is Logic 0, else fetch next instr. 217 | localparam BTL3 = 15; // Branch if T[3] is Logic 0, else fetch next instr. 218 | 219 | /////////////////////////////////////////////////////////////////////////////// 220 | /////////////////////////////////////////////////////////////////////////////// 221 | // 222 | // Declarations 223 | // 224 | 225 | wire [(pAddrWidth - 1):0] Next; // Output Program Counter Incrementer 226 | reg [(pAddrWidth - 1):0] PC_In; // Input to Program Counter 227 | reg [(pAddrWidth - 1):0] PC; // Program Counter 228 | 229 | reg [(pAddrWidth - 1):0] A, B, C, D; // LIFO Stack Registers 230 | 231 | reg dRst; // Reset stretcher 232 | wire MPC_Rst; // Internal MPC Reset signal 233 | 234 | /////////////////////////////////////////////////////////////////////////////// 235 | /////////////////////////////////////////////////////////////////////////////// 236 | // 237 | // Implementation 238 | // 239 | 240 | always @(posedge Clk) 241 | begin 242 | if(Rst) 243 | dRst <= #1 1; 244 | else 245 | dRst <= #1 0; 246 | end 247 | 248 | assign MPC_Rst = ((PLS) ? (Rst | dRst) : Rst); 249 | 250 | // Implement 4-Level LIFO Stack 251 | 252 | always @(posedge Clk) 253 | begin 254 | if(MPC_Rst) 255 | {D, C, B, A} <= #1 0; 256 | else if(I == BSR) 257 | {D, C, B, A} <= #1 {C, B, A, Next}; 258 | else if(I == RTS) 259 | {D, C, B, A} <= #1 {{pAddrWidth{1'b0}}, D, C, B}; 260 | end 261 | 262 | // Program Counter Incrementer 263 | 264 | assign Next = PC + 1; 265 | 266 | // Generate Unconditional Branch Address Select 267 | 268 | assign Via = {((I == BRV2) | (I == BRV3)), ((I == BRV3) | (I == BRV1))}; 269 | 270 | // Generate Program Counter Input Signal 271 | 272 | always @(*) 273 | begin 274 | case({MPC_Rst, I}) 275 | RTS : PC_In <= A; 276 | BSR : PC_In <= BA; 277 | FTCH : PC_In <= Next; 278 | BMW : PC_In <= {BA[(pAddrWidth - 1):3], MW}; 279 | // 280 | BRV0 : PC_In <= BA; 281 | BRV1 : PC_In <= BA; 282 | BRV2 : PC_In <= BA; 283 | BRV3 : PC_In <= BA; 284 | // 285 | BTH0 : PC_In <= (T[0] ? BA : Next); 286 | BTH1 : PC_In <= (T[1] ? BA : Next); 287 | BTH2 : PC_In <= (T[2] ? BA : Next); 288 | BTH3 : PC_In <= (T[3] ? BA : Next); 289 | // 290 | BTL0 : PC_In <= (T[0] ? Next : BA ); 291 | BTL1 : PC_In <= (T[1] ? Next : BA ); 292 | BTL2 : PC_In <= (T[2] ? Next : BA ); 293 | BTL3 : PC_In <= (T[3] ? Next : BA ); 294 | default : PC_In <= pRst_Addrs; 295 | endcase 296 | end 297 | 298 | // Generate Microprogram Address (Program Counter) 299 | 300 | always @(posedge Clk) 301 | begin 302 | if(MPC_Rst) 303 | PC <= #1 pRst_Addrs; 304 | else 305 | PC <= #1 ((En) ? ((Rdy) ? PC_In : PC) : PC_In); 306 | end 307 | 308 | // Assign Memory Address Bus 309 | 310 | always @(*) 311 | begin 312 | MA <= ((PLS) ? ((En) ? ((Rdy) ? PC_In : PC) : PC_In) : PC); 313 | end 314 | 315 | endmodule 316 | -------------------------------------------------------------------------------- /Src/RTL/M65C02_MPCv3.v: -------------------------------------------------------------------------------- 1 | `timescale 1ns / 1ps 2 | /////////////////////////////////////////////////////////////////////////////// 3 | // 4 | // Copyright 2009-2012 by Michael A. Morris, dba M. A. Morris & Associates 5 | // 6 | // All rights reserved. The source code contained herein is publicly released 7 | // under the terms and conditions of the GNU Lesser Public License. No part of 8 | // this source code may be reproduced or transmitted in any form or by any 9 | // means, electronic or mechanical, including photocopying, recording, or any 10 | // information storage and retrieval system in violation of the license under 11 | // which the source code is released. 12 | // 13 | // The source code contained herein is free; it may be redistributed and/or 14 | // modified in accordance with the terms of the GNU Lesser General Public 15 | // License as published by the Free Software Foundation; either version 2.1 of 16 | // the GNU Lesser General Public License, or any later version. 17 | // 18 | // The source code contained herein is freely released WITHOUT ANY WARRANTY; 19 | // without even the implied warranty of MERCHANTABILITY or FITNESS FOR A 20 | // PARTICULAR PURPOSE. (Refer to the GNU Lesser General Public License for 21 | // more details.) 22 | // 23 | // A copy of the GNU Lesser General Public License should have been received 24 | // along with the source code contained herein; if not, a copy can be obtained 25 | // by writing to: 26 | // 27 | // Free Software Foundation, Inc. 28 | // 51 Franklin Street, Fifth Floor 29 | // Boston, MA 02110-1301 USA 30 | // 31 | // Further, no use of this source code is permitted in any form or means 32 | // without inclusion of this banner prominently in any derived works. 33 | // 34 | // Michael A. Morris 35 | // Huntsville, AL 36 | // 37 | /////////////////////////////////////////////////////////////////////////////// 38 | 39 | `timescale 1ns / 1ps 40 | 41 | /////////////////////////////////////////////////////////////////////////////// 42 | // Company: M. A. Morris & Associates 43 | // Engineer: Michael A. Morris 44 | // 45 | // Create Date: 12:02:40 10/28/2012 46 | // Design Name: Microprogram Controller (Version 3) 47 | // Module Name: MPCv3.v 48 | // Project Name: C:\XProjects\VerilogComponents\MPCv3 49 | // Target Devices: Generic SRAM-based FPGA 50 | // Tool versions: Xilinx ISE 10.1i SP3 51 | // 52 | // Description: 53 | // 54 | // This module implements a simple microprogram sequencer based on the Fair- 55 | // child F9408. The sequencer provides: 56 | // 57 | // (1) 4-bit instruction input 58 | // (2) four-level LIFO stack; 59 | // (3) program counter and incrementer; 60 | // (4) 4-bit registered test input; 61 | // (5) 8-way multi-way branch control input; 62 | // (6) branch address input; 63 | // (7) 4-way branch address select output; 64 | // (8) next address output. 65 | // 66 | // These elements provide a relatively flexible general purpose microprogram 67 | // controller without a complex instruction set. The sixteen instructions can 68 | // be categorized into three classes: (1) fetch, (2) unconditional branches, 69 | // and (3) conditional branches. The fetch instruction class, a single instruc- 70 | // tion class, simply increments the program counter and outputs the current 71 | // value of the program counter on the next address bus. The unconditional 72 | // branch instruction class provides instructions to select the next instruc- 73 | // tion using the Via[1:0] outputs and output that value on the next address 74 | // bus and simultaneously load the program counter. The unconditional branch 75 | // instruction class also provides for 8-way multiway branching using an exter- 76 | // nal (priority) encoder/branch selector, and microprogram subroutine call and 77 | // return instructions. 78 | // 79 | // The instruction encodings of the F9408, as provided in "Principles of Firm- 80 | // ware Engineering in Microprogram Control" by Michael Andrews. The instruc- 81 | // tion set and operation map for the implementation is given below: 82 | // 83 | // I[3:0] MNEM Definition T[3:0] MA[m:0] Via Inh Operation 84 | // 0000 RTS Return xxxx TOS[m:0] 00 0 PC<=MA;Pop 85 | // 0001 BSR Call Subroutine xxxx BA[m:0] 00 1 PC<=MA;Push 86 | // 0010 FTCH Next Instruction xxxx PC+1 00 0 PC<=MA[m:0] 87 | // 0011 BMW Multi-way Branch xxxx {BA[m:3],MW[2:0]} 00 1 PC<=MA[m:0] 88 | // 0100 BRV0 Branch Via 0 xxxx BA[m:0] 00 1 PC<=MA[m:0] 89 | // 0101 BRV1 Branch Via 1 xxxx BA[m:0] 01 1 PC<=MA[m:0] 90 | // 0110 BRV2 Branch Via 2 xxxx BA[m:0] 10 1 PC<=MA[m:0] 91 | // 0111 BRV3 Branch Via 3 xxxx BA[m:0] 11 1 PC<=MA[m:0] 92 | // 1000 BTH0 Branch T0 High xxx1 {T0?BA[m:0]:PC+1} 00 1 PC<=MA[m:0] 93 | // 1001 BTH1 Branch T1 High xx1x {T1?BA[m:0]:PC+1} 00 1 PC<=MA[m:0] 94 | // 1010 BTH2 Branch T2 High x1xx {T2?BA[m:0]:PC+1} 00 1 PC<=MA[m:0] 95 | // 1011 BTH3 Branch T3 High 1xxx {T2?BA[m:0]:PC+1} 00 1 PC<=MA[m:0] 96 | // 1100 BTL0 Branch T0 Low xxx0 {T0?PC+1:BA[m:0]} 00 1 PC<=MA[m:0] 97 | // 1101 BTL1 Branch T1 Low xx0x {T1?PC+1:BA[m:0]} 00 1 PC<=MA[m:0] 98 | // 1110 BTL2 Branch T2 Low x0xx {T2?PC+1:BA[m:0]} 00 1 PC<=MA[m:0] 99 | // 1111 BTL3 Branch T3 Low 0xxx {T3?PC+1:BA[m:0]} 00 1 PC<=MA[m:0] 100 | // 101 | // Dependencies: none. 102 | // 103 | // Revision: 104 | // 105 | // 0.01 12J28 MAM File Created 106 | // 107 | // 1.00 12K12 MAM Modified MA multiplexer to either present next 108 | // address or hold current address. This is required 109 | // when the next microcycle has a length greater than 110 | // one. To perform this adjustment/extension of the 111 | // microcycle, two signals track the current and next 112 | // microcycle length: CurLenZ, and NxtLenZ. Also, added 113 | // register MPC_En to control the MPC registers and 114 | // MA multiplexer. Removed non-pipelined mode control 115 | // input because the typical usage of the MPC is with 116 | // Block RAM, which will only work with the pipelined 117 | // mode. 118 | // 119 | // 1.10 12K20 MAM Changed reset for the microcycle length controller 120 | // portion from MPC_Rst to Rst, which releases the 121 | // microcycle length controller one cycle ahead of the 122 | // MPC logic of the module. This is required to ensure 123 | // that MPC_En and the microcycle length controller SM 124 | // are properly conditioned before the start of micro- 125 | // program execution. Removed the multiplexer on MA. 126 | // The multiplexer was used to hold the address of the 127 | // MPC when a delay cycle was required. It was put into 128 | // implementation to correct an issue with BCD instruc- 129 | // tions during testing with single cycle memory. The 130 | // same issue reappeared when multi-cycle microcycles 131 | // were tested. The issue was corrected by removing the 132 | // MA multiplexer, and properly conditioning the PSW, 133 | // interrupt handler update and the microprogram ROMs 134 | // with the Rdy signal. The original fix, adding the MA 135 | // multiplexer, fixed the issue because the PSW ISR 136 | // update logic and microprogram ROMs were not condi- 137 | // tioned with Rdy. The multiplexer added a microcycle 138 | // delay which couldn't be sustained for multi-cycle 139 | // microcycles; the required microprogram address delay 140 | // could only be sustained for one cycle without adding 141 | // the enable, i.e. Rdy, to the microprogram ROM. 142 | // 143 | // Additional Comments: 144 | // 145 | // The Version 3 Microprogram Controller (MPCv3) is based on the Fairchild 146 | // F9408 MPC. It extends that microprogram controller by incorporating a micro- 147 | // cycle controller directly into the module, a al Am2925, which allows each 148 | // microcycle to be controlled by a field in the microprogram, or by external 149 | // logic. 150 | // 151 | // The purpose of these extensions is to allow easy implementation of a varia- 152 | // ble length microprogram cycle, i.e. microcycle. In turn, this simplifies the 153 | // implementation of microprogrammed state machines which interface to synchro- 154 | // nous memories found in most FPGAs, or to external synchronous/asynchronous 155 | // memories. 156 | // 157 | // When a microprogrammed state machine interfaces to a synchronous memory, 158 | // there is a one cycle delay between the presentation of the address and the 159 | // output of the data at that address. In many instances, the microprogram is 160 | // unable to perform any useful work during the first cycle. Thus, the micro- 161 | // program must perform an explicit delay operation, which generally requires 162 | // a state to be added to every read of these memories. If there are a signifi- 163 | // cant number of these read operations in the microprogram, then there is an 164 | // opportunity for the microprogram to be incorrectly programmed when one or 165 | // more of the delay cycles are not included in the microprogram. Isolating 166 | // the resulting fault in the state machine may be difficult. 167 | // 168 | // To avoid errors of this type, microcycles which read from or write to 169 | // devices, such as memories, can be automatically extended explicitly by a 170 | // microprogram field or logic. Using this type of facility reduces the number 171 | // of states required to interface a microprogrammed state machine to these 172 | // types of devices. It also makes the microprogram less tedious to develop and 173 | // improves overall productivity, which is a prime reason for choosing a micro- 174 | // programmed approach for developing complex state machines. 175 | // 176 | // The objective of the embedded microcyle length controller is not to incor- 177 | // porate the full functionality of the Am2925 Microcycle Controller. Instead, 178 | // it is to add a simple microcycle length control function which can be used 179 | // to simplify the microprogram and provide a easy mechanism for interfacing 180 | // the microprogrammed state machine to devices which require more than one 181 | // clock cycle to access. The embedded microcycle length controller included in 182 | // this module allows the microcycle length of the F9408 to be set to 1 , 2, 183 | // or 4 cycles. When extended to 2 cycles, the cycle cannot be extended using 184 | // an external wait state request. When extended to 4 cycles, an external wait 185 | // state generator can be used to add any number of wait states to the micro- 186 | // cycle of the F9408. 187 | // 188 | /////////////////////////////////////////////////////////////////////////////// 189 | 190 | module M65C02_MPCv3 #( 191 | parameter pAddrWidth = 10, // Original F9408 => 10-bit Address 192 | parameter pRst_Addrs = 0 // Reset Address 193 | )( 194 | input Rst, // Module Reset (Synchronous) 195 | input Clk, // Module Clock 196 | 197 | input [1:0] uLen, // Microcycle Length Select 198 | input Wait, // Microcycle Wait State Request Input 199 | 200 | output reg [1:0] MC, // Microcycle State outputs 201 | 202 | input [3:0] I, // Instruction (see description) 203 | input [3:0] T, // Conditional Test Inputs 204 | input [2:0] MW, // Multi-way Branch Address Select 205 | input [(pAddrWidth-1):0] BA, // Microprogram Branch Address Field 206 | output [1:0] Via, // Unconditional Branch Address Select 207 | 208 | 209 | output reg [(pAddrWidth-1):0] MA // Microprogram Address 210 | ); 211 | 212 | /////////////////////////////////////////////////////////////////////////////// 213 | /////////////////////////////////////////////////////////////////////////////// 214 | // 215 | // Local Parameters 216 | // 217 | 218 | localparam pRTS = 0; // Return from Subroutine 219 | localparam pBSR = 1; // Branch to Subroutine 220 | localparam pFTCH = 2; // Fetch Next Instruction 221 | localparam pBMW = 3; // Multi-way Branch 222 | localparam pBRV0 = 4; // Branch Via External Branch Address Source #0 223 | localparam pBRV1 = 5; // Branch Via External Branch Address Source #1 224 | localparam pBRV2 = 6; // Branch Via External Branch Address Source #2 225 | localparam pBRV3 = 7; // Branch Via External Branch Address Source #3 226 | localparam pBTH0 = 8; // Branch if T[0] is Logic 1, else fetch next instr. 227 | localparam pBTH1 = 9; // Branch if T[1] is Logic 1, else fetch next instr. 228 | localparam pBTH2 = 10; // Branch if T[2] is Logic 1, else fetch next instr. 229 | localparam pBTH3 = 11; // Branch if T[3] is Logic 1, else fetch next instr. 230 | localparam pBTL0 = 12; // Branch if T[0] is Logic 0, else fetch next instr. 231 | localparam pBTL1 = 13; // Branch if T[1] is Logic 0, else fetch next instr. 232 | localparam pBTL2 = 14; // Branch if T[2] is Logic 0, else fetch next instr. 233 | localparam pBTL3 = 15; // Branch if T[3] is Logic 0, else fetch next instr. 234 | 235 | /////////////////////////////////////////////////////////////////////////////// 236 | /////////////////////////////////////////////////////////////////////////////// 237 | // 238 | // Declarations 239 | // 240 | 241 | wire NxtLenZ; // Next microcycle length is Z 242 | reg MPC_En; // MPC register enable 243 | 244 | wire [(pAddrWidth - 1):0] Next; // Output Program Counter Incrementer 245 | reg [(pAddrWidth - 1):0] PC_In; // Input to Program Counter 246 | reg [(pAddrWidth - 1):0] PC; // Program Counter 247 | 248 | //reg [(pAddrWidth - 1):0] A, B, C, D; // LIFO Stack Registers 249 | reg [(pAddrWidth - 1):0] A; // LIFO Stack Registers 250 | 251 | reg dRst; // Reset stretcher 252 | wire MPC_Rst; // Internal MPC Reset signal 253 | 254 | /////////////////////////////////////////////////////////////////////////////// 255 | /////////////////////////////////////////////////////////////////////////////// 256 | // 257 | // Implementation 258 | // 259 | 260 | // Implement module reset generator 261 | 262 | always @(posedge Clk) 263 | begin 264 | if(Rst) 265 | dRst <= #1 1; 266 | else 267 | dRst <= #1 0; 268 | end 269 | 270 | assign MPC_Rst = (Rst | dRst); 271 | 272 | // 273 | // Embedded Microcycle Length Controller 274 | // 275 | // Three microcycles are implemented: 1, 2, or 4 clock in length. If word 0 of 276 | // the microprogram, or external logic, sets a different length during reset, 277 | // the microcycle length controller will exit reset in either state 0 or 278 | // state 2. If it exits reset in state 0, a single clock microcycle will be 279 | // performed after reset. If it exits reset in state 2, either a 2 cycle or 280 | // a 4 cycle microcycle will be performed after reset. The microcycle length is 281 | // sampled in state 0. This allows either the microprogram or external logic to 282 | // control the length of each microcycle that the MPCv3 performs. 283 | 284 | always @(posedge Clk) 285 | begin 286 | if(Rst) 287 | MC <= #1 ((|uLen) ? 2 : 0); 288 | else 289 | case(MC) 290 | 2 : MC <= #1 ((uLen[1]) ? 3 : 0); // First cycle of microcycle 291 | 3 : MC <= #1 ((Wait) ? 3 : 1); // 2nd of 4 cycle microcycle 292 | 1 : MC <= #1 ((Wait) ? 1 : 0); // 3rd of 4 cycle microcycle 293 | 0 : MC <= #1 ((|uLen) ? 2 : 0); // Last cycle of microcycle 294 | endcase 295 | end 296 | 297 | // Assign next microcycle length 298 | 299 | assign NxtLenZ = (uLen == 0); 300 | 301 | // Determine the MPC Enable signal 302 | 303 | always @(posedge Clk) 304 | begin 305 | if(Rst) 306 | MPC_En <= #1 ~|uLen; 307 | else 308 | case(MC) 309 | 2 : MPC_En <= #1 ((uLen[1]) ? 0 : 1); 310 | 3 : MPC_En <= #1 0; 311 | 1 : MPC_En <= #1 ~Wait; 312 | 0 : MPC_En <= #1 NxtLenZ; 313 | endcase 314 | end 315 | 316 | //// Implement 4-Level LIFO Stack 317 | // 318 | //always @(posedge Clk) 319 | //begin 320 | // if(MPC_Rst) 321 | // {A, B, C, D} <= #1 0; 322 | // else if(MPC_En) 323 | // if(I == BSR) 324 | // {A, B, C, D} <= #1 {Next, A, B, C}; 325 | // else if(I == RTS) 326 | // {A, B, C, D} <= #1 {B, C, D, {pAddrWidth{1'b0}}}; 327 | //end 328 | 329 | // Implement 1-Level LIFO Stack 330 | 331 | always @(posedge Clk) 332 | begin 333 | if(MPC_Rst) 334 | A <= #1 0; 335 | else if(MPC_En) 336 | if(I == pBSR) 337 | A <= #1 Next; 338 | else if(I == pRTS) 339 | A <= #1 {pAddrWidth{1'b0}}; 340 | end 341 | 342 | // Program Counter Incrementer 343 | 344 | assign Next = PC + 1; 345 | 346 | // Generate Unconditional Branch Address Select 347 | 348 | assign Via = {((I == pBRV2) | (I == pBRV3)), ((I == pBRV3) | (I == pBRV1))}; 349 | 350 | // Generate Program Counter Input Signal 351 | 352 | always @(*) 353 | begin 354 | case({MPC_Rst, I}) 355 | pRTS : PC_In <= A; 356 | pBSR : PC_In <= BA; 357 | pFTCH : PC_In <= Next; 358 | pBMW : PC_In <= {BA[(pAddrWidth - 1):3], MW}; 359 | // 360 | pBRV0 : PC_In <= BA; 361 | pBRV1 : PC_In <= BA; 362 | pBRV2 : PC_In <= BA; 363 | pBRV3 : PC_In <= BA; 364 | // 365 | pBTH0 : PC_In <= (T[0] ? BA : Next); 366 | pBTH1 : PC_In <= (T[1] ? BA : Next); 367 | pBTH2 : PC_In <= (T[2] ? BA : Next); 368 | pBTH3 : PC_In <= (T[3] ? BA : Next); 369 | // 370 | pBTL0 : PC_In <= (T[0] ? Next : BA ); 371 | pBTL1 : PC_In <= (T[1] ? Next : BA ); 372 | pBTL2 : PC_In <= (T[2] ? Next : BA ); 373 | pBTL3 : PC_In <= (T[3] ? Next : BA ); 374 | default : PC_In <= pRst_Addrs; 375 | endcase 376 | end 377 | 378 | // Generate Microprogram Address (Program Counter) 379 | 380 | always @(posedge Clk) 381 | begin 382 | if(MPC_Rst) 383 | PC <= #1 pRst_Addrs; 384 | else if(MPC_En) 385 | PC <= #1 PC_In; 386 | end 387 | 388 | // Assign Memory Address Bus 389 | 390 | always @(*) 391 | begin 392 | MA <= PC_In; 393 | end 394 | 395 | endmodule 396 | -------------------------------------------------------------------------------- /Src/RTL/M65C02_MPCv4.v: -------------------------------------------------------------------------------- 1 | //////////////////////////////////////////////////////////////////////////////// 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 | 0 : MC <= #1 2; // 4th cycle of microcycle (Phi1O) 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 377 | -------------------------------------------------------------------------------- /Src/RTL/M65C02_RAM.v: -------------------------------------------------------------------------------- 1 | //////////////////////////////////////////////////////////////////////////////// 2 | // 3 | // Copyright 2012 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: 22:35:57 02/04/2012 45 | // Design Name: WDC W65C02 Microprocessor Re-Implementation 46 | // Module Name: M65C02_RAM 47 | // Project Name: C:\XProjects\ISE10.1i\MAM6502 48 | // Target Devices: Generic SRAM-based FPGA 49 | // Tool versions: Xilinx ISE10.1i SP3 50 | // 51 | // Description: 52 | // 53 | // The module provides a generic RAM model that can be used to simulate RAM 54 | // found in an FPGA. 55 | // 56 | // Dependencies: 57 | // 58 | // Revision: 59 | // 60 | // 0.00 12B04 MAM Initial File Creation 61 | // 62 | // 1.00 12K18 MAM Modified the RAM model to support three different 63 | // kinds of RAM. The model supports asynchronous, LUT- 64 | // based RAM ({Ext, ZP} == 1), synchronous BRAM-based 65 | // RAM ({Ext, ZP} == 0 | 3), and synchronous, pipelined 66 | // RAM ({Ext, ZP} == 2). 67 | // 68 | // Additional Comments: 69 | // 70 | // In normal use, the model provided in this module can be used to develop a 71 | // memory controller for the M65C02_Core that supports LUT RAM for page 0 72 | // acesses, BRAM for page 1 and internal program and data memory, and pipelined 73 | // SynchRAM for external program and data memory. It is possible to support ex- 74 | // ternal non-pipelined synchronous RAM by setting the RAM module to the BRAM 75 | // mode and providing additional registers in the output paths but not on the 76 | // input paths of the FPGA. 77 | // 78 | //////////////////////////////////////////////////////////////////////////////// 79 | 80 | module M65C02_RAM #( 81 | parameter pAddrSize = 10, 82 | parameter pDataSize = 8, 83 | parameter pFileName = "M65C02_RAM.txt" 84 | )( 85 | input Clk, 86 | 87 | input ZP, // Emulate LUT-based Asynchronous RAM 88 | input Ext, // Emulate BRAM-based Pipelined SyncSRAM 89 | 90 | input WE, 91 | input [(pAddrSize - 1):0] AI, 92 | input [(pDataSize - 1):0] DI, 93 | output [(pDataSize - 1):0] DO 94 | ); 95 | 96 | localparam pRAM_Max = ((2**pAddrSize) - 1); 97 | 98 | reg [(pDataSize - 1):0] RAM [pRAM_Max:0]; 99 | 100 | reg rWE; 101 | reg [(pAddrSize - 1):0] rAI; 102 | reg [(pDataSize - 1):0] rDI, rDO; 103 | 104 | wire W; 105 | wire [(pAddrSize - 1):0] A; 106 | wire [(pDataSize - 1):0] D; 107 | 108 | always @(posedge Clk) 109 | begin 110 | {rWE, rAI, rDI} <= #1 {WE, AI, DI}; 111 | end 112 | 113 | assign W = ((ZP) ? WE : rWE); 114 | assign A = ((ZP) ? AI : rAI); 115 | assign D = ((ZP) ? DI : rDI); 116 | 117 | initial 118 | $readmemh(pFileName, RAM, 0, pRAM_Max); 119 | 120 | always @(posedge Clk) 121 | begin 122 | if(W) 123 | RAM[A] <= #1 D; 124 | end 125 | 126 | always @(posedge Clk) 127 | begin 128 | rDO <= #1 RAM[A]; 129 | end 130 | 131 | assign DO = ((Ext) ? rDO : RAM[A]); 132 | 133 | endmodule 134 | -------------------------------------------------------------------------------- /Src/RTL/fedet.v: -------------------------------------------------------------------------------- 1 | `timescale 1ns / 1ps 2 | ////////////////////////////////////////////////////////////////////////////////// 3 | // Company: Alpha Beta Technologies, Inc. 4 | // Engineer: Michael A. Morris 5 | // 6 | // Create Date: 03/01/2008 7 | // Design Name: USB MBP HDL 8 | // Module Name: fedet.v 9 | // Project Name: 4020 HAWK ZAOM Upgrade 10 | // Target Devices: XC2S150-5PQ208I 11 | // Tool versions: ISE 8.2i 12 | // 13 | // Description: Multi-stage synchronizer with falling edge detection 14 | // 15 | // Dependencies: None 16 | // 17 | // Revision History: 18 | // 19 | // 0.01 08C01 MAM File Created 20 | // 21 | // Additional Comments: 22 | // 23 | /////////////////////////////////////////////////////////////////////////////// 24 | 25 | module fedet(rst, clk, din, pls); 26 | 27 | /////////////////////////////////////////////////////////////////////////////// 28 | // 29 | // Module Port Declarations 30 | // 31 | 32 | input rst; 33 | input clk; 34 | input din; 35 | output pls; 36 | 37 | /////////////////////////////////////////////////////////////////////////////// 38 | // 39 | // Module Level Declarations 40 | // 41 | 42 | reg [2:0] QSync; 43 | 44 | /////////////////////////////////////////////////////////////////////////////// 45 | // 46 | // Implementation 47 | // 48 | 49 | always @(posedge clk or posedge rst) begin 50 | if(rst) 51 | #1 QSync <= 3'b011; 52 | else 53 | #1 QSync <= {~QSync[0] & QSync[1], QSync[0], din}; 54 | end 55 | 56 | assign pls = QSync[2]; 57 | 58 | endmodule 59 | -------------------------------------------------------------------------------- /Utils/BIN2TXT.C: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | void main(int argc, char* argv[]) 6 | { 7 | FILE *in, *out; 8 | int i, j; 9 | char ch; 10 | double m; 11 | 12 | printf("Converts a binary output from AS65 into Xilinx-compatible Memory Intialization File\n"); 13 | printf("\nThe number of arguments supplied: %d\n", argc); 14 | if(argc < 2) { 15 | printf("\n\tProgram requires the following two arguments: infile outfile.\n"); 16 | printf("\tinfile : input binary mode file output of AS65 assembler\n"); 17 | printf("\toutfile: filename of output file into ASCII Hex representation of input file is written\n\n"); 18 | } else { 19 | for(i = 0; i < argc; i++) { 20 | printf("argv[%d] = %s\n", i, argv[i]); 21 | } 22 | 23 | if((in = fopen(argv[1], "rb")) == NULL) { 24 | fprintf(stderr, "Cannot open input file.\n"); 25 | } 26 | 27 | if((out = fopen(argv[2], "wt")) == NULL) { 28 | fprintf(stderr, "Cannot open output file.\n"); 29 | } 30 | 31 | i = 0; 32 | while(!feof(in)) { 33 | ch = fgetc(in); 34 | //printf("%02X ", ch); 35 | fprintf(out, "%02X\n", ch); 36 | i += 1; 37 | } 38 | 39 | m = log(i-1)/log(2.0); 40 | 41 | if((m - ((int) m)) != 0) { 42 | j = (1 << (((int) m) + 1)); 43 | } else { 44 | j = (1 << ((int) m) ); 45 | } 46 | 47 | printf("\n\nm = %12.6g; i = %d; j = %d, ch = %d\n\n", m, i, j, ch); 48 | 49 | if(j > i) { 50 | for(; i < j; i++) { 51 | fprintf(out, "00\n"); 52 | } 53 | } 54 | 55 | fclose(in); 56 | fclose(out); 57 | } 58 | } -------------------------------------------------------------------------------- /Utils/BIN2TXT.EXE: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MorrisMA/MAM65C02-Processor-Core/dabbc3f44616cdb0898375d68b9f36e11fd21081/Utils/BIN2TXT.EXE -------------------------------------------------------------------------------- /Utils/README.md: -------------------------------------------------------------------------------- 1 | M65C02 Processor Core Utilities 2 | =============================== 3 | 4 | Copyright (C) 2012, Michael A. Morris . 5 | All Rights Reserved. 6 | 7 | Released under LGPL. 8 | 9 | Directory Contents 10 | ------------------ 11 | 12 | This subdirectory provides two utilities to support the M65C02 Microprogrammed 13 | Processor Core: 14 | 15 | (1) Bin2Txt.exe 16 | (2) SMRTool.exe 17 | 18 | Bin2Txt.exe 19 | =========== 20 | 21 | **Bin2Txt.exe** convert binary assembler output files from the Kingswood A65 22 | 6502 Assembler into ASCII hexadecimal memory initialization files as required 23 | by Xilinx ISE. 24 | 25 | Usage 26 | ----- 27 | 28 | The utility **bin2txt.exe** and its associated source file, **bin2txt.c**, 29 | operate as a DOS command line utility. It was compiled using the Borland Turbo 30 | C/C++ 2.0 compiler. 31 | 32 | The utility requires the path and filename of a binary input file and the path 33 | and filename of an output file. 34 | 35 | The input file is opened for reading as binary. The output file is opened for 36 | writing as a text (ASCII, single byte character set) file. Data is read from 37 | the input file, converted to ASCII Hexadecimal, and written to the output 38 | file. Each input byte is written to the output as two ASCII characters on a 39 | single line. Each line is terminated with a standard newline terminator, "\n". 40 | 41 | While reading the input file, a count of the number of bytes processed is 42 | kept. After all input data has been read from the input file and written to 43 | the output file, the output file is padded with 0x00 so that the total number 44 | of lines is equal to a power of two. 45 | 46 | Documentation 47 | ------------- 48 | 49 | If the number of required arguments are not supplied, then before terminating 50 | the utility will print out a prompt to the user that defines the needed 51 | arguments. 52 | 53 | Status 54 | ------ 55 | 56 | Design and verification is complete. 57 | 58 | SMRTool.exe 59 | =========== 60 | 61 | **SMRTool.exe** is a tool used to convert text source files into VHDL, 62 | Verilog, or Xilinx memory intialization files. The source files can be used to 63 | construct simple ROM for a number of usefull purposes. It's particular use in 64 | the MAM65C02 Microprogrammed Processor Core is to convert the microprogram 65 | source files provided into two memory initialization files which are loaded 66 | into the fixed and variable microprogram ROMs. 67 | 68 | Usage 69 | ----- 70 | 71 | The primary use for **SMRTool** is as a tool to convert human-readable 72 | microprogrammed state machine descriptions into synthesizable VHDL and/or 73 | Verilog RTL descriptions of ROMs. **SMRTool** also provides memory 74 | initialization files, and this is its primary method of usage for the MAM65C02 75 | Microprogrammed Processor Core. 76 | 77 | **SMRTool** is a Windows-based tool which provides the user graphical user 78 | interface specify the input source file, and check boxes and text boxes to 79 | select various output options and files. It is written in C#, and requires the 80 | .NET framework to run. 81 | 82 | In the final analysis, **SMRTool** is a text substitution tool. As such, it 83 | has a number of limitations, but it is invaluable for its intended purpose. 84 | Extensions are being continually added to the tool as additional functionality 85 | is required to support more complex state machines, and to improve the 86 | simulation and testing of the state machines in VHDL/Verilog or SystemVerilog 87 | verification environment. 88 | 89 | Documentation 90 | ------------- 91 | 92 | A complete description of the tool is not available. The source files provided 93 | in the sources subdirectory, **M65C02_Decode_ROM.txt** and 94 | **M65C02_uPgm_V3.txt**, provide an example of the format and syntax that is 95 | required by **SMRTool**. This section will provide additional information 96 | about the structure and syntax, but the source files provided are the 97 | definitive syntax references for the tool; they make use of all of the current 98 | directives and features of **SMRTool**. 99 | 100 | First and foremost, **SMRTool** is a text substitution tool. No provision is 101 | made for in-line symbolic equations in the publicly released version of the 102 | tool provided herein. 103 | 104 | Each source file must start with a header. The header is marked by the symbol 105 | **header** in column 1 of the first line of the source file, and demarcated by 106 | the symbol **endh**. Within the header, the tool presently recognizes four 107 | fields. Each header field is terminated by a colon, **:**, and followed by a 108 | string which the tool extracts and places into the appropriate GUI text boxes. 109 | The currently recognized header fields are: 110 | 111 | (1) Project 112 | (2) File Revision 113 | (3) Author(s) 114 | (4) Description 115 | 116 | Comments may be used, and are introduced using the VHDL comment symbol **--**, 117 | a double hyphen. The comment extents from that point to the end of the line. 118 | Presently there is no support for multi-line block comments such as is 119 | avaiable in Verilog and C. 120 | 121 | Following the header section, the source file must define all substitution 122 | symbols. Owing to its intended design and implementation as a microprogram 123 | source file processor, there are several directives recognized by **SMRTool** 124 | to aid in this process. 125 | 126 | Each line in the file may be blank, a comment line, or contain symbols to be 127 | processed. Each source line is divided into at least one or more fields. With 128 | the exception of the first and second fields on a source line, fields are 129 | separated by commas. Each field is specified to have a constant width, and the 130 | values assigned to the symbols must be defined to fit into the specified 131 | width. Each field is positionally located in a line of source. 132 | 133 | On a line of source, fields may be skipped, and the default value is inserted 134 | by **SMRTool**, using consecutive commas. From the last used field on a line 135 | to the end, or to a comment, there is no need to include the commas to skip 136 | the unused fields. The tool will automatically substitute the default value 137 | for all skipped fields. **The default value of a field is zero.** A limitation 138 | of the present tool is that the default value can not be changed. 139 | 140 | The current implementation of the tool recognizes the following directives: 141 | 142 | (1) .asm 143 | (2) .def 144 | (3) .equ 145 | (4) .org 146 | 147 | 148 | The **.asm** directive defines the microprogram controller's instructions. 149 | Unless a label (described below) is used at the start of a source line, a 150 | symbol defined by the **.asm** directive must be the first symbol on a source 151 | line. 152 | 153 | The **.def** defines the width of each field in the source file. The first 154 | field defined by a **.def** directive will be the leftmost field in the 155 | output, followed by the second field, etc. The sum of all of the widths of all 156 | defined fields is the total width of the data written to the tool's output. 157 | There is no limit to the total field width, but with respect to to Block RAMs 158 | in Xilinx FPGAs, in particular, the maximum practical width of a ROM is 36 or 159 | 72 bits. 160 | 161 | The **.equ** directive is used to define all other text substitution symbols 162 | beyond those defined by the **.asm** directive. A limitation of the present 163 | implementation is that all symbols must be unique. 164 | 165 | The **.org** directive defines the location counter address of all source 166 | lines which follow the directive. If multiple **.org** directives are used in 167 | a source file, then the intervening locations are automatically filled by the 168 | tool with zeros. In the present implementation there is a limitation that all 169 | **.org** directives be increasing in magnitude. If an **.org** is placed in 170 | the source with a lesser value than one already used, the location counter is 171 | assigned the new value, and the previously defined values may be overwritten 172 | by any new output lines. 173 | 174 | Labels are used to define the symbols to which the **.asm** and **.equ** 175 | directives assigns values, or labels may used to capture the value of the 176 | location counter to a symbol. When labels are used to capture the location 177 | counter value, the labels must always start with an underscore character, 178 | **_**. All labels in a source file must be unique, and all labels capturing 179 | the value of the location counter must be terminated by a colon. Location 180 | counter labels, terminated by a colon, may appear on a source line before a 181 | **.org** directive, or one of the **.asm** symbols. 182 | 183 | The current value of the location counter is the special symbol: **$** or 184 | dollar sign. 185 | 186 | The last line of the source file must be labeled **_end** terminated by colon. 187 | 188 | Extensions 189 | ---------- 190 | 191 | At the present time, there are no plans to port the tool to C/C++ and Linux. 192 | If there is sufficient interest expressed in such a conversion, then 193 | consideration will be given to that task. 194 | 195 | Status 196 | ------ 197 | 198 | Mature. **SMRTool** is in continous usage for a number of FPGA designs, and 199 | being actively maintained. 200 | 201 | Error Reports 202 | ------------- 203 | 204 | If there are any problems found, please open a GitHub issue. Each reported 205 | issue with **SMRTool** will be evaluated. In order to evaluate a problem 206 | report, a description of the problem and the relevant sources are required. 207 | Without both of these components of a problem report, the likelihood of any 208 | significant investigation into a reported problem is a low probability. 209 | -------------------------------------------------------------------------------- /Utils/SMRT_tool.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MorrisMA/MAM65C02-Processor-Core/dabbc3f44616cdb0898375d68b9f36e11fd21081/Utils/SMRT_tool.zip -------------------------------------------------------------------------------- /Utils/m65c02.bat: -------------------------------------------------------------------------------- 1 | ..\as65\as65 -cntvw132h58xz -l -om65c02.bin m65c02_tst2 2 | bin2txt m65c02.bin m65c02.txt 3 | copy m65c02.txt c:\XProjects\ISE10.1i\MAM6502\M65C02_Tst2.txt 4 | --------------------------------------------------------------------------------