dakies/OSS_Verilog huggingface dataset:
module vga_wrapper (
    input clk,	
	input reset,        // system reset	

	output reg vga_iomem_ready,
	input iomem_valid,
	input iomem_ready,
	input [3:0]  iomem_wstrb,
	input [31:0] iomem_addr,
	input [31:0] iomem_wdata,	
	
    input video_on,
    input [9:0] x, y,
    output reg [11:0] rgb,
	
	output[4:0]   o_debug_pins
);
    
    // signal declarations
	wire charset_on, charset_on1, charset_on2;	
	reg char_mem_write, map_mem_write;
	wire [11:0] write_address;    
	wire [11:0] read_address, map_read_address;
	wire [11:0] rgb_rdata;
	wire [3:0] map_rdata;		
	
	always @(posedge clk) 
	begin
		if (reset) begin			
			char_mem_write <= 0;	
			map_mem_write <= 0;
		end else begin
			vga_iomem_ready <= 0;
			char_mem_write <= 0;
			map_mem_write <= 0;
			if (iomem_valid && !iomem_ready) begin
				vga_iomem_ready <= 1;				
				if(iomem_addr[23:20]==4'h1) begin
					if(iomem_wstrb[0]) begin
						char_mem_write <= 1;						
					end				
				end else if(iomem_addr[23:20]==4'h2) begin
					if(iomem_wstrb[0]) begin
						map_mem_write <= 1;
					end
				end
			end
		end
	end
	
	assign write_address = (iomem_addr[15:0]/4);
	assign read_address = {map_rdata, y[3:0], x[3:0]};
	assign map_read_address = ( y >> 4 ) * 6'd40 + ( x >> 4 );

	vga_map_ram map(
		.clk(clk),
		.wen(map_mem_write),			
		.waddr(write_address),		
		.wdata(iomem_wdata[3:0]),
		.ren(video_on), 
		.raddr(map_read_address), 
		.rdata(map_rdata)
	);
	
	vga_ram ram(
		.clk(clk),
		.wen(char_mem_write),			
		.waddr(write_address),		
		.wdata(iomem_wdata[11:0]),
		.ren(video_on), 
		.raddr(read_address), 
		.rdata(rgb_rdata)
	);
	

    // rgb multiplexing circuit
    always @(*)
	begin
        if(~video_on)
            rgb = 12'h000;      // blank
        else	
			rgb = rgb_rdata;				
	end
	
	assign o_debug_pins = {1'b0, 1'b0, 1'b0, 1'b0, 1'b0};	
	
endmodule
module vga_ram (
    input clk,	
	input wen, 
	input [11:0] waddr,
	input [11:0] wdata,	
    input ren,	
	input [11:0] raddr,		    	
    output reg [11:0] rdata
);
	//parameter MEM_INIT_FILE = "vid_ram.mem";
	(* ram_style = "distributed" *) reg [11:0] ram [0:4095];   //  memory for 16 character with dimension 16x16 pixels @ 12bpp
	
	//initial
	//if (MEM_INIT_FILE != "")
	//	$readmemh(MEM_INIT_FILE, ram);
		
    always @(posedge clk) 
	begin
		if (ren)
			rdata <= ram[raddr];
	end		
			
    always @(posedge clk) 
	begin			
		if (wen)
			ram[waddr] <= wdata;
    end
	
endmodule
module vga_map_ram (
    input clk,	
	input wen, 
	input [11:0] waddr,
	input [3:0] wdata,	
    input ren,	
	input [11:0] raddr,		    	
    output reg [3:0] rdata
);
	//parameter MEM_INIT_FILE = "vid_ram.mem";
	(* ram_style = "block" *) reg [3:0] map_ram [0:1199];   // memory for 40 x 30 position mega character with value between 0-15 for character id
	
	//initial
	//if (MEM_INIT_FILE != "")
	//	$readmemh(MEM_INIT_FILE, map_ram);
		
    always @(posedge clk) 
	begin
		if (ren)
			rdata <= map_ram[raddr];
	end		
			
    always @(posedge clk) 
	begin			
		if (wen)
			map_ram[waddr] <= wdata;
    end
	
endmodule
module top
(
   input  i_Rx_Serial,
   input  clk,
   output o_Tx_Serial
);

// Intermediate signals for UART Rx
reg        o_Rx_DV;
reg [7:0]  o_Rx_Byte;
wire       o_Rx_DV1;
wire [7:0] o_Rx_Byte1;

// Intermediate signals for UART Tx
reg       i_Tx_DV;
reg [7:0] i_Tx_Byte;
wire      o_Tx_Active;
wire      o_Tx_Done;


// Instance of UART Receiver
uart_rx  #(.CLKS_PER_BIT(87)) uart_rx1 (
    .osc_clk(clk),
    .i_Rx_Serial(i_Rx_Serial),
    .o_Rx_DV(o_Rx_DV1),
    .o_Rx_Byte(o_Rx_Byte1)
);

// Instance of UART Transmitter
uart_tx  #(.CLKS_PER_BIT(87)) uart_tx1 (
    .osc_clk(clk), 
    .i_Tx_DV(i_Tx_DV),
    .i_Tx_Byte(i_Tx_Byte),
    .o_Tx_Active(o_Tx_Active),
    .o_Tx_Serial(o_Tx_Serial),
    .o_Tx_Done(o_Tx_Done)
);

// Main processing
always @ (posedge clk)
begin
    // Update Rx signals
    o_Rx_DV <= o_Rx_DV1;
    o_Rx_Byte <= o_Rx_Byte1;

    // If data is received, start transmitting it
    if (o_Rx_DV) begin
        i_Tx_Byte <= o_Rx_Byte;
        i_Tx_DV <= 1'b1;  // Start transmission
    end else if (o_Tx_Done) begin
        i_Tx_DV <= 1'b0;  // Transmission done
    end
end

endmodule
module top_checkered (
   input  wire clk,
   input  wire btn,
   output wire oled_csn,
   output wire oled_clk,
   output wire oled_mosi,
   output wire oled_dc,
   output wire oled_resn,
   output wire led
);
   wire [7:0] x ;
   wire [7:0] y ;
   //                  checkered      red   green   blue     red    green  blue
   wire [15:0] color = x[4] ^ y[4] ? {5'd0, x[7:3], 6'd0} : {y[7:3], 6'd0, 5'd0};

   wire clk270, clk180, clk90, clk_25mhz, usr_ref_out;
   wire usr_pll_lock_stdy, usr_pll_lock;
   
   reg [26:0] counter;
   
   CC_PLL #(
   	  .REF_CLK("10.0"),    // reference input in MHz
   	  .OUT_CLK("25.0"),   // pll output frequency in MHz
   	  .PERF_MD("ECONOMY"), // LOWPOWER, ECONOMY, SPEED
   	  .LOW_JITTER(1),      // 0: disable, 1: enable low jitter mode
   	  .CI_FILTER_CONST(2), // optional CI filter constant
   	  .CP_FILTER_CONST(4)  // optional CP filter constant
   ) pll_inst (
   	  .CLK_REF(clk), .CLK_FEEDBACK(1'b0), .USR_CLK_REF(1'b0),
   	  .USR_LOCKED_STDY_RST(1'b0), .USR_PLL_LOCKED_STDY(usr_pll_lock_stdy), .USR_PLL_LOCKED(usr_pll_lock),
   	  .CLK270(clk270), .CLK180(clk180), .CLK90(clk90), .CLK0(clk_25mhz), .CLK_REF_OUT(usr_ref_out)
   );



   lcd_video #(
      .c_clk_spi_mhz(25),
      .c_init_file("st7789_linit.mem"),
      .c_init_size(35),
      .c_color_bits(16)
   ) lcd_video_inst (
	//clk_pixel(clk_25mhz),
	//.clk_pixel_ena(1'b0),
      .clk_spi(clk_25mhz),
      .reset(~btn),
      .x(x),
      .y(y),
      .color(color),
      .spi_clk(oled_clk),
      .spi_mosi(oled_mosi),
      .spi_dc(oled_dc),
      .spi_resn(oled_resn)//,
	 //.spi_csn (oled_csn)
   );

   assign led = counter[26];
   
   always @(posedge clk_25mhz)
   begin
   	  if (!btn) begin
   	     counter <= 0;
   	  end else begin
   	     counter <= counter + 1'b1;
   	  end
   end
   assign oled_csn = 0; // oled_csn is connected to BLK (backlight enable pin)

endmodule
module ksl_add_rom (
	clk,
	fnum,
	block,
	ksl,
	ksl_add_p2
);
	reg _sv2v_0;
	input wire clk;
	localparam opl3_pkg_REG_FNUM_WIDTH = 10;
	input wire [9:0] fnum;
	localparam opl3_pkg_REG_BLOCK_WIDTH = 3;
	input wire [2:0] block;
	localparam opl3_pkg_REG_KSL_WIDTH = 2;
	input wire [1:0] ksl;
	localparam opl3_pkg_KSL_ADD_WIDTH = 8;
	output reg [7:0] ksl_add_p2 = 0;
	reg [6:0] rom_out_p1 = 0;
	reg [5:0] tmp0_p1 = 0;
	reg signed [7:0] tmp1_p1;
	reg [3:0] fnum_shifted_p0;
	reg [1:0] ksl_p1 = 0;
	always @(*) begin
		if (_sv2v_0)
			;
		fnum_shifted_p0 = fnum >> 6;
	end
	always @(posedge clk)
		(* full_case, parallel_case *)
		case (fnum_shifted_p0)
			0: rom_out_p1 <= 0;
			1: rom_out_p1 <= 32;
			2: rom_out_p1 <= 40;
			3: rom_out_p1 <= 45;
			4: rom_out_p1 <= 48;
			5: rom_out_p1 <= 51;
			6: rom_out_p1 <= 53;
			7: rom_out_p1 <= 55;
			8: rom_out_p1 <= 56;
			9: rom_out_p1 <= 58;
			10: rom_out_p1 <= 59;
			11: rom_out_p1 <= 60;
			12: rom_out_p1 <= 61;
			13: rom_out_p1 <= 62;
			14: rom_out_p1 <= 63;
			15: rom_out_p1 <= 64;
		endcase
	always @(posedge clk) tmp0_p1 <= block - 8;
	always @(*) begin
		if (_sv2v_0)
			;
		tmp1_p1 = $signed(rom_out_p1 + (tmp0_p1 << 3));
	end
	always @(posedge clk) begin
		ksl_p1 <= ksl;
		(* full_case, parallel_case *)
		case (ksl_p1)
			0: ksl_add_p2 <= 0;
			1: ksl_add_p2 <= (tmp1_p1 <= 0 ? 0 : tmp1_p1 << 1);
			2: ksl_add_p2 <= (tmp1_p1 <= 0 ? 0 : tmp1_p1);
			3: ksl_add_p2 <= (tmp1_p1 <= 0 ? 0 : tmp1_p1 << 2);
		endcase
	end
	initial _sv2v_0 = 0;
endmodule
module tremolo (
	clk,
	sample_clk_en,
	bank_num,
	op_num,
	dam,
	am_val_p2
);
	reg _sv2v_0;
	input wire clk;
	input wire sample_clk_en;
	localparam opl3_pkg_NUM_BANKS = 2;
	localparam opl3_pkg_BANK_NUM_WIDTH = 1;
	input wire [0:0] bank_num;
	localparam opl3_pkg_NUM_OPERATORS_PER_BANK = 18;
	localparam opl3_pkg_OP_NUM_WIDTH = 5;
	input wire [4:0] op_num;
	input wire dam;
	localparam opl3_pkg_TREMOLO_MAX_COUNT = 13312;
	localparam opl3_pkg_TREMOLO_INDEX_WIDTH = 14;
	localparam opl3_pkg_AM_VAL_WIDTH = 6;
	output reg [5:0] am_val_p2 = 0;
	localparam PIPELINE_DELAY = 2;
	reg [13:0] tremolo_index_p1 = 1'sb0;
	reg [5:0] am_val_tmp0_p1;
	reg [5:0] am_val_tmp1_p1;
	reg dam_p1 = 0;
	always @(posedge clk)
		if ((sample_clk_en && (bank_num == 0)) && (op_num == 0)) begin
			if (tremolo_index_p1 == 13311)
				tremolo_index_p1 <= 0;
			else
				tremolo_index_p1 <= tremolo_index_p1 + 1;
		end
	always @(*) begin
		if (_sv2v_0)
			;
		am_val_tmp0_p1 = tremolo_index_p1 >> 8;
	end
	always @(*) begin
		if (_sv2v_0)
			;
		if (am_val_tmp0_p1 > 26)
			am_val_tmp1_p1 = 52 + ~am_val_tmp0_p1;
		else
			am_val_tmp1_p1 = am_val_tmp0_p1;
	end
	always @(posedge clk) begin
		dam_p1 <= dam;
		if (dam_p1)
			am_val_p2 <= am_val_tmp1_p1;
		else
			am_val_p2 <= am_val_tmp1_p1 >> 2;
	end
	initial _sv2v_0 = 0;
endmodule
module calc_phase_inc (
	clk,
	sample_clk_en,
	bank_num,
	op_num,
	fnum,
	mult,
	block,
	vib,
	dvb,
	phase_inc_p2
);
	reg _sv2v_0;
	input wire clk;
	input wire sample_clk_en;
	localparam opl3_pkg_NUM_BANKS = 2;
	localparam opl3_pkg_BANK_NUM_WIDTH = 1;
	input wire [0:0] bank_num;
	localparam opl3_pkg_NUM_OPERATORS_PER_BANK = 18;
	localparam opl3_pkg_OP_NUM_WIDTH = 5;
	input wire [4:0] op_num;
	localparam opl3_pkg_REG_FNUM_WIDTH = 10;
	input wire [9:0] fnum;
	localparam opl3_pkg_REG_MULT_WIDTH = 4;
	input wire [3:0] mult;
	localparam opl3_pkg_REG_BLOCK_WIDTH = 3;
	input wire [2:0] block;
	input wire vib;
	input wire dvb;
	localparam opl3_pkg_PHASE_ACC_WIDTH = 20;
	output reg [19:0] phase_inc_p2 = 0;
	localparam PIPELINE_DELAY = 2;
	reg signed [19:0] pre_mult_p0;
	reg signed [19:0] pre_mult_p1 = 0;
	reg signed [19:0] post_mult_p2 = 0;
	localparam opl3_pkg_VIB_VAL_WIDTH = 3;
	wire [2:0] vib_val_p2;
	wire [PIPELINE_DELAY:1] vib_p;
	reg [4:0] multiplier_p1 = 0;
	always @(*) begin
		if (_sv2v_0)
			;
		pre_mult_p0 = fnum << block;
	end
	always @(posedge clk)
		(* full_case, parallel_case *)
		case (mult)
			'h0: multiplier_p1 <= 1;
			'h1: multiplier_p1 <= 2;
			'h2: multiplier_p1 <= 4;
			'h3: multiplier_p1 <= 6;
			'h4: multiplier_p1 <= 8;
			'h5: multiplier_p1 <= 10;
			'h6: multiplier_p1 <= 12;
			'h7: multiplier_p1 <= 14;
			'h8: multiplier_p1 <= 16;
			'h9: multiplier_p1 <= 18;
			'ha: multiplier_p1 <= 20;
			'hb: multiplier_p1 <= 20;
			'hc: multiplier_p1 <= 24;
			'hd: multiplier_p1 <= 24;
			'he: multiplier_p1 <= 30;
			'hf: multiplier_p1 <= 30;
		endcase
	always @(posedge clk) begin
		pre_mult_p1 <= pre_mult_p0;
		post_mult_p2 <= (pre_mult_p1 * multiplier_p1) >> 1;
	end
	pipeline_sr #(.ENDING_CYCLE(PIPELINE_DELAY)) vib_sr(
		.clk(clk),
		.in(vib),
		.out(vib_p)
	);
	always @(*) begin
		if (_sv2v_0)
			;
		if (vib_p[2])
			phase_inc_p2 = post_mult_p2 + vib_val_p2;
		else
			phase_inc_p2 = post_mult_p2;
	end
	vibrato vibrato(
		.clk(clk),
		.sample_clk_en(sample_clk_en),
		.fnum(fnum),
		.dvb(dvb),
		.vib_val_p2(vib_val_p2)
	);
	initial _sv2v_0 = 0;
endmodule
module vibrato (
	clk,
	sample_clk_en,
	fnum,
	dvb,
	vib_val_p2
);
	reg _sv2v_0;
	input wire clk;
	input wire sample_clk_en;
	localparam opl3_pkg_REG_FNUM_WIDTH = 10;
	input wire [9:0] fnum;
	input wire dvb;
	localparam opl3_pkg_VIB_VAL_WIDTH = 3;
	output reg [2:0] vib_val_p2 = 0;
	localparam VIBRATO_INDEX_WIDTH = 13;
	reg [12:0] vibrato_index_p1 = 0;
	reg [2:0] delta0_p1;
	reg [2:0] delta1_p1;
	reg [2:0] delta2_p1;
	reg [9:0] fnum_p1 = 0;
	reg dvb_p1 = 0;
	always @(posedge clk) begin
		fnum_p1 <= fnum;
		dvb_p1 <= dvb;
	end
	always @(posedge clk)
		if (sample_clk_en)
			vibrato_index_p1 <= vibrato_index_p1 + 1;
	always @(*) begin
		if (_sv2v_0)
			;
		delta0_p1 = fnum_p1 >> 7;
	end
	always @(*) begin
		if (_sv2v_0)
			;
		delta1_p1 = (((vibrato_index_p1 >> 10) & 3) == 3 ? delta0_p1 >> 1 : delta0_p1);
	end
	always @(*) begin
		if (_sv2v_0)
			;
		delta2_p1 = (!dvb_p1 ? delta1_p1 >> 1 : delta1_p1);
	end
	always @(posedge clk) vib_val_p2 <= (((vibrato_index_p1 >> 10) & 4) != 0 ? ~delta2_p1 : delta2_p1);
	initial _sv2v_0 = 0;
endmodule
module calc_rhythm_phase (
	clk,
	sample_clk_en,
	bank_num,
	op_num,
	phase_acc_p3,
	op_type,
	rhythm_phase_p3
);
	reg _sv2v_0;
	input wire clk;
	input wire sample_clk_en;
	localparam opl3_pkg_NUM_BANKS = 2;
	localparam opl3_pkg_BANK_NUM_WIDTH = 1;
	input wire [0:0] bank_num;
	localparam opl3_pkg_NUM_OPERATORS_PER_BANK = 18;
	localparam opl3_pkg_OP_NUM_WIDTH = 5;
	input wire [4:0] op_num;
	localparam opl3_pkg_PHASE_ACC_WIDTH = 20;
	input wire [19:0] phase_acc_p3;
	input wire [2:0] op_type;
	output reg [19:0] rhythm_phase_p3;
	localparam PIPELINE_DELAY = 3;
	localparam RAND_POLYNOMIAL = 'h800302;
	localparam RAND_NUM_WIDTH = $clog2('h800302);
	reg [19:0] hh_phase_friend = 0;
	reg [19:0] hh_phase_p3;
	reg [19:0] phase_bit_p3;
	reg [19:0] noise_bit_p3;
	reg [RAND_NUM_WIDTH - 1:0] rand_num = 1;
	wire [PIPELINE_DELAY:1] sample_clk_en_p;
	wire [11:3] op_type_p;
	pipeline_sr #(.ENDING_CYCLE(PIPELINE_DELAY)) sample_clk_en_sr(
		.clk(clk),
		.in(sample_clk_en),
		.out(sample_clk_en_p)
	);
	pipeline_sr #(
		.DATA_WIDTH(3),
		.ENDING_CYCLE(PIPELINE_DELAY),
		.POR_VALUE(3'd0)
	) op_type_sr(
		.clk(clk),
		.in(op_type),
		.out(op_type_p)
	);
	always @(posedge clk)
		if ((sample_clk_en_p[3] && (bank_num == 0)) && (op_num == 13))
			hh_phase_friend <= phase_acc_p3;
	always @(*) begin
		if (_sv2v_0)
			;
		(* full_case, parallel_case *)
		case (op_type_p[9+:3])
			3'd4: hh_phase_p3 = (hh_phase_friend & 'h100 ? 'h200 : 'h100);
			3'd5: hh_phase_p3 = hh_phase_friend;
			default: hh_phase_p3 = phase_acc_p3;
		endcase
		phase_bit_p3 = (((hh_phase_p3 & 'h88) ^ ((hh_phase_p3 << 5) & 'h80)) | ((hh_phase_p3 ^ (hh_phase_p3 << 2)) & 'h20) ? 'h2 : 'h0);
		noise_bit_p3 = (op_type_p[9+:3] == 3'd2 ? rand_num[0] << 1 : rand_num[0] << 8);
	end
	always @(*) begin
		if (_sv2v_0)
			;
		(* full_case, parallel_case *)
		case (op_type_p[9+:3])
			3'd0: rhythm_phase_p3 = phase_acc_p3;
			3'd1: rhythm_phase_p3 = phase_acc_p3;
			3'd2: rhythm_phase_p3 = (phase_bit_p3 << 8) | ('h34 << (phase_bit_p3 ^ noise_bit_p3));
			3'd3: rhythm_phase_p3 = phase_acc_p3;
			3'd4: rhythm_phase_p3 = hh_phase_p3 ^ noise_bit_p3;
			3'd5: rhythm_phase_p3 = (1 + phase_bit_p3) << 8;
		endcase
	end
	always @(posedge clk)
		if ((sample_clk_en && (bank_num == 0)) && (op_num == 0)) begin
			if (rand_num & 1)
				rand_num <= (rand_num ^ RAND_POLYNOMIAL) >> 1;
			else
				rand_num <= rand_num >> 1;
		end
	initial _sv2v_0 = 0;
endmodule
module clk_div (
	clk,
	clk_en
);
	parameter CLK_DIV_COUNT = 0;
	input wire clk;
	output reg clk_en = 0;
	reg [$clog2(CLK_DIV_COUNT) - 1:0] counter = 0;
	always @(posedge clk)
		if (counter == (CLK_DIV_COUNT - 1))
			counter <= 0;
		else
			counter <= counter + 1;
	always @(posedge clk) clk_en <= counter == (CLK_DIV_COUNT - 1);
endmodule
module reset_sync (
	clk,
	arst_n,
	reset
);
	reg _sv2v_0;
	input wire clk;
	input wire arst_n;
	output reg reset;
	(* ASYNC_REG = "true" *) reg r0 = 1;
	(* ASYNC_REG = "true" *) reg r1 = 1;
	(* ASYNC_REG = "true" *) reg r2 = 1;
	always @(posedge clk or negedge arst_n)
		if (!arst_n) begin
			r0 <= 1;
			r1 <= 1;
			r2 <= 1;
		end
		else begin
			r0 <= 0;
			r1 <= r0;
			r2 <= r1;
		end
	always @(*) begin
		if (_sv2v_0)
			;
		reset = r2;
	end
	initial _sv2v_0 = 0;
endmodule
module timers (
	clk,
	reset,
	opl3_reg_wr,
	irq_n,
	status,
	force_timer_overflow
);
	reg _sv2v_0;
	input wire clk;
	input wire reset;
	localparam opl3_pkg_REG_FILE_DATA_WIDTH = 8;
	input wire [17:0] opl3_reg_wr;
	output reg irq_n = 0;
	output reg [7:0] status;
	input wire force_timer_overflow;
	localparam opl3_pkg_REG_TIMER_WIDTH = 8;
	reg [7:0] timer1 = 0;
	reg [7:0] timer2 = 0;
	reg irq_rst = 0;
	reg mt1 = 0;
	reg mt2 = 0;
	reg st1 = 0;
	reg st2 = 0;
	wire timer1_overflow_pulse;
	wire timer2_overflow_pulse;
	reg ft1 = 0;
	reg ft2 = 0;
	reg irq;
	always @(posedge clk) begin
		if (opl3_reg_wr[17]) begin
			if ((opl3_reg_wr[16] == 0) && (opl3_reg_wr[15-:8] == 2))
				timer1 <= opl3_reg_wr[7-:opl3_pkg_REG_FILE_DATA_WIDTH];
			if ((opl3_reg_wr[16] == 0) && (opl3_reg_wr[15-:8] == 3))
				timer2 <= opl3_reg_wr[7-:opl3_pkg_REG_FILE_DATA_WIDTH];
			if ((opl3_reg_wr[16] == 0) && (opl3_reg_wr[15-:8] == 4)) begin
				irq_rst <= opl3_reg_wr[7];
				mt1 <= opl3_reg_wr[6];
				mt2 <= opl3_reg_wr[5];
				st2 <= opl3_reg_wr[1];
				st1 <= opl3_reg_wr[0];
			end
		end
		if (reset) begin
			timer1 <= 0;
			timer2 <= 0;
			irq_rst <= 0;
			mt1 <= 0;
			mt2 <= 0;
			st2 <= 0;
			st1 <= 0;
		end
	end
	localparam opl3_pkg_CLK_FREQ = 12727000;
	localparam signed [31:0] opl3_pkg_TIMER1_TICK_INTERVAL = opl3_pkg_CLK_FREQ * 80e-6;
	timer #(.TIMER_TICK_INTERVAL(opl3_pkg_TIMER1_TICK_INTERVAL)) timer1_inst(
		.clk(clk),
		.timer_reg(timer1),
		.start_timer(st1),
		.timer_overflow_pulse(timer1_overflow_pulse)
	);
	localparam signed [31:0] opl3_pkg_TIMER2_TICK_INTERVAL = opl3_pkg_CLK_FREQ * 320e-6;
	timer #(.TIMER_TICK_INTERVAL(opl3_pkg_TIMER2_TICK_INTERVAL)) timer2_inst(
		.clk(clk),
		.timer_reg(timer2),
		.start_timer(st2),
		.timer_overflow_pulse(timer2_overflow_pulse)
	);
	always @(posedge clk) begin
		if ((timer1_overflow_pulse || force_timer_overflow) && !mt1)
			ft1 <= 1;
		if (timer2_overflow_pulse && !mt2)
			ft2 <= 1;
		if (reset || irq_rst) begin
			ft1 <= 0;
			ft2 <= 0;
		end
	end
	always @(*) begin
		if (_sv2v_0)
			;
		irq = ft1 || ft2;
	end
	always @(posedge clk) irq_n <= !irq;
	always @(*) begin
		if (_sv2v_0)
			;
		status = 0;
		status[7] = irq;
		status[6] = ft1;
		status[5] = ft2;
	end
	initial _sv2v_0 = 0;
endmodule
module timer (
	clk,
	timer_reg,
	start_timer,
	timer_overflow_pulse
);
	reg _sv2v_0;
	parameter TIMER_TICK_INTERVAL = 0;
	input wire clk;
	localparam opl3_pkg_REG_TIMER_WIDTH = 8;
	input wire [7:0] timer_reg;
	input wire start_timer;
	output reg timer_overflow_pulse = 0;
	localparam opl3_pkg_CLK_FREQ = 12727000;
	localparam signed [31:0] TICK_TIMER_COUNT_VALUE = opl3_pkg_CLK_FREQ * TIMER_TICK_INTERVAL;
	reg [$clog2(TICK_TIMER_COUNT_VALUE) - 1:0] tick_counter = 0;
	reg tick_pulse = 0;
	reg [7:0] timer = 0;
	wire start_timer_set_pulse;
	edge_detector #(
		.EDGE_LEVEL(1),
		.CLK_DLY(0)
	) start_timer_edge_detect(
		.clk(clk),
		.clk_en(1'b1),
		.in(start_timer),
		.edge_detected(start_timer_set_pulse)
	);
	always @(*) begin
		if (_sv2v_0)
			;
		tick_pulse = tick_counter == (TICK_TIMER_COUNT_VALUE - 1);
	end
	always @(posedge clk)
		if (start_timer) begin
			if (tick_pulse || start_timer_set_pulse)
				tick_counter <= 0;
			else
				tick_counter <= tick_counter + 1;
		end
	always @(posedge clk)
		if (start_timer_set_pulse)
			timer <= timer_reg;
		else if (tick_pulse) begin
			if (timer == 255)
				timer <= timer_reg;
			else
				timer <= timer + 1;
		end
	always @(posedge clk) timer_overflow_pulse <= (timer == 255) && tick_pulse;
	initial _sv2v_0 = 0;
endmodule
module opl3 (
	clk,
	clk_host,
	clk_dac,
	ic_n,
	cs_n,
	rd_n,
	wr_n,
	address,
	din,
	dout,
	sample_valid,
	sample_l,
	sample_r,
	led,
	irq_n
);
	reg _sv2v_0;
	input wire clk;
	input wire clk_host;
	input wire clk_dac;
	input wire ic_n;
	input wire cs_n;
	input wire rd_n;
	input wire wr_n;
	input wire [1:0] address;
	localparam opl3_pkg_REG_FILE_DATA_WIDTH = 8;
	input wire [7:0] din;
	output wire [7:0] dout;
	output wire sample_valid;
	localparam opl3_pkg_DAC_OUTPUT_WIDTH = 24;
	output wire signed [23:0] sample_l;
	output wire signed [23:0] sample_r;
	localparam opl3_pkg_NUM_LEDS = 4;
	output wire [3:0] led;
	output reg irq_n;
	wire reset;
	wire sample_clk_en;
	wire [17:0] opl3_reg_wr;
	wire [7:0] status;
	wire force_timer_overflow;
	reset_sync reset_sync(
		.clk(clk),
		.arst_n(ic_n),
		.reset(reset)
	);
	host_if host_if(
		.clk(clk),
		.reset(reset),
		.clk_host(clk_host),
		.ic_n(ic_n),
		.cs_n(cs_n),
		.rd_n(rd_n),
		.wr_n(wr_n),
		.address(address),
		.din(din),
		.dout(dout),
		.opl3_reg_wr(opl3_reg_wr),
		.status(status),
		.force_timer_overflow(force_timer_overflow)
	);
	localparam signed [31:0] opl3_pkg_CLK_DIV_COUNT = 256;
	clk_div #(.CLK_DIV_COUNT(opl3_pkg_CLK_DIV_COUNT)) sample_clk_gen(
		.clk_en(sample_clk_en),
		.clk(clk)
	);
	channels channels(
		.clk(clk),
		.reset(reset),
		.clk_dac(clk_dac),
		.opl3_reg_wr(opl3_reg_wr),
		.sample_clk_en(sample_clk_en),
		.sample_valid(sample_valid),
		.sample_l(sample_l),
		.sample_r(sample_r)
	);
	leds leds(
		.clk(clk),
		.opl3_reg_wr(opl3_reg_wr),
		.led(led)
	);
	localparam opl3_pkg_INSTANTIATE_TIMERS = 0;
	generate
		if (opl3_pkg_INSTANTIATE_TIMERS) begin : genblk1
			wire [1:1] sv2v_tmp_timers_irq_n;
			always @(*) irq_n = sv2v_tmp_timers_irq_n;
			timers timers(
				.clk(clk),
				.reset(reset),
				.opl3_reg_wr(opl3_reg_wr),
				.irq_n(sv2v_tmp_timers_irq_n),
				.status(status),
				.force_timer_overflow(force_timer_overflow)
			);
		end
		else begin : genblk1
			always @(*) begin
				if (_sv2v_0)
					;
				irq_n = 1;
			end
		end
	endgenerate
	initial _sv2v_0 = 0;
endmodule
module host_if (
	clk,
	reset,
	clk_host,
	ic_n,
	cs_n,
	rd_n,
	wr_n,
	address,
	din,
	dout,
	opl3_reg_wr,
	status,
	force_timer_overflow
);
	reg _sv2v_0;
	input wire clk;
	input wire reset;
	input wire clk_host;
	input wire ic_n;
	input wire cs_n;
	input wire rd_n;
	input wire wr_n;
	input wire [1:0] address;
	localparam opl3_pkg_REG_FILE_DATA_WIDTH = 8;
	input wire [7:0] din;
	output reg [7:0] dout = 0;
	output reg [17:0] opl3_reg_wr = 0;
	input wire [7:0] status;
	output reg force_timer_overflow;
	reg cs_p1_n = 1;
	reg wr_p1_n = 1;
	reg [1:0] address_p1 = 0;
	reg [7:0] din_p1 = 0;
	wire opl3_fifo_empty;
	wire [1:0] opl3_address;
	wire [7:0] opl3_data;
	reg wr_p1;
	reg wr_p2 = 0;
	wire [7:0] host_status;
	reg [7:0] host_status_p1 = 0;
	always @(posedge clk_host) begin
		cs_p1_n <= cs_n;
		wr_p1_n <= wr_n;
		address_p1 <= address;
		din_p1 <= din;
		wr_p2 <= wr_p1;
	end
	always @(*) begin
		if (_sv2v_0)
			;
		wr_p1 = !cs_p1_n && !wr_p1_n;
	end
	afifo #(
		.LGFIFO(6),
		.WIDTH(10)
	) afifo(
		.i_wclk(clk_host),
		.i_wr_reset_n(ic_n),
		.i_wr(wr_p1 && !wr_p2),
		.i_wr_data({address_p1, din_p1}),
		.o_wr_full(),
		.i_rclk(clk),
		.i_rd_reset_n(!reset),
		.i_rd(!opl3_fifo_empty),
		.o_rd_data({opl3_address, opl3_data}),
		.o_rd_empty(opl3_fifo_empty)
	);
	always @(posedge clk) begin
		opl3_reg_wr[17] <= 0;
		if (!opl3_fifo_empty) begin
			if (!opl3_address[0]) begin
				opl3_reg_wr[16] <= opl3_address[1];
				opl3_reg_wr[15-:8] <= opl3_data;
			end
			else begin
				opl3_reg_wr[7-:opl3_pkg_REG_FILE_DATA_WIDTH] <= opl3_data;
				opl3_reg_wr[17] <= 1;
			end
		end
		if (reset)
			opl3_reg_wr <= 0;
	end
	synchronizer #(.DATA_WIDTH(opl3_pkg_REG_FILE_DATA_WIDTH)) dout_sync(
		.clk(clk_host),
		.in(status),
		.out(host_status)
	);
	always @(posedge clk_host) host_status_p1 <= host_status;
	always @(*) begin
		if (_sv2v_0)
			;
		dout = (address_p1 == 0 ? host_status_p1 : {8 {1'sb1}});
	end
	localparam opl3_pkg_INSTANTIATE_TIMERS = 0;
	generate
		if (opl3_pkg_INSTANTIATE_TIMERS) begin : genblk1
			wire [1:1] sv2v_tmp_trick_sw_detection_force_timer_overflow;
			always @(*) force_timer_overflow = sv2v_tmp_trick_sw_detection_force_timer_overflow;
			trick_sw_detection trick_sw_detection(
				.clk(clk),
				.clk_host(clk_host),
				.ic_n(ic_n),
				.cs_n(cs_n),
				.rd_n(rd_n),
				.wr_n(wr_n),
				.address(address),
				.din(din),
				.force_timer_overflow(sv2v_tmp_trick_sw_detection_force_timer_overflow)
			);
		end
		else begin : genblk1
			always @(*) begin
				if (_sv2v_0)
					;
				force_timer_overflow = 0;
			end
		end
	endgenerate
	initial _sv2v_0 = 0;
endmodule
module trick_sw_detection (
	clk,
	clk_host,
	ic_n,
	cs_n,
	rd_n,
	wr_n,
	address,
	din,
	force_timer_overflow
);
	reg _sv2v_0;
	input wire clk;
	input wire clk_host;
	input wire ic_n;
	input wire cs_n;
	input wire rd_n;
	input wire wr_n;
	input wire [1:0] address;
	localparam opl3_pkg_REG_FILE_DATA_WIDTH = 8;
	input wire [7:0] din;
	output wire force_timer_overflow;
	localparam NUM_READS_TO_TRIGGER_OVERFLOW = 50;
	reg cs_p1_n = 1;
	reg wr_p1_n = 1;
	reg rd_p1_n = 1;
	reg [1:0] address_p1 = 0;
	reg [7:0] din_p1 = 0;
	reg wr_p1;
	reg wr_p2 = 0;
	reg [5:0] host_rd_counter = 0;
	reg [17:0] host_reg_wr;
	reg rd_p1;
	reg rd_p2 = 0;
	reg host_force_timer_overflow = 0;
	reg start_counter = 0;
	localparam opl3_pkg_REG_TIMER_WIDTH = 8;
	reg [7:0] timer1 = 0;
	always @(posedge clk_host) begin
		cs_p1_n <= cs_n;
		wr_p1_n <= wr_n;
		rd_p1_n <= rd_n;
		address_p1 <= address;
		din_p1 <= din;
		wr_p2 <= wr_p1;
	end
	always @(*) begin
		if (_sv2v_0)
			;
		wr_p1 = !cs_p1_n && !wr_p1_n;
	end
	always @(posedge clk_host) begin
		host_reg_wr[17] <= 0;
		if (wr_p1 && !wr_p2) begin
			if (!address_p1[0]) begin
				host_reg_wr[16] <= address_p1[1];
				host_reg_wr[15-:8] <= din_p1;
			end
			else begin
				host_reg_wr[17] <= 1;
				host_reg_wr[7-:opl3_pkg_REG_FILE_DATA_WIDTH] <= din_p1;
			end
		end
		if ((host_reg_wr[17] && (host_reg_wr[16] == 0)) && (host_reg_wr[15-:8] == 'h2))
			timer1 <= host_reg_wr[7-:opl3_pkg_REG_FILE_DATA_WIDTH];
		if (!ic_n) begin
			host_reg_wr <= 0;
			timer1 <= 0;
		end
	end
	always @(*) begin
		if (_sv2v_0)
			;
		rd_p1 = !cs_p1_n && !rd_p1_n;
	end
	always @(posedge clk_host) begin
		rd_p2 <= rd_p1;
		if ((((host_reg_wr[17] && (host_reg_wr[16] == 0)) && (host_reg_wr[15-:8] == 'h4)) && host_reg_wr[0]) && (timer1 == 'hff)) begin
			start_counter <= 1;
			host_rd_counter <= 0;
			host_force_timer_overflow <= 0;
		end
		if ((start_counter && rd_p1) && !rd_p2)
			host_rd_counter <= host_rd_counter + 1;
		if (host_rd_counter == NUM_READS_TO_TRIGGER_OVERFLOW)
			host_force_timer_overflow <= 1;
		if (!ic_n || (host_reg_wr[17] && !(((host_reg_wr[16] == 0) && (host_reg_wr[15-:8] == 'h4)) && host_reg_wr[0]))) begin
			start_counter <= 0;
			host_rd_counter <= 0;
			host_force_timer_overflow <= 0;
		end
	end
	synchronizer force_timer_overflow_sync(
		.clk(clk),
		.in(host_force_timer_overflow),
		.out(force_timer_overflow)
	);
	initial _sv2v_0 = 0;
endmodule
module mem_simple_dual_port (
	clka,
	clkb,
	wea,
	reb,
	addra,
	addrb,
	dia,
	dob
);
	reg _sv2v_0;
	parameter DATA_WIDTH = 0;
	parameter DEPTH = 0;
	parameter OUTPUT_DELAY = 0;
	parameter [DATA_WIDTH - 1:0] DEFAULT_VALUE = 0;
	input wire clka;
	input wire clkb;
	input wire wea;
	input wire reb;
	input wire [$clog2(DEPTH) - 1:0] addra;
	input wire [$clog2(DEPTH) - 1:0] addrb;
	input wire [DATA_WIDTH - 1:0] dia;
	output reg [DATA_WIDTH - 1:0] dob;
	reg [DATA_WIDTH - 1:0] dob_p0;
	reg [DATA_WIDTH - 1:0] ram [DEPTH - 1:0];
	initial begin : sv2v_autoblock_1
		reg signed [31:0] i;
		for (i = 0; i < DEPTH; i = i + 1)
			ram[i] = DEFAULT_VALUE;
	end
	always @(posedge clka)
		if (wea)
			ram[addra] <= dia;
	always @(*) begin
		if (_sv2v_0)
			;
		dob_p0 = ram[addrb];
	end
	generate
		if (OUTPUT_DELAY != 0) begin : genblk1
			reg [DATA_WIDTH - 1:0] dob_p1 = DEFAULT_VALUE;
			always @(posedge clkb)
				if (reb)
					dob_p1 <= dob_p0;
			if (OUTPUT_DELAY == 1) begin : genblk1
				always @(*) begin
					if (_sv2v_0)
						;
					dob = dob_p1;
				end
			end
			else if (OUTPUT_DELAY == 2) begin : genblk1
				reg [DATA_WIDTH - 1:0] dob_p2 = DEFAULT_VALUE;
				always @(posedge clkb) dob_p2 <= dob_p1;
				always @(*) begin
					if (_sv2v_0)
						;
					dob = dob_p2;
				end
			end
		end
		else begin : genblk1
			always @(*) begin
				if (_sv2v_0)
					;
				dob = dob_p0;
			end
		end
	endgenerate
	initial _sv2v_0 = 0;
endmodule
module pipeline_sr (
	clk,
	in,
	out
);
	parameter DATA_WIDTH = 1;
	parameter STARTING_CYCLE = 0;
	parameter ENDING_CYCLE = 1;
	parameter POR_VALUE = 0;
	input wire clk;
	input wire [DATA_WIDTH - 1:0] in;
	function automatic [DATA_WIDTH - 1:0] sv2v_cast_DD846;
		input reg [DATA_WIDTH - 1:0] inp;
		sv2v_cast_DD846 = inp;
	endfunction
	output reg [(ENDING_CYCLE >= STARTING_CYCLE ? (((ENDING_CYCLE - STARTING_CYCLE) + 1) * DATA_WIDTH) + ((STARTING_CYCLE * DATA_WIDTH) - 1) : (((STARTING_CYCLE - ENDING_CYCLE) + 1) * DATA_WIDTH) + ((ENDING_CYCLE * DATA_WIDTH) - 1)):(ENDING_CYCLE >= STARTING_CYCLE ? STARTING_CYCLE * DATA_WIDTH : ENDING_CYCLE * DATA_WIDTH)] out = {(ENDING_CYCLE >= STARTING_CYCLE ? (ENDING_CYCLE - STARTING_CYCLE) + 1 : (STARTING_CYCLE - ENDING_CYCLE) + 1) {sv2v_cast_DD846(POR_VALUE)}};
	always @(posedge clk) begin
		out <= out << DATA_WIDTH;
		out[(ENDING_CYCLE >= STARTING_CYCLE ? STARTING_CYCLE : STARTING_CYCLE - (STARTING_CYCLE - ENDING_CYCLE)) * DATA_WIDTH+:DATA_WIDTH] <= in;
	end
endmodule
module mem_simple_dual_port_async_read (
	clka,
	wea,
	addra,
	addrb,
	dia,
	dob
);
	reg _sv2v_0;
	parameter DATA_WIDTH = 0;
	parameter DEPTH = 0;
	parameter [DATA_WIDTH - 1:0] DEFAULT_VALUE = 0;
	input wire clka;
	input wire wea;
	input wire [$clog2(DEPTH) - 1:0] addra;
	input wire [$clog2(DEPTH) - 1:0] addrb;
	input wire [DATA_WIDTH - 1:0] dia;
	output reg [DATA_WIDTH - 1:0] dob;
	reg [DATA_WIDTH - 1:0] ram [DEPTH - 1:0];
	initial begin : sv2v_autoblock_1
		reg signed [31:0] i;
		for (i = 0; i < DEPTH; i = i + 1)
			ram[i] = DEFAULT_VALUE;
	end
	always @(posedge clka)
		if (wea)
			ram[addra] <= dia;
	always @(*) begin
		if (_sv2v_0)
			;
		dob = ram[addrb];
	end
	initial _sv2v_0 = 0;
endmodule
module mem_multi_bank (
	clk,
	wea,
	reb,
	banka,
	addra,
	bankb,
	addrb,
	dia,
	dob
);
	reg _sv2v_0;
	parameter DATA_WIDTH = 0;
	parameter DEPTH = 0;
	parameter OUTPUT_DELAY = 0;
	parameter DEFAULT_VALUE = 0;
	parameter NUM_BANKS = 0;
	parameter BANK_WIDTH = $clog2(NUM_BANKS);
	input wire clk;
	input wire wea;
	input wire reb;
	input wire [BANK_WIDTH - 1:0] banka;
	input wire [$clog2(DEPTH) - 1:0] addra;
	input wire [BANK_WIDTH - 1:0] bankb;
	input wire [$clog2(DEPTH) - 1:0] addrb;
	input wire [DATA_WIDTH - 1:0] dia;
	output reg [DATA_WIDTH - 1:0] dob;
	localparam PIPELINE_DELAY = 2;
	reg [NUM_BANKS - 1:0] wea_array;
	wire [DATA_WIDTH - 1:0] dob_array [0:NUM_BANKS - 1];
	wire [(2 * BANK_WIDTH) - 1:0] bankb_p;
	pipeline_sr #(
		.DATA_WIDTH(BANK_WIDTH),
		.ENDING_CYCLE(PIPELINE_DELAY)
	) bankb_sr(
		.clk(clk),
		.in(bankb),
		.out(bankb_p)
	);
	genvar _gv_i_1;
	generate
		for (_gv_i_1 = 0; _gv_i_1 < NUM_BANKS; _gv_i_1 = _gv_i_1 + 1) begin : bankgen
			localparam i = _gv_i_1;
			always @(*) begin
				if (_sv2v_0)
					;
				wea_array[i] = wea && (banka == i);
			end
			if (OUTPUT_DELAY == 0) begin : genblk1
				mem_simple_dual_port_async_read #(
					.DATA_WIDTH(DATA_WIDTH),
					.DEPTH(DEPTH),
					.DEFAULT_VALUE(DEFAULT_VALUE)
				) mem_bank(
					.clka(clk),
					.wea(wea_array[i]),
					.addra(addra),
					.addrb(addrb),
					.dia(dia),
					.dob(dob_array[i])
				);
			end
			else begin : genblk1
				reg reb_mem;
				always @(*) begin
					if (_sv2v_0)
						;
					reb_mem = reb && (bankb == i);
				end
				mem_simple_dual_port #(
					.DATA_WIDTH(DATA_WIDTH),
					.DEPTH(DEPTH),
					.OUTPUT_DELAY(OUTPUT_DELAY),
					.DEFAULT_VALUE(DEFAULT_VALUE)
				) mem_bank(
					.clka(clk),
					.clkb(clk),
					.wea(wea_array[i]),
					.reb(reb_mem),
					.addra(addra),
					.addrb(addrb),
					.dia(dia),
					.dob(dob_array[i])
				);
			end
		end
		if (OUTPUT_DELAY == 0) begin : genblk2
			always @(*) begin
				if (_sv2v_0)
					;
				dob = dob_array[bankb];
			end
		end
		else begin : genblk2
			always @(*) begin
				if (_sv2v_0)
					;
				dob = dob_array[bankb_p[OUTPUT_DELAY * BANK_WIDTH+:BANK_WIDTH]];
			end
		end
	endgenerate
	initial _sv2v_0 = 0;
endmodule
module leds (
	clk,
	opl3_reg_wr,
	led
);
	reg _sv2v_0;
	input wire clk;
	localparam opl3_pkg_REG_FILE_DATA_WIDTH = 8;
	input wire [17:0] opl3_reg_wr;
	localparam opl3_pkg_NUM_LEDS = 4;
	output reg [3:0] led = 0;
	generate
		if (1) begin : genblk1
			genvar _gv_i_3;
			for (_gv_i_3 = 0; _gv_i_3 < opl3_pkg_NUM_LEDS; _gv_i_3 = _gv_i_3 + 1) begin : led_gen
				localparam i = _gv_i_3;
				always @(posedge clk)
					if ((opl3_reg_wr[17] && (opl3_reg_wr[16] == 0)) && (opl3_reg_wr[15-:8] == ('hb0 + i)))
						led[i] <= opl3_reg_wr[5];
			end
		end
	endgenerate
	initial _sv2v_0 = 0;
endmodule
module edge_detector (
	clk,
	clk_en,
	in,
	edge_detected
);
	reg _sv2v_0;
	parameter EDGE_LEVEL = 1;
	parameter CLK_DLY = 0;
	parameter INITIAL_INPUT_LEVEL = 0;
	input wire clk;
	input wire clk_en;
	input wire in;
	output reg edge_detected = 0;
	reg in_r0 = INITIAL_INPUT_LEVEL;
	reg in_r1 = INITIAL_INPUT_LEVEL;
	always @(posedge clk)
		if (!CLK_DLY)
			in_r0 <= in;
		else if (clk_en) begin
			in_r0 <= in;
			in_r1 <= in_r0;
		end
	always @(*) begin
		if (_sv2v_0)
			;
		if (EDGE_LEVEL) begin
			if (!CLK_DLY)
				edge_detected = in && !in_r0;
			else
				edge_detected = in_r0 && !in_r1;
		end
		else if (!CLK_DLY)
			edge_detected = !in && in_r0;
		else
			edge_detected = !in_r0 && in_r1;
	end
	initial _sv2v_0 = 0;
endmodule
module synchronizer (
	clk,
	in,
	out
);
	reg _sv2v_0;
	parameter DATA_WIDTH = 1;
	input wire clk;
	input wire [DATA_WIDTH - 1:0] in;
	output reg [DATA_WIDTH - 1:0] out;
	(* ASYNC_REG = "TRUE" *) reg [(2 * DATA_WIDTH) - 1:0] sync_regs = 0;
	always @(posedge clk) {sync_regs[DATA_WIDTH+:DATA_WIDTH], sync_regs[0+:DATA_WIDTH]} <= {sync_regs[0+:DATA_WIDTH], in};
	always @(*) begin
		if (_sv2v_0)
			;
		out = sync_regs[DATA_WIDTH+:DATA_WIDTH];
	end
	initial _sv2v_0 = 0;
endmodule
module dac_prep (
	clk,
	clk_dac,
	channel_valid,
	channel_l,
	channel_r,
	sample_valid,
	sample_l,
	sample_r
);
	reg _sv2v_0;
	input wire clk;
	input wire clk_dac;
	input wire channel_valid;
	localparam opl3_pkg_SAMPLE_WIDTH = 16;
	input wire signed [15:0] channel_l;
	input wire signed [15:0] channel_r;
	output reg sample_valid;
	localparam opl3_pkg_DAC_OUTPUT_WIDTH = 24;
	output reg signed [23:0] sample_l;
	output reg signed [23:0] sample_r;
	reg sample_valid_opl3_p1 = 0;
	reg signed [23:0] sample_opl3_l_p1 = 0;
	reg signed [23:0] sample_opl3_r_p1 = 0;
	localparam opl3_pkg_DAC_LEFT_SHIFT = ($signed(6) < 0 ? 0 : 6);
	always @(posedge clk) begin
		sample_valid_opl3_p1 <= channel_valid;
		sample_opl3_l_p1 <= channel_l <<< opl3_pkg_DAC_LEFT_SHIFT;
		sample_opl3_r_p1 <= channel_r <<< opl3_pkg_DAC_LEFT_SHIFT;
	end
	localparam opl3_pkg_INSTANTIATE_SAMPLE_SYNC_TO_DAC_CLK = 0;
	generate
		if (opl3_pkg_INSTANTIATE_SAMPLE_SYNC_TO_DAC_CLK) begin : genblk1
			reg [2:0] sample_valid_opl3_pulse_extend;
			reg sample_valid_opl3_extended_pulse = 0;
			wire sample_valid_cpu_p0;
			reg sample_valid_cpu_p1 = 0;
			always @(posedge clk) begin
				sample_valid_opl3_pulse_extend <= sample_valid_opl3_pulse_extend << 1;
				sample_valid_opl3_pulse_extend[0] <= sample_valid_opl3_p1;
				sample_valid_opl3_extended_pulse <= sample_valid_opl3_pulse_extend != 0;
			end
			synchronizer channel_valid_sync(
				.clk(clk_dac),
				.in(sample_valid_opl3_extended_pulse),
				.out(sample_valid_cpu_p0)
			);
			always @(posedge clk_dac) begin
				sample_valid_cpu_p1 <= sample_valid_cpu_p0;
				if (sample_valid_cpu_p0) begin
					sample_l <= sample_opl3_l_p1;
					sample_r <= sample_opl3_r_p1;
				end
				sample_valid <= sample_valid_cpu_p0 && !sample_valid_cpu_p1;
			end
		end
		else begin : genblk1
			always @(*) begin
				if (_sv2v_0)
					;
				sample_valid = sample_valid_opl3_p1;
				sample_l = sample_opl3_l_p1;
				sample_r = sample_opl3_r_p1;
			end
		end
	endgenerate
	initial _sv2v_0 = 0;
endmodule
module opl3 (
	clk,
	clk_host,
	clk_dac,
	ic_n,
	cs_n,
	rd_n,
	wr_n,
	address,
	din,
	dout,
	sample_valid,
	sample_l,
	sample_r,
	led,
	irq_n
);
	reg _sv2v_0;
	input wire clk;
	input wire clk_host;
	input wire clk_dac;
	input wire ic_n;
	input wire cs_n;
	input wire rd_n;
	input wire wr_n;
	input wire [1:0] address;
	localparam opl3_pkg_REG_FILE_DATA_WIDTH = 8;
	input wire [7:0] din;
	output wire [7:0] dout;
	output wire sample_valid;
	localparam opl3_pkg_DAC_OUTPUT_WIDTH = 24;
	output wire signed [23:0] sample_l;
	output wire signed [23:0] sample_r;
	localparam opl3_pkg_NUM_LEDS = 4;
	output wire [3:0] led;
	output reg irq_n;
	wire reset;
	wire sample_clk_en;
	wire [17:0] opl3_reg_wr;
	wire [7:0] status;
	wire force_timer_overflow;
	reset_sync reset_sync(
		.clk(clk),
		.arst_n(ic_n),
		.reset(reset)
	);
	host_if host_if(.*);
	localparam signed [31:0] opl3_pkg_CLK_DIV_COUNT = 256;
	clk_div #(.CLK_DIV_COUNT(opl3_pkg_CLK_DIV_COUNT)) sample_clk_gen(
		.clk_en(sample_clk_en),
		.*
	);
	channels channels(.*);
	leds leds(.*);
	localparam opl3_pkg_INSTANTIATE_TIMERS = 0;
	generate
		if (opl3_pkg_INSTANTIATE_TIMERS) begin : genblk1
			timers timers(.*);
		end
		else begin : genblk1
			always @(*) begin
				if (_sv2v_0)
					;
				irq_n = 1;
			end
		end
	endgenerate
	initial _sv2v_0 = 0;
endmodule
module pe_mem_interface_tb(
);

	reg clk;
	reg reset;
	reg pe_namespace_inst_wrt;
	reg [instLen - 1 : 0] pe_namespace_inst;
	wire [instLen - 1 : 0] pe_namespace_inst_out;
	reg pe_core_inst_stall;
	
	reg pe_namespace_data_wrt;
	reg [dataAddrLen - 1 : 0] pe_namespace_data_wrt_addr;
	reg [dataAddrLen - 1 : 0] pe_core_data_rd_addr;
	wire [dataLen - 1 : 0] pe_namespace_data_out;
	
	reg [dataLen - 1 : 0] pe_namespace_data;
	
	wire mem_weight_wrt;
	wire [weightAddrLen - 1 : 0]  mem_weight_wrt_addr;
	
	wire pe_namespace_meta_wrt;
	wire [metaAddrLen - 1 : 0] pe_namespace_meta_wrt_addr;
	

	parameter memIndexLen = 6;
	parameter instAddrLen = 6;
	parameter dataAddrLen = 5;
	parameter weightAddrLen = 5;
	parameter metaAddrLen = 2;
	parameter dataLen = 32;
	parameter instLen = 32;
	parameter logMemNamespaces = 2; //instruction, data, weight, meta

	pe_namespaces#(
		.instAddrLen(instAddrLen),
		.dataLen(dataLen),
		.instLen(instLen),	
		.dataAddrLen(dataAddrLen),
		.weightAddrLen(weightAddrLen),
		.metaAddrLen(metaAddrLen)
	)
	pe_namespace_unit(
		.clk(clk),
		.reset(reset),	
		
		.inst_wrt(pe_namespace_inst_wrt),
		.inst_in(pe_namespace_inst),
		.inst_fifo_full(pe_namespace_inst_fifo_full),
	
		.inst_stall(pe_core_inst_stall),
		.inst_eol(pe_core_inst_eol),
		
		.inst_out(pe_namespace_inst_out),
		.inst_valid(pe_namespace_inst_valid),

		.data_wrt(pe_namespace_data_wrt),
		.data_wrt_addr(pe_namespace_data_wrt_addr),
		.data_rd_addr(pe_core_data_rd_addr),
		.data_in(pe_namespace_data),
		.data_out(pe_namespace_data_out),
	
		.weight_wrt(pe_namespace_weight_wrt),
		.weight_wrt_addr(pe_namespace_weight_wrt_addr),
		.weight_rd_addr(pe_core_weight_rd_addr),
		.weight_in(pe_namespace_data),
		.weight_out(pe_namespace_weight_out),
		
		.gradient_wrt(pe_core_gradient_wrt),
		.gradient_wrt_addr(pe_core_gradient_wrt_addr),
		.gradient_rd_addr(pe_core_gradient_rd_addr),
		.gradient_in(pe_core_gradient_wrt_data),
		.gradient_out(pe_namespace_gradient_out),
	
		.meta_wrt(pe_namespace_meta_wrt),
		.meta_wrt_addr(pe_namespace_meta_wrt_addr),
		.meta_rd_addr(pe_core_meta_rd_addr),
		.meta_in(pe_namespace_data),
		.meta_out(pe_namespace_meta_out)
	);

	initial
	begin
		$dumpfile("./bin/pe_mem_interface.vcd");
		$dumpvars(0, pe_mem_interface_tb);
		$monitor("clk,pe_namespace_inst_out");
	end

	initial
	begin
		clk = 0;
		reset = 0;
		pe_core_inst_stall = 1;
		pe_namespace_inst_wrt = 0;
		pe_namespace_data_wrt = 0;
		pe_core_data_rd_addr = 1;
	#5
		reset = 1;
	#10
		reset = 0;
		pe_namespace_inst = 3;
		pe_namespace_inst_wrt = 1;
	#20
		pe_namespace_inst_wrt = 0;
		pe_core_inst_stall = 0;
	#20 
		pe_core_inst_stall = 1;
	#50
		pe_namespace_data_wrt_addr = 4;
		pe_namespace_data = 10;
		pe_namespace_data_wrt = 1;
	#20
		pe_namespace_data_wrt = 0;
	#10
		pe_core_data_rd_addr = 4;
		
		
	#100
		$finish;
	end

	always
	begin
		#5 clk = !clk;
	end
endmodule
module divider_tb(
);

	reg clk;
	reg [31:0] in1;
	reg [31:0] in2;
	wire [31:0] out;
	wire done;

	divider //#(
		//.dataLen(32)
	//)
	div (
		.in1 (in1),
	  	.in2 (in2),
	  	.out (out),
	  	.done (done)
	);

	initial
	begin
		$dumpfile("./bin/divider.vcd");
		$dumpvars(0, divider_tb);
		$monitor("in1,in2,out,done,clk");
	end

	initial
	begin
		clk = 0;
		in1 = 2;
		in2 = 2;
	#10
		in1 = 10;
		in2 = 4;
	#10
		in1 = 10;
		in2 = 3;
	#100
		$finish;
	end

	always
	begin
		#5 clk = !clk;
	end
endmodule
module pe_namespace_tb;

	parameter memIndexLen = 6;
	parameter instAddrLen = 6;
	parameter dataAddrLen = 6;
	parameter weightAddrLen = 6;
	parameter metaAddrLen = 2;
	parameter dataLen = 32;
	parameter instLen = 32;
	parameter logMemNamespaces = 2; //instruction, data, weight, meta


	reg clk;
	reg reset;
	
	reg inst_wrt;
	reg [instLen - 1: 0] 		inst;
	reg inst_stall;
	
	wire [instLen - 1: 0] 		inst_out;
	wire inst_fifo_full;
	wire inst_valid;
	
	reg data_wrt;
	reg [dataAddrLen - 1 : 0] 	data_wrt_addr;
	reg [dataAddrLen - 1 : 0] 	data_rd_addr;
	reg [dataLen - 1 : 0 ] 		data_in;
	wire [dataLen - 1 : 0 ] 		data_out;
	
	reg weight_wrt;
	reg [weightAddrLen - 1 : 0 ] 	weight_wrt_addr;
	reg [weightAddrLen - 1 : 0 ]	weight_rd_addr;
	reg [dataLen - 1 : 0 ]		weight_in;
	wire [dataLen - 1 : 0 ]		weight_out;
	
	reg gradient_wrt;
	reg [weightAddrLen - 1 : 0 ] 	gradient_wrt_addr;
	reg [weightAddrLen - 1 : 0 ] 	gradient_rd_addr;
	reg [dataLen - 1 : 0 ]		gradient_in;
	wire [dataLen - 1 : 0 ]		gradient_out;
	
	reg meta_wrt;
	reg [metaAddrLen - 1 : 0 ]	meta_wrt_addr;
	reg [metaAddrLen - 1 : 0 ]	meta_rd_addr;
	reg [dataLen - 1 : 0 ]		meta_in;
	wire [dataLen - 1 : 0 ]		meta_out;

	
	pe_namespace
	#(
		.instAddrLen(instAddrLen),
		.dataLen(dataLen),
		.instLen(instLen),	
		.dataAddrLen(dataAddrLen),
		.weightAddrLen(weightAddrLen),
		.metaAddrLen(metaAddrLen)
	)
	pe_namespace_unit(
		.clk(clk),
		.reset(reset),	
		
		.inst_wrt(inst_wrt),
		.inst_in(inst),
		.inst_fifo_full(inst_fifo_full),
	
		.inst_stall(inst_stall),
		
		.inst_out(inst_out),
		.inst_valid(inst_valid),

		.data_wrt(data_wrt),
		.data_wrt_addr(data_wrt_addr),
		.data_rd_addr(data_rd_addr),
		.data_in(data_in),
		.data_out(data_out),
	
		.weight_wrt(weight_wrt),
		.weight_wrt_addr(weight_wrt_addr),
		.weight_rd_addr(weight_rd_addr),
		.weight_in(weight_in),
		.weight_out(weight_out),
		
		.gradient_wrt(gradient_wrt),
		.gradient_wrt_addr(gradient_wrt_addr),
		.gradient_rd_addr(gradient_rd_addr),
		.gradient_in(gradient_in),
		.gradient_out(gradient_out),
	
		.meta_wrt(meta_wrt),
		.meta_wrt_addr(meta_wrt_addr),
		.meta_rd_addr(meta_rd_addr),
		.meta_in(meta_in),
		.meta_out(meta_out)
	);

	initial
	begin
		$dumpfile("hw-imp/bin/waveform/pe_namespace_tb.vcd");
		$dumpvars(0, pe_namespace_tb);
		$monitor(clk, inst_out);
	end

	initial
	begin
		clk = 1;
		reset = 0;
		inst_stall = 0;
		inst_wrt = 0;
		data_wrt = 0;
	#5
		reset = 1;
	#10
		reset = 0;
		inst = 3;
		inst_wrt = 1;
	#10
		reset = 0;
		inst = 321;
		inst_wrt = 1;
		inst_stall = 0;
	#10 
		reset = 0;
		inst = 723;
		inst_wrt = 1;
		inst_stall = 1;
		
	#10
		inst_stall = 0;
		inst_wrt = 0;
		
	#10
		reset = 1;
	
	#10
		reset = 0;
		data_wrt_addr = 6;
		data_in = 10;
		data_wrt = 1;
	#10
		data_wrt = 0;
		data_rd_addr = 6;
		
	#10	
		weight_wrt_addr = 21;
		weight_in = 212;
		weight_wrt = 1;
		
	#10	
		weight_rd_addr = 21;
		weight_wrt = 0;
		
	#10	
		gradient_wrt_addr = 30;
		gradient_in = 3222;
		gradient_wrt = 1;
		
	#10	
		gradient_rd_addr = 30;
		gradient_wrt = 0;
		
	#10	
		meta_wrt_addr = 1;
		meta_in = 13;
		meta_wrt = 1;
		
	#10	
		meta_rd_addr = 1;
		meta_wrt = 0;
		
	#100
		$finish;
	end

	always #1 clk = !clk;
	
endmodule
module addSub_tb(
);

	reg clk;
    reg [8:0] in1;
    reg [8:0] in2;
    wire [8:0] outAdd;
    wire [8:0] outSub;
	wire overflowA, overflowS;		
	

  addSub #(
		//input parameters
		.LEN(9)
	)
	as0 (
	//input output ports
        .in1 (in1),
        .in2 (in2),
        .outAdd (outAdd),
        .outSub (outSub),
        .overflowA (overflowA),
        .overflowS (overflowS)
    );


	initial
	begin
		$dumpfile("./bin/addSub.vcd");
		$dumpvars(0,addSub_tb);
		$monitor("in1,in2,outAdd,outSub,overflowA,overflowS,clk");
	end

	initial 
	begin
		clk = 0;
		in1 = 100;
		in2 = 88;
		
	#10
		in1 = 3297;
		in2 = 323;

	#10
		in1 = 2121;
		in2 = -231;
		
	
	#100 
		$finish;
	end

	always
	begin
		#10 clk = ~clk;
	end

endmodule
module buffer_tb(
);

	reg clk;
	reg reset;
	reg [7:0] rd_addr1;
	reg [7:0] rd_addr2;
	reg [7:0] wr_addr;
	wire [31:0] rd_data1;
	wire [31:0] rd_data2;
	reg [31:0] wr_data;
	reg wr_en;

	buffer buff (
		.clk (clk),
		.reset (reset),
		
		.wr_en (wr_en),
		.wr_addr (wr_addr),
		.wr_data (wr_data),
		
		.rd_addr1 (rd_addr1),
		.rd_data1 (rd_data1),
		
		.rd_addr2 (rd_addr2),
		.rd_data2 (rd_data2)
		
	);

	initial
	begin
		$dumpfile("./bin/buffer.vcd");
		$dumpvars(0, buffer_tb);
		$monitor("rd_addr1,rd_addr2,rd_data1,rd_data2,wr_en,wr_addr,wr_data,clk,reset");
	end

	initial
	begin
		clk = 0;
		reset = 0;
		wr_en = 0;
	#5
		reset = 1;
	#10
		reset = 0;
		wr_addr = 0;
		wr_data = 1;
	#10
		wr_en = 1;
		wr_addr = 1;
		wr_data = 1;
	#10
		wr_en = 0;
		rd_addr1 = 0;
		rd_addr2 = 1;
	#100
		$finish;
	end

	always
	begin
		#5 clk = !clk;
	end
endmodule
module comp_tb(
);

	reg clk;
    reg [8:0] in1;
    reg [8:0] in2;
	wire out;

  comp #(
	//input parameters
		.LEN(9)
	)
	c0 (
	//input output ports
        .in1 (in1),
        .in2 (in2),
        .out (out)
    );


	initial
	begin
		$dumpfile("./bin/comparator.vcd");
		$dumpvars(0,comp_tb);
		$monitor("in1,in2,outAdd,outSub,overflowA,overflowS,clk");
	end

	initial 
	begin
		clk = 0;
		in1 = -100;
		in2 = 88;
		
	#10
		in1 = 3297;
		in2 = 323;

	#10
		in1 = 121;
		in2 = 231;
		
	
	#100 
		$finish;
	end

	always
	begin
		#10 clk = ~clk;
	end

endmodule
module mac_tb(
);

	reg clk;
  reg [8:0] in1;
  reg [8:0] in2;
	reg [8:0] preResult;
  wire [17:0] out;
  wire overflow;
	//wire overflowA, overflowS;		
	

  mac #(
	//input parameters
		.LEN(9)
	)
	m0 (
	//input output ports
		.in1 (in1),
  	.in2 (in2),
		.preResult (preResult),
  	.out (out),
  	.overflow (overflow)
  );


	initial
	begin
		$dumpfile("./bin/mac.vcd");
		$dumpvars(0,mac_tb);
		$monitor("in1,in2,preResult,out,overflow,clk");
	end

	initial 
	begin
		clk = 0;
		in1 = 100;
		in2 = 88;
		preResult = 0;
		
	#10
		in1 = 32;
		in2 = -32;
		preResult = 10;

	#10
		in1 = -21;
		in2 = -231;
		preResult = -11;
		
	
	#100 
		$finish;
	end

	always
	begin
		#10 clk = ~clk;
	end

endmodule
module sigmoid_tb(
);

	reg clk;
	reg [31:0] in;
	wire [31:0] out;

	sigmoid //#(
		//.dataLen(32);
	//)
	sig (
		.in (in),
	  	.out (out)
	);

	initial
	begin
		$dumpfile("./bin/sigmoid.vcd");
		$dumpvars(0, sigmoid_tb);
		$monitor("in,out,clk");
	end

	initial
	begin
		clk = 0;
		in = -1;
	#10
		in = 0;
	#10
		in = 1 << 15;
	#10
		in = 3 << 14;
	#10
		in = 1.9;
	#100
		$finish;
	end

	always
	begin
		#5 clk = !clk;
	end
endmodule
module alu_tb(
);

	reg clk;
  	reg [15:0] in1;
  	reg [15:0] in2;
	reg [15:0] in3;
	reg [1:0] sel;
  	wire [15:0] out;
  	wire overflow;
	//wire overflowA, overflowS;		

  mac #(
	//input parameters
		.LEN(16),
		.SELECT_LEN(2)
	)
	alu0 (
	//input output ports
		.in1 (in1),
  		.in2 (in2),
		.in3 (in3),
		.select (sel),
  	.out (out)
  );


	initial
	begin
		$dumpfile("./bin/alu.vcd");
		$dumpvars(0,alu_tb);
		$monitor("in1,in2,in3,out,sel,clk");
	end

	initial 
	begin
		clk = 0;
		in1 = 100;
		in2 = 88;
		in3 = 0;
		sel = 0;
		
	#10
		in1 = 32;
		in2 = -32;
		in3 = 10;
		sel = 2;

	#10
		in1 = -21;
		in2 = -121;
		in3 = -11;
		sel = 3;
	

	#10

		in1 = 100;
		in2 = 0;
		sel = 1;
	#100 
		$finish;
	end

	always
	begin
		#10 clk = ~clk;
	end

endmodule
module sqrt_tb(
);

	reg clk;
	reg [31:0] in;
	wire [15:0] out;
	wire [16:0] rout;
	wire done;

	sqrt //#(
		//.dataLen(32);
	//)
	sqrt0 (
		.in (in),
	  	.out (out),
	  	.rout (rout),
	  	.done (done)
	);

	initial
	begin
		$dumpfile("./bin/sqrt_tb.vcd");
		$dumpvars(0, sqrt_tb);
		$monitor("in,out,rout,done,clk");
	end

	initial
	begin
		clk = 0;
		in = 140;
	#50
		in = 2 << 10;	// 5 bits fraction
	#50
		in = 9 << 10;	// 5 bits fraction
	#200
		$finish;
	end

	always
	begin
		#1 clk = !clk;
	end
endmodule
module interim_buffer #(
    parameter addrLen = 6,
	parameter dataLen = 32,
	parameter memSize = 1 << addrLen
	)(
	input clk,
	input rstn,
	input wrt_en,
	input stall,
	input interim_invalid,
	
	input [addrLen-1:0] wrt_addr,
	input [dataLen-1:0] wrt_data,
    input rd_en,
	input [addrLen-1:0] rd_addr,
	//input [addrLen-1:0] rd_addr1,

	output reg [dataLen-1:0] data_out,
	output reg data_out_v
	//output reg [dataLen-1:0] data_out1,
	//output reg data_out1_v
);

reg [ dataLen - 1 : 0 ] mem [ 0 : memSize - 1 ];
reg [ memSize - 1 : 0 ] mem_en;
 

always @(posedge clk or negedge rstn) begin
	if(~rstn) begin
		mem_en <= {memSize{1'b0}};
	end
	else if(wrt_en)
		mem_en[wrt_addr] <= 1'b1;
end

always @(posedge clk or negedge rstn) begin
	if(~rstn) begin
		data_out_v <= 1'b0;
		//data_out1_v <= 1'b0;
	end
	else if(rd_en &&(~stall) ) begin
		data_out_v <= wrt_en && (wrt_addr == rd_addr) ? 1'b1 : mem_en[rd_addr];
		//data_out1_v <= wrt_en && (wrt_addr == rd_addr1) ? 1'b1 : mem_en[rd_addr1];
	end
	else if(~rd_en) begin
		data_out_v <= 1'b0;
		//data_out1_v <= 1'b0;
	end
end

always @(posedge clk) begin
	if(wrt_en)
		mem[wrt_addr] <= wrt_data;
end

always @(posedge clk) begin
	if(rd_en && (~stall) ) begin
		data_out <= wrt_en && (wrt_addr == rd_addr) ? wrt_data : mem[rd_addr];
		//data_out1 <= wrt_en && (wrt_addr == rd_addr1) ? wrt_data : mem[rd_addr1];
	end
end

endmodule