Created
December 22, 2014 10:54
-
-
Save dev-zzo/f4dd7edebd09b2b323eb to your computer and use it in GitHub Desktop.
BM80A
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// | |
// copyright (c) 2014 by [email protected] | |
//______________________________________________________________________________ | |
// | |
`timescale 1ns / 1ns | |
module vm80a | |
( | |
input pin_clk, // global module clock (no in original 8080) | |
input pin_f1, // clock phase 1 (used as clock enable) | |
input pin_f2, // clock phase 2 (used as clock enable) | |
input pin_reset, // module reset | |
output[15:0] pin_a, // address bus outputs | |
inout [7:0] pin_d, // | |
input pin_hold, // | |
output pin_hlda, // | |
input pin_ready, // | |
output pin_wait, // | |
input pin_int, // | |
output pin_inte, // | |
output pin_sync, // | |
output pin_dbin, // | |
output pin_wr_n | |
); | |
wire pin_aena, pin_dena; | |
wire [7:0] pin_din, pin_dout; | |
wire [15:0] pin_addr; | |
reg f1_core, f2_core; | |
assign pin_a = pin_aena ? pin_addr : 16'hZZZZ; | |
assign pin_d = pin_dena ? pin_dout : 8'hZZ; | |
assign pin_din = pin_d; | |
always @(posedge pin_clk) | |
begin | |
f1_core <= pin_f1; | |
f2_core <= pin_f2; | |
end | |
vm80a_core core | |
( | |
.pin_clk (pin_clk), | |
.pin_f1 (f1_core), | |
.pin_f2 (f2_core), | |
.pin_reset (pin_reset), | |
.pin_a (pin_addr), | |
.pin_dout (pin_dout), | |
.pin_din (pin_din), | |
.pin_aena (pin_aena), | |
.pin_dena (pin_dena), | |
.pin_hold (pin_hold), | |
.pin_hlda (pin_hlda), | |
.pin_ready (pin_ready), | |
.pin_wait (pin_wait), | |
.pin_int (pin_int), | |
.pin_inte (pin_inte), | |
.pin_sync (pin_sync), | |
.pin_dbin (pin_dbin), | |
.pin_wr_n (pin_wr_n) | |
); | |
endmodule | |
module vm80a_core | |
( | |
input pin_clk, // global module clock (no in original 8080) | |
input pin_f1, // clock phase 1 (used as clock enable) | |
input pin_f2, // clock phase 2 (used as clock enable) | |
input pin_reset, // module reset | |
output[15:0] pin_a, // address bus outputs | |
output[7:0] pin_dout, // data bus output | |
input [7:0] pin_din, // data bus input | |
output pin_aena, // address outputs enable | |
output pin_dena, // data outputs enable | |
input pin_hold, // | |
output pin_hlda, // | |
input pin_ready, // | |
output pin_wait, // | |
input pin_int, // | |
output pin_inte, // | |
output pin_sync, // | |
output pin_dbin, // | |
output pin_wr_n | |
); | |
//______________________________________________________________________________ | |
// | |
wire [7:0] d; | |
reg [7:0] db, di; | |
reg [15:0] a; | |
wire clk, f1, f2; | |
reg abufena, db_ena, db_stb, dbin_pin, dbinf2; | |
reg reset; | |
wire ready; | |
wire dbin_ext; | |
reg t851, t404, t382, t383, t712, t735, t773; | |
reg hold, hlda_pin; | |
wire hlda, h889; | |
reg wr_n, t1124, t1011, sync; | |
wire ready_int; | |
reg [15:0] r16_pc, r16_hl, r16_de, r16_bc, r16_sp, r16_wz, mxo; | |
wire [15:0] mxi; | |
wire mxr0, mxr1, mxr2, mxr3, mxr4, mxr5; | |
wire mxwh, mxwl, mxrh, mxrl, mxw16, mxwadr; | |
wire dec16, inc16, iad16; | |
reg xchg_dh, xchg_tt, t3144; | |
wire t1460, t1467, t1513, t1514, t1519; | |
wire sy_inta, sy_wo_n, sy_hlta, sy_out, sy_m1, sy_inp, sy_memr; | |
reg sy_stack; | |
wire thalt, twt2; | |
reg t1, t2, tw, t3, t4, t5; | |
reg t1f1, t2f1, twf1, t3f1, t4f1, t5f1; | |
reg m1, m2, m3, m4, m5; | |
reg m1f1, m2f1, m3f1, m4f1, m5f1; | |
wire start, ms0, ms1, m836, m839, m871; | |
reg eom, t789, t887, t953, t976, t980; | |
reg intr, inta, inte, mstart, minta; | |
wire irq; | |
reg [7:0] i; | |
reg i25, i14, i03; | |
wire imx, acc_sel; | |
wire id_op, id_io, id_in, id_popsw, id_pupsw, | |
id_nop, id_lxi, id_inx, id_inr, id_dcr, id_idr, id_mvi, id_dad, | |
id_dcx, id_opa, id_idm, id_hlt, id_mov, id_opm, id_pop, id_rst, | |
id_cxx, id_jxx, id_rxx, id_ret, id_jmp, id_opi, id_out, id_11x, | |
id_rlc, id_rxc, id_rar, id_sha, id_daa, id_cma, id_stc, id_cmc, | |
id_add, id_adc, id_sub, id_sbb, id_ana, id_xra, id_ora, id_cmp, | |
id_lsax, id_mvim, id_shld, id_lhld, id_mvmr, id_mvrm, id_push, | |
id_xthl, id_sphl, id_pchl, id_xchg, id_call, id_eidi, id_stlda; | |
wire id80, id81, id82, id83, id84, id85, id86, id00, id01, | |
id02, id03, id04, id05, id06, id07, id08, id09, id10; | |
wire goto, jmpflag; | |
reg jmptake, tree0, tree1, tree2; | |
reg t2806, t2817, t2819, t3047, t2998, t3363, t3403, t3335, t3361; | |
reg [7:0] xr, r, acc; | |
wire [7:0] x, s, c; | |
wire cl, ch, daa, daa_6x, daa_x6; | |
wire a398; | |
reg a327, a357, a358; | |
wire alu_xout, alu_xwr, alu_xrd, alu_ald, alu_awr, alu_ard, | |
alu_rld, alu_r00, alu_rwr, alu_srd, alu_zrd, alu_frd; | |
reg psw_z, psw_s, psw_p, psw_c, psw_ac, tmp_c; | |
reg t2222, t1375, t1497, t1698, t1668, t1780, t1993, t1994; | |
reg psw_ld, psw_wr, t2046, t2133, t2175; | |
//_____________________________________________________________________________ | |
// | |
assign clk = pin_clk; | |
assign f1 = pin_f1; | |
assign f2 = pin_f2; | |
assign pin_a = a; | |
assign pin_aena = abufena; | |
assign pin_dout = db; | |
assign pin_dena = db_ena; | |
assign dbin_ext = dbinf2; | |
assign d[7] = ~reset & ~alu_zrd & | |
( dbin_ext & di[7] | |
| mxrl & mxo[7] | |
| mxrh & mxo[15] | |
| t1f1 & sy_memr | |
| alu_xrd & xr[7] | |
| alu_ard & acc[7] | |
| alu_frd & psw_s | |
| alu_srd & s[7] ); | |
assign d[6] = ~reset & ~alu_zrd & | |
( dbin_ext & di[6] | |
| mxrl & mxo[6] | |
| mxrh & mxo[14] | |
| t1f1 & sy_inp | |
| alu_xrd & xr[6] | |
| alu_ard & acc[6] | |
| alu_frd & psw_z | |
| alu_srd & s[6] ); | |
assign d[5] = ~reset & ~alu_zrd & | |
( dbin_ext & di[5] | |
| mxrl & mxo[5] | |
| mxrh & mxo[13] | |
| t1f1 & sy_m1 | |
| alu_xrd & xr[5] | |
| alu_ard & acc[5] | |
| alu_frd & 1'b0 | |
| alu_srd & s[5] ); | |
assign d[4] = ~reset & ~alu_zrd & | |
( dbin_ext & di[4] | |
| mxrl & mxo[4] | |
| mxrh & mxo[12] | |
| t1f1 & sy_out | |
| alu_xrd & xr[4] | |
| alu_ard & acc[4] | |
| alu_frd & psw_ac | |
| alu_srd & s[4] ); | |
assign d[3] = ~reset & ~alu_zrd & | |
( dbin_ext & di[3] | |
| mxrl & mxo[3] | |
| mxrh & mxo[11] | |
| t1f1 & sy_hlta | |
| alu_xrd & xr[3] | |
| alu_ard & acc[3] | |
| alu_frd & 1'b0 | |
| alu_srd & s[3] ); | |
assign d[2] = ~reset & ~alu_zrd & | |
( dbin_ext & di[2] | |
| mxrl & mxo[2] | |
| mxrh & mxo[10] | |
| t1f1 & sy_stack | |
| alu_xrd & xr[2] | |
| alu_ard & acc[2] | |
| alu_frd & psw_p | |
| alu_srd & s[2] ); | |
assign d[1] = ~reset & ~alu_zrd & | |
( dbin_ext & di[1] | |
| mxrl & mxo[1] | |
| mxrh & mxo[9] | |
| t1f1 & sy_wo_n | |
| alu_xrd & xr[1] | |
| alu_ard & acc[1] | |
| alu_frd & 1'b1 | |
| alu_srd & s[1] ); | |
assign d[0] = ~reset & ~alu_zrd & | |
( dbin_ext & di[0] | |
| mxrl & mxo[0] | |
| mxrh & mxo[8] | |
| t1f1 & sy_inta | |
| alu_xrd & xr[0] | |
| alu_ard & acc[0] | |
| alu_frd & psw_c | |
| alu_srd & s[0] ); | |
always @(posedge clk) | |
begin | |
if (f2 & db_stb) db <= d; | |
if (f2) abufena <= (~twt2 | ~thalt) & ~hlda_pin; | |
if (f1) db_stb <= t1 | (~sy_wo_n & t2); | |
if (f1) t851 <= t1 | (~sy_wo_n & (t2 | tw | t3)); | |
if (f2) db_ena <= ~reset & t851; | |
end | |
//______________________________________________________________________________ | |
// | |
// reset input buffer | |
// | |
always @(posedge clk) | |
begin | |
if (f1) t404 <= pin_reset; | |
if (f2) reset <= t404; | |
end | |
//______________________________________________________________________________ | |
// | |
// hold input buffer | |
// | |
assign pin_hlda = hlda_pin; | |
assign hlda = hold & (t773 | (t3 & sy_wo_n) | (~m1 & sy_hlta) | t735); | |
assign h889 = t2f1 | twf1; | |
always @(posedge clk) | |
begin | |
if (f1) t712 <= ~sy_wo_n & t3; | |
if (f2) t735 <= t712; | |
if (~f2) t382 <= pin_hold; | |
if (f2) t383 <= ((~t382 & hold) | t383); // extend the front detector pulse for entire F2 duration | |
if (~f2) t383 <= 1'b0; | |
if (f2) t773 <= hlda_pin; | |
if (f1) hlda_pin <= hlda; | |
end | |
always @(posedge clk) | |
begin | |
if (reset) | |
hold <= 1'b0; | |
else | |
if (f2) | |
begin | |
if (t382) | |
begin | |
if (~sy_inta & h889) hold <= 1'b1; | |
end | |
else | |
hold <= 1'b0; | |
end | |
end | |
//______________________________________________________________________________ | |
// | |
assign pin_dbin = dbin_pin; | |
assign pin_wr_n = wr_n; | |
assign pin_sync = sync; | |
always @(posedge clk) | |
begin | |
dbinf2 <= (f2 | dbin_pin) & ((t1124 & (m1f1 | ~sy_hlta)) | dbinf2); | |
if (dbin_pin) di <= pin_din; | |
if (f2) dbin_pin <= t1124 & (m1f1 | ~sy_hlta); | |
if (f2) sync <= ~ready_int & t1011; | |
if (f1) t1011 <= t1 & ~reset; | |
if (f1) t1124 <= (t2 | tw) & sy_wo_n; | |
if (f1) wr_n <= ~(t3 | tw) | ready_int | sy_wo_n; | |
end | |
//______________________________________________________________________________ | |
// | |
// ready pin and internal circuits | |
// | |
assign ready_int = (m4 | m5) & id_dad; | |
assign ready = ready_int | pin_ready; | |
assign pin_wait = twf1; | |
//______________________________________________________________________________ | |
// | |
// register unit - 6 16-bit registers | |
// | |
// r0 - pc | |
// r1 - hl, de | |
// r2 - de, hl | |
// r3 - bc | |
// r4 - sp | |
// r5 - wz | |
// | |
assign t1467 = tree1 | (id04 & t4f1 & ~id_xthl); | |
assign t1519 = tree2 | (id00 & t4f1 & ~id_xthl); | |
assign mxi = inc16 ? (a + 16'h0001) | |
: dec16 ? (a - 16'h0001) | |
: a; | |
assign inc16 = iad16 & ~dec16; | |
assign dec16 = iad16 & id05 & (t4f1 | t5f1 | m4f1 | m5f1); | |
assign iad16 = ~(id00 & (t4f1 | t5f1)) & (~minta | m5 | t3144); | |
assign mxw16 = t3403; | |
assign mxwadr = t3363 | (t4f1 & ~id_dad & ~id_hlt); | |
assign t1513 = (t4f1 & id07) | t3335; | |
assign t1514 = (t4f1 & id08) | t3361; | |
assign mxrh = t2998 | (id08 & t4f1 & ~i03); | |
assign mxrl = t3047 | (id08 & t4f1 & i03); | |
assign mxwh = t2817 | (t2806 & ~i03); | |
assign mxwl = t2819 | (t2806 & i03); | |
assign mxr0 = tree0; | |
assign mxr1 = xchg_dh & (((t1513 | t1514) & (~i14 & i25)) | t1519) | |
| ~xchg_dh & (t1513 | t1514) & (i14 & ~i25); | |
assign mxr2 = xchg_dh & (t1513 | t1514) & (i14 & ~i25) | |
| ~xchg_dh & (((t1513 | t1514) & (~i14 & i25)) | t1519); | |
assign mxr3 = (t1513 | t1514) & (~i14 & ~i25); | |
assign mxr4 = t1467 | (t1513 & i14 & i25); | |
assign mxr5 = ~(t1467 | t1513 | t1514 | t1519 | mxr0); | |
always @ (posedge clk) | |
begin | |
if (f1) t3144 <= t4 | t5 | (m4 & ~id02); | |
xchg_tt <= id_xchg & t2; | |
xchg_dh <= ~reset & ((xchg_tt & ~(id_xchg & t2)) ? ~xchg_dh : xchg_dh); | |
end | |
always @ (*) | |
case ({mxr0, mxr1, mxr2, mxr3, mxr4, mxr5}) | |
6'b100000: mxo = r16_pc; | |
6'b010000: mxo = r16_hl; | |
6'b001000: mxo = r16_de; | |
6'b000100: mxo = r16_bc; | |
6'b000010: mxo = r16_sp; | |
6'b000001: mxo = r16_wz; | |
default: mxo = 16'h0000; | |
endcase | |
always @ (posedge clk) | |
if (f2) | |
begin | |
if (mxwadr) a <= mxo; | |
if (mxw16) | |
begin | |
if (mxr0) r16_pc <= mxi; | |
if (mxr1) r16_hl <= mxi; | |
if (mxr2) r16_de <= mxi; | |
if (mxr3) r16_bc <= mxi; | |
if (mxr4) r16_sp <= mxi; | |
if (mxr5) r16_wz <= mxi; | |
end | |
else | |
begin | |
if (mxwl) | |
begin | |
if (mxr0) r16_pc[7:0] <= d; | |
if (mxr1) r16_hl[7:0] <= d; | |
if (mxr2) r16_de[7:0] <= d; | |
if (mxr3) r16_bc[7:0] <= d; | |
if (mxr4) r16_sp[7:0] <= d; | |
if (mxr5) r16_wz[7:0] <= d; | |
end | |
if (mxwh) | |
begin | |
if (mxr0) r16_pc[15:8] <= d; | |
if (mxr1) r16_hl[15:8] <= d; | |
if (mxr2) r16_de[15:8] <= d; | |
if (mxr3) r16_bc[15:8] <= d; | |
if (mxr4) r16_sp[15:8] <= d; | |
if (mxr5) r16_wz[15:8] <= d; | |
end | |
end | |
end | |
//______________________________________________________________________________ | |
// | |
// processor state | |
// | |
assign sy_hlta = id_hlt; | |
assign sy_m1 = m1; | |
assign sy_inp = m5 & id_in; | |
assign sy_out = m5 & id_out; | |
assign sy_inta = inta; | |
assign sy_memr = sy_wo_n & ~sy_inp & ~minta; | |
assign sy_wo_n = m1 | m2 | m3 | (((m4 & ~id86) | (m5 & ~id85)) & ~ready_int); | |
always @(posedge clk) | |
begin | |
if (f1) | |
begin | |
sy_stack <= (t1 & t1460) | |
| (t3 & m3 & id_cxx & ~jmptake) | |
| (t5 & m1 & id_rxx & ~jmptake); | |
end | |
end | |
//______________________________________________________________________________ | |
// | |
// ticks state machine | |
// | |
assign twt2 = (t2f1 | twf1) & ~start; | |
assign thalt = ~m1 & sy_hlta; | |
always @(posedge clk) | |
begin | |
if (f1) | |
begin | |
t1f1 <= t1 & ~reset; // ensure the reliable start after reset | |
t2f1 <= t2; | |
twf1 <= tw; | |
t3f1 <= t3; | |
t4f1 <= t4; | |
t5f1 <= t5; | |
end | |
if (f2) | |
begin | |
t1 <= start; | |
t2 <= ~start & t1f1; | |
tw <= ~start & (t2f1 | twf1) & (~ready | thalt); | |
t3 <= ~start & (t2f1 | twf1) & ready & ~thalt; | |
t4 <= ~start & t3f1 & ms0 & ~ms1; | |
t5 <= ~start & t4f1 & ms0 & ~ms1; | |
end | |
end | |
//______________________________________________________________________________ | |
// | |
assign m836 = m1f1 & id82; | |
assign m839 = ~t976 | ~sy_hlta; | |
assign m871 = t789 | id81; | |
assign start = ~m839 | |
| t953 | |
| (eom & ~(hold & t887)) | |
| (f2 & ((~t382 & hold) | t383) & ~(twf1 | t3f1 | t4f1 | t5f1)); | |
assign ms0 = ~reset & m839 & ~(sy_stack & ~t1f1) & ~(eom & ~m836); | |
assign ms1 = ~reset & m839 & ~(sy_stack & ~t1f1) & ~(m871 & ~m836) & eom; | |
always @(posedge clk) | |
begin | |
if (f1) | |
begin | |
t789 <= (id84 & m3) | (id83 & ~id_mvim & m4) | m5; | |
t887 <= hold; | |
t953 <= reset; | |
t976 <= t980 & m4; | |
eom <= t5 | |
| t4 & m1 & id80 | |
| t3 & m2 | |
| t3 & m3 | |
| t3 & m4 | |
| t3 & m5 & ~id_xthl; | |
end | |
if (f2) | |
begin | |
t980 <= sy_inta; | |
end | |
end | |
//______________________________________________________________________________ | |
// | |
// processor cycles state machine | |
// | |
always @(posedge clk) | |
begin | |
if (f1) | |
begin | |
m1f1 <= m1; | |
m2f1 <= m2; | |
m3f1 <= m3; | |
m4f1 <= m4; | |
m5f1 <= m5; | |
end | |
if (f2) | |
begin | |
m1 <= (~ms0 & ~ms1) | (~ms1 & m1f1); | |
m2 <= (~ms0 | ~ms1) & ((ms0 & m2f1) | (ms1 & m1f1)); | |
m3 <= (ms0 & m3f1) | (ms1 & m2f1); | |
m4 <= (ms0 & m4f1) | (ms1 & m3f1) | (ms0 & ms1); | |
m5 <= (ms0 & m5f1) | (ms1 & m4f1); | |
end | |
end | |
//______________________________________________________________________________ | |
// | |
// interrupt logic | |
// | |
assign irq = intr & inte & ~reset & ~hold; | |
assign pin_inte = inte; | |
always @(posedge clk) | |
begin | |
if (f2) intr <= pin_int; | |
if (f2) mstart <= ~ms0 & ~ms1; | |
if (sy_inta) minta <= 1; | |
if (f1 & t1 & m1) minta <= 0; | |
end | |
always @(posedge clk or posedge reset) | |
begin | |
if (reset) | |
begin | |
inta <= 0; | |
inte <= 0; | |
end | |
else | |
begin | |
if (f1) | |
begin | |
if (irq & ((tw & sy_hlta) | (mstart & ~id_eidi))) inta <= 1; | |
if (~intr | id_eidi | (t5 & id_rst)) inta <= 0; | |
end | |
if (f2) | |
begin | |
if (t1f1 & id_eidi) inte <= i[3]; | |
if (t1f1 & sy_inta) inte <= 0; | |
end | |
end | |
end | |
//______________________________________________________________________________ | |
// | |
// instruction register and decoder | |
// | |
function cmp | |
( | |
input [7:0] i, | |
input [7:0] c, | |
input [7:0] m | |
); | |
cmp = &(~(i ^ c) | m); | |
endfunction | |
assign imx = ~(id_op | (id_mov & t4)); | |
assign acc_sel = imx ? (i[5:3] == 3'b111) : (i[2:0] == 3'b111); | |
assign jmpflag = (psw_c & i14 & ~i25) // Intel original: d[0] instead of psw_c | |
| (psw_p & ~i14 & i25) // Intel original: d[2] instead of psw_p | |
| (psw_z & ~i14 & ~i25) // Intel original: d[6] instead of psw_z | |
| (psw_s & i14 & i25); // Intel original: d[7] instead of psw_s | |
always @(posedge clk) | |
begin | |
// | |
// Simplify the D-bus multiplexer and feed the I-register by input pins directly | |
// | |
if (~f2 & (reset | (m1 & t3))) i <= pin_din; | |
if (f1) | |
begin | |
i25 <= imx ? i[5] : i[2]; | |
i14 <= imx ? i[4] : i[1]; | |
i03 <= imx ? i[3] : i[0]; | |
end | |
end | |
assign goto = id_rst | id_jmp | id_call | (jmptake & (id_cxx | id_jxx)); | |
assign t1460 = (t1 & ( (m2 & id00) | |
| (m3 & id00) | |
| (m4 & (id01 | id04)) | |
| (m5 & (id01 | id04))) | |
| t2 & ( (m2 & id00) | |
| (m4 & id01) | |
| (m5 & id01)) | |
| t3 & ( (m4 & (id04 | id_sphl))) | |
| t5 & ( (m1 & (id04 | id_sphl)))) & ~(~jmptake & id_cxx & t5); | |
always @(posedge clk) | |
begin | |
if (f2 & t4f1) | |
begin | |
jmptake <= i03 ? jmpflag : ~jmpflag; | |
end | |
if (f1) | |
begin | |
tree0 <= t1 & ( (m1 & ~goto) | |
| (m2 & ~id_xthl) | |
| (m3 & ~id_xthl) | |
| (m4 & id02)) | |
| t2 & ( m1 | |
| (m2 & ~id_xthl) | |
| (m3 & ~id_xthl) | |
| (m4 & (id02 | id_rst | id_cxx | id_call)) | |
| (m5 & (id_rst | id_cxx | id_call))) | |
| t3 & ( (m4 & (id_ret | id_rxx)) | |
| (m5 & (id_ret | id_rxx))) | |
| t5 & id_pchl; | |
tree1 <= t1460; | |
tree2 <= t1 & ( (m4 & (id_mov | id_idr | id_op)) | |
| (m5 & id08)) | |
| t2 & ( (m4 & (id_shld | id00 | id_dad)) | |
| (m5 & (id_shld | id00 | id_dad))) | |
| t3 & ( (m4 & (id_lhld | id_dad)) | |
| (m5 & (id_lhld | id_dad))) | |
| t5 & m5; | |
t2806 <= id08 & ((t3 & m4) | (t5 & m1)); | |
t2817 <= reset | (t3 & (m1 | m3 | (m4 & id_io) | (m5 & id06))); | |
t2819 <= reset | (t3 & (m2 | (m4 & id06) | (m5 & id_rst))); | |
t3047 <= m4 & (t1 | t2) & id_dad | |
| t2 & ((m4 & id_shld) | (m5 & id03)); | |
t2998 <= (t1 | t2) & m5 & id_dad | |
| t2 & ((m5 & id_shld) | (m4 & id03)); | |
t3403 <= t2 & ( (m1 | m2) | |
| (m3 & ~id_xthl) | |
| ((m4 | m5) & ~id_dad & ~id09)) | |
| t3 & m4 & id09 | |
| t5 & (m5 | (m1 & ~id08)); | |
t3363 <= t1 & (m1 | m2 | m3 | ((m4 | m5) & ~id_hlt & ~id_dad)); | |
t3335 <= id07 & ((t1 & (m4 | m5)) | (t3 & (m2 | m3)) | t5); | |
t3361 <= t1 & m4 & id_lsax | |
| t2 & id10 & ~sy_wo_n | |
| t3 & id10 & sy_wo_n & (m4 | m5) | |
| t5 & id08 & m1; | |
end | |
end | |
assign id_nop = cmp(i, 8'b00xxx000, 8'b00111000); | |
assign id_lxi = cmp(i, 8'b00xx0001, 8'b00110000); | |
assign id_lsax = cmp(i, 8'b000xx010, 8'b00011000); | |
assign id_inx = cmp(i, 8'b00xx0011, 8'b00110000); | |
assign id_inr = cmp(i, 8'b00xxx100, 8'b00111000); | |
assign id_dcr = cmp(i, 8'b00xxx101, 8'b00111000); | |
assign id_idr = cmp(i, 8'b00xxx10x, 8'b00111001); | |
assign id_mvi = cmp(i, 8'b00xxx110, 8'b00111000); | |
assign id_dad = cmp(i, 8'b00xx1001, 8'b00110000); | |
assign id_dcx = cmp(i, 8'b00xx1011, 8'b00110000); | |
assign id_opa = cmp(i, 8'b00xxx111, 8'b00111000); | |
assign id_idm = cmp(i, 8'b0011010x, 8'b00000001); | |
assign id_stlda = cmp(i, 8'b0011x010, 8'b00001000); | |
assign id_mvim = cmp(i, 8'b00110110, 8'b00000000); | |
assign id_shld = cmp(i, 8'b00100010, 8'b00000000); | |
assign id_lhld = cmp(i, 8'b00101010, 8'b00000000); | |
assign id_mvmr = cmp(i, 8'b01110xxx, 8'b00000111) & ~id_hlt; | |
assign id_mvrm = cmp(i, 8'b01xxx110, 8'b00111000) & ~id_hlt; | |
assign id_hlt = cmp(i, 8'b01110110, 8'b00000000); | |
assign id_mov = cmp(i, 8'b01xxxxxx, 8'b00111111); | |
assign id_op = cmp(i, 8'b10xxxxxx, 8'b00111111); | |
assign id_opm = cmp(i, 8'b10xxx110, 8'b00111000); | |
assign id_pop = cmp(i, 8'b11xx0001, 8'b00110000); | |
assign id_push = cmp(i, 8'b11xx0101, 8'b00110000); | |
assign id_rst = cmp(i, 8'b11xxx111, 8'b00111000); | |
assign id_xthl = cmp(i, 8'b11100011, 8'b00000000); | |
assign id_sphl = cmp(i, 8'b11111001, 8'b00000000); | |
assign id_pchl = cmp(i, 8'b11101001, 8'b00000000); | |
assign id_xchg = cmp(i, 8'b11101011, 8'b00000000); | |
assign id_cxx = cmp(i, 8'b11xxx100, 8'b00111000); | |
assign id_jxx = cmp(i, 8'b11xxx010, 8'b00111000); | |
assign id_rxx = cmp(i, 8'b11xxx000, 8'b00111000); | |
assign id_ret = cmp(i, 8'b110x1001, 8'b00010000); | |
assign id_call = cmp(i, 8'b11xx1101, 8'b00110000); | |
assign id_eidi = cmp(i, 8'b1111x011, 8'b00001000); | |
assign id_jmp = cmp(i, 8'b1100x011, 8'b00001000); | |
assign id_io = cmp(i, 8'b1101x011, 8'b00001000); | |
assign id_opi = cmp(i, 8'b11xxx110, 8'b00111000); | |
assign id_in = cmp(i, 8'b11011011, 8'b00000000); | |
assign id_popsw = cmp(i, 8'b11110001, 8'b00000000); | |
assign id_out = cmp(i, 8'b11010011, 8'b00000000); | |
assign id_11x = cmp(i, 8'b11xxxxxx, 8'b00111111); | |
assign id_pupsw = cmp(i, 8'b11110101, 8'b00000000); | |
assign id_rxc = ~i[5] & i[3] & id_opa; | |
assign id_sha = ~i[5] & id_opa; | |
assign id_rlc = (i[5:3] == 3'b000) & id_opa; | |
assign id_rar = (i[5:3] == 3'b011) & id_opa; | |
assign id_daa = (i[5:3] == 3'b100) & id_opa; | |
assign id_cma = (i[5:3] == 3'b101) & id_opa; | |
assign id_stc = (i[5:3] == 3'b110) & id_opa; | |
assign id_cmc = (i[5:3] == 3'b111) & id_opa; | |
assign id_add = (i[5:3] == 3'b000) & (id_op | id_opi); | |
assign id_adc = (i[5:3] == 3'b001) & (id_op | id_opi); | |
assign id_sub = (i[5:3] == 3'b010) & (id_op | id_opi); | |
assign id_sbb = (i[5:3] == 3'b011) & (id_op | id_opi); | |
assign id_ana = (i[5:3] == 3'b100) & (id_op | id_opi); | |
assign id_xra = (i[5:3] == 3'b101) & (id_op | id_opi); | |
assign id_ora = (i[5:3] == 3'b110) & (id_op | id_opi); | |
assign id_cmp = (i[5:3] == 3'b111) & (id_op | id_opi); | |
assign id80 = id_lxi | id_pop | id_opm | id_idm | id_dad | |
| id_xthl | id_xchg | id_jxx | id_ret | id_eidi | |
| id_nop | id_stlda | id_mvmr | id_mvrm | id_hlt | |
| id_opa | id_mvim | id_jmp | id_io | id_opi | |
| id_mvi | id_lsax | id_lhld | id_shld | id_op; | |
assign id81 = id_dcx | id_inx | id_sphl | id_pchl | id_xchg | |
| id_eidi | id_nop | id_opa | id_op | id_mov | |
| (id_idr & ~id82); | |
assign id82 = id_pop | id_push | id_opm | id_idm | id_dad | |
| id_rst | id_ret | id_rxx | id_mvrm | id_mvmr | |
| id_hlt | id_mvim | id_io | id_opi | id_mvi | |
| id_lsax; | |
assign id83 = id_opm | id_stlda | id_mvmr | id_mvrm | id_opi | |
| id_mvi | id_lsax; | |
assign id84 = id_lxi | id_jxx | id_jmp; | |
assign id85 = id_push | id_idm | id_rst | id_xthl | id_cxx | |
| id_call | id_mvim | id_shld | (id_io & ~i[3]); | |
assign id86 = id_push | id_rst | id_xthl | id_cxx | id_call | |
| id_mvmr | id_shld | (~i[3] & (id_lsax | id_stlda)); | |
assign id00 = id_xthl | id_pchl | id_sphl; | |
assign id01 = id_pop | id_rxx | id_ret; | |
assign id02 = id_mvi | id_opi | id_io; | |
assign id03 = id_rst | id_push | id_xthl | id_cxx | id_call; | |
assign id04 = id_rst | id_push | id_xthl | id_cxx | id_call; | |
assign id05 = id_rst | id_push | id_xthl | id_cxx | id_call | id_dcx; | |
assign id06 = id_pop | id_rxx | id_ret | id_dad | id_lhld | id_io; | |
assign id07 = id_dcx | id_inx | id_lxi | id_dad; | |
assign id08 = id_mov | id_mvi | id_idr | id_op; | |
assign id09 = id_rst | id_push | id_xthl | id_cxx | id_call | id_shld; | |
assign id10 = id_pop | id_push | id_mvrm | id_mvi; | |
//______________________________________________________________________________ | |
// | |
// function alu | |
// ( | |
// input rxc, | |
// input ora, | |
// input ana, | |
// input xra, | |
// input x, | |
// input r, | |
// input nc, | |
// input rn, | |
// input cp | |
// ); | |
// alu = x & r & cp & ~(rxc | ora | ana | xra) | |
// | nc & (cp | x | r) & ~(rxc | ora | ana | xra) | |
// | rxc & rn | |
// | ora & (x | r) | |
// | ana & (x & r) | |
// | xra & (x ^ r); | |
// endfunction | |
// | |
// | |
// assign s[0] = alu(id_rxc, id_ora, id_ana, id_xra, x[0], r[0], ~c[0], r[1], cl) | (id_rlc & c[7]); | |
// assign s[1] = alu(id_rxc, id_ora, id_ana, id_xra, x[1], r[1], ~c[1], r[2], c[0]); | |
// assign s[2] = alu(id_rxc, id_ora, id_ana, id_xra, x[2], r[2], ~c[2], r[3], c[1]); | |
// assign s[3] = alu(id_rxc, id_ora, id_ana, id_xra, x[3], r[3], ~c[3], r[4], c[2]); | |
// assign s[4] = alu(id_rxc, id_ora, id_ana, id_xra, x[4], r[4], ~c[4], r[5], c[3]); | |
// assign s[5] = alu(id_rxc, id_ora, id_ana, id_xra, x[5], r[5], ~c[5], r[6], c[4]); | |
// assign s[6] = alu(id_rxc, id_ora, id_ana, id_xra, x[6], r[6], ~c[6], r[7], c[5]); | |
// assign s[7] = alu(id_rxc, id_ora, id_ana, id_xra, x[7], r[7], ~c[7], ch, c[6]); | |
// | |
// | |
//______________________________________________________________________________ | |
// | |
// arithmetic and logic unit | |
// | |
// assign alu_xwr = (f1 & m1 & t3) | (f2 & (a327 | t4f1 & (id_out | ~id_11x))); | |
// | |
assign alu_xwr = (a327 | t4f1 & (id_rst | id_out | ~id_11x)); | |
assign alu_xout = ~(id_sub | id_sbb | id_cmp | id_cma); | |
assign alu_xrd = t1698 | a358; | |
assign x = alu_xout ? xr : ~xr; | |
assign alu_ald = t2222 & ( id_adc | id_add | id_daa | id_xra | id_sbb | |
| id_sub | id_ana | id_ora | id_sha | id_cma); | |
assign alu_ard = t1375 | a398; | |
assign alu_awr = t1497 | a357; | |
assign alu_r00 = id_dcr & t4f1; | |
assign alu_srd = t1668; | |
assign alu_rwr = t1780; | |
assign alu_rld = t4f1 & (id_sha | id_op | id_opi); | |
assign daa = id_daa & t4f1; | |
assign daa_x6 = (acc[3] & (acc[2] | acc[1])) | psw_ac; | |
assign daa_6x = ((acc[3] & (acc[2] | acc[1])) & acc[4] & acc[7]) | |
| (acc[7] & (acc[6] | acc[5])) | tmp_c; | |
assign s = {7'b0000000, id_rlc & c[7]} | |
| ((id_rxc | id_ora | id_ana | id_xra) ? 8'h00 : (x + r + cl)) | |
| (id_rxc ? {ch, r[7:1]} : 8'h00) | |
| (id_ora ? (x | r) : 8'h00) | |
| (id_ana ? (x & r) : 8'h00) | |
| (id_xra ? (x ^ r) : 8'h00); | |
assign cl = tmp_c & ~id_daa & ~id_rlc & ~id_ora & ~id_xra & ~id_rxc; | |
assign ch = tmp_c & id_rar | r[0] & ~id_rar; | |
// | |
// wire ca0_n, ca2_n, ca1, ca3; | |
// assign ca0_n = ~(cl & (x[0] | r[0])) & ~(x[0] & r[0]) & ~(id_ana & id_rxc); | |
// assign ca2_n = ~(ca1 & (x[2] | r[2])) & ~(x[2] & r[2]) & ~(id_ana & id_rxc); | |
// assign ca1 = ~(~x[1] & ~r[1]) & ~(ca0_n & (~x[1] | ~r[1])) & ~(id_ora | id_rxc | id_xra); | |
// assign ca3 = ~(~x[3] & ~r[3]) & ~(ca2_n & (~x[3] | ~r[3])) & ~(id_ora | id_rxc | id_xra); | |
// | |
assign c[0] = (r[0] & x[0]) | (cl & (r[0] | x[0])); | |
assign c[1] = (r[1] & x[1]) | (c[0] & (r[1] | x[1])); | |
assign c[2] = (r[2] & x[2]) | (c[1] & (r[2] | x[2])); | |
assign c[3] = (r[3] & x[3]) | (c[2] & (r[3] | x[3])); | |
assign c[4] = (r[4] & x[4]) | (c[3] & (r[4] | x[4])); | |
assign c[5] = (r[5] & x[5]) | (c[4] & (r[5] | x[5])); | |
assign c[6] = (r[6] & x[6]) | (c[5] & (r[6] | x[6])); | |
assign c[7] = (r[7] & x[7]) | (c[6] & (r[7] | x[7])); | |
assign alu_frd = t2046; /* | t4f1 & (id_11x & ~id_out); */ | |
assign alu_zrd = m1f1 & t3f1; | |
assign a398 = t1993 & ((t1994 & id08) | id_opa | id_stlda | id_lsax | id_io); | |
always @(posedge clk) | |
begin | |
if (f1) | |
begin | |
t1375 <= t2 & m4 & id_pupsw; | |
t1497 <= t3 & m5 & id_popsw; | |
t1698 <= t5 & m1 & ~id_inr & ~id_dcr | |
| t3 & m5 & id_rst; | |
t1668 <= t2 & m5 & (id_inr | id_dcr) | |
| t3 & m5 & id_dad | |
| t3 & m4 & id_dad | |
| t5 & m1 & (id_inr | id_dcr); | |
t1780 <= t3 & m1 | |
| t1 & (m4 | m5) & id_dad; | |
t2222 <= (t2 & m1) | (t1 & m5); | |
a327 <= t3 & m4 & ~(id_dad | id_out | id_rst) | |
| t2 & (m4 | m5) & id_dad; | |
a357 <= t3 & m5 & (id_io | id_mvim) & sy_wo_n | |
| t3 & m4 & (id_stlda | id_lsax | id_mvmr) & sy_wo_n | |
| acc_sel & id08 & (t5 & m1 | t3 & m4); | |
a358 <= t2 & ~sy_wo_n & (id_io | id_mvim | id_stlda | id_lsax | id_mvmr); | |
psw_ld <= t3 & m4 & id_popsw; | |
psw_wr <= t2 & m1 & (id_opi | id_inr | id_dcr | id_daa | id_op); | |
t2046 <= t2 & m5 & id_pupsw; /* | reset | t3 & m1; */ | |
// | |
// t2047 <= reset | |
// | t3 & m1 | |
// | t3 & m5 & id_rst; | |
// | |
t1993 <= t4 & m1; | |
t1994 <= acc_sel; | |
t2133 <= ~id_rxc & c[7]; | |
t2175 <= t3 & m1 | |
| t2 & m5 & id_dad; | |
end | |
end | |
always @(posedge clk) | |
begin | |
if (f2) | |
begin | |
if (alu_xwr) xr <= id_rst ? (i & 8'b00111000) : d; | |
if (alu_awr) acc <= d; | |
if (alu_ald) acc <= s; | |
if (alu_rld) r <= acc; | |
if (alu_rwr) r <= d; | |
if (alu_r00) r <= 8'hff; | |
if (daa) | |
begin | |
r[1] <= daa_x6; | |
r[2] <= daa_x6; | |
r[5] <= daa_6x; | |
r[6] <= daa_6x; | |
end | |
if (psw_ld) | |
begin | |
psw_c <= d[0]; // x register was in original Intel design | |
psw_p <= d[2]; | |
psw_ac <= d[4]; | |
psw_z <= d[6]; | |
psw_s <= d[7]; | |
end | |
if (psw_wr) | |
begin | |
psw_p <= ~(^s); | |
psw_ac <= (c[3] & ~id_xra & ~id_ora & ~id_rxc) | (id_ana & (x[3] | r[3])); | |
psw_z <= ~(|s); | |
psw_s <= s[7]; | |
end | |
if (t2222) | |
begin | |
if (id_xra | id_stc | id_ora | id_ana | id_cmc) | |
psw_c <= ~tmp_c; | |
if (id_cmp | id_sbb | id_sub) | |
psw_c <= ~(t2133 | id_rxc & x[0]); | |
if (id_dad | id_sha | id_adc | id_add) | |
psw_c <= t2133 | id_rxc & x[0]; | |
end | |
if (daa & daa_6x) | |
psw_c <= 1'b1; | |
if (t2175) | |
tmp_c <= psw_c; | |
if (t4f1) | |
begin | |
if (id_sbb) | |
tmp_c <= ~psw_c; | |
if (id_inr | id_ora | id_xra | id_ana | id_cmp | id_sub) | |
tmp_c <= 1'b1; | |
if (id_dad | id_cma | id_dcr | id_add | id_stc) | |
tmp_c <= 1'b0; | |
end | |
end | |
end | |
//______________________________________________________________________________ | |
// | |
endmodule |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment