dakies/OSS_Verilog huggingface dataset:
module PixelClock (
	n_CLK, CLK, RES,
	n_PCLK, PCLK);

	input n_CLK;
	input CLK;				// NTSC: 21477272 Hz (~0,046 µs), PAL: 26601712 Hz (~0,037 µs)
	input RES;

	output n_PCLK;
	output PCLK;			// NTSC: 5369318 Hz (~0,186 µs), PAL: 5320342.4 Hz (~0,187 µs)

	// wires
	
	wire latch1_in;
	wire latch2_in;
	wire latch1_out;
	wire latch2_out;
	wire latch3_out;
	wire latch4_out;
	wire latch5_out;
	wire latch6_out;
	wire pclk;
	wire pclk_out;
	wire npclk_out;

`ifdef RP2C02

	// The PCLK is obtained by slowing down (dividing) the input clock signal CLK (21.48 MHz) by a factor of 4.
	// For this purpose, a divider on static latches is used:

	nor (latch1_in, RES, latch4_out);

	dlatch latch1 (.d(latch1_in), .en(n_CLK), .nq(latch1_out) );
	dlatch latch2 (.d(latch1_out), .en(CLK), .nq(latch2_out) );
	dlatch latch3 (.d(latch2_out), .en(n_CLK), .nq(latch3_out) );
	dlatch latch4 (.d(latch3_out), .en(CLK), .nq(latch4_out) );

	assign pclk = latch4_out;

`elsif RP2C07

	nor (latch2_in, latch1_out, RES);

	dlatch latch1 (.d(latch1_in), .en(n_CLK), .q(latch1_out));
	dlatch latch2 (.d(latch2_in), .en(CLK), .nq(latch2_out));
	dlatch latch3 (.d(latch2_out), .en(n_CLK), .nq(latch3_out));
	dlatch latch4 (.d(latch3_out), .en(CLK), .nq(latch4_out));
	dlatch latch5 (.d(latch4_out), .en(n_CLK), .nq(latch5_out));
	dlatch latch6 (.d(latch5_out), .en(CLK), .nq(latch6_out));

	nor (pclk, latch6_out, ~latch5_out);
	nor (latch1_in, latch6_out, latch4_out);

`else
`endif

	// Just below the divider is the single phase splitter.
	// This is a canonical circuit based on a single FF that makes two phases (/PCLK + PCLK) from a single phase (PCLK).

	rsff PCLK_FF (.r(pclk), .s(~pclk), .q(pclk_out), .nq(npclk_out) );

	assign n_PCLK = ~pclk_out;
	assign PCLK = ~npclk_out;

endmodule // PixelClock
module OAMEval(
	n_PCLK, PCLK,
	BLNK, I_OAM2, n_VIS, PAR_O, n_EVAL, RESCL, H0_DD, H0_D, n_H2_D, OFETCH, n_FNT, S_EV,
	n_W3, n_DBE,
	DB5, 
	n_OAM, OAM8, OAMCTR2, SPR_OV, OV, PD_FIFO, n_SPR0_EV);

	input n_PCLK;
	input PCLK;

	input BLNK;
	input I_OAM2;
	input n_VIS;
	input PAR_O;
	input n_EVAL;
	input RESCL;
	input H0_DD;
	input H0_D;
	input n_H2_D;
	input OFETCH;
	input n_FNT;
	input S_EV;

	input n_W3;
	input n_DBE;
	inout DB5;

	output [7:0] n_OAM;
	output OAM8;
	output OAMCTR2;
	output SPR_OV;
	output [7:0] OV;
	output PD_FIFO;
	output n_SPR0_EV;

endmodule // OAMEval
module PataddrGen(
	n_PCLK,
	H0_DD, n_FNT, BGSEL, OBSEL, O8_16, PAR_O, n_SH2, n_H1D, OB, PD, OV, n_FVO,
	PAddr_out);

	input n_PCLK;

	input H0_DD;
	input n_FNT;
	input BGSEL;
	input OBSEL;
	input O8_16;
	input PAR_O;
	input n_SH2;
	input n_H1D;
	input [7:0] OB;
	input [7:0] PD;
	input [3:0] OV;
	input [2:0] n_FVO;

	output [13:0] PAddr_out;

endmodule // PataddrGen
module DelayedH (PCLK, n_PCLK, H_out, H0_DD, H0_D, H1_DD, nH1_D, H2_DD, nH2_D, H3_DD, H4_DD, H5_DD);

	input PCLK;
	input n_PCLK;
	input [8:0] H_out;

	output H0_DD;
	output H0_D;
	output H1_DD; 
	output nH1_D;
	output H2_DD;
	output nH2_D;
	output H3_DD;
	output H4_DD;
	output H5_DD;

	// Wires

	wire h0_latch1_nq;
	wire h3_latch1_nq;
	wire h4_latch1_nq;
	wire h5_latch1_nq;

	// Instances

	dlatch h0_latch1 (.d(H_out[0]), .en(n_PCLK), .nq(h0_latch1_nq));
	dlatch h0_latch2 (.d(h0_latch1_nq), .en(PCLK), .nq(H0_DD));
	dlatch h1_latch1 (.d(H_out[1]), .en(n_PCLK), .nq(nH1_D));
	dlatch h1_latch2 (.d(nH1_D), .en(PCLK), .nq(H1_DD));
	dlatch h2_latch1 (.d(H_out[2]), .en(n_PCLK), .nq(nH2_D));
	dlatch h2_latch2 (.d(nH2_D), .en(PCLK), .nq(H2_DD));
	dlatch h3_latch1 (.d(H_out[3]), .en(n_PCLK), .nq(h3_latch1_nq));
	dlatch h3_latch2 (.d(h3_latch1_nq), .en(PCLK), .nq(H3_DD));
	dlatch h4_latch1 (.d(H_out[4]), .en(n_PCLK), .nq(h4_latch1_nq));
	dlatch h4_latch2 (.d(h4_latch1_nq), .en(PCLK), .nq(H4_DD));
	dlatch h5_latch1 (.d(H_out[5]), .en(n_PCLK), .nq(h5_latch1_nq));
	dlatch h5_latch2 (.d(h5_latch1_nq), .en(PCLK), .nq(H5_DD));

endmodule // DelayedH
module EvenOdd (V8, RES, nHPLA_5, RESCL, EvenOddOut);

	input V8;
	input RES;
	input nHPLA_5;
	input RESCL;
	output EvenOddOut;

	wire q1;
	wire q2;
	wire nq2;

	sdff FF_1 (.d(nq2), .phi_keep(V8), .q(q1));
	sdffr FF_2 (.d(q1), .res(), .phi_keep(~V8), .q(q2), .nq(nq2));

	nor (EvenOddOut, q2, nHPLA_5, ~RESCL);

endmodule // EvenOdd
module EvenOdd_2C07 (n_PCLK, PCLK, BLNK, H0_D, VPLA_8, VPLA_9, EvenOddOut);

	input n_PCLK;
	input PCLK;
	input BLNK;
	input H0_D;
	input VPLA_8;
	input VPLA_9;
	output EvenOddOut; 		// Don't mind the name, it's just historically that way. In fact, it's more like `Sprite_Workaround`.

	wire latch1_q;
	wire latch2_q;
	wire latch3_in;
	wire latch3_nq;
	wire tmp;

	dlatch latch1 (.d(VPLA_9), .en(n_PCLK), .q(latch1_q));
	dlatch latch2 (.d(VPLA_8), .en(n_PCLK), .q(latch2_q));
	dlatch latch3 (.d(latch3_in), .en(PCLK), .nq(latch3_nq));
	rsff FF_1 (.r(latch2_q), .s(latch1_q), .nq());

	nand (tmp, BLNK, latch3_nq);
	nor (EvenOddOut, ~H0_D, tmp, n_PCLK);

endmodule // EvenOdd_2C07
module VBlankInt (PCLK, n_PCLK, nVSET, VCLR, VBL_EN, n_R2, n_DBE, INT, DB7Out);

	input PCLK;
	input n_PCLK;
	input nVSET;
	input VCLR;
	input VBL_EN;
	input n_R2;
	input n_DBE;
	output INT;
	inout DB7Out;

	wire R2_EN;
	wire vset_latch1_nq;
	wire vset_latch2_q;
	wire db_latch_nq;
	wire int_ff_q;

	dlatch vset_latch1 (.d(nVSET), .en(PCLK), .nq(vset_latch1_nq));
	dlatch vset_latch2 (.d(vset_latch1_nq), .en(n_PCLK), .q(vset_latch2));
	dlatch db_latch (.d(~int_ff_q), .en(~R2_EN), .nq(db_latch_nq));
	rsff_2_3 int_ff (.res1(VCLR), .res2(R2_EN), .s(~(n_PCLK | nVSET | vset_latch2_q)), .q(int_ff_q));

	nor (R2_EN, n_R2, n_DBE);
	nor (INT, ~VBL_EN, ~int_ff_q);
	assign DB7Out = R2_EN ? db_latch_nq : 1'bz;

endmodule // VBlankInt
module HVCounterControl (n_PCLK, HPLA_23, EvenOddOut, VPLA_2, V_IN, HC, VC);

	input n_PCLK;
	input HPLA_23;
	input EvenOddOut;
	input VPLA_2;
	output V_IN;
	output HC;
	output VC;

	wire ctrl_latch2_nq;

	dlatch ctrl_latch1 (.d(~(HPLA_23 | EvenOddOut)), .en(n_PCLK), .nq(HC));
	dlatch ctrl_latch2 (.d(VPLA_2), .en(n_PCLK), .nq(ctrl_latch2_nq));

	assign V_IN = HPLA_23;
	nor (VC, ~HC, ctrl_latch2_nq);

endmodule // HVCounterControl
module HVCounterControl_2C07 (n_PCLK, HPLA_23, VPLA_8, V_IN, HC, VC);

	input n_PCLK;
	input HPLA_23;
	input VPLA_8;
	output V_IN;
	output HC;
	output VC;

	wire ctrl_latch2_nq;

	dlatch ctrl_latch1 (.d(~HPLA_23), .en(n_PCLK), .nq(HC));
	dlatch ctrl_latch2 (.d(VPLA_8), .en(n_PCLK), .nq(ctrl_latch2_nq));

	assign V_IN = HPLA_23;
	nor (VC, ~HC, ctrl_latch2_nq);

endmodule // HVCounterControl_2C07
module VPosLogic (PCLK, n_PCLK, n_HB, BPORCH, BLACK, VPLA_out, 
	n_PICTURE, RESCL, VSYNC, nVSET, VB, BLNK);

	input PCLK;
	input n_PCLK;
	input n_HB;
	input BPORCH;
	input BLACK;
	input [9:0] VPLA_out;
	
	output n_PICTURE;
	output RESCL;
	output VSYNC;
	output nVSET;
	output VB;
	output BLNK;

	// Wires

	wire vsync_latch1_q;
	wire pic_latch1_q;
	wire pic_latch2_q;
	wire vset_latch1_nq;
	wire vb_latch1_q;
	wire vb_latch2_q;
	wire blnk_latch1_q;
	wire vclr_latch1_nq;
	wire vclr_latch2_nq;

	wire vsync_ff_q;
	wire picture_ff_q;
	wire vb_ff_nq;
	wire blnk_ff_q;

	// Instances

	dlatch vsync_latch1 (.d(~(n_HB | vsync_ff_q)), .en(PCLK), .q(vsync_latch1_q));
	dlatch pic_latch1 (.d(picture_ff_q), .en(PCLK), .q(pic_latch1_q));
	dlatch pic_latch2 (.d(BPORCH), .en(PCLK), .q(pic_latch2_q));
	dlatch vset_latch1 (.d(VPLA_out[4]), .en(n_PCLK), .nq(vset_latch1_nq));
	dlatch vb_latch1 (.d(VPLA_out[5]), .en(n_PCLK), .q(vb_latch1_q));
	dlatch vb_latch2 (.d(VPLA_out[6]), .en(n_PCLK), .q(vb_latch2_q));
	dlatch blnk_latch1 (.d(VPLA_out[7]), .en(n_PCLK), .q(blnk_latch1_q));
	dlatch vclr_latch1 (.d(VPLA_out[8]), .en(n_PCLK), .nq(vclr_latch1_nq));
	dlatch vclr_latch2 (.d(vclr_latch1_nq), .en(PCLK), .nq(vclr_latch2_nq));

	rsff vsync_ff (.r(n_HB & VPLA_out[0]), .s(n_HB & VPLA_out[1]), .q(vsync_ff_q));
	rsff picture_ff (.r(BPORCH & VPLA_out[2]), .s(BPORCH & VPLA_out[3]), .q(picture_ff_q));
	rsff vb_ff (.r(vb_latch1_q), .s(vb_latch2_q), .nq(vb_ff_nq));
	rsff blnk_ff (.r(blnk_latch1_q), .s(vb_latch2_q), .q(blnk_ff_q));

	assign n_PICTURE = ~(~(pic_latch1_q | pic_latch2_q));
	assign RESCL = vclr_latch2_nq;
	assign VSYNC = vsync_latch1_q;
	assign nVSET = vset_latch1_nq;
	assign VB = ~vb_ff_nq;
	assign BLNK = ~(~blnk_ff_q & ~BLACK);

endmodule // VPosLogic
module OAMBlock(
	n_PCLK, PCLK,
	n_OAM, OAM8, BLNK, SPR_OV, OAMCTR2, H0_DD, n_VIS, I_OAM2, n_W4, n_R4, n_DBE, 
	CPU_DB,
	OB_Out, OFETCH);

	input n_PCLK;
	input PCLK;

	input [7:0] n_OAM;
	input OAM8;
	input BLNK;
	input SPR_OV;
	input OAMCTR2;
	input H0_DD;
	input n_VIS;
	input I_OAM2;
	input n_W4;
	input n_R4;
	input n_DBE;

	inout [7:0] CPU_DB;

	output [7:0] OB_Out;
	output OFETCH;

endmodule // OAMBlock
module ScrollRegs(
	n_W0, n_W5_1, n_W5_2, n_W6_1, n_W6_2, n_DBE, RC, CPU_DB,
	FH, FV, NTH, NTV, TV, TH, W6_2_Ena);

	input n_W0;
	input n_W5_1;
	input n_W5_2;
	input n_W6_1;
	input n_W6_2;
	input n_DBE;
	input RC;
	inout [7:0] CPU_DB;

	output [2:0] FH;
	output [2:0] FV;
	output NTH;
	output NTV;
	output [4:0] TV;
	output [4:0] TH;
	output W6_2_Ena;

endmodule // ScrollRegs
module PPU_CompositeDAC (RawIn, CompositeOut);

	input [10:0] RawIn;
	output [31:0] CompositeOut;

	assign CompositeOut = 32'b0;

endmodule // PPU_CompositeDAC
module PictureMUX(
	n_PCLK, PCLK, 
	BGC, n_ZPRIO, n_ZCOL0, n_ZCOL1, ZCOL2, ZCOL3, EXT_in, THO, TH_MUX,
	PAL_out, n_EXT_out);

	input n_PCLK;
	input PCLK;

	input [3:0] BGC;
	input n_ZPRIO;
	input n_ZCOL0;
	input n_ZCOL1;
	input ZCOL2;
	input ZCOL3;
	input [3:0] EXT_in;
	input [4:0] THO;
	input TH_MUX;

	output [4:0] PAL_out;
	output [3:0] n_EXT_out;

endmodule // PictureMUX
module Spr0Hit(
	PCLK,
	BGC, n_SPR0HIT, n_SPR0_EV, n_VIS, n_R2, n_DBE, RESCL,
	DB6);

	input PCLK;

	input [3:0] BGC;
	input n_SPR0HIT;
	input n_SPR0_EV;
	input n_VIS;
	input n_R2;
	input n_DBE;
	input RESCL;
	inout DB6;

	wire bg;
	nor (bg, BGC[0], BGC[1]);  

	wire Strike;
	nor (Strike, PCLK, bg, n_SPR0HIT, n_SPR0_EV, n_VIS);	

	wire Strike_out;
	rsff STRIKE_FF (
		.r(RESCL),
		.s(Strike),
		.q(Strike_out) );

	wire R2_Ena;
	nor (R2_Ena, n_R2, n_DBE);
	bufif1 (DB6, Strike_out, R2_Ena);

endmodule // Spr0Hit
module PpuPadsLogic(
	n_PCLK,
	n_CpuRD, n_CpuWR, CPU_DB, DPads,
	n_ALE_topad, ALE, 	
	PD_out, n_PA, PAPads, ADPads, RD_topad, WR_topad, n_RDPad, n_WRPad, 
	EXTPads, n_SLAVE, EXT_in, n_EXT_out, 
	CLKPad, n_CLK_frompad, CLK_frompad,
	n_RESPad, RES, RESCL, RC,
	Int_topad, n_INTPad);

	input n_PCLK;

	input n_CpuRD;
	input n_CpuWR;
	inout [7:0] CPU_DB;
	inout [7:0] DPads;

	input n_ALE_topad;
	output ALE;

	output [7:0] PD_out;
	input [13:0] n_PA;
	output [5:0] PAPads;
	inout [7:0] ADPads;
	input RD_topad;
	input WR_topad;
	output n_RDPad;
	output n_WRPad; 

	inout [3:0] EXTPads;
	input n_SLAVE;
	output [3:0] EXT_in;
	input [3:0] n_EXT_out;

	input CLKPad;
	output n_CLK_frompad;
	output CLK_frompad;

	input n_RESPad;
	output RES;
	input RESCL;
	output RC;

	input Int_topad;
	output n_INTPad;

	// Logic

	wire [7:0] DB_temp;
	pnor DB_out [7:0] (CPU_DB, {8{n_CpuRD}}, DB_temp);
	bustris DB_out_tris [7:0] (.a(DB_temp), .n_x(DPads), .n_en(n_CpuRD) );
	bustris DB_in_tris [7:0] (.a(~DPads), .n_x(CPU_DB), .n_en(n_CpuWR) );

	assign ALE = ~n_ALE_topad;
	assign PD_out = ADPads;
	bustris AD_out_tris [7:0] (.a(n_PA[7:0] | {8{RD_topad}}), .n_x(ADPads), .n_en(RD_topad) );
	assign PAPads = ~n_PA[13:8];
	assign n_RDPad = ~RD_topad;
	assign n_WRPad = ~WR_topad;

	wire [3:0] ext_latch_out;
	pnor EXT_in_nors [3:0] (~EXTPads, {4{n_SLAVE}}, EXT_in);
	dlatch EXT_out_latch [3:0] (.d(n_EXT_out), .en(n_PCLK), .q(ext_latch_out) );
	bustris EXT_out_tris [3:0] (.a(ext_latch_out | {4{~n_SLAVE}}), .n_x(EXTPads), .n_en(~n_SLAVE) );

	assign n_CLK_frompad = ~CLKPad;
	assign CLK_frompad = CLKPad;

	assign RES = ~n_RESPad;
	wire Reset_FF_out;
	rsff Reset_FF (.r(RESCL), .s(RES), .q(Reset_FF_out) );
	assign RC = ~Reset_FF_out;

	notif1 (n_INTPad, Int_topad, Int_topad);

endmodule // PadsLogic
module CRAM_Block (
	n_PCLK, PCLK,
	n_R7, n_DBE, TH_MUX, DB_PAR, n_PICTURE, BnW,
	PAL,
	CPU_DB, 
	n_CC, n_LL);

	input n_PCLK;
	input PCLK;

	input n_R7;
	input n_DBE;
	input TH_MUX;
	input DB_PAR;
	input n_PICTURE;
	input BnW;

	input [4:0] PAL;

	inout [7:0] CPU_DB;

	output [3:0] n_CC;
	output [1:0] n_LL;

	wire n_CB_DB;
	wire color_mode;
	wire n_DB_CB;

	wire [5:0] cram_val;
	wire [5:0] CB_Out;
	wire [3:0] COL;
	wire [6:0] ROW;

	CB_Control cbctl(
		.PCLK(PCLK),
		.n_R7(n_R7),
		.n_DBE(n_DBE),
		.TH_MUX(TH_MUX),
		.DB_PAR(DB_PAR),
		.n_PICTURE(n_PICTURE),
		.BnW(BnW),
		.n_CB_DB(n_CB_DB),
		.n_BW(color_mode),
		.n_DB_CB(n_DB_CB) );

	ColorBuf cb(
		.n_PCLK(n_PCLK),
		.PCLK(PCLK),
		.CPU_DB(CPU_DB),
		.n_DB_CB(n_DB_CB),
		.n_CB_DB(n_CB_DB),
		.n_OE(color_mode),
		.cram_val(cram_val),
		.CB_Out(CB_Out) );

	CRAM_Decoder cramdec(
		.PCLK(PCLK),
		.PAL(PAL),
		.COL(COL),
		.ROW(ROW) );

	CRAM cram(
		.PCLK(PCLK),
		.COL(COL),
		.ROW(ROW),
		.cram_val(cram_val) );

endmodule // CRAM_Block
module CB_Control(
	PCLK,
	n_R7, n_DBE, TH_MUX, DB_PAR, n_PICTURE, BnW,
	n_CB_DB, n_BW, n_DB_CB);

	input PCLK;

	input n_R7;
	input n_DBE;
	input TH_MUX;
	input DB_PAR;
	input n_PICTURE;
	input BnW;

	output n_CB_DB;
	output n_BW;
	output n_DB_CB;

endmodule // CB_Control
module ColorBuf(
	n_PCLK, PCLK,
	CPU_DB,
	n_DB_CB, n_CB_DB, n_OE, cram_val,
	CB_Out );

	input n_PCLK;
	input PCLK;

	inout [7:0] CPU_DB;

	input n_DB_CB;
	input n_CB_DB;
	input n_OE;
	inout [5:0] cram_val;

	output [5:0] CB_Out;

endmodule // ColorBuf
module CRAM_Decoder(PCLK, PAL, COL, ROW);

	input PCLK;
	input [4:0] PAL;
	output [3:0] COL;
	output [6:0] ROW;

endmodule // CRAM_Decoder
module CRAM(PCLK, COL, ROW, cram_val);

	input PCLK;
	input [3:0] COL;
	input [6:0] ROW;
	inout [5:0] cram_val;

endmodule // CRAM
module ObjectFIFO(
	n_PCLK, PCLK,
	PAR_O, H0_DD, H1_DD, H2_DD, H3_DD, H4_DD, H5_DD, Z_HPOS, n_VIS, PD_FIFO, PD, CLPO,
	n_SPR0HIT, n_ZCOL0, n_ZCOL1, ZCOL2, ZCOL3, n_ZPRIO, n_SH2);

	input n_PCLK;
	input PCLK;

	input PAR_O;
	input H0_DD;
	input H1_DD;
	input H2_DD;
	input H3_DD;
	input H4_DD;
	input H5_DD;
	input Z_HPOS;
	input n_VIS;
	input PD_FIFO;
	input [7:0] PD;
	input CLPO;

	output n_SPR0HIT;
	output n_ZCOL0;
	output n_ZCOL1;
	output ZCOL2;
	output ZCOL3;
	output n_ZPRIO;
	output n_SH2;



endmodule // ObjectFIFO
module HVCounters (
	n_PCLK, PCLK,
	RES, HC, VC, V_IN,
	H_out, V_out);

	input n_PCLK;
	input PCLK;

	input RES;
	input HC;
	input VC;
	input V_IN;

	output [8:0] H_out;
	output [8:0] V_out;

	// Wires

	wire [8:0] n_h;
	wire [8:0] n_v;
	wire [8:0] hc;
	wire [8:0] vc;

	wire half_hc;
	wire half_vc;

	// Instances

	// The counters use some attempt to speed up the carry propagation, but a questionable one.
	// Without these tweaks carry_in looks the usual way: {carry_chain[7:0], Carry_in}   (9-bit counter)

	HVCounterBit hcnt [8:0] (.PCLK(PCLK), .n_PCLK(n_PCLK), .CLR(HC), .RES(RES),
		.cin({hc[7:5],half_hc,hc[3:0],1'b1}),
		.val(H_out), .n_val(n_h), .cout(hc) );

	assign half_hc = ~(n_h[0] | n_h[1] | n_h[2] | n_h[3] | n_h[4]);

	HVCounterBit vcnt [8:0] (.PCLK(PCLK), .n_PCLK(n_PCLK), .CLR(VC), .RES(RES),
		.cin({vc[7:5],half_vc,vc[3:0],V_IN}),
		.val(V_out), .n_val(n_v), .cout(vc) );

	assign half_vc = ~(~V_IN | n_v[0] | n_v[1] | n_v[2] | n_v[3] | n_v[4]);

endmodule // HVCounters
module HVCounterBit (PCLK, n_PCLK, CLR, RES, cin, val, n_val, cout);

	input PCLK;
	input n_PCLK;
	input CLR;
	input RES;
	input cin;
	output val;
	output n_val;
	output cout;

	wire keep_latch_q;

	dlatch keep_latch (.d(cin ? val : n_val), .en(n_PCLK), .q(keep_latch_q) );
	dlatch out_latch (.d(PCLK ? ~(keep_latch_q | CLR) : val), .en(1'b1), .nq(n_val) );

	assign val = ~(n_val | RES);
	assign cout = ~(n_val | ~cin);

endmodule // HVCounterBit
module PpuRegs(
	RC, n_DBE, RS, RnW, CPU_DB, 
	n_W5_1, n_W5_2, n_W6_1, n_W6_2,
	n_R7, n_W7, n_W4, n_W3, n_R2, n_W1, n_W0, n_R4, 
	I_1_32, OBSEL, BGSEL, O_8_16, n_SLAVE, VBL, 
	BnW, n_BGCLIP, n_OBCLIP, BGE, BLACK, OBE, n_TR, n_TG, n_TB);

	input RC;
	input n_DBE;
	input [2:0] RS;
	input RnW;
	inout [7:0] CPU_DB;

	output n_W5_1;
	output n_W5_2;
	output n_W6_1;
	output n_W6_2;

	output n_R7;
	output n_W7;
	output n_W4;
	output n_W3;
	output n_R2;
	output n_W1;
	output n_W0;
	output n_R4;

	output I_1_32;
	output OBSEL;
	output BGSEL;
	output O_8_16;
	output n_SLAVE;
	output VBL;

	output BnW;
	output n_BGCLIP;
	output n_OBCLIP;
	output BGE;
	output BLACK;
	output OBE;
	output n_TR;
	output n_TG;
	output n_TB;

	wire n_W56;
	wire sccx_first;
	wire sccx_second;

	SCCXFirstSecond fs(
		.RC(RC),
		.n_DBE(n_DBE),
		.n_R2(n_R2),
		.n_W56(n_W56),
		.Frst(sccx_first),
		.Scnd(sccx_second) );

	RegCTRL0 ctrl0(
		.RC(RC),
		.n_W0(n_W0),
		.n_DBE(n_DBE),
		.D_in(CPU_DB),
		.I_1_32(I_1_32),
		.OBSEL(OBSEL),
		.BGSEL(BGSEL),
		.O_8_16(O_8_16),
		.n_SLAVE(n_SLAVE),
		.VBL(VBL) );

	RegCTRL1 ctrl1(
		.RC(RC),
		.n_W1(n_W1),
		.n_DBE(n_DBE),
		.D_in(CPU_DB),
		.BnW(BnW),
		.n_BGCLIP(n_BGCLIP),
		.n_OBCLIP(n_OBCLIP),
		.BGE(BGE),
		.BLACK(BLACK),
		.OBE(OBE),
		.n_TR(n_TR),
		.n_TG(n_TG),
		.n_TB(n_TB) );

endmodule // Regs
module SCCXFirstSecond(RC, n_DBE, n_R2, n_W56, Frst, Scnd);

	input RC;
	input n_DBE;
	input n_R2;
	input n_W56;
	output Frst;
	output Scnd;

	wire q1;
	wire nq1;
	wire q2;
	wire nq2;
	wire W56;
	wire R2;

	assign R2 = n_R2 ~| n_DBE;
	assign W56 = n_W56 ~| n_DBE;

	sdffr2e FF_1 (.d(q2), .en(~W56), .res1(RC), .res2(R2), .phi_keep(W56), .q(q1), .nq(nq1) );
	sdffr2e FF_2 (.d(nq1), .en(W56), .res1(RC), .res2(R2), .phi_keep(~W56), .q(q2), .nq(nq2) );

	assign Frst = q1;
	assign Scnd = nq1;

endmodule // SCCXFirstSecond
module RegCTRL0(RC, n_W0, n_DBE, D_in, I_1_32, OBSEL, BGSEL, O_8_16, n_SLAVE, VBL);

	input RC;
	input n_W0;
	input n_DBE;
	inout [7:0] D_in;

	output I_1_32;
	output OBSEL;
	output BGSEL;
	output O_8_16;
	output n_SLAVE;
	output VBL;

endmodule // RegCTRL0
module RegCTRL1(RC, n_W1, n_DBE, D_in, BnW, n_BGCLIP, n_OBCLIP, BGE, BLACK, OBE, n_TR, n_TG, n_TB);

	input RC;
	input n_W1;
	input n_DBE;
	inout [7:0] D_in;

	output BnW;
	output n_BGCLIP;
	output n_OBCLIP;
	output BGE;
	output BLACK;
	output OBE;
	output n_TR;
	output n_TG;
	output n_TB;

endmodule // RegCTRL1
module Clipper(n_PCLK, n_VIS, CLIP_B, CLIP_O, BGE, OBE, n_CLPB, CLPO);

	input n_PCLK;
	input n_VIS;
	input CLIP_B;
	input CLIP_O;
	input BGE;
	input OBE;

	output n_CLPB;
	output CLPO;

endmodule // Clipper
module RWDecoder(RnW, n_DBE, n_RD, n_WR);

	input RnW;
	input n_DBE;
	output n_RD;
	output n_WR;

	assign n_RD = ~( ~RnW ~| n_DBE );
	assign n_WR = ~( RnW ~| n_DBE );

endmodule // RWDecoder
module PAR(
	n_PCLK, PCLK,
	BLNK, DB_PAR, F_AT, SC_CNT, RESCL, E_EV, TSTEP, F_TB, H0_DD, n_H2_D, I_1_32, W6_2_Ena, 
	PAD_in, CPU_DB, TH, TV, NTH, NTV, FV, 
	n_FVO, THO, TVO, n_PA );

	input n_PCLK;
	input PCLK;

	input BLNK;
	input DB_PAR;
	input F_AT;
	input SC_CNT;
	input RESCL;
	input E_EV;
	input TSTEP;
	input F_TB;
	input H0_DD;
	input n_H2_D;
	input I_1_32;
	input W6_2_Ena;

	input [13:0] PAD_in;
	inout [7:0] CPU_DB;
	input [4:0] TH;
	input [4:0] TV;
	input NTH;
	input NTV;
	input [2:0] FV;

	output [2:0] n_FVO;
	output [4:0] THO;
	output [4:0] TVO;
	output [13:0] n_PA;

endmodule // PAR
module BGCol(
	n_PCLK, PCLK,
	H0_DD, F_TA, F_TB, n_FO, F_AT, THO, TVO, FH, PD, n_CLPB,
	BGC);

	input n_PCLK;
	input PCLK;

	input H0_DD;
	input F_TA;
	input F_TB;
	input n_FO;
	input F_AT;
	input [4:0] THO;
	input [4:0] TVO;
	input [2:0] FH;
	input [7:0] PD;
	input n_CLPB;

	output [3:0] BGC;

endmodule // BGCol
module HVDecoder (
	H_in, V_in, VB, BLNK,
	HPLA_out, VPLA_out);

	input [8:0] H_in;
	input [8:0] V_in;
	input VB;
	input BLNK;

	output [23:0] HPLA_out;
	output [9:0] VPLA_out;

	HDecoder hpla (.H(H_in), .VB(VB), .BLNK(BLNK), .dec_out(HPLA_out) );
	VDecoder vpla (.V(V_in), .dec_out(VPLA_out) );

endmodule // HVDecoder
module VDecoder (V, dec_out);

	input [8:0] V;
	output [9:0] dec_out;

	wire [8:0] nV;
	assign nV = ~V;

	wire [17:0] d;
	assign d = {V[8],nV[8],V[7],nV[7],V[6],nV[6],V[5],nV[5],V[4],nV[4],V[3],nV[3],V[2],nV[2],V[1],nV[1],V[0],nV[0]};

`ifdef RP2C02

	assign dec_out[0] = ~|{d[0],d[2],d[4],d[7],d[8],d[10],d[12],d[14]};
	assign dec_out[1] = ~|{d[1],d[3],d[4],d[7],d[8],d[10],d[12],d[14]};
	assign dec_out[2] = ~|{d[0],d[3],d[4],d[7],d[9],d[11],d[13],d[15],d[16]};
	assign dec_out[3] = ~|{d[0],d[3],d[5],d[7],d[8],d[10],d[12],d[14]};
	assign dec_out[4] = ~|{d[0],d[3],d[5],d[7],d[8],d[10],d[12],d[14]};
	assign dec_out[5] = ~|{d[1],d[3],d[5],d[7],d[9],d[11],d[13],d[15],d[17]};
	assign dec_out[6] = ~|{d[1],d[3],d[5],d[7],d[8],d[10],d[12],d[14]};
	assign dec_out[7] = ~|{d[0],d[3],d[4],d[7],d[9],d[11],d[13],d[15],d[16]};
	assign dec_out[8] = ~|{d[0],d[3],d[4],d[7],d[9],d[11],d[13],d[15],d[16]};
	assign dec_out[9] = 1'b0; 		// Not present in NTSC PPUs

`elsif RP2C07

	assign dec_out[0] = ~|{d[1],d[3],d[5],d[7],d[8],d[11],d[13],d[15],d[16]};
	assign dec_out[1] = ~|{d[0],d[3],d[4],d[6],d[9],d[11],d[13],d[15],d[16]};
	assign dec_out[2] = ~|{d[0],d[3],d[5],d[7],d[9],d[11],d[13],d[15],d[17]};
	assign dec_out[3] = ~|{d[1],d[3],d[5],d[7],d[8],d[10],d[12],d[14]};
	assign dec_out[4] = ~|{d[0],d[3],d[5],d[7],d[8],d[10],d[12],d[14]};
	assign dec_out[5] = ~|{d[1],d[3],d[5],d[7],d[9],d[11],d[13],d[15],d[17]};
	assign dec_out[6] = ~|{d[1],d[3],d[5],d[7],d[8],d[10],d[12],d[14]};
	assign dec_out[7] = ~|{d[0],d[2],d[4],d[7],d[8],d[10],d[13],d[15],d[16]};
	assign dec_out[8] = ~|{d[0],d[2],d[4],d[7],d[8],d[10],d[13],d[15],d[16]};
	assign dec_out[9] = ~|{d[0],d[3],d[5],d[6],d[9],d[11],d[13],d[15],d[16]};

`else
`endif

endmodule // VDecoder
module VRAM_Control(
	n_PCLK, PCLK, 
	n_R7, n_W7, n_DBE, H0_D, BLNK, nPA,
	DB_PAR, TSTEP, WR, RD, n_ALE, PD_RB, XRB, TH_MUX);

	input n_PCLK;
	input PCLK;

	input n_R7;
	input n_W7;
	input n_DBE;
	input H0_D;
	input BLNK;
	input [13:0] nPA;

	output DB_PAR;
	output TSTEP;
	output WR;
	output RD;
	output n_ALE;
	output PD_RB;
	output XRB;
	output TH_MUX;

endmodule // VRAM_Control
module ReadBuffer(XRB, RC, PD_RB, PD_in, CPU_DB);

	input XRB;
	input RC;
	input PD_RB;
	input [7:0] PD_in;
	inout [7:0] CPU_DB;

endmodule // ReadBuffer
module ACLKGen(PHI1, PHI2, ACLK1, nACLK2, RES);

	input PHI1;
	input PHI2;
	output ACLK1;
	output nACLK2;
	input RES;

	wire n_latch1_out;
	wire n_latch2_out;
	wire latch1_in;

	dlatch phi1_latch (
		.d(latch1_in),
		.en(PHI1),
		.nq(n_latch1_out) );

	dlatch phi2_latch (
		.d(n_latch1_out),
		.en(PHI2),
		.nq(n_latch2_out) );

	nor (latch1_in, RES, n_latch2_out);

	wire n1;
	nor (n1, ~PHI1, latch1_in);
	nor (ACLK1, ~PHI1, n_latch2_out);
	not (nACLK2, n1);

endmodule // ACLKGen
module SoftTimer(
	PHI1, ACLK1, nACLK2,
	RES, n_R4015, W4017, DB, DMCINT, INT_out, nLFO1, nLFO2);

	input PHI1;
	input ACLK1;
	input nACLK2;

	input RES;
	input n_R4015;
	input W4017;
	inout [7:0] DB;
	input DMCINT;
	output INT_out;
	output nLFO1;
	output nLFO2;

	wire n_mode;
	wire mode;
	wire [5:0] PLA_out;
	wire Z2;
	wire F1;				// 1: Reset LFSR
	wire F2;				// 1: Perform the LFSR step
	wire sin;
	wire [14:0] sout;
	wire [14:0] n_sout;

	// SoftCLK control circuits have a very conventional division, because they are "scattered" in an even layer on the chip and it is difficult to determine their boundaries

	SoftCLK_Control ctrl (
		.PHI1(PHI1),
		.ACLK1(ACLK1),
		.RES(RES),
		.DB(DB),
		.DMCINT(DMCINT),
		.n_R4015(n_R4015),
		.W4017(W4017),
		.PLA_in(PLA_out),
		.n_mdout(n_mode),
		.mdout(mode),
		.Timer_Int(INT_out) );

	SoftCLK_LFSR_Control lfsr_ctrl (
		.ACLK1(ACLK1),
		.nACLK2(nACLK2),
		.RES(RES),
		.W4017(W4017),
		.n_mode(n_mode),
		.mode(mode),
		.PLA_in(PLA_out),
		.C13(sout[13]),
		.C14(sout[14]),
		.Z2(Z2),
		.F1(F1),
		.F2(F2),
		.sin_toLFSR(sin) );

	SoftCLK_LFSR lfsr (
		.ACLK1(ACLK1),
		.F1_Reset(F1),
		.F2_Step(F2),
		.sin(sin),
		.sout(sout),
		.n_sout(n_sout) );

	SoftCLK_PLA pla (
		.s(sout),
		.ns(n_sout),
		.md(mode),
		.PLA_out(PLA_out) );

	// LFO Output

	wire tmp1;
	nor (tmp1, PLA_out[0], PLA_out[1], PLA_out[2], PLA_out[3], PLA_out[4], Z2);
	wire tmp2;
	nor (tmp2, tmp1, nACLK2);
	assign nLFO1 = ~tmp2;

	wire tmp3;
	nor (tmp3, PLA_out[1], PLA_out[3], PLA_out[4], Z2);
	wire tmp4;
	nor (tmp4, tmp3, nACLK2);
	assign nLFO2 = ~tmp4;

endmodule // SoftTimer
module SoftCLK_Control(
	PHI1, ACLK1,
	RES, DB, DMCINT, n_R4015, W4017, PLA_in,
	n_mdout, mdout, Timer_Int);

	input PHI1;
	input ACLK1;

	input RES;
	inout [7:0] DB;
	input DMCINT;
	input n_R4015;
	input W4017;
	input [5:0] PLA_in;

	inout n_mdout;
	output mdout;
	output Timer_Int;

	wire R4015_clear;
	wire mask_clear;
	wire intff_out;
	wire n_intff_out;
	wire int_sum;
	wire int_latch_out;

	nor (R4015_clear, n_R4015, PHI1);

	RegisterBit mode (.d(DB[7]), .ena(W4017), .ACLK1(ACLK1), .nq(n_mdout) );
	RegisterBit mask (.d(DB[6]), .ena(W4017), .ACLK1(ACLK1), .q(mask_clear) );
	rsff_2_4 int_ff (.res1(RES), .res2(R4015_clear), .res3(mask_clear), .s(n_mdout & PLA_in[3]), .q(intff_out), .nq(n_intff_out) );
	dlatch md_latch (.d(n_mdout), .en(ACLK1), .nq(mdout) );
	dlatch int_latch (.d(n_intff_out), .en(ACLK1), .q(int_latch_out) );
	bustris int_status (.a(int_latch_out), .n_x(DB[6]), .n_en(n_R4015) );

	nor (int_sum, intff_out, DMCINT);
	assign Timer_Int = ~int_sum;

endmodule // SoftCLK_Control
module SoftCLK_LFSR_Control(
	ACLK1, nACLK2,
	RES, W4017, n_mode, mode, PLA_in, C13, C14,
	Z2, F1, F2, sin_toLFSR);

	input ACLK1;
	input nACLK2;

	input RES;
	input W4017;
	inout n_mode;
	input mode;
	input [5:0] PLA_in;
	input C13;
	input C14;

	output Z2;
	output F1;
	output F2;
	output sin_toLFSR;

	wire Z1;

	// LFSR control

	wire t1;
	nor (t1, PLA_in[3], PLA_in[4], Z1);
	nor (F1, t1, nACLK2);
	nor (F2, ~t1, nACLK2);

	// LFO control

	wire z1_out;
	wire z2_out;
	wire zff_out;
	wire zff_set;
	nor (zff_set, z1_out, nACLK2);
	dlatch z1 (.d(zff_out), .en(ACLK1), .q(z1_out), .nq(Z1) );
	dlatch z2 (.d(n_mode), .en(ACLK1), .q(z2_out) );
	rsff_2_3 z_ff (.res1(RES), .res2(W4017), .s(zff_set), .q(zff_out) );
	nor (Z2, z1_out, z2_out);

	// LFSR shift in

	wire tmp1;
	nor (tmp1, C13, C14, PLA_in[5]);
	nor (sin_toLFSR, C13 & C14, tmp1);

endmodule // SoftCLK_LFSR_Control
module SoftCLK_LFSR_Bit(
	ACLK1,
	sin, F1, F2,
	sout, n_sout);

	input ACLK1;

	input sin;
	input F1;
	input F2;

	output sout;
	output n_sout;

	wire inlatch_out;
	dlatch in_latch (
		.d(F2 ? sin : (F1 ? 1'b1 : 1'bz)),
		.en(1'b1), .nq(inlatch_out));
	dlatch out_latch (.d(inlatch_out), .en(ACLK1), .q(n_sout), .nq(sout));

endmodule // SoftCLK_LFSR_Bit
module SoftCLK_LFSR(
	ACLK1, F1_Reset, F2_Step, sin,
	sout, n_sout);

	input ACLK1;
	input F1_Reset;
	input F2_Step;
	input sin;

	output [14:0] sout;
	output [14:0] n_sout;

	SoftCLK_LFSR_Bit bits [14:0] (
		.ACLK1(ACLK1),
		.sin({sout[13:0],sin}),
		.F1(F1_Reset),
		.F2(F2_Step),
		.sout(sout),
		.n_sout(n_sout) );

endmodule // SoftCLK_LFSR
module SoftCLK_PLA(s, ns, md, PLA_out);

	input [14:0] s;
	input [14:0] ns;
	input md; 			// For PLA[3]
	output [5:0] PLA_out;

	nor (PLA_out[0], ns[0], s[1], s[2], s[3], s[4], ns[5], ns[6], s[7], s[8], s[9], s[10], s[11], ns[12], s[13], s[14]);
	nor (PLA_out[1], ns[0], ns[1], s[2], s[3], s[4], s[5], s[6], s[7], s[8], ns[9], ns[10], s[11], ns[12], ns[13], s[14]);
	nor (PLA_out[2], ns[0], ns[1], s[2], s[3], ns[4], s[5], ns[6], ns[7], s[8], s[9], ns[10], ns[11], s[12], ns[13], s[14]);
	nor (PLA_out[3], ns[0], ns[1], ns[2], ns[3], ns[4], s[5], s[6], s[7], s[8], ns[9], s[10], ns[11], s[12], s[13], s[14], md);	// ⚠️
	nor (PLA_out[4], ns[0], s[1], ns[2], s[3], s[4], s[5], s[6], ns[7], ns[8], s[9], s[10], s[11], ns[12], ns[13], ns[14]);
	nor (PLA_out[5], s[0], s[1], s[2], s[3], s[4], s[5], s[6], s[7], s[8], s[9], s[10], s[11], s[12], s[13], s[14]);

endmodule // SoftCLK_PLA
module Core(
	core_PHI0, core_PHI1, core_PHI2,
	core_nNMI, core_nIRQ, core_nRES, core_RDY, 
	core_SO, core_RnW, core_SYNC, core_DPads, core_APads);

	input core_PHI0;
	output core_PHI1;
	output core_PHI2;

	input core_nNMI;
	input core_nIRQ;
	input core_nRES;
	input core_RDY;

	input core_SO;
	output core_RnW;
	output core_SYNC;
	inout [7:0] core_DPads;
	output [15:0] core_APads;

	Core6502 embedded_6502 (
		.n_NMI(core_nNMI),
		.n_IRQ(core_nIRQ),
		.n_RES(core_nRES),
		.PHI0(core_PHI0),
		.PHI1(core_PHI1),
		.PHI2(core_PHI2),
		.RDY(core_RDY),
		.SO(core_SO),
		.RnW(core_RnW),
		.SYNC(core_SYNC),
		.A(core_APads),
		.D(core_DPads) );

endmodule // Core
module CLK_Divider(n_CLK_frompad, PHI0_tocore, PHI2_fromcore, n_M2_topad);

	input n_CLK_frompad;
	output PHI0_tocore;
	input PHI2_fromcore;
	output n_M2_topad;

	wire [5:0] sout;
	wire rst;
	wire q;
	wire nq;
	wire nval_4;

	DivPhaseSplitter phase_split (
		.n_clk(n_CLK_frompad),
		.q(q),
		.nq(nq) );

	assign PHI0_tocore = ~sout[5];
	nor (rst, PHI0_tocore, sout[4]);

	DivSRBit sr0 (.q(q), .nq(nq), .rst(rst), .sin(PHI0_tocore), .sout(sout[0]));
	DivSRBit sr1 (.q(q), .nq(nq), .rst(rst), .sin(sout[0]), .sout(sout[1]));
	DivSRBit sr2 (.q(q), .nq(nq), .rst(rst), .sin(sout[1]), .sout(sout[2]));
	DivSRBit sr3 (.q(q), .nq(nq), .rst(rst), .sin(sout[2]), .sout(sout[3]));
	DivSRBit sr4 (.q(q), .nq(nq), .rst(1'b0), .sin(sout[3]), .sout(sout[4]), .n_val(nval_4));
	DivSRBit sr5 (.q(q), .nq(nq), .rst(1'b0), .sin(sout[4]), .sout(sout[5]));

	nor (n_M2_topad, nval_4, PHI2_fromcore);

endmodule // CLK_Divider
module DivSRBit(q, nq, rst, sin, n_val, sout);

	input q;
	input nq;
	input rst;
	input sin;
	output n_val;
	output sout;

	wire out_val;

	dlatch in_latch (
		.d(sin),
		.en(q),
		.nq(n_val) );

	dlatch out_latch (
		.d(n_val),
		.en(nq),
		.q(out_val) );

	nor (sout, out_val, rst);

endmodule // DivSRBit
module DivPhaseSplitter(n_clk, q, nq);

	input n_clk;
	output q;
	output nq;

	(* keep = "true" *) wire not1_out;
	(* keep = "true" *) wire not2_out;

	assign not1_out = ~n_clk;
	assign not2_out = ~not1_out;

	nor (nq, not1_out, q);
	nor (q, nq, not2_out);

endmodule // DivPhaseSplitter
module LengthCounters(
	nACLK2, ACLK1,
	RES, DB, n_R4015, W4015, nLFO2, 
	W4003, W4007, W400B, W400F,
	SQA_LC, SQB_LC, TRI_LC, RND_LC,
	NOSQA, NOSQB, NOTRI, NORND);

	input nACLK2;
	input ACLK1;

	input RES;
	inout [7:0] DB;
	input n_R4015;
	input W4015;
	input nLFO2;

	input W4003;
	input W4007;
	input W400B;
	input W400F;

	input SQA_LC;
	input SQB_LC;
	input TRI_LC;
	input RND_LC;

	output NOSQA;
	output NOSQB;
	output NOTRI;
	output NORND;

	wire [7:0] LC;

	LengthCounter_PLA pla (
		.DB(DB),
		.LC_Out(LC) );

	LengthCounter length_cnt [3:0] (
		.nACLK2(nACLK2),
		.ACLK1(ACLK1),
		.RES(RES),
		.W400x_load({W400F, W400B, W4007, W4003}),
		.n_R4015(n_R4015),
		.W4015(W4015),
		.LC(LC),
		.dbit_ena({DB[3], DB[2], DB[1], DB[0]}),
		.nLFO2(nLFO2),
		.Carry_in({RND_LC, TRI_LC, SQB_LC, SQA_LC}),
		.NotCount({NORND, NOTRI, NOSQB, NOSQA}) );

endmodule // LengthCounters
module LengthCounter(
	nACLK2, ACLK1,
	RES, W400x_load, n_R4015, W4015, LC, dbit_ena, nLFO2,
	Carry_in, NotCount);

	input nACLK2;
	input ACLK1;

	input RES;
	input W400x_load;
	input n_R4015;
	input W4015;
	input [7:0] LC;
	inout dbit_ena;
	input nLFO2;

	input Carry_in;
	output NotCount;

	wire STEP;
	wire Carry_out;

	LC_DownCounter cnt (
		.Clk(ACLK1),
		.Clear(RES),
		.Step(STEP),
		.Load(W400x_load),
		.Val_in(LC),
		.Carry_in(Carry_in),
		.Carry_out(Carry_out) );

	LC_Control ctl (
		.nACLK2(nACLK2),
		.ACLK1(ACLK1),
		.RES(RES),
		.W400x_load(W400x_load),
		.n_R4015(n_R4015),
		.W4015(W4015),
		.dbit_ena(dbit_ena),
		.nLFO2(nLFO2),
		.cout(Carry_out),
		.NotCount(NotCount),
		.Step(STEP) );

endmodule // LengthCounter
module LC_Control(
	nACLK2, ACLK1,
	RES, W400x_load, n_R4015, W4015, dbit_ena, nLFO2, cout,
	NotCount, Step);

	input nACLK2;
	input ACLK1;

	input RES;
	input W400x_load;
	input n_R4015;
	input W4015;
	inout dbit_ena;
	input nLFO2;
	input cout;

	output NotCount;
	output Step;

	wire LCDIS;
	wire ena_latch_out;
	wire cout_latch_out;
	wire StatOut;
	wire n_StatOut;
	wire step_latch_out;
	wire ACLK4;		// Other ACLK

	assign ACLK4 = ~nACLK2;
	sdffre ena_ff (.d(dbit_ena), .en(W4015), .res(RES), .phi_keep(ACLK1), .nq(LCDIS));
	dlatch ena_latch (.d(LCDIS), .en(ACLK1), .q(ena_latch_out));
	dlatch cout_latch (.d(cout), .en(ACLK1), .q(cout_latch_out));
	rsff_2_4 stat_ff (
		.res1(ena_latch_out & ACLK4),
		.res2(cout_latch_out & Step),
		.res3(RES),
		.s(W400x_load),
		.q(StatOut),
		.nq(n_StatOut) );
	dlatch step_latch (.d(n_StatOut), .en(ACLK1), .q(step_latch_out));

	assign NotCount = ~StatOut;
	bustris stat_tris (.a(n_StatOut), .n_x(dbit_ena), .n_en(n_R4015));

	nor (Step, step_latch_out, nLFO2);

endmodule // LC_Control
module LC_DownCounter(Clk, Clear, Step, Load, Val_in, Carry_in, Carry_out);

	input Clk;
	input Clear;
	input Step;
	input Load;
	input [7:0] Val_in;
	input Carry_in;
	output Carry_out;

	wire [7:0] carry_chain;
	wire [7:0] cnt_value; 	// debug

	DownCounterBit lc_cnt [7:0] (
		.ACLK1(Clk),
		.load(Load),
		.clear(Clear),
		.step(Step),
		.d(Val_in),
		.q(cnt_value),
		.cin({carry_chain[6:0], Carry_in}),
		.cout(carry_chain) );

	assign Carry_out = carry_chain[7];

endmodule // LC_DownCounter
module LengthCounter_PLA(DB, LC_Out);

	inout [7:0] DB;
	output [7:0] LC_Out;

	wire [4:0] Dec1_in;
	wire [31:0] Dec1_out;

	dlatch din [4:0] (.d(DB[7:3]), .en(1'b1), .q(Dec1_in));
	LengthDecoder1 dec1 (.Dec1_in(Dec1_in), .Dec1_out(Dec1_out));
	LengthDecoder2 dec2 (.Dec2_in(Dec1_out), .Dec2_out(LC_Out));

endmodule // LengthCounter_PLA
module LengthDecoder1 (Dec1_in, Dec1_out);

	input [4:0] Dec1_in;
	output [31:0] Dec1_out;

	wire [4:0] d;
	wire [4:0] nd;

	assign d = Dec1_in;
	assign nd = ~Dec1_in;

	nor (Dec1_out[0], d[0], d[1], d[2], d[3], d[4]);
	nor (Dec1_out[1], d[0], nd[1], d[2], d[3], d[4]);
	nor (Dec1_out[2], d[0], d[1], nd[2], d[3], d[4]);
	nor (Dec1_out[3], d[0], nd[1], nd[2], d[3], d[4]);
	nor (Dec1_out[4], d[0], d[1], d[2], nd[3], d[4]);
	nor (Dec1_out[5], d[0], nd[1], d[2], nd[3], d[4]);
	nor (Dec1_out[6], d[0], d[1], nd[2], nd[3], d[4]);
	nor (Dec1_out[7], d[0], nd[1], nd[2], nd[3], d[4]);

	nor (Dec1_out[8], d[0], d[1], d[2], d[3], nd[4]);
	nor (Dec1_out[9], d[0], nd[1], d[2], d[3], nd[4]);
	nor (Dec1_out[10], d[0], d[1], nd[2], d[3], nd[4]);
	nor (Dec1_out[11], d[0], nd[1], nd[2], d[3], nd[4]);
	nor (Dec1_out[12], d[0], d[1], d[2], nd[3], nd[4]);
	nor (Dec1_out[13], d[0], nd[1], d[2], nd[3], nd[4]);
	nor (Dec1_out[14], d[0], d[1], nd[2], nd[3], nd[4]);
	nor (Dec1_out[15], d[0], nd[1], nd[2], nd[3], nd[4]);

	nor (Dec1_out[16], nd[0], d[1], d[2], d[3], d[4]);
	nor (Dec1_out[17], nd[0], nd[1], d[2], d[3], d[4]);
	nor (Dec1_out[18], nd[0], d[1], nd[2], d[3], d[4]);
	nor (Dec1_out[19], nd[0], nd[1], nd[2], d[3], d[4]);
	nor (Dec1_out[20], nd[0], d[1], d[2], nd[3], d[4]);
	nor (Dec1_out[21], nd[0], nd[1], d[2], nd[3], d[4]);
	nor (Dec1_out[22], nd[0], d[1], nd[2], nd[3], d[4]);
	nor (Dec1_out[23], nd[0], nd[1], nd[2], nd[3], d[4]);

	nor (Dec1_out[24], nd[0], d[1], d[2], d[3], nd[4]);
	nor (Dec1_out[25], nd[0], nd[1], d[2], d[3], nd[4]);
	nor (Dec1_out[26], nd[0], d[1], nd[2], d[3], nd[4]);
	nor (Dec1_out[27], nd[0], nd[1], nd[2], d[3], nd[4]);
	nor (Dec1_out[28], nd[0], d[1], d[2], nd[3], nd[4]);
	nor (Dec1_out[29], nd[0], nd[1], d[2], nd[3], nd[4]);
	nor (Dec1_out[30], nd[0], d[1], nd[2], nd[3], nd[4]);
	nor (Dec1_out[31], nd[0], nd[1], nd[2], nd[3], nd[4]);

endmodule // LengthDecoder1
module LengthDecoder2 (Dec2_in, Dec2_out);

	input [31:0] Dec2_in;
	output [7:0] Dec2_out;

	wire [31:0] d;
	assign d = Dec2_in;

	nor (Dec2_out[7], 
		d[0], d[1], d[2], d[3], d[5], d[6], d[7],
		d[8], d[9], d[10], d[11], d[13], d[14], d[15],
		d[17], d[18], d[19], d[20], d[21], d[22], d[23],
		d[24], d[25], d[26], d[27], d[28], d[29], d[30], d[31] );
	nor (Dec2_out[6], 
		d[0], d[1], d[2], d[4], d[5], d[6], d[7], 
		d[8], d[9], d[10], d[12], d[14], d[15], 
		d[17], d[18], d[19], d[20], d[21], d[22], d[23], 
		d[24], d[25], d[26], d[27], d[28], d[29], d[30], d[31] );
	nor (Dec2_out[5], 
		d[0], d[1], d[3], d[4], d[6], d[7], 
		d[8], d[9], d[11], d[13], d[14], d[15], 
		d[17], d[18], d[19], d[20], d[21], d[22], d[23], 
		d[24], d[25], d[26], d[27], d[28], d[29], d[30], d[31] );
	nor (Dec2_out[4], 
		d[0], d[2], d[3], d[6], 
		d[8], d[10], d[13], d[14], 
		d[17], d[18], d[19], d[20], d[21], d[22], d[23],
		d[24] );
	nor (Dec2_out[3], 
		d[1], d[2], 
		d[9], d[13], 
		d[17], d[18], d[19], d[20], 
		d[25], d[26], d[27], d[28] );
	nor (Dec2_out[2], 
		d[0], d[1], d[5], d[7], 
		d[8], 
		d[17], d[18], d[21], d[22], 
		d[25], d[26], d[29], d[30] );
	nor (Dec2_out[1], 
		d[0], d[6], d[7], 
		//...
		d[16], d[17], d[19], d[21], d[23], 
		d[25], d[27], d[29], d[31] );
	assign Dec2_out[0] = 1'b1;

endmodule //  LengthDecoder2
module DPCM_ControlReg (ACLK1, W4010, DB, Fx, n_IRQEN, LOOPMode);

	input ACLK1;
	input W4010;
	inout [7:0] DB;
	output [3:0] Fx;
	output n_IRQEN;
	output LOOPMode;

	RegisterBit f_reg [3:0] (.ACLK1(ACLK1), .ena(W4010), .d(DB[3:0]), .q(Fx) );
	RegisterBit loop_reg (.ACLK1(ACLK1), .ena(W4010), .d(DB[6]), .q(LOOPMode) );
	RegisterBit irq_reg (.ACLK1(ACLK1), .ena(W4010), .d(DB[7]), .nq(n_IRQEN) );

endmodule // DPCM_ControlReg
module DPCM_Control( nACLK2, ACLK1, ACLK2, PHI1, RES, RnW, LOCK, W4015, n_R4015, LOOPMode, n_IRQEN, DOUT, n_NOUT, SOUT, DFLOAD, DB,
	n_DMCAB, RUNDMC, DMCRDY, DMCINT, DSLOAD, DSSTEP, BLOAD, BSTEP, NSTEP, DSTEP, PCM );

	input nACLK2;
	input ACLK1;
	input ACLK2;
	input PHI1;
	input RES;
	input RnW;
	input LOCK;
	input W4015;
	input n_R4015;
	input LOOPMode;
	input n_IRQEN;
	input DOUT;
	input n_NOUT;
	input SOUT;
	input DFLOAD;
	inout [7:0] DB;

	output n_DMCAB;
	output RUNDMC;
	output DMCRDY;
	output DMCINT;
	output DSLOAD;
	output DSSTEP;
	output BLOAD;
	output BSTEP;
	output NSTEP;
	output DSTEP;
	output PCM;

	// Internal temp wires

	wire ED1;
	wire ED2;
	wire DMC1;
	wire DMC2;
	wire CTRL1;
	wire CTRL2;

	DPCM_IntControl int_ctrl (.RES(RES), .W4015(W4015), .n_R4015(n_R4015), .n_IRQEN(n_IRQEN), .AssertInt(ED1), .DB(DB), .DMCINT(DMCINT) );

	DPCM_EnableControl enable_ctrl (.ACLK1(ACLK1), .RES(RES), .W4015(W4015), .n_R4015(n_R4015), .LOOPMode(LOOPMode), .PCMDone(DMC1), .SOUT(SOUT), .DB(DB), .ED1(ED1), .DMC2(DMC2), .ED2(ED2) );

	DPCM_DMAControl dma_ctrl (.nACLK2(nACLK2), .ACLK1(ACLK1), .ACLK2(ACLK2), .PHI1(PHI1), .RnW(RnW), .RES(RES), .nDMAStop(CTRL1), .nDMCEnableDelay(CTRL2), .DMCRDY(DMCRDY), .RUNDMC(RUNDMC), .n_DMCAB(n_DMCAB) );

	DPCM_SampleCounterControl scnt_ctrl (.nACLK2(nACLK2), .ACLK1(ACLK1), .ACLK2(ACLK2), .PCMDone(DMC1), .DMCFinish(DMC2), .DMCEnable(ED2), .DFLOAD(DFLOAD), .DSLOAD(DSLOAD), .DSSTEP(DSSTEP), .NSTEP(NSTEP), .CTRL2(CTRL2) );

	DPCM_SampleBufferControl sbuf_ctrl (.nACLK2(nACLK2), .ACLK1(ACLK1), .ACLK2(ACLK2), .PHI1(PHI1), .RES(RES), .LOCK(LOCK), .DFLOAD(DFLOAD), .DOUT(DOUT), .n_NOUT(n_NOUT), .n_DMCAB(n_DMCAB), .BLOAD(BLOAD), .BSTEP(BSTEP), .PCM(PCM), .DSTEP(DSTEP), .DMC1(DMC1), .CTRL1(CTRL1) );

endmodule // DPCMControl
module DPCM_IntControl(RES, W4015, n_R4015, n_IRQEN, AssertInt, DB, DMCINT);

	input RES;
	input W4015;
	input n_R4015;
	input n_IRQEN;
	input AssertInt;
	inout [7:0] DB;
	output DMCINT;

	wire int_ff_nq;

	rsff_2_4 int_ff (.res1(W4015), .res2(n_IRQEN), .res3(RES), .s(AssertInt), .nq(int_ff_nq) );
	bustris int_stat (.a(int_ff_nq), .n_x(DB[7]), .n_en(n_R4015) );
	nor (DMCINT, int_ff_nq, n_IRQEN);

endmodule // DPCMIntControl
module DPCM_EnableControl(ACLK1, RES, W4015, n_R4015, LOOPMode, PCMDone, SOUT, DB, ED1, DMC2, ED2);

	input ACLK1;
	input RES;
	input W4015;
	input n_R4015;
	input LOOPMode;
	input PCMDone;
	input SOUT;
	inout [7:0] DB;
	output ED1;
	output DMC2;
	output ED2;

	wire sout_latch_nq;
	wire ena_ff_nq;

	dlatch sout_latch (.d(SOUT), .en(ACLK1), .q(DMC2), .nq(sout_latch_nq) );
	RegisterBitRes2 ena_ff (.ACLK1(ACLK1), .ena(W4015), .d(DB[4]), .res1(ED1), .res2(RES), .q(ED2), .nq(ena_ff_nq) );
	nor (ED1, LOOPMode, sout_latch_nq, ~PCMDone);
	bustris ena_stat (.a(ena_ff_nq), .n_x(DB[4]), .n_en(n_R4015) );

endmodule // DPCMEnableControl
module DPCM_DMAControl(nACLK2, ACLK1, ACLK2, PHI1, RnW, RES, nDMAStop, nDMCEnableDelay, DMCRDY, RUNDMC, n_DMCAB);

	input nACLK2;
	input ACLK1;
	input ACLK2;
	input PHI1;
	input RnW;
	input RES;
	input nDMAStop;
	input nDMCEnableDelay;
	output DMCRDY;
	output RUNDMC;
	output n_DMCAB;

	wire DMAStart;
	wire run_latch1_q;
	wire run_latch1_nq;
	wire start_set;
	wire rdy_ff_nq;

	dlatch run_latch1 (.d(DMAStart), .en(ACLK2), .q(run_latch1_q), .nq(run_latch1_nq) );
	dlatch run_latch2 (.d(run_latch1_nq), .en(ACLK1), .nq(RUNDMC) );
	assign start_set = ~( ~(~PHI1 & RnW) | nDMCEnableDelay | ~nDMAStop );
	rsff_2_4 start_ff (.res1(nDMCEnableDelay), .res2(RES), .res3(~nDMAStop), .s(start_set), .q(DMAStart) );
	rsff rdy_ff (.r(run_latch1_q & ACLK1), .s(ACLK2), .q(n_DMCAB), .nq(rdy_ff_nq) );
	nor (DMCRDY, DMAStart, rdy_ff_nq);

endmodule // DPCM_DMAControl
module DPCM_SampleCounterControl(nACLK2, ACLK1, ACLK2, PCMDone, DMCFinish, DMCEnable, DFLOAD, DSLOAD, DSSTEP, NSTEP, CTRL2);

	input nACLK2;
	input ACLK1;
	input ACLK2;
	input PCMDone;
	input DMCFinish;
	input DMCEnable;
	input DFLOAD;
	output DSLOAD;
	output DSSTEP;
	output NSTEP;
	output CTRL2;

	wire DMC3;
	wire en_latch1_nq;
	wire en_latch2_nq;
	wire en_latch3_q;

	dlatch en_latch1 (.d(DMCEnable), .en(ACLK1), .nq(en_latch1_nq) );
	dlatch en_latch2 (.d(en_latch1_nq), .en(ACLK2), .nq(en_latch2_nq) );
	dlatch en_latch3 (.d(en_latch2_nq), .en(ACLK1), .q(en_latch3_q), .nq(CTRL2) );
	nor (DMC3, nACLK2, en_latch1_nq, en_latch3_q);

	assign NSTEP = ~(~DFLOAD);
	assign DSLOAD = ~(~((DMCFinish & PCMDone) | DMC3));
	assign DSSTEP = ~(~PCMDone | DMC3 | DMCFinish);

endmodule // DPCM_SampleCounterControl
module DPCM_SampleBufferControl(nACLK2, ACLK1, ACLK2, PHI1, RES, LOCK, DFLOAD, DOUT, n_NOUT, n_DMCAB, BLOAD, BSTEP, PCM, DSTEP, DMC1, CTRL1);

	input nACLK2;
	input ACLK1;
	input ACLK2;
	input PHI1;
	input RES;
	input LOCK;
	input DFLOAD;
	input DOUT;
	input n_NOUT;
	input n_DMCAB;
	output BLOAD;
	output BSTEP;
	output PCM;
	output DSTEP;
	output DMC1;
	output CTRL1;

	wire n_DFLOAD;
	wire step_ff_nq;
	wire stop_ff_q;
	wire pcm_ff_nq;
	wire dout_latch_q;
	wire dstep_latch_q;
	wire stop_latch_nq;
	wire pcm_latch_q;

	assign n_DFLOAD = ~DFLOAD;

	rsff_2_3 step_ff (.res1(~(~stop_latch_nq | n_DFLOAD | n_NOUT)), .res2(RES), .s(BLOAD), .nq(step_ff_nq) );
	rsff_2_3 stop_ff (.res1(BLOAD), .res2(RES), .s(PCM), .q(stop_ff_q), .nq(CTRL1) );
	rsff_2_3 pcm_ff (.res1(DMC1), .res2(RES), .s(PCM), .nq(pcm_ff_nq) );

	dlatch dout_latch (.d(DOUT), .en(ACLK1), .q(dout_latch_q) );
	dlatch dstep_latch (.d(step_ff_nq), .en(ACLK1), .q(dstep_latch_q) );
	dlatch stop_latch (.d(stop_ff_q), .en(ACLK1), .nq(stop_latch_nq) );
	dlatch pcm_latch (.d(pcm_ff_nq), .en(ACLK1), .q(pcm_latch_q) );

	nor (PCM, PHI1, n_DMCAB);
	nor (DMC1, pcm_latch_q, ~ACLK2);
	nor (DSTEP, dout_latch_q, dstep_latch_q, n_DFLOAD, LOCK);
	nor (BLOAD, stop_latch_nq, n_DFLOAD, n_NOUT);
	nor (BSTEP, n_DFLOAD, ~n_NOUT);

endmodule // DPCM_SampleBufferControl
module DPCM_Decoder (Fx, FR);

	input [3:0] Fx;
	output [8:0] FR;

	wire [15:0] Dec1_out;

	DPCM_Decoder1 dec1 (.Dec1_in(Fx), .Dec1_out(Dec1_out) );
	DPCM_Decoder2 dec2 (.Dec2_in(Dec1_out), .Dec2_out(FR) );

endmodule // DPCM_Decoder
module DPCM_Decoder1 (Dec1_in, Dec1_out);

	input [3:0] Dec1_in;
	output [15:0] Dec1_out;

	wire [3:0] F;
	wire [3:0] nF;

	assign F = Dec1_in;
	assign nF = ~Dec1_in;

	nor (Dec1_out[0], F[0], F[1], F[2], F[3]);
	nor (Dec1_out[1], nF[0], F[1], F[2], F[3]);
	nor (Dec1_out[2], F[0], nF[1], F[2], F[3]);
	nor (Dec1_out[3], nF[0], nF[1], F[2], F[3]);
	nor (Dec1_out[4], F[0], F[1], nF[2], F[3]);
	nor (Dec1_out[5], nF[0], F[1], nF[2], F[3]);
	nor (Dec1_out[6], F[0], nF[1], nF[2], F[3]);
	nor (Dec1_out[7], nF[0], nF[1], nF[2], F[3]);

	nor (Dec1_out[8], F[0], F[1], F[2], nF[3]);
	nor (Dec1_out[9], nF[0], F[1], F[2], nF[3]);
	nor (Dec1_out[10], F[0], nF[1], F[2], nF[3]);
	nor (Dec1_out[11], nF[0], nF[1], F[2], nF[3]);
	nor (Dec1_out[12], F[0], F[1], nF[2], nF[3]);
	nor (Dec1_out[13], nF[0], F[1], nF[2], nF[3]);
	nor (Dec1_out[14], F[0], nF[1], nF[2], nF[3]);
	nor (Dec1_out[15], nF[0], nF[1], nF[2], nF[3]);

endmodule // DPCM_Decoder1
module DPCM_Decoder2 (Dec2_in, Dec2_out);

	input [15:0] Dec2_in;
	output [8:0] Dec2_out;

	wire [15:0] d;
	assign d = Dec2_in;

	nor (Dec2_out[0], d[1], d[4], d[9], d[14], d[15]);
	nor (Dec2_out[1], d[6], d[7], d[8], d[9], d[10], d[11], d[12], d[13]);
	nor (Dec2_out[2], d[0], d[1], d[2], d[3], d[7], d[8], d[10], d[11], d[13]);
	nor (Dec2_out[3], d[0], d[2], d[7], d[10], d[15]);
	nor (Dec2_out[4], d[1], d[2], d[4], d[8], d[12], d[13], d[14]);
	nor (Dec2_out[5], d[1], d[2], d[3], d[7], d[8], d[9], d[12], d[13], d[14], d[15]);
	nor (Dec2_out[6], d[1], d[5], d[8], d[12], d[13], d[14]);
	nor (Dec2_out[7], d[0], d[2], d[5], d[6], d[8], d[15]);
	nor (Dec2_out[8], d[1], d[3], d[5], d[6], d[8], d[9], d[10], d[11], d[12]);

endmodule // DPCM_Decoder2
module DPCM_FreqLFSR (nACLK2, ACLK1, ACLK2, RES, FR, DFLOAD);

	input nACLK2;
	input ACLK1;
	input ACLK2;
	input RES;
	input [8:0] FR;
	output DFLOAD;

	wire feedback;
	wire DFSTEP;
	wire [8:0] sout;
	wire nor1_out;
	wire nor2_out;
	wire nor3_out;

	assign feedback = ~((sout[0] & sout[4]) | RES | ~(sout[0] | sout[4] | nor1_out));
	assign nor3_out = ~(RES | ~nor2_out);
	assign DFLOAD = ~(~ACLK2 | ~nor3_out);
	assign DFSTEP = ~(~ACLK2 | nor3_out);

	nor (nor1_out, sout[0], sout[1], sout[2], sout[3], sout[4], sout[5], sout[6], sout[7], sout[8]);
	nor (nor2_out, ~sout[0], sout[1], sout[2], sout[3], sout[4], sout[5], sout[6], sout[7], sout[8]);

	DPCM_LFSRBit lfsr [8:0] (.ACLK1(ACLK1), .load(DFLOAD), .step(DFSTEP), .val(FR), .sin({feedback,sout[8:1]}), .sout(sout) );

endmodule // DPCM_FreqLFSR
module DPCM_LFSRBit (ACLK1, load, step, val, sin, sout);

	input ACLK1;
	input load;
	input step;
	input val;
	input sin;
	output sout;

	wire d;
	wire in_latch_nq;

	assign d = load ? val : (step ? sin : 1'bz);

	dlatch in_latch (.d(d), .en(1'b1), .nq(in_latch_nq) );
	dlatch out_latch (.d(in_latch_nq), .en(ACLK1), .nq(sout) );

endmodule // DPCM_LFSRBit
module DPCM_SampleCounterReg (ACLK1, W4013, DB, DSC);

	input ACLK1;
	input W4013;
	inout [7:0] DB;
	output [7:0] DSC;

	RegisterBit scnt_reg [7:0] (.ACLK1(ACLK1), .ena(W4013), .d(DB[7:0]), .q(DSC[7:0]) );

endmodule // DPCM_SampleCounterReg
module DPCM_SampleCounter (ACLK1, RES, DSLOAD, DSSTEP, DSC, SOUT);

	input ACLK1;
	input RES;
	input DSLOAD;
	input DSSTEP;
	input [7:0] DSC;
	output SOUT;

	wire [11:0] cout;

	DownCounterBit cnt [11:0] (.ACLK1(ACLK1), .d({DSC[7:0],4'b0000}), .load(DSLOAD), .clear(RES), .step(DSSTEP), .cin({cout[10:0],1'b1}), .cout(cout) );

	assign SOUT = cout[11];

endmodule // DPCM_SampleCounter
module DPCM_SampleBitCounter (ACLK1, RES, NSTEP, n_NOUT);

	input ACLK1;
	input RES;
	input NSTEP;
	output n_NOUT;

	wire [2:0] cout;

	CounterBit cnt [2:0] (.ACLK1(ACLK1), .d(3'b000), .load(RES), .clear(RES), .step(NSTEP), .cin({cout[1:0],1'b1}), .cout(cout) );
	dlatch nout_latch (.d(cout[2]), .en(ACLK1), .nq(n_NOUT));

endmodule // DPCM_SampleBitCounter
module DPCM_SampleBuffer (ACLK1, RES, BLOAD, BSTEP, PCM, DB, n_BOUT);

	input ACLK1;
	input RES;
	input BLOAD;
	input BSTEP;
	input PCM;
	inout [7:0] DB;
	output n_BOUT;

	wire [7:0] buf_nq;
	wire [7:0] sout;

	RegisterBit buf_reg [7:0] (.ACLK1(ACLK1), .ena(PCM), .d(DB), .nq(buf_nq) );
	DPCM_SRBit shift_reg [7:0] (.ACLK1(ACLK1), .clear(RES), .load(BLOAD), .step(BSTEP), .n_val(buf_nq), .sin({1'b0,sout[7:1]}), .sout(sout) );

	assign n_BOUT = ~sout[0];

endmodule // DPCM_SampleBuffer
module DPCM_SRBit (ACLK1, clear, load, step, n_val, sin, sout);

	input ACLK1;
	input clear;
	input load;
	input step;
	input n_val;
	input sin;
	output sout;

	wire d;
	wire in_latch_nq;

	assign d = clear ? 1'b0 : (load ? n_val : (step ? in_latch_nq : (ACLK1 ? ~sout : 1'bz)));

	dlatch in_latch (.d(sin), .en(ACLK1), .nq(in_latch_nq) );
	dlatch out_latch (.d(d), .en(1'b1), .nq(sout) );

endmodule // DPCM_SRBit
module DPCM_AddressReg (ACLK1, W4012, DB, DPA);

	input ACLK1;
	input W4012;
	inout [7:0] DB;
	output [7:0] DPA;

	RegisterBit addr_reg [7:0] (.ACLK1(ACLK1), .ena(W4012), .d(DB[7:0]), .q(DPA[7:0]) );

endmodule // DPCM_AddressReg
module DPCM_AddressCounter (ACLK1, RES, DSLOAD, DSSTEP, DPA, DMC_Addr);

	input ACLK1;
	input RES;
	input DSLOAD;
	input DSSTEP;
	input [7:0] DPA;
	output [15:0] DMC_Addr;

	wire [7:0] addr_lo_cout;
	wire [6:0] addr_hi_cout;
	wire [7:0] addr_lo_q;
	wire [6:0] addr_hi_q;

	CounterBit addr_lo [7:0] (.ACLK1(ACLK1), .d({DPA[1:0], 6'b000000}), .load(DSLOAD), .clear(RES), .step(DSSTEP), .cin({addr_lo_cout[6:0],1'b1}), .q(addr_lo_q), .cout(addr_lo_cout));
	CounterBit addr_hi [6:0] (.ACLK1(ACLK1), .d({1'b1, DPA[7:2]}), .load(DSLOAD), .clear(RES), .step(DSSTEP), .cin({addr_hi_cout[5:0],addr_lo_cout[7]}), .q(addr_hi_q), .cout(addr_hi_cout) );

	assign DMC_Addr = {1'b1,addr_hi_q,addr_lo_q};

endmodule // DPCM_AddressCounter