Added support for RDY
This commit is contained in:
6
ALU.v
6
ALU.v
@@ -17,7 +17,7 @@
|
||||
*
|
||||
*/
|
||||
|
||||
module ALU( clk, op, right, AI, BI, CI, CO, BCD, OUT, V, Z, N, HC );
|
||||
module ALU( clk, op, right, AI, BI, CI, CO, BCD, OUT, V, Z, N, HC, RDY );
|
||||
input clk;
|
||||
input right;
|
||||
input [3:0] op; // operation
|
||||
@@ -31,6 +31,7 @@ module ALU( clk, op, right, AI, BI, CI, CO, BCD, OUT, V, Z, N, HC );
|
||||
output Z;
|
||||
output N;
|
||||
output HC;
|
||||
input RDY;
|
||||
|
||||
reg [7:0] OUT;
|
||||
reg CO;
|
||||
@@ -89,7 +90,8 @@ always @* begin
|
||||
end
|
||||
|
||||
// calculate the flags
|
||||
always @(posedge clk) begin
|
||||
always @(posedge clk)
|
||||
if( RDY ) begin
|
||||
OUT <= temp[7:0];
|
||||
CO <= temp[8] | CO9;
|
||||
Z <= ~|temp[7:0];
|
||||
|
||||
123
cpu.v
123
cpu.v
@@ -18,7 +18,7 @@
|
||||
* on the output pads if external memory is required.
|
||||
*/
|
||||
|
||||
module cpu( clk, reset, AB, DI, DO, WE, IRQ, NMI );
|
||||
module cpu( clk, reset, AB, DI, DO, WE, IRQ, NMI, RDY );
|
||||
|
||||
input clk; // CPU clock
|
||||
input reset; // reset signal
|
||||
@@ -28,6 +28,7 @@ output [7:0] DO; // data out, write bus
|
||||
output WE; // write enable
|
||||
input IRQ; // interrupt request
|
||||
input NMI; // non-maskable interrupt request
|
||||
input RDY; // Ready signal. Pauses CPU when RDY=0
|
||||
|
||||
/*
|
||||
* internal signals
|
||||
@@ -38,6 +39,10 @@ reg [7:0] ABL; // Address Bus Register LSB
|
||||
reg [7:0] ABH; // Address Bus Register MSB
|
||||
wire [7:0] ADD; // Adder Hold Register (registered in ALU)
|
||||
|
||||
reg [7:0] DIHOLD; // Hold for Data In
|
||||
reg DIHOLD_valid; //
|
||||
wire [7:0] DIMUX; //
|
||||
|
||||
reg [7:0] IRHOLD; // Hold for Instruction register
|
||||
reg IRHOLD_valid; // Valid instruction in IRHOLD
|
||||
|
||||
@@ -88,9 +93,7 @@ wire [7:0] Y = AXYS[SEL_Y]; // Y register
|
||||
wire [7:0] S = AXYS[SEL_S]; // Stack pointer
|
||||
`endif
|
||||
|
||||
wire B = ~(IRQ | NMI_edge);
|
||||
|
||||
wire [7:0] P = { N, V, 1'b1, B, D, I, Z, C };
|
||||
wire [7:0] P = { N, V, 2'b0, D, I, Z, C };
|
||||
|
||||
/*
|
||||
* instruction decoder/sequencer
|
||||
@@ -279,8 +282,8 @@ always @*
|
||||
JMPI1: statename <= "JMPI1";
|
||||
endcase
|
||||
|
||||
always @( PC )
|
||||
$display( "PC:%04x A:%02x X:%02x Y:%02x S:%02x C:%d Z:%d V:%d N:%d", PC, A, X, Y, S, C, Z, V, N );
|
||||
//always @( PC )
|
||||
//$display( "%t, PC:%04x A:%02x X:%02x Y:%02x S:%02x C:%d Z:%d V:%d N:%d", $time, PC, A, X, Y, S, C, Z, V, N );
|
||||
|
||||
`endif
|
||||
|
||||
@@ -302,7 +305,7 @@ always @*
|
||||
JMPI1,
|
||||
JSR3,
|
||||
RTS3,
|
||||
RTI4: PC_temp = { DI, ADD };
|
||||
RTI4: PC_temp = { DIMUX, ADD };
|
||||
|
||||
BRA1: PC_temp = { ABH, ADD };
|
||||
|
||||
@@ -344,6 +347,7 @@ always @*
|
||||
* Set new PC
|
||||
*/
|
||||
always @(posedge clk)
|
||||
if( RDY )
|
||||
PC <= PC_temp + PC_inc;
|
||||
|
||||
/*
|
||||
@@ -362,7 +366,7 @@ always @*
|
||||
JMP1,
|
||||
JMPI1,
|
||||
RTI4,
|
||||
ABS1: AB <= { DI, ADD };
|
||||
ABS1: AB <= { DIMUX, ADD };
|
||||
|
||||
BRA2,
|
||||
INDY3,
|
||||
@@ -392,7 +396,7 @@ always @*
|
||||
INDX2: AB <= { ZEROPAGE, ADD };
|
||||
|
||||
ZP0,
|
||||
INDY0: AB <= { ZEROPAGE, DI };
|
||||
INDY0: AB <= { ZEROPAGE, DIMUX };
|
||||
|
||||
REG,
|
||||
READ,
|
||||
@@ -426,7 +430,7 @@ always @*
|
||||
|
||||
PUSH1: DO <= php ? P : ADD;
|
||||
|
||||
BRK2: DO <= P;
|
||||
BRK2: DO <= (IRQ | NMI_edge) ? P : P | 8'b0001_0000;
|
||||
|
||||
default: DO <= regfile;
|
||||
endcase
|
||||
@@ -522,8 +526,8 @@ end
|
||||
* the ALU during those cycles.
|
||||
*/
|
||||
always @(posedge clk)
|
||||
if( write_register )
|
||||
AXYS[regsel] <= (state == JSR0) ? DI : { ADD[7:4] + ADJH, ADD[3:0] + ADJL };
|
||||
if( write_register & RDY )
|
||||
AXYS[regsel] <= (state == JSR0) ? DIMUX : { ADD[7:4] + ADJH, ADD[3:0] + ADJL };
|
||||
|
||||
/*
|
||||
* register select logic. This determines which of the A, X, Y or
|
||||
@@ -571,7 +575,8 @@ ALU ALU( .clk(clk),
|
||||
.V(AV),
|
||||
.Z(AZ),
|
||||
.N(AN),
|
||||
.HC(HC) );
|
||||
.HC(HC),
|
||||
.RDY(RDY) );
|
||||
|
||||
/*
|
||||
* Select current ALU operation
|
||||
@@ -586,6 +591,9 @@ always @*
|
||||
FETCH,
|
||||
REG : alu_op <= op;
|
||||
|
||||
DECODE,
|
||||
ABS1: alu_op <= 1'bx;
|
||||
|
||||
PUSH1,
|
||||
BRK0,
|
||||
BRK1,
|
||||
@@ -611,7 +619,8 @@ always @*
|
||||
*/
|
||||
|
||||
always @(posedge clk)
|
||||
backwards <= DI[7];
|
||||
if( RDY )
|
||||
backwards <= DIMUX[7];
|
||||
|
||||
/*
|
||||
* ALU A Input MUX
|
||||
@@ -642,12 +651,15 @@ always @*
|
||||
PUSH1: AI <= regfile;
|
||||
|
||||
BRA0,
|
||||
READ: AI <= DI;
|
||||
READ: AI <= DIMUX;
|
||||
|
||||
BRA1: AI <= ABH; // don't use PCH in case we're
|
||||
|
||||
FETCH: AI <= load_only ? 0 : regfile;
|
||||
|
||||
DECODE,
|
||||
ABS1: AI <= 8'hxx; // don't care
|
||||
|
||||
default: AI <= 0;
|
||||
endcase
|
||||
|
||||
@@ -679,7 +691,10 @@ always @*
|
||||
|
||||
BRA0: BI <= PCL;
|
||||
|
||||
default: BI <= DI;
|
||||
DECODE,
|
||||
ABS1: BI <= 8'hxx;
|
||||
|
||||
default: BI <= DIMUX;
|
||||
endcase
|
||||
|
||||
/*
|
||||
@@ -690,9 +705,11 @@ always @*
|
||||
case( state )
|
||||
INDY2,
|
||||
BRA1,
|
||||
ABS1,
|
||||
ABSX1: CI <= CO;
|
||||
|
||||
DECODE,
|
||||
ABS1: CI <= 1'bx;
|
||||
|
||||
READ,
|
||||
REG: CI <= rotate ? C :
|
||||
shift ? 0 : inc;
|
||||
@@ -725,7 +742,7 @@ always @(posedge clk )
|
||||
if( shift && state == WRITE )
|
||||
C <= CO;
|
||||
else if( state == RTI2 )
|
||||
C <= DI[0];
|
||||
C <= DIMUX[0];
|
||||
else if( ~write_back && state == DECODE ) begin
|
||||
if( adc_sbc | shift | compare )
|
||||
C <= CO;
|
||||
@@ -745,7 +762,7 @@ always @(posedge clk)
|
||||
if( state == WRITE )
|
||||
Z <= AZ;
|
||||
else if( state == RTI2 )
|
||||
Z <= DI[1];
|
||||
Z <= DIMUX[1];
|
||||
else if( state == DECODE ) begin
|
||||
if( plp )
|
||||
Z <= ADD[1];
|
||||
@@ -757,14 +774,14 @@ always @(posedge clk)
|
||||
if( state == WRITE )
|
||||
N <= AN;
|
||||
else if( state == RTI2 )
|
||||
N <= DI[7];
|
||||
N <= DIMUX[7];
|
||||
else if( state == DECODE ) begin
|
||||
if( plp )
|
||||
N <= ADD[7];
|
||||
else if( (load_reg & (regsel != SEL_S)) | compare )
|
||||
N <= AN;
|
||||
end else if( state == FETCH && bit )
|
||||
N <= DI[7];
|
||||
N <= DIMUX[7];
|
||||
|
||||
/*
|
||||
* Update I flag
|
||||
@@ -774,7 +791,7 @@ always @(posedge clk)
|
||||
if( state == BRK3 )
|
||||
I <= 1;
|
||||
else if( state == RTI2 )
|
||||
I <= DI[2];
|
||||
I <= DIMUX[2];
|
||||
else if( state == DECODE ) begin
|
||||
if( sei ) I <= 1;
|
||||
if( cli ) I <= 0;
|
||||
@@ -786,7 +803,7 @@ always @(posedge clk)
|
||||
*/
|
||||
always @(posedge clk )
|
||||
if( state == RTI2 )
|
||||
D <= DI[3];
|
||||
D <= DIMUX[3];
|
||||
else if( state == DECODE ) begin
|
||||
if( sed ) D <= 1;
|
||||
if( cld ) D <= 0;
|
||||
@@ -798,13 +815,13 @@ always @(posedge clk )
|
||||
*/
|
||||
always @(posedge clk )
|
||||
if( state == RTI2 )
|
||||
V <= DI[6];
|
||||
V <= DIMUX[6];
|
||||
else if( state == DECODE ) begin
|
||||
if( adc_sbc ) V <= AV;
|
||||
if( clv ) V <= 0;
|
||||
if( plp ) V <= ADD[6];
|
||||
end else if( state == FETCH && bit )
|
||||
V <= DI[6];
|
||||
V <= DIMUX[6];
|
||||
|
||||
/*
|
||||
* Instruction decoder
|
||||
@@ -816,17 +833,30 @@ always @(posedge clk )
|
||||
* time to read the IR again before the next decode.
|
||||
*/
|
||||
|
||||
reg RDY1 = 1;
|
||||
|
||||
always @(posedge clk )
|
||||
RDY1 <= RDY;
|
||||
|
||||
always @(posedge clk )
|
||||
if( ~RDY && RDY1 )
|
||||
DIHOLD <= DI;
|
||||
|
||||
always @(posedge clk )
|
||||
if( reset )
|
||||
IRHOLD_valid <= 0;
|
||||
else if( state == PULL0 || state == PUSH0 ) begin
|
||||
IRHOLD <= DI;
|
||||
else if( RDY ) begin
|
||||
if( state == PULL0 || state == PUSH0 ) begin
|
||||
IRHOLD <= DIMUX;
|
||||
IRHOLD_valid <= 1;
|
||||
end else if( state == DECODE )
|
||||
IRHOLD_valid <= 0;
|
||||
end
|
||||
|
||||
assign IR = (IRQ & ~I) | NMI_edge ? 8'h00 :
|
||||
IRHOLD_valid ? IRHOLD : DI;
|
||||
IRHOLD_valid ? IRHOLD : DIMUX;
|
||||
|
||||
assign DIMUX = ~RDY1 ? DIHOLD : DI;
|
||||
|
||||
/*
|
||||
* Microcode state machine
|
||||
@@ -834,7 +864,7 @@ assign IR = (IRQ & ~I) | NMI_edge ? 8'h00 :
|
||||
always @(posedge clk or posedge reset)
|
||||
if( reset )
|
||||
state <= BRK0;
|
||||
else case( state )
|
||||
else if( RDY ) case( state )
|
||||
DECODE :
|
||||
casex ( IR )
|
||||
8'b0000_0000: state <= BRK0;
|
||||
@@ -942,7 +972,7 @@ always @(posedge clk)
|
||||
res <= 0;
|
||||
|
||||
always @(posedge clk)
|
||||
if( state == DECODE )
|
||||
if( state == DECODE && RDY )
|
||||
casex( IR )
|
||||
8'b0xxx_xx01, // ORA, AND, EOR, ADC
|
||||
8'b1x1x_xx01, // LDA, SBC
|
||||
@@ -955,7 +985,7 @@ always @(posedge clk)
|
||||
endcase
|
||||
|
||||
always @(posedge clk)
|
||||
if( state == DECODE )
|
||||
if( state == DECODE && RDY )
|
||||
casex( IR )
|
||||
8'b1110_1000, // INX
|
||||
8'b1100_1010, // DEX
|
||||
@@ -975,7 +1005,7 @@ always @(posedge clk)
|
||||
endcase
|
||||
|
||||
always @(posedge clk)
|
||||
if( state == DECODE )
|
||||
if( state == DECODE && RDY )
|
||||
casex( IR )
|
||||
8'b1011_1010: // TSX
|
||||
src_reg <= SEL_S;
|
||||
@@ -996,7 +1026,7 @@ always @(posedge clk)
|
||||
endcase
|
||||
|
||||
always @(posedge clk)
|
||||
if( state == DECODE )
|
||||
if( state == DECODE && RDY )
|
||||
casex( IR )
|
||||
8'bxxx1_0001, // INDY
|
||||
8'b10x1_x110, // LDX/STX zpg/abs, Y
|
||||
@@ -1008,7 +1038,7 @@ always @(posedge clk)
|
||||
|
||||
|
||||
always @(posedge clk)
|
||||
if( state == DECODE )
|
||||
if( state == DECODE && RDY )
|
||||
casex( IR )
|
||||
8'b100x_x1x0, // STX, STY
|
||||
8'b100x_xx01: // STA
|
||||
@@ -1019,7 +1049,7 @@ always @(posedge clk)
|
||||
endcase
|
||||
|
||||
always @(posedge clk )
|
||||
if( state == DECODE )
|
||||
if( state == DECODE && RDY )
|
||||
casex( IR )
|
||||
8'b0xxx_x110, // ASL, ROL, LSR, ROR
|
||||
8'b11xx_x110: // DEC/INC
|
||||
@@ -1030,7 +1060,7 @@ always @(posedge clk )
|
||||
|
||||
|
||||
always @(posedge clk )
|
||||
if( state == DECODE )
|
||||
if( state == DECODE && RDY )
|
||||
casex( IR )
|
||||
8'b101x_xxxx: // LDA, LDX, LDY
|
||||
load_only <= 1;
|
||||
@@ -1038,7 +1068,7 @@ always @(posedge clk )
|
||||
endcase
|
||||
|
||||
always @(posedge clk )
|
||||
if( state == DECODE )
|
||||
if( state == DECODE && RDY )
|
||||
casex( IR )
|
||||
8'b111x_x110, // INC
|
||||
8'b11x0_1000: // INX, INY
|
||||
@@ -1048,7 +1078,7 @@ always @(posedge clk )
|
||||
endcase
|
||||
|
||||
always @(posedge clk )
|
||||
if( state == DECODE || state == BRK0 )
|
||||
if( (state == DECODE || state == BRK0) && RDY )
|
||||
casex( IR )
|
||||
8'bx11x_xx01: // SBC, ADC
|
||||
adc_sbc <= 1;
|
||||
@@ -1057,7 +1087,7 @@ always @(posedge clk )
|
||||
endcase
|
||||
|
||||
always @(posedge clk )
|
||||
if( state == DECODE || state == BRK0 )
|
||||
if( (state == DECODE || state == BRK0) && RDY )
|
||||
casex( IR )
|
||||
8'b011x_xx01: // ADC
|
||||
adc_bcd <= D;
|
||||
@@ -1066,7 +1096,7 @@ always @(posedge clk )
|
||||
endcase
|
||||
|
||||
always @(posedge clk )
|
||||
if( state == DECODE )
|
||||
if( state == DECODE && RDY )
|
||||
casex( IR )
|
||||
8'b0xxx_x110, // ASL, ROL, LSR, ROR (abs, absx, zpg, zpgx)
|
||||
8'b0xxx_1010: // ASL, ROL, LSR, ROR (acc)
|
||||
@@ -1076,7 +1106,7 @@ always @(posedge clk )
|
||||
endcase
|
||||
|
||||
always @(posedge clk )
|
||||
if( state == DECODE )
|
||||
if( state == DECODE && RDY )
|
||||
casex( IR )
|
||||
8'b11x0_0x00, // CPX, CPY (imm/zp)
|
||||
8'b11x0_1100, // CPX, CPY (abs)
|
||||
@@ -1087,7 +1117,7 @@ always @(posedge clk )
|
||||
endcase
|
||||
|
||||
always @(posedge clk )
|
||||
if( state == DECODE )
|
||||
if( state == DECODE && RDY )
|
||||
casex( IR )
|
||||
8'b01xx_xx10: // ROR, LSR
|
||||
shift_right <= 1;
|
||||
@@ -1096,7 +1126,7 @@ always @(posedge clk )
|
||||
endcase
|
||||
|
||||
always @(posedge clk )
|
||||
if( state == DECODE )
|
||||
if( state == DECODE && RDY )
|
||||
casex( IR )
|
||||
8'b0x1x_1010, // ROL A, ROR A
|
||||
8'b0x1x_x110: // ROR, ROL
|
||||
@@ -1106,7 +1136,7 @@ always @(posedge clk )
|
||||
endcase
|
||||
|
||||
always @(posedge clk )
|
||||
if( state == DECODE )
|
||||
if( state == DECODE && RDY )
|
||||
casex( IR )
|
||||
8'b00xx_xx10: // ROL, ASL
|
||||
op <= OP_ROL;
|
||||
@@ -1132,7 +1162,7 @@ always @(posedge clk )
|
||||
endcase
|
||||
|
||||
always @(posedge clk )
|
||||
if( state == DECODE )
|
||||
if( state == DECODE && RDY )
|
||||
casex( IR )
|
||||
8'b0010_x100: // BIT zp/abs
|
||||
bit <= 1;
|
||||
@@ -1144,7 +1174,7 @@ always @(posedge clk )
|
||||
* special instructions
|
||||
*/
|
||||
always @(posedge clk )
|
||||
if( state == DECODE ) begin
|
||||
if( state == DECODE && RDY ) begin
|
||||
php <= (IR == 8'h08);
|
||||
clc <= (IR == 8'h18);
|
||||
plp <= (IR == 8'h28);
|
||||
@@ -1158,6 +1188,7 @@ always @(posedge clk )
|
||||
end
|
||||
|
||||
always @(posedge clk)
|
||||
if( RDY )
|
||||
cond_code <= IR[7:5];
|
||||
|
||||
always @*
|
||||
|
||||
Reference in New Issue
Block a user