URL
https://opencores.org/ocsvn/mc6803/mc6803/trunk
Subversion Repositories mc6803
[/] [mc6803/] [trunk/] [6801_core.sv] - Rev 3
Go to most recent revision | Compare with Previous | Blame | View Log
module cpu01(
input logic clk,
input logic rst,
output logic rw,
output logic vma,
output logic[15:0]address,
input logic[7:0] data_in,
output logic[7:0] data_out,
input logic hold,
input logic halt,
input logic irq,
input logic nmi,
input logic irq_icf,
input logic irq_ocf,
input logic irq_tof,
input logic irq_sci,
output logic[15:0] test_alu,
output logic[7:0] test_cc
);
localparam SBIT = 7;
localparam XBIT = 6;
localparam HBIT = 5;
localparam IBIT = 4;
localparam NBIT = 3;
localparam ZBIT = 2;
localparam VBIT = 1;
localparam CBIT = 0;
typedef enum logic[5:0] {reset_state, fetch_state, decode_state,
extended_state, indexed_state, read8_state, read16_state, immediate16_state,
write8_state, write16_state,
execute_state, halt_state, error_state,
mul_state, mulea_state, muld_state,
mul0_state, mul1_state, mul2_state, mul3_state,
mul4_state, mul5_state, mul6_state, mul7_state,
jmp_state, jsr_state, jsr1_state,
branch_state, bsr_state, bsr1_state,
rts_hi_state, rts_lo_state,
int_pcl_state, int_pch_state,
int_ixl_state, int_ixh_state,
int_cc_state, int_acca_state, int_accb_state,
int_wai_state, int_mask_state,
rti_state, rti_cc_state, rti_acca_state, rti_accb_state,
rti_ixl_state, rti_ixh_state,
rti_pcl_state, rti_pch_state,
pula_state, psha_state, pulb_state, pshb_state,
pulx_lo_state, pulx_hi_state, pshx_lo_state, pshx_hi_state,
vect_lo_state, vect_hi_state } state_type;
typedef enum logic[5:0] {idle_ad, fetch_ad, read_ad, write_ad, push_ad, pull_ad, int_hi_ad, int_lo_ad } addr_type;
typedef enum logic[5:0] {md_lo_dout, md_hi_dout, acca_dout, accb_dout, ix_lo_dout, ix_hi_dout, cc_dout, pc_lo_dout, pc_hi_dout} dout_type;
typedef enum logic[2:0] {reset_op, fetch_op, latch_op } op_type;
typedef enum logic[5:0] {reset_acca, load_acca, load_hi_acca, pull_acca, latch_acca } acca_type;
typedef enum logic[5:0] {reset_accb, load_accb, pull_accb, latch_accb } accb_type;
typedef enum logic[5:0] {reset_cc, load_cc, pull_cc, latch_cc } cc_type;
typedef enum logic[5:0] {reset_ix, load_ix, pull_lo_ix, pull_hi_ix, latch_ix } ix_type;
typedef enum logic[5:0] {reset_sp, latch_sp, load_sp } sp_type;
typedef enum logic[5:0] {reset_pc, latch_pc, load_ea_pc, add_ea_pc, pull_lo_pc, pull_hi_pc, inc_pc } pc_type;
typedef enum logic[5:0] {reset_md, latch_md, load_md, fetch_first_md, fetch_next_md, shiftl_md } md_type;
typedef enum logic[5:0] {reset_ea, latch_ea, add_ix_ea, load_accb_ea, inc_ea, fetch_first_ea, fetch_next_ea } ea_type;
typedef enum logic[5:0] {reset_iv, latch_iv, swi_iv, nmi_iv, irq_iv, icf_iv, ocf_iv, tof_iv, sci_iv } iv_type;
typedef enum logic[5:0] {reset_nmi, set_nmi, latch_nmi } nmi_type;
typedef enum logic[5:0] {acca_left, accb_left, accd_left, md_left, ix_left, sp_left } left_type;
typedef enum logic[5:0] {md_right, zero_right, plus_one_right, accb_right } right_type;
typedef enum logic[5:0] {alu_add8, alu_sub8, alu_add16, alu_sub16, alu_adc, alu_sbc,
alu_and, alu_ora, alu_eor,
alu_tst, alu_inc, alu_dec, alu_clr, alu_neg, alu_com,
alu_inx, alu_dex,
alu_lsr16, alu_lsl16,
alu_ror8, alu_rol8,
alu_asr8, alu_asl8, alu_lsr8,
alu_sei, alu_cli, alu_sec, alu_clc, alu_sev, alu_clv, alu_tpa, alu_tap,
alu_ld8, alu_st8, alu_ld16, alu_st16, alu_nop, alu_daa } alu_type;
logic[7:0] op_code;
logic[7:0] acca;
logic[7:0] accb;
logic[7:0] cc;
logic[7:0] cc_out;
logic[15:0] xreg;
logic[15:0] sp;
logic[15:0] ea;
logic[15:0] pc;
logic[15:0] md;
logic[15:0] left;
logic[15:0] right;
logic[15:0] out_alu;
logic[2:0] iv;
logic nmi_req;
logic nmi_ack;
state_type state;
state_type next_state;
pc_type pc_ctrl;
ea_type ea_ctrl;
op_type op_ctrl;
md_type md_ctrl;
acca_type acca_ctrl;
accb_type accb_ctrl;
ix_type ix_ctrl;
cc_type cc_ctrl;
sp_type sp_ctrl;
iv_type iv_ctrl;
left_type left_ctrl;
right_type right_ctrl;
alu_type alu_ctrl;
addr_type addr_ctrl;
dout_type dout_ctrl;
nmi_type nmi_ctrl;
////////////////////////////////////
////
//// Address bus multiplexer
////
////////////////////////////////////
always_comb
begin
case(addr_ctrl)
idle_ad:
begin
address = 16'b1111111111111111;
vma = 1'b0;
rw = 1'b1;
end
fetch_ad:
begin
address = pc;
vma = 1'b1;
rw = 1'b1;
end
read_ad:
begin
address = ea;
vma = 1'b1;
rw = 1'b1;
end
write_ad:
begin
address = ea;
vma = 1'b1;
rw = 1'b0;
end
push_ad:
begin
address = sp;
vma = 1'b1;
rw = 1'b0;
end
pull_ad:
begin
address = sp;
vma = 1'b1;
rw = 1'b1;
end
int_hi_ad:
begin
address = {12'b111111111111, iv, 1'b0};
vma = 1'b1;
rw = 1'b1;
end
int_lo_ad:
begin
address = {12'b111111111111, iv, 1'b1};
vma = 1'b1;
rw = 1'b1;
end
default:
begin
address = 16'b1111111111111111;
vma = 1'b0;
rw = 1'b1;
end
endcase
end
//////////////////////////////////
////
//// Data Bus output
////
//////////////////////////////////
always_comb
begin
case (dout_ctrl)
md_hi_dout: //// alu output
data_out = md[15:8];
md_lo_dout:
data_out = md[7:0];
acca_dout: //// accumulator a
data_out = acca;
accb_dout: //// accumulator b
data_out = accb;
ix_lo_dout: //// index reg
data_out = xreg[7:0];
ix_hi_dout: //// index reg
data_out = xreg[15:8];
cc_dout: //// condition codes
data_out = cc;
pc_lo_dout: //// low order pc
data_out = pc[7:0];
pc_hi_dout: //// high order pc
data_out = pc[15:8];
default:
data_out = 8'b00000000;
endcase
end
////////////////////////////////////
////
//// Program Counter Control
////
////////////////////////////////////
logic[15:0] tempof;
logic[15:0] temppc;
always_comb
begin
case (pc_ctrl)
add_ea_pc:
begin
if (ea[7] == 0)
tempof = {8'b00000000, ea[7:0]};
else
tempof = {8'b11111111, ea[7:0]};
end
inc_pc:
tempof = 16'b0000000000000001;
default:
tempof = 16'b0000000000000000;
endcase
case (pc_ctrl)
reset_pc:
temppc = 16'b1111111111111110;
load_ea_pc:
temppc = ea;
pull_lo_pc:
begin
temppc[7:0] = data_in;
temppc[15:8] = pc[15:8];
end
pull_hi_pc:
begin
temppc[7:0] = pc[7:0];
temppc[15:8] = data_in;
end
default:
temppc = pc;
endcase
end
always_ff @(posedge clk)
begin
if (hold == 1'b1)
pc <= pc;
else
pc <= temppc + tempof;
end
////////////////////////////////////
////
//// Effective Address Control
////
////////////////////////////////////
logic[15:0] tempind;
logic[15:0] tempea;
always_comb
begin
case (ea_ctrl)
add_ix_ea:
tempind = {8'b00000000, ea[7:0]};
inc_ea:
tempind = 16'b0000000000000001;
default:
tempind = 16'b0000000000000000;
endcase
case (ea_ctrl)
reset_ea:
tempea = 16'b0000000000000000;
load_accb_ea:
tempea = {8'b00000000, accb[7:0]};
add_ix_ea:
tempea = xreg;
fetch_first_ea:
begin
tempea[7:0] = data_in;
tempea[15:8] = 8'b00000000;
end
fetch_next_ea:
begin
tempea[7:0] = data_in;
tempea[15:8] = ea[7:0];
end
default:
tempea = ea;
endcase
end
always_ff @(posedge clk)
begin
if (hold == 1'b1)
ea <= ea;
else
ea <= tempea + tempind;
end
//////////////////////////////////
////
//// Accumulator A
////
//////////////////////////////////
always_ff @(posedge clk)
begin
if (hold == 1'b1)
acca <= acca;
else
case (acca_ctrl)
reset_acca:
acca <= 8'b00000000;
load_acca:
acca <= out_alu[7:0];
load_hi_acca:
acca <= out_alu[15:8];
pull_acca:
acca <= data_in;
default:
// latch_acca:
acca <= acca;
endcase
end
//////////////////////////////////
////
//// Accumulator B
////
//////////////////////////////////
always_ff @(posedge clk)
begin
if (hold == 1'b1)
accb <= accb;
else
case (accb_ctrl)
reset_accb:
accb <= 8'b00000000;
load_accb:
accb <= out_alu[7:0];
pull_accb:
accb <= data_in;
default:
// latch_accb:
accb <= accb;
endcase
end
//////////////////////////////////
////
//// X Index register
////
//////////////////////////////////
always_ff @(posedge clk)
begin
if (hold == 1'b1)
xreg <= xreg;
else
case (ix_ctrl)
reset_ix:
xreg <= 16'b0000000000000000;
load_ix:
xreg <= out_alu[15:0];
pull_hi_ix:
xreg[15:8] <= data_in;
pull_lo_ix:
xreg[7:0] <= data_in;
default:
// latch_ix:
xreg <= xreg;
endcase
end
//////////////////////////////////
////
//// stack pointer
////
//////////////////////////////////
always_ff @(posedge clk)
begin
if (hold == 1'b1)
sp <= sp;
else
case (sp_ctrl)
reset_sp:
sp <= 16'b0000000000000000;
load_sp:
sp <= out_alu[15:0];
default:
// latch_sp:
sp <= sp;
endcase
end
//////////////////////////////////
////
//// Memory Data
////
//////////////////////////////////
always_ff @(posedge clk)
begin
if (hold == 1'b1)
md <= md;
else
case (md_ctrl)
reset_md:
md <= 16'b0000000000000000;
load_md:
md <= out_alu[15:0];
fetch_first_md:
begin
md[15:8] <= 8'b00000000;
md[7:0] <= data_in;
end
fetch_next_md:
begin
md[15:8] <= md[7:0];
md[7:0] <= data_in;
end
shiftl_md:
begin
md[15:1] <= md[14:0];
md[0] <= 1'b0;
end
default:
// latch_md:
md <= md;
endcase
end
////////////////////////////////////
////
//// Condition Codes
////
////////////////////////////////////
always_ff @(posedge clk)
begin
if (hold == 1'b1)
cc <= cc;
else
case (cc_ctrl)
reset_cc:
cc <= 8'b11000000;
load_cc:
cc <= cc_out;
pull_cc:
cc <= data_in;
default:
// latch_cc:
cc <= cc;
endcase
end
////////////////////////////////////
////
//// interrupt vector
////
////////////////////////////////////
always_ff @(posedge clk)
begin
if (hold == 1'b1)
iv <= iv;
else
case (iv_ctrl)
reset_iv:
iv <= 3'b111;
nmi_iv:
iv <= 3'b110;
swi_iv:
iv <= 3'b101;
irq_iv:
iv <= 3'b100;
icf_iv:
iv <= 3'b011;
ocf_iv:
iv <= 3'b010;
tof_iv:
iv <= 3'b001;
sci_iv:
iv <= 3'b000;
default:
iv <= iv;
endcase
end
////////////////////////////////////
////
//// op code fetch
////
////////////////////////////////////
always_ff @(posedge clk)
begin
if (hold == 1'b1)
op_code <= op_code;
else
case (op_ctrl)
reset_op:
op_code <= 8'b00000001; // nop
fetch_op:
op_code <= data_in;
default:
// latch_op:
op_code <= op_code;
endcase
end
////////////////////////////////////
////
//// Left Mux
////
////////////////////////////////////
always_comb
begin
case (left_ctrl)
acca_left:
begin
left[15:8] = 8'b00000000;
left[7:0] = acca;
end
accb_left:
begin
left[15:8] = 8'b00000000;
left[7:0] = accb;
end
accd_left:
begin
left[15:8] = acca;
left[7:0] = accb;
end
ix_left:
left = xreg;
sp_left:
left = sp;
default:
// md_left:
left = md;
endcase
end
////////////////////////////////////
////
//// Right Mux
////
////////////////////////////////////
always_comb
begin
case (right_ctrl)
zero_right:
right = 16'b0000000000000000;
plus_one_right:
right = 16'b0000000000000001;
accb_right:
right = {8'b00000000, accb};
default:
// md_right:
right = md;
endcase
end
////////////////////////////////////
////
//// Arithmetic Logic Unit
////
////////////////////////////////////
logic valid_lo, valid_hi;
logic carry_in;
logic[7:0] daa_reg;
always_comb
begin
case (alu_ctrl)
alu_adc, alu_sbc,
alu_rol8, alu_ror8:
carry_in = cc[CBIT];
default:
carry_in = 1'b0;
endcase
valid_lo = (left[3:0] <= 9);
valid_hi = (left[7:4] <= 9);
if (cc[CBIT] == 1'b0)
begin
if( cc[HBIT] == 1'b1 )
begin
if (valid_hi)
daa_reg = 8'b00000110;
else
daa_reg = 8'b01100110;
end
else
begin
if (valid_lo)
begin
if (valid_hi)
daa_reg = 8'b00000000;
else
daa_reg = 8'b01100000;
end
else
begin
if( left[7:4] <= 8 )
daa_reg = 8'b00000110;
else
daa_reg = 8'b01100110;
end
end
end
else
begin
if ( cc[HBIT] == 1'b1 )
daa_reg = 8'b01100110;
else
if (valid_lo)
daa_reg = 8'b01100000;
else
daa_reg = 8'b01100110;
end
case (alu_ctrl)
alu_add8, alu_inc, alu_add16, alu_inx, alu_adc:
out_alu = left + right + {15'b000000000000000, carry_in};
alu_sub8, alu_dec, alu_sub16, alu_dex, alu_sbc:
out_alu = left - right - {15'b000000000000000, carry_in};
alu_and:
out_alu = left & right; // and/bit
alu_ora:
out_alu = left | right; // or
alu_eor:
out_alu = left ^ right; // eor/xor
alu_lsl16, alu_asl8, alu_rol8:
out_alu = {left[14:0], carry_in}; // rol8/asl8/lsl16
alu_lsr16, alu_lsr8:
out_alu = {carry_in, left[15:1]}; // lsr
alu_ror8:
out_alu = {8'b00000000, carry_in, left[7:1]}; // ror
alu_asr8:
out_alu = {8'b00000000, left[7], left[7:1]}; // asr
alu_neg:
out_alu = right - left; // neg (right=0)
alu_com:
out_alu = ~left;
alu_clr, alu_ld8, alu_ld16:
out_alu = right; // clr, ld
alu_st8, alu_st16:
out_alu = left;
alu_daa:
out_alu = left + {8'b00000000, daa_reg};
alu_tpa:
out_alu = {8'b00000000, cc};
default:
out_alu = left; // nop
endcase
//
// carry bit
//
case (alu_ctrl)
alu_add8, alu_adc:
cc_out[CBIT] = (left[7] & right[7]) | (left[7] & ~out_alu[7]) | (right[7] & ~out_alu[7]);
alu_sub8, alu_sbc:
cc_out[CBIT] = ((~left[7]) & right[7]) | ((~left[7]) & out_alu[7]) | (right[7] & out_alu[7]);
alu_add16:
cc_out[CBIT] = (left[15] & right[15]) | (left[15] & ~out_alu[15]) | (right[15] & ~out_alu[15]);
alu_sub16:
cc_out[CBIT] = ((~left[15]) & right[15]) | ((~left[15]) & out_alu[15]) | (right[15] & out_alu[15]);
alu_ror8 , alu_lsr16, alu_lsr8, alu_asr8:
cc_out[CBIT] = left[0];
alu_rol8, alu_asl8:
cc_out[CBIT] = left[7];
alu_lsl16:
cc_out[CBIT] = left[15];
alu_com:
cc_out[CBIT] = 1'b1;
alu_neg, alu_clr:
cc_out[CBIT] = out_alu[7] | out_alu[6] | out_alu[5] | out_alu[4] | out_alu[3] | out_alu[2] | out_alu[1] | out_alu[0];
alu_daa:
begin
if ( daa_reg[7:4] == 4'b0110 )
cc_out[CBIT] = 1'b1;
else
cc_out[CBIT] = 1'b0;
end
alu_sec:
cc_out[CBIT] = 1'b1;
alu_clc:
cc_out[CBIT] = 1'b0;
alu_tap:
cc_out[CBIT] = left[CBIT];
default:
cc_out[CBIT] = cc[CBIT];
endcase
//
// Zero flag
//
case (alu_ctrl)
alu_add8 , alu_sub8 ,
alu_adc , alu_sbc ,
alu_and , alu_ora , alu_eor ,
alu_inc , alu_dec ,
alu_neg , alu_com , alu_clr ,
alu_rol8 , alu_ror8 , alu_asr8 , alu_asl8 , alu_lsr8 ,
alu_ld8 , alu_st8:
cc_out[ZBIT] = ~( out_alu[7] | out_alu[6] | out_alu[5] | out_alu[4] |
out_alu[3] | out_alu[2] | out_alu[1] | out_alu[0] );
alu_add16, alu_sub16,
alu_lsl16, alu_lsr16,
alu_inx, alu_dex,
alu_ld16, alu_st16:
cc_out[ZBIT] = ~( out_alu[15] | out_alu[14] | out_alu[13] | out_alu[12] |
out_alu[11] | out_alu[10] | out_alu[9] | out_alu[8] |
out_alu[7] | out_alu[6] | out_alu[5] | out_alu[4] |
out_alu[3] | out_alu[2] | out_alu[1] | out_alu[0] );
alu_tap:
cc_out[ZBIT] = left[ZBIT];
default:
cc_out[ZBIT] = cc[ZBIT];
endcase
//
// negative flag
//
case (alu_ctrl)
alu_add8, alu_sub8,
alu_adc, alu_sbc,
alu_and, alu_ora, alu_eor,
alu_rol8, alu_ror8, alu_asr8, alu_asl8, alu_lsr8,
alu_inc, alu_dec, alu_neg, alu_com, alu_clr,
alu_ld8 , alu_st8:
cc_out[NBIT] = out_alu[7];
alu_add16, alu_sub16,
alu_lsl16, alu_lsr16,
alu_ld16, alu_st16:
cc_out[NBIT] = out_alu[15];
alu_tap:
cc_out[NBIT] = left[NBIT];
default:
cc_out[NBIT] = cc[NBIT];
endcase
//
// Interrupt mask flag
//
case (alu_ctrl)
alu_sei:
cc_out[IBIT] = 1'b1; // set interrupt mask
alu_cli:
cc_out[IBIT] = 1'b0; // clear interrupt mask
alu_tap:
cc_out[IBIT] = left[IBIT];
default:
cc_out[IBIT] = cc[IBIT]; // interrupt mask
endcase
//
// Half Carry flag
//
case (alu_ctrl)
alu_add8, alu_adc:
cc_out[HBIT] = (left[3] & right[3]) |
(right[3] & ~out_alu[3]) |
(left[3] & ~out_alu[3]);
alu_tap:
cc_out[HBIT] = left[HBIT];
default:
cc_out[HBIT] = cc[HBIT];
endcase
//
// Overflow flag
//
case (alu_ctrl)
alu_add8, alu_adc:
cc_out[VBIT] = (left[7] & right[7] & (~out_alu[7])) |
((~left[7]) & (~right[7]) & out_alu[7]);
alu_sub8, alu_sbc:
cc_out[VBIT] = (left[7] & (~right[7]) & (~out_alu[7])) |
((~left[7]) & right[7] & out_alu[7]);
alu_add16:
cc_out[VBIT] = (left[15] & right[15] & (~out_alu[15])) |
((~left[15]) & (~right[15]) & out_alu[15]);
alu_sub16:
cc_out[VBIT] = (left[15] & (~right[15]) & (~out_alu[15])) |
((~left[15]) & right[15] & out_alu[15]);
alu_inc:
cc_out[VBIT] = ((~left[7]) & left[6] & left[5] & left[4] &
left[3] & left[2] & left[1] & left[0]);
alu_dec, alu_neg:
cc_out[VBIT] = (left[7] & (~left[6]) & (~left[5]) & (~left[4]) &
(~left[3]) & (~left[2]) & (~left[1]) & (~left[0]));
alu_asr8:
cc_out[VBIT] = left[0] ^ left[7];
alu_lsr8, alu_lsr16:
cc_out[VBIT] = left[0];
alu_ror8:
cc_out[VBIT] = left[0] ^ cc[CBIT];
alu_lsl16:
cc_out[VBIT] = left[15] ^ left[14];
alu_rol8, alu_asl8:
cc_out[VBIT] = left[7] ^ left[6];
alu_tap:
cc_out[VBIT] = left[VBIT];
alu_and, alu_ora, alu_eor, alu_com,
alu_st8, alu_st16, alu_ld8, alu_ld16,
alu_clv:
cc_out[VBIT] = 1'b0;
alu_sev:
cc_out[VBIT] = 1'b1;
default:
cc_out[VBIT] = cc[VBIT];
endcase
case (alu_ctrl)
alu_tap:
begin
cc_out[XBIT] = cc[XBIT] & left[XBIT];
cc_out[SBIT] = left[SBIT];
end
default:
begin
cc_out[XBIT] = cc[XBIT] & left[XBIT];
cc_out[SBIT] = cc[SBIT];
end
endcase
test_alu = out_alu;
test_cc = cc_out;
end
////////////////////////////////////
//
// Detect Edge of NMI interrupt
//
////////////////////////////////////
always_ff @(posedge clk)
begin
if (hold == 1'b1)
nmi_req <= nmi_req;
else if (rst==1'b1)
nmi_req <= 1'b0;
else if (nmi==1'b1 && nmi_ack==1'b0)
nmi_req <= 1'b1;
else if (nmi==1'b0 && nmi_ack==1'b1)
nmi_req <= 1'b0;
else
nmi_req <= nmi_req;
end
////////////////////////////////////
//
// Nmi mux
//
////////////////////////////////////
always_ff @(posedge clk)
begin
if (hold == 1'b1)
nmi_ack <= nmi_ack;
else
case (nmi_ctrl)
set_nmi:
nmi_ack <= 1'b1;
reset_nmi:
nmi_ack <= 1'b0;
default:
// when latch_nmi =>
nmi_ack <= nmi_ack;
endcase
end
////////////////////////////////////
//
// state sequencer
//
////////////////////////////////////
always_comb
begin
case (state)
reset_state: // released from reset
begin
// reset the registers
op_ctrl = reset_op;
acca_ctrl = reset_acca;
accb_ctrl = reset_accb;
ix_ctrl = reset_ix;
sp_ctrl = reset_sp;
pc_ctrl = reset_pc;
ea_ctrl = reset_ea;
md_ctrl = reset_md;
iv_ctrl = reset_iv;
nmi_ctrl = reset_nmi;
// idle the ALU
left_ctrl = acca_left;
right_ctrl = zero_right;
alu_ctrl = alu_nop;
cc_ctrl = reset_cc;
// idle the bus
dout_ctrl = md_lo_dout;
addr_ctrl = idle_ad;
next_state = vect_hi_state;
end
//
// Jump via interrupt vector
// iv holds interrupt type
// fetch PC hi from vector location
//
vect_hi_state:
begin
// default the registers
op_ctrl = latch_op;
nmi_ctrl = latch_nmi;
acca_ctrl = latch_acca;
accb_ctrl = latch_accb;
ix_ctrl = latch_ix;
sp_ctrl = latch_sp;
md_ctrl = latch_md;
ea_ctrl = latch_ea;
iv_ctrl = latch_iv;
// idle the ALU
left_ctrl = acca_left;
right_ctrl = zero_right;
alu_ctrl = alu_nop;
cc_ctrl = latch_cc;
// fetch pc low interrupt vector
pc_ctrl = pull_hi_pc;
addr_ctrl = int_hi_ad;
dout_ctrl = pc_hi_dout;
next_state = vect_lo_state;
end
//
// jump via interrupt vector
// iv holds vector type
// fetch PC lo from vector location
//
vect_lo_state:
begin
// default the registers
op_ctrl = latch_op;
nmi_ctrl = latch_nmi;
acca_ctrl = latch_acca;
accb_ctrl = latch_accb;
ix_ctrl = latch_ix;
sp_ctrl = latch_sp;
md_ctrl = latch_md;
ea_ctrl = latch_ea;
iv_ctrl = latch_iv;
// idle the ALU
left_ctrl = acca_left;
right_ctrl = zero_right;
alu_ctrl = alu_nop;
cc_ctrl = latch_cc;
// fetch the vector low byte
pc_ctrl = pull_lo_pc;
addr_ctrl = int_lo_ad;
dout_ctrl = pc_lo_dout;
next_state = fetch_state;
end
//
// Here to fetch an instruction
// PC points to opcode
// Should service interrupt requests at this point
// either from the timer
// or from the external input.
//
fetch_state:
begin
case (op_code[7:4])
4'b0000,
4'b0001,
4'b0010, // branch conditional
4'b0011,
4'b0100, // acca single op
4'b0101, // accb single op
4'b0110, // indexed single op
4'b0111: // extended single op
begin
// idle ALU
left_ctrl = acca_left;
right_ctrl = zero_right;
alu_ctrl = alu_nop;
cc_ctrl = latch_cc;
acca_ctrl = latch_acca;
accb_ctrl = latch_accb;
ix_ctrl = latch_ix;
sp_ctrl = latch_sp;
end
4'b1000, // acca immediate
4'b1001, // acca direct
4'b1010, // acca indexed
4'b1011: // acca extended
begin
case (op_code[3:0])
4'b0000: // suba
begin
left_ctrl = acca_left;
right_ctrl = md_right;
alu_ctrl = alu_sub8;
cc_ctrl = load_cc;
acca_ctrl = load_acca;
accb_ctrl = latch_accb;
ix_ctrl = latch_ix;
sp_ctrl = latch_sp;
end
4'b0001: // cmpa
begin
left_ctrl = acca_left;
right_ctrl = md_right;
alu_ctrl = alu_sub8;
cc_ctrl = load_cc;
acca_ctrl = latch_acca;
accb_ctrl = latch_accb;
ix_ctrl = latch_ix;
sp_ctrl = latch_sp;
end
4'b0010: // sbca
begin
left_ctrl = acca_left;
right_ctrl = md_right;
alu_ctrl = alu_sbc;
cc_ctrl = load_cc;
acca_ctrl = load_acca;
accb_ctrl = latch_accb;
ix_ctrl = latch_ix;
sp_ctrl = latch_sp;
end
4'b0011: // subd
begin
left_ctrl = accd_left;
right_ctrl = md_right;
alu_ctrl = alu_sub16;
cc_ctrl = load_cc;
acca_ctrl = load_hi_acca;
accb_ctrl = load_accb;
ix_ctrl = latch_ix;
sp_ctrl = latch_sp;
end
4'b0100: // anda
begin
left_ctrl = acca_left;
right_ctrl = md_right;
alu_ctrl = alu_and;
cc_ctrl = load_cc;
acca_ctrl = load_acca;
accb_ctrl = latch_accb;
ix_ctrl = latch_ix;
sp_ctrl = latch_sp;
end
4'b0101: // bita
begin
left_ctrl = acca_left;
right_ctrl = md_right;
alu_ctrl = alu_and;
cc_ctrl = load_cc;
acca_ctrl = latch_acca;
accb_ctrl = latch_accb;
ix_ctrl = latch_ix;
sp_ctrl = latch_sp;
end
4'b0110: // ldaa
begin
left_ctrl = acca_left;
right_ctrl = md_right;
alu_ctrl = alu_ld8;
cc_ctrl = load_cc;
acca_ctrl = load_acca;
accb_ctrl = latch_accb;
ix_ctrl = latch_ix;
sp_ctrl = latch_sp;
end
4'b0111: // staa
begin
left_ctrl = acca_left;
right_ctrl = md_right;
alu_ctrl = alu_st8;
cc_ctrl = load_cc;
acca_ctrl = latch_acca;
accb_ctrl = latch_accb;
ix_ctrl = latch_ix;
sp_ctrl = latch_sp;
end
4'b1000: // eora
begin
left_ctrl = acca_left;
right_ctrl = md_right;
alu_ctrl = alu_eor;
cc_ctrl = load_cc;
acca_ctrl = load_acca;
accb_ctrl = latch_accb;
ix_ctrl = latch_ix;
sp_ctrl = latch_sp;
end
4'b1001: // adca
begin
left_ctrl = acca_left;
right_ctrl = md_right;
alu_ctrl = alu_adc;
cc_ctrl = load_cc;
acca_ctrl = load_acca;
accb_ctrl = latch_accb;
ix_ctrl = latch_ix;
sp_ctrl = latch_sp;
end
4'b1010: // oraa
begin
left_ctrl = acca_left;
right_ctrl = md_right;
alu_ctrl = alu_ora;
cc_ctrl = load_cc;
acca_ctrl = load_acca;
accb_ctrl = latch_accb;
ix_ctrl = latch_ix;
sp_ctrl = latch_sp;
end
4'b1011: // adda
begin
left_ctrl = acca_left;
right_ctrl = md_right;
alu_ctrl = alu_add8;
cc_ctrl = load_cc;
acca_ctrl = load_acca;
accb_ctrl = latch_accb;
ix_ctrl = latch_ix;
sp_ctrl = latch_sp;
end
4'b1100: // cpx
begin
left_ctrl = ix_left;
right_ctrl = md_right;
alu_ctrl = alu_sub16;
cc_ctrl = load_cc;
acca_ctrl = latch_acca;
accb_ctrl = latch_accb;
ix_ctrl = latch_ix;
sp_ctrl = latch_sp;
end
4'b1101: // bsr / jsr
begin
left_ctrl = acca_left;
right_ctrl = md_right;
alu_ctrl = alu_nop;
cc_ctrl = latch_cc;
acca_ctrl = latch_acca;
accb_ctrl = latch_accb;
ix_ctrl = latch_ix;
sp_ctrl = latch_sp;
end
4'b1110: // lds
begin
left_ctrl = sp_left;
right_ctrl = md_right;
alu_ctrl = alu_ld16;
cc_ctrl = load_cc;
acca_ctrl = latch_acca;
accb_ctrl = latch_accb;
ix_ctrl = latch_ix;
sp_ctrl = load_sp;
end
4'b1111: // sts
begin
left_ctrl = sp_left;
right_ctrl = md_right;
alu_ctrl = alu_st16;
cc_ctrl = load_cc;
acca_ctrl = latch_acca;
accb_ctrl = latch_accb;
ix_ctrl = latch_ix;
sp_ctrl = latch_sp;
end
default:
begin
left_ctrl = acca_left;
right_ctrl = md_right;
alu_ctrl = alu_nop;
cc_ctrl = latch_cc;
acca_ctrl = latch_acca;
accb_ctrl = latch_accb;
ix_ctrl = latch_ix;
sp_ctrl = latch_sp;
end
endcase
end
4'b1100, // accb immediate
4'b1101, // accb direct
4'b1110, // accb indexed
4'b1111: // accb extended
begin
case (op_code[3:0])
4'b0000: // subb
begin
left_ctrl = accb_left;
right_ctrl = md_right;
alu_ctrl = alu_sub8;
cc_ctrl = load_cc;
acca_ctrl = latch_acca;
accb_ctrl = load_accb;
ix_ctrl = latch_ix;
sp_ctrl = latch_sp;
end
4'b0001: // cmpb
begin
left_ctrl = accb_left;
right_ctrl = md_right;
alu_ctrl = alu_sub8;
cc_ctrl = load_cc;
acca_ctrl = latch_acca;
accb_ctrl = latch_accb;
ix_ctrl = latch_ix;
sp_ctrl = latch_sp;
end
4'b0010: // sbcb
begin
left_ctrl = accb_left;
right_ctrl = md_right;
alu_ctrl = alu_sbc;
cc_ctrl = load_cc;
acca_ctrl = latch_acca;
accb_ctrl = load_accb;
ix_ctrl = latch_ix;
sp_ctrl = latch_sp;
end
4'b0011: // addd
begin
left_ctrl = accd_left;
right_ctrl = md_right;
alu_ctrl = alu_add16;
cc_ctrl = load_cc;
acca_ctrl = load_hi_acca;
accb_ctrl = load_accb;
ix_ctrl = latch_ix;
sp_ctrl = latch_sp;
end
4'b0100: // andb
begin
left_ctrl = accb_left;
right_ctrl = md_right;
alu_ctrl = alu_and;
cc_ctrl = load_cc;
acca_ctrl = latch_acca;
accb_ctrl = load_accb;
ix_ctrl = latch_ix;
sp_ctrl = latch_sp;
end
4'b0101: // bitb
begin
left_ctrl = accb_left;
right_ctrl = md_right;
alu_ctrl = alu_and;
cc_ctrl = load_cc;
acca_ctrl = latch_acca;
accb_ctrl = latch_accb;
ix_ctrl = latch_ix;
sp_ctrl = latch_sp;
end
4'b0110: // ldab
begin
left_ctrl = accb_left;
right_ctrl = md_right;
alu_ctrl = alu_ld8;
cc_ctrl = load_cc;
acca_ctrl = latch_acca;
accb_ctrl = load_accb;
ix_ctrl = latch_ix;
sp_ctrl = latch_sp;
end
4'b0111: // stab
begin
left_ctrl = accb_left;
right_ctrl = md_right;
alu_ctrl = alu_st8;
cc_ctrl = load_cc;
acca_ctrl = latch_acca;
accb_ctrl = latch_accb;
ix_ctrl = latch_ix;
sp_ctrl = latch_sp;
end
4'b1000: // eorb
begin
left_ctrl = accb_left;
right_ctrl = md_right;
alu_ctrl = alu_eor;
cc_ctrl = load_cc;
acca_ctrl = latch_acca;
accb_ctrl = load_accb;
ix_ctrl = latch_ix;
sp_ctrl = latch_sp;
end
4'b1001: // adcb
begin
left_ctrl = accb_left;
right_ctrl = md_right;
alu_ctrl = alu_adc;
cc_ctrl = load_cc;
acca_ctrl = latch_acca;
accb_ctrl = load_accb;
ix_ctrl = latch_ix;
sp_ctrl = latch_sp;
end
4'b1010: // orab
begin
left_ctrl = accb_left;
right_ctrl = md_right;
alu_ctrl = alu_ora;
cc_ctrl = load_cc;
acca_ctrl = latch_acca;
accb_ctrl = load_accb;
ix_ctrl = latch_ix;
sp_ctrl = latch_sp;
end
4'b1011: // addb
begin
left_ctrl = accb_left;
right_ctrl = md_right;
alu_ctrl = alu_add8;
cc_ctrl = load_cc;
acca_ctrl = latch_acca;
accb_ctrl = load_accb;
ix_ctrl = latch_ix;
sp_ctrl = latch_sp;
end
4'b1100: // ldd
begin
left_ctrl = accd_left;
right_ctrl = md_right;
alu_ctrl = alu_ld16;
cc_ctrl = load_cc;
acca_ctrl = load_hi_acca;
accb_ctrl = load_accb;
ix_ctrl = latch_ix;
sp_ctrl = latch_sp;
end
4'b1101: // std
begin
left_ctrl = accd_left;
right_ctrl = md_right;
alu_ctrl = alu_st16;
cc_ctrl = load_cc;
acca_ctrl = latch_acca;
accb_ctrl = latch_accb;
ix_ctrl = latch_ix;
sp_ctrl = latch_sp;
end
4'b1110: // ldx
begin
left_ctrl = ix_left;
right_ctrl = md_right;
alu_ctrl = alu_ld16;
cc_ctrl = load_cc;
acca_ctrl = latch_acca;
accb_ctrl = latch_accb;
ix_ctrl = load_ix;
sp_ctrl = latch_sp;
end
4'b1111: // stx
begin
left_ctrl = ix_left;
right_ctrl = md_right;
alu_ctrl = alu_st16;
cc_ctrl = load_cc;
acca_ctrl = latch_acca;
accb_ctrl = latch_accb;
ix_ctrl = latch_ix;
sp_ctrl = latch_sp;
end
default:
begin
left_ctrl = accb_left;
right_ctrl = md_right;
alu_ctrl = alu_nop;
cc_ctrl = latch_cc;
acca_ctrl = latch_acca;
accb_ctrl = latch_accb;
ix_ctrl = latch_ix;
sp_ctrl = latch_sp;
end
endcase
end
default:
begin
left_ctrl = accd_left;
right_ctrl = md_right;
alu_ctrl = alu_nop;
cc_ctrl = latch_cc;
acca_ctrl = latch_acca;
accb_ctrl = latch_accb;
ix_ctrl = latch_ix;
sp_ctrl = latch_sp;
end
endcase
md_ctrl = latch_md;
// fetch the op code
op_ctrl = fetch_op;
ea_ctrl = reset_ea;
addr_ctrl = fetch_ad;
dout_ctrl = md_lo_dout;
iv_ctrl = latch_iv;
if (halt == 1'b1)
begin
pc_ctrl = latch_pc;
nmi_ctrl = latch_nmi;
next_state = halt_state;
end
// service non maskable interrupts
else if (nmi_req == 1'b1 && nmi_ack == 1'b0)
begin
pc_ctrl = latch_pc;
nmi_ctrl = set_nmi;
next_state = int_pcl_state;
end
// service maskable interrupts
else
begin
//
// nmi request is not cleared until nmi input goes low
//
if(nmi_req == 1'b0 && nmi_ack==1'b1)
nmi_ctrl = reset_nmi;
else
nmi_ctrl = latch_nmi;
//
// IRQ is level sensitive
//
if ((irq == 1'b1 || irq_icf == 1'b1 || irq_ocf == 1'b1 || irq_tof == 1'b1 || irq_sci == 1'b1) && cc[IBIT] == 1'b0)
begin
pc_ctrl = latch_pc;
next_state = int_pcl_state;
end
else
begin
// Advance the PC to fetch next instruction byte
pc_ctrl = inc_pc;
next_state = decode_state;
end
end
end
//
// Here to decode instruction
// and fetch next byte of intruction
// whether it be necessary or not
//
decode_state:
begin
// fetch first byte of address or immediate data
ea_ctrl = fetch_first_ea;
addr_ctrl = fetch_ad;
dout_ctrl = md_lo_dout;
op_ctrl = latch_op;
nmi_ctrl = latch_nmi;
iv_ctrl = latch_iv;
case (op_code[7:4])
4'b0000:
begin
md_ctrl = fetch_first_md;
sp_ctrl = latch_sp;
pc_ctrl = latch_pc;
case (op_code[3:0])
4'b0001: // nop
begin
left_ctrl = accd_left;
right_ctrl = zero_right;
alu_ctrl = alu_nop;
cc_ctrl = latch_cc;
acca_ctrl = latch_acca;
accb_ctrl = latch_accb;
ix_ctrl = latch_ix;
end
4'b0100: // lsrd
begin
left_ctrl = accd_left;
right_ctrl = zero_right;
alu_ctrl = alu_lsr16;
cc_ctrl = load_cc;
acca_ctrl = load_hi_acca;
accb_ctrl = load_accb;
ix_ctrl = latch_ix;
end
4'b0101: // lsld
begin
left_ctrl = accd_left;
right_ctrl = zero_right;
alu_ctrl = alu_lsl16;
cc_ctrl = load_cc;
acca_ctrl = load_hi_acca;
accb_ctrl = load_accb;
ix_ctrl = latch_ix;
end
4'b0110: // tap
begin
left_ctrl = acca_left;
right_ctrl = zero_right;
alu_ctrl = alu_tap;
cc_ctrl = load_cc;
acca_ctrl = latch_acca;
accb_ctrl = latch_accb;
ix_ctrl = latch_ix;
end
4'b0111: // tpa
begin
left_ctrl = acca_left;
right_ctrl = zero_right;
alu_ctrl = alu_tpa;
cc_ctrl = latch_cc;
acca_ctrl = load_acca;
accb_ctrl = latch_accb;
ix_ctrl = latch_ix;
end
4'b1000: // inx
begin
left_ctrl = ix_left;
right_ctrl = plus_one_right;
alu_ctrl = alu_inx;
cc_ctrl = load_cc;
acca_ctrl = latch_acca;
accb_ctrl = latch_accb;
ix_ctrl = load_ix;
end
4'b1001: // dex
begin
left_ctrl = ix_left;
right_ctrl = plus_one_right;
alu_ctrl = alu_dex;
cc_ctrl = load_cc;
acca_ctrl = latch_acca;
accb_ctrl = latch_accb;
ix_ctrl = load_ix;
end
4'b1010: // clv
begin
left_ctrl = acca_left;
right_ctrl = zero_right;
alu_ctrl = alu_clv;
cc_ctrl = load_cc;
acca_ctrl = latch_acca;
accb_ctrl = latch_accb;
ix_ctrl = latch_ix;
end
4'b1011: // sev
begin
left_ctrl = acca_left;
right_ctrl = zero_right;
alu_ctrl = alu_sev;
cc_ctrl = load_cc;
acca_ctrl = latch_acca;
accb_ctrl = latch_accb;
ix_ctrl = latch_ix;
end
4'b1100: // clc
begin
left_ctrl = acca_left;
right_ctrl = zero_right;
alu_ctrl = alu_clc;
cc_ctrl = load_cc;
acca_ctrl = latch_acca;
accb_ctrl = latch_accb;
ix_ctrl = latch_ix;
end
4'b1101: // sec
begin
left_ctrl = acca_left;
right_ctrl = zero_right;
alu_ctrl = alu_sec;
cc_ctrl = load_cc;
acca_ctrl = latch_acca;
accb_ctrl = latch_accb;
ix_ctrl = latch_ix;
end
4'b1110: // cli
begin
left_ctrl = acca_left;
right_ctrl = zero_right;
alu_ctrl = alu_cli;
cc_ctrl = load_cc;
acca_ctrl = latch_acca;
accb_ctrl = latch_accb;
ix_ctrl = latch_ix;
end
4'b1111: // sei
begin
left_ctrl = acca_left;
right_ctrl = zero_right;
alu_ctrl = alu_sei;
cc_ctrl = load_cc;
acca_ctrl = latch_acca;
accb_ctrl = latch_accb;
ix_ctrl = latch_ix;
end
default:
begin
left_ctrl = acca_left;
right_ctrl = zero_right;
alu_ctrl = alu_nop;
cc_ctrl = latch_cc;
acca_ctrl = latch_acca;
accb_ctrl = latch_accb;
ix_ctrl = latch_ix;
end
endcase
next_state = fetch_state;
end
// acca / accb inherent instructions
4'b0001:
begin
md_ctrl = fetch_first_md;
ix_ctrl = latch_ix;
sp_ctrl = latch_sp;
pc_ctrl = latch_pc;
left_ctrl = acca_left;
right_ctrl = accb_right;
case (op_code[3:0])
4'b0000: // sba
begin
alu_ctrl = alu_sub8;
cc_ctrl = load_cc;
acca_ctrl = load_acca;
accb_ctrl = latch_accb;
end
4'b0001: // cba
begin
alu_ctrl = alu_sub8;
cc_ctrl = load_cc;
acca_ctrl = latch_acca;
accb_ctrl = latch_accb;
end
4'b0110: // tab
begin
alu_ctrl = alu_st8;
cc_ctrl = load_cc;
acca_ctrl = latch_acca;
accb_ctrl = load_accb;
end
4'b0111: // tba
begin
alu_ctrl = alu_ld8;
cc_ctrl = load_cc;
acca_ctrl = load_acca;
accb_ctrl = latch_accb;
end
4'b1001: // daa
begin
alu_ctrl = alu_daa;
cc_ctrl = load_cc;
acca_ctrl = load_acca;
accb_ctrl = latch_accb;
end
4'b1011: // aba
begin
alu_ctrl = alu_add8;
cc_ctrl = load_cc;
acca_ctrl = load_acca;
accb_ctrl = latch_accb;
end
default:
begin
alu_ctrl = alu_nop;
cc_ctrl = latch_cc;
acca_ctrl = latch_acca;
accb_ctrl = latch_accb;
end
endcase
next_state = fetch_state;
end
4'b0010: // branch conditional
begin
md_ctrl = fetch_first_md;
acca_ctrl = latch_acca;
accb_ctrl = latch_accb;
ix_ctrl = latch_ix;
sp_ctrl = latch_sp;
left_ctrl = acca_left;
right_ctrl = zero_right;
alu_ctrl = alu_nop;
cc_ctrl = latch_cc;
// increment the pc
pc_ctrl = inc_pc;
case (op_code[3:0])
4'b0000: // bra
next_state = branch_state;
4'b0001: // brn
next_state = fetch_state;
4'b0010: // bhi
begin
if ((cc[CBIT] | cc[ZBIT]) == 1'b0)
next_state = branch_state;
else
next_state = fetch_state;
end
4'b0011: // bls
begin
if ((cc[CBIT] | cc[ZBIT]) == 1'b1)
next_state = branch_state;
else
next_state = fetch_state;
end
4'b0100: // bcc/bhs
begin
if (cc[CBIT] == 1'b0)
next_state = branch_state;
else
next_state = fetch_state;
end
4'b0101: // bcs/blo
begin
if (cc[CBIT] == 1'b1)
next_state = branch_state;
else
next_state = fetch_state;
end
4'b0110: // bne
begin
if (cc[ZBIT] == 1'b0)
next_state = branch_state;
else
next_state = fetch_state;
end
4'b0111: // beq
begin
if (cc[ZBIT] == 1'b1)
next_state = branch_state;
else
next_state = fetch_state;
end
4'b1000: // bvc
begin
if (cc[VBIT] == 1'b0)
next_state = branch_state;
else
next_state = fetch_state;
end
4'b1001: // bvs
begin
if (cc[VBIT] == 1'b1)
next_state = branch_state;
else
next_state = fetch_state;
end
4'b1010: // bpl
begin
if (cc[NBIT] == 1'b0)
next_state = branch_state;
else
next_state = fetch_state;
end
4'b1011: // bmi
begin
if (cc[NBIT] == 1'b1)
next_state = branch_state;
else
next_state = fetch_state;
end
4'b1100: // bge
begin
if ((cc[NBIT] ^ cc[VBIT]) == 1'b0)
next_state = branch_state;
else
next_state = fetch_state;
end
4'b1101: // blt
begin
if ((cc[NBIT] ^ cc[VBIT]) == 1'b1)
next_state = branch_state;
else
next_state = fetch_state;
end
4'b1110: // bgt
begin
if ((cc[ZBIT] | (cc[NBIT] ^ cc[VBIT])) == 1'b0)
next_state = branch_state;
else
next_state = fetch_state;
end
4'b1111: // ble
begin
if ((cc[ZBIT] | (cc[NBIT] ^ cc[VBIT])) == 1'b1)
next_state = branch_state;
else
next_state = fetch_state;
end
default:
next_state = fetch_state;
endcase
end
//
// Single byte stack operators
// Do not advance PC
//
4'b0011:
begin
md_ctrl = fetch_first_md;
acca_ctrl = latch_acca;
accb_ctrl = latch_accb;
pc_ctrl = latch_pc;
case (op_code[3:0])
4'b0000: // tsx
begin
left_ctrl = sp_left;
right_ctrl = plus_one_right;
alu_ctrl = alu_add16;
cc_ctrl = latch_cc;
ix_ctrl = load_ix;
sp_ctrl = latch_sp;
next_state = fetch_state;
end
4'b0001: // ins
begin
left_ctrl = sp_left;
right_ctrl = plus_one_right;
alu_ctrl = alu_add16;
cc_ctrl = latch_cc;
ix_ctrl = latch_ix;
sp_ctrl = load_sp;
next_state = fetch_state;
end
4'b0010: // pula
begin
left_ctrl = sp_left;
right_ctrl = plus_one_right;
alu_ctrl = alu_add16;
cc_ctrl = latch_cc;
ix_ctrl = latch_ix;
sp_ctrl = load_sp;
next_state = pula_state;
end
4'b0011: // pulb
begin
left_ctrl = sp_left;
right_ctrl = plus_one_right;
alu_ctrl = alu_add16;
cc_ctrl = latch_cc;
ix_ctrl = latch_ix;
sp_ctrl = load_sp;
next_state = pulb_state;
end
4'b0100: // des
begin
// decrement sp
left_ctrl = sp_left;
right_ctrl = plus_one_right;
alu_ctrl = alu_sub16;
cc_ctrl = latch_cc;
ix_ctrl = latch_ix;
sp_ctrl = load_sp;
next_state = fetch_state;
end
4'b0101: // txs
begin
left_ctrl = ix_left;
right_ctrl = plus_one_right;
alu_ctrl = alu_sub16;
cc_ctrl = latch_cc;
ix_ctrl = latch_ix;
sp_ctrl = load_sp;
next_state = fetch_state;
end
4'b0110: // psha
begin
left_ctrl = sp_left;
right_ctrl = zero_right;
alu_ctrl = alu_nop;
cc_ctrl = latch_cc;
ix_ctrl = latch_ix;
sp_ctrl = latch_sp;
next_state = psha_state;
end
4'b0111: // pshb
begin
left_ctrl = sp_left;
right_ctrl = zero_right;
alu_ctrl = alu_nop;
cc_ctrl = latch_cc;
ix_ctrl = latch_ix;
sp_ctrl = latch_sp;
next_state = pshb_state;
end
4'b1000: // pulx
begin
left_ctrl = sp_left;
right_ctrl = plus_one_right;
alu_ctrl = alu_add16;
cc_ctrl = latch_cc;
ix_ctrl = latch_ix;
sp_ctrl = load_sp;
next_state = pulx_hi_state;
end
4'b1001: // rts
begin
left_ctrl = sp_left;
right_ctrl = plus_one_right;
alu_ctrl = alu_add16;
cc_ctrl = latch_cc;
ix_ctrl = latch_ix;
sp_ctrl = load_sp;
next_state = rts_hi_state;
end
4'b1010: // abx
begin
left_ctrl = ix_left;
right_ctrl = accb_right;
alu_ctrl = alu_add16;
cc_ctrl = latch_cc;
ix_ctrl = load_ix;
sp_ctrl = latch_sp;
next_state = fetch_state;
end
4'b1011: // rti
begin
left_ctrl = sp_left;
right_ctrl = plus_one_right;
alu_ctrl = alu_add16;
cc_ctrl = latch_cc;
ix_ctrl = latch_ix;
sp_ctrl = load_sp;
next_state = rti_cc_state;
end
4'b1100: // pshx
begin
left_ctrl = sp_left;
right_ctrl = zero_right;
alu_ctrl = alu_nop;
cc_ctrl = latch_cc;
ix_ctrl = latch_ix;
sp_ctrl = latch_sp;
next_state = pshx_lo_state;
end
4'b1101: // mul
begin
left_ctrl = acca_left;
right_ctrl = accb_right;
alu_ctrl = alu_add16;
cc_ctrl = latch_cc;
ix_ctrl = latch_ix;
sp_ctrl = latch_sp;
next_state = mul_state;
end
4'b1110: // wai
begin
left_ctrl = sp_left;
right_ctrl = zero_right;
alu_ctrl = alu_nop;
cc_ctrl = latch_cc;
ix_ctrl = latch_ix;
sp_ctrl = latch_sp;
next_state = int_pcl_state;
end
4'b1111: // swi
begin
left_ctrl = sp_left;
right_ctrl = zero_right;
alu_ctrl = alu_nop;
cc_ctrl = latch_cc;
ix_ctrl = latch_ix;
sp_ctrl = latch_sp;
next_state = int_pcl_state;
end
default:
begin
left_ctrl = sp_left;
right_ctrl = zero_right;
alu_ctrl = alu_nop;
cc_ctrl = latch_cc;
ix_ctrl = latch_ix;
sp_ctrl = latch_sp;
next_state = fetch_state;
end
endcase
end
//
// Accumulator A Single operand
// source = Acc A dest = Acc A
// Do not advance PC
//
4'b0100: // acca single op
begin
md_ctrl = fetch_first_md;
accb_ctrl = latch_accb;
pc_ctrl = latch_pc;
ix_ctrl = latch_ix;
sp_ctrl = latch_sp;
left_ctrl = acca_left;
case (op_code[3:0])
4'b0000: // neg
begin
right_ctrl = zero_right;
alu_ctrl = alu_neg;
acca_ctrl = load_acca;
cc_ctrl = load_cc;
end
4'b0011: // com
begin
right_ctrl = zero_right;
alu_ctrl = alu_com;
acca_ctrl = load_acca;
cc_ctrl = load_cc;
end
4'b0100: // lsr
begin
right_ctrl = zero_right;
alu_ctrl = alu_lsr8;
acca_ctrl = load_acca;
cc_ctrl = load_cc;
end
4'b0110: // ror
begin
right_ctrl = zero_right;
alu_ctrl = alu_ror8;
acca_ctrl = load_acca;
cc_ctrl = load_cc;
end
4'b0111: // asr
begin
right_ctrl = zero_right;
alu_ctrl = alu_asr8;
acca_ctrl = load_acca;
cc_ctrl = load_cc;
end
4'b1000: // asl
begin
right_ctrl = zero_right;
alu_ctrl = alu_asl8;
acca_ctrl = load_acca;
cc_ctrl = load_cc;
end
4'b1001: // rol
begin
right_ctrl = zero_right;
alu_ctrl = alu_rol8;
acca_ctrl = load_acca;
cc_ctrl = load_cc;
end
4'b1010: // dec
begin
right_ctrl = plus_one_right;
alu_ctrl = alu_dec;
acca_ctrl = load_acca;
cc_ctrl = load_cc;
end
4'b1011: // undefined
begin
right_ctrl = zero_right;
alu_ctrl = alu_nop;
acca_ctrl = latch_acca;
cc_ctrl = latch_cc;
end
4'b1100: // inc
begin
right_ctrl = plus_one_right;
alu_ctrl = alu_inc;
acca_ctrl = load_acca;
cc_ctrl = load_cc;
end
4'b1101: // tst
begin
right_ctrl = zero_right;
alu_ctrl = alu_st8;
acca_ctrl = latch_acca;
cc_ctrl = load_cc;
end
4'b1110: // jmp
begin
right_ctrl = zero_right;
alu_ctrl = alu_nop;
acca_ctrl = latch_acca;
cc_ctrl = latch_cc;
end
4'b1111: // clr
begin
right_ctrl = zero_right;
alu_ctrl = alu_clr;
acca_ctrl = load_acca;
cc_ctrl = load_cc;
end
default:
begin
right_ctrl = zero_right;
alu_ctrl = alu_nop;
acca_ctrl = latch_acca;
cc_ctrl = latch_cc;
end
endcase
next_state = fetch_state;
end
//
// single operand acc b
// Do not advance PC
//
4'b0101:
begin
md_ctrl = fetch_first_md;
acca_ctrl = latch_acca;
pc_ctrl = latch_pc;
ix_ctrl = latch_ix;
sp_ctrl = latch_sp;
left_ctrl = accb_left;
case (op_code[3:0])
4'b0000: // neg
begin
right_ctrl = zero_right;
alu_ctrl = alu_neg;
accb_ctrl = load_accb;
cc_ctrl = load_cc;
end
4'b0011: // com
begin
right_ctrl = zero_right;
alu_ctrl = alu_com;
accb_ctrl = load_accb;
cc_ctrl = load_cc;
end
4'b0100: // lsr
begin
right_ctrl = zero_right;
alu_ctrl = alu_lsr8;
accb_ctrl = load_accb;
cc_ctrl = load_cc;
end
4'b0110: // ror
begin
right_ctrl = zero_right;
alu_ctrl = alu_ror8;
accb_ctrl = load_accb;
cc_ctrl = load_cc;
end
4'b0111: // asr
begin
right_ctrl = zero_right;
alu_ctrl = alu_asr8;
accb_ctrl = load_accb;
cc_ctrl = load_cc;
end
4'b1000: // asl
begin
right_ctrl = zero_right;
alu_ctrl = alu_asl8;
accb_ctrl = load_accb;
cc_ctrl = load_cc;
end
4'b1001: // rol
begin
right_ctrl = zero_right;
alu_ctrl = alu_rol8;
accb_ctrl = load_accb;
cc_ctrl = load_cc;
end
4'b1010: // dec
begin
right_ctrl = plus_one_right;
alu_ctrl = alu_dec;
accb_ctrl = load_accb;
cc_ctrl = load_cc;
end
4'b1011: // undefined
begin
right_ctrl = zero_right;
alu_ctrl = alu_nop;
accb_ctrl = latch_accb;
cc_ctrl = latch_cc;
end
4'b1100: // inc
begin
right_ctrl = plus_one_right;
alu_ctrl = alu_inc;
accb_ctrl = load_accb;
cc_ctrl = load_cc;
end
4'b1101: // tst
begin
right_ctrl = zero_right;
alu_ctrl = alu_st8;
accb_ctrl = latch_accb;
cc_ctrl = load_cc;
end
4'b1110: // jmp
begin
right_ctrl = zero_right;
alu_ctrl = alu_nop;
accb_ctrl = latch_accb;
cc_ctrl = latch_cc;
end
4'b1111: // clr
begin
right_ctrl = zero_right;
alu_ctrl = alu_clr;
accb_ctrl = load_accb;
cc_ctrl = load_cc;
end
default:
begin
right_ctrl = zero_right;
alu_ctrl = alu_nop;
accb_ctrl = latch_accb;
cc_ctrl = latch_cc;
end
endcase
next_state = fetch_state;
end
//
// Single operand indexed
// Two byte instruction so advance PC
// EA should hold index offset
//
4'b0110: // indexed single op
begin
md_ctrl = fetch_first_md;
acca_ctrl = latch_acca;
accb_ctrl = latch_accb;
ix_ctrl = latch_ix;
sp_ctrl = latch_sp;
// increment the pc
left_ctrl = acca_left;
right_ctrl = zero_right;
alu_ctrl = alu_nop;
cc_ctrl = latch_cc;
pc_ctrl = inc_pc;
next_state = indexed_state;
end
//
// Single operand extended addressing
// three byte instruction so advance the PC
// Low order EA holds high order address
//
4'b0111: // extended single op
begin
md_ctrl = fetch_first_md;
acca_ctrl = latch_acca;
accb_ctrl = latch_accb;
ix_ctrl = latch_ix;
sp_ctrl = latch_sp;
// increment the pc
left_ctrl = acca_left;
right_ctrl = zero_right;
alu_ctrl = alu_nop;
cc_ctrl = latch_cc;
pc_ctrl = inc_pc;
next_state = extended_state;
end
4'b1000: // acca immediate
begin
md_ctrl = fetch_first_md;
acca_ctrl = latch_acca;
accb_ctrl = latch_accb;
ix_ctrl = latch_ix;
sp_ctrl = latch_sp;
// increment the pc
left_ctrl = acca_left;
right_ctrl = zero_right;
alu_ctrl = alu_nop;
cc_ctrl = latch_cc;
pc_ctrl = inc_pc;
case (op_code[3:0])
4'b0011, // subdd #
4'b1100, // cpx #
4'b1110: // lds #
next_state = immediate16_state;
4'b1101: // bsr
next_state = bsr_state;
default:
next_state = fetch_state;
endcase
end
4'b1001: // acca direct
begin
acca_ctrl = latch_acca;
accb_ctrl = latch_accb;
ix_ctrl = latch_ix;
sp_ctrl = latch_sp;
// increment the pc
pc_ctrl = inc_pc;
case (op_code[3:0])
4'b0111: // staa direct
begin
left_ctrl = acca_left;
right_ctrl = zero_right;
alu_ctrl = alu_st8;
cc_ctrl = latch_cc;
md_ctrl = load_md;
next_state = write8_state;
end
4'b1111: // sts direct
begin
left_ctrl = sp_left;
right_ctrl = zero_right;
alu_ctrl = alu_st16;
cc_ctrl = latch_cc;
md_ctrl = load_md;
next_state = write16_state;
end
4'b1101: // jsr direct
begin
left_ctrl = acca_left;
right_ctrl = zero_right;
alu_ctrl = alu_nop;
cc_ctrl = latch_cc;
md_ctrl = fetch_first_md;
next_state = jsr_state;
end
default:
begin
left_ctrl = acca_left;
right_ctrl = zero_right;
alu_ctrl = alu_nop;
cc_ctrl = latch_cc;
md_ctrl = fetch_first_md;
next_state = read8_state;
end
endcase
end
4'b1010: // acca indexed
begin
md_ctrl = fetch_first_md;
acca_ctrl = latch_acca;
accb_ctrl = latch_accb;
ix_ctrl = latch_ix;
sp_ctrl = latch_sp;
// increment the pc
left_ctrl = acca_left;
right_ctrl = zero_right;
alu_ctrl = alu_nop;
cc_ctrl = latch_cc;
pc_ctrl = inc_pc;
next_state = indexed_state;
end
4'b1011: // acca extended
begin
md_ctrl = fetch_first_md;
acca_ctrl = latch_acca;
accb_ctrl = latch_accb;
ix_ctrl = latch_ix;
sp_ctrl = latch_sp;
// increment the pc
left_ctrl = acca_left;
right_ctrl = zero_right;
alu_ctrl = alu_nop;
cc_ctrl = latch_cc;
pc_ctrl = inc_pc;
next_state = extended_state;
end
4'b1100: // accb immediate
begin
md_ctrl = fetch_first_md;
acca_ctrl = latch_acca;
accb_ctrl = latch_accb;
ix_ctrl = latch_ix;
sp_ctrl = latch_sp;
// increment the pc
left_ctrl = acca_left;
right_ctrl = zero_right;
alu_ctrl = alu_nop;
cc_ctrl = latch_cc;
pc_ctrl = inc_pc;
case (op_code[3:0])
4'b0011, // addd #
4'b1100, // ldd #
4'b1110: // ldx #
next_state = immediate16_state;
default:
next_state = fetch_state;
endcase
end
4'b1101: // accb direct
begin
acca_ctrl = latch_acca;
accb_ctrl = latch_accb;
ix_ctrl = latch_ix;
sp_ctrl = latch_sp;
// increment the pc
pc_ctrl = inc_pc;
case (op_code[3:0])
4'b0111: // stab direct
begin
left_ctrl = accb_left;
right_ctrl = zero_right;
alu_ctrl = alu_st8;
cc_ctrl = latch_cc;
md_ctrl = load_md;
next_state = write8_state;
end
4'b1101: // std direct
begin
left_ctrl = accd_left;
right_ctrl = zero_right;
alu_ctrl = alu_st16;
cc_ctrl = latch_cc;
md_ctrl = load_md;
next_state = write16_state;
end
4'b1111: // stx direct
begin
left_ctrl = ix_left;
right_ctrl = zero_right;
alu_ctrl = alu_st16;
cc_ctrl = latch_cc;
md_ctrl = load_md;
next_state = write16_state;
end
default:
begin
left_ctrl = acca_left;
right_ctrl = zero_right;
alu_ctrl = alu_nop;
cc_ctrl = latch_cc;
md_ctrl = fetch_first_md;
next_state = read8_state;
end
endcase
end
4'b1110: // accb indexed
begin
md_ctrl = fetch_first_md;
acca_ctrl = latch_acca;
accb_ctrl = latch_accb;
ix_ctrl = latch_ix;
sp_ctrl = latch_sp;
// increment the pc
left_ctrl = acca_left;
right_ctrl = zero_right;
alu_ctrl = alu_nop;
cc_ctrl = latch_cc;
pc_ctrl = inc_pc;
next_state = indexed_state;
end
4'b1111: // accb extended
begin
md_ctrl = fetch_first_md;
acca_ctrl = latch_acca;
accb_ctrl = latch_accb;
ix_ctrl = latch_ix;
sp_ctrl = latch_sp;
// increment the pc
left_ctrl = acca_left;
right_ctrl = zero_right;
alu_ctrl = alu_nop;
cc_ctrl = latch_cc;
pc_ctrl = inc_pc;
next_state = extended_state;
end
default:
begin
md_ctrl = fetch_first_md;
acca_ctrl = latch_acca;
accb_ctrl = latch_accb;
ix_ctrl = latch_ix;
sp_ctrl = latch_sp;
// idle the pc
left_ctrl = acca_left;
right_ctrl = zero_right;
alu_ctrl = alu_nop;
cc_ctrl = latch_cc;
pc_ctrl = latch_pc;
next_state = fetch_state;
end
endcase
end
immediate16_state:
begin
acca_ctrl = latch_acca;
accb_ctrl = latch_accb;
ix_ctrl = latch_ix;
sp_ctrl = latch_sp;
op_ctrl = latch_op;
iv_ctrl = latch_iv;
nmi_ctrl = latch_nmi;
ea_ctrl = latch_ea;
//ea_ctrl = fetch_next_ea; //steve
// increment pc
left_ctrl = acca_left;
right_ctrl = zero_right;
alu_ctrl = alu_nop;
cc_ctrl = latch_cc;
pc_ctrl = inc_pc;
// fetch next immediate byte
md_ctrl = fetch_next_md;
addr_ctrl = fetch_ad;
dout_ctrl = md_lo_dout;
next_state = fetch_state;
end
//
// ea holds 8 bit index offet
// calculate the effective memory address
// using the alu
//
indexed_state:
begin
acca_ctrl = latch_acca;
accb_ctrl = latch_accb;
ix_ctrl = latch_ix;
sp_ctrl = latch_sp;
pc_ctrl = latch_pc;
iv_ctrl = latch_iv;
op_ctrl = latch_op;
nmi_ctrl = latch_nmi;
// calculate effective address from index reg
// index offest is not sign extended
ea_ctrl = add_ix_ea;
// idle the bus
addr_ctrl = idle_ad;
dout_ctrl = md_lo_dout;
// work out next state
case (op_code[7:4])
4'b0110: // single op indexed
begin
md_ctrl = latch_md;
left_ctrl = acca_left;
right_ctrl = zero_right;
alu_ctrl = alu_nop;
cc_ctrl = latch_cc;
case (op_code[3:0])
4'b1011: // undefined
next_state = fetch_state;
4'b1110: // jmp
next_state = jmp_state;
default:
next_state = read8_state;
endcase
end
4'b1010: // acca indexed
begin
case (op_code[3:0])
4'b0111: // staa
begin
left_ctrl = acca_left;
right_ctrl = zero_right;
alu_ctrl = alu_st8;
cc_ctrl = latch_cc;
md_ctrl = load_md;
next_state = write8_state;
end
4'b1101: // jsr
begin
left_ctrl = acca_left;
right_ctrl = zero_right;
alu_ctrl = alu_nop;
cc_ctrl = latch_cc;
md_ctrl = latch_md;
next_state = jsr_state;
end
4'b1111: // sts
begin
left_ctrl = sp_left;
right_ctrl = zero_right;
alu_ctrl = alu_st16;
cc_ctrl = latch_cc;
md_ctrl = load_md;
next_state = write16_state;
end
default:
begin
left_ctrl = acca_left;
right_ctrl = zero_right;
alu_ctrl = alu_nop;
cc_ctrl = latch_cc;
md_ctrl = latch_md;
next_state = read8_state;
end
endcase
end
4'b1110: // accb indexed
begin
case (op_code[3:0])
4'b0111: // stab direct
begin
left_ctrl = accb_left;
right_ctrl = zero_right;
alu_ctrl = alu_st8;
cc_ctrl = latch_cc;
md_ctrl = load_md;
next_state = write8_state;
end
4'b1101: // std direct
begin
left_ctrl = accd_left;
right_ctrl = zero_right;
alu_ctrl = alu_st16;
cc_ctrl = latch_cc;
md_ctrl = load_md;
next_state = write16_state;
end
4'b1111: // stx direct
begin
left_ctrl = ix_left;
right_ctrl = zero_right;
alu_ctrl = alu_st16;
cc_ctrl = latch_cc;
md_ctrl = load_md;
next_state = write16_state;
end
default:
begin
left_ctrl = acca_left;
right_ctrl = zero_right;
alu_ctrl = alu_nop;
cc_ctrl = latch_cc;
md_ctrl = latch_md;
next_state = read8_state;
end
endcase
end
default:
begin
md_ctrl = latch_md;
left_ctrl = acca_left;
right_ctrl = zero_right;
alu_ctrl = alu_nop;
cc_ctrl = latch_cc;
next_state = fetch_state;
end
endcase
end
//
// ea holds the low byte of the absolute address
// Move ea low byte into ea high byte
// load new ea low byte to for absolute 16 bit address
// advance the program counter
//
extended_state: // fetch ea low byte
begin
acca_ctrl = latch_acca;
accb_ctrl = latch_accb;
ix_ctrl = latch_ix;
sp_ctrl = latch_sp;
iv_ctrl = latch_iv;
op_ctrl = latch_op;
nmi_ctrl = latch_nmi;
// increment pc
pc_ctrl = inc_pc;
// fetch next effective address bytes
ea_ctrl = fetch_next_ea;
addr_ctrl = fetch_ad;
dout_ctrl = md_lo_dout;
// work out the next state
case (op_code[7:4])
4'b0111: // single op extended
begin
md_ctrl = latch_md;
left_ctrl = acca_left;
right_ctrl = zero_right;
alu_ctrl = alu_nop;
cc_ctrl = latch_cc;
case (op_code[3:0])
4'b1011: // undefined
next_state = fetch_state;
4'b1110: // jmp
next_state = jmp_state;
default:
next_state = read8_state;
endcase
end
4'b1011: // acca extended
case (op_code[3:0])
4'b0111: // staa
begin
left_ctrl = acca_left;
right_ctrl = zero_right;
alu_ctrl = alu_st8;
cc_ctrl = latch_cc;
md_ctrl = load_md;
next_state = write8_state;
end
4'b1101: // jsr
begin
left_ctrl = acca_left;
right_ctrl = zero_right;
alu_ctrl = alu_nop;
cc_ctrl = latch_cc;
md_ctrl = latch_md;
next_state = jsr_state;
end
4'b1111: // sts
begin
left_ctrl = sp_left;
right_ctrl = zero_right;
alu_ctrl = alu_st16;
cc_ctrl = latch_cc;
md_ctrl = load_md;
next_state = write16_state;
end
default:
begin
left_ctrl = acca_left;
right_ctrl = zero_right;
alu_ctrl = alu_nop;
cc_ctrl = latch_cc;
md_ctrl = latch_md;
next_state = read8_state;
end
endcase
4'b1111: // accb extended
case (op_code[3:0])
4'b0111: // stab
begin
left_ctrl = accb_left;
right_ctrl = zero_right;
alu_ctrl = alu_st8;
cc_ctrl = latch_cc;
md_ctrl = load_md;
next_state = write8_state;
end
4'b1101: // std
begin
left_ctrl = accd_left;
right_ctrl = zero_right;
alu_ctrl = alu_st16;
cc_ctrl = latch_cc;
md_ctrl = load_md;
next_state = write16_state;
end
4'b1111: // stx
begin
left_ctrl = ix_left;
right_ctrl = zero_right;
alu_ctrl = alu_st16;
cc_ctrl = latch_cc;
md_ctrl = load_md;
next_state = write16_state;
end
default:
begin
left_ctrl = acca_left;
right_ctrl = zero_right;
alu_ctrl = alu_nop;
cc_ctrl = latch_cc;
md_ctrl = latch_md;
next_state = read8_state;
end
endcase
default:
begin
md_ctrl = latch_md;
left_ctrl = acca_left;
right_ctrl = zero_right;
alu_ctrl = alu_nop;
cc_ctrl = latch_cc;
next_state = fetch_state;
end
endcase
end
//
// here if ea holds low byte (direct page)
// can enter here from extended addressing
// read memory location
// note that reads may be 8 or 16 bits
//
read8_state: // read data
begin
acca_ctrl = latch_acca;
accb_ctrl = latch_accb;
ix_ctrl = latch_ix;
sp_ctrl = latch_sp;
pc_ctrl = latch_pc;
iv_ctrl = latch_iv;
op_ctrl = latch_op;
nmi_ctrl = latch_nmi;
//
addr_ctrl = read_ad;
dout_ctrl = md_lo_dout;
case (op_code[7:4])
4'b0110, 4'b0111: // single operand
begin
left_ctrl = acca_left;
right_ctrl = zero_right;
alu_ctrl = alu_nop;
cc_ctrl = latch_cc;
md_ctrl = fetch_first_md;
ea_ctrl = latch_ea;
next_state = execute_state;
end
4'b1001, 4'b1010, 4'b1011: // acca
case (op_code[3:0])
4'b0011, // subd
4'b1110, // lds
4'b1100: // cpx
begin
left_ctrl = acca_left;
right_ctrl = zero_right;
alu_ctrl = alu_nop;
cc_ctrl = latch_cc;
md_ctrl = fetch_first_md;
// increment the effective address in case of 16 bit load
ea_ctrl = inc_ea;
next_state = read16_state;
end
default:
begin
left_ctrl = acca_left;
right_ctrl = zero_right;
alu_ctrl = alu_nop;
cc_ctrl = latch_cc;
md_ctrl = fetch_first_md;
ea_ctrl = latch_ea;
next_state = fetch_state;
end
endcase
4'b1101, 4'b1110, 4'b1111: // accb
case (op_code[3:0])
4'b0011, // addd
4'b1100, // ldd
4'b1110: // ldx
begin
left_ctrl = acca_left;
right_ctrl = zero_right;
alu_ctrl = alu_nop;
cc_ctrl = latch_cc;
md_ctrl = fetch_first_md;
// increment the effective address in case of 16 bit load
ea_ctrl = inc_ea;
next_state = read16_state;
end
default:
begin
left_ctrl = acca_left;
right_ctrl = zero_right;
alu_ctrl = alu_nop;
cc_ctrl = latch_cc;
md_ctrl = fetch_first_md;
ea_ctrl = latch_ea;
next_state = execute_state;
end
endcase
default:
begin
left_ctrl = acca_left;
right_ctrl = zero_right;
alu_ctrl = alu_nop;
cc_ctrl = latch_cc;
md_ctrl = fetch_first_md;
ea_ctrl = latch_ea;
next_state = fetch_state;
end
endcase
end
read16_state: // read second data byte from ea
begin
// default
acca_ctrl = latch_acca;
accb_ctrl = latch_accb;
ix_ctrl = latch_ix;
sp_ctrl = latch_sp;
pc_ctrl = latch_pc;
iv_ctrl = latch_iv;
op_ctrl = latch_op;
nmi_ctrl = latch_nmi;
left_ctrl = acca_left;
right_ctrl = zero_right;
alu_ctrl = alu_nop;
cc_ctrl = latch_cc;
// idle the effective address
ea_ctrl = latch_ea;
// read the low byte of the 16 bit data
md_ctrl = fetch_next_md;
addr_ctrl = read_ad;
dout_ctrl = md_lo_dout;
next_state = fetch_state;
end
//
// 16 bit Write state
// write high byte of ALU output.
// EA hold address of memory to write to
// Advance the effective address in ALU
//
write16_state:
begin
// default
acca_ctrl = latch_acca;
accb_ctrl = latch_accb;
ix_ctrl = latch_ix;
sp_ctrl = latch_sp;
pc_ctrl = latch_pc;
md_ctrl = latch_md;
iv_ctrl = latch_iv;
op_ctrl = latch_op;
nmi_ctrl = latch_nmi;
// increment the effective address
left_ctrl = acca_left;
right_ctrl = zero_right;
alu_ctrl = alu_nop;
cc_ctrl = latch_cc;
ea_ctrl = inc_ea;
// write the ALU hi byte to ea
addr_ctrl = write_ad;
dout_ctrl = md_hi_dout;
next_state = write8_state;
end
//
// 8 bit write
// Write low 8 bits of ALU output
//
write8_state:
begin
// default registers
acca_ctrl = latch_acca;
accb_ctrl = latch_accb;
ix_ctrl = latch_ix;
sp_ctrl = latch_sp;
pc_ctrl = latch_pc;
md_ctrl = latch_md;
iv_ctrl = latch_iv;
op_ctrl = latch_op;
nmi_ctrl = latch_nmi;
ea_ctrl = latch_ea;
// idle the ALU
left_ctrl = acca_left;
right_ctrl = zero_right;
alu_ctrl = alu_nop;
cc_ctrl = latch_cc;
// write ALU low byte output
addr_ctrl = write_ad;
dout_ctrl = md_lo_dout;
next_state = fetch_state;
end
jmp_state:
begin
acca_ctrl = latch_acca;
accb_ctrl = latch_accb;
ix_ctrl = latch_ix;
sp_ctrl = latch_sp;
md_ctrl = latch_md;
iv_ctrl = latch_iv;
op_ctrl = latch_op;
nmi_ctrl = latch_nmi;
ea_ctrl = latch_ea;
// load PC with effective address
left_ctrl = acca_left;
right_ctrl = zero_right;
alu_ctrl = alu_nop;
cc_ctrl = latch_cc;
pc_ctrl = load_ea_pc;
// idle the bus
addr_ctrl = idle_ad;
dout_ctrl = md_lo_dout;
next_state = fetch_state;
end
jsr_state: // JSR
begin
acca_ctrl = latch_acca;
accb_ctrl = latch_accb;
ix_ctrl = latch_ix;
sp_ctrl = latch_sp;
pc_ctrl = latch_pc;
md_ctrl = latch_md;
iv_ctrl = latch_iv;
op_ctrl = latch_op;
nmi_ctrl = latch_nmi;
ea_ctrl = latch_ea;
// decrement sp
left_ctrl = sp_left;
right_ctrl = plus_one_right;
alu_ctrl = alu_sub16;
cc_ctrl = latch_cc;
sp_ctrl = load_sp;
// write pc low
addr_ctrl = push_ad;
dout_ctrl = pc_lo_dout;
next_state = jsr1_state;
end
jsr1_state: // JSR
begin
acca_ctrl = latch_acca;
accb_ctrl = latch_accb;
ix_ctrl = latch_ix;
pc_ctrl = latch_pc;
md_ctrl = latch_md;
iv_ctrl = latch_iv;
op_ctrl = latch_op;
nmi_ctrl = latch_nmi;
ea_ctrl = latch_ea;
// decrement sp
left_ctrl = sp_left;
right_ctrl = plus_one_right;
alu_ctrl = alu_sub16;
cc_ctrl = latch_cc;
sp_ctrl = load_sp;
// write pc hi
addr_ctrl = push_ad;
dout_ctrl = pc_hi_dout;
next_state = jmp_state;
end
branch_state: // Bcc
begin
// default registers
acca_ctrl = latch_acca;
accb_ctrl = latch_accb;
ix_ctrl = latch_ix;
sp_ctrl = latch_sp;
md_ctrl = latch_md;
iv_ctrl = latch_iv;
op_ctrl = latch_op;
nmi_ctrl = latch_nmi;
ea_ctrl = latch_ea;
// calculate signed branch
left_ctrl = acca_left;
right_ctrl = zero_right;
alu_ctrl = alu_nop;
cc_ctrl = latch_cc;
pc_ctrl = add_ea_pc;
// idle the bus
addr_ctrl = idle_ad;
dout_ctrl = md_lo_dout;
next_state = fetch_state;
end
bsr_state: // BSR
begin
// default
acca_ctrl = latch_acca;
accb_ctrl = latch_accb;
ix_ctrl = latch_ix;
pc_ctrl = latch_pc;
md_ctrl = latch_md;
iv_ctrl = latch_iv;
op_ctrl = latch_op;
nmi_ctrl = latch_nmi;
ea_ctrl = latch_ea;
// decrement sp
left_ctrl = sp_left;
right_ctrl = plus_one_right;
alu_ctrl = alu_sub16;
cc_ctrl = latch_cc;
sp_ctrl = load_sp;
// write pc low
addr_ctrl = push_ad;
dout_ctrl = pc_lo_dout;
next_state = bsr1_state;
end
bsr1_state: // BSR
begin
// default registers
acca_ctrl = latch_acca;
accb_ctrl = latch_accb;
ix_ctrl = latch_ix;
pc_ctrl = latch_pc;
md_ctrl = latch_md;
iv_ctrl = latch_iv;
op_ctrl = latch_op;
nmi_ctrl = latch_nmi;
ea_ctrl = latch_ea;
// decrement sp
left_ctrl = sp_left;
right_ctrl = plus_one_right;
alu_ctrl = alu_sub16;
cc_ctrl = latch_cc;
sp_ctrl = load_sp;
// write pc hi
addr_ctrl = push_ad;
dout_ctrl = pc_hi_dout;
next_state = branch_state;
end
rts_hi_state: // RTS
begin
// default
acca_ctrl = latch_acca;
accb_ctrl = latch_accb;
ix_ctrl = latch_ix;
pc_ctrl = latch_pc;
md_ctrl = latch_md;
iv_ctrl = latch_iv;
op_ctrl = latch_op;
nmi_ctrl = latch_nmi;
ea_ctrl = latch_ea;
// increment the sp
left_ctrl = sp_left;
right_ctrl = plus_one_right;
alu_ctrl = alu_add16;
cc_ctrl = latch_cc;
sp_ctrl = load_sp;
// read pc hi
pc_ctrl = pull_hi_pc;
addr_ctrl = pull_ad;
dout_ctrl = pc_hi_dout;
next_state = rts_lo_state;
end
rts_lo_state: // RTS1
begin
// default
acca_ctrl = latch_acca;
accb_ctrl = latch_accb;
ix_ctrl = latch_ix;
sp_ctrl = latch_sp;
md_ctrl = latch_md;
iv_ctrl = latch_iv;
op_ctrl = latch_op;
nmi_ctrl = latch_nmi;
ea_ctrl = latch_ea;
// idle the ALU
left_ctrl = acca_left;
right_ctrl = zero_right;
alu_ctrl = alu_nop;
cc_ctrl = latch_cc;
// read pc low
pc_ctrl = pull_lo_pc;
addr_ctrl = pull_ad;
dout_ctrl = pc_lo_dout;
next_state = fetch_state;
end
mul_state:
begin
// default
acca_ctrl = latch_acca;
accb_ctrl = latch_accb;
ix_ctrl = latch_ix;
sp_ctrl = latch_sp;
pc_ctrl = latch_pc;
iv_ctrl = latch_iv;
op_ctrl = latch_op;
nmi_ctrl = latch_nmi;
ea_ctrl = latch_ea;
// move acca to md
left_ctrl = acca_left;
right_ctrl = zero_right;
alu_ctrl = alu_st16;
cc_ctrl = latch_cc;
md_ctrl = load_md;
// idle bus
addr_ctrl = idle_ad;
dout_ctrl = md_lo_dout;
next_state = mulea_state;
end
mulea_state:
begin
// default
acca_ctrl = latch_acca;
accb_ctrl = latch_accb;
ix_ctrl = latch_ix;
sp_ctrl = latch_sp;
pc_ctrl = latch_pc;
iv_ctrl = latch_iv;
op_ctrl = latch_op;
nmi_ctrl = latch_nmi;
md_ctrl = latch_md;
// idle ALU
left_ctrl = acca_left;
right_ctrl = zero_right;
alu_ctrl = alu_nop;
cc_ctrl = latch_cc;
// move accb to ea
ea_ctrl = load_accb_ea;
// idle bus
addr_ctrl = idle_ad;
dout_ctrl = md_lo_dout;
next_state = muld_state;
end
muld_state:
begin
// default
ix_ctrl = latch_ix;
sp_ctrl = latch_sp;
pc_ctrl = latch_pc;
iv_ctrl = latch_iv;
op_ctrl = latch_op;
nmi_ctrl = latch_nmi;
ea_ctrl = latch_ea;
md_ctrl = latch_md;
// clear accd
left_ctrl = acca_left;
right_ctrl = zero_right;
alu_ctrl = alu_ld8;
cc_ctrl = latch_cc;
acca_ctrl = load_hi_acca;
accb_ctrl = load_accb;
// idle bus
addr_ctrl = idle_ad;
dout_ctrl = md_lo_dout;
next_state = mul0_state;
end
mul0_state:
begin
// default
ix_ctrl = latch_ix;
sp_ctrl = latch_sp;
pc_ctrl = latch_pc;
iv_ctrl = latch_iv;
op_ctrl = latch_op;
nmi_ctrl = latch_nmi;
ea_ctrl = latch_ea;
// if bit 0 of ea set, add accd to md
left_ctrl = accd_left;
right_ctrl = md_right;
alu_ctrl = alu_add16;
if (ea[0] == 1'b1)
begin
cc_ctrl = load_cc;
acca_ctrl = load_hi_acca;
accb_ctrl = load_accb;
end
else
begin
cc_ctrl = latch_cc;
acca_ctrl = latch_acca;
accb_ctrl = latch_accb;
end
md_ctrl = shiftl_md;
// idle bus
addr_ctrl = idle_ad;
dout_ctrl = md_lo_dout;
next_state = mul1_state;
end
mul1_state:
begin
// default
ix_ctrl = latch_ix;
sp_ctrl = latch_sp;
pc_ctrl = latch_pc;
iv_ctrl = latch_iv;
op_ctrl = latch_op;
nmi_ctrl = latch_nmi;
ea_ctrl = latch_ea;
// if bit 1 of ea set, add accd to md
left_ctrl = accd_left;
right_ctrl = md_right;
alu_ctrl = alu_add16;
if (ea[1] == 1'b1)
begin
cc_ctrl = load_cc;
acca_ctrl = load_hi_acca;
accb_ctrl = load_accb;
end
else
begin
cc_ctrl = latch_cc;
acca_ctrl = latch_acca;
accb_ctrl = latch_accb;
end
md_ctrl = shiftl_md;
// idle bus
addr_ctrl = idle_ad;
dout_ctrl = md_lo_dout;
next_state = mul2_state;
end
mul2_state:
begin
// default
ix_ctrl = latch_ix;
sp_ctrl = latch_sp;
pc_ctrl = latch_pc;
iv_ctrl = latch_iv;
op_ctrl = latch_op;
nmi_ctrl = latch_nmi;
ea_ctrl = latch_ea;
// if bit 2 of ea set, add accd to md
left_ctrl = accd_left;
right_ctrl = md_right;
alu_ctrl = alu_add16;
if (ea[2] == 1'b1)
begin
cc_ctrl = load_cc;
acca_ctrl = load_hi_acca;
accb_ctrl = load_accb;
end
else
begin
cc_ctrl = latch_cc;
acca_ctrl = latch_acca;
accb_ctrl = latch_accb;
end
md_ctrl = shiftl_md;
// idle bus
addr_ctrl = idle_ad;
dout_ctrl = md_lo_dout;
next_state = mul3_state;
end
mul3_state:
begin
// default
ix_ctrl = latch_ix;
sp_ctrl = latch_sp;
pc_ctrl = latch_pc;
iv_ctrl = latch_iv;
op_ctrl = latch_op;
nmi_ctrl = latch_nmi;
ea_ctrl = latch_ea;
// if bit 3 of ea set, add accd to md
left_ctrl = accd_left;
right_ctrl = md_right;
alu_ctrl = alu_add16;
if (ea[3] == 1'b1)
begin
cc_ctrl = load_cc;
acca_ctrl = load_hi_acca;
accb_ctrl = load_accb;
end
else
begin
cc_ctrl = latch_cc;
acca_ctrl = latch_acca;
accb_ctrl = latch_accb;
end
md_ctrl = shiftl_md;
// idle bus
addr_ctrl = idle_ad;
dout_ctrl = md_lo_dout;
next_state = mul4_state;
end
mul4_state:
begin
// default
ix_ctrl = latch_ix;
sp_ctrl = latch_sp;
pc_ctrl = latch_pc;
iv_ctrl = latch_iv;
op_ctrl = latch_op;
nmi_ctrl = latch_nmi;
ea_ctrl = latch_ea;
// if bit 4 of ea set, add accd to md
left_ctrl = accd_left;
right_ctrl = md_right;
alu_ctrl = alu_add16;
if (ea[4] == 1'b1)
begin
cc_ctrl = load_cc;
acca_ctrl = load_hi_acca;
accb_ctrl = load_accb;
end
else
begin
cc_ctrl = latch_cc;
acca_ctrl = latch_acca;
accb_ctrl = latch_accb;
end
md_ctrl = shiftl_md;
// idle bus
addr_ctrl = idle_ad;
dout_ctrl = md_lo_dout;
next_state = mul5_state;
end
mul5_state:
begin
// default
ix_ctrl = latch_ix;
sp_ctrl = latch_sp;
pc_ctrl = latch_pc;
iv_ctrl = latch_iv;
op_ctrl = latch_op;
nmi_ctrl = latch_nmi;
ea_ctrl = latch_ea;
// if bit 5 of ea set, add accd to md
left_ctrl = accd_left;
right_ctrl = md_right;
alu_ctrl = alu_add16;
if (ea[5] == 1'b1)
begin
cc_ctrl = load_cc;
acca_ctrl = load_hi_acca;
accb_ctrl = load_accb;
end
else
begin
cc_ctrl = latch_cc;
acca_ctrl = latch_acca;
accb_ctrl = latch_accb;
end
md_ctrl = shiftl_md;
// idle bus
addr_ctrl = idle_ad;
dout_ctrl = md_lo_dout;
next_state = mul6_state;
end
mul6_state:
begin
// default
ix_ctrl = latch_ix;
sp_ctrl = latch_sp;
pc_ctrl = latch_pc;
iv_ctrl = latch_iv;
op_ctrl = latch_op;
nmi_ctrl = latch_nmi;
ea_ctrl = latch_ea;
// if bit 6 of ea set, add accd to md
left_ctrl = accd_left;
right_ctrl = md_right;
alu_ctrl = alu_add16;
if (ea[6] == 1'b1)
begin
cc_ctrl = load_cc;
acca_ctrl = load_hi_acca;
accb_ctrl = load_accb;
end
else
begin
cc_ctrl = latch_cc;
acca_ctrl = latch_acca;
accb_ctrl = latch_accb;
end
md_ctrl = shiftl_md;
// idle bus
addr_ctrl = idle_ad;
dout_ctrl = md_lo_dout;
next_state = mul7_state;
end
mul7_state:
begin
// default
ix_ctrl = latch_ix;
sp_ctrl = latch_sp;
pc_ctrl = latch_pc;
iv_ctrl = latch_iv;
op_ctrl = latch_op;
nmi_ctrl = latch_nmi;
ea_ctrl = latch_ea;
// if bit 7 of ea set, add accd to md
left_ctrl = accd_left;
right_ctrl = md_right;
alu_ctrl = alu_add16;
if (ea[7] == 1'b1)
begin
cc_ctrl = load_cc;
acca_ctrl = load_hi_acca;
accb_ctrl = load_accb;
end
else
begin
cc_ctrl = latch_cc;
acca_ctrl = latch_acca;
accb_ctrl = latch_accb;
end
md_ctrl = shiftl_md;
// idle bus
addr_ctrl = idle_ad;
dout_ctrl = md_lo_dout;
next_state = fetch_state;
end
execute_state: // execute single operand instruction
begin
// default
op_ctrl = latch_op;
nmi_ctrl = latch_nmi;
case (op_code[7:4])
4'b0110, // indexed single op
4'b0111: // extended single op
begin
acca_ctrl = latch_acca;
accb_ctrl = latch_accb;
ix_ctrl = latch_ix;
sp_ctrl = latch_sp;
pc_ctrl = latch_pc;
iv_ctrl = latch_iv;
ea_ctrl = latch_ea;
// idle the bus
addr_ctrl = idle_ad;
dout_ctrl = md_lo_dout;
case (op_code[3:0])
4'b0000: // neg
begin
left_ctrl = md_left;
right_ctrl = zero_right;
alu_ctrl = alu_neg;
cc_ctrl = load_cc;
md_ctrl = load_md;
next_state = write8_state;
end
4'b0011: // com
begin
left_ctrl = md_left;
right_ctrl = zero_right;
alu_ctrl = alu_com;
cc_ctrl = load_cc;
md_ctrl = load_md;
next_state = write8_state;
end
4'b0100: // lsr
begin
left_ctrl = md_left;
right_ctrl = zero_right;
alu_ctrl = alu_lsr8;
cc_ctrl = load_cc;
md_ctrl = load_md;
next_state = write8_state;
end
4'b0110: // ror
begin
left_ctrl = md_left;
right_ctrl = zero_right;
alu_ctrl = alu_ror8;
cc_ctrl = load_cc;
md_ctrl = load_md;
next_state = write8_state;
end
4'b0111: // asr
begin
left_ctrl = md_left;
right_ctrl = zero_right;
alu_ctrl = alu_asr8;
cc_ctrl = load_cc;
md_ctrl = load_md;
next_state = write8_state;
end
4'b1000: // asl
begin
left_ctrl = md_left;
right_ctrl = zero_right;
alu_ctrl = alu_asl8;
cc_ctrl = load_cc;
md_ctrl = load_md;
next_state = write8_state;
end
4'b1001: // rol
begin
left_ctrl = md_left;
right_ctrl = zero_right;
alu_ctrl = alu_rol8;
cc_ctrl = load_cc;
md_ctrl = load_md;
next_state = write8_state;
end
4'b1010: // dec
begin
left_ctrl = md_left;
right_ctrl = plus_one_right;
alu_ctrl = alu_dec;
cc_ctrl = load_cc;
md_ctrl = load_md;
next_state = write8_state;
end
4'b1011: // undefined
begin
left_ctrl = md_left;
right_ctrl = zero_right;
alu_ctrl = alu_nop;
cc_ctrl = latch_cc;
md_ctrl = latch_md;
next_state = fetch_state;
end
4'b1100: // inc
begin
left_ctrl = md_left;
right_ctrl = plus_one_right;
alu_ctrl = alu_inc;
cc_ctrl = load_cc;
md_ctrl = load_md;
next_state = write8_state;
end
4'b1101: // tst
begin
left_ctrl = md_left;
right_ctrl = zero_right;
alu_ctrl = alu_st8;
cc_ctrl = load_cc;
md_ctrl = latch_md;
next_state = fetch_state;
end
4'b1110: // jmp
begin
left_ctrl = md_left;
right_ctrl = zero_right;
alu_ctrl = alu_nop;
cc_ctrl = latch_cc;
md_ctrl = latch_md;
next_state = fetch_state;
end
4'b1111: // clr
begin
left_ctrl = md_left;
right_ctrl = zero_right;
alu_ctrl = alu_clr;
cc_ctrl = load_cc;
md_ctrl = load_md;
next_state = write8_state;
end
default:
begin
left_ctrl = md_left;
right_ctrl = zero_right;
alu_ctrl = alu_nop;
cc_ctrl = latch_cc;
md_ctrl = latch_md;
next_state = fetch_state;
end
endcase
end
default:
begin
left_ctrl = accd_left;
right_ctrl = md_right;
alu_ctrl = alu_nop;
cc_ctrl = latch_cc;
acca_ctrl = latch_acca;
accb_ctrl = latch_accb;
ix_ctrl = latch_ix;
sp_ctrl = latch_sp;
pc_ctrl = latch_pc;
md_ctrl = latch_md;
iv_ctrl = latch_iv;
ea_ctrl = latch_ea;
// idle the bus
addr_ctrl = idle_ad;
dout_ctrl = md_lo_dout;
next_state = fetch_state;
end
endcase
end
psha_state:
begin
// default registers
acca_ctrl = latch_acca;
accb_ctrl = latch_accb;
ix_ctrl = latch_ix;
pc_ctrl = latch_pc;
md_ctrl = latch_md;
iv_ctrl = latch_iv;
op_ctrl = latch_op;
nmi_ctrl = latch_nmi;
ea_ctrl = latch_ea;
// decrement sp
left_ctrl = sp_left;
right_ctrl = plus_one_right;
alu_ctrl = alu_sub16;
cc_ctrl = latch_cc;
sp_ctrl = load_sp;
// write acca
addr_ctrl = push_ad;
dout_ctrl = acca_dout;
next_state = fetch_state;
end
pula_state:
begin
// default registers
acca_ctrl = latch_acca;
accb_ctrl = latch_accb;
ix_ctrl = latch_ix;
pc_ctrl = latch_pc;
md_ctrl = latch_md;
iv_ctrl = latch_iv;
op_ctrl = latch_op;
nmi_ctrl = latch_nmi;
ea_ctrl = latch_ea;
// idle sp
left_ctrl = sp_left;
right_ctrl = zero_right;
alu_ctrl = alu_nop;
cc_ctrl = latch_cc;
sp_ctrl = latch_sp;
// read acca
acca_ctrl = pull_acca;
addr_ctrl = pull_ad;
dout_ctrl = acca_dout;
next_state = fetch_state;
end
pshb_state:
begin
// default registers
acca_ctrl = latch_acca;
accb_ctrl = latch_accb;
ix_ctrl = latch_ix;
pc_ctrl = latch_pc;
md_ctrl = latch_md;
iv_ctrl = latch_iv;
op_ctrl = latch_op;
nmi_ctrl = latch_nmi;
ea_ctrl = latch_ea;
// decrement sp
left_ctrl = sp_left;
right_ctrl = plus_one_right;
alu_ctrl = alu_sub16;
cc_ctrl = latch_cc;
sp_ctrl = load_sp;
// write accb
addr_ctrl = push_ad;
dout_ctrl = accb_dout;
next_state = fetch_state;
end
pulb_state:
begin
// default
acca_ctrl = latch_acca;
accb_ctrl = latch_accb;
ix_ctrl = latch_ix;
pc_ctrl = latch_pc;
md_ctrl = latch_md;
iv_ctrl = latch_iv;
op_ctrl = latch_op;
nmi_ctrl = latch_nmi;
ea_ctrl = latch_ea;
// idle sp
left_ctrl = sp_left;
right_ctrl = zero_right;
alu_ctrl = alu_nop;
cc_ctrl = latch_cc;
sp_ctrl = latch_sp;
// read accb
accb_ctrl = pull_accb;
addr_ctrl = pull_ad;
dout_ctrl = accb_dout;
next_state = fetch_state;
end
pshx_lo_state:
begin
// default
acca_ctrl = latch_acca;
accb_ctrl = latch_accb;
ix_ctrl = latch_ix;
sp_ctrl = latch_sp;
pc_ctrl = latch_pc;
md_ctrl = latch_md;
iv_ctrl = latch_iv;
op_ctrl = latch_op;
nmi_ctrl = latch_nmi;
ea_ctrl = latch_ea;
// decrement sp
left_ctrl = sp_left;
right_ctrl = plus_one_right;
alu_ctrl = alu_sub16;
cc_ctrl = latch_cc;
sp_ctrl = load_sp;
// write ix low
addr_ctrl = push_ad;
dout_ctrl = ix_lo_dout;
next_state = pshx_hi_state;
end
pshx_hi_state:
begin
// default registers
acca_ctrl = latch_acca;
accb_ctrl = latch_accb;
ix_ctrl = latch_ix;
pc_ctrl = latch_pc;
md_ctrl = latch_md;
iv_ctrl = latch_iv;
op_ctrl = latch_op;
nmi_ctrl = latch_nmi;
ea_ctrl = latch_ea;
// decrement sp
left_ctrl = sp_left;
right_ctrl = plus_one_right;
alu_ctrl = alu_sub16;
cc_ctrl = latch_cc;
sp_ctrl = load_sp;
// write ix hi
addr_ctrl = push_ad;
dout_ctrl = ix_hi_dout;
next_state = fetch_state;
end
pulx_hi_state:
begin
// default
acca_ctrl = latch_acca;
accb_ctrl = latch_accb;
pc_ctrl = latch_pc;
md_ctrl = latch_md;
iv_ctrl = latch_iv;
op_ctrl = latch_op;
nmi_ctrl = latch_nmi;
ea_ctrl = latch_ea;
// increment sp
left_ctrl = sp_left;
right_ctrl = plus_one_right;
alu_ctrl = alu_add16;
cc_ctrl = latch_cc;
sp_ctrl = load_sp;
// pull ix hi
ix_ctrl = pull_hi_ix;
addr_ctrl = pull_ad;
dout_ctrl = ix_hi_dout;
next_state = pulx_lo_state;
end
pulx_lo_state:
begin
// default
acca_ctrl = latch_acca;
accb_ctrl = latch_accb;
pc_ctrl = latch_pc;
md_ctrl = latch_md;
iv_ctrl = latch_iv;
op_ctrl = latch_op;
nmi_ctrl = latch_nmi;
ea_ctrl = latch_ea;
// idle sp
left_ctrl = sp_left;
right_ctrl = zero_right;
alu_ctrl = alu_nop;
cc_ctrl = latch_cc;
sp_ctrl = latch_sp;
// read ix low
ix_ctrl = pull_lo_ix;
addr_ctrl = pull_ad;
dout_ctrl = ix_lo_dout;
next_state = fetch_state;
end
//
// return from interrupt
// enter here from bogus interrupts
//
rti_state:
begin
// default registers
acca_ctrl = latch_acca;
accb_ctrl = latch_accb;
ix_ctrl = latch_ix;
pc_ctrl = latch_pc;
md_ctrl = latch_md;
iv_ctrl = latch_iv;
op_ctrl = latch_op;
nmi_ctrl = latch_nmi;
ea_ctrl = latch_ea;
// increment sp
left_ctrl = sp_left;
right_ctrl = plus_one_right;
alu_ctrl = alu_add16;
sp_ctrl = load_sp;
// idle address bus
cc_ctrl = latch_cc;
addr_ctrl = idle_ad;
dout_ctrl = cc_dout;
next_state = rti_cc_state;
end
rti_cc_state:
begin
// default registers
acca_ctrl = latch_acca;
accb_ctrl = latch_accb;
ix_ctrl = latch_ix;
pc_ctrl = latch_pc;
md_ctrl = latch_md;
iv_ctrl = latch_iv;
op_ctrl = latch_op;
nmi_ctrl = latch_nmi;
ea_ctrl = latch_ea;
// increment sp
left_ctrl = sp_left;
right_ctrl = plus_one_right;
alu_ctrl = alu_add16;
sp_ctrl = load_sp;
// read cc
cc_ctrl = pull_cc;
addr_ctrl = pull_ad;
dout_ctrl = cc_dout;
next_state = rti_accb_state;
end
rti_accb_state:
begin
// default registers
acca_ctrl = latch_acca;
ix_ctrl = latch_ix;
pc_ctrl = latch_pc;
md_ctrl = latch_md;
iv_ctrl = latch_iv;
op_ctrl = latch_op;
nmi_ctrl = latch_nmi;
ea_ctrl = latch_ea;
// increment sp
left_ctrl = sp_left;
right_ctrl = plus_one_right;
alu_ctrl = alu_add16;
cc_ctrl = latch_cc;
sp_ctrl = load_sp;
// read accb
accb_ctrl = pull_accb;
addr_ctrl = pull_ad;
dout_ctrl = accb_dout;
next_state = rti_acca_state;
end
rti_acca_state:
begin
// default registers
accb_ctrl = latch_accb;
ix_ctrl = latch_ix;
pc_ctrl = latch_pc;
md_ctrl = latch_md;
iv_ctrl = latch_iv;
op_ctrl = latch_op;
nmi_ctrl = latch_nmi;
ea_ctrl = latch_ea;
// increment sp
left_ctrl = sp_left;
right_ctrl = plus_one_right;
alu_ctrl = alu_add16;
cc_ctrl = latch_cc;
sp_ctrl = load_sp;
// read acca
acca_ctrl = pull_acca;
addr_ctrl = pull_ad;
dout_ctrl = acca_dout;
next_state = rti_ixh_state;
end
rti_ixh_state:
begin
// default
acca_ctrl = latch_acca;
accb_ctrl = latch_accb;
pc_ctrl = latch_pc;
md_ctrl = latch_md;
iv_ctrl = latch_iv;
op_ctrl = latch_op;
nmi_ctrl = latch_nmi;
ea_ctrl = latch_ea;
// increment sp
left_ctrl = sp_left;
right_ctrl = plus_one_right;
alu_ctrl = alu_add16;
cc_ctrl = latch_cc;
sp_ctrl = load_sp;
// read ix hi
ix_ctrl = pull_hi_ix;
addr_ctrl = pull_ad;
dout_ctrl = ix_hi_dout;
next_state = rti_ixl_state;
end
rti_ixl_state:
begin
// default
acca_ctrl = latch_acca;
accb_ctrl = latch_accb;
pc_ctrl = latch_pc;
md_ctrl = latch_md;
iv_ctrl = latch_iv;
op_ctrl = latch_op;
nmi_ctrl = latch_nmi;
ea_ctrl = latch_ea;
// increment sp
left_ctrl = sp_left;
right_ctrl = plus_one_right;
alu_ctrl = alu_add16;
cc_ctrl = latch_cc;
sp_ctrl = load_sp;
// read ix low
ix_ctrl = pull_lo_ix;
addr_ctrl = pull_ad;
dout_ctrl = ix_lo_dout;
next_state = rti_pch_state;
end
rti_pch_state:
begin
// default
acca_ctrl = latch_acca;
accb_ctrl = latch_accb;
ix_ctrl = latch_ix;
pc_ctrl = latch_pc;
md_ctrl = latch_md;
iv_ctrl = latch_iv;
op_ctrl = latch_op;
nmi_ctrl = latch_nmi;
ea_ctrl = latch_ea;
// increment sp
left_ctrl = sp_left;
right_ctrl = plus_one_right;
alu_ctrl = alu_add16;
cc_ctrl = latch_cc;
sp_ctrl = load_sp;
// pull pc hi
pc_ctrl = pull_hi_pc;
addr_ctrl = pull_ad;
dout_ctrl = pc_hi_dout;
next_state = rti_pcl_state;
end
rti_pcl_state:
begin
// default
acca_ctrl = latch_acca;
accb_ctrl = latch_accb;
ix_ctrl = latch_ix;
md_ctrl = latch_md;
iv_ctrl = latch_iv;
op_ctrl = latch_op;
nmi_ctrl = latch_nmi;
ea_ctrl = latch_ea;
// idle sp
left_ctrl = sp_left;
right_ctrl = zero_right;
alu_ctrl = alu_nop;
cc_ctrl = latch_cc;
sp_ctrl = latch_sp;
// pull pc low
pc_ctrl = pull_lo_pc;
addr_ctrl = pull_ad;
dout_ctrl = pc_lo_dout;
next_state = fetch_state;
end
//
// here on interrupt
// iv register hold interrupt type
//
int_pcl_state:
begin
// default
acca_ctrl = latch_acca;
accb_ctrl = latch_accb;
ix_ctrl = latch_ix;
pc_ctrl = latch_pc;
md_ctrl = latch_md;
iv_ctrl = latch_iv;
op_ctrl = latch_op;
nmi_ctrl = latch_nmi;
ea_ctrl = latch_ea;
// decrement sp
left_ctrl = sp_left;
right_ctrl = plus_one_right;
alu_ctrl = alu_sub16;
cc_ctrl = latch_cc;
sp_ctrl = load_sp;
// write pc low
addr_ctrl = push_ad;
dout_ctrl = pc_lo_dout;
next_state = int_pch_state;
end
int_pch_state:
begin
// default
acca_ctrl = latch_acca;
accb_ctrl = latch_accb;
ix_ctrl = latch_ix;
pc_ctrl = latch_pc;
md_ctrl = latch_md;
iv_ctrl = latch_iv;
op_ctrl = latch_op;
nmi_ctrl = latch_nmi;
ea_ctrl = latch_ea;
// decrement sp
left_ctrl = sp_left;
right_ctrl = plus_one_right;
alu_ctrl = alu_sub16;
cc_ctrl = latch_cc;
sp_ctrl = load_sp;
// write pc hi
addr_ctrl = push_ad;
dout_ctrl = pc_hi_dout;
next_state = int_ixl_state;
end
int_ixl_state:
begin
// default
acca_ctrl = latch_acca;
accb_ctrl = latch_accb;
ix_ctrl = latch_ix;
pc_ctrl = latch_pc;
md_ctrl = latch_md;
iv_ctrl = latch_iv;
op_ctrl = latch_op;
nmi_ctrl = latch_nmi;
ea_ctrl = latch_ea;
// decrement sp
left_ctrl = sp_left;
right_ctrl = plus_one_right;
alu_ctrl = alu_sub16;
cc_ctrl = latch_cc;
sp_ctrl = load_sp;
// write ix low
addr_ctrl = push_ad;
dout_ctrl = ix_lo_dout;
next_state = int_ixh_state;
end
int_ixh_state:
begin
// default
acca_ctrl = latch_acca;
accb_ctrl = latch_accb;
ix_ctrl = latch_ix;
pc_ctrl = latch_pc;
md_ctrl = latch_md;
iv_ctrl = latch_iv;
op_ctrl = latch_op;
nmi_ctrl = latch_nmi;
ea_ctrl = latch_ea;
// decrement sp
left_ctrl = sp_left;
right_ctrl = plus_one_right;
alu_ctrl = alu_sub16;
cc_ctrl = latch_cc;
sp_ctrl = load_sp;
// write ix hi
addr_ctrl = push_ad;
dout_ctrl = ix_hi_dout;
next_state = int_acca_state;
end
int_acca_state:
begin
// default
acca_ctrl = latch_acca;
accb_ctrl = latch_accb;
ix_ctrl = latch_ix;
pc_ctrl = latch_pc;
md_ctrl = latch_md;
iv_ctrl = latch_iv;
op_ctrl = latch_op;
nmi_ctrl = latch_nmi;
ea_ctrl = latch_ea;
// decrement sp
left_ctrl = sp_left;
right_ctrl = plus_one_right;
alu_ctrl = alu_sub16;
cc_ctrl = latch_cc;
sp_ctrl = load_sp;
// write acca
addr_ctrl = push_ad;
dout_ctrl = acca_dout;
next_state = int_accb_state;
end
int_accb_state:
begin
// default
acca_ctrl = latch_acca;
accb_ctrl = latch_accb;
ix_ctrl = latch_ix;
pc_ctrl = latch_pc;
md_ctrl = latch_md;
iv_ctrl = latch_iv;
op_ctrl = latch_op;
nmi_ctrl = latch_nmi;
ea_ctrl = latch_ea;
// decrement sp
left_ctrl = sp_left;
right_ctrl = plus_one_right;
alu_ctrl = alu_sub16;
cc_ctrl = latch_cc;
sp_ctrl = load_sp;
// write accb
addr_ctrl = push_ad;
dout_ctrl = accb_dout;
next_state = int_cc_state;
end
int_cc_state:
begin
// default
acca_ctrl = latch_acca;
accb_ctrl = latch_accb;
ix_ctrl = latch_ix;
pc_ctrl = latch_pc;
md_ctrl = latch_md;
op_ctrl = latch_op;
nmi_ctrl = latch_nmi;
ea_ctrl = latch_ea;
// decrement sp
left_ctrl = sp_left;
right_ctrl = plus_one_right;
alu_ctrl = alu_sub16;
cc_ctrl = latch_cc;
sp_ctrl = load_sp;
// write cc
addr_ctrl = push_ad;
dout_ctrl = cc_dout;
nmi_ctrl = latch_nmi;
//
// nmi is edge triggered
// nmi_req is cleared when nmi goes low.
//
if (nmi_req == 1'b1)
begin
iv_ctrl = nmi_iv;
next_state = vect_hi_state;
end
else
begin
//
// IRQ is level sensitive
//
if ((irq == 1'b1) & (cc[IBIT] == 1'b0))
begin
iv_ctrl = irq_iv;
next_state = int_mask_state;
end
else if ((irq_icf == 1'b1) & (cc[IBIT] == 1'b0))
begin
iv_ctrl = icf_iv;
next_state = int_mask_state;
end
else if ((irq_ocf == 1'b1) & (cc[IBIT] == 1'b0))
begin
iv_ctrl = ocf_iv;
next_state = int_mask_state;
end
else if ((irq_tof == 1'b1) & (cc[IBIT] == 1'b0))
begin
iv_ctrl = tof_iv;
next_state = int_mask_state;
end
else if ((irq_sci == 1'b1) & (cc[IBIT] == 1'b0))
begin
iv_ctrl = sci_iv;
next_state = int_mask_state;
end
else
case (op_code)
8'b00111110: // WAI (wait for interrupt)
begin
iv_ctrl = latch_iv;
next_state = int_wai_state;
end
8'b00111111: // SWI (Software interrupt)
begin
iv_ctrl = swi_iv;
next_state = vect_hi_state;
end
default: // bogus interrupt (return)
begin
iv_ctrl = latch_iv;
next_state = rti_state;
end
endcase
end
end
int_wai_state:
begin
// default
acca_ctrl = latch_acca;
accb_ctrl = latch_accb;
ix_ctrl = latch_ix;
pc_ctrl = latch_pc;
md_ctrl = latch_md;
op_ctrl = latch_op;
ea_ctrl = latch_ea;
// enable interrupts
left_ctrl = sp_left;
right_ctrl = plus_one_right;
alu_ctrl = alu_cli;
cc_ctrl = load_cc;
sp_ctrl = latch_sp;
// idle bus
addr_ctrl = idle_ad;
dout_ctrl = cc_dout;
if ((nmi_req == 1'b1) & (nmi_ack==1'b0))
begin
iv_ctrl = nmi_iv;
nmi_ctrl = set_nmi;
next_state = vect_hi_state;
end
else
begin
//
// nmi request is not cleared until nmi input goes low
//
if ((nmi_req == 1'b0) & (nmi_ack==1'b1))
nmi_ctrl = reset_nmi;
else
nmi_ctrl = latch_nmi;
//
// IRQ is level sensitive
//
if ((irq == 1'b1) & (cc[IBIT] == 1'b0))
begin
iv_ctrl = irq_iv;
next_state = int_mask_state;
end
else if ((irq_icf == 1'b1) & (cc[IBIT] == 1'b0))
begin
iv_ctrl = icf_iv;
next_state = int_mask_state;
end
else if ((irq_ocf == 1'b1) & (cc[IBIT] == 1'b0))
begin
iv_ctrl = ocf_iv;
next_state = int_mask_state;
end
else if ((irq_tof == 1'b1) & (cc[IBIT] == 1'b0))
begin
iv_ctrl = tof_iv;
next_state = int_mask_state;
end
else if ((irq_sci == 1'b1) & (cc[IBIT] == 1'b0))
begin
iv_ctrl = sci_iv;
next_state = int_mask_state;
end
else
begin
iv_ctrl = latch_iv;
next_state = int_wai_state;
end
end
end
int_mask_state:
begin
// default
acca_ctrl = latch_acca;
accb_ctrl = latch_accb;
ix_ctrl = latch_ix;
pc_ctrl = latch_pc;
md_ctrl = latch_md;
iv_ctrl = latch_iv;
op_ctrl = latch_op;
nmi_ctrl = latch_nmi;
ea_ctrl = latch_ea;
// Mask IRQ
left_ctrl = sp_left;
right_ctrl = zero_right;
alu_ctrl = alu_sei;
cc_ctrl = load_cc;
sp_ctrl = latch_sp;
// idle bus cycle
addr_ctrl = idle_ad;
dout_ctrl = md_lo_dout;
next_state = vect_hi_state;
end
halt_state: // halt CPU.
begin
// default
acca_ctrl = latch_acca;
accb_ctrl = latch_accb;
ix_ctrl = latch_ix;
sp_ctrl = latch_sp;
pc_ctrl = latch_pc;
md_ctrl = latch_md;
iv_ctrl = latch_iv;
op_ctrl = latch_op;
nmi_ctrl = latch_nmi;
ea_ctrl = latch_ea;
// do nothing in ALU
left_ctrl = acca_left;
right_ctrl = zero_right;
alu_ctrl = alu_nop;
cc_ctrl = latch_cc;
// idle bus cycle
addr_ctrl = idle_ad;
dout_ctrl = md_lo_dout;
if (halt == 1'b1)
next_state = halt_state;
else
next_state = fetch_state;
end
default: // error state halt on undefine states
begin
// default
acca_ctrl = latch_acca;
accb_ctrl = latch_accb;
ix_ctrl = latch_ix;
sp_ctrl = latch_sp;
pc_ctrl = latch_pc;
md_ctrl = latch_md;
iv_ctrl = latch_iv;
op_ctrl = latch_op;
nmi_ctrl = latch_nmi;
ea_ctrl = latch_ea;
// do nothing in ALU
left_ctrl = acca_left;
right_ctrl = zero_right;
alu_ctrl = alu_nop;
cc_ctrl = latch_cc;
// idle bus cycle
addr_ctrl = idle_ad;
dout_ctrl = md_lo_dout;
next_state = error_state;
end
endcase
end
////////////////////////////////
//
// state machine
//
////////////////////////////////
always_ff @(posedge clk)
begin
if (rst == 1'b1)
state <= reset_state;
else if (hold == 1'b1)
state <= state;
else
state <= next_state;
end
endmodule
Go to most recent revision | Compare with Previous | Blame | View Log