URL
https://opencores.org/ocsvn/mc6803/mc6803/trunk
Subversion Repositories mc6803
Compare Revisions
- This comparison shows the changes necessary to convert path
/mc6803
- from Rev 1 to Rev 2
- ↔ Reverse comparison
Rev 1 → Rev 2
/trunk/6801_core.sv
0,0 → 1,4422
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 |
trunk/6801_core.sv
Property changes :
Added: svn:executable
## -0,0 +1 ##
+*
\ No newline at end of property
Index: trunk/MC6803.sv
===================================================================
--- trunk/MC6803.sv (nonexistent)
+++ trunk/MC6803.sv (revision 2)
@@ -0,0 +1,233 @@
+//MC6803 processor
+module MC6803(
+ input logic Clk,
+ RST,
+ hold,
+ halt,
+ //irq,
+ nmi,
+ input logic[7:0] PORT_A_IN,
+ input logic[4:0] PORT_B_IN,
+ input logic[7:0] DATA_IN,
+ output logic[7:0] PORT_A_OUT,
+ PORT_B_OUT,
+ output logic[15:0] ADDRESS, last_write,
+ output logic[7:0] DATA_OUT,
+ output logic E_CLK, rw);
+logic[15:0] address, counter, next_counter;// capture;
+logic[7:0] A_DIRECTION_o, B_DIRECTION_o, data_in, data_out, outcomp_l, outcomp_h;
+//logic[7:0] DATA_IN_S;
+//logic[4:0] PORT_B_IN_S, PORT_A_IN_S;
+//logic[1:0] cycle, next_cycle;
+logic[7:0] REG_DATA;
+logic REG_RW, iRAM_E;
+logic B_EN, A_EN, vma, hold_s, nmi_s, PORTB_W, PORTA_W, outcomp_l_EN, outcomp_h_EN, counter_he, counter_le, counter_w, RST_S, irq_s;
+logic OCF, TOF, EOCI, ETOI, TCSR_EN, TCSR_READ;
+REG_8 direction_a(.Din(data_out), .Dout(A_DIRECTION_o), .EN(A_EN), .Clk);
+REG_8 direction_b(.Din(data_out), .Dout(B_DIRECTION_o), .EN(B_EN), .Clk);
+REG_8 port_b(.Din(data_out), .Dout(PORT_B_OUT), .EN(PORTB_W), .Clk);
+REG_8 port_a(.Din(data_out), .Dout(PORT_A_OUT), .EN(PORTA_W), .Clk);
+REG_8 outc_h(.Din(data_out), .Dout(outcomp_h), .EN(outcomp_h_EN), .Clk);
+REG_8 outc_l(.Din(data_out), .Dout(outcomp_l), .EN(outcomp_l_EN), .Clk);
+
+//cpu68 cpu68_inst(.clk(Clk), .rst(RST_S), .rw(rw), .vma(vma), .address(address), .data_in(data_in), .data_out(data_out), .hold(hold_s), .halt(halt), .irq(1'b0), .nmi(nmi_s));
+cpu01 cpu01_inst(.clk(Clk), .rst(RST_S), .rw(rw), .vma(vma), .address(address), .data_in(data_in), .data_out(data_out), .hold(hold_s), .halt(halt), .irq(1'b0), .nmi(nmi_s), .irq_icf(1'b0), .irq_ocf(1'b0), .irq_tof(1'b0), .irq_sci(1'b0));
+MEM_128_8 iMEM(.Clk, .reset(RST_S), .data_in(data_out), .data_out(REG_DATA), .RW(REG_RW), .address(address[6:0]));
+assign ADDRESS = address;
+assign DATA_OUT = data_out;
+//assign last_write = {1'b1, OCF, TOF, 1'b0, EOCI, ETOI, 10'h00};
+always_ff @ (negedge Clk)
+begin
+ hold_s <= hold;
+ nmi_s <= nmi;
+ RST_S <= RST;
+ //irq_s <= irq;
+ //PORT_B_IN_S <= PORT_B_IN;
+ //PORT_A_IN_S <= PORT_A_IN;
+ if(vma & (~rw))
+ last_write <= address;
+// if(counter_he)
+// counter <= {data_out, counter[7:0]};
+// else if(counter_le)
+// counter <= {counter[15:8], data_out};
+ if(RST_S)
+ begin
+ counter <= 0;
+ OCF <= 0;
+ TOF <= 0;
+ EOCI <= 0;
+ ETOI <= 0;
+ end
+ else
+ begin
+ if(counter_w)
+ counter <= 16'hfff8;
+ else
+ begin
+ counter <= next_counter;
+ end
+ //cycle <= next_cycle;
+// if(capture_EN)
+// capture <= counter;
+ if(TCSR_EN)
+ begin
+ EOCI <= data_out[3];
+ ETOI <= data_out[2];
+ end
+ if(TCSR_READ)
+ begin
+ TOF <= 0;
+ OCF <= 0;
+ end
+ else
+ begin
+ if(counter == {outcomp_h, outcomp_l})
+ OCF <= 1'b1;
+ if(counter == 16'hffff)
+ TOF <= 1'b1;
+ end
+ end
+end
+
+always_comb
+begin
+outcomp_h_EN = 0;
+outcomp_l_EN = 0;
+REG_RW = 1;
+TCSR_EN = 0;
+TCSR_READ = 0;
+next_counter = counter + 16'h01;
+//next_cycle = cycle + 2'b01;
+//if(counter == {outcomp_h, outcomp_l})
+// capture_EN = 1'b1;
+//else
+// capture_EN = 0;
+if(address > 16'h7f && address < 16'h100 && vma)
+ iRAM_E = 1'b1;
+else
+ iRAM_E = 0;
+counter_w = 0;
+A_EN = 0;
+B_EN = 0;
+PORTB_W = 0;
+PORTA_W = 0;
+//ADDRESS = 16'h06;
+E_CLK = 0;
+data_in = DATA_IN;
+//DATA_OUT = 8'bxxxxxxxx;
+ case (address)
+ 16'h00:
+ begin
+ if(vma & (~rw))
+ A_EN = 1'b1;
+ else if(vma)
+ data_in = A_DIRECTION_o;
+ end
+ 16'h01:
+ begin
+ if(vma & (~rw))
+ B_EN = 1'b1;
+ else if(vma)
+ data_in = B_DIRECTION_o;
+ end
+ 16'h02:
+ begin
+ if(vma & (~rw))
+ PORTA_W = 1'b1;
+ else if(vma)
+ data_in = PORT_A_IN;
+ end
+ 16'h03:
+ begin
+ if(vma & (~rw)) //write to port B
+ PORTB_W = 1'b1;
+ else if(vma) //read port B
+ data_in = {PORT_B_OUT[7:5], PORT_B_IN};
+ end
+ 16'h08:
+ begin
+ if(vma & (~rw))
+ TCSR_EN = 1'b1;
+ else if(vma)
+ begin
+ TCSR_READ = 1'b1;
+ data_in = {1'b1, OCF, TOF, 1'b0, EOCI, ETOI, 2'b00};
+ end
+ end
+ 16'h09:
+ begin
+ if(vma & (~rw))
+ counter_w = 1'b1; //preset the counter
+ else if(vma)
+ data_in = counter[15:8];
+ end
+ 16'h0A:
+ begin
+ if(vma & rw)
+ data_in = counter[7:0];
+ end
+ 16'h0B:
+ begin
+ if(vma & (~rw))
+ outcomp_h_EN = 1'b1;
+ else if(vma)
+ data_in = outcomp_h;
+ end
+ 16'h0C:
+ begin
+ if(vma & (~rw))
+ outcomp_l_EN = 1'b1;
+ else if(vma)
+ data_in = outcomp_l;
+ end
+// 16'h0D:
+// begin
+// if(vma & rw)
+// data_in = capture[15:8];
+// end
+// 16'h0E:
+// begin
+// if(vma & rw)
+// data_in = capture[7:0];
+// end
+ default:
+ begin
+ if(iRAM_E)
+ begin
+ REG_RW = rw;
+ data_in = REG_DATA;
+ end
+ else
+ begin
+ E_CLK = vma;
+ data_in = DATA_IN;
+ end
+ end
+ endcase
+end
+endmodule
+
+module REG_8(input logic [7:0] Din, input logic EN, Clk, output logic[7:0] Dout);
+ always_ff @ (posedge Clk)
+ begin
+ if(EN)
+ Dout <= Din;
+ else
+ Dout <= Dout;
+ end
+endmodule
+
+module MEM_128_8(input logic[6:0] address, input logic RW, Clk, reset, input logic[7:0] data_in, output logic[7:0] data_out);
+logic[7:0] REGS[127:0];
+integer i;
+always_ff @ (posedge Clk)
+begin
+if(reset)
+ for(i=0; i<128; i=i+1)
+ REGS[i]=0;
+else if(~RW)
+ REGS[address] <= data_in;
+end
+assign data_out = REGS[address];
+endmodule
+
trunk/MC6803.sv
Property changes :
Added: svn:executable
## -0,0 +1 ##
+*
\ No newline at end of property