diff --git a/sim/verilog6502_32bit.yaml b/sim/verilog6502_32bit.yaml new file mode 100644 index 0000000..3553d1f --- /dev/null +++ b/sim/verilog6502_32bit.yaml @@ -0,0 +1,9 @@ +tests: + - name: "cpu_65c02" + toplevel: "cpu_65c02" + modules: + - "verilog6502_32bit_test" + sources: "sources.list" + waves: True + defines: + SIM: "hi" \ No newline at end of file diff --git a/sim/verilog6502_32bit_test.py b/sim/verilog6502_32bit_test.py new file mode 100644 index 0000000..08d111d --- /dev/null +++ b/sim/verilog6502_32bit_test.py @@ -0,0 +1,20 @@ +import cocotb +from cocotb.handle import Immediate + +from cocotb.clock import Clock +from cocotb.triggers import Timer, RisingEdge + +CLK_PERIOD = 5 + +@cocotb.test +async def test_absolute(dut): + cocotb.start_soon(Clock(dut.clk, CLK_PERIOD, unit="ns").start()) + + dut.RDY.value = Immediate(1) + + dut.reset.value = Immediate(1) + for _ in range(10): + await RisingEdge(dut.clk) + dut.reset.value = 0 + + await Timer(1, "us") \ No newline at end of file diff --git a/src/cpu_65c02.v b/src/cpu_65c02.v index 1086546..c140cf9 100644 --- a/src/cpu_65c02.v +++ b/src/cpu_65c02.v @@ -52,7 +52,7 @@ module cpu_65c02( clk, reset, AB, DI, DO, WE, IRQ, NMI, RDY, RDY_O, SYNC ); input clk; // CPU clock input reset; // reset signal -output reg [15:0] AB; // address bus +output reg [31:0] AB; // address bus input [7:0] DI; // data in, read bus output [7:0] DO; // data out, write bus output WE; // write enable @@ -66,9 +66,8 @@ output reg SYNC; // AB is first cycle of the intruction * internal signals */ -reg [15:0] PC; // Program Counter -reg [7:0] ABL; // Address Bus Register LSB -reg [7:0] ABH; // Address Bus Register MSB +reg [31:0] PC; // Program Counter +reg [31:0] ABR; // Address Bus Register wire [7:0] ADD; // Adder Hold Register (registered in ALU) reg [7:0] DIHOLD; // Hold for Data In @@ -103,8 +102,6 @@ wire [7:0] AO; // ALU output after BCD adjustment reg WE; // Write Enable reg CI; // Carry In wire CO; // Carry Out -wire [7:0] PCH = PC[15:8]; -wire [7:0] PCL = PC[7:0]; reg NMI_edge = 0; // captured NMI edge @@ -142,7 +139,7 @@ reg [5:0] state; */ reg PC_inc; // Increment PC -reg [15:0] PC_temp; // intermediate value of PC +reg [31:0] PC_temp; // intermediate value of PC reg [1:0] src_reg; // source register index reg [1:0] dst_reg; // destination register index @@ -263,7 +260,9 @@ parameter JMPIX0 = 6'd51, // JMP (,X)- fetch LSB and send to ALU (+X) JMPIX1 = 6'd52, // JMP (,X)- fetch MSB and send to ALU (+Carry) JMPIX2 = 6'd53, // JMP (,X)- Wait for ALU (only if needed) - WAI = 6'd54; // WAI - Wait for interrupt, then go to decode + WAI = 6'd54, // WAI - Wait for interrupt, then go to decode + BRK4 = 6'd55, // TODO + BRK5 = 6'd56; // TODO `ifdef SIM @@ -318,6 +317,8 @@ always @* BRK1: statename = "BRK1"; BRK2: statename = "BRK2"; BRK3: statename = "BRK3"; + BRK4: statename = "BRK4"; + BRK5: statename = "BRK5"; BRA0: statename = "BRA0"; BRA1: statename = "BRA1"; BRA2: statename = "BRA2"; @@ -346,7 +347,7 @@ always @* always @* case( state ) DECODE: if( (~I & IRQ) | NMI_edge ) - PC_temp = { ABH, ABL }; + PC_temp = ABR; else PC_temp = PC; @@ -358,13 +359,13 @@ always @* RTS3, RTI4: PC_temp = { DIMUX, ADD }; - BRA1: PC_temp = { ABH, ADD }; + BRA1: PC_temp = { ABR[15:8], ADD }; JMPIX2, - BRA2: PC_temp = { ADD, PCL }; + BRA2: PC_temp = { ADD, PC[7:0] }; // TODO - BRK2: PC_temp = res ? 16'hfffc : - NMI_edge ? 16'hfffa : 16'hfffe; + BRK2: PC_temp = res ? 32'hFFFFFFF4 : + NMI_edge ? 32'hFFFFFFF8 : 32'hFFFFFFFC; default: PC_temp = PC; endcase @@ -386,7 +387,7 @@ always @* FETCH, BRA0, BRA2, - BRK3, + BRK5, JMPI1, JMP1, RTI4, @@ -428,15 +429,15 @@ always @* BRA2, INDY3, JMPIX2, - ABSX2: AB = { ADD, ABL }; + ABSX2: AB = { ADD, ABR[7:0] }; // TODO - BRA1: AB = { ABH, ADD }; + BRA1: AB = { ABR[15:8], ADD }; // TODO JSR0, PUSH1, RTS0, RTI0, - BRK0: AB = { STACKPAGE, regfile }; + BRK0: AB = { 16'h0, STACKPAGE, regfile }; BRK1, JSR1, @@ -446,7 +447,9 @@ always @* RTI1, RTI2, RTI3, - BRK2: AB = { STACKPAGE, ADD }; + BRK2, + BRK3, + BRK4: AB = { 16'h0, STACKPAGE, ADD }; INDY1, INDX1, @@ -458,7 +461,7 @@ always @* REG, READ, - WRITE: AB = { ABH, ABL }; + WRITE: AB = ABR; default: AB = PC; endcase @@ -472,8 +475,7 @@ always @(posedge clk) if( state != PUSH0 && state != PUSH1 && RDY && state != PULL0 && state != PULL1 && state != PULL2 ) begin - ABL <= AB[7:0]; - ABH <= AB[15:8]; + ABR <= AB; end /* @@ -484,14 +486,20 @@ always @* WRITE: DO = ADD; JSR0, - BRK0: DO = PCH; + BRK0: DO = PC[31:24]; JSR1, - BRK1: DO = PCL; + BRK1: DO = PC[23:16]; + + JSR2, + BRK2: DO = PC[15:8]; + + JSR3, + BRK3: DO = PC[7:0]; PUSH1: DO = php ? P : ADD; - BRK2: DO = (IRQ | NMI_edge) ? (P & 8'b1110_1111) : P; + BRK4: DO = (IRQ | NMI_edge) ? (P & 8'b1110_1111) : P; default: DO = store_zero ? 8'b0 : regfile; endcase @@ -505,8 +513,13 @@ always @* BRK0, // writing to stack or memory BRK1, BRK2, + BRK2, + BRK3, + BRK4, JSR0, JSR1, + JSR2, + JSR3, PUSH1, WRITE: WE = 1; @@ -535,7 +548,7 @@ always @* PULL1, RTS2, RTI3, - BRK3, + BRK5, JSR0, JSR2 : write_register = 1; @@ -621,7 +634,7 @@ always @* DECODE : regsel = dst_reg; BRK0, - BRK3, + BRK5, JSR0, JSR2, PULL0, @@ -730,7 +743,7 @@ always @* BRA0, READ: AI = DIMUX; - BRA1: AI = ABH; // don't use PCH in case we're + BRA1: AI = ABR[15:8]; // don't use PCH in case we're TODO FETCH: AI = load_only ? 8'b0 : regfile; @@ -767,7 +780,7 @@ always @* READ: BI = txb_ins ? (trb_ins ? ~regfile : regfile) : 8'h00; - BRA0: BI = PCL; + BRA0: BI = PC[7:0]; // TODO DECODE, ABS1: BI = 8'hxx; @@ -880,7 +893,7 @@ always @(posedge clk) */ always @(posedge clk) - if( state == BRK3 ) + if( state == BRK5 ) I <= 1; else if( state == RTI2 ) I <= DIMUX[2]; @@ -1069,7 +1082,9 @@ always @(posedge clk or posedge reset) BRK0 : state <= BRK1; BRK1 : state <= BRK2; BRK2 : state <= BRK3; - BRK3 : state <= JMP0; + BRK3 : state <= BRK4; + BRK4 : state <= BRK5; + BRK5 : state <= JMP0; WAI : state <= ( (~I & IRQ) | NMI_edge ) ? DECODE : WAI; @@ -1415,7 +1430,7 @@ always @(posedge clk) NMI_1 <= NMI; always @(posedge clk ) - if( NMI_edge && state == BRK3 ) + if( NMI_edge && state == BRK5 ) NMI_edge <= 0; else if( NMI & ~NMI_1 ) NMI_edge <= 1;