Skip to content

Instantly share code, notes, and snippets.

@dev-zzo
Created December 22, 2014 10:54
Show Gist options
  • Save dev-zzo/f4dd7edebd09b2b323eb to your computer and use it in GitHub Desktop.
Save dev-zzo/f4dd7edebd09b2b323eb to your computer and use it in GitHub Desktop.
BM80A
//
// copyright (c) 2014 by 1801BM1@gmail.com
//______________________________________________________________________________
//
`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