dakies/OSS_Verilog huggingface dataset:
module ta161_bar (
    input           CLR_BAR,             // CLEAR
    input           LD_BAR,              // LOAD
    input           ENT,                 // ENABLE T
    input           ENP,                 // ENABLE P
    input           CLK,                 // CLK 
    input           A, B, C, D,          // DATA IN
    output          QA, QB, QC, QD,      // DATA OUT
    output          RCO                  // RIPPLE CARRY OUTPUT
);

// 4-bit synchronous counter
// Replaced ta161 in THESIS with jeff_74x161
jeff_74x161 U1 (
    .clr_bar(CLR_BAR),
    .ld_bar(LD_BAR),
    .ent(ENT),
    .enp(ENP),
    .clk(CLK),
    .a(A),
    .b(B),
    .c(C),
    .d(D),
    .qa(QA),
    .qb(QB),
    .qc(QC),
    .qd(QD),
    .rco(RCO)
);

endmodule
module ta157_8(
    input  [7:0]    A8,                 // 
    input  [7:0]    B8,                 // 
    input           S,                  //
    input           EN_BAR,             //
    output [7:0]    Y8                  // 
);


// Replaced ta157_bar and ta157 in THESIS with jeff_74x157
assign EN = ~EN_BAR;

// Lower 4 bits - Quad 2x1 multiplexers
jeff_74x157_behavioral MUX0 (
    .a(A8[3:0]),
    .b(B8[3:0]),
    .s(S),
    .en(EN),
    .y(Y8[3:0])
);

// Upper 4 bits - Quad 2x1 multiplexers
jeff_74x157_behavioral MUX1 (
    .a(A8[7:4]),
    .b(B8[7:4]),
    .s(S),
    .en(EN),
    .y(Y8[7:4])
);

endmodule
module opcodedec (
    input  [3:0]    OPCODE,             // 
    input  [7:4]    MW_AD_HIGH,         // 
    input  [12:9]   MW_BOP,             //
    output [7:4]    TO_COUNTER,         //
    output          EIL_BAR             //
);

// WIRES
wire W1;

// ASSIGN VALUES
assign LOW = 1'b0;
assign EIL_BAR = W1;

// Four (2x1) multiplexers
ta157_4 U1 (
    .A4(OPCODE),
    .B4(MW_AD_HIGH),
    .S(W1),
    .EN_BAR(LOW),
    .Y4(TO_COUNTER)
);

// FOUR INPUT NAND GATE
// Replaced nand4 in THESIS with jeff's nand4
nand4_behavioral U2 (
    .a(MW_BOP[9]),
    .b(MW_BOP[10]),
    .c(MW_BOP[11]),
    .d(MW_BOP[12]),
    .y(W1)
);

endmodule
module alu (
    input  [7:0]    IN_A,               // WORD 1
    input  [7:0]    IN_B,               // WORD 2
    input           CIN,                // CARRY IN
    input  [19:15]  ALU_FUNC,           // FUNCTION SELECT (19 is MODE: 0 is arithmetic, 1 is logic)
    output [7:0]    OUT8,               // OUTPUT
    output          C4,                 // CARRY OUT
    output          C8,                 // CARRY OUT
    output          Z                   // WHEN A = B
);

//WIRES
wire CARRY;
wire NOTHING1, NOTHING2;
wire NOTHING3, NOTHING4;
wire AEQB1, AEQB2;

assign C4 = CARRY;

ta181_bar U1 (
    .A3_BAR(IN_A[3]),
    .A2_BAR(IN_A[2]),
    .A1_BAR(IN_A[1]),
    .A0_BAR(IN_A[0]),
    .B3_BAR(IN_B[3]),
    .B2_BAR(IN_B[2]),
    .B1_BAR(IN_B[1]),
    .B0_BAR(IN_B[0]),
    .S3(ALU_FUNC[18]),
    .S2(ALU_FUNC[17]),
    .S1(ALU_FUNC[16]),
    .S0(ALU_FUNC[15]),
    .M(ALU_FUNC[19]),
    .CI(CIN),
    .F3_BAR(OUT8[3]),
    .F2_BAR(OUT8[2]),
    .F1_BAR(OUT8[1]),
    .F0_BAR(OUT8[0]),
    .CO(CARRY),
    .AEQB(AEQB1),
    .P_BAR(NOTHING1),
    .G_BAR(NOTHING2)
);

ta181_bar U2 (
    .A3_BAR(IN_A[7]),
    .A2_BAR(IN_A[6]),
    .A1_BAR(IN_A[5]),
    .A0_BAR(IN_A[4]),
    .B3_BAR(IN_B[7]),
    .B2_BAR(IN_B[6]),
    .B1_BAR(IN_B[5]),
    .B0_BAR(IN_B[4]),
    .S3(ALU_FUNC[18]),
    .S2(ALU_FUNC[17]),
    .S1(ALU_FUNC[16]),
    .S0(ALU_FUNC[15]),
    .M(ALU_FUNC[19]),
    .CI(CARRY),
    .F3_BAR(OUT8[7]),
    .F2_BAR(OUT8[6]),
    .F1_BAR(OUT8[5]),
    .F0_BAR(OUT8[4]),
    .CO(C8),
    .AEQB(AEQB2),
    .P_BAR(NOTHING3),
    .G_BAR(NOTHING4)
);

and2_behavioral AND1 (
    .a(AEQB1),
    .b(AEQB2),
    .y(Z)
);

endmodule
module control (
    input  [3:0]    OPCODE,             //
    input           GO_BAR,             // 
    input           RESET,              // 
    input           JAM,                // 
    input           SYSTEM_CLK,         //
    input  [3:0]    STATUS_BITS,        // 
    input  [23:0]   MW,                 //
    output [7:0]    MICROADDRESS,       //
    output [23:13]  CONTROL_BITS,       // PASS THREW FOR MW[23:13]
    output          EIL_BAR             // 
);

// WIRES
wire [3:0]      MICRO_AD_LOW;
wire [7:4]      MICRO_AD_HIGH;
wire            COUNT;
wire [12:9]     BOP;
wire [7:4]      COUNTER_IN_HIGH_SIG;
wire [7:0]      BUFFER_IN;
wire            MPC_LOAD_BAR;
wire            COND_OUT;
wire            HIGH;
wire [7:0]      HIGH8;
wire            LOW;
wire            NOTHING;

// BREAK UP THE MICROWORD (MW) INTO FIELDS
assign MICRO_AD_LOW     = MW[3:0];
assign MICRO_AD_HIGH    = MW[7:4];
assign COUNT            = MW[8];
assign BOP              = MW[12:9];
assign CONTROL_BITS     = MW[23:13];

// ASSIGN VALUES
assign HIGH             = 1'b1;
assign HIGH8            = 8'b11111111;
assign LOW              = 1'b0;

// COUNTER8 SECTION
counter8 COUNTER_8 (
    .COUNTER_IN_LOW(MICRO_AD_LOW),
    .COUNTER_IN_HIGH(COUNTER_IN_HIGH_SIG),
    .MPC_LOAD_BAR(MPC_LOAD_BAR),
    .RESET(RESET),
    .COUNT(COUNT),
    .SYSTEM_CLK(SYSTEM_CLK),
    .COUNTER_OUT(BUFFER_IN)
);

// MUX8 SECTION - Eight (2x1) multiplexers
ta157_8 MUX8 (
    .A8(BUFFER_IN),
    .B8(HIGH8),
    .S(JAM),
    .EN_BAR(LOW),
    .Y8(MICROADDRESS)
);

// OPCODEDEC SECTION
opcodedec OPCODEDEC0 (
    .OPCODE(OPCODE),
    .MW_AD_HIGH(MICRO_AD_HIGH),
    .MW_BOP(BOP),
    .TO_COUNTER(COUNTER_IN_HIGH_SIG),
    .EIL_BAR(EIL_BAR)
);

// COND_SELECT SECTION
ta151_bar COND_SELECT (
    .D0(STATUS_BITS[2]),
    .D1(LOW),
    .D2(STATUS_BITS[0]),
    .D3(STATUS_BITS[1]),
    .D4(GO_BAR),
    .D5(STATUS_BITS[3]),
    .D6(LOW),
    .D7(LOW),
    .A(BOP[9]),
    .B(BOP[10]),
    .C(BOP[11]),
    .EN_BAR(LOW),
    .Y(NOTHING),
    .W(COND_OUT)
);

//   Replaced xor2 in THESIS with jeff's xor2
xor2_behavioral XOR_2 (
    .a(BOP[12]),
    .b(COND_OUT),
    .y(MPC_LOAD_BAR)
);

endmodule
module processor (
    input  [7:0]    DATA_IN_A,          // 
    input  [7:0]    DATA_IN_B,          // 
    input           SYSTEM_CLK,         //
    input           EIL_BAR,            //
    input  [23:13]  CONTROL_BITS,       //
    output [3:0]    STATUS_BITS,        // 
    output [7:0]    DATA_OUT            // 
);

// WIRES
wire [7:0]      DATA_OUT_A;
wire [7:0]      DATA_OUT_B;
wire [7:0]      DATA_OUT_TA;
wire [7:0]      DATA_OUT_TB;
wire [7:0]      ALU_IN_A;
wire [7:0]      ALU_IN_B;
wire [7:0]      ALU_OUT;
wire            A_SOURCE;
wire            B_SOURCE;
wire [19:15]    ALU_FUNC;
wire            CIN;
wire [23:21]    ALU_DEST;
wire [7:0]      IN_ZP;
wire            LOW;

// BREAK UP THE CONTROL_BITS INTO FIELDS
assign A_SOURCE     = CONTROL_BITS[13];
assign B_SOURCE     = CONTROL_BITS[14];
assign ALU_FUNC     = CONTROL_BITS[19:15];
assign CIN          = CONTROL_BITS[20];
assign ALU_DEST     = CONTROL_BITS[23:21];

// ASSIGN VALUES
assign LOW              = 1'b0;
assign DATA_OUT         = IN_ZP;

// REGISTERA SECTION
register_ab8 REGISTERA (
    .DATA_IN(DATA_IN_A),
    .SYSTEM_CLK(SYSTEM_CLK),
    .ENABLE_CLK(EIL_BAR),
    .DATA_OUT(DATA_OUT_A)
);

// REGISTERB SECTION
register_ab8 REGISTERB (
    .DATA_IN(DATA_IN_B),
    .SYSTEM_CLK(SYSTEM_CLK),
    .ENABLE_CLK(EIL_BAR),
    .DATA_OUT(DATA_OUT_B)
);

// TEMP_REGISTER_A SECTION
register_ab8 TEMP_REGISTER_A (
    .DATA_IN(ALU_OUT),
    .SYSTEM_CLK(SYSTEM_CLK),
    .ENABLE_CLK(ALU_DEST[21]),
    .DATA_OUT(DATA_OUT_TA)    
);

// TEMP_REGISTER_B SECTION
register_ab8 TEMP_REGISTER_B (
    .DATA_IN(ALU_OUT),
    .SYSTEM_CLK(SYSTEM_CLK),
    .ENABLE_CLK(ALU_DEST[22]),
    .DATA_OUT(DATA_OUT_TB)
);

// MUX_A SECTION
ta157_8 MUX_A (
    .A8(DATA_OUT_TA),
    .B8(DATA_OUT_A),
    .S(A_SOURCE),
    .EN_BAR(LOW),
    .Y8(ALU_IN_A)
);

// MUX_B SECTION
ta157_8 MUX_B (
    .A8(DATA_OUT_TB),
    .B8(DATA_OUT_B),
    .S(B_SOURCE),
    .EN_BAR(LOW),
    .Y8(ALU_IN_B)
);

// ALU1 SECTION
alu ALU1 (
    .IN_A(ALU_IN_A),
    .IN_B(ALU_IN_B),
    .CIN(CIN),
    .ALU_FUNC(ALU_FUNC),
    .OUT8(ALU_OUT),
    .C4(STATUS_BITS[0]),
    .C8(STATUS_BITS[1]),
    .Z(STATUS_BITS[2])
);

// F_REGISTER SECTION
register_ab8 F_REGISTER (
    .DATA_IN(ALU_OUT),
    .SYSTEM_CLK(SYSTEM_CLK),
    .ENABLE_CLK(ALU_DEST[23]),
    .DATA_OUT(IN_ZP)
);

// ZP_BIT1 SECTION
zp_bit ZP_BIT1 (
    .F8(IN_ZP),
    .ZP_BAR(STATUS_BITS[3])
);

endmodule
module osc2(
    input clk,              // 48.0MHz CPU clock
    input reset,            // Low-true reset
	
	// external toggle switch inputs
	input [1:0] range, mod1, mod2,

	// SYNC input
	input sync,
	
	// PWM LED outputs
	output pwm_r, pwm_g, pwm_b,
	
	// Rate LED output
    output rate,
	
	// SPI ADC interface
	output adc_cs, adc_si, adc_clk,
	input adc_so,
	
	// Differentiall PDM outputs
	output pdm_l_p, pdm_l_n, pdm_r_p, pdm_r_n,
	
	// diagnostic
	output [1:0] diag,
	output [11:0] a0, a1, a2, a3
);
	// Sample rate enable
	reg [2:0] clk_cnt;
	reg ena;
	always @(posedge clk)
		if(reset)
		begin
			clk_cnt <= 3'b000;
			ena <= 1'b1;
		end
		else
		begin
			clk_cnt <= clk_cnt + 3'b001;
			if(clk_cnt == 3'b010)
			begin
				clk_cnt <= 3'b000;
				ena <= 1'b1;
			end
			else
				ena <= 1'b0;
		end
	
	// ADC
	//wire [11:0] a0, a1, a2, a3;
	wire a0_v, a1_v, a2_v, a3_v;
	adc u_adc(
		.clk(clk),
		.reset(reset),
		.adc_cs(adc_cs),
		.adc_si(adc_si),
		.adc_so(adc_so),
		.adc_clko(adc_clk),
		.a0(a0),	// CV1
		.a1(a1),	// CV3
		.a2(a2),	// CV2
		.a3(a3),	// 1V/Oct
		.a0_v(a0_v),
		.a1_v(a1_v),
		.a2_v(a2_v),
		.a3_v(a3_v)
	);
	
	// PWMs
	pwm u_pwm_r(
		.clk(clk),
		.val(a0[11:4]),
		.pwm(pwm_r)
	);
	pwm u_pwm_g(
		.clk(clk),
		.val(a1[11:4]),
		.pwm(pwm_g)
	);
	pwm u_pwm_b(
		.clk(clk),
		.val(a2[11:4]),
		.pwm(pwm_b)
	);

	// Expo Calculation
	wire [31:0] frq;
	expo_calc u_expo(
		.clk(clk),
		.reset(reset),
		.range(range),
		.in(a3),
		.in_v(a3_v),
		.out(frq)
	);
	
	// detect falling edge of sync
	reg sync_d, sync_edge;
	always @(posedge clk)
		if(ena)
		begin
			sync_d <= sync;
			sync_edge = !sync & sync_d;
		end
		
	// NCO
	reg [31:0] phs;
	always @(posedge clk)
		if(reset | sync_edge)
			phs <= 0;
		else if(ena)
			phs <= phs + frq;
	
	// Rate output
	assign rate = phs[31];
	
	// waveforms
	wire signed [15:0] saw = phs[31:16];
	wire signed [15:0] pwm;
	wire signed [15:0] sin;
		
	// square / pulse wave
	wire pwm_v;
	pulse_wave u_pulse(
		.clk(clk),
		.ena(ena),
		.phs(phs),
		.width(a1),
		.out(pwm),
		.valid(pwm_v)
	);
		
	// sine wave
	sine u_sine(
		.clk(clk),
		.reset(reset),
		.ena(ena),
		.phs(phs),
		.out(sin),
		.valid()
	);
	
	// select the outputs
	reg signed [15:0] src_l, src_r;
	always @(posedge clk)
		if(ena)
		begin
			case(mod1)
				2'b00: src_l = sin;
				2'b01: src_l = saw;
				2'b10: src_l = pwm;
				default: src_l = sin;
			endcase
			case(mod2)
				2'b00: src_r = sin;
				2'b01: src_r = saw;
				2'b10: src_r = pwm;
				default: src_r = sin;
			endcase
		end
	
	// PDM outputs
	pdm u_pdm_l(
		.clk(clk),
		.reset(reset),
		.ena(ena),
		.in(src_l),
		.pdm_p(pdm_l_p),
		.pdm_n(pdm_l_n)
	);
	pdm u_pdm_r(
		.clk(clk),
		.reset(reset),
		.ena(ena),
		.in(src_r),
		.pdm_p(pdm_r_p),
		.pdm_n(pdm_r_n)
	);
		
	// diagnostic
	assign diag[0] = rate;
	assign diag[1] = 1'b0;
endmodule
module pwm(
    input clk,
	input [7:0] val,
	output reg pwm
);
	reg [7:0] cnt;
	initial
		cnt = 0;
		
	always @(posedge clk)
	begin
		cnt <= cnt + 1;
		pwm <= val > cnt;
	end
endmodule
module toggle3pos(
    input [1:0] pkgpin,	// raw pin input
	output reg [1:0] out
);
	always @(*)
		case(pkgpin)
			2'b00: out = 2'b11;		// can't happen
			2'b01: out = 2'b00;		// top
			2'b10: out = 2'b10;		// bottom
			2'b11: out = 2'b01;		// center
		endcase
endmodule
module expo_calc(
    input clk,              // 16MHz CPU clock
    input reset,            // Low-true reset
    input [1:0] range,		// range select
	input [11:0] in,		// 1V/Oct input
	input in_v,				// input valid flag
	output reg [31:0] out	// frequency output
);
	reg [3:0] inpipe;
	reg [27:0] inscl;
	reg [34:0] pout;
	wire [7:0] addr = inscl[23:16];
	wire [3:0] shf = inscl[27:24];
			
	reg [15:0] LUT[255:0], LUT_reg;
	initial
		$readmemh("../src/expo.hex",LUT);

	always @(posedge clk)
		if(reset)
		begin
			inpipe <= 4'd0;
			inscl <= 28'd0;
			pout <= 32'd0;
			out <= 32'd0;
		end
		else
		begin
			// pipeline the valid signal
			inpipe <= {inpipe[2:0],in_v};
			
			// scale the input
			if(in_v)
				inscl <= in * `ADC_cal;
			
			// lookup table
			if(inpipe[1])
				LUT_reg <= LUT[addr];
			
			// octave shifter
			if(inpipe[2])
				pout <= LUT_reg << shf;
			
			// range shifter
			if(inpipe[3])
				case(range)
					2'b00: out <= pout >>> 3;
					2'b01: out <= pout >>> 9;
					2'b10: out <= pout >>> 16;
					default out <= pout >>> 3;
				endcase
		end
endmodule
module pdm(
    input clk,              // system clock
    input reset,			// system reset
	input ena,				// systetm clock enable
	input signed [15:0] in,	// signed binary input
	output pdm_p, pdm_n		// differential pdm output
);
	// convert input to offset binary
	wire [15:0] ob = in ^ 16'h8000;
	
	// 1st-order sigma-delta
	reg [16:0] sd_acc;
	always @(posedge clk)
		if(reset)
			sd_acc = 0;
		else if(ena)
			sd_acc <= {1'b0,sd_acc[15:0]} + {1'b0,ob};

`define EDGE_BAL
`ifdef EDGE_BAL
	// balanced rising/falling edges - does it help distortion?
	reg [2:0] ccnt;
	reg out;
	always @(posedge clk)
		if(reset)
		begin
			ccnt <= 3'b000;
			out <= 1'b0;
		end
		else
		begin
			if(ena)
			begin
				ccnt <= 3'b000;
				out <= 1'b0;
			end
			else
			begin
				ccnt <= ccnt + 1;
				case(ccnt)
					3'b000: out <= 1'b1;
					3'b001: out <= sd_acc[16];
					default: out <= out;
				endcase
			end
		end
		wire oclk = clk;
`else
	// simple output
	wire out = sd_acc[16];

	// clock for output reg
	reg oclk;
	always @(posedge clk)
		oclk <= ena;	
`endif

	// Instantiate IO
	SB_IO #(
		.PIN_TYPE(6'b1001_01), 	// registered, enabled w/ simple input
		.PULLUP(1'b0),			// no pullup
		.NEG_TRIGGER(1'b0),		// positive edge
		.IO_STANDARD("SB_LVCMOS")
	) io_pdm_p(
		.PACKAGE_PIN (pdm_p),
		.LATCH_INPUT_VALUE (1'b0),
		.CLOCK_ENABLE (1'b1),
		.INPUT_CLK (1'b0),
		.OUTPUT_CLK (oclk),
		.OUTPUT_ENABLE (1'b1),
		.D_OUT_0 (out),
		.D_OUT_1 (1'b0),
		.D_IN_0 (),
		.D_IN_1 ()
	);
	SB_IO #(
		.PIN_TYPE(6'b1001_01), 	// registered, enabled w/ simple input
		.PULLUP(1'b0),			// no pullup
		.NEG_TRIGGER(1'b0),		// positive edge
		.IO_STANDARD("SB_LVCMOS")
	) io_pdm_n(
		.PACKAGE_PIN (pdm_n),
		.LATCH_INPUT_VALUE (1'b0),
		.CLOCK_ENABLE (1'b1),
		.INPUT_CLK (1'b0),
		.OUTPUT_CLK (oclk),
		.OUTPUT_ENABLE (1'b1),
		.D_OUT_0 (!out),
		.D_OUT_1 (1'b0),
		.D_IN_0 (),
		.D_IN_1 ()
	);
endmodule
module diag_serial(
    input clk,              // 48MHz CPU clock
    input reset,            // Low-true reset
    
	input [11:0] a0, a1, a2, a3,
	output tx
);
	// hard-coded bit-rate
	localparam sym_rate = 115200;
    localparam clk_freq = 48000000;
    localparam sym_cnt = clk_freq / sym_rate;
	localparam SCW = $clog2(sym_cnt);
	
	wire [SCW-1:0] sym_cntr = sym_cnt;
	
	// sequencing state machine
	reg [1:0] chl;
	reg [2:0] char;
	reg [7:0] din;
	reg [11:0] a_mux;
	reg [3:0] nybble;
	reg [7:0] digit;
	reg tx_start;
	wire tx_busy;
	always @(posedge clk)
	begin
		if(reset)
		begin
			chl <= 2'b00;
			char <= 3'b000;
			din <= 2'h00;
			tx_start <= 1'b0;
		end
		else
		begin
			// start next char
			tx_start <= !tx_busy;
			
			// advance state
			if(!tx_start && !tx_busy)
			begin
				// choose char
				case(char)
					3'b000: din <= digit;
					3'b001: din <= digit;
					3'b010: din <= digit;
					3'b011: din <= (chl == 3) ? 8'h0d : 8'h20;
					3'b100: din <= (chl == 3) ? 8'h0a : 8'h20;
				endcase
				
				char <= char + 3'b001;
				if(char == 3'b100)
				begin
					char <= 3'b000;
					chl <= chl + 2'b01;
				end
			end
			
			// choose channel
			case(chl)
				2'b00: a_mux <= a0;
				2'b01: a_mux <= a1;
				2'b10: a_mux <= a2;
				2'b11: a_mux <= a3;
			endcase
			
			// choose nybble
			case(char)
				3'b000: nybble <= a_mux[11:8];
				3'b001: nybble <= a_mux[7:4];
				3'b010: nybble <= a_mux[3:0];
			endcase
			
			// convert nybble to hex
			if(nybble > 4'h9)
				digit = nybble + 8'd55;
			else
				digit = nybble + 8'd48;
		end
	end
	
	// Transmitter
	acia_tx #(
		.SCW(SCW),              // rate counter width
		.sym_cnt(sym_cnt)       // rate count value
	)
	my_tx(
		.clk(clk),				// system clock
		.rst(reset),			// system reset
		.tx_dat(din),           // transmit data byte
		.tx_start(tx_start),    // trigger transmission
		.tx_serial(tx),         // tx serial output
		.tx_busy(tx_busy)       // tx is active (not ready)
	);
endmodule
module sine(
    input clk,              	// system clock
	input reset,				// system reset
	input ena,					// system clock enable
	input [31:0] phs,			// phase input
	output signed [15:0] out,	// wave output
	output valid
);	
	// enable pipeline
	reg [6:0] ena_pipe;
	always @(posedge clk)
		if(reset)
			ena_pipe <= 6'b000;
		else
			ena_pipe <= {ena_pipe[6:0],ena};
	
	// select interp components
	reg [7:0] idx;
	reg signed [15:0] interp;
	always @(posedge clk)
		if(ena_pipe[0])
		begin
			idx <= phs[31:24];
			interp <= 16'h7fff - phs[23:9];
			//interp <= 16'h7fff;
		end
		else if(ena_pipe[1])
		begin
			idx <= phs[31:24] + 8'h01;
			interp <= {1'b0,phs[23:9]};
			//interp <= 16'h0;
		end
			
	// sine lookup table
	reg [15:0] sine_mem[255:0];
	initial
		$readmemh("../src/sine.hex",sine_mem);
	
	// look up sine & delay interpolation
	reg signed [15:0] interp_d;
	reg signed [15:0] sin;
	always @(posedge clk)
		if(ena_pipe[1] | ena_pipe[2])
		begin 
			sin <= sine_mem[idx];
			interp_d <= interp;
		end
	
	// sum of products
	reg signed [31:0] m;
	always @(posedge clk)
		if(ena_pipe[2] | ena_pipe[3])
			m <= sin * interp_d;
		
	reg signed [31:0] acc;
	always @(posedge clk)
		if(ena_pipe[2])
			acc <= 32'd0;
		else if(ena_pipe[3] | ena_pipe[4])
			acc <= acc + m;
	
	reg signed [15:0] out;
	always @(posedge clk)
		if(ena_pipe[5])
			out <= acc[30:15];
	
	assign valid = ena_pipe[6];
endmodule
module pulse_wave(
    input clk,              	// system clock
	input ena,					// system clock enable
	input [31:0] phs,			// phase input
	input [11:0] width,			// width input
	output signed [15:0] out,	// wave output
	output valid
);
	// compare threshold
	reg signed [15:0] out;
	reg valid;
	always @(posedge clk)
	begin
		valid <= ena;
		if(ena)
			out <= (phs[31:20] > width) ? 16'h7fff : 16'h8001;
	end
endmodule
module tb_system;
    reg clk;
    reg reset;
	reg rx;
	wire tx;
	reg [11:0] a0, a1, a2, a3;
	wire [31:0] gp_out;
	
    // 24 MHz clock source
    always
        #(2*10.4167) clk = ~clk;
    
    // reset
    initial
    begin
`ifdef icarus
  		$dumpfile("tb_system.vcd");
		$dumpvars;
`endif
		
       // init regs
        clk = 1'b0;
        reset = 1'b1;
		rx = 1'b1;
		a0 = 12'h000;
		a1 = 12'h000;
		a2 = 12'h000;
		a3 = 12'h000;
		
        // release reset
        #1000
        reset = 1'b0;
        
`ifdef icarus
        // stop after 1 sec
		//#12000000 $finish;
		#700000 $finish;
`endif
    end
	
    // Unit under test
	system u_riscv(
		.clk24(clk),
		.reset(reset),
		.RX(rx),
		.TX(tx),
		.gp_in0({20'h00000,a0}),
		.gp_in1({20'h00000,a1}),
		.gp_in2({20'h00000,a2}),
		.gp_in3({20'h00000,a3}),
		.gp_out(gp_out)
	);
endmodule
module up5k_osc_top(
	// 12MHz clock osc
	input clk_12,
	
	// ADC SPI bus
	output adc_cs, adc_si, adc_clk,
	input adc_so,
	
	// LEDs
	output RGB0, RGB1, RGB2, // RGB LED outs
	output LEDR,			// discrete LED
	
	// Differential PDM Audio
	output pdm_l_p, pdm_l_n, pdm_r_p, pdm_r_n,
	
	// Serial port
	output tx,
	output rx,
	
	// SYNC input
	input SYNC,

	// toggle inputs
	input [1:0] SW103, SW104, SW105,	// mod1, range, mod2
	
	// SPI Flash
	output MEM_SPI_MOSI_IO0, MEM_SPI_SCLK, MEM_SPI_CS,
	output MEM_SPI_WP_IO2, MEM_SPI_HLD_IO3,
	input MEM_SPI_MISO_IO1
);
	//------------------------------
	// Clock PLL
	//------------------------------
	// Fin=12, FoutA=24, FoutB=48
	wire clk, clk24, pll_lock;
	SB_PLL40_2F_PAD #(
		.DIVR(4'b0000),
		.DIVF(7'b0111111),	// 24/48
		.DIVQ(3'b100),
		.FILTER_RANGE(3'b001),
		.FEEDBACK_PATH("SIMPLE"),
		.DELAY_ADJUSTMENT_MODE_FEEDBACK("FIXED"),
		.FDA_FEEDBACK(4'b0000),
		.DELAY_ADJUSTMENT_MODE_RELATIVE("FIXED"),
		.FDA_RELATIVE(4'b0000),
		.SHIFTREG_DIV_MODE(2'b00),
		.PLLOUT_SELECT_PORTA("GENCLK_HALF"),
		.PLLOUT_SELECT_PORTB("GENCLK"),
		.ENABLE_ICEGATE_PORTA(1'b0),
		.ENABLE_ICEGATE_PORTB(1'b0)
	)
	pll_inst (
		.PACKAGEPIN(clk_12),
		.PLLOUTCOREA(clk24),
		.PLLOUTGLOBALA(),
		.PLLOUTCOREB(clk),
		.PLLOUTGLOBALB(),
		.EXTFEEDBACK(),
		.DYNAMICDELAY(8'h00),
		.RESETB(1'b1),
		.BYPASS(1'b0),
		.LATCHINPUTVALUE(),
		.LOCK(pll_lock),
		.SDI(),
		.SDO(),
		.SCLK()
	);
	
	//------------------------------
	// reset generator waits > 10us
	//------------------------------
	reg [8:0] reset_cnt;
	reg reset, reset24;    
	always @(posedge clk or negedge pll_lock)
	begin
		if(!pll_lock)
		begin
			reset_cnt <= 9'h000;
			reset <= 1'b1;
		end
		else
		begin
			if(reset_cnt != 9'h1ff)
			begin
				reset_cnt <= reset_cnt + 9'h001;
				reset <= 1'b1;
			end
			else
				reset <= 1'b0;
		end
	end
	
	always @(posedge clk24 or negedge pll_lock)
		if(!pll_lock)
			reset24 <= 1'b1;
		else
			reset24 <= reset;
	
	//------------------------------
	// Instantiate RISC-V system
	//------------------------------
	wire [31:0] gpo;
	wire sys_diag;
	system u_riscv(
		.clk24(clk24),
		.reset(reset24),
		.RX(rx),
		.TX(tx),
		.gp_in0(SW103),
		.gp_in1(SW104),
		.gp_in2(SW105),
		.gp_in3(SYNC),
		.gp_out(gpo),
		.diag(sys_diag)
	);

	//------------------------------
	// Instantiate RGB DRV 
	//------------------------------
	SB_RGBA_DRV #(
		.RGB0_CURRENT("0b000001"),
		.RGB1_CURRENT("0b000001"),
		.RGB2_CURRENT("0b000001")
	) RGBA_DRIVER (
	   .CURREN    (1'b1),
	   .RGBLEDEN  (1'b1), // Enable current for all 3 RGB LED pins
	   .RGB0PWM   (gpo[17]), // Input to drive RGB0 - from LEDD HardIP
	   .RGB1PWM   (gpo[18]), // Input to drive RGB1 - from LEDD HardIP
	   .RGB2PWM   (gpo[19]), // Input to drive RGB2 - from LEDD HardIP
	   .RGB0      (RGB0), 
	   .RGB1      (RGB1),
	   .RGB2      (RGB2)
	);

	assign LEDR = gpo[20];
endmodule
module bram_512x32(
	input clk,
	input sel,
	input [3:0] we,
	input [10:0] addr,
	input [31:0] wdat,
	output reg [31:0] rdat
);
	// memory
	reg [31:0] ram[511:0];
	
	// write logic
	always @(posedge clk)
		if(sel)
		begin
			if(we[0])
				ram[addr[10:2]][7:0] <= wdat[7:0];
			if(we[1])
				ram[addr[10:2]][15:8] <= wdat[15:8];
			if(we[2])
				ram[addr[10:2]][23:16] <= wdat[23:16];
			if(we[3])
				ram[addr[10:2]][31:24] <= wdat[31:24];
		end
	
	// read logic
	always @(posedge clk)
		rdat <= ram[addr[10:2]];

endmodule
module spram_16kx32(
	input clk,
	input sel,
	input [3:0] we,
	input [15:0] addr,
	input [31:0] wdat,
	output [31:0] rdat
);
    // instantiate the big RAMs
	SB_SPRAM256KA mem_lo (
		.ADDRESS(addr[15:2]),
		.DATAIN(wdat[15:0]),
		.MASKWREN({we[1],we[1],we[0],we[0]}),
		.WREN(|we),
		.CHIPSELECT(sel),
		.CLOCK(clk),
		.STANDBY(1'b0),
		.SLEEP(1'b0),
		.POWEROFF(1'b1),
		.DATAOUT(rdat[15:0])
	);
	SB_SPRAM256KA mem_hi (
		.ADDRESS(addr[15:2]),
		.DATAIN(wdat[31:16]),
		.MASKWREN({we[3],we[3],we[2],we[2]}),
		.WREN(|we),
		.CHIPSELECT(sel),
		.CLOCK(clk),
		.STANDBY(1'b0),
		.SLEEP(1'b0),
		.POWEROFF(1'b1),
		.DATAOUT(rdat[31:16])
	);
endmodule
module \$_DFF_P_ (D, C, Q);
    input D;
    input C;
    output Q;
    parameter _TECHMAP_WIREINIT_Q_ = 1'bx;
    dff _TECHMAP_REPLACE_ (.Q(Q), .D(D), .C(C));
endmodule
module \$_DFF_PP0_ (D, C, R, Q);
    input D;
    input C;
    input R;
    output Q;
    parameter _TECHMAP_WIREINIT_Q_ = 1'bx;
    dffr _TECHMAP_REPLACE_ (.Q(Q), .D(D), .C(C), .R(R));
endmodule
module \$_DFF_PP1_ (D, C, R, Q);
    input D;
    input C;
    input R;
    output Q;
    parameter _TECHMAP_WIREINIT_Q_ = 1'bx;
    dffs _TECHMAP_REPLACE_ (.Q(Q), .D(D), .C(C), .S(R));
endmodule
module \$_DFF_PN0_ (D, C, R, Q);
    input D;
    input C;
    input R;
    output Q;
    parameter _TECHMAP_WIREINIT_Q_ = 1'bx;
    dffrn _TECHMAP_REPLACE_ (.Q(Q), .D(D), .C(C), .RN(R));
endmodule
module \$_DFF_PN1_ (D, C, R, Q);
    input D;
    input C;
    input R;
    output Q;
    parameter _TECHMAP_WIREINIT_Q_ = 1'bx;
    dffsn _TECHMAP_REPLACE_ (.Q(Q), .D(D), .C(C), .SN(R));
endmodule
module dpram_1024x8_core (
  input wclk,
  input wen,
  input [0:9] waddr,
  input [0:7] data_in,
  input rclk,
  input ren,
  input [0:9] raddr,
  output [0:7] data_out );

  reg [0:7] ram[0:1023];
  reg [0:7] internal;

  assign data_out = internal;

  always @(posedge wclk) begin
    if(wen) begin
      ram[waddr] <= data_in;
    end
  end

  always @(posedge rclk) begin
    if(ren) begin
      internal <= ram[raddr];
    end
  end

endmodule
module dpram_1024x8 (
  input clk,
  input wen,
  input ren,
  input [0:9] waddr,
  input [0:9] raddr,
  input [0:7] data_in,
  output [0:7] data_out );

    dpram_1024x8_core memory_0 (
      .wclk    (clk),
      .wen    (wen),
      .waddr    (waddr),
      .data_in  (data_in),
      .rclk    (clk),
      .ren    (ren),
      .raddr    (raddr),
      .data_out    (data_out) );

endmodule
module mult_36(
  input [0:35] A,
  input [0:35] B,
  output [0:71] Y
);

assign Y = A * B;

endmodule
module dffr(
    output reg Q,
    input D,
    input R,
    (* clkbuf_sink *)
    (* invertible_pin = "IS_C_INVERTED" *)
    input C
);
    parameter [0:0] INIT = 1'b0;
    parameter [0:0] IS_C_INVERTED = 1'b0;
    initial Q = INIT;
    case(|IS_C_INVERTED)
          1'b0:
            always @(posedge C or posedge R)
                if (R == 1'b1)
                        Q <= 1'b0;
                else
                        Q <= D;
          1'b1:
            always @(negedge C or posedge R)
                if (R == 1'b1)
                        Q <= 1'b0;
                else
                        Q <= D;
    endcase
endmodule
module dffs(
    output reg Q,
    input D,
    input S,
    (* clkbuf_sink *)
    (* invertible_pin = "IS_C_INVERTED" *)
    input C
);
    parameter [0:0] INIT = 1'b0;
    parameter [0:0] IS_C_INVERTED = 1'b0;
    initial Q = INIT;
    case(|IS_C_INVERTED)
          1'b0:
            always @(posedge C or posedge S)
                if (S == 1'b1)
                        Q <= 1'b1;
                else
                        Q <= D;
          1'b1:
            always @(negedge C or posedge S)
                if (S == 1'b1)
                        Q <= 1'b1;
                else
                        Q <= D;
    endcase
endmodule
module dffrn(
    output reg Q,
    input D,
    input RN,
    (* clkbuf_sink *)
    (* invertible_pin = "IS_C_INVERTED" *)
    input C
);
    parameter [0:0] INIT = 1'b0;
    parameter [0:0] IS_C_INVERTED = 1'b0;
    initial Q = INIT;
    case(|IS_C_INVERTED)
          1'b0:
            always @(posedge C or negedge RN)
                if (RN == 1'b0)
                        Q <= 1'b0;
                else
                        Q <= D;
          1'b1:
            always @(negedge C or negedge RN)
                if (RN == 1'b0)
                        Q <= 1'b0;
                else
                        Q <= D;
    endcase
endmodule
module dffsn(
    output reg Q,
    input D,
    input SN,
    (* clkbuf_sink *)
    (* invertible_pin = "IS_C_INVERTED" *)
    input C
);
    parameter [0:0] INIT = 1'b0;
    parameter [0:0] IS_C_INVERTED = 1'b0;
    initial Q = INIT;
    case(|IS_C_INVERTED)
          1'b0:
            always @(posedge C or negedge SN)
                if (SN == 1'b0)
                        Q <= 1'b1;
                else
                        Q <= D;
          1'b1:
            always @(negedge C or negedge SN)
                if (SN == 1'b0)
                        Q <= 1'b1;
                else
                        Q <= D;
    endcase
endmodule
module mult_8(
  input [0:7] A,
  input [0:7] B,
  output [0:15] Y
);

assign Y = A * B;

endmodule
module mult_8(
  input [0:7] A,
  input [0:7] B,
  output [0:15] Y
);
parameter MODE = 1'b1;

assign Y = A * B;

endmodule
module mult_16(
  input [0:15] A,
  input [0:15] B,
  output [0:31] Y
);
parameter MODE = 1'b0;

assign Y = A * B;

endmodule
module mult_36x36 (
  input [0:35] A,
  input [0:35] B,
  output [0:71] Y
);
  parameter A_SIGNED = 0;
  parameter B_SIGNED = 0;
  parameter A_WIDTH = 0;
  parameter B_WIDTH = 0;
  parameter Y_WIDTH = 0;

  mult_36 #() _TECHMAP_REPLACE_ (
    .A    (A),
    .B    (B),
    .Y    (Y) );

endmodule
module dpram_128x8_core (
  input wclk,
  input wen,
  input [0:6] waddr,
  input [0:7] data_in,
  input rclk,
  input ren,
  input [0:6] raddr,
  output [0:7] data_out );

  reg [0:7] ram[0:127];
  reg [0:7] internal;

  assign data_out = internal;

  always @(posedge wclk) begin
    if(wen) begin
      ram[waddr] <= data_in;
    end
  end

  always @(posedge rclk) begin
    if(ren) begin
      internal <= ram[raddr];
    end
  end

endmodule
module dpram_128x8 (
  input clk,
  input wen,
  input ren,
  input [0:6] waddr,
  input [0:6] raddr,
  input [0:7] data_in,
  output [0:7] data_out );

    dpram_128x8_core memory_0 (
      .wclk    (clk),
      .wen    (wen),
      .waddr    (waddr),
      .data_in  (data_in),
      .rclk    (clk),
      .ren    (ren),
      .raddr    (raddr),
      .data_out    (data_out) );

endmodule
module  \$_DFFE_PP0P_ (D, C, E, R, Q);
    input D;
    input C;
    input E;
    input R;
    output Q;
    parameter _TECHMAP_WIREINIT_Q_ = 1'bx;
    dffre  _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .E(E), .R(R));
endmodule
module  \$_DLATCH_PP0_ (input E, R, D, output Q);
    parameter _TECHMAP_WIREINIT_Q_ = 1'bx;
    latchre _TECHMAP_REPLACE_ (.D(D), .Q(Q), .E(1'b1), .G(E),  .R(R));
endmodule
module \$_DFF_N_ (D, CN, Q);
    input D;
    input CN;
    output Q;
    parameter _TECHMAP_WIREINIT_Q_ = 1'bx;
    dff #(.IS_C_INVERTED(1'b1)) _TECHMAP_REPLACE_ (.Q(Q), .D(D), .C(CN));
endmodule
module \$_DFF_NP0_ (D, C, R, Q);
    input D;
    input C;
    input R;
    output Q;
    parameter _TECHMAP_WIREINIT_Q_ = 1'bx;
    dffnr #(.IS_C_INVERTED(1'b1)) _TECHMAP_REPLACE_ (.Q(Q), .D(D), .CN(C), .R(R));
endmodule
module  \$_DFFE_NP0P_ (D, C, E, R, Q);
    input D;
    input C;
    input E;
    input R;
    output Q;
    parameter _TECHMAP_WIREINIT_Q_ = 1'bx;
    dffre  #(.IS_C_INVERTED(1'b1)) _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .E(E), .R(R));
endmodule
module mult_16(
  input [0:15] A,
  input [0:15] B,
  output [0:31] Y
);

assign Y = A * B;

endmodule
module mult_8x8 (
  input [0:7] A,
  input [0:7] B,
  output [0:15] Y
);
  parameter A_SIGNED = 0;
  parameter B_SIGNED = 0;
  parameter A_WIDTH = 0;
  parameter B_WIDTH = 0;
  parameter Y_WIDTH = 0;

  mult_8 #() _TECHMAP_REPLACE_ (
    .A    (A),
    .B    (B),
    .Y    (Y) );

endmodule
module mult_16x16 (
  input [0:15] A,
  input [0:15] B,
  output [0:31] Y
);
  parameter A_SIGNED = 0;
  parameter B_SIGNED = 0;
  parameter A_WIDTH = 0;
  parameter B_WIDTH = 0;
  parameter Y_WIDTH = 0;

  mult_16 #() _TECHMAP_REPLACE_ (
    .A    (A),
    .B    (B),
    .Y    (Y) );

endmodule
module mult_8x8 (
  input [0:7] A,
  input [0:7] B,
  output [0:15] Y
);
  parameter A_SIGNED = 0;
  parameter B_SIGNED = 0;
  parameter A_WIDTH = 0;
  parameter B_WIDTH = 0;
  parameter Y_WIDTH = 0;

  mult_8 #(.MODE(1'b1)) _TECHMAP_REPLACE_ (
    .A    (A),
    .B    (B),
    .Y    (Y) );

endmodule
module mult_16x16 (
  input [0:15] A,
  input [0:15] B,
  output [0:31] Y
);
  parameter A_SIGNED = 0;
  parameter B_SIGNED = 0;
  parameter A_WIDTH = 0;
  parameter B_WIDTH = 0;
  parameter Y_WIDTH = 0;

  mult_16 #(.MODE(1'b0)) _TECHMAP_REPLACE_ (
    .A    (A),
    .B    (B),
    .Y    (Y) );

endmodule
module dffnr(
    output reg Q,
    input D,
    input R,
    (* clkbuf_sink *)
    (* invertible_pin = "IS_C_INVERTED" *)
    input CN
);
    parameter [0:0] INIT = 1'b0;
    parameter [0:0] IS_C_INVERTED = 1'b0;
    initial Q = INIT;
    case(|IS_C_INVERTED)
          1'b0:
            always @(posedge CN or posedge R)
                if (R == 1'b1)
                        Q <= 1'b0;
                else
                        Q <= D;
          1'b1:
            always @(negedge CN or posedge R)
                if (R == 1'b1)
                        Q <= 1'b0;
                else
                        Q <= D;
    endcase
endmodule
module dffre(
    output reg Q,
    input D,
    input R,
    input E,
    (* clkbuf_sink *)
    (* invertible_pin = "IS_C_INVERTED" *)
    input C
);
    parameter [0:0] INIT = 1'b0;
    parameter [0:0] IS_C_INVERTED = 1'b0;
    initial Q = INIT;
    case(|IS_C_INVERTED)
          1'b0:
            always @(posedge C or posedge R)
              if (R == 1'b1)
                Q <= 1'b0;
              else if(E)
                Q <= D;
          1'b1:
            always @(negedge C or posedge R)
              if (R == 1'b1)
                Q <= 1'b0;
              else if(E)
                Q <= D;
        endcase
endmodule
module latchre (
    output reg Q,
    input S,
    input R,
    input D,
    input G,
    input E
);
    parameter [0:0] INIT = 1'b0;
    initial Q = INIT;
    always @*
            begin
              if (R) Q <= 1'b0;
              if (S) Q <= 1'b1;
            else if (E && G) Q <= D;
    end
endmodule
module dpram (
	input clk,
	input wen,
	input ren,
	input[9:0] waddr,
	input[9:0] raddr,
	input[31:0] d_in,
	output[31:0] d_out );

		dual_port_sram memory_0 (
			.wclk		(clk),
			.wen		(wen),
			.waddr		(waddr),
			.data_in	(d_in),
			.rclk		(clk),
			.ren		(ren),
			.raddr		(raddr),
			.d_out		(d_out) );

endmodule
module dual_port_sram (
	input wclk,
	input wen,
	input[9:0] waddr,
	input[31:0] data_in,
	input rclk,
	input ren,
	input[9:0] raddr,
	output[31:0] d_out );

	reg[31:0] ram[1023:0];
	reg[31:0] internal;

	assign d_out = internal;

	always @(posedge wclk) begin
		if(wen) begin
			ram[waddr] <= data_in;
		end
	end

	always @(posedge rclk) begin
		if(ren) begin
			internal <= ram[raddr];
		end
	end

endmodule
module diffeq_f_systemC(aport, dxport, xport, yport, uport, clk, reset);

input clk;
input reset;
input [31:0]aport;
input [31:0]dxport;
output [31:0]xport;
output [31:0]yport;
output [31:0]uport;
reg [31:0]xport;
reg [31:0]yport;
reg [31:0]uport;
wire [31:0]temp;

assign temp = uport * dxport;
always @(posedge clk )
begin
	if (reset == 1'b1)
	begin
		xport <= 0;
		yport <= 0;
		uport <= 0;
	end
else
  	if (xport < aport) 
	begin
		xport <= xport + dxport;
		yport <= yport + temp;//(uport * dxport);
		uport <= (uport - (temp/*(uport * dxport)*/ * (5 * xport))) - (dxport * (3 * yport));
	end
end
endmodule
module diffeq_paj_convert (Xinport, Yinport, Uinport, Aport, DXport, Xoutport, Youtport, Uoutport, clk, reset);
    input[31:0] Xinport; 
    input[31:0] Yinport; 
    input[31:0] Uinport; 
    input[31:0] Aport; 
    input[31:0] DXport; 
    input clk; 
    input reset; 
    output[31:0] Xoutport; 
    output[31:0] Youtport; 
    output[31:0] Uoutport; 
    reg[31:0] Xoutport;
    reg[31:0] Youtport;
    reg[31:0] Uoutport;

       reg[31:0] x_var; 
       reg[31:0] y_var; 
       reg[31:0] u_var; 
       wire[31:0] temp; 
       reg looping; 
 
assign temp = u_var * DXport;
    always @(posedge clk)
    begin
		if (reset == 1'b1)
		begin
			looping <= 1'b0;
			x_var <= 0;
            y_var <= 0;
            u_var <= 0;
		end
		else
          if (looping == 1'b0)
          begin
             x_var <= Xinport; 
             y_var <= Yinport; 
             u_var <= Uinport; 
             looping <= 1'b1; 
          end
          else if (x_var < Aport)
          begin
             u_var <= (u_var - (temp/*u_var * DXport*/ * 3 * x_var)) - (DXport * 3 * y_var); 
             y_var <= y_var + temp;//(u_var * DXport); 
             x_var <= x_var + DXport; 
			looping <= looping;
          end
          else
          begin
             Xoutport <= x_var ; 
             Youtport <= y_var ; 
             Uoutport <= u_var ; 
             looping <= 1'b0; 
          end 
    end 
 endmodule
module io_reg_tb;
    
    reg clk_gen, in_gen;
    wire out;

    io_reg inst(.clk(clk_gen), .in(in_gen), .out(out));

    initial begin
        #0 in_gen = 1'b1; clk_gen = 1'b0;
        #100 in_gen = 1'b0;
    end

    always begin
        #10 clk_gen = ~clk_gen;
    end

    initial begin
        #5000 $stop;
    end

endmodule
module io_reg(clk, in, out);

    input clk;
    input in;
    output out;
    reg out;

    //reg temp;

    always @(posedge clk)
    begin
        out <= in;
    end
    
    /*always @(posedge clk)
    begin
        out <= temp ;
    end*/
    
endmodule
module tb_bin2bcd;

    // Input
    reg [7:0] bin;
    // Output
    wire [11:0] bcd;
    // Extra variables
    reg [8:0] i;

    // Instantiate the Unit Under Test (UUT)
    bin2bcd uut (
        .bin(bin), 
        .bcd(bcd)
    );

//Simulation - Apply inputs
    initial begin
    //A for loop for checking all the input combinations.
        for(i=0;i<256;i=i+1)
        begin
            bin = i; 
            #10; //wait for 10 ns.
        end 
        $finish; //system function for stoping the simulation.
    end
      
endmodule
module counter_tb;

	reg clk_counter, rst_counter;
	wire [7:0] q_counter;

	counter_original C_1(
		clk_counter, 
		q_counter, 
		rst_counter);
	
	initial begin
		#0 rst_counter = 1'b1; clk_counter = 1'b0;
		#100 rst_counter = 1'b0;
	end

	always begin
		#10 clk_counter = ~clk_counter;
	end
	
	initial begin
		#5000 $stop;
	end

endmodule
module div_su(clk, ena, z, d, q, s, div0, ovf);

	//
	// parameters
	//
	parameter z_width = 16;
	parameter d_width = z_width /2;
	
	//
	// inputs & outputs
	//
	input clk;              // system clock
	input ena;              // clock enable

	input  [z_width-1:0] z; // divident
	input  [d_width-1:0] d; // divisor
	output [d_width  :0] q; // quotient
	output [d_width-1:0] s; // remainder
	output div0;
	output ovf;

	reg [d_width :0] q;
	reg [d_width-1:0] s;
	reg div0;
	reg ovf;

	//
	// variables
	//
	reg [z_width -1:0] iz;
	reg [d_width -1:0] id;
	reg [d_width +1:0] spipe;

	wire [d_width -1:0] iq, is;
	wire                idiv0, iovf;

	//
	// module body
	//

	// delay d
	always @(posedge clk)
	  if (ena)
	    id <= #1 d;

	// check z, take abs value
	always @(posedge clk)
	  if (ena)
	    if (z[z_width-1])
	       iz <= #1 ~z +1'h1;
	    else
	       iz <= #1 z;

	// generate spipe (sign bit pipe)
	integer n;
	always @(posedge clk)
	  if(ena)
	  begin
	      spipe[0] <= #1 z[z_width-1];

	      for(n=1; n <= d_width+1; n=n+1)
	         spipe[n] <= #1 spipe[n-1];
	  end

	// hookup non-restoring divider
	div_uu #(z_width, d_width)
	divider (
		.clk(clk),
		.ena(ena),
		.z(iz),
		.d(id),
		.q(iq),
		.s(is),
		.div0(idiv0),
		.ovf(iovf)
	);

	// correct divider results if 'd' was negative
	always @(posedge clk)
	  if(ena)
	    if(spipe[d_width+1])
	    begin
	        q <= #1 (~iq) + 1'h1;
	        s <= #1 (~is) + 1'h1;
	    end
	    else
	    begin
	        q <= #1 {1'b0, iq};
	        s <= #1 {1'b0, is};
	    end

	// delay flags same as results
	always @(posedge clk)
	  if(ena)
	  begin
	      div0 <= #1 idiv0;
	      ovf  <= #1 iovf;
	  end
endmodule
module div_uu(clk, ena, z, d, q, s, div0, ovf);

	//
	// parameters
	//
	parameter z_width = 16;
	parameter d_width = z_width /2;
	
	//
	// inputs & outputs
	//
	input clk;               // system clock
	input ena;               // clock enable

	input  [z_width -1:0] z; // divident
	input  [d_width -1:0] d; // divisor
	output [d_width -1:0] q; // quotient
	reg [d_width-1:0] q;
	output [d_width -1:0] s; // remainder
	reg [d_width-1:0] s;
	output div0;
	reg div0;
	output ovf;
	reg ovf;

	//	
	// functions
	//
	function [z_width:0] gen_s;
		input [z_width:0] si;
		input [z_width:0] di;
	begin
	  if(si[z_width])
	    gen_s = {si[z_width-1:0], 1'b0} + di;
	  else
	    gen_s = {si[z_width-1:0], 1'b0} - di;
	end
	endfunction

	function [d_width-1:0] gen_q;
		input [d_width-1:0] qi;
		input [z_width:0] si;
	begin
	  gen_q = {qi[d_width-2:0], ~si[z_width]};
	end
	endfunction

	function [d_width-1:0] assign_s;
		input [z_width:0] si;
		input [z_width:0] di;
		reg [z_width:0] tmp;
	begin
	  if(si[z_width])
	    tmp = si + di;
	  else
	    tmp = si;

	  assign_s = tmp[z_width-1:z_width-4];
	end
	endfunction

	//
	// variables
	//
	reg [d_width-1:0] q_pipe  [d_width-1:0];
	reg [z_width:0] s_pipe  [d_width:0];
	reg [z_width:0] d_pipe  [d_width:0];

	reg [d_width:0] div0_pipe, ovf_pipe;
	//
	// perform parameter checks
	//
	// synopsys translate_off
	initial
	begin
	  if(d_width !== z_width / 2)
	    $display("div.v parameter error (d_width != z_width/2).");
	end
	// synopsys translate_on

	integer n0, n1, n2, n3;

	// generate divisor (d) pipe
	always @(d)
	  d_pipe[0] <= {1'b0, d, {(z_width-d_width){1'b0}} };

	always @(posedge clk)
	  if(ena)
	    for(n0=1; n0 <= d_width; n0=n0+1)
	       d_pipe[n0] <= #1 d_pipe[n0-1];

	// generate internal remainder pipe
	always @(z)
	  s_pipe[0] <= z;

	always @(posedge clk)
	  if(ena)
	    for(n1=1; n1 <= d_width; n1=n1+1)
	       s_pipe[n1] <= #1 gen_s(s_pipe[n1-1], d_pipe[n1-1]);

	// generate quotient pipe
	always @(posedge clk)
	  q_pipe[0] <= #1 0;

	always @(posedge clk)
	  if(ena)
	    for(n2=1; n2 < d_width; n2=n2+1)
	       q_pipe[n2] <= #1 gen_q(q_pipe[n2-1], s_pipe[n2]);


	// flags (divide_by_zero, overflow)
	always @(z or d)
	begin
	  ovf_pipe[0]  <= !(z[z_width-1:d_width] < d);
	  div0_pipe[0] <= ~|d;
	end

	always @(posedge clk)
	  if(ena)
	    for(n3=1; n3 <= d_width; n3=n3+1)
	    begin
	        ovf_pipe[n3] <= #1 ovf_pipe[n3-1];
	        div0_pipe[n3] <= #1 div0_pipe[n3-1];
	    end

	// assign outputs
	always @(posedge clk)
	  if(ena)
	    ovf <= #1 ovf_pipe[d_width];

	always @(posedge clk)
	  if(ena)
	    div0 <= #1 div0_pipe[d_width];

	always @(posedge clk)
	  if(ena)
	    q <= #1 gen_q(q_pipe[d_width-1], s_pipe[d_width]);

	always @(posedge clk)
	  if(ena)
	    s <= #1 assign_s(s_pipe[d_width], d_pipe[d_width]);
endmodule
module top (clk, reset, enable, count);
input clk, reset, enable;
output [15:0] count;
reg [15:0] count;                                   

always @ (posedge clk)
if (reset == 1'b1) begin
  count <= 0;
end else if ( enable == 1'b1) begin
  count <= count + 1;
end

endmodule
module dct_syn(clk, ena, rst, dstrb, din, dout, den);

	input clk;
	input ena;
	input rst;

	input dstrb;
	input [7:0] din;
	
	output [11:0] dout;
	output den;

	//
	// DCT unit
	//

	// As little as 11bits coefficients can be used while
	// all errors remain in the decimal bit range (dout[0])
	// total errors =  5(14bit resolution)
	//              = 12(13bit resolution)
	//              = 26(12bit resolution)
	//              = 54(11bit resolution)
	fdct #(13) dut (
		.clk(clk),
		.ena(1'b1),
		.rst(rst),
		.dstrb(dstrb),
		.din(din),
		.dout(dout),
		.douten(den)
	);

endmodule
module counter120bitx5(clk1,clk2,clk3,clk4,clk5,out1x,out2x,out3x,out4x,out5x,reset);

input clk1,clk2,clk3,clk4,clk5,reset;

output [13:0] out1x;
output [13:0] out2x;
output [13:0] out3x;
output [13:0] out4x;
output [13:0] out5x;

reg [120:0] cnt1;
reg [120:0] cnt2;
reg [120:0] cnt3;
reg [120:0] cnt4;
reg [120:0] cnt5;


assign out1x = {cnt1[120:115],cnt1[7:0]};
assign out2x = {cnt2[120:115],cnt2[7:0]};
assign out3x = {cnt3[120:115],cnt3[7:0]};
assign out4x = {cnt4[120:115],cnt4[7:0]};
assign out5x = {cnt5[120:115],cnt5[7:0]};
                     

always  @(posedge clk1)

begin

    if (reset)

        cnt1 <=1'b0;

    else

        cnt1 <= cnt1+1;

end


always  @(posedge clk2)

begin

    if (reset)

        cnt2 <=1'b0;

    else

        cnt2 <= cnt2 +1;

end
always  @(posedge clk3)

begin

    if (reset)

        cnt3 <=1'b0;

    else

        cnt3 <= cnt3 +1;

end
always  @(posedge clk4)

begin

    if (reset)

        cnt4 <=1'b0;

    else

        cnt4 <= cnt4 +1;

end

always  @(posedge clk5)

begin

    if (reset)

        cnt5 <=1'b0;

    else

        cnt5 <= cnt5 +1;

end


endmodule
module SMEMemoryMux (
	input		Select,
	
	input [9:0]		ReadAddressIn0,    // Expanded for Rel 0 on 6/18
	input [9:0]		ReadAddressIn1,    // Expanded for Rel 0 on 6/18
	output[9:0]		ReadAddressOut,    // Expanded for Rel 0 on 6/18
	
	input [9:0]		WriteAddressIn0,
	input [9:0]		WriteAddressIn1,
	output[9:0]		WriteAddressOut,
	
	input [8:0]		DataToMemoryIn0,
	input [8:0]		DataToMemoryIn1,
	output[8:0]		DataToMemoryOut,
	
	input [17:0]	DataFromMemoryIn0,
	input [17:0]	DataFromMemoryIn1,
	output[17:0]	DataFromMemoryOut,
	
	input			ReadEnableIn0,
	input			ReadEnableIn1,
	output			ReadEnableOut,
	
	input			WriteEnableIn0,
	input			WriteEnableIn1,
	output			WriteEnableOut,
	
	input			ReadClockIn0,
	input			ReadClockIn1,
	output			ReadClockOut	
	);
	
	assign ReadAddressOut = (Select) ? ReadAddressIn1 : ReadAddressIn0;
	assign WriteAddressOut = (Select) ? WriteAddressIn1 : WriteAddressIn0;
	assign DataToMemoryOut = (Select) ? DataToMemoryIn1 : DataToMemoryIn0;
	assign DataFromMemoryOut = (Select) ? DataFromMemoryIn1 : DataFromMemoryIn0;
	assign ReadEnableOut = (Select) ? ReadEnableIn1 : ReadEnableIn0;
	assign WriteEnableOut = (Select) ? WriteEnableIn1 : WriteEnableIn0;
	assign ReadClockOut = (Select) ? ReadClockIn1 : ReadClockIn0;

endmodule
module FFEDataMemoryMux (
	input		Select,
	
	input [9:0]		ReadAddressIn0,
	input [9:0]		ReadAddressIn1,
	output[9:0]		ReadAddressOut,
	
	input [9:0]		WriteAddressIn0,
	input [9:0]		WriteAddressIn1,
	output[9:0]		WriteAddressOut,
	
	input [35:0]	DataToMemoryIn0,
	input [35:0]	DataToMemoryIn1,
	output[35:0]	DataToMemoryOut,
	
	input [35:0]	DataFromMemoryIn0,
	input [35:0]	DataFromMemoryIn1,
	output[35:0]	DataFromMemoryOut,
	
	input			ReadEnable0,
	input			ReadEnable1,
	output			ReadEnable,
	
	input			WriteEnable0,
	input			WriteEnable1,
	output			WriteEnable
	);
	
	assign ReadAddressOut = (Select) ? ReadAddressIn1 : ReadAddressIn0;
	assign WriteAddressOut = (Select) ? WriteAddressIn1 : WriteAddressIn0;
	assign DataToMemoryOut = (Select) ? DataToMemoryIn1 : DataToMemoryIn0;
	assign DataFromMemoryOut = (Select) ? DataFromMemoryIn1 : DataFromMemoryIn0;
	assign ReadEnable = (Select) ? ReadEnable1 : ReadEnable0;
	assign WriteEnable = (Select) ? WriteEnable1 : WriteEnable0;

endmodule
module ring_osc_adjust (
	input			reset_i,				// async reset
	input			clk_ringosc_i,		// the ring oscillator output divided by 2 (this is not clk_main)
	input			clk_32khz_i,			// 32.768KHz reference clock
	input			enable_i,				// enable, can be tied off externally or driven occasionally to force re-calibration
	output	[15:0]	cal_val_o				// divider selection control for the ring oscillator divider circuit (in ASSP)
);

reg			enable_r1, enable_r2, enable_r3;
reg	[2:0]	downCnt;
reg			downCnt1_r1, downCnt1_r2;
reg	[15:0]	ringosc_2_cnt;
wire		ringosccnt_reset;

//// New Logic to produce CNT to system
//// Detect transition of Calibration aneble from Low to Hi
always @(posedge clk_32khz_i or posedge reset_i)
begin
	if (reset_i) begin
		enable_r1 <= 1'b0;
		enable_r2 <= 1'b0;
		enable_r3 <= 1'b0;
	end
	else begin
		enable_r1 <= enable_i;
		enable_r2 <= enable_r1;
		enable_r3 <= enable_r2;
	end
end

// Generating enable for Clock Cnt circuit
// Default is is 2 32KHz CLK period
always @(posedge clk_32khz_i or posedge reset_i)
begin
	if (reset_i)
		downCnt <= 3'b0;
	else
		if (enable_r2 && !enable_r3)
			downCnt <= 3'b111;
		else if (downCnt != 3'b000)
			downCnt <= downCnt - 1'b1;
		else
			downCnt <= downCnt;
end

// Sync to ring osc clk
always @(posedge clk_ringosc_i or posedge reset_i)
	if (reset_i)
	begin
		downCnt1_r1 <= 1'b0;
		downCnt1_r2 <= 1'b0;
	end
	else
	begin
		downCnt1_r1 <= downCnt[2];
		downCnt1_r2 <= downCnt1_r1;
	end

assign ringosccnt_reset = reset_i || !enable_i;
// Counting # of ringosc cyces in two 32KHz clock
always @(posedge clk_ringosc_i or posedge ringosccnt_reset)
begin
	if (ringosccnt_reset)
		ringosc_2_cnt <= 16'b0;
	else if (downCnt1_r2)
		ringosc_2_cnt <= ringosc_2_cnt + 1'b1;
	else
		ringosc_2_cnt <= ringosc_2_cnt;
end

assign	cal_val_o = ringosc_2_cnt;

endmodule