data/full_repos/permissive/450072296/verilog/rtl/audiodac_dsmod.v
data/verilator_xmls/7d3d871e-3d59-427e-93af-a4101f106a09.xml
module audiodac_dsmod(
	input 		[15:0]	audio_i,
	output wire		audio_rd_o,
	input			rst_n_i,
	input			clk_i,
	input			mode_i,
	input 		[3:0]	volume_i,
	input		[1:0]	osr_i,
	output reg		ds_o,
	output wire		ds_n_o
);

	reg 		[15:0]	accu1;
	reg		[15:0]	accu2;
	reg		[1:0]	accu3;
	wire 		[15:0]	audio_scaled;
	reg		[7:0]	fetch_ctr;

	reg		[1:0]	mod2_ctr;
	reg		[1:0]	mod2_out;

	localparam	[7:0]	CTR_OSR32  	=  8'd31;
	localparam	[7:0]	CTR_OSR64  	=  8'd63;
	localparam	[7:0]	CTR_OSR128 	=  8'd127;
	localparam	[7:0]	CTR_OSR256 	=  8'd255;
	localparam	[1:0]	OSR32  		= 2'd0;
	localparam	[1:0]	OSR64  		= 2'd1;
	localparam	[1:0]	OSR128 		= 2'd2;
	localparam	[1:0]	OSR256 		= 2'd3;
	localparam		ORD1 		= 1'd0;
	localparam		ORD2 		= 1'd1;


  	assign ds_n_o = ~ds_o;


	assign audio_scaled = (volume_i === 4'd0) ? 16'b0 : audio_i >> (4'd15 - volume_i);




	assign audio_rd_o = (fetch_ctr === 8'd0);

  	always @(posedge clk_i) begin
		if (!rst_n_i) begin

			accu1 <= 16'b0;
			accu2 <= 16'b0;
			accu3 <=  2'b0;
			ds_o <= 1'b0;
			fetch_ctr <= 8'b0;
			mod2_ctr <= 2'b0;
			mod2_out <= 2'b0;
		end else begin


			if (fetch_ctr === 8'd0) begin


				case (osr_i)
					OSR32:		fetch_ctr <= CTR_OSR32;
					OSR64:		fetch_ctr <= CTR_OSR64;
					OSR128:		fetch_ctr <= CTR_OSR128;
					OSR256:		fetch_ctr <= CTR_OSR256;
					default:	fetch_ctr <= 8'bx;
				endcase
			end else

				fetch_ctr <= fetch_ctr - 1'b1;
		
			if (mode_i === ORD1) begin



				{ds_o,accu1} <= audio_scaled + accu1;
			
			end else if (mode_i === ORD2) begin




				if (mod2_ctr === 2'b0) begin


					{mod2_out,accu1} <= {2'b00,audio_scaled} 
								+ {1'b0,accu1,1'b0} 
								+ 18'h10000 
								- {2'b0,accu2};
					accu2 <= accu1;
				end


				mod2_ctr <= mod2_ctr + 1'b1;
				


				{ds_o,accu3} <= mod2_out + accu3;
			end
		end
	end
endmodule
module audiodac_dsmod(
	input 		[15:0]	audio_i,
	output wire		audio_rd_o,
	input			rst_n_i,
	input			clk_i,
	input			mode_i,
	input 		[3:0]	volume_i,
	input		[1:0]	osr_i,
	output reg		ds_o,
	output wire		ds_n_o
);


	reg 		[15:0]	accu1;
	reg		[15:0]	accu2;
	reg		[1:0]	accu3;
	wire 		[15:0]	audio_scaled;
	reg		[7:0]	fetch_ctr;

	reg		[1:0]	mod2_ctr;
	reg		[1:0]	mod2_out;

	localparam	[7:0]	CTR_OSR32  	=  8'd31;
	localparam	[7:0]	CTR_OSR64  	=  8'd63;
	localparam	[7:0]	CTR_OSR128 	=  8'd127;
	localparam	[7:0]	CTR_OSR256 	=  8'd255;
	localparam	[1:0]	OSR32  		= 2'd0;
	localparam	[1:0]	OSR64  		= 2'd1;
	localparam	[1:0]	OSR128 		= 2'd2;
	localparam	[1:0]	OSR256 		= 2'd3;
	localparam		ORD1 		= 1'd0;
	localparam		ORD2 		= 1'd1;


  	assign ds_n_o = ~ds_o;


	assign audio_scaled = (volume_i === 4'd0) ? 16'b0 : audio_i >> (4'd15 - volume_i);




	assign audio_rd_o = (fetch_ctr === 8'd0);

  	always @(posedge clk_i) begin
		if (!rst_n_i) begin

			accu1 <= 16'b0;
			accu2 <= 16'b0;
			accu3 <=  2'b0;
			ds_o <= 1'b0;
			fetch_ctr <= 8'b0;
			mod2_ctr <= 2'b0;
			mod2_out <= 2'b0;
		end else begin


			if (fetch_ctr === 8'd0) begin


				case (osr_i)
					OSR32:		fetch_ctr <= CTR_OSR32;
					OSR64:		fetch_ctr <= CTR_OSR64;
					OSR128:		fetch_ctr <= CTR_OSR128;
					OSR256:		fetch_ctr <= CTR_OSR256;
					default:	fetch_ctr <= 8'bx;
				endcase
			end else

				fetch_ctr <= fetch_ctr - 1'b1;
		
			if (mode_i === ORD1) begin



				{ds_o,accu1} <= audio_scaled + accu1;
			
			end else if (mode_i === ORD2) begin




				if (mod2_ctr === 2'b0) begin


					{mod2_out,accu1} <= {2'b00,audio_scaled} 
								+ {1'b0,accu1,1'b0} 
								+ 18'h10000 
								- {2'b0,accu2};
					accu2 <= accu1;
				end


				mod2_ctr <= mod2_ctr + 1'b1;
				


				{ds_o,accu3} <= mod2_out + accu3;
			end
		end
	end
endmodule