dakies/OSS_Verilog huggingface dataset:
module Flags_Control (
	PHI2, X,
	T7, ZTST, n_ready, SR,
	P_DB, IR5_I, IR5_C, IR5_D, Z_V, ACR_C, DBZ_Z, DB_N, DB_P, DB_C, DB_V);

	input PHI2;

	input [129:0] X;

	input T7;
	input ZTST;
	input n_ready;
	input SR;

	output P_DB;
	output IR5_I;
	output IR5_C;
	output IR5_D;
	output Z_V;
	output ACR_C;
	output DBZ_Z;
	output DB_N;
	output DB_P;
	output DB_C;
	output DB_V;

	wire dbz_latch_q;
	wire dbn_latch_q;
	wire pin_latch_q;
	wire bit_latch_q;

	wire nARITH;
	assign nARITH = ~((X[107] & T7) | X[112] | X[116] | X[117] | X[118] | X[119]);

	dlatch pdb_latch (.d(~(X[98]|X[99])), .en(PHI2), .nq(P_DB));
	dlatch iri_latch (.d(~X[108]), .en(PHI2), .nq(IR5_I));
	dlatch irc_latch (.d(~X[110]), .en(PHI2), .nq(IR5_C));
	dlatch ird_latch (.d(~X[120]), .en(PHI2), .nq(IR5_D));
	dlatch zv_latch (.d(~X[127]), .en(PHI2), .nq(Z_V));
	dlatch acrc_latch (.d(nARITH), .en(PHI2), .nq(ACR_C));
	dlatch dbz_latch (.d(~(ACR_C|ZTST|X[109])), .en(PHI2), .q(dbz_latch_q), .nq(DBZ_Z));
	dlatch dbn_latch (.d(X[109]), .en(PHI2), .q(dbn_latch_q));
	dlatch dbc_latch (.d(~(SR|DB_P)), .en(PHI2), .nq(DB_C));
	dlatch pin_latch (.d(~(X[114]|X[115])), .en(PHI2), .q(pin_latch_q));
	dlatch bit_latch (.d(~X[113]), .en(PHI2), .q(bit_latch_q));

	assign DB_N = ~((dbz_latch_q&pin_latch_q) | dbn_latch_q);
	assign DB_P = ~(pin_latch_q | n_ready);
	assign DB_V = ~(pin_latch_q & bit_latch_q);

endmodule // Flags_Control
module DataBusBit (
	PHI1, PHI2,
	ADL, ADH, DB, DB_Ext,
	DL_ADL, DL_ADH, DL_DB,
	RD);

	input PHI1;
	input PHI2;

	inout ADL;
	inout ADH;
	inout DB;
	inout DB_Ext;

	input DL_ADL;
	input DL_ADH;
	input DL_DB;
	input RD;

	dlatch transp_latch (.d(DB_Ext), .en(1'b1), .nq(transp_latch_nq) );
	wire transp_latch_nq;
	dlatch dir_latch (.d(transp_latch_nq), .en(PHI2), .nq(dir_latch_nq) );
	wire dir_latch_nq;

	wire dir_val;
	assign dir_val = PHI1 ? dir_latch_nq : 1'bz;
	assign ADL = DL_ADL ? dir_val : 1'bz;
	assign ADH = DL_ADH ? dir_val : 1'bz;
	assign DB = DL_DB ? dir_val : 1'bz;

	dlatch int_db_latch (.d(DB), .en(1'b1), .nq(int_db_latch_nq) );
	wire int_db_latch_nq;
	dlatch dor_latch (.d(int_db_latch_nq), .en(PHI1), .nq(dor_latch_nq) );
	wire dor_latch_nq;
	bufif0 (DB_Ext, dor_latch_nq, RD);

endmodule // DataBusBit
module WRLatch (PHI1, PHI2, WR, RD);

	input PHI1;
	input PHI2;
	input WR;
	output RD;

	dlatch wr_latch (.d(WR), .en(PHI1), .nq(wr_latch_nq) );
	wire wr_latch_nq;
	wire tmp1;
	nor (tmp1, ~PHI2, wr_latch_nq);
	not (RD, tmp1);

endmodule // WRLatch
module IR (
	PHI1, PHI2,
	n_PD, FETCH,
	IR01, IR_out, n_IR_out);

	input PHI1;
	input PHI2;

	input [7:0] n_PD;
	input FETCH;

	output IR01;
	output [7:0] IR_out;
	output [7:0] n_IR_out;

	wire ena;
	and (ena, FETCH, PHI1);

	dlatch ir [7:0] (.d(n_PD), .en(ena), .q(n_IR_out), .nq(IR_out));
	or (IR01, IR_out[0], IR_out[1]);

endmodule // IR
module AddrBusBit (
	PHI1, PHI2,
	ADX, ADX_ABX,
	ABus_out);

	input PHI1;
	input PHI2;
	input ADX;
	input ADX_ABX;
	output ABus_out;

	wire n_adx = ~(ADX);
	wire abff_out;

	AddrBusFF abff (
		.phi_load(PHI1),
		.phi_keep(PHI2),
		.en(ADX_ABX),
		.val(n_adx),
		.q(abff_out));

	assign ABus_out = ~abff_out;

endmodule // AddrBusBit
module AddrBusFF (phi_load, phi_keep, en, val, q, nq);

	input phi_load;		// PHI phase during which the FF value can be modified
	input phi_keep;		// PHI phase during which the current value is "holding".
	input en;			// 1: Writing a value is enabled
	input val;			// New value
	output q;			// Current value
	output nq;			// Current value (complement)

	(* keep = "true" *) wire inp;
	not (inp, val);

	(* keep = "true" *) wire not1out;
	not(not1out, floater);

	(* keep = "true" *) wire not2out;
	not(not2out, not1out);

	(* keep = "true" *) wire floater;
	bufif1(floater, not2out, phi_keep);
	(* keep = "true" *) wire mid;
	bufif1(mid, inp, phi_load);
	bufif1(floater, mid, en);

	assign q = ~not2out;
	assign nq = not2out;

endmodule // AddrBusFF
module ExtraCounter (
	PHI1, PHI2, TRES2, n_ready, T1,
	n_T2, n_T3, n_T4, n_T5);

	input PHI1;
	input PHI2;
	input TRES2;
	input n_ready;
	input T1;

	output n_T2;
	output n_T3;
	output n_T4;
	output n_T5;

	wire t1_latch_nq;
	wire [3:0] nq;

	dlatch t1_latch (.d(T1), .en(PHI2), .nq(t1_latch_nq));

	ExtraCounter_SRBit sr [3:0] (
		.PHI1(PHI1),
		.PHI2(PHI2),
		.nd({nq[2:0],t1_latch_nq}),
		.n_EN(n_ready),
		.RES(TRES2),
		.nq(nq),
		.nsout({n_T5,n_T4,n_T3,n_T2}));

endmodule // ExtraCounter
module ExtraCounter_SRBit (PHI1, PHI2, nd, n_EN, RES, nq, nsout);

	input PHI1;
	input PHI2;
	input nd;
	input n_EN;
	input RES;
	output nq;
	output nsout;

	wire latch1_q;
	wire latch2_d;

	nor (latch2_d, latch1_q, RES);
	dlatch latch1 (.d(n_EN ? nq : nd), .en(PHI1), .q(latch1_q));
	dlatch latch2 (.d(latch2_d), .en(PHI2), .nq(nq));
	assign nsout = ~latch2_d;

endmodule // ExtraCounter_SRBit
module PreDecode (
	PHI2,
	Z_IR,
	Data_bus, n_PD,
	n_IMPLIED, n_TWOCYCLE);

	input PHI2;

	input Z_IR;

	inout [7:0] Data_bus;
	output [7:0] n_PD;

	output n_IMPLIED;
	output n_TWOCYCLE;

	// Implementation

	wire [7:0] PD;
	wire [7:0] transp_latch_nq;
	wire [7:0] PD_latch_q;
	wire implied;
	wire tmp1;
	wire tmp2;
	wire tmp3;

	dlatch transp_latch [7:0] (.d(Data_bus), .en(1'b1), .nq(transp_latch_nq));
	dlatch PD_latch [7:0] (.d(transp_latch_nq), .en(PHI2), .q(PD_latch_q));
	pnor pd_nors [7:0] (.a0(PD_latch_q), .a1(Z_IR), .x(PD));

	assign n_PD = ~PD;

	nor (implied, PD[0], PD[2], n_PD[3]);
	nor (tmp1, PD[1], PD[4], PD[7]);
	nor (tmp2, n_PD[0], PD[2], n_PD[3], PD[4]);
	nor (tmp3, PD[0], PD[2], PD[3], PD[4], n_PD[7]);

	assign n_IMPLIED = ~implied;
	assign n_TWOCYCLE = ~((implied&~tmp1)|tmp2|tmp3);

endmodule // PreDecode
module BRKProcessing (
	PHI1, PHI2,
	BRK5, n_ready, RESP, n_NMIP, BR2, T0, n_IRQP, n_IOUT,
	BRK6E, BRK7, BRK5_RDY, DORES, n_DONMI, B_OUT);

	input PHI1;
	input PHI2;

	input BRK5;
	input n_ready;
	input RESP;
	input n_NMIP;
	input BR2;
	input T0;
	input n_IRQP;
	input n_IOUT;

	output BRK6E;
	output BRK7;
	output BRK5_RDY;
	output DORES;
	output n_DONMI;
	output B_OUT;

	// BRK sequence cycles 6-7

	wire BRK5_RDY;
	and (BRK5_RDY, BRK5, ~n_ready);
	dlatch brk5_latch (.d(BRK5_RDY), .en(PHI2), .q(brk5_latch_q) );
	wire brk5_latch_q;
	wire tmp2;
	nand (tmp2, n_ready, brk6_latch1_nq);
	wire brk6_latch1_d;
	and (brk6_latch1_d, ~brk5_latch_q, tmp2);
	dlatch brk6_latch1 (.d(brk6_latch1_d), .en(PHI1), .nq(brk6_latch1_nq) );
	wire brk6_latch1_nq;
	dlatch brk6_latch2 (.d(brk6_latch1_nq), .en(PHI2), .nq(brk6_latch2) );
	wire brk6_latch2_nq;
	nor (BRK6E, brk6_latch2_nq, n_ready);
	nor (BRK7, brk6_latch1_nq, BRK5_RDY);

	// Reset FF

	wire nDORES;
	nor (nDORES, res_latch1_q, res_latch2_q);
	dlatch res_latch1 (.d(RESP), .en(PHI2), .q(res_latch1_q) );
	wire res_latch1_q;
	wire res_latch2_d;
	nor (res_latch2_d, nDORES, BRK6E);
	dlatch res_latch2 (.d(res_latch2_d), .en(PHI1), .q(res_latch2_q) );
	wire res_latch2_q;
	not (DORES, nDORES);

	// NMI Edge Detect

	wire tmp1;
	nor (tmp1, ff2_latch_q, delay_latch2_q);
	wire ff2_latch_d;
	nor (ff2_latch_d, nmip_latch_q, tmp1);
	dlatch brk7_latch (.d(BRK7), .en(PHI2), .nq(brk7_latch_nq) );
	wire brk7_latch_nq;
	wire donmi_latch_d;
	nor (donmi_latch_d, brk7_latch_nq, n_NMIP, ff2_latch_d);
	dlatch donmi_latch (.d(donmi_latch_d), .en(PHI1), .q(donmi_latch_q) );
	wire donmi_latch_q;
	dlatch nmip_latch (.d(n_NMIP), .en(PHI1), .q(nmip_latch_q) );
	wire nmip_latch_q;
	dlatch ff2_latch (.d(ff2_latch_d), .en(PHI2), .q(ff2_latch_q) );
	wire ff2_latch_q;
	dlatch delay_latch1 (.d(n_DONMI), .en(PHI2), .nq(delay_latch1_nq) );
	wire delay_latch1_nq;
	dlatch delay_latch2 (.d(delay_latch1_nq), .en(PHI1), .q(delay_latch2_q) );
	wire delay_latch2_q;
	dlatch ff1_latch (.d(n_DONMI), .en(PHI2), .q(ff1_latch_q) );
	wire ff1_latch_q;
	dlatch brk6e_latch (.d(BRK6E), .en(PHI1), .q(brk6e_latch_q) );
	wire brk6e_latch_q;
	wire nmitmp1;
	nor (nmitmp1, ff1_latch_q, brk6e_latch_q);
	nor (n_DONMI, donmi_latch_q, nmitmp1);

	// Interrupt Check

	wire intr = ~( (BR2|T0) & (~((n_IRQP|~n_IOUT)&n_DONMI)) );

	wire b_latch2_d;
	nor (b_latch2_d, b_latch1_q, BRK6E);
	dlatch b_latch2 (.d(b_latch2_d), .en(PHI1), .q(b_latch2_q) );
	wire b_latch2_q;
	wire b_latch1_d;
	and (b_latch1_d, intr, ~b_latch2_q);
	dlatch b_latch1 (.d(b_latch1_d), .en(PHI2), .q(b_latch1_q) );
	wire b_latch1_q;

	nor (B_OUT, DORES, b_latch2_d);

endmodule // BRKProcessing
module IntVector (
	PHI2, BRK5_RDY, BRK7, DORES, n_DONMI,
	Z_ADL0, Z_ADL1, Z_ADL2);

	input PHI2;
	input BRK5_RDY;
	input BRK7;
	input DORES;
	input n_DONMI;

	output Z_ADL0;
	output Z_ADL1;
	output Z_ADL2;

	dlatch zadl0_latch (.d(~BRK5_RDY), .en(PHI2), .nq(Z_ADL0) );
	wire tmp1;
	nor (tmp1, BRK7, ~DORES);
	dlatch zadl1_latch (.d(~tmp1), .en(PHI2), .nq(Z_ADL1) );
	wire zadl2_latch_d;
	nor (zadl2_latch_d, BRK7, DORES, n_DONMI);
	dlatch zadl2_latch (.d(zadl2_latch_d), .en(PHI2), .nq(zadl2_latch_nq) );
	wire zadl2_latch_nq;
	not (Z_ADL2, zadl2_latch_nq);

endmodule // IntVector
module ClkGen (PHI0, PHI1, PHI2, PHI1_topad, PHI2_topad);

	input PHI0;
	output PHI1;
	output PHI2;
	output PHI1_topad;
	output PHI2_topad;

	Phi1Gen phi1_tocore (.PHI0(PHI0), .PHI1(PHI1) );
	Phi2Gen phi2_tocore (.PHI0(PHI0), .PHI1(PHI1), .PHI2(PHI2) );

	Phi1Gen phi1_topad (.PHI0(PHI0), .PHI1(PHI1_topad) );
	Phi2Gen phi2_topad (.PHI0(PHI0), .PHI1(PHI1_topad), .PHI2(PHI2_topad) );

endmodule 	// ClkGen
module Phi1Gen (PHI0, PHI1);

	input PHI0;
	output PHI1;

	assign PHI1 = ~(~(~PHI0));

endmodule // Phi1Gen
module Phi2Gen (PHI0, PHI1, PHI2);

	input PHI0;
	input PHI1;
	output PHI2;

	wire tmp1;
	wire tmp2;
	assign tmp1 = ~PHI0 | PHI1;
	assign tmp2 = ~PHI0 & tmp1;
	assign PHI2 = ~(tmp2 ? tmp2 : tmp1);	

endmodule // Phi2Gen
module PadsLogic (
	PHI1, PHI2,
	n_NMI, n_IRQ, n_RES, n_NMIP, n_IRQP, RESP, 
	RDY, RDY_frompad, n_PRDY, 
	T1_topad, SYNC, SO, SO_frompad,
	WR_topad, RnW);

	input PHI1;
	input PHI2;
	input n_NMI;
	input n_IRQ; 
	input n_RES; 
	output n_NMIP;
	output n_IRQP; 
	output RESP;
	
	input RDY;
	output RDY_frompad;
	output n_PRDY;

	input T1_topad;
	output SYNC;

	input SO;
	output SO_frompad;

	input WR_topad;
	output RnW;

	// Implementation of logic that is located around terminals (pads)

	// Interrupt pads
	// Input inverters can act as transparent latches (since the values of external interrupt signals can be `Z`),
	// but there's probably no point in doing that, they usually put pull-ups on the outside for them anyway. 

	wire nmip_ff_q;
	int_ff nmip_ff (.PHI2(PHI2), .d(~n_NMI), .q(nmip_ff_q));
	assign n_NMIP = ~nmip_ff_q;

	wire irqp_ff_q;
	int_ff irqp_ff (.PHI2(PHI2), .d(~n_IRQ), .q(irqp_ff_q));
	dlatch irqp_latch (.d(irqp_ff_q), .en(PHI1), .nq(n_IRQP));

	wire resp_ff_nq;	// !!!
	int_ff resp_ff (.PHI2(PHI2), .d(~n_RES), .nq(resp_ff_nq));
	dlatch resp_latch (.d(resp_ff_nq), .en(PHI1), .nq(RESP));

	// Others

	assign RDY_frompad = RDY;
	wire prdy_latch1_nq;
	dlatch prdy_latch1 (.d(~RDY), .en(PHI2), .nq(prdy_latch1_nq));
	dlatch prdy_latch2 (.d(prdy_latch1_nq), .en(PHI1), .nq(n_PRDY));

	buf (SYNC, T1_topad);

	wire so_latch1_nq;
	wire so_latch2_nq;
	wire so_latch3_q;
	dlatch so_latch1 (.d(~SO), .en(PHI1), .nq(so_latch1_nq));
	dlatch so_latch2 (.d(so_latch1_nq), .en(PHI2), .nq(so_latch2_nq));
	dlatch so_latch3 (.d(so_latch2_nq), .en(PHI1), .q(so_latch3_q));
	nor (SO_frompad, so_latch3_q, so_latch1_nq);

	dlatch rw_latch (.d(WR_topad), .en(PHI1), .nq(RnW));

endmodule // PadsLogic
module int_ff (PHI2, d, q, nq);

	input PHI2; 		// 1: enable (level-triggered)
	input d;
	output q;
	output nq;

	// Cycle of two AOI-21s
	wire g0_out;
	wire g1_out;
	aoi g0 (.a0(~d), .a1(PHI2), .b(g1_out), .x(g0_out));
	aoi g1 (.a0(d), .a1(PHI2), .b(g0_out), .x(g1_out));

	assign q = g0_out;
	assign nq = g1_out;

endmodule // int_ff
module pc_notcarry (PHI2, n_carry, AD, DB, PC_AD, PC_DB, AD_PC, PC_PC, n_val, cout, pc, pcs);

	input PHI2;
	input n_carry;
	inout AD;
	inout DB;
	input PC_AD;
	input PC_DB;
	input AD_PC;
	input PC_PC;
	output n_val;
	output cout;
	output pc; 		// Not on a real chip
	output pcs;		// Not on a real chip

	wire in_latch_d;
	assign #2 in_latch_d = AD_PC ? AD : (PC_PC ? q : 1'bz);

	wire out_latch_d;
	aoi g1 (.a0(n_val), .a1(n_carry), .b(cout), .x(out_latch_d) );

	dlatch in_latch (.d(in_latch_d), .en(1'b1), .nq(n_val) ); 				// PCLS/PCHS bits
	dlatch out_latch (.d(out_latch_d), .en(PHI2), .nq(out_latch_nq) ); 		// PCL/PCH bits
	wire out_latch_nq;
	wire q;
	not (q, out_latch_nq);

	nor (cout, n_val, n_carry);

	assign DB = PC_DB ? q : 1'bz;
	assign AD = PC_AD ? q : 1'bz;
	assign pcs = ~n_val;
	assign pc = q;

endmodule // pc_notcarry
module pc_carry (PHI2, carry, AD, DB, PC_AD, PC_DB, AD_PC, PC_PC, n_val, n_cout, pc, pcs);

	input PHI2;
	input carry;
	inout AD;
	inout DB;
	input PC_AD;
	input PC_DB;
	input AD_PC;
	input PC_PC;
	output n_val;
	output n_cout;
	output pc; 		// Not on a real chip
	output pcs;		// Not on a real chip	

	wire in_latch_d;
	assign #2 in_latch_d = AD_PC ? AD : (PC_PC ? q : 1'bz);

	wire out_latch_d;
	oai g1 (.a0(val), .a1(carry), .b(n_cout), .x(out_latch_d) );

	dlatch in_latch (.d(in_latch_d), .en(1'b1), .nq(n_val) ); 			// PCLS/PCHS bits
	wire val;
	not (val, n_val);
	dlatch out_latch (.d(out_latch_d), .en(PHI2), .nq(q) ); 		// PCL/PCH bits
	wire q;

	nand (n_cout, val, carry);

	assign DB = PC_DB ? q : 1'bz;
	assign AD = PC_AD ? q : 1'bz;
	assign pcs = val;
	assign pc = q;

endmodule // pc_carry
module PC_Control (
	PHI1, PHI2,
	n_ready, T0, T1, BR0,
	X,
	PCL_DB, PCH_DB, PC_DB, PCL_ADL, PCH_ADH, PCL_PCL, ADL_PCL, n_ADL_PCL, DL_PCH, ADH_PCH, PCH_PCH, n_PCH_PCH);

	input PHI1;
	input PHI2;

	input n_ready;
	input T0;
	input T1;
	input BR0;

	input [129:0] X;

	output PCL_DB;
	output PCH_DB;
	output PC_DB;
	output PCL_ADL;
	output PCH_ADH;
	output PCL_PCL;
	output ADL_PCL;
	output n_ADL_PCL;
	output DL_PCH;
	output ADH_PCH;
	output PCH_PCH;
	output n_PCH_PCH;

	wire BR2;
	wire BR3;
	wire n_PCH_DB;
	wire n_PCL_DB;
	wire ABS_2;
	wire JB;
	wire n_PCL_ADL;
	wire n_ADL_PCL;
	wire n_ADH_PCH;
	wire n_T0;
	wire t1;
	wire t2;
	wire t3;
	wire nready_latch_q;
	wire pch_db_latch1_q;
	wire pcl_db_latch1_nq;
	wire pcl_pcl_latch_q;
	wire adl_pcl_latch_q;
	wire adh_pch_latch_q;
	wire pch_pch_latch_q;
	wire pcl_db_latch1_d;
	wire pch_adh_latch_d;

	assign BR2 = X[80];
	assign BR3 = X[93];
	not (n_T0, T0);
	nor (t1, JB, nready_latch_q);
	nor (t2, t1, n_T0);
	nor (n_PCH_DB, X[77], X[78]);
	nor (JB, X[94], X[95], X[96]);
	assign ABS_2 = X[83] & ~X[129];
	nor (n_PCL_ADL, T1, X[56], ABS_2, t2, BR2);
	nor (n_ADL_PCL, ~n_PCL_ADL, X[84], T0, BR3 & ~nready_latch_q);
	nor (n_ADH_PCH, X[84], ABS_2, T0, T1, BR2, BR3 );
	nor (DL_PCH, n_T0, JB);
	nor (pcl_db_latch1_d, pch_db_latch1_q, n_ready);
	nor (t3, n_PCL_ADL, DL_PCH, BR0);
	nor (pch_adh_latch_d, t3, BR3);
	nand (PC_DB, n_PCL_DB, n_PCH_DB);

	dlatch nready_latch (.d(n_ready), .en(PHI1), .q(nready_latch_q) );
	
	dlatch pcl_db_latch1 (.d(pcl_db_latch1_d), .en(PHI1), .nq(n_PCL_DB) );
	dlatch pch_db_latch1 (.d(n_PCH_DB), .en(PHI2), .q(pch_db_latch1_q) );
	dlatch pcl_db_latch2 (.d(n_PCL_DB), .en(PHI2), .nq(PCL_DB) );
	dlatch pch_db_latch2 (.d(n_PCH_DB), .en(PHI2), .nq(PCH_DB) );

	dlatch pcl_adl_latch (.d(n_PCL_ADL), .en(PHI2), .nq(PCL_ADL) );
	dlatch pch_adh_latch (.d(pch_adh_latch_d), .en(PHI2), .nq(PCH_ADH) );
	dlatch pcl_pcl_latch (.d(~n_ADL_PCL), .en(PHI2), .q(pcl_pcl_latch_q) );
	dlatch adl_pcl_latch (.d(n_ADL_PCL), .en(PHI2), .q(adl_pcl_latch_q) );
	dlatch adh_pch_latch (.d(n_ADH_PCH), .en(PHI2), .q(adh_pch_latch_q) );
	dlatch pch_pch_latch (.d(n_PCH_PCH), .en(PHI2), .q(pch_pch_latch_q) );

	nor (PCL_PCL, pcl_pcl_latch_q, PHI2);
	nor (ADL_PCL, adl_pcl_latch_q, PHI2);
	nor (ADH_PCH, adh_pch_latch_q, PHI2);
	nor (PCH_PCH, pch_pch_latch_q, PHI2);
	not (n_PCH_PCH, n_ADH_PCH);

endmodule // PC_Control
module Dispatch (
	PHI1, PHI2,
	BRK6E, RESP, ACR, DORES, PC_DB, RDY, B_OUT, BRFW, n_BRTAKEN, n_TWOCYCLE, n_IMPLIED, n_ADL_PCL, 
	X, 
	ACRL2, T6, T7, TRES2, STOR, Z_IR, FETCH, n_ready, WR, T1, n_T0, T0, n_T1X, n_IPC);

	input PHI1;
	input PHI2;

	input BRK6E;
	input RESP;
	input ACR;
	input DORES;
	input PC_DB;
	input RDY;
	input B_OUT;
	input BRFW;
	input n_BRTAKEN;
	input n_TWOCYCLE;
	input n_IMPLIED;
	input n_ADL_PCL;

	input [129:0] X;

	output ACRL2;
	output T6;
	output T7;
	output TRES2;
	output STOR;
	output Z_IR;
	output FETCH;
	output n_ready;
	output WR;
	output T1;
	output n_T0;
	output T0;
	output n_T1X;
	output n_IPC;

	// Implementation

	wire n_STORE;
	wire n_SHIFT;
	wire n_MemOP;
	wire STOR;
	wire REST;
	wire BR2;
	wire BR3;
	wire NotReadyPhi1;
	wire ACRL1;
	wire ENDS;
	wire n_TRESX;
	wire BRA;

	assign n_STORE = ~X[97];
	nor (n_SHIFT, X[106], X[107]);
	nor (n_MemOP, X[111], X[122], X[123], X[124], X[125]);
	nor (STOR, n_MemOP, n_STORE);
	nand (REST, n_SHIFT, n_STORE);
	assign BR2 = X[80];
	assign BR3 = X[93];

	ReadyRW ready_rw (
		.PHI1(PHI1), 
		.PHI2(PHI2), 
		.RDY(RDY), 
		.STOR(STOR), 
		.PC_DB(PC_DB), 
		.D98(X[98]), 
		.D100(X[100]), 
		.T6(T6), 
		.T7(T7), 
		.DORES(DORES), 
		.n_ready(n_ready), 
		.NotReadyPhi1(NotReadyPhi1), 
		.WR(WR) );

	ACRLatch acrl (
		.PHI1(PHI1), 
		.PHI2(PHI2), 
		.ACR(ACR), 
		.NotReadyPhi1(NotReadyPhi1), 
		.ACRL1(ACRL1), 
		.ACRL2(ACRL2) );

	RMWCycle rmw (
		.PHI1(PHI1), 
		.PHI2(PHI2), 
		.n_ready(n_ready), 
		.n_SHIFT(n_SHIFT), 
		.n_MemOP(n_MemOP), 
		.T6(T6), 
		.T7(T7) );

	TwoCycle twocyc (
		.PHI1(PHI1), 
		.PHI2(PHI2), 
		.n_ready(n_ready), 
		.RESP(RESP), 
		.ENDS(ENDS), 
		.n_TWOCYCLE(n_TWOCYCLE), 
		.n_TRESX(n_TRESX),
		.BRA(BRA),
		.T0(T0), 
		.T1(T1), 
		.n_T0(n_T0), 
		.n_T1X(n_T1X) );

	CompletionUnit comp_unit (
		.PHI1(PHI1), 
		.PHI2(PHI2), 
		.n_ready(n_ready), 
		.ACRL1(ACRL1), 
		.REST(REST), 
		.BRK6E(BRK6E), 
		.RESP(RESP), 
		.n_SHIFT(n_SHIFT), 
		.n_MemOP(n_MemOP), 
		.X(X), 
		.T0(T0), 
		.T1(T1), 
		.T7(T7), 
		.n_BRTAKEN(n_BRTAKEN), 
		.BR2(BR2), 
		.BR3(BR3), 
		.TRES2(TRES2), 
		.n_TRESX(n_TRESX), 
		.ENDS(ENDS) );

	IncrementPC incpc (
		.PHI1(PHI1), 
		.PHI2(PHI2), 
		.B_OUT(B_OUT), 
		.NotReadyPhi1(NotReadyPhi1), 
		.BRFW(BRFW), 
		.ACR(ACR), 
		.n_ready(n_ready), 
		.n_BRTAKEN(n_BRTAKEN), 
		.n_ADL_PCL(n_ADL_PCL), 
		.n_IMPLIED(n_IMPLIED), 
		.BR2(BR2),
		.BR3(BR3),
		.BRA(BRA), 
		.n_IPC(n_IPC) );

	FetchUnit fetch_unit (
		.PHI2(PHI2), 
		.B_OUT(B_OUT), 
		.T1(T1), 
		.n_ready(n_ready), 
		.Z_IR(Z_IR), 
		.FETCH(FETCH) );

endmodule // Dispatch
module ReadyRW (PHI1, PHI2, RDY, STOR, PC_DB, D98, D100, T6, T7, DORES, n_ready, NotReadyPhi1, WR);

	input PHI1;
	input PHI2;
	input RDY;
	input STOR;
	input PC_DB;
	input D98;
	input D100;
	input T6;
	input T7;
	input DORES;
	output n_ready;
	output NotReadyPhi1;
	output WR;

	wire wr_latch_d;
	wire wr_latch_q;
	wire ready_latch1_d;
	wire ready_latch1_nq;
	wire ready_latch2_q;
	wire rdydelay_latch1_nq;

	nor (wr_latch_d, STOR, PC_DB, D98, D100, T6, T7);
	nor (ready_latch1_d, RDY, ready_latch2_q);
	nor (WR, n_ready, wr_latch_q, DORES);

	dlatch wr_latch (.d(wr_latch_d), .en(PHI2), .q(wr_latch_q));
	dlatch ready_latch1 (.d(ready_latch1_d), .en(PHI2), .nq(ready_latch1_nq));
	dlatch ready_latch2 (.d(WR), .en(PHI1), .q(ready_latch2_q));
	dlatch rdydelay_latch1 (.d(n_ready), .en(PHI1), .nq(rdydelay_latch1_nq));
	dlatch rdydelay_latch2 (.d(rdydelay_latch1_nq), .en(PHI2), .nq(NotReadyPhi1));

	assign n_ready = ~ready_latch1_nq;

endmodule // ReadyRW
module ACRLatch (PHI1, PHI2, ACR, NotReadyPhi1, ACRL1, ACRL2);

	input PHI1;
	input PHI2;
	input ACR;
	input NotReadyPhi1;
	output ACRL1;
	output ACRL2;

	wire acr_latch1_nq;
	wire ReadyPhi1;
	wire t1;
	wire t2;

	assign ReadyPhi1 = ~NotReadyPhi1;
	and (t1, ~ACR, ReadyPhi1);
	nor (t2, ReadyPhi1, ACRL2);
	nor (ACRL1, t1, t2);

	dlatch acr_latch1 (.d(ACRL1), .en(PHI1), .nq(acr_latch1_nq));
	dlatch acr_latch2 (.d(acr_latch1_nq), .en(PHI2), .nq(ACRL2));

endmodule // ACRLatch
module TwoCycle (PHI1, PHI2, n_ready, RESP, ENDS, n_TWOCYCLE, n_TRESX, BRA, T0, T1, n_T0, n_T1X);

	input PHI1;
	input PHI2;
	input n_ready;
	input RESP;
	input ENDS;
	input n_TWOCYCLE;
	input n_TRESX;
	input BRA;
	output T0;
	output T1;
	output n_T0;
	output n_T1X;

	wire nready_latch_q;
	wire step_latch1_d;
	wire step_latch1_q;
	wire step_latch2_d;
	wire step_latch2_q;
	wire t2;
	wire t1_latch_d;
	wire TRES1;

	nor (step_latch1_d, RESP, nready_latch_q, step_latch2_q);
	nor (step_latch2_d, step_latch1_q, BRA);
	nor (t2, step_latch2_d, n_ready);
	nor (t1_latch_d, t2, ENDS);
	assign TRES1 = ~t1_latch_d;

	dlatch nready_latch (.d(~n_ready), .en(PHI1), .q(nready_latch_q));
	dlatch step_latch1 (.d(step_latch1_d), .en(PHI2), .q(step_latch1_q));
	dlatch step_latch2 (.d(step_latch2_d), .en(PHI1), .q(step_latch2_q));
	dlatch t1_latch (.d(t1_latch_d), .en(PHI1), .nq(T1));
	
	wire comp_latch1_q;
	wire comp_latch2_q;
	wire comp_latch3_q;
	wire t3;
	wire t4;
	wire t0_latch_q;
	wire t1x_latch_q;
	wire t1x_latch_d;

	nor (t3, comp_latch1_q, comp_latch2_q & comp_latch3_q);
	nor (t4, t0_latch_q, t1x_latch_q);
	nor (n_T0, t3, t4);
	assign T0 = ~n_T0;
	nor (t1x_latch_d, t0_latch_q, n_ready);

	dlatch comp_latch1 (.d(TRES1), .en(PHI1), .q(comp_latch1_q));
	dlatch comp_latch2 (.d(n_TWOCYCLE), .en(PHI1), .q(comp_latch2_q));
	dlatch comp_latch3 (.d(n_TRESX), .en(PHI1), .q(comp_latch3_q));
	dlatch t0_latch (.d(n_T0), .en(PHI2), .q(t0_latch_q));
	dlatch t1x_latch (.d(t1x_latch_d), .en(PHI1), .q(t1x_latch_q), .nq(n_T1X));

endmodule // TwoCycle
module RMWCycle (PHI1, PHI2, n_ready, n_SHIFT, n_MemOP, T6, T7);

	input PHI1;
	input PHI2;
	input n_ready;
	input n_SHIFT;
	input n_MemOP;
	output T6;
	output T7;

	wire t67_latch_d;
	wire t67_latch_q;
	wire t6_latch1_d;
	wire t6_latch2_q;
	wire t7_latch1_d;
	wire t7_latch1_nq;
	wire t7_latch2_nq;

	nor (t67_latch_d, n_SHIFT, n_MemOP, n_ready);
	nor (t6_latch1_d, t67_latch_q, t6_latch2_q & n_ready);
	nand (t7_latch1_d, T6, ~n_ready);

	dlatch t67_latch (.d(t67_latch_d), .en(PHI2), .q(t67_latch_q));
	dlatch t6_latch1 (.d(t6_latch1_d), .en(PHI1), .nq(T6));
	dlatch t6_latch2 (.d(T6), .en(PHI2), .q(t6_latch2_q));
	dlatch t7_latch1 (.d(t7_latch1_d), .en(PHI2), .nq(t7_latch1_nq));
	dlatch t7_latch2 (.d(t7_latch1_nq), .en(PHI1), .nq(t7_latch2_nq));

	assign T7 = ~t7_latch2_nq;

endmodule // RMWCycle
module CompletionUnit (PHI1, PHI2, n_ready, ACRL1, REST, BRK6E, RESP, n_SHIFT, n_MemOP, X, T0, T1, T7, n_BRTAKEN, BR2, BR3, TRES2, n_TRESX, ENDS);

	input PHI1;
	input PHI2;
	input n_ready;
	input ACRL1;
	input REST;
	input BRK6E;
	input RESP;
	input n_SHIFT;
	input n_MemOP;
	input [129:0] X;
	input T0;
	input T1;
	input T7;
	input n_BRTAKEN;
	input BR2;
	input BR3;
	output TRES2;
	output n_TRESX;
	output ENDS;

	wire tresx_latch1_q;
	wire tresx_latch1_d;
	wire tresx_latch2_nq;
	wire tresx_latch2_d;
	wire ends_latch1_q;
	wire ends_latch1_d;
	wire ends_latch2_q;
	wire t1;
	wire t2;
	wire t3;
	wire t4;
	wire ENDX;
	wire t5;

	nor (tresx_latch1_d, X[91], X[92]);
	nor (t1, ACRL1, tresx_latch1_q, n_ready, REST);
	nor (n_TRESX, t1, BRK6E, tresx_latch2_nq);

	nor (t2, X[96], ~n_SHIFT, n_MemOP);
	nor (t3, X[100], X[101], X[102], X[103], X[104], X[105]);
	nor (ENDX, t2, T7, ~t3, BR3);
	nor (t4, n_ready, ENDX);
	nor (tresx_latch2_d, RESP, ENDS, t4);

	nor (t5, T0, n_BRTAKEN & BR2);
	assign ends_latch1_d = n_ready ? ~T1 : t5;

	dlatch tresx_latch1 (.d(tresx_latch1_d), .en(PHI2), .q(tresx_latch1_q));
	dlatch tresx_latch2 (.d(tresx_latch2_d), .en(PHI2), .nq(tresx_latch2_nq));
	dlatch tres2_latch (.d(n_TRESX), .en(PHI1), .nq(TRES2));
	dlatch ends_latch1 (.d(ends_latch1_d), .en(PHI2), .q(ends_latch1_q));
	dlatch ends_latch2 (.d(RESP), .en(PHI2), .q(ends_latch2_q));

	nor (ENDS, ends_latch1_q, ends_latch2_q);

endmodule // CompletionUnit
module IncrementPC (PHI1, PHI2, B_OUT, NotReadyPhi1, BRFW, ACR, n_ready, n_BRTAKEN, n_ADL_PCL, n_IMPLIED, BR2, BR3, BRA, n_IPC);

	input PHI1;
	input PHI2;
	input B_OUT;
	input NotReadyPhi1;
	input BRFW;
	input ACR;
	input n_ready;
	input n_BRTAKEN;
	input n_ADL_PCL;
	input n_IMPLIED;
	input BR2;
	input BR3;
	output BRA;
	output n_IPC;

	wire br_latch2_d;
	wire br_latch2_nq;
	wire br_latch1_q;
	wire br_latch1_d;
	wire ipc_latch1_q;
	wire ipc_latch2_q;
	wire ipc_latch3_q;
	wire ipc_latch3_d;
	wire t1;
	wire t2;

	nor (br_latch2_d, ~BR3, NotReadyPhi1);
	xor (t1, BRFW, ~ACR);
	and (BRA, t1, ~br_latch2_nq);
	nor (t2, n_ADL_PCL, BR2 | BR3);
	nor (br_latch1_d, t2, n_BRTAKEN & BR2);
	nor (ipc_latch3_d, n_ready, br_latch1_q, ~n_IMPLIED);

	dlatch br_latch2 (.d(br_latch2_d), .en(PHI2), .nq(br_latch2_nq));
	dlatch br_latch1 (.d(br_latch1_d), .en(PHI2), .q(br_latch1_q));
	dlatch ipc_latch1 (.d(B_OUT), .en(PHI1), .q(ipc_latch1_q));
	dlatch ipc_latch2 (.d(BRA), .en(PHI1), .q(ipc_latch2_q));
	dlatch ipc_latch3 (.d(ipc_latch3_d), .en(PHI1), .q(ipc_latch3_q));

	nand (n_IPC, ipc_latch1_q, ipc_latch2_q | ipc_latch3_q);

endmodule // IncrementPC
module FetchUnit (PHI2, B_OUT, T1, n_ready, Z_IR, FETCH);

	input PHI2;
	input B_OUT;
	input T1;
	input n_ready;
	output Z_IR;
	output FETCH;

	wire fetch_latch_nq;

	dlatch fetch_latch (.d(T1), .en(PHI2), .nq(fetch_latch_nq));

	nor (FETCH, fetch_latch_nq, n_ready);
	nand (Z_IR, FETCH, B_OUT);

endmodule // FetchUnit
module Regs (
	PHI2,
	Y_SB, SB_Y, X_SB, SB_X, S_SB, S_ADL, S_S, SB_S, 
	SB, ADL);

	input PHI2;

	input Y_SB;
	input SB_Y;
	input X_SB;
	input SB_X;
	input S_SB;
	input S_ADL;
	input S_S;  		// Stack reg -> Shadow Stack reg
	input SB_S;

	inout [7:0] SB;
	inout [7:0] ADL;

	XYRegBit yreg[7:0] (.PHI2(PHI2), .Reg_SB(Y_SB), .SB_Reg(SB_Y), .SB_bit(SB), .dbg(y) );
	XYRegBit xreg[7:0] (.PHI2(PHI2), .Reg_SB(X_SB), .SB_Reg(SB_X), .SB_bit(SB), .dbg(x) );
	SRegBit sreg[7:0] (.PHI2(PHI2), .S_SB(S_SB), .S_ADL(S_ADL), .SB_S(SB_S), .S_S(S_S), .SB_bit(SB), .ADL_bit(ADL), .S_dbg(s), .SS_dbg(ss) );

	// Debug. Not on a real chip

	wire [7:0] x, y, ss, s;

endmodule // Regs
module XYRegBit (PHI2, Reg_SB, SB_Reg, SB_bit, dbg);

	input PHI2;
	input Reg_SB;
	input SB_Reg;
	inout SB_bit;
	output dbg; 			// Not on a real chip

	wire d;
	assign d = SB_Reg ? SB_bit : (PHI2 ? not_nq : 1'bz);

	wire hold_latch_nq;
	wire not_nq;
	dlatch hold_latch (.d(d), .en(1'b1), .q(dbg), .nq(hold_latch_nq));
	not (not_nq, hold_latch_nq);

	assign SB_bit = Reg_SB ? not_nq : 1'bz;

endmodule // XYRegBit
module SRegBit (PHI2, S_SB, S_ADL, SB_S, S_S, SB_bit, ADL_bit, S_dbg, SS_dbg);

	input PHI2;
	input S_SB;
	input S_ADL;
	input SB_S;
	input S_S;
	inout SB_bit;
	inout ADL_bit;
	output S_dbg; 		// Not on a real chip
	output SS_dbg; 		// Not on a real chip

	wire d;
	assign d = SB_S ? SB_bit : (S_S ? out_latch_nq : 1'bz);

	wire in_latch_nq;
	wire out_latch_nq;
	dlatch in_latch (.d(d), .en(1'b1), .q(SS_dbg), .nq(in_latch_nq)); 		// Shadow Stack reg
	dlatch out_latch (.d(in_latch_nq), .en(PHI2), .nq(out_latch_nq)); 		// Stack reg
	assign S_dbg = out_latch_nq;

	assign SB_bit = S_SB ? out_latch_nq : 1'bz;
	assign ADL_bit = S_ADL ? out_latch_nq : 1'bz;

endmodule // SRegBit
module Regs_Control (
	PHI1, PHI2, 
	STOR, n_ready, 
	X,
	STXY, n_SBXY, STKOP, 
	Y_SB, X_SB, S_SB, SB_X, SB_Y, SB_S, S_S, S_ADL);

	input PHI1;
	input PHI2;

	input STOR;
	input n_ready;

	input [129:0] X;

	output STXY;
	output n_SBXY;
	output STKOP;

	output Y_SB;
	output X_SB;
	output S_SB;
	output SB_X;
	output SB_Y;
	output SB_S;
	output S_S;
	output S_ADL;

	wire nYSB;
	wire nXSB;
	wire nSBX;
	wire nSBY;
	wire nSBS;
	wire nSADL;
	wire tmp1;

	wire nready_latch_q;
	wire nready_latch_nq;
	wire ysb_latch_q;
	wire xsb_latch_q;
	wire sbx_latch_q;
	wire sby_latch_q;
	wire sbs_latch_q;
	wire ss_latch_q;

	assign nYSB = ~(X[1] | X[2] | X[3] | X[4] | X[5] | (X[6]&X[7]) | (X[0]&STOR));
	assign nXSB = ~(X[8] | X[9] | X[10] | X[11] | X[13] | (X[6]&~X[7]) | (X[12]&STOR));
	assign nSBX = ~(X[14] | X[15] | X[16]);
	assign nSBY = ~(X[18] | X[19] | X[20]);
	assign tmp1 = ~(X[21] | X[22] | X[23] | X[24] | X[25] | X[26]);
	assign nSBS = ~(X[13] | ~(~X[48]|n_ready) | STKOP);
	assign nSADL = ~((X[21]&nready_latch_nq) | X[35]);

	assign STXY = ~((X[0]&STOR) | (X[12]&STOR));
	assign n_SBXY = ~(nSBX & nSBY);
	assign STKOP = ~(tmp1|nready_latch_q);

	dlatch nready_latch (.d(n_ready), .en(PHI1), .q(nready_latch_q), .nq(nready_latch_nq));
	dlatch ysb_latch (.d(nYSB), .en(PHI2), .q(ysb_latch_q));
	dlatch xsb_latch (.d(nXSB), .en(PHI2), .q(xsb_latch_q));
	dlatch ssb_latch (.d(~X[17]), .en(PHI2), .nq(S_SB));
	dlatch sbx_latch (.d(nSBX), .en(PHI2), .q(sbx_latch_q));
	dlatch sby_latch (.d(nSBY), .en(PHI2), .q(sby_latch_q));
	dlatch sbs_latch (.d(nSBS), .en(PHI2), .q(sbs_latch_q));
	dlatch ss_latch (.d(~nSBS), .en(PHI2), .q(ss_latch_q));
	dlatch sadl_latch (.d(nSADL), .en(PHI2), .nq(S_ADL));

	assign Y_SB = ~(ysb_latch_q|PHI2);
	assign X_SB = ~(xsb_latch_q|PHI2);
	assign SB_X = ~(sbx_latch_q|PHI2);
	assign SB_Y = ~(sby_latch_q|PHI2);
	assign SB_S = ~(sbs_latch_q|PHI2);
	assign S_S = ~(ss_latch_q|PHI2);

endmodule  // Regs_Control
module bcd_nibble (daa, dsa, sb, bcd, b1, b2);

	input daa;
	input dsa;
	input [3:0] sb;
	output [3:0] bcd;
	input b1;
	input b2;

	assign bcd[0] = sb[0];
	xor (bcd[1], ~(daa|dsa), ~sb[1]);
	xor (bcd[2], ((~(b1&daa)) & (~(~b1&dsa))), ~sb[2]);
	wire t1, t2;
	nand (t1, b1, b2);
	nor (t2, b1, b2);
	xor (bcd[3], ((~(t1&daa)) & (~(~t2&dsa))), ~sb[3]);

endmodule // bcd_nibble
module ROR_Unit (PHI1, PHI2, n_COUT, n_ready, SR, n_ROR, nADDSB7);

	input PHI1;
	input PHI2;
	input n_COUT;
	input n_ready;
	input SR;
	input n_ROR;
	output nADDSB7;

	wire cout_latch_nq;
	wire nready_latch_q;
	wire mux_latch1_q;
	wire ff_latch1_nq;
	wire ff_latch2_q;
	wire sr_latch1_nq;
	wire sr_latch2_q;

	wire mux_latch_in;
	nor (mux_latch_in, nready_latch_q, ~SR);

	wire ff1_d;
	assign ff1_d = ~(mux_latch1_q ? cout_latch_nq : ff_latch2_q);

	dlatch cout_latch (.d(~n_COUT), .en(PHI2), .nq(cout_latch_nq));
	dlatch nready_latch (.d(n_ready), .en(PHI1), .q(nready_latch_q));
	dlatch mux_latch1 (.d(mux_latch_in), .en(PHI2), .q(mux_latch1_q));
	dlatch ff_latch1 (.d(ff1_d), .en(PHI1), .nq(ff_latch1_nq));
	dlatch ff_latch2 (.d(ff_latch1_nq), .en(PHI2), .q(ff_latch2_q));
	dlatch sr_latch1 (.d(SR), .en(PHI2), .nq(sr_latch1_nq));
	dlatch sr_latch2 (.d(sr_latch1_nq), .en(PHI1), .q(sr_latch2_q));

	nor (nADDSB7, ff_latch1_nq, sr_latch2_q, n_ROR);

endmodule // ROR_Unit
module BranchLogic (
	PHI1, PHI2,
	n_IR5, X, n_COUT, n_VOUT, n_NOUT, n_ZOUT, DB, BR2,
	n_BRTAKEN, BRFW);

	input PHI1;
	input PHI2;

	input n_IR5;
	input [129:0] X;
	input n_COUT;
	input n_VOUT;
	input n_NOUT;
	input n_ZOUT;
	inout [7:0] DB;
	input BR2;

	output n_BRTAKEN;
	output BRFW;

	// Branch forward

	wire br2_latch_q;
	wire br2_latch_nq;
	wire brfw_latch1_nq;
	wire brfw_latch2_q;
	wire brfw_latch1_d;

	dlatch br2_latch (.d(BR2), .en(PHI2), .q(br2_latch_q), .nq(br2_latch_nq));
	nor (brfw_latch1_d, br2_latch_q & ~DB[7], br2_latch_nq & brfw_latch2_q);
	dlatch brfw_latch1 (.d(brfw_latch1_d), .en(PHI1), .nq(brfw_latch1_nq));
	dlatch brfw_latch2 (.d(brfw_latch1_nq), .en(PHI2), .q(brfw_latch2_q));
	not (BRFW, brfw_latch1_nq);

	// Branch taken

	wire n_IR6;
	wire IR6;
	wire n_IR7;
	wire IR7;
	assign n_IR6 = X[121];
	assign n_IR7 = X[126];
	not (IR6, n_IR6);
	not (IR7, n_IR7);

	// The flag test logic is a 2-4 multiplexer

	wire ctest;
	wire vtest;
	wire ntest;
	wire ztest;

	nor (ctest, IR6, n_IR7, n_COUT);
	nor (vtest, n_IR6, IR7, n_VOUT);
	nor (ntest, IR6, IR7, n_NOUT);
	nor (ztest, n_IR6, n_IR7, n_ZOUT);

	wire mux_out;
	nor (mux_out, ctest, vtest, ntest, ztest);

	xor (n_BRTAKEN, mux_out, n_IR5);

endmodule // BranchLogic
module AclkGenStandalone (CLK, RES, PHI1, ACLK1, nACLK2);

	input CLK; 
	input RES; 
	output PHI1;			// Sometimes it is required from the outside (triangle channel for example)
	output ACLK1;
	output nACLK2; 

	wire PHI0;
	wire PHI2;

	// The ACLK pattern requires all of these "spares".

	CLK_Divider div (
		.n_CLK_frompad(~CLK),
		.PHI0_tocore(PHI0));

	BogusCorePhi phi (.PHI0(PHI0), .PHI1(PHI1), .PHI2(PHI2));

	ACLKGen clkgen (
		.PHI1(PHI1),
		.PHI2(PHI2),
		.nACLK2(nACLK2),
		.ACLK1(ACLK1),
		.RES(RES));	

endmodule // AclkGenStandalone
module BogusCorePhi (PHI0, PHI1, PHI2);
	
	input PHI0;
	output PHI1;
	output PHI2;

	assign PHI1 = ~PHI0;
	assign PHI2 = PHI0;

endmodule // BogusCorePhi
module BogusLFO (CLK, RES, nACLK2, LFO);
	
	input CLK;
	input RES;
	input nACLK2;
	output reg LFO; 		// inverse polarity (0: LFO triggers)
	reg [1:0] cnt;
	wire [1:0] n_cnt;
	wire all_ones;

	initial begin
		cnt <= 0;
	end
	always @ (negedge nACLK2) begin
		cnt <= cnt + 1;
		LFO <= all_ones && ~RES ? 1'b0 : 1'b1;
	end
	always @ (posedge CLK)
		LFO <= 1'b1;

	assign n_cnt = ~cnt;
	nor (all_ones, n_cnt[0], n_cnt[1]);

endmodule // BogusLFO
module AUX (AUX_A, AUX_B, AOut, BOut);

	input [7:0] AUX_A;			// Digital input AUX A {SQB[3:0],SQA[3:0]}
	input [14:0] AUX_B;			// Digital input AUX B {DMC[6:0],RND[3:0],TRI[3:0]}
	output [31:0] AOut; 		// Analog output AUX A (float)
	output [31:0] BOut;			// Analog output AUX B (float)

	reg [31:0] auxa_rom [0:255];
	reg [31:0] auxb_rom [0:32767];

	initial begin
		$readmemh("auxa.mem", auxa_rom);
		$readmemh("auxb.mem", auxb_rom);
	end

	assign AOut = auxa_rom[AUX_A];
	assign BOut = auxb_rom[AUX_B];

endmodule // AUX
module AUX_Dumper (addr, val);

	input [23:0] addr;
	input [31:0] val;

	reg [31:0] mem [0:16777215];
	integer i;

	initial begin
		for (i = 0; i<16777216; i=i+1) begin
			mem[i] = 32'h00000000;
		end
	end

	always @(*) mem[addr] = val;

endmodule
module TestCounters_Run();

	reg CLK;
	reg DownCount;

	always #25 CLK = ~CLK;

	UpCounterTest up_counter (.CLK(CLK));
	DownCounterTest down_counter (.CLK(CLK));
	RevCounterTest rev_counter (.CLK(CLK), .DownCount(DownCount));

	initial begin

		CLK <= 1'b0;

		$dumpfile("test_counters.vcd");
		$dumpvars(0, up_counter);
		$dumpvars(1, down_counter);
		$dumpvars(2, rev_counter);

		DownCount <= 1'b0;
		repeat (256) @ (posedge CLK);

		DownCount <= 1'b1;
		repeat (256) @ (posedge CLK);

		$finish;
	end

endmodule // TestCounters_Run
module UpCounterTest(CLK);
	input CLK;

	wire [7:0] carry_chain;
	wire [7:0] q;

	CounterBit cnt [7:0] (
		.ACLK1(~CLK),
		.clear(1'b0),
		.step(CLK),
		.load(1'b0),
		.q(q),
		.cin({carry_chain[6:0], 1'b1}),
		.cout(carry_chain) );

endmodule // UpCounterTest
module DownCounterTest(CLK);
	input CLK;

	wire [7:0] carry_chain;
	wire [7:0] q;

	DownCounterBit cnt [7:0] (
		.ACLK1(~CLK),
		.clear(1'b0),
		.step(CLK),
		.load(1'b0),
		.q(q),
		.cin({carry_chain[6:0], 1'b1}),
		.cout(carry_chain) );

endmodule // UpCounterTest
module RevCounterTest(CLK, DownCount);
	input CLK;
	input DownCount;

	wire [7:0] carry_chain;
	wire [7:0] q;

	RevCounterBit cnt [7:0] (
		.ACLK1(~CLK),
		.clear(1'b0),
		.step(CLK),
		.load(1'b0),
		.q(q),
		.dec(DownCount),
		.cin({carry_chain[6:0], 1'b1}),
		.cout(carry_chain) );

endmodule // UpCounterTest
module Core6502 (n_NMI, n_IRQ, n_RES, PHI0, PHI1, PHI2, RDY, SO, RnW, SYNC, A, D);

	input n_NMI;		// Non-maskable interrupt signal, active low
	input n_IRQ;		// Maskable interrupt signal, active low
	input n_RES;		// Reset signal, active low
	input PHI0;			// Reference clock signal
	output PHI1;		// First half-cycle, processor in `Set RW / Address` mode
	output PHI2;		// Second half-cycle, processor in `Read/Write Data` mode
	input RDY;			// Processor Ready (1: ready)
	input SO;			// Forced setting of the overflow flag (V)
	output RnW;			// Data bus direction (R/W=1: processor reads data, R/W=0: processor writes)
	output SYNC;		// The processor is on cycle T1 (opcode fetch)
	output [15:0] A;	// Address bus
	inout [7:0] D; 		// Data bus (bidirectional)

	assign PHI1 = ~PHI0;
	assign PHI2 = PHI0;
	assign SYNC = 1'b0;

	reg [31:0] regdump_rom [0:32767];
	wire [23:0] regdump_addr;

	initial begin
		$readmemh("regdump.mem", regdump_rom);
	end

	RegDumpProcessor rp (
		.PHI0(PHI0), 
		.n_RES(n_RES),
		.RnW(RnW), 
		.addr_bus(A), 
		.data_bus(D),
		.regdump_data(regdump_rom[regdump_addr]), 
		.regdump_addr(regdump_addr) );

endmodule // Core6502
module RegDumpProcessor (PHI0, n_RES, RnW, addr_bus, data_bus, regdump_data, regdump_addr);

	input PHI0; 						// Core PHI0
	input n_RES; 						// Core #RES
	output RnW; 						// Core R/W
	output [15:0] addr_bus; 			// Core address bus
	inout [7:0] data_bus; 				// Core data bus
	input [31:0] regdump_data; 			// Data bus for external asynchronous memory where registers dump is stored (`APULogEntry` entries)
	output [23:0] regdump_addr; 		// Address bus for external asynchronous memory

	reg [31:0] phi_dec_cnt; 			// PHI delta down-counter
	reg [31:0] delta_phi_word; 			// word[0] from regdump
	reg [31:0] regop_word; 				// word[1] from regdump
	reg cnt_ovf_reg;
	reg [31:0] addr_cnt; 		// negedge
	wire cntz; 				// 1: Counter is zero
	wire deltanz; 			// 1: Delta PHI is NOT zero
	wire inc_address; 		// 1: Increment addr_cnt

	wire DoRegOp; 			// 1: Issue register operation
	wire LoadPhiCounter;	// 1: Reload PHI decrement counter
	wire [15:0] RegAddress;
	wire [7:0] RegValue; 	// if write
	wire ReadMode; 			// 1: read register

	initial begin
		phi_dec_cnt <= 0;
		delta_phi_word <= 0;
		regop_word <= 0;
		cnt_ovf_reg <= 0;
		addr_cnt <= 0;
	end

	// Counter + control words

	always @(posedge PHI0) begin
		delta_phi_word <= regdump_data;
		if (LoadPhiCounter) regop_word <= 0;
		if (LoadPhiCounter) phi_dec_cnt <= regdump_data >= 2 ? regdump_data - 2 : 0; 	// Take into account 2 cycles on the RegDump logic
		else if (n_RES) phi_dec_cnt <= phi_dec_cnt - 1;
		cnt_ovf_reg <= cntz;
	end

	assign cntz = phi_dec_cnt == 0;
	assign LoadPhiCounter = cnt_ovf_reg & n_RES;
	assign deltanz = delta_phi_word != 0;
	assign DoRegOp = (PHI0 & deltanz & cntz & ~LoadPhiCounter & n_RES);
	assign inc_address = DoRegOp | LoadPhiCounter;

	always @(posedge DoRegOp) begin
		regop_word <= regdump_data;
	end

	always @(negedge inc_address) begin
		if (n_RES) addr_cnt <= addr_cnt + 1;
	end

	// RegOp

	assign RegAddress = 'h4000 | ({11'b0, regop_word[4:0]});
	assign RegValue = regop_word[15:8];
	assign ReadMode = regop_word[7];

	// Default core mode: read address 0

	assign RnW = DoRegOp ? ReadMode : 1'b1;
	assign addr_bus = DoRegOp ? RegAddress : 16'b0;
	assign data_bus = (DoRegOp & ~ReadMode) ? RegValue : 8'bz;
	
	assign regdump_addr = addr_cnt;

endmodule // RegDumpProcessor
module VidOut_Run ();

	reg CLK;
	reg RES;

	wire PCLK;
	wire n_PCLK;

	wire [8:0] HCnt;
	wire [8:0] VCnt;
	wire [23:0] HDecoder_out;
	wire [9:0] VDecoder_out;

	wire HC;
	wire VC;
	wire V_IN;
	wire VB;
	wire BLNK;

	// Tune CLK/PCLK timing according to 2C02/2C07
`ifdef RP2C02
	always #23.28 CLK = ~CLK;
`elsif RP2C07
	always #18.79 CLK = ~CLK;
`else
	always #1 CLK = ~CLK;
`endif

	PixelClock pclk (
		.n_CLK(~CLK), .CLK(CLK), .RES(RES),
		.n_PCLK(n_PCLK), .PCLK(PCLK) );

	HVCounters hv (
		.n_PCLK(n_PCLK), .PCLK(PCLK),
		.RES(RES), .HC(HC), .VC(VC), .V_IN(V_IN),
		.H_out(HCnt), .V_out(VCnt) );

	HVDecoder dec (
		.H_in(HCnt), .V_in(VCnt), .VB(VB), .BLNK(BLNK),
		.HPLA_out(HDecoder_out), .VPLA_out(VDecoder_out) );

	// VideoGen

	wire [10:0] RawVOut;

	VideoGen vidgen (
		.n_CLK(~CLK), .CLK(CLK), .n_PCLK(n_PCLK), .PCLK(PCLK), 
		.RES(RES),
		.n_CC(4'b0100), .n_LL(2'b00),
		.BURST(1'b0), .SYNC(1'b0), .n_PICTURE(1'b0), 
		.n_TR(1'b0), .n_TG(1'b0), .n_TB(1'b0), 
`ifdef RP2C07
		.V0(VCnt[0]),
`endif
		.RawVOut(RawVOut) );

	initial begin

		$dumpfile("vidout_test.vcd");
		$dumpvars(0, VidOut_Run);

		CLK <= 1'b0;
		RES <= 1'b0;

		// Run the number of cycles

		repeat (1000) @ (posedge CLK);
		$finish;
	end

endmodule // VidOut_Run
module FSM_Run ();

	reg CLK;
	reg RES;

	wire PCLK;
	wire n_PCLK;

	wire [8:0] HCnt;
	wire [8:0] VCnt;
	wire [23:0] HDecoder_out;
	wire [9:0] VDecoder_out;

	wire HC;
	wire VC;
	wire V_IN;
	wire VB;
	wire BLNK;

	// Tune CLK/PCLK timing according to 2C02/2C07
`ifdef RP2C02
	always #23.28 CLK = ~CLK;
`elsif RP2C07
	always #18.79 CLK = ~CLK;
`else
	always #1 CLK = ~CLK;
`endif

	PixelClock pclk (
		.n_CLK(~CLK), .CLK(CLK), .RES(RES),
		.n_PCLK(n_PCLK), .PCLK(PCLK) );

	HVCounters hv (
		.n_PCLK(n_PCLK), .PCLK(PCLK),
		.RES(RES), .HC(HC), .VC(VC), .V_IN(V_IN),
		.H_out(HCnt), .V_out(VCnt) );

	HVDecoder dec (
		.H_in(HCnt), .V_in(VCnt), .VB(VB), .BLNK(BLNK),
		.HPLA_out(HDecoder_out), .VPLA_out(VDecoder_out) );

	// There is no need to connect all FSM output signals, they will be perfectly visible in the .vcd dump

	PPU_FSM fsm (
		.n_PCLK(n_PCLK), .PCLK(PCLK),
		.H_out(HCnt), .V_out(VCnt), .HPLA_out(HDecoder_out), .VPLA_out(VDecoder_out),
		.RES(RES), .VBL_EN(1'b0), .n_R2(1'b1), .n_DBE(1'b1), .n_OBCLIP(1'b0), .n_BGCLIP(1'b0), .BLACK(1'b0),
		.VB(VB), .BLNK(BLNK),
		.V_IN(V_IN), .HC(HC), .VC(VC) );

	initial begin

`ifdef RP2C02
		$dumpfile("fsm_test_ntsc.vcd");
`elsif RP2C07
		$dumpfile("fsm_test_pal.vcd");
`else
		$display("wtf?");
		$finish;
`endif
		$dumpvars(0, FSM_Run);

		CLK <= 1'b0;
		RES <= 1'b0;

		// Run the number of cycles sufficient to capture the full field.

`ifdef RP2C02
		repeat (2048 * 262) @ (posedge CLK);
`elsif RP2C07
		repeat (2048 * 312) @ (posedge CLK);
`else
`endif
		$finish;
	end

endmodule // FSM_Run
module busmux_test ();

	reg CLK;
	wire PHI1, PHI2;
	always #25 CLK = ~CLK;

	ClkGen clkgen (.PHI0(CLK), .PHI1(PHI1), .PHI2(PHI2) );

	wire [7:0] SB, DB, ADL, ADH;

	BusMux busmux (
		.PHI2(PHI2),
		.SB(SB),
		.DB(DB),
		.ADL(ADL),
		.ADH(ADH),
		.Z_ADL0(1'b0),
		.Z_ADL1(1'b0),
		.Z_ADL2(1'b0),
		.Z_ADH0(1'b0),
		.Z_ADH17(1'b0),
		.SB_DB(1'b0),
		.SB_ADH(1'b0) );

	initial begin

		$dumpfile("busmux_test.vcd");
		$dumpvars(0, busmux_test);

		CLK <= 1'b0;

		repeat (256) @ (posedge CLK);
		$finish;
	end

endmodule // busmux_test
module regs_test ();

	reg CLK;
	wire PHI1, PHI2;
	always #25 CLK = ~CLK;

	ClkGen clkgen (.PHI0(CLK), .PHI1(PHI1), .PHI2(PHI2) );

	wire [7:0] SB, ADL;

	Regs regs (
		.PHI2(PHI2),
		.Y_SB(1'b0),
		.SB_Y(1'b0), 
		.X_SB(1'b0), 
		.SB_X(1'b0), 
		.S_SB(1'b0), 
		.S_ADL(1'b0), 
		.S_S(1'b1), 
		.SB_S(1'b0), 
		.SB(SB), 
		.ADL(ADL) );

	initial begin

		$dumpfile("regs_test.vcd");
		$dumpvars(0, regs_test);

		CLK <= 1'b0;

		repeat (256) @ (posedge CLK);
		$finish;
	end

endmodule // regs_test
module Core_Run ();

	reg CLK;
	reg n_RES;
	reg n_IRQ;
	reg n_NMI;
	reg SO;
	reg RDY;

	wire [15:0] addr_bus;
	wire [7:0] data_bus;

	wire PHI1;
	wire PHI2;
	wire SYNC;
	wire RnW;

	always #25 CLK = ~CLK;

	Core6502 core (
		.n_NMI(n_NMI),
		.n_IRQ(n_IRQ),
		.n_RES(n_RES),
		.PHI0(CLK),
		.PHI1(PHI1),
		.PHI2(PHI2),
		.RDY(RDY),
		.SO(SO),
		.RnW(RnW),
		.SYNC(SYNC),
		.A(addr_bus),
		.D(data_bus) );

	ExtMem mem (
		.M2(PHI2), 
		.WE(~RnW),
		.OE(RnW), 
		.Addr(addr_bus), 
		.Data(data_bus) );

	initial begin

		$display("Check that MOS6502 Core is moving.");

		RDY <= 1'b1; 		// Always ready
		SO <= 1'b1; 			// SO is enough to set to 1 to prevent the falling edge detector from triggering

		CLK <= 1'b0;
		n_IRQ <= 1'b1;
		n_NMI <= 1'b1;

		$dumpfile("core.vcd");
		$dumpvars(0, Core_Run);

		// Perform reset
		n_RES <= 1'b0;
		repeat (8) @ (posedge CLK);
		n_RES <= 1'b1;

		repeat (256) @ (posedge CLK);
		$finish;
	end	

endmodule // Core_Run
module ExtMem (M2, WE, OE, Addr, Data);

	input M2;
	input WE;
	input OE;
	input [15:0] Addr;
	inout [7:0] Data;

	reg [7:0] mem [0:65535];
	reg [7:0] temp;

	// You need to pre-fill the memory with some value so you don't run into `xx`
	integer j;
	initial 
	for(j = 0; j < 65536; j = j+1) 
		mem[j] = 0;

	initial $readmemh("core.mem", mem);

	always @(M2) begin
		if (OE)
			temp <= mem[Addr];
		else if (WE)
			mem[Addr] <= Data;
	end

	assign Data = (M2 & OE) ? temp : 'bz;

endmodule // ExtMem
module pads_test ();

	reg CLK;
	wire PHI1, PHI2;
	always #25 CLK = ~CLK;

	ClkGen clkgen (.PHI0(CLK), .PHI1(PHI1), .PHI2(PHI2) );

	PadsLogic pads (
		.PHI1(PHI1), 
		.PHI2(PHI2),
		.n_NMI(1'b1), 
		.n_IRQ(1'b1), 
		.n_RES(1'b1), 
		.RDY(1'b1),  
		.T1_topad(1'b0),  
		.SO(1'b1), 
		.WR_topad(1'b0) );

	initial begin

		$dumpfile("pads_test.vcd");
		$dumpvars(0, pads_test);

		CLK <= 1'b0;

		repeat (256) @ (posedge CLK);
		$finish;
	end

endmodule // pads_test
module extra_counter_test ();

	reg CLK;
	wire PHI1;
	wire PHI2;

	reg TRES2;
	reg n_ready;
	reg T1;

	always #25 CLK = ~CLK;

	ClkGen clk (.PHI0(CLK), .PHI1(PHI1), .PHI2(PHI2));

	ExtraCounter extra_cnt (
		.PHI1(PHI1), .PHI2(PHI2), .TRES2(TRES2), .n_ready(n_ready), .T1(T1));

	initial begin

		$dumpfile("extra_counter_test.vcd");
		$dumpvars(0, extra_counter_test);

		CLK <= 1'b0;
		TRES2 <= 1'b0;
		n_ready <= 1'b0;
		T1 <= 1'b0;

		// Just work

		repeat (4) @ (posedge CLK);

		// Load T1 and check how it is pushed out through outputs T2-T5

		T1 <= 1'b1;
		repeat (1) @ (posedge CLK);
		T1 <= 1'b0;
		repeat (8) @ (posedge CLK);

		// Load T1, then suddenly do NotReady; then ready

		T1 <= 1'b1;
		repeat (1) @ (posedge CLK);
		T1 <= 1'b0;
		repeat (2) @ (posedge CLK);
		n_ready <= 1'b1;
		repeat (4) @ (posedge CLK);
		n_ready <= 1'b0;
		repeat (4) @ (posedge CLK);

		// Load T1, then suddenly do TRES2; then just work

		T1 <= 1'b1;
		repeat (1) @ (posedge CLK);
		T1 <= 1'b0;
		repeat (2) @ (posedge CLK);
		TRES2 <= 1'b1;
		repeat (4) @ (posedge CLK);
		TRES2 <= 1'b0;
		repeat (4) @ (posedge CLK);

		$finish;
	end

endmodule // extra_counter_test
module data_bus_test ();

	reg CLK;
	wire PHI1, PHI2;
	always #25 CLK = ~CLK;

	ClkGen clkgen (.PHI0(CLK), .PHI1(PHI1), .PHI2(PHI2) );

	wire ADL, ADH, DB, DB_Ext;

	DataBusBit databus_bit (
		.PHI1(PHI1),
		.PHI2(PHI2),
		.ADL(ADL), 
		.ADH(ADH), 
		.DB(DB), 
		.DB_Ext(DB_Ext),
		.DL_ADL(1'b0), 
		.DL_ADH(1'b0), 
		.DL_DB(1'b0),
		.RD(RD) );

	WRLatch wrlatch (
		.PHI1(PHI1), 
		.PHI2(PHI2), 
		.WR(1'b0),  		// From dispatch
		.RD(RD) );

	wire RD;

	initial begin

		$dumpfile("data_bus_test.vcd");
		$dumpvars(0, data_bus_test);

		CLK <= 1'b0;

		repeat (256) @ (posedge CLK);
		$finish;
	end

endmodule // data_bus_test
module decoder_test ();

	reg CLK;
	integer f;

	always #1 CLK = ~CLK;

	reg [13:0] Decoder_cnt; 		// The counter acts as an enumerator for all decoder inputs

	wire [129:0] Decoder_out;

	wire n_T0;
	wire n_T1X;
	wire n_T2;
	wire n_T3;
	wire n_T4;
	wire n_T5; 
	wire IR01;
	wire [7:0] IR;

	// Assign the decoder inputs.
	// The lower six bits represent the Tx. The remaining high bits are IR.

	assign n_T0 = ~Decoder_cnt[0];
	assign n_T1X = ~Decoder_cnt[1];
	assign n_T2 = ~Decoder_cnt[2];
	assign n_T3 = ~Decoder_cnt[3];
	assign n_T4 = ~Decoder_cnt[4];
	assign n_T5 = ~Decoder_cnt[5];
	assign IR = Decoder_cnt[13:6];
	assign IR01 = IR[0]|IR[1];

	Decoder dec (
		.n_T0(n_T0), .n_T1X(n_T1X),
		.n_T2(n_T2), .n_T3(n_T3), .n_T4(n_T4), .n_T5(n_T5), 
		.IR01(IR01),
		.IR(IR), .n_IR(~IR),
		.X(Decoder_out) );

	always @(posedge CLK) begin
		$fwrite (f, "%b,%b\n", Decoder_cnt, Decoder_out);
		Decoder_cnt = Decoder_cnt + 1;
	end

	initial begin

		$dumpfile("decoder_test.vcd");
		$dumpvars(0, decoder_test);

		f = $fopen("decoder_6502.csv","w");
		$fwrite(f, "inputs,outputs\n");

		Decoder_cnt <= 0;
		CLK <= 1'b0;

		repeat (1<<14) @ (posedge CLK);
		$fclose (f);
		$finish;
	end

endmodule // decoder_test
module alu_control_test ();

	reg CLK;
	wire PHI1, PHI2;
	always #25 CLK = ~CLK;

	ClkGen clkgen (.PHI0(CLK), .PHI1(PHI1), .PHI2(PHI2) );

	wire INC_SB, SR, AND;

	ALU_Control alu_control (
		.PHI1(PHI1), 
		.PHI2(PHI2),
		.BRFW(1'b0), 
		.n_ready(1'b0), 
		.BRK6E(1'b0),
		.STKOP(1'b0), 
		.PGX(1'b0),
		.X({130{1'b0}}),
		.T0(1'b0),
		.T1(1'b0),
		.T6(1'b0),
		.T7(1'b0),
		.n_DOUT(1'b1),
		.n_COUT(1'b1),
		.INC_SB(INC_SB),
		.SR(SR),
		.AND(AND) );

	initial begin

		$dumpfile("alu_control_test.vcd");
		$dumpvars(0, alu_control_test);

		CLK <= 1'b0;

		repeat (256) @ (posedge CLK);
		$finish;
	end

endmodule // alu_control_test
module flags_control_test ();

	reg CLK;
	wire PHI1, PHI2;
	always #25 CLK = ~CLK;

	ClkGen clkgen (.PHI0(CLK), .PHI1(PHI1), .PHI2(PHI2) );

	Flags_Control flags_control (
		.PHI2(PHI2), 
		.X({130{1'b0}}),
		.T7(1'b0), 
		.ZTST(1'b0), 
		.n_ready(1'b1), 
		.SR(1'b0) );

	initial begin

		$dumpfile("flags_control_test.vcd");
		$dumpvars(0, flags_control_test);

		CLK <= 1'b0;

		repeat (256) @ (posedge CLK);
		$finish;
	end

endmodule // flags_control_test
module addr_bus_test ();

	reg CLK;
	wire PHI1, PHI2;
	always #25 CLK = ~CLK;

	ClkGen clkgen (.PHI0(CLK), .PHI1(PHI1), .PHI2(PHI2) );

	reg ADX;
	reg ADX_ABX;
	wire ABus_out;

	AddrBusBit ab (
		.PHI1(PHI1), .PHI2(PHI2),
		.ADX(ADX), .ADX_ABX(ADX_ABX),
		.ABus_out(ABus_out) );

	initial begin

		$dumpfile("addr_bus_test.vcd");
		$dumpvars(0, addr_bus_test);

		CLK <= 1'b0;
		ADX <= 1'b0;
		ADX_ABX <= 1'b0;

		repeat (16) @ (posedge CLK);

		ADX_ABX <= 1'b1;
		ADX <= 1'b1;
		repeat (16) @ (posedge CLK);

		ADX_ABX <= 1'b0;
		repeat (16) @ (posedge CLK);

		ADX_ABX <= 1'b1;
		ADX <= 1'b0;
		repeat (16) @ (posedge CLK);

		ADX_ABX <= 1'b0;
		repeat (16) @ (posedge CLK);

		$finish;
	end

endmodule // addr_bus_test