dakies/OSS_Verilog huggingface dataset:
module fpu_tb ();
   /*AUTOWIRE*/
   // Beginning of automatic wires (for undeclared instantiated-module outputs)
   wire			div_zero_o;		// From DUT of fpu_arith.v
   wire			ine_o;			// From DUT of fpu_arith.v
   wire			inf_o;			// From DUT of fpu_arith.v
   wire [32-1:0]	output_o;		// From DUT of fpu_arith.v
   wire			overflow_o;		// From DUT of fpu_arith.v
   wire			qnan_o;			// From DUT of fpu_arith.v
   wire			ready_o;		// From DUT of fpu_arith.v
   wire			snan_o;			// From DUT of fpu_arith.v
   wire			underflow_o;		// From DUT of fpu_arith.v
   wire			zero_o;			// From DUT of fpu_arith.v
   // End of automatics
   /*AUTOREGINPUT*/
   // Beginning of automatic reg inputs (for undeclared instantiated-module inputs)
   reg			clk;			// To DUT of fpu_arith.v
   reg [2:0]		fpu_op_i;		// To DUT of fpu_arith.v
   reg [32-1:0]	opa_i;			// To DUT of fpu_arith.v
   reg [32-1:0]	opb_i;			// To DUT of fpu_arith.v
   reg [1:0]		rmode_i;		// To DUT of fpu_arith.v
   reg			rst;			// To DUT of fpu_arith.v
   reg			start_i;		// To DUT of fpu_arith.v
   // End of automatics
   reg goahead;

   fpu_arith DUT
	(
	 // Outputs
	 .ready_o			(ready_o),
	 .output_o			(output_o[32-1:0]),
	 .ine_o				(ine_o),
	 .overflow_o			(overflow_o),
	 .underflow_o			(underflow_o),
	 .div_zero_o			(div_zero_o),
	 .inf_o				(inf_o),
	 .zero_o			(zero_o),
	 .qnan_o			(qnan_o),
	 .snan_o			(snan_o),
	 // Inputs
	 .clk				(clk),
	 .rst				(rst),
	 .opa_i				(opa_i[32-1:0]),
	 .opb_i				(opb_i[32-1:0]),
	 .fpu_op_i			(fpu_op_i[2:0]),
	 .rmode_i			(rmode_i[1:0]),
	 .start_i			(start_i));

   // Stimulus


   // clock
   initial begin
      clk = 0;
      while (1) begin
	 #40;
	 clk = ~clk;
      end
   end

   // reset
   initial begin
      rst = 1;
      #200;
      rst = 0;

      #10000;
      $finish;
   end



   always @(posedge clk or posedge rst)
   begin
      if (rst)
      begin
         opa_i <= 'd0;
         opb_i <= 'd0;
         fpu_op_i <= 'd0;
         rmode_i <= 'd0;
         start_i <= 1'b0;
         goahead <= 1'b1;
      end
      else
      begin
         if (goahead)
         begin
            opa_i <= $random;
            opb_i <= $random;
            fpu_op_i <= 3'd2;
            rmode_i <= 2'd0;
            start_i <= 1'b1;
         end
         else
         begin
            start_i <= 1'b0;
         end
         if (goahead)
            goahead <= 1'b0;
         else if (ready_o)
            goahead <= 1'b1;
   end // else: !if(rst)
   end // always @ (posedge clk or posedge rst)

 //waveforms
  initial begin
    if ($test$plusargs("dump_waveforms")) begin
      $vcdpluson(0,fpu_tb);
      //$vcdpluson(<level>,scope,<signal>);
      //Lots of options for dumping waves
      //(both system calls and run time arguments)
      // http://read.pudn.com/downloads97/sourcecode/others/399556/vcs_0123.pdf
    end
  end


endmodule // fpu_tb
module tester(
    clk,
    rst
);
parameter end_simulation = 32'hffff;


output clk,rst;
reg clk, rst;
integer clk_count;

integer tests_done;
integer tests_failed;

initial begin
    forever begin
        #10 clk <= ~clk;
        if(clk) clk_count = clk_count + 1;
        if(clk_count == end_simulation) begin
           $display("not ok - Simulation took too long"); 
           tests_failed = tests_failed+1;    
           print_report();
           $finish;
       end
    end
end

initial begin
    clk = 0;
    rst = 0;
    clk_count = 0;
    tests_done = 0;
    tests_failed = 0;
end

task reset_module;
begin
    wait_clock();
    rst = 1;
    wait_clock();
    wait_clock();
    rst = 0;
end
endtask

task wait_clock;
begin
    @( negedge clk );
end
endtask

task check_boolean;
    input test_result;
    input[0:400] description;
    reg test_result;
    reg [0:400] description;
begin
    tests_done = tests_done + 1;
    if(test_result) $display("ok - %s",description);
    else begin
        $display("not ok - %s",description);
        tests_failed = tests_failed + 1;
    end
end
endtask

task check_value;    
    parameter VALUE_WIDTH = 32;
    input[VALUE_WIDTH-1:0] value,corr_value;
    input[0:400] description;
    reg[VALUE_WIDTH-1:0] value,corr_value;
    reg[0:400] description;
begin    
    tests_done = tests_done + 1;
    if(value === corr_value) $display("ok - %s",description);
    else begin
        $display("not ok - %s # found %h, expected %h",description,value,corr_value);
        tests_failed = tests_failed + 1;    
    end
end
endtask

task print_report;
    begin
        if(tests_failed == 0) $display("\n#################\n# All tests passed!\n");
        else $display("\n#################\n# Failed %0d/%0d tests\n",tests_failed,tests_done );
    end
endtask

endmodule
module memory_tb();

reg clk;
reg rst;

reg[3:0] rd_en, wr_en;
reg[6:0] input_tag;
reg[63:0] wr_mask;
reg[2047:0] addresses;
reg[8191:0] wr_data;

wire ack;
wire[6:0] output_tag;
wire[2047:0] tracemon_addr;
wire[8191:0] rd_data, tracemon_store_data;

memory mem(
      rd_en,
      wr_en,
      addresses,
      wr_data,
      input_tag,
      wr_mask,
      rd_data,
      output_tag,
      ack,
      tracemon_addr,
      tracemon_store_data,
      clk,
      rst
	);

initial begin
	clk = 0;
	while (1) begin
		#2;
		clk = ~clk;
	end
end

initial begin
	rst = 1;
	rd_en = 4'b0000;
	wr_en = 4'b0000;
	#11;
	rst = 0;
	#20
	input_tag = 1;
	addresses  = 2048'h00000034_00000024_00000014_00000004;
	wr_data = 8192'h00000001_00000002_00000003_00000004_00000005_00000006_00000007_00000008;
	wr_en = 4'b0101;
	wr_mask = 7;
	#4
	wr_en = 4'b0000;
	#20;
	input_tag = 2;
	addresses  = 2048'h00000034_00000024_00000014_00000004;
	rd_en = 4'b0101;
	wr_mask = 1;
	#4
	rd_en = 0;
	#10
	$finish;
end

always @ (posedge clk) begin
	if (!rst) begin
		$display ("Time= %g : Ack= %b : Output_tag= %b", $time, ack, output_tag);
		if(ack) begin
            $display ("Addr: %h Read Data: %h", addresses[31:0], rd_data[127:0]);
            $display ("Addr: %h Read Data: %h", addresses[63:32], rd_data[255:128]);
            $display ("Addr: %h Read Data: %h", addresses[95:64], rd_data[383:256]);
            $display ("Addr: %h Read Data: %h", addresses[127:96], rd_data[511:384]);
        end
	end
end

endmodule
module addr_calc_test;

wire[2047:0] out_addr;

reg[127:0] resource_buffer;
reg[2047:0] vreg_value;
reg[31:0] sreg_value;
reg[15:0] imm_value;
reg[15:0] opcode;

address_calculation adcal(out_addr, resource_buffer, vreg_value, sreg_value, imm_value, opcode);

initial
	begin
		// sbuff_load test
		resource_buffer <= 128'h02;
		vreg_value <= 2048'hx;
		sreg_value <= 32'h3;
		imm_value <= 16'h04;
		opcode <= 16'b0000_0001_0010_1000;
		#1
		$display("Out Address = %H", out_addr);
		#20
		// tbuff_load test
		resource_buffer <= 128'h02;
		vreg_value <= 2048'h01;
		sreg_value <= 32'h03;
		imm_value <= 16'h04;
		opcode <= 16'b0000_0010_0001_1000;
		#1
		$display("Out Address = %H", out_addr);
		#20
		$finish;
	end

endmodule
module fsm_otopilot
(
input clk,
input rst_n,
input [15:0] gnss_i,
input [15:0] altimetre_i,
input [7:0] hedef_yukseklik_i,
input yukseklik_bilgisi_i,
output motor_o,
output yesil_led_o,
output kirmizi_led_o
);

localparam S_YUKSEKLIK_BEKLE    = 2'b00;
localparam S_ACIL_DURUS         = 2'b01;
localparam S_UCUS               = 2'b10;

// combinational assignments
reg hedef_yukseklik_hata;
reg motor_ac;
reg [15:0] sensor_fark;
reg [15:0] sensor_ortalama;

// registers
reg [1:0] state;
reg [1:0] hata_sayaci;
reg [7:0] atanan_yukseklik;
reg yesil_led;
reg kirmizi_led;
reg motor;


always @(*) begin
    if (hedef_yukseklik_i < 10 || hedef_yukseklik_i > 100) begin
        hedef_yukseklik_hata = 1'b1;
    end
    else begin
        hedef_yukseklik_hata = 1'b0;
    end

    if (gnss_i > altimetre_i) begin
        sensor_fark = gnss_i - altimetre_i;    
    end
    else begin
        sensor_fark = altimetre_i - gnss_i;
    end

    if (sensor_fark > 9) begin
        sensor_ortalama     = gnss_i;
    end
    else begin
        sensor_ortalama     = (gnss_i + altimetre_i) >> 1;        
    end
    
    motor_ac = 0;
    if (state == S_UCUS) begin
        if (sensor_ortalama >= atanan_yukseklik) begin
            motor_ac = 1'b0;
        end
        else begin
            motor_ac = 1'b1;
        end
    end

end

always @(posedge clk, negedge rst_n) begin
    if (rst_n == 1'b0) begin
        state               <= S_YUKSEKLIK_BEKLE;
        hata_sayaci         <= 2'b00;
        atanan_yukseklik    <= 8'b00000000;
        yesil_led           <= 1'b0;
        kirmizi_led         <= 1'b0;
        motor               <= 1'b0;
    end
    else begin
        case (state)
            S_YUKSEKLIK_BEKLE : begin
                if (yukseklik_bilgisi_i == 1'b1) begin
                    if (hedef_yukseklik_hata == 1'b0) begin
                        atanan_yukseklik    <= hedef_yukseklik_i;
                        state               <= S_UCUS;
                    end
                    else begin
                        if (hata_sayaci == 2'b10) begin
                            state       <= S_ACIL_DURUS;
                            kirmizi_led <= 1'b1;
                        end
                        else begin
                            hata_sayaci <= hata_sayaci + 2'b01;
                            state       <= S_YUKSEKLIK_BEKLE;
                        end
                    end
                end
                else begin
                    state <= S_YUKSEKLIK_BEKLE;
                end
            end
            S_ACIL_DURUS : begin
                //
            end
            S_UCUS : begin
                if (motor_ac == 1'b1) begin
                   motor        <= 1'b1; 
                end
                else begin
                    motor       <= 1'b0;
                    yesil_led   <= 1'b1;
                end
            end

            default: begin
                state <= S_YUKSEKLIK_BEKLE;
            end
        endcase
    end
end

assign motor_o          = motor;
assign yesil_led_o      = yesil_led;
assign kirmizi_led_o    = kirmizi_led;

endmodule
module tb_fsm_otopilot;

reg clk;
reg rst_n;
reg [15:0] gnss_i;
reg [15:0] altimetre_i;
reg [7:0] hedef_yukseklik_i;
reg yukseklik_bilgisi_i;
wire  motor_o;
wire  yesil_led_o;
wire  kirmizi_led_o;

localparam real c_clk_period = 20;

fsm_otopilot DUT
(
.clk                 (clk                ),
.rst_n               (rst_n              ),
.gnss_i              (gnss_i             ),
.altimetre_i         (altimetre_i        ),
.hedef_yukseklik_i   (hedef_yukseklik_i  ),
.yukseklik_bilgisi_i (yukseklik_bilgisi_i),
.motor_o             (motor_o            ),
.yesil_led_o         (yesil_led_o        ),
.kirmizi_led_o       (kirmizi_led_o      )
);

always begin
    // #10 clk = !clk;
    #(c_clk_period/2) clk = !clk;
end

initial begin
clk = 1'b0;
rst_n = 1'b0;
gnss_i = 0;
altimetre_i = 0;
hedef_yukseklik_i = 0;
yukseklik_bilgisi_i = 0;
#40;
rst_n = 1'b1;
#20;
yukseklik_bilgisi_i = 1;
hedef_yukseklik_i = 5;
#20;
hedef_yukseklik_i = 7;
#20;
hedef_yukseklik_i = 9;
#60;
rst_n = 0;
#20;
rst_n = 1;
#20
yukseklik_bilgisi_i = 1;
hedef_yukseklik_i = 110;
#20;
yukseklik_bilgisi_i = 0;
hedef_yukseklik_i = 0;
#60;
rst_n = 0;
#20;
rst_n = 1;
#20
yukseklik_bilgisi_i = 1;
hedef_yukseklik_i = 50;
#20;
gnss_i = 4;
altimetre_i = 6;
#20;
gnss_i = 8;
altimetre_i = 16;
#20;
gnss_i = 20;
altimetre_i = 36;
#20;
gnss_i = 40;
altimetre_i = 46;
#20;
gnss_i = 36;
altimetre_i = 20;
#20;
gnss_i = 46;
altimetre_i = 52;
#20;
gnss_i = 56;
altimetre_i = 72;
#20;
gnss_i = 46;
altimetre_i = 60;
#20;
gnss_i = 36;
altimetre_i = 40;
#20;
gnss_i = 56;
altimetre_i = 60;
#20;
gnss_i = 46;
altimetre_i = 50;
#20;
gnss_i = 45;
altimetre_i = 45;
#40
$finish;
end

endmodule
module soru3 #(parameter c_clkfreq = 100000000) 
(
input clk, 
input rst, 
input signal_i,
output reg signal_o
);

localparam S_ZERO       = 2'b00;
localparam S_ZERO2ONE   = 2'b01;
localparam S_ONE2ZERO   = 2'b10;
localparam S_ONE        = 2'b11;

reg [1:0] state;

reg [$clog2(c_clkfreq/1000)-1:0] timer1ms;
reg timertick1ms;
reg timeren;

always@(posedge clk) begin
    if (rst) begin
        timertick1ms    <= 0;
        timer1ms        <= 0;
    end
    else begin
        if (timeren == 1'b1) begin
            if (timer1ms == (c_clkfreq/1000)-1) begin
                timer1ms        <= 0;
                timertick1ms    <= 1; 
            end
            else begin
                timer1ms        <= timer1ms + 1;
                timertick1ms    <= 0;
            end            
        end
        else begin
            timer1ms        <= 0;
            timertick1ms    <= 0;
        end
    end
end

always@(posedge clk) begin
    if (rst) begin
        state       <= S_ZERO;
        timeren     <= 0;
        signal_o    <= 1'b0;
    end
    else begin

        case (state)
        S_ZERO  : begin
            signal_o    <= 1'b0;
            timeren     <= 0;
            if (signal_i == 1'b1) begin
                state   <= S_ZERO2ONE;
                timeren <= 1;
            end          
        end
        S_ZERO2ONE  : begin
            signal_o    <= 1'b0; 
            if (signal_i == 1'b0) begin
                state   <= S_ZERO;
                timeren <= 0;
            end
            if (timertick1ms) begin
                state   <= S_ONE;
                timeren <= 0;
            end                    
        end
        S_ONE2ZERO  : begin
            signal_o    <= 1'b1; 
            if (signal_i == 1'b1) begin
                state   <= S_ONE;
                timeren <= 0;
            end
            if (timertick1ms) begin
                state   <= S_ZERO;
                timeren <= 0;
            end 
        end
        S_ONE  : begin
            signal_o    <= 1'b1;
            timeren     <= 0;
            if (signal_i == 1'b0) begin
                state   <= S_ONE2ZERO;
                timeren <= 1;
            end                       
        end
        default: begin
                    
                 end
        endcase     

    end
end
    
endmodule
module soru2 #(parameter c_clkfreq = 100000000) 
(
input clk, 
input rst, 
input [9:0] start_pos_i,
input [9:0] dest_pos_i, 
input [7:0] start_vel_i, 
input [7:0] vel_i,
output reg reached_o, 
output reg [9:0] pos_o,
output reg [15:0] dest_reach_second_o
);

reg [$clog2(c_clkfreq)-1:0] timer_clk;
reg [15:0] timer_second;
reg timertick;

reg [9:0] start_pos;
reg [9:0] dest_pos;
reg [7:0] start_vel; 
reg [7:0] vel;

always@(posedge clk, posedge rst) begin
    if (rst) begin
        timertick       <= 0;
        timer_second    <= 0;
        timer_clk       <= 0;
    end
    else begin
        if (timer_clk == c_clkfreq-1) begin
            timertick       <= 1'b1;
            timer_clk       <= 0;
            timer_second    <= timer_second + 1;
        end
        else begin
            timertick       <= 1'b0;
            timer_clk       <= timer_clk + 1;
        end
    end
end

always@(posedge clk, posedge rst) begin
    if (rst) begin
        start_pos           <= start_pos_i;
        dest_pos            <= dest_pos_i;
        start_vel           <= start_vel_i;
        reached_o           <= 1'b0;
        pos_o               <= start_pos_i;
        dest_reach_second_o <= 0;
        vel                 <= 0;
    end
    else begin
        if (timertick == 1'b1) begin
            vel <= vel_i;
            if (timer_second == 1) begin
                pos_o   <= start_pos + start_vel;
            end
            else begin
                pos_o   <= pos_o + vel;
            end
        end
        if ((pos_o >= dest_pos) && (reached_o == 1'b0)) begin
            reached_o           <= 1'b1;
            dest_reach_second_o <= timer_second;
        end
    end
end

endmodule
module soru1 
(
input [4:0] number1_i,
input [4:0] number2_i,
output reg [8:0] mult_o
);

reg [7:0] num1, num2, num3, num4;

//        - - - -
//        - - - -
//        ________
//        - - - -
//      - - - - 0
//    - - - - 0 0
//  - - - - 0 0 0
// _______________

always@(*) begin
    mult_o[8] = number1_i[4] ^ number2_i[4]; 
end

always @(*) begin

    num1 = 0;
    num2 = 0;
    num3 = 0;
    num4 = 0;

    if (number2_i[0] == 1'b1) begin
        num1[3:0] = number1_i[3:0];
    end
    if (number2_i[1] == 1'b1) begin
        num2[4:1] = number1_i[3:0];
    end
    if (number2_i[2] == 1'b1) begin
        num3[5:2] = number1_i[3:0];
    end
    if (number2_i[3] == 1'b1) begin
        num4[6:3] = number1_i[3:0];
    end

    mult_o[7:0] = num1 + num2 + num3 + num4;

end

endmodule
module fsm_mealy_1always
(
input x_i,
input rst_n,
input clk,
output y_o
);

reg A_reg, B_reg;

always @(posedge clk, negedge rst_n) begin
    if (rst_n == 1'b0) begin
        A_reg <= 1'b0;
        B_reg <= 1'b0;
    end
    else begin
        A_reg <= (A_reg & x_i) | (B_reg & x_i);
        B_reg <= (!A_reg & x_i);
    end
end

assign y_o = (A_reg | B_reg) & !x_i;


endmodule
module counter_2bit
(
input clk,
input rst_n,
output [1:0] count_o
);

reg [1:0] count;

always @(posedge clk, negedge rst_n) begin
    if (rst_n == 1'b0) begin
        count <= 2'b00;
    end else begin
        count <= count + 1;
    end
end

assign count_o = count;

endmodule
module fsm_mealy_3always
(
input x_i,
input rst_n,
input clk,
output y_o
);

reg y;
reg A_reg, B_reg, A_next, B_next;

// always block #1 for assigning D to Q
always @(posedge clk, negedge rst_n) begin
    if (rst_n == 1'b0) begin
        A_reg <= 1'b0;
        B_reg <= 1'b0;
    end
    else begin
        A_reg <= A_next;
        B_reg <= B_next;
    end
end

// always block #2 for evaluating next state
always @(*) begin
    A_next = (A_reg & x_i) | (B_reg & x_i);
    B_next = (!A_reg & x_i);
end

// always block #3 for evaluating output
always @(*) begin
    y = (A_reg | B_reg) & !x_i;
end

assign y_o = y;

endmodule
module fsm_mealy_param
(
input x_i,
input rst_n,
input clk,
output y_o
);

localparam S0 = 2'b00;
localparam S1 = 2'b01;
localparam S2 = 2'b10;
localparam S3 = 2'b11;

reg y;
reg [1:0] state;

always @(posedge clk, negedge rst_n) begin
    if (rst_n == 1'b0) begin
        state <= S0;
    end
    else begin
        case (state)
            S0 : begin
                if (x_i == 1'b0) begin
                    state <= S0;
                end
                else begin
                    state <= S1;
                end
            end 
            S1 : begin
                if (x_i == 1'b0) begin
                    state <= S0;
                end
                else begin
                    state <= S3;
                end                
            end
            S2 : begin
                if (x_i == 1'b0) begin
                    state <= S0;
                end
                else begin
                    state <= S2;
                end                 
            end
            S3 : begin
                if (x_i == 1'b0) begin
                    state <= S0;
                end
                else begin
                    state <= S2;
                end                  
            end
            default : begin
                state <= S0;
            end 
        endcase
    end
end

always @(*) begin
   case (state)
    S0 : begin
        if (x_i == 1'b0) begin
            y = 1'b0;
        end
        else begin
            y = 1'b0;
        end 
    end 
    S1 : begin
        if (x_i == 1'b0) begin
            y = 1'b1;
        end
        else begin
            y = 1'b0;
        end         
    end
    S2 : begin
        if (x_i == 1'b0) begin
            y = 1'b1;
        end
        else begin
            y = 1'b0;
        end         
    end
    S3 : begin
        if (x_i == 1'b0) begin
            y = 1'b1;
        end
        else begin
            y = 1'b0;
        end           
    end
    default : begin
        
    end 
   endcase
end

assign y_o = y;

endmodule
module counter_param
#(
parameter N = 8
)
(
input clk,
input rst_n,
output [N-1:0] count_o
);

reg [N-1:0] count;

always @(posedge clk, negedge rst_n) begin
    if (rst_n == 1'b0) begin
        count <= {N{1'b0}};
    end else begin
        count <= count + 1;
    end
end

assign count_o = count;

endmodule
module add_sub_8bit_initval
(
input [7:0] in0_i,
input [7:0] in1_i,
input op_i,
input clk,
output [7:0] result_o
);

// only works on SRAM based FPGAs
reg [7:0] result = 8'b00000000;

always @(posedge clk) begin

    if (op_i == 1'b0) begin
        result <= in0_i + in1_i;
    end
    else begin
        result <= in0_i - in1_i;
    end        

end

assign result_o = result; 

endmodule
module reg_param
#(
parameter N=32
)
(
input [N-1:0] d_i,
input rst_n,
input clk,
output [N-1:0] q_o
);

reg [N-1:0] q;

always @(posedge clk or negedge rst_n) begin
    if (rst_n == 1'b0) begin
        q <= {N{1'b0}};
    end
    else begin
        q <= d_i;
    end
end

assign q_o = q;

endmodule
module reg4
(
input [3:0] d_i,
input rst_n,
input clk,
output [3:0] q_o
);

reg [3:0] q;

always @(posedge clk or negedge rst_n) begin
    if (rst_n == 1'b0) begin
        q <= 4'b0000;
    end
    else begin
        q <= d_i;
    end
end

assign q_o = q;

endmodule
module d_ff
(
input d_i,
input clk,
output q_o
);

reg q;

always@(posedge clk) begin
    q <= d_i;
end

assign q_o = q;

endmodule
module add_sub_8bit_sync
(
input [7:0] in0_i,
input [7:0] in1_i,
input op_i,
input clk,
input rst_n,
output [7:0] result_o
);

reg [7:0] result;

always @(posedge clk, negedge rst_n) begin
    if (rst_n == 1'b0) begin
        result <= 8'b00000000;
    end
    else begin
        if (op_i == 1'b0) begin
            result <= in0_i + in1_i;
        end
        else begin
            result <= in0_i - in1_i;
        end        
    end

end

assign result_o = result; 

endmodule
module reg8
(
input [7:0] d_i,
input rst_n,
input clk,
output [7:0] q_o
);

reg [7:0] q;

always @(posedge clk or negedge rst_n) begin
    if (rst_n == 1'b0) begin
        q <= 8'b00000000;
    end
    else begin
        q <= d_i;
    end
end

assign q_o = q;

endmodule
module d_ff_rst
(
input d_i,
input rst_n,    // Active-low reset
input clk,
output q_o
);

reg q;

// always@(posedge clk) begin // Synchronous reset
always@(posedge clk, negedge rst_n) begin   // Asynchronous reset
    if (rst_n == 1'b0) begin
        q <= 1'b0;
    end
    else begin
        q <= d_i;    
    end    
end

assign q_o = q;

endmodule
module d_latch
(
input d_i,
input clk,
output q_o
);

reg q;

always@(clk,d_i) begin
    if (clk == 1'b1) begin
        q <= d_i;
    end
end

assign q_o = q;

endmodule
module tb_binary_adder_2bit;

reg [1:0] a_i,b_i;  // define inputs of DUT as reg
reg cin_i;
wire [1:0] s_o;     // define outputs of DUT as wire
wire cout_o;

binary_adder_2bit DUT   // Design Under Test
(
.a_i    (a_i   ),
.b_i    (b_i   ),
.cin_i  (cin_i ),
.s_o    (s_o   ),
.cout_o (cout_o)
);

initial begin
    a_i     = 2'b00;
    b_i     = 2'b00;
    cin_i   = 1'b0;
    #10;
    a_i     = 2'b01;
    b_i     = 2'b10;
    cin_i   = 1'b1;
    #10;
    a_i     = 2'b11;
    b_i     = 2'b11;
    cin_i   = 1'b1;
    #10;
    a_i     = 2'b11;
    b_i     = 2'b11;
    cin_i   = 1'b0;
    #10;
    a_i     = 2'b01;
    b_i     = 2'b01;
    cin_i   = 1'b1;
    #10;
    $finish;
end

endmodule
module half_adder
(
input a_i,
input b_i,
output s_o,
output cout_o
);

xor G1 (s_o,a_i,b_i);
and G2 (cout_o,a_i,b_i);


endmodule
module ornek1
(
input x,
input y,
input z,
output F1
);

wire y_not;
wire y_not_and_z;

not G1 (y_not,y);
and G2 (y_not_and_z,y_not,z);
or G3 (F1,x,y_not_and_z);

endmodule
module ornek3
(
input x,
input y,
input z,
output F2
);

wire x_not;
wire y_not;
wire and1_out;
wire and2_out;

not G1 (x_not,x);
not G2 (y_not,y);
and G3 (and1_out,x,y_not);
and G4 (and2_out,x_not,z);
or G5 (F2,and1_out,and2_out);

endmodule
module binary_adder_2bit
(
input [1:0] a_i,
input [1:0] b_i,
input cin_i,
output [1:0] s_o,
output cout_o
);

wire cout_fa1;

full_adder_hier FA1 
(
.a_i    (a_i[0]),
.b_i    (b_i[0]),
.cin_i  (cin_i),
.s_o    (s_o[0]),
.cout_o (cout_fa)
);

full_adder_hier FA2 
(
.a_i    (a_i[1]),
.b_i    (b_i[1]),
.cin_i  (cout_fa),
.s_o    (s_o[1]),
.cout_o (cout_o)
);

endmodule
module ornek2
(
input x,
input y,
input z,
output F2
);

wire x_not;
wire y_not;
wire and1_out;
wire and2_out;
wire and3_out;

not G1 (x_not,x);
not G2 (y_not,y);
and G3 (and1_out,x_not,y_not,z);
and G4 (and2_out,x_not,y,z);
and G5 (and3_out,x,y_not);
or G6 (F2,and1_out,and2_out,and3_out);

endmodule
module full_adder
(
input a_i,
input b_i,
input cin_i,
output s_o,
output cout_o
);

wire and1, and2, and3;

xor G1 (s_o,a_i,b_i,cin_i);
and G2 (and1,a_i,b_i);
and G3 (and2,a_i,cin_i);
and G4 (and3,b_i,cin_i);
or G5 (cout_o,and1,and2,and3);

endmodule
module full_adder_hier
(
input a_i,
input b_i,
input cin_i,
output s_o,
output cout_o
);

wire ha1_s, ha1_cout, ha2_cout;

half_adder HA1 
(
.a_i    (a_i),
.b_i    (b_i),
.s_o    (ha1_s),
.cout_o (ha1_cout)
);

half_adder HA2 
(
.a_i    (ha1_s),
.b_i    (cin_i),
.s_o    (s_o),
.cout_o (ha2_cout)
);

or G1 (cout_o,ha2_cout,ha1_cout);

endmodule
module pipeline
(
input clk,
input rst_n,
input [7:0] a_i,
input [7:0] b_i,
input [7:0] c_i,
input [7:0] d_i,
input [7:0] ctrl1_i,
input [7:0] ctrl2_i,
output [9:0] e_o,
output [9:0] f_o
);

reg [9:0] e,f;
reg [7:0] a,b,c,d;
reg [7:0] ctrl1,ctrl2;
reg [8:0] ctrl_result;
reg gr,sm;

always @(*) begin

    if (ctrl1 > ctrl2)
        ctrl_result = ctrl1 - ctrl2;
    else
        ctrl_result = ctrl1 | ctrl2;
    
    gr = 0;
    sm = 0;
    if (ctrl_result > 9'd355) begin
        gr = 1;
    end
    else if (ctrl_result < 9'd355) begin
        sm = 1;
    end

end

always @(posedge clk, negedge rst_n) begin
    if (rst_n == 1'b0) begin
        a       <= {8{1'b0}};
        b       <= {8{1'b0}};
        c       <= {8{1'b0}};
        d       <= {8{1'b0}};
        ctrl1   <= {8{1'b0}};
        ctrl2   <= {8{1'b0}};
        e       <= {10{1'b0}};
        f       <= {10{1'b0}};        
    end
    else begin
        a       <= a_i;
        b       <= b_i;
        c       <= c_i;
        d       <= d_i;
        ctrl1   <= ctrl1_i;
        ctrl2   <= ctrl2_i;
        if (gr) begin
            e   <= (a + b) + (c + d);
            f   <= (a + b) - (c + d);
        end
        else if (sm) begin
            e   <= (a - b) + (c - d);
            f   <= (-a + b) + (-c + d);
        end
        else begin
            e   <= {2'b00, (a ^ b) | (c ^ d)};
            f   <= {2'b11, (a & b) ^ (c & d)};
        end
    end
    
end

assign e_o = e;
assign f_o = f;

endmodule
module fsm_ornek3
(
input clk,
input rst_n,
input signal_i,
output detect_o
);

localparam tetik_bekle  = 2'b00;
localparam tetik_alindi = 2'b01;
localparam bekle        = 2'b10;

reg [1:0] state;
reg detect;

always @(posedge clk, negedge rst_n) begin
    if (rst_n == 1'b0) begin
        state <= tetik_bekle;
    end
    else begin
        case (state)
            tetik_bekle : begin
                if (signal_i == 1'b0) begin
                    state <= tetik_bekle;
                end
                else begin
                    state <= tetik_alindi;
                end
            end 
            tetik_alindi : begin
                state <= bekle;             
            end
            bekle : begin
                if (signal_i == 1'b0) begin
                    state <= tetik_bekle;
                end
                else begin
                    state <= bekle;
                end
            end             
            default: begin
                state <= tetik_bekle;
            end
        endcase
    end
end

always@(*) begin
    case (state)
        tetik_bekle : begin
            detect = 1'b0;
        end 
        tetik_alindi : begin
            detect = 1'b1;             
        end
        bekle : begin
            detect = 1'b0;
        end             
        default: begin
            detect = 1'b0;
        end
    endcase
end

assign detect_o = detect;

endmodule
module fsm_ornek2
(
input clk,
input rst_n,
input signal_i,
output detect_o
);

localparam tetik_bekle  = 1'b0;
localparam tetik_alindi = 1'b1;

reg state;
reg detect;

always @(posedge clk, negedge rst_n) begin
    if (rst_n == 1'b0) begin
        state <= tetik_bekle;
    end
    else begin
        case (state)
            tetik_bekle : begin
                if (signal_i == 1'b0) begin
                    state <= tetik_bekle;
                end
                else begin
                    state <= tetik_alindi;
                end
            end 
            tetik_alindi : begin
                if (signal_i == 1'b0) begin
                    state <= tetik_bekle;
                end
                else begin
                    state <= tetik_alindi;
                end                
            end
            default: begin
                state <= tetik_bekle;
            end
        endcase
    end
end

always@(*) begin
    if (state == tetik_bekle) begin
        if (signal_i == 1'b0) begin
            detect = 1'b0;
        end
        else begin
            detect = 1'b1;
        end
    end
    else begin
        detect = 1'b0;
    end
end

assign detect_o = detect;

endmodule
module fsm_ornek1
(
input clk,
input rst_n,
input anahtar_i,
output kirmizi_o,
output yesil_o
);

localparam kat0 = 1'b0;
localparam kat1 = 1'b1;

reg kat;
reg kirmizi, yesil;

always @(posedge clk, negedge rst_n) begin
    if (rst_n == 1'b0) begin
        kat <= kat0;
    end
    else begin
        case (kat)
            kat0 : begin
                if (anahtar_i == 1'b0) begin
                    kat <= kat0;
                end
                else begin
                    kat <= kat1;
                end
            end 
            kat1 : begin
                if (anahtar_i == 1'b0) begin
                    kat <= kat0;
                end
                else begin
                    kat <= kat1;
                end                
            end
            default: begin
                kat <= kat0;
            end
        endcase
    end
end

always@(*) begin
    if (kat == kat0) begin
        kirmizi = 1'b1;
        yesil   = 1'b0;
    end
    else begin
        kirmizi = 1'b0;
        yesil   = 1'b1;        
    end
end

assign kirmizi_o = kirmizi; 
assign yesil_o = yesil; 

endmodule
module fsm_ornek4
(
input clk,
input rst_n,
input ta_i,
input tb_i,
output [1:0] la_o,
output [1:0] lb_o
);

localparam S0  = 2'b00;
localparam S1  = 2'b01;
localparam S2  = 2'b10;
localparam S3  = 2'b11;

localparam green    = 2'b00;
localparam yellow   = 2'b01;
localparam red      = 2'b10;

reg [1:0] la,lb;
reg [1:0] state;

always @(posedge clk, negedge rst_n) begin
    if (rst_n == 1'b0) begin
        state <= S0;
    end
    else begin
        case (state)
            S0 : begin
                if (ta_i == 1'b1) begin
                    state <= S0;
                end
                else begin
                    state <= S1;
                end
            end 
            S1 : begin
                state <= S2;             
            end
            S2 : begin
                if (tb_i == 1'b0) begin
                    state <= S3;
                end
                else begin
                    state <= S2;
                end
            end
            S3 : begin
                state <= S0; 
            end                         
            default: begin
                state <= S0;
            end
        endcase
    end
end

always@(*) begin
    case (state)
        S0 : begin
            la = green;
            lb = red;
        end 
        S1 : begin
            la = yellow;
            lb = red;
        end
        S2 : begin
            la = red;
            lb = green;
        end
        S3 : begin
            la = red;
            lb = yellow;
        end             
        default: begin
            la = green;
            lb = red;
        end
    endcase
end

assign la_o = la;
assign lb_o = lb;

endmodule
module adder
(
input [3:0] a_i,
input [3:0] b_i,
input [3:0] c_i,
input [3:0] d_i,
input [3:0] e_i,
input [3:0] f_i,
input [3:0] g_i,
input [3:0] h_i,
input [3:0] i_i,
input [3:0] j_i,
input [3:0] k_i,
input [3:0] l_i,
input [3:0] m_i,
input [3:0] n_i,
input [3:0] o_i,
input [3:0] p_i,
output [7:0] sum_o
);

reg [4:0] ab,cd,ef,gh,ij,kl,mn,op;
reg [5:0] sum1,sum2,sum3,sum4;
reg [6:0] sum5, sum6;
reg [7:0] sum7;

always @(*) begin
    
   ab = a_i + b_i;
   cd = c_i + d_i;
   ef = e_i + f_i;
   gh = g_i + h_i;
   ij = i_i + j_i;
   kl = k_i + l_i;
   mn = m_i + n_i;
   op = o_i + p_i;

   sum1 = ab + cd;
   sum2 = ef + gh;
   sum3 = ij + kl;
   sum4 = mn + op;

   sum5 = sum1 + sum2;
   sum6 = sum3 + sum4;

   sum7 = sum5 + sum6;

end

assign sum_o = sum7;

endmodule
module adder_pipe
(
input clk,
input rst_n,
input [3:0] a_i,
input [3:0] b_i,
input [3:0] c_i,
input [3:0] d_i,
input [3:0] e_i,
input [3:0] f_i,
input [3:0] g_i,
input [3:0] h_i,
input [3:0] i_i,
input [3:0] j_i,
input [3:0] k_i,
input [3:0] l_i,
input [3:0] m_i,
input [3:0] n_i,
input [3:0] o_i,
input [3:0] p_i,
output [7:0] sum_o
);

// input regs
reg [3:0] a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p;

reg [4:0] ab,cd,ef,gh,ij,kl,mn,op;
reg [5:0] sum1,sum2,sum3,sum4;
reg [6:0] sum5, sum6;
reg [7:0] sum7;

always @(posedge clk) begin
    if (!rst_n) begin
        a       <= 0;
        b       <= 0;
        c       <= 0;
        d       <= 0;
        e       <= 0;
        f       <= 0;
        g       <= 0;
        h       <= 0;
        i       <= 0;
        j       <= 0;
        k       <= 0;
        l       <= 0;
        m       <= 0;
        n       <= 0;
        o       <= 0;
        p       <= 0;   
        ab      <= 0;
        cd      <= 0;
        ef      <= 0;
        gh      <= 0;
        ij      <= 0;
        kl      <= 0;
        mn      <= 0;
        op      <= 0;
        sum1    <= 0;     
        sum2    <= 0;     
        sum3    <= 0;     
        sum4    <= 0;     
        sum5    <= 0;     
        sum6    <= 0;     
        sum7    <= 0;     
    end
    else begin
        a       <= a_i;
        b       <= b_i;
        c       <= c_i;
        d       <= d_i;
        e       <= e_i;
        f       <= f_i;
        g       <= g_i;
        h       <= h_i;
        i       <= i_i;
        j       <= j_i;
        k       <= k_i;
        l       <= l_i;
        m       <= m_i;
        n       <= n_i;
        o       <= o_i;
        p       <= p_i;

        ab      <= a + b;
        cd      <= c + d;
        ef      <= e + f;
        gh      <= g + h;
        ij      <= i + j;
        kl      <= k + l;
        mn      <= m + n;
        op      <= o + p;
     
        sum1    <= ab + cd;
        sum2    <= ef + gh;
        sum3    <= ij + kl;
        sum4    <= mn + op;
     
        sum5    <= sum1 + sum2;
        sum6    <= sum3 + sum4;
     
        sum7    <= sum5 + sum6;
    end
end

assign sum_o = sum7;

endmodule
module ram
#(
parameter RAM_WIDTH = 8,                    // Specify RAM data width
parameter RAM_DEPTH = 4                     // Specify RAM depth (number of entries)
) 
(
input clk,                               // Clock
input we_i,                              // Write enable
input [clogb2(RAM_DEPTH-1)-1:0] addr_i,  // Address bus, width determined from RAM_DEPTH
input [RAM_WIDTH-1:0] din_i,             // RAM input data
output [RAM_WIDTH-1:0] dout_o            // RAM output data
);

// block, distributed, registers, auto
(* ram_style="auto" *)

reg [RAM_WIDTH-1:0] BRAM [RAM_DEPTH-1:0];
reg [RAM_WIDTH-1:0] ram_data = {RAM_WIDTH{1'b0}};

always @(posedge clk) begin
    // write
    if (we_i == 1'b1) begin
        BRAM[addr_i]    <= din_i;        
    end
    // read
    ram_data        <= BRAM[addr_i];
end

assign dout_o = ram_data;

//  The following function calculates the address width based on specified RAM depth
function integer clogb2;
input integer depth;
  for (clogb2=0; depth>0; clogb2=clogb2+1)
    depth = depth >> 1;
endfunction

endmodule
module ram_ornek
#(
parameter RAM_WIDTH = 8,                    
parameter RAM_DEPTH = 4096                  
) 
(
input clk,                                  
input rst_n,
input yaz_komut_i,
input [RAM_WIDTH-1:0] yaz_veri_i,
input [clogb2(RAM_DEPTH-1)-1:0] yaz_adres_i,
input oku_komut_i,
output [RAM_WIDTH-1:0] oku_veri_o,
input [clogb2(RAM_DEPTH-1)-1:0] oku_adres_i,
output yaz_hata_o,                              
output oku_hata_o
);

reg we;  
reg [clogb2(RAM_DEPTH-1)-1:0] addr;
reg [RAM_WIDTH-1:0] din;
wire [RAM_WIDTH-1:0] dout;

reg yaz_komut_ff;
reg oku_komut_ff;
reg yaz_hata;
reg oku_hata;

ram
#(
.RAM_WIDTH(RAM_WIDTH),                    
.RAM_DEPTH(RAM_DEPTH)                     
)
ram_i
(
.clk    (clk),
.we_i   (we),
.addr_i (addr),
.din_i  (din),
.dout_o (dout) 
);

always @(posedge clk, negedge rst_n) begin

    if (rst_n == 1'b0) begin
        we      <= 1'b0;
        addr    <= {clogb2(RAM_DEPTH-1){1'b0}};
        din     <= {RAM_WIDTH{1'b0}};
        yaz_komut_ff    <= 1'b0;
        oku_komut_ff    <= 1'b0;
        yaz_hata        <= 1'b0;
        oku_hata        <= 1'b0;
    end
    else begin

        yaz_hata    <= 1'b0;
        oku_hata    <= 1'b0;
        we          <= 1'b0;

        yaz_komut_ff    <= yaz_komut_i;
        oku_komut_ff    <= oku_komut_i;

        if (yaz_komut_ff == 1'b0 && yaz_komut_i == 1'b1) begin
            if (yaz_adres_i < 12'h800) begin
                yaz_hata    <= 1'b1;
            end
            else begin
                we      <= 1'b1;
                addr    <= yaz_adres_i;
                din     <= yaz_veri_i;
            end
        end
        else if (oku_komut_ff == 1'b0 && oku_komut_i == 1'b1) begin
            if (oku_adres_i < 12'h400 || oku_adres_i > 12'h7FF) begin
                oku_hata    <= 1'b1;
            end
            else begin
                addr    <= oku_adres_i;
            end
        end
    end
    
end

assign oku_veri_o = dout;
assign yaz_hata_o = yaz_hata;
assign oku_hata_o = oku_hata;

//  The following function calculates the address width based on specified RAM depth
function integer clogb2;
input integer depth;
  for (clogb2=0; depth>0; clogb2=clogb2+1)
    depth = depth >> 1;
endfunction

endmodule
module tb_ram_ornek;

parameter RAM_WIDTH = 8;              
parameter RAM_DEPTH = 4096;                  

reg clk                                     ;                                  
reg rst_n                                   ;
reg yaz_komut_i                             ;
reg [RAM_WIDTH-1:0] yaz_veri_i              ;
reg [clogb2(RAM_DEPTH-1)-1:0] yaz_adres_i   ;
reg oku_komut_i                             ;
wire [RAM_WIDTH-1:0] oku_veri_o             ;
reg [clogb2(RAM_DEPTH-1)-1:0] oku_adres_i   ;
wire yaz_hata_o                             ;                              
wire oku_hata_o                             ;

localparam real c_clk_period = 10;

ram_ornek 
#(
.RAM_WIDTH(RAM_WIDTH),                    
.RAM_DEPTH(RAM_DEPTH)                     
)
DUT
(
.clk            (clk        ),                                          
.rst_n          (rst_n      ),     
.yaz_komut_i    (yaz_komut_i),        
.yaz_veri_i     (yaz_veri_i ),
.yaz_adres_i    (yaz_adres_i),    
.oku_komut_i    (oku_komut_i),    
.oku_veri_o     (oku_veri_o ),
.oku_adres_i    (oku_adres_i),    
.yaz_hata_o     (yaz_hata_o ),                
.oku_hata_o     (oku_hata_o )
);

always begin
    #(c_clk_period/2) clk = !clk;
end

initial begin
clk = 1'b0;
rst_n = 1'b0;
yaz_komut_i = 0;
yaz_veri_i = 0;
yaz_adres_i = 0;
oku_komut_i = 0;
oku_adres_i = 0;
#40;
rst_n = 1'b1;
#20;
oku_adres_i = 12'h010;
oku_komut_i = 1'b1;
#20;
oku_adres_i = 12'h500;
#10;
oku_komut_i = 1'b0;
#10;
oku_komut_i = 1'b1;
#10;
oku_adres_i = 12'h804;
#10;
oku_komut_i = 1'b0;
#10;
oku_komut_i = 1'b1;
#20;
oku_komut_i = 1'b0;
yaz_adres_i = 12'h004;
yaz_veri_i = 8'hBA;
#10;
yaz_komut_i = 1'b1;
#10;
yaz_komut_i = 1'b0;
yaz_adres_i = 12'h404;
#10;
yaz_komut_i = 1'b1;
#10;
yaz_adres_i = 12'h804;
yaz_komut_i = 1'b0;
#10;
yaz_komut_i = 1'b1;
#20;
$finish;
end

//  The following function calculates the address width based on specified RAM depth
function integer clogb2;
input integer depth;
  for (clogb2=0; depth>0; clogb2=clogb2+1)
    depth = depth >> 1;
endfunction

endmodule
module tb_add_sub_8bit;

reg [7:0] in0_i, in1_i;
reg op_i;
wire [7:0] result_o;

add_sub_8bit DUT
(
.in0_i      (in0_i   ),
.in1_i      (in1_i   ),
.op_i       (op_i    ),
.result_o   (result_o)
);

initial begin
in0_i = 8'd10;
in1_i = 8'd55;
op_i = 1'b0;
#10;
in0_i = 8'd10;
in1_i = 8'd55;
op_i = 1'b1;
#10;
in0_i = 8'd55;
in1_i = 8'd10;
op_i = 1'b1;
#10;
in0_i = 8'd55;
in1_i = 8'd10;
op_i = 1'b0;
#10;
in0_i = 8'd100;
in1_i = 8'd55;
op_i = 1'b0;
#10;
in0_i = 8'd100;
in1_i = 8'd55;
op_i = 1'b1;
#10;
in0_i = 8'd55;
in1_i = 8'd100;
op_i = 1'b1;
#10;
$finish;    
end

endmodule
module mux_2_1
(
input i0_i,
input i1_i,
input sel_i,
output out_o
);

wire not1, and1, and2;

not G1 (not1,sel_i);
and G2 (and1,i0_i,not1);
and G3 (and2,i1_i,sel_i);
or G4 (out_o,and1,and2);

endmodule
module binary_adder_2bit_assign
(
input [1:0] a_i,
input [1:0] b_i,
input cin_i,
output [1:0] s_o,
output cout_o
);

assign {cout_o,s_o} = a_i + b_i + cin_i;

endmodule
module decoder_2_4_behav
(
input [1:0] a_i,
output [3:0] d_o
);

reg [3:0] d;

always @(a_i) begin
    case (a_i)
        2'b00   : d = 4'b0001;  
        2'b01   : d = 4'b0010;  
        2'b10   : d = 4'b0100;  
        default : d = 4'b1000;
    endcase
end

assign d_o = d;

endmodule
module half_adder_behav
(
input wire a_i,
input wire b_i,
output reg s_o,
output reg cout_o
);

always @(a_i,b_i) begin
    {cout_o,s_o} = a_i + b_i;
end

endmodule
module mux_2_1_assign
(
input i0_i,
input i1_i,
input sel_i,
output out_o
);

// not G1 (not1,sel_i);
// and G2 (and1,i0_i,not1);
// and G3 (and2,i1_i,sel_i);
// or G4 (out_o,and1,and2);

assign out_o = (sel_i == 1'b0) ? i0_i : i1_i;

endmodule
module decoder_2_4
(
input [1:0] a_i,
output [3:0] d_o
);


assign d_o =    (a_i == 2'b00) ? 4'b0001 :
                (a_i == 2'b01) ? 4'b0010 :
                (a_i == 2'b10) ? 4'b0100 :
                                 4'b1000;


endmodule
module mux_4_1_8bit_assign
(
input [7:0] i0_i,
input [7:0] i1_i,
input [7:0] i2_i,
input [7:0] i3_i,
input [1:0] sel_i,
output [7:0] out_o
);

assign out_o =  (sel_i[0] == 1'b0) ? 
                (sel_i[1] == 1'b0) ? i0_i : i2_i :
                (sel_i[1] == 1'b0) ? i1_i : i3_i;

//assign out_o =  (sel_i == 2'b00) ? i0_i : 
//                (sel_i == 2'b01) ? i1_i :
//                (sel_i == 2'b10) ? i2_i :
//                                   i3_i;                

endmodule
module mux_4_1
(
input i0_i,
input i1_i,
input i2_i,
input i3_i,
input sel0_i,
input sel1_i,
output out_o
);

wire muxout1, muxout2;

mux_2_1 MUX1 
(
.i0_i   (i0_i),
.i1_i   (i1_i),
.sel_i  (sel0_i),
.out_o  (muxout1)
);

mux_2_1 MUX2 
(
.i0_i   (i2_i),
.i1_i   (i3_i),
.sel_i  (sel0_i),
.out_o  (muxout2)
);

mux_2_1 MUX3
(
.i0_i   (muxout1),
.i1_i   (muxout2),
.sel_i  (sel1_i),
.out_o  (out_o)
);

endmodule
module full_adder_assign
(
input a_i,
input b_i,
input cin_i,
output s_o,
output cout_o
);

// xor G1 (s_o,a_i,b_i,cin_i);
// and G2 (and1,a_i,b_i);
// and G3 (and2,a_i,cin_i);
// and G4 (and3,b_i,cin_i);
// or G5 (cout_o,and1,and2,and3);

assign {cout_o,s_o} = a_i + b_i + cin_i;

endmodule
module mux_2_1_behav
(
input i0_i,
input i1_i,
input sel_i,
output out_o
);

reg out;

always@(i0_i or i1_i or sel_i) begin
    if (sel_i == 1'b0) begin
        out = i0_i;
    end
    else begin
        out = i1_i;
    end
end

assign out_o = out;

endmodule
module tb_decoder_2_4;

reg [1:0] a_i;
wire [3:0] d_o;

decoder_2_4 DUT
(
.a_i (a_i),
.d_o (d_o)
);

initial begin
a_i = 2'b00;
#10;
a_i = 2'b01;
#10;
a_i = 2'b10;
#10;
a_i = 2'b11;
#10;
$finish;
end

endmodule
module mux_4_1_assign
(
input i0_i,
input i1_i,
input i2_i,
input i3_i,
input sel0_i,
input sel1_i,
output out_o
);

assign out_o =  (sel0_i == 1'b0) ? 
                (sel1_i == 1'b0) ? i0_i : i2_i :
                (sel1_i == 1'b0) ? i1_i : i3_i;


endmodule
module add_sub_8bit
(
input [7:0] in0_i,
input [7:0] in1_i,
input op_i,
output [7:0] result_o
);

reg [7:0] result;

always @(in0_i, in1_i, op_i) begin
    if (op_i == 1'b0) begin
        result = in0_i + in1_i;
    end
    else begin
        result = in0_i - in1_i;
    end
end

assign result_o = result; 

endmodule
module half_adder_assign
(
input a_i,
input b_i,
output s_o,
output cout_o
);

// xor G1 (s_o,a_i,b_i);
// and G2 (cout_o,a_i,b_i);

assign s_o      = a_i ^ b_i; 
assign cout_o   = a_i & b_i; 

endmodule
module slowMul(input clk,
               input         rst,
               input         req,
               
               input [31:0]  p0,
               input [31:0]  p1,
               output        ack,
               output [31:0] out);

    mul32x32_fsm S(.clk(clk),
                   .rst(rst),
                   .req(req),
                   .ack(ack),
                   .p0(p0),
                   .p1(p1),
                   .out(out));

endmodule
module ledwriter (input clk,
                  input rst,

                  output reg [7:0] LED,
                  
                  input [31:0]     addr_b,
                  input [31:0]     data_b_in,
                  input [31:0]     data_b_we);

   always @(posedge clk)
     if (~rst) begin
        LED <= 0;
     end else begin
        if (addr_b == 65540)
          LED <= data_b_in[7:0];
     end

endmodule
module socram(input clk,
              input             rst,

              output reg [31:0] data_a,
              input [31:0]      addr_a,
              
              output reg [31:0] data_b,
              output reg        strobe_b,
              input [31:0]      addr_b,
              input [31:0]      data_b_in,
              input [31:0]      data_b_we);

   parameter RAM_DEPTH = `C2_RAM_DEPTH;
   parameter INIT_FILE = `STR(`INIT_FILE_PATH);
   
   reg [31:0]                   mem [0:RAM_DEPTH-1];
   
   initial begin
      if (INIT_FILE != "")
         $readmemh(INIT_FILE, mem);
   end
   
   always @(posedge clk)
     begin
        if (data_b_we & (addr_b[31:16] == 0)) begin
           mem[addr_b] <= data_b_in;
        end
        data_a <= mem[addr_a];
        data_b <= mem[addr_b];
        strobe_b <= (addr_b[31:16] == 0);
     end
   
endmodule // socram
module mul16x16 (input [15:0]      a,
                 input [15:0]      b,
                 output [31:0] o);

   assign o = a * b;
   
endmodule // mul16x16
module hls_Mul(input clk,
               input reset,

               input [31:0]  p0,
               input [31:0]  p1,
               output [31:0] out);

   wire [15:0]               a = p0r[31:16];
   wire [15:0]               b = p0r[15:0];
   wire [15:0]               c = p1r[31:16];
   wire [15:0]               d = p1r[15:0];

   wire [15:0]               ad = a * d;
   wire [15:0]               bc = b * c;
   wire [31:0]               bd = b * d;

   reg [15:0]                adr;
   
   reg [31:0]                p0r;
   reg [31:0]                p1r;
   reg [31:0]                t1;
   reg [31:0]                t2;
   assign out = t2;
   

   always @(posedge clk)
     begin
        p0r <= p0; p1r <= p1;
        t1 <= bd + {bc[15:0], 16'b0}; adr <= ad[15:0];
        t2 <= t1 + {adr[15:0], 16'b0};
     end
   
   
endmodule // hls_Mul
module hls_MulFSM(input clk,
                  input         reset,
                  input         req,
                  output        ack,
                  
                  input [31:0]  p0,
                  input [31:0]  p1,
                  output [31:0] out);

    mul32x32_fsm S(.clk(clk),
                   .rst(reset),
                   .req(req),
                   .ack(ack),
                   .p0(p0),
                   .p1(p1),
                   .out(out));

endmodule // hls_MulFSM
module baudgen(
  input wire clk,
  output wire ser_clk);

  localparam lim = (`CLKFREQ / `BAUD) - 1; 
  localparam w = $clog2(lim);
  wire [w-1:0] limit = lim;
  reg [w-1:0] counter;
  assign ser_clk = (counter == limit);

  always @(posedge clk)
    counter <= ser_clk ? 0 : (counter + 1);
endmodule
module baudgen2(
  input wire clk,
  input wire restart,
  output wire ser_clk);

  localparam lim = (`CLKFREQ / (2 * `BAUD)) - 1; 
  localparam w = $clog2(lim);
  wire [w-1:0] limit = lim;
  reg [w-1:0] counter;
  assign ser_clk = (counter == limit);

  always @(posedge clk)
    if (restart)
      counter <= 0;
    else
      counter <= ser_clk ? 0 : (counter + 1);

endmodule