dakies/OSS_Verilog huggingface dataset:
module top(input wire clk_i, 
	input wire nrst_i, 
	input wire fclk_i,
	input wire data_i,
	output wire pclk_o,
	output wire [9:0]q_o);

    IDES10 ides(
        .D(data_i),
		.FCLK(fclk_i),
		.PCLK(pclk_o),
		.CALIB(1'b0),
		.RESET(!nrst_i),
        .Q0(q_o[0]),
        .Q1(q_o[1]),
        .Q2(q_o[2]),
        .Q3(q_o[3]),
        .Q4(q_o[4]),
        .Q5(q_o[5]),
        .Q6(q_o[6]),
        .Q7(q_o[7]),
        .Q8(q_o[8]),
        .Q9(q_o[9])
    );
	defparam ides.GSREN="false";
	defparam ides.LSREN="true";

	// div by 5
	reg [2:0] count;
	wire clkA;
	reg clkB;
	always @(posedge fclk_i) begin
		if (!nrst_i) begin
			count <= 0;
		end else begin 
			if (count == 3'd4) begin
				count <= 0;
			end else begin
				count <= count+1;
			end
		end 
	end
	assign clkA = count[1];

	always@(negedge fclk_i) begin
		clkB <= clkA;
	end
	assign pclk_o = clkA | clkB;
endmodule
module top(input wire clk_i, 
	input wire nrst_i,
	output wire [(2 * `CH) - 1:0]q_o,
	output wire pclk_o,
    output wire fclk_o);

	genvar i;
	generate
	  for (i = 0; i < `CH; i = i + 1) begin
		OVIDEO os(
			.D0(1'b1),
			.D1(1'b0),
			.D2(1'b1),
			.D3(1'b0),
			.D4(1'b1),
			.D5(1'b0),
			.D6(1'b1),
			.FCLK(fclk_w),
			.PCLK(pclk_w),
			.RESET(1'b0),
			.Q(dso_w)
		);
		wire dso_w;
		defparam os.GSREN = "false";
		defparam os.LSREN = "true";
		TLVDS_OBUF dso(
			.O(q_o[2 * i]),
			.OB(q_o[1 + 2 * i]),
			.I(dso_w)
		);
	  end
	endgenerate

	wire clk_w;
	wire pclk_w;
	wire fclk_w;
	assign fclk_w = tick_w;

	assign pclk_o = pclk_w;
	assign fclk_o = fclk_w;

	reg [24:0] ctr_q;
	wire [24:0] ctr_d;
	wire tick_w;

	// Sequential code (flip-flop)
	always @(posedge clk_i)
		ctr_q <= ctr_d;

	// Combinational code (boolean logic)
	assign ctr_d = ctr_q + 1'b1;
	//assign i_tick = |ctr_q[24:23];
	assign tick_w = ctr_q[10];


    reg [1:0]pclk_r;
    always @(posedge tick_w) begin
        pclk_r <= pclk_r + 2'b01;
    end
    assign pclk_w = pclk_r[1];
endmodule
module top(input wire clk_i, 
	input wire nrst_i,
	output wire [`CH - 1:0]q_o,
	output wire pclk_o,
    output wire fclk_o);

	genvar i;
	generate
	  for (i = 0; i < `CH; i = i + 1) begin
		OSER8 os8(
			.D0(1'b0),
			.D1(1'b1),
			.D2(1'b0),
			.D3(1'b1),
			.D4(1'b0),
			.D5(1'b1),
			.D6(1'b0),
			.D7(1'b1),
			.TX0(1'b1),
			.TX1(1'b1),
			.TX2(1'b1),
			.TX3(1'b1),
			.FCLK(fclk_w),
			.PCLK(pclk_r[1]),
			.RESET(1'b0),
			.Q0(q_o[i])
		);
		defparam os8.GSREN = "false";
		defparam os8.LSREN = "true";
		defparam os8.TXCLK_POL = 0;
		defparam os8.HWL = "false";
	  end
	endgenerate

    reg [1:0]pclk_r;
    wire fclk_w;

    always @(posedge fclk_w) begin
		if (!nrst_i) begin
			pclk_r <= 2'b00;
		end else begin
	        pclk_r <= pclk_r + 2'b01;
		end
    end
    assign pclk_o = pclk_r[1];
	assign fclk_o = fclk_w;
	
	// slow 
	reg [24:0] ctr_q;
	wire [24:0] ctr_d;
	wire tick_w;

	// Sequential code (flip-flop)
	always @(posedge clk_i)
		ctr_q <= ctr_d;

	// Combinational code (boolean logic)
	assign ctr_d = ctr_q + 1'b1;
	assign tick_w = ctr_q[24];

	assign fclk_w = tick_w;
endmodule
module top(input wire clk_i,
	input wire key_i,
	input wire nrst_i,
	output wire [4 * `CH - 1:0]q_o,
	output wire pclk_o,
    output wire fclk_o);

	genvar i;
	generate
	  for (i = 0; i < `CH; i = i + 1) begin
		OSER16 oser(
			.D0(1'b0),
			.D1(1'b1),
			.D2(1'b0),
			.D3(1'b1),
			.D4(1'b0),
			.D5(1'b1),
			.D6(1'b0),
			.D7(1'b1),
			.D8(1'b0),
			.D9(1'b1),
			.D10(1'b0),
			.D11(1'b1),
			.D12(1'b0),
			.D13(1'b1),
			.D14(1'b0),
			.D15(1'b1),
			.FCLK(fclk_w),
			.PCLK(pclk_o),
			.RESET(1'b0),
			.Q(q_o[i * 4])
		);
		defparam oser.GSREN = "false";
		defparam oser.LSREN = "true";
	  end
	endgenerate

    reg [2:0]pclk_r;
    wire fclk_w;

    always @(posedge fclk_w) begin
		if (!nrst_i) begin
			pclk_r <= 3'b00;
		end else begin
			pclk_r <= pclk_r + 3'b01;
		end
    end
    assign pclk_o = pclk_r[2];
	assign fclk_o = fclk_w;

	// slow
	reg [24:0] ctr_q;
	wire [24:0] ctr_d;
	wire tick_w;

	// Sequential code (flip-flop)
	always @(posedge clk_i)
		ctr_q <= ctr_d;

	// Combinational code (boolean logic)
	assign ctr_d = ctr_q + 1'b1;
	assign tick_w = ctr_q[24];

	assign fclk_w = tick_w;
endmodule
module top(input wire clk_i, 
	input wire nrst_i,
	output wire [`CH - 1:0]q_o,
	output wire pclk_o,
    output wire fclk_o);

	genvar i;
	generate
	  for (i = 0; i < `CH; i = i + 1) begin
		OSER10 os(
			.D0(1'b0),
			.D1(1'b1),
			.D2(1'b0),
			.D3(1'b1),
			.D4(1'b0),
			.D5(1'b1),
			.D6(1'b0),
			.D7(1'b1),
			.D8(1'b0),
			.D9(1'b1),
			.FCLK(fclk_w),
			.PCLK(pclk_w),
			.RESET(1'b0),
			.Q(q_o[i])
		);
		defparam os.GSREN = "false";
		defparam os.LSREN = "true";
	  end
	endgenerate

	wire clk_w;
	wire pclk_w;
	wire fclk_w;

	assign pclk_o = pclk_w;
	assign fclk_o = fclk_w;

	reg [2:0] count;
	wire clkA;
	reg clkB;
	always @(posedge fclk_w) begin
		if (!nrst_i) begin
			count <= 0;
		end else begin 
			if (count == 3'd4) begin
				count <= 0;
			end else begin
				count <= count+1;
			end
		end 
	end
	assign clkA = count[1];

	always@(negedge fclk_w) begin
		clkB <= clkA;
	end
	assign pclk_w = clkA | clkB;

	// slow 
	reg [24:0] ctr_q;
	wire [24:0] ctr_d;
	wire tick_w;

	// Sequential code (flip-flop)
	always @(posedge clk_i)
		ctr_q <= ctr_d;

	// Combinational code (boolean logic)
	assign ctr_d = ctr_q + 1'b1;
	assign tick_w = ctr_q[24];

	assign fclk_w = tick_w;
endmodule
module top(input wire clk_i,
	input wire nrst_i,
	input wire fclk_i,
	input wire data_i,
	output wire pclk_o,
	output wire [9:0]q_o);

	wire [5:0]dummy_w;

    IDES16 ides(
        .D(data_i),
		.FCLK(fclk_i),
		.PCLK(pclk_o),
		.CALIB(1'b0),
		.RESET(!nrst_i),
//`define SECOND_HALF
`ifndef SECOND_HALF
        .Q0(q_o[0]),
        .Q1(q_o[1]),
        .Q2(q_o[2]),
        .Q3(q_o[3]),
        .Q4(q_o[4]),
        .Q5(q_o[5]),
        .Q6(q_o[6]),
        .Q7(q_o[7]),
        .Q8(q_o[8]),
        .Q9(q_o[9]),
        .Q10(dummy_w[0]),
        .Q11(dummy_w[1]),
        .Q12(dummy_w[2]),
        .Q13(dummy_w[3]),
        .Q14(dummy_w[4]),
        .Q15(dummy_w[5])
`else
        .Q0(dummy_w[0]),
        .Q1(dummy_w[1]),
        .Q2(dummy_w[2]),
        .Q3(dummy_w[3]),
        .Q4(dummy_w[4]),
        .Q5(dummy_w[5]),
        .Q6(q_o[6]),
        .Q7(q_o[7]),
        .Q8(q_o[8]),
        .Q9(q_o[9]),
        .Q10(q_o[0]),
        .Q11(q_o[1]),
        .Q12(q_o[2]),
        .Q13(q_o[3]),
        .Q14(q_o[4]),
        .Q15(q_o[5])
`endif
    );
	defparam ides.GSREN="false";
	defparam ides.LSREN="true";

    reg [2:0]pclk_r;
    wire fclk_w;

    always @(posedge fclk_w) begin
		if (!nrst_i) begin
			pclk_r <= 3'b00;
		end else begin
	        pclk_r <= pclk_r + 3'b01;
		end
    end
    assign pclk_o = pclk_r[2];
	assign fclk_w = fclk_i;
endmodule
module top(input wire clk_i, 
	output wire [`CH - 1:0]q_o,
	output wire pclk_o,
    output wire fclk_o,
    input wire nrst_i);

	genvar i;
	generate
	  for (i = 0; i < `CH; i = i + 1) begin
		OVIDEO os(
			.D0(1'b1),
			.D1(1'b0),
			.D2(1'b1),
			.D3(1'b0),
			.D4(1'b1),
			.D5(1'b0),
			.D6(1'b1),
			.FCLK(fclk_w),
			.PCLK(pclk_w),
			.RESET(1'b0),
			.Q(q_o[i])
		);
		defparam os.GSREN = "false";
		defparam os.LSREN = "true";
	  end
	endgenerate

    wire pclk_w;
    wire fclk_w;

    assign pclk_o = pclk_w;
	assign fclk_o = fclk_w;
    
	// div by 3.5
	reg [6:0]cnt_r;
	reg ps0_r;
	reg ps3_r;
	reg ps4_r;
	always @(posedge fclk_w) begin
		if (!nrst_i) begin
			cnt_r[6:0] <= 7'b000_0001;
		end else begin
			cnt_r[6:0] <= {cnt_r[5:0], cnt_r[6]};
		end
	end

	always @(negedge fclk_w) begin
		if (!nrst_i) begin
			ps0_r <= 1'b0;
			ps3_r <= 1'b0;
			ps4_r <= 1'b0;
		end else begin
			ps0_r <= cnt_r[0];
			ps3_r <= cnt_r[3];
			ps4_r <= cnt_r[4];
		end
	end
    assign pclk_w = (ps0_r | cnt_r[0] | cnt_r[1]) | (ps3_r | ps4_r | cnt_r[4]);
	
	// slow 
	reg [24:0] ctr_q;
	wire [24:0] ctr_d;
	wire tick_w;

	// Sequential code (flip-flop)
	always @(posedge clk_i)
		ctr_q <= ctr_d;

	// Combinational code (boolean logic)
	assign ctr_d = ctr_q + 1'b1;
	assign tick_w = ctr_q[24];

	assign fclk_w = tick_w;

endmodule
module top(input wire clk_i, 
	input wire nrst_i, 
	input wire fclk_i,
	input wire data_i,
	output wire [7:0]q_o);

	assign q_o[2] = !nrst_i;
    IDDR id(
        .D(data_i),
		.CLK(fclk_i),
        .Q0(q_o[0]),
        .Q1(q_o[1])
    );
	defparam id.Q0_INIT=1'b0;
	defparam id.Q1_INIT=1'b0;

	// dummy DFF
	assign q_o[4] = dummy_r;
	reg dummy_r;
	always @(posedge fclk_i) begin
		if (!nrst_i) begin
			dummy_r <= 0;
		end else begin
			dummy_r <= !dummy_r;
		end
	end
endmodule
module top(input wire clk_i, 
	input wire nrst_i,
	output wire [(2 * `CH) - 1:0]q_o,
	output wire pclk_o,
    output wire fclk_o);

	genvar i;
	generate
	  for (i = 0; i < `CH; i = i + 1) begin
		OSER10 os(
			.D0(1'b1),
			.D1(1'b0),
			.D2(1'b1),
			.D3(1'b0),
			.D4(1'b1),
			.D5(1'b0),
			.D6(1'b1),
			.D7(1'b0),
			.D8(1'b1),
			.D9(1'b0),
			.FCLK(fclk_w),
			.PCLK(pclk_w),
			.RESET(1'b0),
			.Q(dso_w)
		);
		wire dso_w;
		defparam os.GSREN = "false";
		defparam os.LSREN = "true";
		TLVDS_OBUF dso(
			.O(q_o[2 * i]),
			.OB(q_o[1 + 2 * i]),
			.I(dso_w)
		);
	  end
	endgenerate

	wire clk_w;
	wire pclk_w;
	wire fclk_w;
	assign fclk_w = tick_w;

	assign pclk_o = pclk_w;
	assign fclk_o = fclk_w;

	reg [24:0] ctr_q;
	wire [24:0] ctr_d;
	wire tick_w;

	// Sequential code (flip-flop)
	always @(posedge clk_i)
		ctr_q <= ctr_d;

	// Combinational code (boolean logic)
	assign ctr_d = ctr_q + 1'b1;
	//assign i_tick = |ctr_q[24:23];
	assign tick_w = ctr_q[10];


    reg [1:0]pclk_r;
    always @(posedge tick_w) begin
        pclk_r <= pclk_r + 2'b01;
    end
    assign pclk_w = pclk_r[1];
endmodule
module top(input wire clk_i, 
	input wire nrst_i, 
	input wire fclk_i,
	input wire data_i,
	output wire pclk_o,
	output wire [7:0]q_o);

    IDES4 ides(
        .D(data_i),
		.FCLK(fclk_i),
		.PCLK(pclk_o),
		.CALIB(1'b0),
		.RESET(!nrst_i),
        .Q0(q_o[0]),
        .Q1(q_o[1]),
        .Q2(q_o[2]),
        .Q3(q_o[3])
    );
	defparam ides.GSREN="false";
	defparam ides.LSREN="true";

    reg pclk_r;
    always @(posedge fclk_i) begin
        pclk_r <= !pclk_r;
    end
	assign pclk_o = pclk_r;

endmodule
module top(input wire clk_i, 
	output wire [`CH - 1:0]q_o,
	output wire pclk_o,
    output wire fclk_o);

	genvar i;
	generate
	  for (i = 0; i < `CH; i = i + 1) begin
		OSER4 os4(
			.D0(1'b0),
			.D1(1'b1),
			.D2(1'b0),
			.D3(1'b1),
			.TX0(1'b0),
			.TX1(1'b0),
			.FCLK(fclk_w),
			.PCLK(pclk_r),
			.RESET(1'b0),
			.Q0(q_o[i])
		);
		defparam os4.GSREN = "false";
		defparam os4.LSREN = "true";
		defparam os4.TXCLK_POL = 0;
		defparam os4.HWL = "false";
	  end
	endgenerate

    reg pclk_r;
    wire fclk_w;

    always @(posedge fclk_w) begin
        pclk_r <= !pclk_r;
    end
    assign pclk_o = pclk_r;
	assign fclk_o = fclk_w;
    
	// slow 
	reg [24:0] ctr_q;
	wire [24:0] ctr_d;
	wire tick_w;

	// Sequential code (flip-flop)
	always @(posedge clk_i)
		ctr_q <= ctr_d;

	// Combinational code (boolean logic)
	assign ctr_d = ctr_q + 1'b1;
	assign tick_w = ctr_q[24];

	assign fclk_w = tick_w;
endmodule
module top(input wire clk_i, 
	input wire nrst_i, 
	input wire fclk_i,
	input wire data_i,
	output wire pclk_o,
	output wire [7:0]q_o);

    IVIDEO ides(
        .D(data_i),
		.FCLK(fclk_i),
		.PCLK(pclk_o),
		.CALIB(1'b0),
		.RESET(!nrst_i),
        .Q0(q_o[0]),
        .Q1(q_o[1]),
        .Q2(q_o[2]),
        .Q3(q_o[3]),
        .Q4(q_o[4]),
        .Q5(q_o[5]),
        .Q6(q_o[6])
    );
	defparam ides.GSREN="false";
	defparam ides.LSREN="true";

	// div by 3.5
	reg [6:0]cnt_r;
	reg ps0_r;
	reg ps3_r;
	reg ps4_r;
	always @(posedge fclk_i) begin
		if (!nrst_i) begin
			cnt_r[6:0] <= 7'b000_0001;
		end else begin
			cnt_r[6:0] <= {cnt_r[5:0], cnt_r[6]};
		end
	end

	always @(negedge fclk_i) begin
		if (!nrst_i) begin
			ps0_r <= 1'b0;
			ps3_r <= 1'b0;
			ps4_r <= 1'b0;
		end else begin
			ps0_r <= cnt_r[0];
			ps3_r <= cnt_r[3];
			ps4_r <= cnt_r[4];
		end
	end
    assign pclk_o = (ps0_r | cnt_r[0] | cnt_r[1]) | (ps3_r | ps4_r | cnt_r[4]);
endmodule
module top(input wire clk_i, 
	input wire nrst_i,
	output wire [(2 * `CH) - 1:0]q_o,
	output wire pclk_o,
    output wire fclk_o);

	genvar i;
	generate
	  for (i = 0; i < `CH; i = i + 1) begin
		OSER8 os(
			.D0(1'b1),
			.D1(1'b0),
			.D2(1'b1),
			.D3(1'b0),
			.D4(1'b1),
			.D5(1'b0),
			.D6(1'b1),
			.D7(1'b0),
			.FCLK(fclk_w),
			.PCLK(pclk_w),
			.RESET(1'b0),
			.TX0(1'b0),
			.TX1(1'b0),
			.TX2(1'b0),
			.TX3(1'b0),
			.Q0(dso_w)
		);
		wire dso_w;
		defparam os.GSREN = "false";
		defparam os.LSREN = "true";
		TLVDS_OBUF dso(
			.O(q_o[2 * i]),
			.OB(q_o[1 + 2 * i]),
			.I(dso_w)
		);
	  end
	endgenerate

	wire clk_w;
	wire pclk_w;
	wire fclk_w;
	assign fclk_w = tick_w;

	assign pclk_o = pclk_w;
	assign fclk_o = fclk_w;

	reg [24:0] ctr_q;
	wire [24:0] ctr_d;
	wire tick_w;

	// Sequential code (flip-flop)
	always @(posedge clk_i)
		ctr_q <= ctr_d;

	// Combinational code (boolean logic)
	assign ctr_d = ctr_q + 1'b1;
	assign tick_w = |ctr_q[24:23];
	//assign tick_w = ctr_q[10];


    reg [1:0]pclk_r;
    always @(posedge tick_w) begin
        pclk_r <= pclk_r + 2'b01;
    end
    assign pclk_w = pclk_r[1];
endmodule
module top(input wire clk_i, 
	input wire nrst_i, 
	input wire fclk_i,
	input wire data_i,
	output wire [7:0]q_o);

	assign q_o[2] = !nrst_i;
    IDDRC id(
        .D(data_i),
		.CLK(fclk_i),
		.CLEAR(!nrst_i),
        .Q0(q_o[0]),
        .Q1(q_o[1])
    );
	defparam id.Q0_INIT=1'b0;
	defparam id.Q1_INIT=1'b0;

	// dummy DFF
	assign q_o[4] = dummy_r;
	reg dummy_r;
	always @(posedge fclk_i) begin
		dummy_r <= !dummy_r;
	end
endmodule
module top(input wire clk_i, 
	input wire nrst_i,
	output wire [(2 * `CH) - 1:0]q_o,
	output wire pclk_o,
    output wire fclk_o);

	genvar i;
	generate
	  for (i = 0; i < `CH; i = i + 1) begin
		OSER4 os(
			.D0(1'b1),
			.D1(1'b0),
			.D2(1'b1),
			.D3(1'b0),
			.FCLK(fclk_w),
			.PCLK(pclk_w),
			.RESET(1'b0),
			.TX0(1'b0),
			.TX1(1'b0),
			.Q0(dso_w)
		);
		wire dso_w;
		defparam os.GSREN = "false";
		defparam os.LSREN = "true";
		TLVDS_OBUF dso(
			.O(q_o[2 * i]),
			.OB(q_o[1 + 2 * i]),
			.I(dso_w)
		);
	  end
	endgenerate

	wire clk_w;
	wire pclk_w;
	wire fclk_w;
	assign fclk_w = tick_w;

	assign pclk_o = pclk_w;
	assign fclk_o = fclk_w;

	reg [24:0] ctr_q;
	wire [24:0] ctr_d;
	wire tick_w;

	// Sequential code (flip-flop)
	always @(posedge clk_i)
		ctr_q <= ctr_d;

	// Combinational code (boolean logic)
	assign ctr_d = ctr_q + 1'b1;
	assign tick_w = |ctr_q[24:23];
	//assign tick_w = ctr_q[10];


    reg [1:0]pclk_r;
    always @(posedge tick_w) begin
        pclk_r <= pclk_r + 2'b01;
    end
    assign pclk_w = pclk_r[1];
endmodule
module stud_ds_modulator #(parameter AUDIO_WIDTH = 16, VOLUME_WIDTH = 8)(
	input								clk_i,
	input								rst_n_i,
	input signed [AUDIO_WIDTH - 1 : 0]	audio_i,
	input								mode_i,
	input			[1 : 0]				osr_i,
	input								mute_i,
	input		 [VOLUME_WIDTH - 1 : 0]	volume_i,
	output				wire			audio_rd,
	output				wire			ds_o,
	output  			wire			ds_n_o
);
	
	wire [AUDIO_WIDTH-1:0] audio;
	assign ds_n_o = ~ds_o;
	
	stud_strobe strobe1 (
		.clk_i(clk_i),
		.rst_n_i(rst_n_i),
		.osr_i(osr_i),
		.audio_rd_o(audio_rd)
  	);
	
	stud_ds_volume #(.AUDIO_WIDTH(AUDIO_WIDTH), .VOLUME_WIDTH(VOLUME_WIDTH)) ds_volume1 (
		.audio_o(audio),
		.audio_i(audio_i),
		.mute_i(mute_i),
		.volume_i(volume_i),
		.clk_i(clk_i),
		.n_rst_i(rst_n_i)
	);
	
	stud_dsmod #(.BITWIDTH(AUDIO_WIDTH)) modulator (
		.n_rst_i(rst_n_i),
		.clk_i(clk_i),
		.mode_i(mode_i),
		.data_i(audio),
		.mod_o(ds_o)
	);
	
endmodule
module audiodac_sinegen (
	output wire	[15:0]			data_o,
	input					data_rd_i,
	input					rst_n_i,
	input					clk_i,

	input					tst_sinegen_en_i,
	input		[3:0]			tst_sinegen_step_i
);

	reg		[5:0]			read_ptr;

	// this bitpattern is a 16b UINT sine with a period of 64 samples with
	// 90% amplitude and an offset of 0x8000
	/* verilator lint_off LITENDIAN */
	localparam [0:(64*16)-1] sin_const = {
		16'h8000,16'h8B4B,16'h9679,16'hA171,16'hAC16,16'hB64E,16'hC000,16'hC915,
		16'hD175,16'hD90D,16'hDFC9,16'hE599,16'hEA6E,16'hEE3D,16'hF0FD,16'hF2A5,
		16'hF333,16'hF2A5,16'hF0FD,16'hEE3D,16'hEA6E,16'hE599,16'hDFC9,16'hD90D,
		16'hD175,16'hC915,16'hC000,16'hB64E,16'hAC16,16'hA171,16'h9679,16'h8B4B,
		16'h8000,16'h74B5,16'h6987,16'h5E8F,16'h53EA,16'h49B2,16'h4000,16'h36EB,
		16'h2E8B,16'h26F3,16'h2037,16'h1A67,16'h1592,16'h11C3,16'h0F03,16'h0D5B,
		16'h0CCD,16'h0D5B,16'h0F03,16'h11C3,16'h1592,16'h1A67,16'h2037,16'h26F3,
		16'h2E8B,16'h36EB,16'h4000,16'h49B2,16'h53EA,16'h5E8F,16'h6987,16'h74B5
	};
	/* verilator lint_on LITENDIAN */

	assign data_o = sin_const[read_ptr*16 +: 16];

	always @(posedge clk_i) begin
		if (!rst_n_i) begin
			// reset all registers
			read_ptr <= 6'b0;
		end else begin
			if (tst_sinegen_en_i && data_rd_i) begin
				read_ptr <= (read_ptr + {2'b0,tst_sinegen_step_i}) % 6'b111111;
			end
		end
	end

endmodule // audiodac_fifo
module audiodac (
`ifdef USE_POWER_PINS
	inout 			vccd1,
	inout 			vssd1,
`endif
	// FIFO interface
	input		[15:0]	fifo_i,
	input			fifo_rdy_i,
	output 			fifo_ack_o,
	output			fifo_full_o,
	output			fifo_empty_o,
	// housekeeping
	input			rst_n_i,
	input			clk_i,
	// configuration bits
	input			mode_i, 	// 0 = 1st, 1 = 2nd order SD-mod
	input 		[3:0]	volume_i,	// 0 = off, 1 = min volume, 15 = max volume
	input		[1:0]	osr_i, 		// 0 = 32; 1 = 64, 2 = 128, 3 = 256
	// ds-modulator outputs
	output			ds_o,		// single-bit SD-modulator output
	output 			ds_n_o,		//  plus the complementary output
	// test modes
	input			tst_sinegen_en_i,
	input		[3:0]	tst_sinegen_step_i,
	input			tst_fifo_loop_i
);

	wire		[15:0]	data_audio, data_sine;
	wire			audio_rd;

	wire [15:0] data = tst_sinegen_en_i ? data_sine : data_audio;

	audiodac_fifo fifo (
		.fifo_data_i(fifo_i),
		.fifo_rdy_i(fifo_rdy_i),
		.fifo_ack_o(fifo_ack_o),
		.fifo_full_o(fifo_full_o),
		.fifo_empty_o(fifo_empty_o),
		.audio_data_o(data_audio),
		.audio_rd_i(audio_rd),
		.rst_n_i(rst_n_i),
		.clk_i(clk_i),
		.tst_fifo_loop_i(tst_fifo_loop_i)
	);

	audiodac_dsmod dsmod (	
		.audio_i(data),
		.audio_rd_o(audio_rd),
		.rst_n_i(rst_n_i),
		.clk_i(clk_i),
		.mode_i(mode_i),
		.volume_i(volume_i),
		.osr_i(osr_i),
		.ds_o(ds_o),
		.ds_n_o(ds_n_o)
	);

	audiodac_sinegen sinegen (
		.data_o(data_sine),
		.data_rd_i(audio_rd),
		.rst_n_i(rst_n_i),
		.clk_i(clk_i),
		.tst_sinegen_en_i(tst_sinegen_en_i),
		.tst_sinegen_step_i(tst_sinegen_step_i)
	);


endmodule // audiodac
module stud_fifo_master #(parameter FIFO_LENGTH = 128, SIGNAL_WIDTH = 16, WB_DATA_WIDTH = 32, WB_SEL_WIDTH = 4, SYNC_LEN = 2)
	(
    	input [SIGNAL_WIDTH-1:0] 	fifo_i,
    	input [3:0] 			test_sine_psc_i,
	input fifo_rdy_i, audio_rd_i, rst_n_i, clk_i, test_mode_i, 
    	output reg [SIGNAL_WIDTH-1:0] 	audio_o,
    	output fifo_ack_o, fifo_full_o, fifo_empty_o 
	);
    	/* Internal signals */
    	wire [SIGNAL_WIDTH-1:0] fifo_audio_o, sine_audio_o, sine_buffered_o;
    	reg [SIGNAL_WIDTH-1:0] fifo_data_internal;
    	reg fifo_data_rdy;
    
	/* MODULES */
    	stud_fifo #(FIFO_LENGTH, SIGNAL_WIDTH, SYNC_LEN) fifo1(
		.fifo_i(fifo_data_internal),
		.fifo_rdy_i(fifo_data_rdy),
		.audio_rd_i(audio_rd_i),
		.rst_n_i(rst_n_i),
		.clk_i(clk_i),
		.fifo_ack_o(fifo_ack_o),
		.fifo_full_o(fifo_full_o),
		.fifo_empty_o(fifo_empty_o),
		.audio_o(fifo_audio_o)
	);
    
    	stud_sine_generator sine_gen1 (
        	.clk_i(clk_i),
        	.rst_n_i(rst_n_i),
        	.psc_i(test_sine_psc_i),
        	.sine_o(sine_audio_o)
    	);
    
    	stud_synchronizer #(1, SIGNAL_WIDTH) sine_buffer (
		.clk_i(audio_rd_i),
		.rst_n_i(rst_n_i),
		.input_i(sine_audio_o),
		.output_o(sine_buffered_o)
	);
	
	always @(posedge clk_i)
	begin
        	// If test mode is active, connect sine generator buffer to output
		if(test_mode_i) begin
            		audio_o <= sine_buffered_o;
		end else begin
			audio_o <= fifo_audio_o;
		end
			
		fifo_data_internal <= fifo_i;
		fifo_data_rdy <= fifo_rdy_i;
    	end
endmodule
module stud_strobe #(parameter WIDTH=8)(
	input              clk_i,
	input        	   rst_n_i,
	input  [1:0] 	   osr_i,
	output             audio_rd_o
);

reg strb, next_strb;
reg[WIDTH-1:0] counter, next_counter;
localparam [7:0] OSR32 = 8'd31;
localparam [7:0] OSR64 = 8'd63;
localparam [7:0] OSR128 = 8'd127;
localparam [7:0] OSR256 = 8'd255;


assign audio_rd_o = strb;

always @(posedge clk_i) begin
	    // we use a synchronous reset
    if (!rst_n_i) begin
	strb	   <= 1'b0;
	counter    <= {WIDTH{1'b0}};
    end else begin
	strb	   <= next_strb;
	counter    <= next_counter;
    end
  end

  always @(counter, osr_i, strb)begin
	next_counter = counter;
	next_strb  = strb;
	next_counter = counter - 1'b1;
	if (counter == 8'd0)begin
		case(osr_i)
		2'b00: begin
			next_counter = OSR32;
		end
		2'b01: begin
			next_counter = OSR64;
		end
		2'b10: begin
			next_counter = OSR128;
		end
		2'b11: begin
			next_counter = OSR256;
		end
		default: next_counter = OSR128;
		endcase
	end
	if (next_counter == 8'd0)begin //generate strobe every time the counter reaches 0
		next_strb = 1'b1;
	end else begin
		next_strb = 1'b0;
	end
  end


endmodule
module jku_logo(
	input jku
);

/* verilator lint_off UNUSED */
wire dummy1 = jku;
/* verilator lint_off UNUSED */

endmodule
module stud_d_flip_flop (input clk_i, rst_n_i, data_i, 
					output reg output_o);
	always @(posedge clk_i) begin
		if(~rst_n_i) begin
			output_o <= 1'b0;
		end else begin
			output_o <= data_i;
		end
	end
endmodule
module audiodac_drv(
`ifdef USE_POWER_PINS
    input vdd,
    input vss,
`endif
    input in_p,
    input in_n,
    input in_hi,
    output wire out_p,
    output wire out_n
);

assign out_p = (in_hi) ? in_p : 1'bx;
assign out_n = (in_hi) ? in_n : 1'bx;

endmodule
module audiodac_dsmod(
	input 		[15:0]	audio_i,	// audio data from FIFO
	output wire		audio_rd_o, 	// indicates a read from FIFO
	input			rst_n_i,
	input			clk_i,
	input			mode_i, 	// 0 = 1st order, 1 = 2nd order SD-modulator
	input 		[3:0]	volume_i,	// 0 = off, 15 = max volume
	input		[1:0]	osr_i, 		// 0 = 32; 1 = 64, 2 = 128, 3 = 256
	output reg		ds_o,		// single-bit SD-modulator output
	output wire		ds_n_o		//  plus the complementary output
);

	reg 		[15:0]	accu1;
	reg		[15:0]	accu2;
	reg		[1:0]	accu3;
	wire 		[15:0]	audio_scaled;	// audio data treated with volume control
	reg		[7:0]	fetch_ctr;	// clock divideid by osr

	reg		[1:0]	mod2_ctr;	// clk divide by 4 for 1st stage of 2nd order mod.
	reg		[1:0]	mod2_out;	// output 1st stage

	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;

	// provide out and out_n to make levelshifter easier
  	assign ds_n_o = ~ds_o;

	// we provide volume control in 6dB steps, 0=min (off), 15=max
	assign audio_scaled = (volume_i === 4'd0) ? 16'b0 : audio_i >> (4'd15 - volume_i);

	// the fetch counter controls the read of the next sample from the FIFO
	// counter runs down so decoding is easier for different counter
	// cycles
	assign audio_rd_o = (fetch_ctr === 8'd0);

  	always @(posedge clk_i) begin
		if (!rst_n_i) begin
			// reset all registers
			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
			// sd-modulator is running

			if (fetch_ctr === 8'd0) begin
			// fetch_ctr finished, restart with proper cycle count
			// depending on osr
				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
				//just keep counting down
				fetch_ctr <= fetch_ctr - 1'b1;
		
			if (mode_i === ORD1) begin
				// delta-sigma modulator 1st order
				// this simple structure works if everything
				// is UINT
				{ds_o,accu1} <= audio_scaled + accu1;
			
			end else if (mode_i === ORD2) begin
				// delta-sigma modulator 2nd order
				// the first stage runs on clk/4, the second
				// stage runs on clk

				if (mod2_ctr === 2'b0) begin
					// this only happens every 4th clk
					// cycle
					{mod2_out,accu1} <= {2'b00,audio_scaled} 
								+ {1'b0,accu1,1'b0} 
								+ 18'h10000 
								- {2'b0,accu2};
					accu2 <= accu1;
				end

				// this is the clk divider for the 1st stage
				mod2_ctr <= mod2_ctr + 1'b1;
				
				// this simple structure is the 2nd stage
				// running on clk
				{ds_o,accu3} <= mod2_out + accu3;
			end
		end
	end
endmodule // audiodac_dsmod
module stud_fifo 
       #( parameter LENGTH = 128,
	  parameter WIDTH = 16,
	  parameter SYNC_LEN = 2
  	)
	(
	  input [WIDTH-1:0] fifo_i,
	  input fifo_rdy_i, audio_rd_i, rst_n_i, clk_i,
	  output reg fifo_ack_o, fifo_full_o, fifo_empty_o,
	  output [WIDTH-1:0] audio_o
	);

	/* Internal buffers */
	reg [WIDTH-1:0] buffer [LENGTH - 1 : 0];
	reg [$clog2(LENGTH)-1:0] buffer_r_ind;
	reg [$clog2(LENGTH)-1:0] buffer_w_ind;
	wire fifo_rdy; // Synchronous fifo_rdy
	reg [WIDTH-1:0] audio_tmp;
	reg fifo_ack_next;
	reg fifo_rdy_last;
	reg audio_rd_last;

	/* External modules */
	stud_synchronizer #(SYNC_LEN,1) fifo_rdy_sync(
		.clk_i(clk_i),
		.rst_n_i(rst_n_i),
		.input_i(fifo_rdy_i),
		.output_o(fifo_rdy)
	);

	/* CLK_i process */
	always @(posedge clk_i) begin
		if(~rst_n_i) begin
			/* Reset whole buffer, for loops are allowed (according to internet) */
			buffer[0] <= {WIDTH{1'b0}};
			buffer_r_ind <= {$clog2(LENGTH){1'b0}};
			buffer_w_ind <= {$clog2(LENGTH){1'b0}};
			audio_tmp <= {WIDTH{1'b0}};
			fifo_empty_o <= 1'b1;
			fifo_full_o <= 1'b0;
			fifo_ack_o <= 1'b0;
			fifo_ack_next <= 1'b0;
		end else begin

			/* FIFO WRITE */
			if(fifo_rdy && ! fifo_rdy_last && !fifo_full_o) begin
				buffer[buffer_w_ind] <= fifo_i;
				buffer_w_ind <= buffer_w_ind + 1'b1;
				fifo_ack_next <= 1'b1;
			end else begin
				buffer[buffer_w_ind] <= buffer[buffer_w_ind];
				buffer_w_ind <= buffer_w_ind;
				fifo_ack_next <= 1'b0;
			end

			/* FIFO READ */
			if(audio_rd_i && !audio_rd_last && !fifo_empty_o) begin
				audio_tmp <= buffer[buffer_r_ind];
				buffer_r_ind <= buffer_r_ind + 1'b1;
			end else begin
				audio_tmp <= audio_tmp;
				buffer_r_ind <= buffer_r_ind;
			end

			/* FIFO status */
			if (buffer_r_ind == buffer_w_ind) begin
				fifo_empty_o <= 1'b1;
			end else begin
				fifo_empty_o <= 1'b0;
			end
			if(buffer_w_ind == (buffer_r_ind - 1'b1)) begin
				fifo_full_o <= 1'b1;
			end else begin
				fifo_full_o <= 1'b0;
			end

			fifo_ack_o <= fifo_ack_next;
			fifo_rdy_last <= fifo_rdy;
			audio_rd_last <= audio_rd_i;
		end
	end
	assign audio_o = audio_tmp;
endmodule
module audiodac_fifo
	#(parameter AUDIO_WIDTH=16, FIFO_SIZE=9, FIFO_ASYNC=1) (
	// 0=sync, 1=async write I/F

	input 		[AUDIO_WIDTH-1:0]	fifo_data_i,
	input					fifo_rdy_i,
	// note that fifo_rdy_i/fifo_data_i can originate from an asynchronous
	// clk domain, so potentially needs to be synchronized; 
	// use FIFO_ASYNC to select the proper behaviour
	output reg				fifo_ack_o,
	output wire				fifo_full_o,
	output wire				fifo_empty_o,

	output wire	[AUDIO_WIDTH-1:0]	audio_data_o,
	input					audio_rd_i,
	
	input					rst_n_i,
	input					clk_i,

	input					tst_fifo_loop_i
);

	reg		[FIFO_SIZE-1:0]		read_ptr, write_ptr;
	wire		[FIFO_SIZE-1:0]		next_write;
	reg		[AUDIO_WIDTH-1:0]	fifo_reg[0:(1<<FIFO_SIZE)-1];

	// needed for asynch. I/F synchronization (use 2 stages)
	reg     				fifo_rdy_del1, fifo_rdy_del2;
	reg		[AUDIO_WIDTH-1:0]	fifo_data_del1, fifo_data_del2;


	assign fifo_full_o = (next_write === read_ptr);
	assign fifo_empty_o = (write_ptr === read_ptr);

	assign audio_data_o = fifo_reg[read_ptr];
	assign next_write = write_ptr + 1'b1;

	wire _fifo_rdy = FIFO_ASYNC ? fifo_rdy_del2 : fifo_rdy_i;
	wire [AUDIO_WIDTH-1:0] _fifo_data = FIFO_ASYNC ? fifo_data_del2 : fifo_data_i;

	always @(posedge clk_i) begin
		if (!rst_n_i) begin
			// reset all registers
			fifo_ack_o <= 1'b0;
			read_ptr <= {FIFO_SIZE{1'b0}};
			write_ptr <= {FIFO_SIZE{1'b0}};

			// for FIFO only first entry needs reset, so that
			// first read is OK
			// reset to midscale of UINT
              		fifo_reg[0] <= {1'b1,{(AUDIO_WIDTH-1){1'b0}}};

			fifo_rdy_del1 <= 1'b0;
			fifo_rdy_del2 <= 1'b0;
			fifo_data_del1 <= {AUDIO_WIDTH{1'b0}};
			fifo_data_del2 <= {AUDIO_WIDTH{1'b0}};
		end else begin
                       	// use two stages to sync-in fifo_rdy_i
                       	fifo_rdy_del2 <= fifo_rdy_del1;
                       	fifo_rdy_del1 <= fifo_rdy_i;
                       	// use two stages to sync-in fifo_data_i
                       	fifo_data_del2 <= fifo_data_del1;
                       	fifo_data_del1 <= fifo_data_i;

			// manage the FIFO read process, if audio_rd is asserted
			// the read pointer location is increased, as long as
			// the FIFO is not empty
			if (audio_rd_i && (!fifo_empty_o || tst_fifo_loop_i))
				read_ptr <= read_ptr + 1'b1;
		
			// manage the FIFO write process. if fifo_rdy is
			// asserted, and the FIFO is not full, and no pending ack,
			// then the write pointer is increased and the datum is 
			// written into the FIFO. further ack is asserted
			if (_fifo_rdy && !fifo_ack_o && !fifo_full_o) begin
				write_ptr <= next_write;
				fifo_reg[next_write] <= _fifo_data;
				fifo_ack_o <= 1'b1;
			end

			if (!_fifo_rdy)
				fifo_ack_o <= 1'b0;
		end
	end

endmodule // audiodac_fifo
module stud_second_order_modulator
#(
    parameter BITWIDTH = 16             // audio data input width
)
(
    input n_rst_i,                      // active low synchronous reset
    input clk_i,                        // clock input

    input [BITWIDTH - 1 : 0] data_i,    // audio data input (unsigned)

    output reg [1 : 0] mod_o            // 2 bit modulator output
);

// counter to realize fs / 4 sampling rate
reg [1 : 0] counter;
reg [1 : 0] counter_next;

// sampling strobe, triggered every 4 cycles
reg sampling_strb;
reg sampling_strb_next;

// feedback line 1
reg [BITWIDTH - 1 : 0] fb1;
reg [BITWIDTH - 1 : 0] fb1_next;

// feedback line 2
reg [BITWIDTH - 1 : 0] fb2;
reg [BITWIDTH - 1 : 0] fb2_next;

// accumulator
reg [BITWIDTH + 1: 0] acc;
reg [BITWIDTH + 1: 0] acc_next;

// modulator output
reg [1 : 0] mod_next;

// counter and sampling strobe combinatorics
always @* begin
    // default assignments
    counter_next = counter;
    sampling_strb_next = 1'b0;

    if (counter == 2'd3) begin
        // reset counter on overflow and trigger strobe
        counter_next = 2'b0;
        sampling_strb_next = 1'b1;
    end else begin
        // increment counter
        counter_next = counter + 2'd1;
    end
end

// modulator combinatorics
always @* begin
    // default assignments
    fb1_next = fb1;
    fb2_next = fb2;
    acc_next = acc;
    mod_next = mod_o;

    // only update registers every sampling interval (4 clock cycles)
    if (sampling_strb) begin
        // fb2 is the (n - 2) least significant bits of the accumulator
        // delayed by 2 sampling intervals (8 clock cycles)
        fb2_next = fb1;

        // fb1 is the (n - 2) least significant bits of the accumulator
        // delayed by 1 sampling interval (4 clock cycles)
        fb1_next = acc[BITWIDTH - 1 : 0];

        // accumulator value = audio data input + 2 * fb1 + (-1) * fb2
        // in order to prevent underflows, an offset of 2 ^ BITWIDTH has to be added to (-1) * fb2
        acc_next = {2'b0, data_i} + ({2'b0, fb1} << 1) + {1'b0, {1'b1, {BITWIDTH {1'b0}}} - {1'b0, fb2}};

        // 2 most significant bits of the accumulator become the output
        mod_next = acc[BITWIDTH + 1 : BITWIDTH];
    end
end

// registers
always @(posedge clk_i) begin
    if (!n_rst_i) begin
        // synchronously reset register values
        counter <= 2'd3; // ensure counter overflow at the start
        sampling_strb <= 1'b0;

        fb1 <= {BITWIDTH {1'b0}};
        fb2 <= {BITWIDTH {1'b0}};
        acc <= {BITWIDTH + 2 {1'b0}};
        mod_o <= 2'b0;
    end else begin
        counter <= counter_next;
        sampling_strb <= sampling_strb_next;

        fb1 <= fb1_next;
        fb2 <= fb2_next;
        acc <= acc_next;

        mod_o <= mod_next;
    end
end

endmodule
module stud_ds_volume
#(
	parameter AUDIO_WIDTH=16,					// audio data input and output width
	VOLUME_WIDTH=8								// volume input width
)
(
	output reg [AUDIO_WIDTH - 1:0] audio_o,		// audio data output (unsigned)

	input signed [AUDIO_WIDTH - 1:0] audio_i,	// audio data input (signed)

	input mute_i,								// mute input, 1'b0 => normal operation, 1'b1 => output muted
	input [VOLUME_WIDTH - 1:0] volume_i,		// volume input (unsigned)

	input clk_i,								// clock input
	input n_rst_i								// active low synchronous reset
);

// actual volume, an offset of 1 is added to the volume input so that the audio data remains unchanged at
// maximum volume
reg [VOLUME_WIDTH : 0] volume;
// scaled signed audio data
reg signed [AUDIO_WIDTH : 0] audio_scaled;
// scaled audio data offset to unsigned value range, but still in signed format
reg signed [AUDIO_WIDTH-1 : 0] audio_offset;
// scaled, unsigned audio data
reg [AUDIO_WIDTH-1 : 0] next_audio_out;
/* verilator lint_off UNUSED */
reg dummy1;
reg [VOLUME_WIDTH-1:0] dummy2;
/* verilator lint_on UNUSED */

// combinatorics
always @* begin
	if (mute_i) begin
		// mute input activated, set volume to 0
		volume = {VOLUME_WIDTH + 1 {1'b0}};
	end else begin
		// normal operation, add 1 to volume input
		volume = {1'b0, volume_i} + {{VOLUME_WIDTH {1'b0}}, 1'b1};
	end

	// multiply input data by volume and shift right by VOLUME_WIDTH
	{dummy2,audio_scaled} = ({{VOLUME_WIDTH {audio_i[AUDIO_WIDTH - 1]}}, audio_i} * volume) >>> VOLUME_WIDTH;

	// add 2 ^ (AUDIO_WIDTH - 1) to convert the signed audio data to the unsigned data range
	{dummy1,audio_offset} = audio_scaled[AUDIO_WIDTH : 0] + {2'b01, {AUDIO_WIDTH - 1 {1'b0}}};
	
	// truncate result to AUDIO_WIDTH bits
	next_audio_out = audio_offset[AUDIO_WIDTH - 1 : 0];
end

// registers
always @(posedge clk_i) begin
	if (!n_rst_i) begin
		// synchronously reset register values
		// start audio output at 50 % i.e. 0
		audio_o <= {1'b0, {AUDIO_WIDTH - 1 {1'b1}}};
	end else begin
		audio_o <= next_audio_out;
	end
end
	
endmodule
module stud_first_order_modulator
#(
    parameter BITWIDTH = 16             // audio data input width
)
(
    input n_rst_i,                      // active low synchronous reset
    input clk_i,                        // clock input

    input [BITWIDTH - 1 : 0] data_i,    // audio data input (unsigned)

    output reg mod_o                    // 1 bit modulator output
);

// feedback line
reg [BITWIDTH - 1 : 0] fb;
reg [BITWIDTH - 1 : 0] fb_next;

// accumulator
reg [BITWIDTH : 0] acc;
reg [BITWIDTH : 0] acc_next;

// modulator output
reg mod_next;

// combinatorics
always @* begin
    // least significant bits of the accumulator get delayed by 1 clock cycle
    // and then fed back into the accumulator
    fb_next = acc[BITWIDTH - 1 : 0];
    acc_next = {1'b0, data_i} + {1'b0, fb};

    // most significant bit of the accumulator becomes the output
    mod_next = acc[BITWIDTH];
end

// registers
always @(posedge clk_i) begin
    if (!n_rst_i) begin
        // synchronously reset register values
        fb <= {BITWIDTH {1'b0}};
        acc <= {BITWIDTH + 1 {1'b0}};
        mod_o <= 1'b0;
    end else begin
        fb <= fb_next;
        acc <= acc_next;

        mod_o <= mod_next;
    end
end

endmodule
module stud_synchronizer
	#(parameter N=4,
	  parameter WIDTH = 16)
	(	input clk_i, rst_n_i,
		input [WIDTH-1:0] input_i,
		output [WIDTH-1:0] output_o);

	genvar i;
	genvar w;
	wire [WIDTH-1:0] buffer [0:N-1];
	generate
		/* Generate chain for each bit in WIDTH*/
		for(w = 0; w < WIDTH; w = w + 1) begin
			/* First FF in chain*/
			stud_d_flip_flop d0(clk_i, rst_n_i, input_i[w], buffer[0][w]);
			/* Every other FF in chain*/
			for(i = 1; i < N; i = i + 1) begin
				stud_d_flip_flop d_mid (clk_i, rst_n_i, buffer[i-1][w], buffer[i][w]);
			end
		end
	endgenerate
	assign output_o = buffer[N-1];	
endmodule
module stud_dac_dsmod #(parameter AUDIO_WIDTH = 16, VOLUME_WIDTH = 8,FIFO_LENGTH = 128, WB_DATA_WIDTH = 32, WB_SEL_WIDTH = 4, SYNC_LEN = 2)(
`ifdef USE_POWER_PINS
	inout 				vccd1,
	inout 				vssd1,
`endif
	input [AUDIO_WIDTH-1:0] 	fifo_i,
    	input [3:0] 			test_sine_psc_i,
	input 				fifo_rdy_i, rst_n_i, clk_i, test_mode_i, 
   	output 				fifo_ack_o, fifo_full_o, fifo_empty_o, 
	output				ds_o, ds_n_o,
	input [1:0]			osr_i,
	input				mute_i, mode_i,
	input [VOLUME_WIDTH - 1 : 0]	volume_i
);
	
	
	wire [AUDIO_WIDTH-1:0] data;
	wire audio_rd;
	
	stud_fifo_master #(FIFO_LENGTH, AUDIO_WIDTH, WB_DATA_WIDTH, WB_SEL_WIDTH, SYNC_LEN) DUT(
		.fifo_i(fifo_i),
		.test_sine_psc_i(test_sine_psc_i),
		.fifo_rdy_i(fifo_rdy_i),
		.audio_rd_i(audio_rd),
		.rst_n_i(rst_n_i),
		.clk_i(clk_i),
		.test_mode_i(test_mode_i),
		.fifo_ack_o(fifo_ack_o),
		.fifo_full_o(fifo_full_o),
		.fifo_empty_o(fifo_empty_o),
		.audio_o(data)
    	);
	
	stud_ds_modulator #(.AUDIO_WIDTH(AUDIO_WIDTH), .VOLUME_WIDTH(VOLUME_WIDTH)) modulator(
		.clk_i(clk_i),
		.rst_n_i(rst_n_i),
		.audio_i(data),
		.mode_i(mode_i),
		.osr_i(osr_i),
		.mute_i(mute_i),
		.volume_i(volume_i),
		.audio_rd(audio_rd),
		.ds_o(ds_o),
		.ds_n_o(ds_n_o)
	);
	
endmodule
module stud_dsmod
#(
    parameter BITWIDTH = 16             // audio data input width
)
(
    input n_rst_i,                      // active low synchronous reset
    input clk_i,                        // clock input

    input mode_i,                       // modulator mode, 1'b0 -> first order, 1'b1 -> second order
    
    input [BITWIDTH - 1 : 0] data_i,    // audio data input (unsigned)

    output wire mod_o                   // 1 bit modulator output
);

// mode input delayed by 1 clock cycle
reg prev_mode;
// active low reset strobe for the first order modulator, triggered every time the mode changes
reg rst_strb;

// input data for the first order modulator
// In first order mode, this is simply the input audio data.
// In second order mode, the two bit output of the second order modulator is padded with zeros
// and used as the input for the first order modulator.
reg [BITWIDTH - 1 : 0] first_order_data;

// output of the first stage (second oder modulator)
wire [1 : 0] stage1;
// output of the second stage (first order modulator)
wire stage2;

// registers
always @(posedge clk_i) begin
    if (!n_rst_i) begin
        // synchronously reset register values
        prev_mode <= 1'b0;
    end else begin
        // store mode input
        prev_mode <= mode_i;
    end
end

// combinatorics
always @* begin
    // gerate negative strobe every time the mode changes
    rst_strb = mode_i == prev_mode;

    if (mode_i) begin
        // second order mode => use output of the first stage (second order modulator) as input data
        // for the second stage (first order modulator)
        first_order_data = {stage1, {BITWIDTH - 2 {1'b0}}};
    end else begin
        // first order mode => use audio data input as input for the first order modulator
        first_order_data = data_i;
    end
end

// second order modulator, first stage of the design when in second order mode
stud_second_order_modulator #(.BITWIDTH(BITWIDTH)) modulator1
(
    .n_rst_i(n_rst_i & mode_i), // disable first stage when first order mode is enabled
    .clk_i(clk_i),
    .data_i(data_i),
    .mod_o(stage1)
);

// first order modulator, second stage of the design when in second order mode
stud_first_order_modulator #(.BITWIDTH(BITWIDTH)) modulator2
(
    .n_rst_i(n_rst_i & rst_strb), // reset second stage every time the mode chages
    .clk_i(clk_i),
    .data_i(first_order_data),
    .mod_o(stage2)
);

// output of the modulator is the output of the second stage
assign mod_o = stage2;

endmodule
module user_project_wrapper #(
    parameter BITS = 32
) (
`ifdef USE_POWER_PINS
    inout vdda1,	// User area 1 3.3V supply
    inout vdda2,	// User area 2 3.3V supply
    inout vssa1,	// User area 1 analog ground
    inout vssa2,	// User area 2 analog ground
    inout vccd1,	// User area 1 1.8V supply
    inout vccd2,	// User area 2 1.8v supply
    inout vssd1,	// User area 1 digital ground
    inout vssd2,	// User area 2 digital ground
`endif

    // Wishbone Slave ports (WB MI A)
    input wb_clk_i,
    input wb_rst_i,
    input wbs_stb_i,
    input wbs_cyc_i,
    input wbs_we_i,
    input [3:0] wbs_sel_i,
    input [31:0] wbs_dat_i,
    input [31:0] wbs_adr_i,

    output wbs_ack_o,
    output [31:0] wbs_dat_o,

    // Logic Analyzer Signals
    input  [127:0] la_data_in,
    output [127:0] la_data_out,
    input  [127:0] la_oenb,

    // IOs
    input  [`MPRJ_IO_PADS-1:0] io_in,
    output [`MPRJ_IO_PADS-1:0] io_out,
    output [`MPRJ_IO_PADS-1:0] io_oeb,

    // Analog (direct connection to GPIO pad---use with caution)
    // Note that analog I/O is not available on the 7 lowest-numbered
    // GPIO pads, and so the analog_io indexing is offset from the
    // GPIO indexing by 7 (also upper 2 GPIOs do not have analog_io).
    inout [`MPRJ_IO_PADS-10:0] analog_io,

    // Independent clock (on independent integer divider)
    input   user_clock2,

    // User maskable interrupt signals
    output [2:0] user_irq
);

/*--------------------------------------*/
/* User project is instantiated  here   */
/*--------------------------------------*/

//jku_logo logo0 (
//    .jku(1'b0)
//);


user_proj_dac dac0 (
`ifdef USE_POWER_PINS
    	.vccd1(vccd1),
    	.vssd1(vssd1),
`endif
    .wb_clk_i(wb_clk_i),
    .wb_rst_i(wb_rst_i),
    .wbs_stb_i(wbs_stb_i),
    .wbs_cyc_i(wbs_cyc_i),
    .wbs_we_i(wbs_we_i),
    .wbs_sel_i(wbs_sel_i),
    .wbs_dat_i(wbs_dat_i),
    .wbs_adr_i(wbs_adr_i),
    .wbs_ack_o(wbs_ack_o),
    .wbs_dat_o(wbs_dat_o),
    .la_data_in(la_data_in),
    .la_data_out(la_data_out),
    .la_oenb(la_oenb),
    .io_in(io_in),
    .io_out(io_out),
    .io_oeb(io_oeb),
    .irq(user_irq),
    .user_clock2(user_clock2),
    .analog_io(analog_io)
);


// Connect the analog output driver
audiodac_drv drv0 (
`ifdef USE_POWER_PINS
   	.vdd(vdda1),		// User area 1 3.3V supply
    	.vss(vssa1),		// User area 1 analog ground
`endif
	.in_p(io_in[16]),
	.in_n(io_in[17]),
	.in_hi(1'b1),
	.out_p(analog_io[7]),
	.out_n(analog_io[8])
);


endmodule	// user_project_wrapper
module mprj_stimulus_tb;
    // Signals declaration
    reg clock;
    reg RSTB;
    reg CSB;
    reg power1, power2;

    wire gpio;
    wire [37:0] mprj_io;
    wire [15:0] checkbits;
    wire [3:0] status;

    // Signals Assignment
    assign checkbits  = mprj_io[31:16];
    assign status = mprj_io[35:32];

    // Force CSB high until simulation is underway
    // Note:  The CSB GPIO pin default needs to be set to a pull-up. . .
    assign mprj_io[3] = CSB;

    always #12.5 clock <= (clock === 1'b0);

    initial begin
        clock = 0;
    end

    initial begin
        $dumpfile("mprj_stimulus.vcd");
        $dumpvars(0, mprj_stimulus_tb);

        // Repeat cycles of 1000 clock edges as needed to complete testbench
        repeat (150) begin
            repeat (1000) @(posedge clock);
        end
        $display("%c[1;31m",27);
        $display ("Monitor: Timeout, Test Project IO Stimulus (RTL) Failed");
        $display("%c[0m",27);
        $finish;
    end

    initial begin
        wait(checkbits == 16'hAB40);
        $display("Monitor: mprj_stimulus test started");
        wait(status == 4'ha);
        wait(status == 4'h5);

	// Values reflect copying user-controlled outputs to memory and back
	// to management-controlled outputs.  Note that there is a slight
	// discrepancy in timing when using gate level simulation;  either
	// of the specified values is okay.

        wait(checkbits == 16'h0840 || checkbits == 16'h0841);
        wait(checkbits == 16'h0a00 || checkbits == 16'h0a01);

        wait(checkbits == 16'hAB51);
        $display("Monitor: mprj_stimulus test Passed");
        #10000;
        $finish;
    end

    // Reset Operation
    initial begin
        RSTB <= 1'b0;
	CSB <= 1'b1;
        #2000;
        RSTB <= 1'b1;       	// Release reset
	#200000;
	CSB <= 1'bz;		// Stop driving CSB
    end

    initial begin		// Power-up sequence
        power1 <= 1'b0;
        power2 <= 1'b0;
        #200;
        power1 <= 1'b1;
        #200;
        power2 <= 1'b1;
    end

    wire flash_csb;
    wire flash_clk;
    wire flash_io0;
    wire flash_io1;

    wire VDD3V3 = power1;
    wire VDD1V8 = power2;
    wire VSS = 1'b0;

    caravel uut (
        .vddio	  (VDD3V3),
        .vssio	  (VSS),
        .vdda	  (VDD3V3),
        .vssa	  (VSS),
        .vccd	  (VDD1V8),
        .vssd	  (VSS),
        .vdda1    (VDD3V3),
        .vdda2    (VDD3V3),
        .vssa1	  (VSS),
        .vssa2	  (VSS),
        .vccd1	  (VDD1V8),
        .vccd2	  (VDD1V8),
        .vssd1	  (VSS),
        .vssd2	  (VSS),
        .clock	  (clock),
        .gpio     (gpio),
        .mprj_io  (mprj_io),
        .flash_csb(flash_csb),
        .flash_clk(flash_clk),
        .flash_io0(flash_io0),
        .flash_io1(flash_io1),
        .resetb	  (RSTB)
    );


    spiflash #(
        .FILENAME("mprj_stimulus.hex")
    ) spiflash (
        .csb(flash_csb),
        .clk(flash_clk),
        .io0(flash_io0),
        .io1(flash_io1),
        .io2(),         // not used
        .io3()          // not used
    );

endmodule
module wb_port_tb;
	reg clock;
	reg RSTB;
	reg CSB;
	reg power1, power2;
	reg power3, power4;

	wire gpio;
	wire [37:0] mprj_io;
	wire [7:0] mprj_io_0;
	wire [15:0] checkbits;

	assign checkbits = mprj_io[31:16];

	assign mprj_io[3] = (CSB == 1'b1) ? 1'b1 : 1'bz;

	// External clock is used by default.  Make this artificially fast for the
	// simulation.  Normally this would be a slow clock and the digital PLL
	// would be the fast clock.

	always #12.5 clock <= (clock === 1'b0);

	initial begin
		clock = 0;
	end

	initial begin
		$dumpfile("wb_port.vcd");
		$dumpvars(0, wb_port_tb);

		// Repeat cycles of 1000 clock edges as needed to complete testbench
		repeat (30) begin
			repeat (1000) @(posedge clock);
			// $display("+1000 cycles");
		end
		$display("%c[1;31m",27);
		`ifdef GL
			$display ("Monitor: Timeout, Test Mega-Project WB Port (GL) Failed");
		`else
			$display ("Monitor: Timeout, Test Mega-Project WB Port (RTL) Failed");
		`endif
		$display("%c[0m",27);
		$finish;
	end

	initial begin
	   wait(checkbits == 16'h AB60);
		$display("Monitor: MPRJ-Logic WB Started");
		wait(checkbits == 16'h AB61);
		`ifdef GL
	    	$display("Monitor: Mega-Project WB (GL) Passed");
		`else
		    $display("Monitor: Mega-Project WB (RTL) Passed");
		`endif
	    $finish;
	end

	initial begin
		RSTB <= 1'b0;
		CSB  <= 1'b1;		// Force CSB high
		#2000;
		RSTB <= 1'b1;	    	// Release reset
		#170000;
		CSB = 1'b0;		// CSB can be released
	end

	initial begin		// Power-up sequence
		power1 <= 1'b0;
		power2 <= 1'b0;
		power3 <= 1'b0;
		power4 <= 1'b0;
		#100;
		power1 <= 1'b1;
		#100;
		power2 <= 1'b1;
		#100;
		power3 <= 1'b1;
		#100;
		power4 <= 1'b1;
	end

	always @(mprj_io) begin
		#1 $display("MPRJ-IO state = %b ", mprj_io[7:0]);
	end

	wire flash_csb;
	wire flash_clk;
	wire flash_io0;
	wire flash_io1;

	wire VDD3V3 = power1;
	wire VDD1V8 = power2;
	wire USER_VDD3V3 = power3;
	wire USER_VDD1V8 = power4;
	wire VSS = 1'b0;

	caravel uut (
		.vddio	  (VDD3V3),
		.vssio	  (VSS),
		.vdda	  (VDD3V3),
		.vssa	  (VSS),
		.vccd	  (VDD1V8),
		.vssd	  (VSS),
		.vdda1    (USER_VDD3V3),
		.vdda2    (USER_VDD3V3),
		.vssa1	  (VSS),
		.vssa2	  (VSS),
		.vccd1	  (USER_VDD1V8),
		.vccd2	  (USER_VDD1V8),
		.vssd1	  (VSS),
		.vssd2	  (VSS),
		.clock	  (clock),
		.gpio     (gpio),
        .mprj_io  (mprj_io),
		.flash_csb(flash_csb),
		.flash_clk(flash_clk),
		.flash_io0(flash_io0),
		.flash_io1(flash_io1),
		.resetb	  (RSTB)
	);

	spiflash #(
		.FILENAME("wb_port.hex")
	) spiflash (
		.csb(flash_csb),
		.clk(flash_clk),
		.io0(flash_io0),
		.io1(flash_io1),
		.io2(),			// not used
		.io3()			// not used
	);

endmodule
module sine_generator_tb();
localparam CLK_PERIOD = 1000;
reg clk_tb, rst_n_tb;
reg [3:0] psc_tb;
wire [15:0] sine_tb;

sine_generator DUT (.clk_i(clk_tb),
                    .rst_n_i(rst_n_tb),
                    .psc_i(psc_tb),
                    .sine_o(sine_tb));

always #(CLK_PERIOD/2) clk_tb  = !clk_tb;

initial
begin
    clk_tb = 0;
    rst_n_tb = 0;
    #CLK_PERIOD
    rst_n_tb = 1;
    psc_tb = 4;
    #100000000
    psc_tb = 6;
    #100000000
    psc_tb = 8;
    #100000000
    psc_tb = 10;
    #150000000
    rst_n_tb = 0;
    #CLK_PERIOD
    rst_n_tb = 1;
    #50000000
    $stop;
end

endmodule