dakies/OSS_Verilog huggingface dataset:
module synchronizer (
  input clk_a,
  input clk_b,
  input arstn,
  input brstn,
  input [3:0] data_in,
  input data_en,
  output reg [3:0] dataout
);
  reg [3:0] data_reg;
  reg en_data_reg;
  reg en_clap_one, en_clap_two;

  always @(posedge clk_a or negedge arstn) begin
    if (~arstn) begin
      data_reg <= 0;
      en_data_reg <= 0;
    end
    else begin
      data_reg <= data_in;
      en_data_reg <= data_en;
    end
  end

  always @(posedge clk_b or negedge brstn) begin
    if (~brstn) begin
      en_clap_one <= 0;
      en_clap_two <= 0;
      dataout <= 0;
    end
    else begin
      en_clap_one <= en_data_reg;
      en_clap_two <= en_clap_one;

      if (en_clap_two)
        dataout <= data_reg;
    end
  end
endmodule
module fsm (
  input IN,
  input CLK,
  input RST,
  output reg MATCH
);
  
  reg [4:0] state;
  reg [4:0] next_state;
  
  always @(posedge CLK or posedge RST) begin
    if (RST)
      state <= 5'b00000;
    else
      state <= next_state;
  end
  
  always @(IN or posedge CLK or posedge RST) begin
    case (state)
      5'b00000: begin
        if (IN)
          next_state = 5'b00001;
        else
          next_state = 5'b00000;
      end
      5'b00001: begin
        if (IN)
          next_state = 5'b00010;
        else
          next_state = 5'b00000;
      end
      5'b00010: begin
        if (IN)
          next_state = 5'b00011;
        else
          next_state = 5'b00000;
      end
      5'b00011: begin
        if (IN)
          next_state = 5'b00100;
        else
          next_state = 5'b00000;
      end
      5'b00100: begin
        if (IN)
          next_state = 5'b00101;
        else
          next_state = 5'b00000;
      end
      5'b00101: begin
        if (IN)
          next_state = 5'b00101;
        else
          next_state = 5'b00000;
      end
      default: next_state = 5'b00000;
    endcase
  end
  
  always @(posedge CLK or posedge RST) begin
    if (RST)
      MATCH <= 1'b0;
    else if (state == 5'b00101)
      MATCH <= 1'b1;
    else
      MATCH <= 1'b0;
  end
  
endmodule
module width_8to16(
  input clk,
  input rst_n,
  input valid_in,
  input [7:0] data_in,
  output valid_out,
  output [15:0] data_out
);

  reg [7:0] data_lock;
  reg [15:0] data_out_reg;
  reg flag;

  always @(posedge clk or negedge rst_n) begin
    if (!rst_n) begin
      data_lock <= 8'b0;
      data_out_reg <= 16'b0;
      flag <= 1'b0;
    end
    else begin
      if (valid_in) begin
        if (!flag) begin
          data_lock <= data_in;
          flag <= 1'b1;
        end
        else begin
          data_out_reg <= {data_lock, data_in};
          flag <= 1'b0;
        end
      end
    end
  end

  assign valid_out = flag;
  assign data_out = data_out_reg;

endmodule
module JC_counter (
  input clk,
  input rst_n,
  output reg [63:0] Q
);

  always @(posedge clk or negedge rst_n) begin
    if (~rst_n) begin
      Q <= 64'b0;
    end
    else begin
      if (Q[0] == 1'b0) begin
        Q <= {Q[62:0], 1'b1};
      end
      else begin
        Q <= {Q[62:0], 1'b0};
      end
    end
  end

endmodule
module adder_pipe_64bit (
  input clk,
  input rst_n,
  input i_en,
  input [63:0] adda,
  input [63:0] addb,
  output reg [64:0] result,
  output reg o_en
);
  reg [63:0] stage1_adda, stage1_addb;
  reg [64:0] stage1_sum;
  reg [63:0] stage2_adda, stage2_addb;
  reg [64:0] stage2_sum;
  reg [63:0] stage3_adda, stage3_addb;
  reg [64:0] stage3_sum;
  
  always @(posedge clk or negedge rst_n) begin
    if (!rst_n) begin
      stage1_adda <= 64'b0;
      stage1_addb <= 64'b0;
      stage1_sum <= 65'b0;
      stage2_adda <= 64'b0;
      stage2_addb <= 64'b0;
      stage2_sum <= 65'b0;
      stage3_adda <= 64'b0;
      stage3_addb <= 64'b0;
      stage3_sum <= 65'b0;
      result <= 65'b0;
      o_en <= 1'b0;
    end
    else begin
      if (i_en) begin
        stage1_adda <= adda;
        stage1_addb <= addb;
        stage1_sum <= stage1_adda + stage1_addb;
      end
      else begin
        stage1_adda <= 64'b0;
        stage1_addb <= 64'b0;
        stage1_sum <= 65'b0;
      end
      
      stage2_adda <= stage1_adda;
      stage2_addb <= stage1_addb;
      stage2_sum <= stage1_sum;
      
      stage3_adda <= stage2_adda;
      stage3_addb <= stage2_addb;
      stage3_sum <= stage2_sum;
      
      result <= stage3_sum;
      o_en <= i_en;
    end
  end
endmodule
module right_shifter (
  input clk,
  input d,
  output reg [7:0] q
);

  always @(posedge clk) begin
    q <= {q[6:0], d};
  end

  initial begin
    q <= 8'b0;
  end

endmodule
module serial2parallel (
  input wire clk,
  input wire rst_n,
  input wire din_serial,
  input wire din_valid,
  output reg [7:0] dout_parallel,
  output reg dout_valid
);

  reg [3:0] cnt;

  always @(posedge clk or negedge rst_n) begin
    if (~rst_n) begin
      cnt <= 4'b0000;
      dout_parallel <= 8'b0;
      dout_valid <= 0;
    end else begin
      if (din_valid) begin
        if (cnt < 4'b1000) begin
          cnt <= cnt + 1;
          dout_parallel[cnt] <= din_serial;
        end else begin
          dout_valid <= 1;
        end
      end
    end
  end

endmodule
module multi_16bit (
  input clk,
  input rst_n,
  input start,
  input [15:0] ain,
  input [15:0] bin,
  output reg [31:0] yout,
  output reg done
);

  reg [3:0] i;
  reg [15:0] areg;
  reg [15:0] breg;
  reg [31:0] yout_r;
  reg done_r;

  always @(posedge clk or negedge rst_n) begin
    if (~rst_n) begin
      i <= 4'b0;
      yout_r <= 32'b0;
      done_r <= 1'b0;
    end
    else begin
      if (start && (i < 4'b10000)) begin
        i <= i + 1;
      end
      else if (!start) begin
        i <= 4'b0;
      end
    end
  end

  always @(posedge clk or negedge rst_n) begin
    if (~rst_n) begin
      areg <= 16'b0;
      breg <= 16'b0;
    end
    else begin
      if (start) begin
        if (i == 4'b0) begin
          areg <= ain;
          breg <= bin;
        end
        else if ((i > 4'b0) && (i < 4'b10001)) begin
          if (areg[i-1] == 1'b1) begin
            yout_r <= yout_r + (breg << (i-1));
          end
        end
      end
    end
  end

  always @(posedge clk or negedge rst_n) begin
    if (~rst_n) begin
      yout <= 32'b0;
      done <= 1'b0;
    end
    else begin
      yout <= yout_r;
      done <= done_r;
      if (i == 4'b10000) begin
        done_r <= 1'b1;
      end
      else if (i == 4'b10001) begin
        done_r <= 1'b0;
      end
    end
  end

endmodule
module freq_div (
  input CLK_in,
  input RST,
  output reg CLK_50,
  output reg CLK_10,
  output reg CLK_1
);

  reg [2:0] cnt_10;
  reg [5:0] cnt_100;

  always @(posedge CLK_in or posedge RST) begin
    if (RST) begin
      CLK_50 <= 0;
      CLK_10 <= 0;
      CLK_1 <= 0;
      cnt_10 <= 0;
      cnt_100 <= 0;
    end
    else begin
      // CLK_50 generation
      CLK_50 <= ~CLK_50;

      // CLK_10 generation
      if (cnt_10 == 4) begin
        CLK_10 <= ~CLK_10;
        cnt_10 <= 0;
      end
      else begin
        cnt_10 <= cnt_10 + 1;
      end

      // CLK_1 generation
      if (cnt_100 == 49) begin
        CLK_1 <= ~CLK_1;
        cnt_100 <= 0;
      end
      else begin
        cnt_100 <= cnt_100 + 1;
      end
    end
  end

endmodule
module counter_12 (
  input rst_n,
  input clk,
  input valid_count,
  output reg [3:0] out
);
  
  always @(posedge clk) begin
    if (~rst_n)
      out <= 4'b0000;
    else if (valid_count) begin
      if (out == 4'd11)
        out <= 4'b0000;
      else
        out <= out + 1;
    end
  end
  
endmodule
module edge_detect (
  input clk,
  input rst_n,
  input a,
  output reg rise,
  output reg down
);
  
  reg a_prev;
  
  always @(posedge clk or negedge rst_n) begin
    if (~rst_n)
      a_prev <= 1'b0;
    else
      a_prev <= a;
  end
  
  always @(posedge clk or negedge rst_n) begin
    if (~rst_n) begin
      rise <= 1'b0;
      down <= 1'b0;
    end else begin
      rise <= (a == 1'b1) && (a_prev == 1'b0);
      down <= (a == 1'b0) && (a_prev == 1'b1);
    end
  end
  
endmodule
module calendar (
  input CLK,
  input RST,
  output reg [5:0] Hours,
  output reg [5:0] Mins,
  output reg [5:0] Secs
);
  
  always @(posedge CLK or posedge RST) begin
    if (RST)
      Secs <= 6'b0;
    else if (Secs == 6'b111111)
      Secs <= 6'b0;
    else
      Secs <= Secs + 1;
  end
  
  always @(posedge CLK or posedge RST) begin
    if (RST)
      Mins <= 6'b0;
    else if (Secs == 6'b111111 && Mins == 6'b111111)
      Mins <= 6'b0;
    else if (Secs == 6'b111111)
      Mins <= Mins + 1;
  end
  
  always @(posedge CLK or posedge RST) begin
    if (RST)
      Hours <= 6'b0;
    else if (Secs == 6'b111111 && Mins == 6'b111111 && Hours == 6'b101111)
      Hours <= 6'b0;
    else if (Secs == 6'b111111 && Mins == 6'b111111)
      Hours <= Hours + 1;
  end
  
endmodule
module adder_8bit(
  input [7:0] a,
  input [7:0] b,
  input cin,
  output [7:0] sum,
  output cout
);

  // Define internal signals
  wire [7:0] carry;
  wire [7:0] sum_intermediate;

  // Instantiate full adders
  genvar i;
  generate
    for (i = 0; i < 8; i = i + 1) begin : full_adder_inst
      full_adder full_adder_inst(
        .a(a[i]),
        .b(b[i]),
        .cin(i ? carry[i-1] : cin),
        .sum(sum_intermediate[i]),
        .cout(carry[i])
      );
    end
  endgenerate

  // Assign the outputs
  assign sum = sum_intermediate;
  assign cout = carry[7];

endmodule
module full_adder(
  input a,
  input b,
  input cin,
  output sum,
  output cout
);

  // Implement full adder logic
  assign sum = a ^ b ^ cin;
  assign cout = (a & b) | (a & cin) | (b & cin);

endmodule
module radix2_div #(
  parameter DATAWIDTH = 8
)(
  input wire clk,
  input wire rstn,
  input wire en,
  input wire [DATAWIDTH-1:0] dividend,
  input wire [DATAWIDTH-1:0] divisor,
  output wire ready,
  output wire [DATAWIDTH-1:0] quotient,
  output wire [DATAWIDTH-1:0] remainder,
  output wire vld_out
);

  localparam LOG2_DATAWIDTH = $clog2(DATAWIDTH);
  
  reg [LOG2_DATAWIDTH:0] current_state;
  reg [LOG2_DATAWIDTH-1:0] dividend_e;
  reg [LOG2_DATAWIDTH-1:0] divisor_e;
  reg [LOG2_DATAWIDTH-1:0] quotient_e;
  reg [LOG2_DATAWIDTH-1:0] remainder_e;
  reg [LOG2_DATAWIDTH-1:0] count;
  
  always @(posedge clk or negedge rstn) begin
    if (~rstn) begin
      // Reset condition
      current_state <= 0;
      dividend_e <= 0;
      divisor_e <= 0;
      quotient_e <= 0;
      remainder_e <= 0;
      count <= 0;
    end
    else begin
      // State transition logic
      case (current_state)
        0: begin // IDLE
          if (en) begin
            current_state <= 1; // Transition to SUB state
            dividend_e <= {dividend, {LOG2_DATAWIDTH{1'b0}}}; // Extend dividend
            divisor_e <= {divisor, {LOG2_DATAWIDTH{1'b0}}}; // Extend divisor
          end
        end
        1: begin // SUB
          if (dividend_e >= divisor_e) begin
            current_state <= 2; // Transition to SHIFT state
            quotient_e <= quotient_e + {1'b1, {LOG2_DATAWIDTH{1'b0}}}; // Increment quotient
            remainder_e <= dividend_e - divisor_e; // Calculate remainder
          end
          else begin
            current_state <= 1; // Stay in SUB state
            quotient_e <= quotient_e + {1'b0, {LOG2_DATAWIDTH{1'b0}}}; // Append 0 to quotient
            remainder_e <= dividend_e; // Remainder remains the same
          end
        end
        2: begin // SHIFT
          if (count == (DATAWIDTH - 1)) begin
            current_state <= 3; // Transition to DONE state
          end
          else begin
            current_state <= 2; // Stay in SHIFT state
            dividend_e <= dividend_e << 1; // Shift dividend left
            count <= count + 1; // Increment count
          end
        end
        3: begin // DONE
          current_state <= 0; // Transition back to IDLE state
        end
      endcase
    end
  end
  
  assign ready = (current_state == 0);
  assign quotient = quotient_e;
  assign remainder = remainder_e;
  assign vld_out = (current_state == 3);

endmodule
module accu (
    input wire clk,
    input wire rst_n,
    input wire [7:0] data_in,
    input wire valid_in,
    output wire valid_out,
    output wire [9:0] data_out
);

    reg [9:0] accumulator;
    reg [2:0] counter;
    reg valid_out_reg;

    always @(posedge clk or negedge rst_n) begin
        if (~rst_n) begin
            accumulator <= 10'b0;
            counter <= 3'b0;
            valid_out_reg <= 1'b0;
        end else begin
            if (valid_in) begin
                accumulator <= accumulator + data_in;
                counter <= counter + 1'b1;
            end
            
            if (counter == 3'b11) begin
                valid_out_reg <= 1'b1;
                counter <= 3'b0;
            end else begin
                valid_out_reg <= 1'b0;
            end
        end
    end

    assign valid_out = valid_out_reg;
    assign data_out = accumulator;

endmodule
module signal_generator (
  input wire clk,
  input wire rst_n,
  output reg [4:0] wave
);
  reg [1:0] state;
  
  always @(posedge clk or negedge rst_n) begin
    if (~rst_n) begin
      state <= 2'b0;
      wave <= 5'b0;
    end
    else begin
      case (state)
        2'b0:
          begin
            if (wave == 5'b11111)
              state <= 2'b1;
            else
              wave <= wave + 1;
          end
        2'b1:
          begin
            if (wave == 5'b00000)
              state <= 2'b0;
            else
              wave <= wave - 1;
          end
      endcase
    end
  end
  
endmodule
module multi_booth_8bit (
  input clk,
  input reset,
  input [7:0] a,
  input [7:0] b,
  output reg [15:0] p,
  output reg rdy
);

  reg [7:0] multiplicand;
  reg [7:0] multiplier;
  reg [3:0] ctr;

  always @(posedge clk or posedge reset) begin
    if (reset) begin
      multiplicand <= 8'b0;
      multiplier <= 8'b0;
      ctr <= 4'b0;
      p <= 16'b0;
      rdy <= 1'b0;
    end
    else begin
      if (ctr < 4'b10000) begin
        multiplicand <= multiplicand << 1;
        if (multiplier[ctr] == 1'b1) begin
          p <= p + multiplicand;
        end
        ctr <= ctr + 1;
        if (ctr == 4'b10000) begin
          rdy <= 1'b1;
        end
      end
    end
  end

  always @(posedge clk) begin
    if (reset) begin
      rdy <= 1'b0;
    end
  end

endmodule
module pe (
  input clk,
  input rst,
  input [31:0] a,
  input [31:0] b,
  output reg [31:0] c
);

  always @(posedge clk or posedge rst) begin
    if (rst)
      c <= 32'b0;
    else
      c <= c + (a * b);
  end

endmodule
module synchronizer (
  input wire clk_a,
  input wire clk_b,
  input wire arstn,
  input wire brstn,
  input wire [3:0] data_in,
  input wire data_en,
  output reg [3:0] dataout
);

  reg [3:0] data_reg;
  reg en_data_reg;
  reg en_clap_one;
  reg en_clap_two;

  always @(posedge clk_a or negedge arstn) begin
    if (~arstn) begin
      data_reg <= 4'b0000;
      en_data_reg <= 1'b0;
    end
    else begin
      data_reg <= data_in;
      en_data_reg <= data_en;
    end
  end

  always @(posedge clk_b or negedge brstn) begin
    if (~brstn) begin
      en_clap_one <= 1'b0;
      en_clap_two <= 1'b0;
      dataout <= 4'b0000;
    end
    else begin
      en_clap_one <= en_data_reg;
      en_clap_two <= en_clap_one;
      if (en_clap_two)
        dataout <= data_reg;
    end
  end

endmodule
module asyn_fifo #
  (
   parameter WIDTH = 8,
   parameter DEPTH = 16
  )
  (
   input wclk,
   input rclk,
   input wrstn,
   input rrstn,
   input winc,
   input rinc,
   input [WIDTH-1:0] wdata,
   output reg wfull,
   output reg rempty,
   output reg [WIDTH-1:0] rdata
  );

  // Dual-port RAM submodule
  dual_port_RAM #
    (
     .WIDTH(WIDTH),
     .DEPTH(DEPTH)
    )
    ram
    (
     .wclk(wclk),
     .wenc(winc),
     .waddr(wptr[3:0]),
     .wdata(wdata),
     .rclk(rclk),
     .renc(rinc),
     .raddr(rptr[3:0]),
     .rdata(rdata)
    );

  reg [3:0] wptr;
  reg [3:0] rptr;
  reg [3:0] wptr_buff;
  reg [3:0] rptr_buff;
  reg [3:0] wptr_syn;
  reg [3:0] rptr_syn;

  // Write pointer logic
  always @(posedge wclk or negedge wrstn)
  begin
    if (~wrstn)
      wptr <= 4'b0000;
    else if (winc)
      wptr <= wptr + 1;
  end

  // Read pointer logic
  always @(posedge rclk or negedge rrstn)
  begin
    if (~rrstn)
      rptr <= 4'b0000;
    else if (rinc)
      rptr <= rptr + 1;
  end

  // Gray code conversion for write pointer
  always @*
  begin
    wptr_syn[0] = wptr[0];
    wptr_syn[1] = wptr[0] ^ wptr[1];
    wptr_syn[2] = wptr[1] ^ wptr[2];
    wptr_syn[3] = wptr[2] ^ wptr[3];
  end

  // Gray code conversion for read pointer
  always @*
  begin
    rptr_syn[0] = rptr[0];
    rptr_syn[1] = rptr[0] ^ rptr[1];
    rptr_syn[2] = rptr[1] ^ rptr[2];
    rptr_syn[3] = rptr[2] ^ rptr[3];
  end

  // Pointer buffers
  always @(posedge wclk or negedge wrstn)
  begin
    if (~wrstn)
      wptr_buff <= 4'b0000;
    else
      wptr_buff <= wptr_syn;
  end

  always @(posedge rclk or negedge rrstn)
  begin
    if (~rrstn)
      rptr_buff <= 4'b0000;
    else
      rptr_buff <= rptr_syn;
  end

  // Full and empty signals
  always @*
  begin
    wfull = (wptr_syn == ~rptr_buff[3] & rptr_buff[2:0]);
    rempty = (rptr_syn == wptr_buff);
  end

endmodule
module fsm (
  input IN,
  input CLK,
  input RST,
  output reg MATCH
);

  reg [4:0] state;
  reg [4:0] next_state;

  parameter S0 = 5'b00000;
  parameter S1 = 5'b00001;
  parameter S2 = 5'b00010;
  parameter S3 = 5'b00011;
  parameter S4 = 5'b00100;

  always @(posedge CLK or posedge RST) begin
    if (RST) begin
      state <= S0;
      MATCH <= 0;
    end
    else begin
      state <= next_state;
      MATCH <= (state == S4);
    end
  end

  always @(state or IN) begin
    case (state)
      S0: begin
        if (IN)
          next_state <= S1;
        else
          next_state <= S0;
      end
      S1: begin
        if (IN)
          next_state <= S1;
        else
          next_state <= S2;
      end
      S2: begin
        if (IN)
          next_state <= S1;
        else
          next_state <= S3;
      end
      S3: begin
        if (IN)
          next_state <= S4;
        else
          next_state <= S0;
      end
      S4: begin
        if (IN)
          next_state <= S1;
        else
          next_state <= S2;
      end
    endcase
  end

endmodule
module width_8to16 (
  input wire clk,
  input wire rst_n,
  input wire valid_in,
  input wire [7:0] data_in,
  output reg valid_out,
  output reg [15:0] data_out
);

  reg [7:0] data_lock;
  reg valid_flag;

  always @(posedge clk or negedge rst_n) begin
    if (!rst_n) begin
      data_lock <= 8'b0;
      valid_flag <= 1'b0;
      valid_out <= 1'b0;
      data_out <= 16'b0;
    end
    else begin
      if (valid_in) begin
        if (!valid_flag) begin
          data_lock <= data_in;
          valid_flag <= 1'b1;
        end
        else begin
          data_out <= {data_lock, data_in};
          valid_out <= 1'b1;
          valid_flag <= 1'b0;
        end
      end
    end
  end

endmodule
module JC_counter (
  input clk,
  input rst_n,
  output reg [63:0] Q
);

  always @(posedge clk or negedge rst_n) begin
    if (~rst_n)
      Q <= 64'b0;
    else begin
      if (Q[0] == 1)
        Q <= {Q[62:0], 1'b0};
      else
        Q <= {Q[62:0], 1'b1};
    end
  end

endmodule
module adder_pipe_64bit (
    input clk,
    input rst_n,
    input i_en,
    input [63:0] adda,
    input [63:0] addb,
    output reg [64:0] result,
    output reg o_en
);

    reg [63:0] stage1;
    reg [63:0] stage2;
    reg [63:0] stage3;

    always @(posedge clk or negedge rst_n) begin
        if (~rst_n) begin
            stage1 <= 64'b0;
            stage2 <= 64'b0;
            stage3 <= 64'b0;
            result <= 65'b0;
            o_en <= 1'b0;
        end else begin
            if (i_en) begin
                stage1 <= adda + addb;
                stage2 <= stage1 + stage2[63:0];
                stage3 <= stage2 + stage3[63:0];
                result <= {stage3[63], stage3};
                o_en <= 1'b1;
            end else begin
                stage1 <= 64'b0;
                stage2 <= 64'b0;
                stage3 <= 64'b0;
                result <= 65'b0;
                o_en <= 1'b0;
            end
        end
    end

endmodule
module right_shifter (
  input wire clk,
  input wire d,
  output reg [7:0] q
);

  always @(posedge clk) begin
    q <= {d, q[7:1]};
  end

  initial begin
    q <= 8'b0;
  end

endmodule
module multi_16bit (
  input clk,
  input rst_n,
  input start,
  input [15:0] ain,
  input [15:0] bin,
  output [31:0] yout,
  output reg done
);

  reg [3:0] i;
  reg [15:0] areg;
  reg [15:0] breg;
  reg [31:0] yout_r;

  always @(posedge clk or negedge rst_n) begin
    if (~rst_n) begin
      i <= 4'b0000;
      areg <= 16'b0;
      breg <= 16'b0;
      yout_r <= 32'b0;
      done <= 0;
    end
    else begin
      if (start && (i < 4'b10001))
        i <= i + 1;
      else if (!start)
        i <= 4'b0000;

      if (i == 4'b10000)
        done <= 1;
      else if (i == 4'b10001)
        done <= 0;
    end
  end

  always @(posedge clk or negedge rst_n) begin
    if (~rst_n) begin
      areg <= 16'b0;
      breg <= 16'b0;
      yout_r <= 32'b0;
    end
    else begin
      if (start) begin
        if (i == 4'b0000) begin
          areg <= ain;
          breg <= bin;
        end
        else if ((i > 4'b0000) && (i < 4'b10001)) begin
          if (areg[i-1])
            yout_r <= yout_r + (breg << (i-1));
        end
      end
    end
  end

  assign yout = yout_r;

endmodule
module freq_div (
  input CLK_in,
  input RST,
  output reg CLK_50,
  output reg CLK_10,
  output reg CLK_1
);

  reg [2:0] cnt_10;
  reg [6:0] cnt_100;

  always @(posedge CLK_in or posedge RST) begin
    if (RST) begin
      CLK_50 <= 0;
      CLK_10 <= 0;
      CLK_1 <= 0;
      cnt_10 <= 0;
      cnt_100 <= 0;
    end
    else begin
      // CLK_50 generation
      CLK_50 <= ~CLK_50;

      // CLK_10 generation
      if (cnt_10 == 4) begin
        CLK_10 <= ~CLK_10;
        cnt_10 <= 0;
      end
      else begin
        cnt_10 <= cnt_10 + 1;
      end

      // CLK_1 generation
      if (cnt_100 == 49) begin
        CLK_1 <= ~CLK_1;
        cnt_100 <= 0;
      end
      else begin
        cnt_100 <= cnt_100 + 1;
      end
    end
  end

endmodule
module counter_12 (
  input rst_n,
  input clk,
  input valid_count,
  output reg [3:0] out
);

  always @(posedge clk or negedge rst_n) begin
    if (~rst_n)
      out <= 4'b0000;
    else if (valid_count) begin
      if (out == 4'd11)
        out <= 4'b0000;
      else
        out <= out + 1;
    end
  end

endmodule
module edge_detect (
  input clk,
  input rst_n,
  input a,
  output reg rise,
  output reg down
);

  reg a_prev;

  always @(posedge clk or negedge rst_n) begin
    if (!rst_n) begin
      rise <= 0;
      down <= 0;
      a_prev <= 0;
    end
    else begin
      if (a && !a_prev) // Rising edge detection
        rise <= 1;
      else
        rise <= 0;

      if (!a && a_prev) // Falling edge detection
        down <= 1;
      else
        down <= 0;

      a_prev <= a;
    end
  end

endmodule
module calendar (
  input CLK,
  input RST,
  output reg [5:0] Hours,
  output reg [5:0] Mins,
  output reg [5:0] Secs
);

  always @(posedge CLK or posedge RST) begin
    if (RST)
      Secs <= 6'b000000;
    else if (Secs == 6'b111111)
      Secs <= 6'b000000;
    else
      Secs <= Secs + 1;
  end

  always @(posedge CLK or posedge RST) begin
    if (RST)
      Mins <= 6'b000000;
    else if (Secs == 6'b111111 && Mins == 6'b111111)
      Mins <= 6'b000000;
    else if (Secs == 6'b111111)
      Mins <= Mins + 1;
  end

  always @(posedge CLK or posedge RST) begin
    if (RST)
      Hours <= 6'b000000;
    else if (Secs == 6'b111111 && Mins == 6'b111111 && Hours == 6'b111111)
      Hours <= 6'b000000;
    else if (Secs == 6'b111111 && Mins == 6'b111111)
      Hours <= Hours + 1;
  end

endmodule
module cla_16bit(
  input [15:0] A,
  input [15:0] B,
  input C_in,
  output [16:0] S,
  output C_out
);

  wire [16:0] P, G;
  wire [16:0] C;
  
  assign P[0] = A[0] ^ B[0];
  assign G[0] = A[0] & B[0];
  assign C[0] = C_in;
  
  generate
    genvar i;
    for (i = 1; i < 16; i = i + 1) begin : gen
      assign P[i] = A[i] ^ B[i];
      assign G[i] = A[i] & B[i];
      assign C[i] = G[i - 1] | (P[i - 1] & C[i - 1]);
    end
  endgenerate
  
  assign S = {C[15], C};
  assign C_out = G[15] | (P[15] & C[15]);

endmodule
module adder_32bit(
  input [31:0] A,
  input [31:0] B,
  output [31:0] S,
  output C32
);

  wire [16:0] C;
  wire [16:0] S_intermediate;
  
  cla_16bit cla0(.A(A[15:0]), .B(B[15:0]), .C_in(1'b0), .S(S_intermediate[15:0]), .C_out(C[0]));
  cla_16bit cla1(.A(A[31:16]), .B(B[31:16]), .C_in(C[0]), .S(S_intermediate[31:16]), .C_out(C[1]));
  
  assign S = {S_intermediate[31], S_intermediate[31:16]};
  assign C32 = C[1];
  
endmodule
module signal_generator (
  input wire clk,
  input wire rst_n,
  output reg [4:0] wave
);

  reg [1:0] state;

  always @(posedge clk or negedge rst_n) begin
    if (~rst_n) begin
      state <= 2'b00;
      wave <= 5'b0;
    end else begin
      case (state)
        2'b00: begin
          if (wave == 5'b11111)
            state <= 2'b01;
          else
            wave <= wave + 1;
        end
        2'b01: begin
          if (wave == 5'b00000)
            state <= 2'b00;
          else
            wave <= wave - 1;
        end
        default: state <= 2'b00;
      endcase
    end
  end

endmodule
module multi_booth_8bit (
  input clk,
  input reset,
  input [7:0] a,
  input [7:0] b,
  output reg [15:0] p,
  output reg rdy
);

  reg [3:0] ctr;
  reg [7:0] multiplicand;
  reg [7:0] multiplier;

  always @(posedge clk or posedge reset) begin
    if (reset) begin
      ctr <= 4'b0000;
      multiplicand <= 8'b0;
      multiplier <= 8'b0;
      p <= 16'b0;
      rdy <= 0;
    end
    else begin
      if (ctr < 4'b10000) begin
        multiplicand <= multiplicand << 1;
        if (multiplier[ctr] == 1)
          p <= p + multiplicand;
        ctr <= ctr + 1;
      end
      else begin
        rdy <= 1;
      end
    end
  end

  always @(posedge clk) begin
    if (reset)
      p <= 16'b0;
  end

endmodule
module pe (
  input wire clk,
  input wire rst,
  input wire [31:0] a,
  input wire [31:0] b,
  output wire [31:0] c
);

  reg [31:0] c_reg;
  
  always @(posedge clk or posedge rst) begin
    if (rst) begin
      // Reset condition
      c_reg <= 32'd0;
    end
    else begin
      // Multiplication and accumulation
      c_reg <= c_reg + (a * b);
    end
  end
  
  assign c = c_reg;

endmodule
module alu (
    input [31:0] a,
    input [31:0] b,
    input [5:0] aluc,
    output reg [31:0] r,
    output reg zero,
    output reg carry,
    output reg negative,
    output reg overflow,
    output reg flag
);

    parameter ADD = 6'b100000;
    parameter ADDU = 6'b100001;
    parameter SUB = 6'b100010;
    parameter SUBU = 6'b100011;
    parameter AND = 6'b100100;
    parameter OR = 6'b100101;
    parameter XOR = 6'b100110;
    parameter NOR = 6'b100111;
    parameter SLT = 6'b101010;
    parameter SLTU = 6'b101011;
    parameter SLL = 6'b000000;
    parameter SRL = 6'b000010;
    parameter SRA = 6'b000011;
    parameter SLLV = 6'b000100;
    parameter SRLV = 6'b000110;
    parameter SRAV = 6'b000111;
    parameter LUI = 6'b001111;

    wire [31:0] a_signed;
    wire [31:0] b_signed;
    reg [32:0] res;

    assign a_signed = a;
    assign b_signed = b;

    always @(a, b, aluc) begin
        case (aluc)
            ADD, ADDU: res = a + b;
            SUB, SUBU: res = a - b;
            AND: res = a & b;
            OR: res = a | b;
            XOR: res = a ^ b;
            NOR: res = ~(a | b);
            SLT: begin
                res = (a_signed < b_signed) ? 1'b1 : 1'b0;
                flag = 1'b1;
            end
            SLTU: begin
                res = (a < b) ? 1'b1 : 1'b0;
                flag = 1'b1;
            end
            SLL: res = a << b[4:0];
            SRL: res = a >> b[4:0];
            SRA: res = $signed(a) >>> b[4:0];
            SLLV: res = a << (b[4:0] & 5'b11111);
            SRLV: res = a >> (b[4:0] & 5'b11111);
            SRAV: res = $signed(a) >>> (b[4:0] & 5'b11111);
            LUI: res = {a[31:16], 16'b0};
            default: res = 33'bz;
        endcase

        r = res[31:0];
        zero = (res[31:0] == 32'b0) ? 1'b1 : 1'b0;
        carry = res[32];
        negative = (res[31] == 1'b1) ? 1'b1 : 1'b0;
        overflow = (aluc == ADD || aluc == SUB) ? (a[31] == b[31] && res[31] != a[31]) : 1'b0;
        flag = (aluc == SLT || aluc == SLTU) ? flag : 1'bz;
    end

endmodule
module adder_16bit (
  input [15:0] a,
  input [15:0] b,
  input Cin,
  output [15:0] y,
  output Co
);

  wire [7:0] carry;
  wire [7:0] sum;

  // Instantiating eight 8-bit adders
  genvar i;
  generate
    for (i = 0; i < 8; i = i + 1) begin : ADDER_INST
      // Instantiating 8-bit adder
      adder_8bit adder_inst (
        .a(a[i*2 +: 8]),  // Extracting 8-bit portion from a
        .b(b[i*2 +: 8]),  // Extracting 8-bit portion from b
        .Cin(i ? carry[i-1] : Cin),  // Using carry from previous adder or Cin for the first adder
        .y(y[i*2 +: 8]),  // Storing the 8-bit sum
        .Co(carry[i])  // Storing the carry-out
      );
    end
  endgenerate

  // Generating carry-out for the 16-bit output
  assign Co = carry[7];

endmodule
module adder_8bit (
  input [7:0] a,
  input [7:0] b,
  input Cin,
  output [7:0] y,
  output Co
);

  wire [7:0] carry;
  wire [7:0] sum;

  // Generating sum and carry for each bit position
  assign {carry[0], sum[0]} = a[0] + b[0] + Cin;
  assign {carry[1], sum[1]} = a[1] + b[1] + carry[0];
  assign {carry[2], sum[2]} = a[2] + b[2] + carry[1];
  assign {carry[3], sum[3]} = a[3] + b[3] + carry[2];
  assign {carry[4], sum[4]} = a[4] + b[4] + carry[3];
  assign {carry[5], sum[5]} = a[5] + b[5] + carry[4];
  assign {carry[6], sum[6]} = a[6] + b[6] + carry[5];
  assign {carry[7], sum[7]} = a[7] + b[7] + carry[6];

  // Storing the sum and carry-out
  assign y = sum;
  assign Co = carry[7];

endmodule
module pulse_detect (
  input clk,
  input rst_n,
  input data_in,
  output reg data_out
);

  reg [1:0] state;

  parameter IDLE = 2'b00;
  parameter DETECT = 2'b01;
  parameter PULSE_END = 2'b10;

  always @(posedge clk or negedge rst_n) begin
    if (~rst_n) begin
      state <= IDLE;
      data_out <= 1'b0;
    end
    else begin
      case (state)
        IDLE:
          if (data_in == 1'b1)
            state <= DETECT;
          else
            state <= IDLE;
        
        DETECT:
          if (data_in == 1'b0)
            state <= PULSE_END;
          else
            state <= DETECT;
        
        PULSE_END:
          if (data_in == 1'b0)
            state <= IDLE;
          else
            state <= DETECT;
      endcase

      if (state == PULSE_END)
        data_out <= 1'b1;
      else
        data_out <= 1'b0;
    end
  end

endmodule
module synchronizer (
  input wire clk_a,
  input wire clk_b,
  input wire arstn,
  input wire brstn,
  input wire [3:0] data_in,
  input wire data_en,
  output reg [3:0] dataout
);
  reg [3:0] data_reg;
  reg en_data_reg;
  reg en_clap_one;
  reg en_clap_two;
  
  always @(posedge clk_a or negedge arstn) begin
    if (~arstn)
      data_reg <= 4'b0;
    else
      data_reg <= data_in;
  end
  
  always @(posedge clk_a or negedge arstn) begin
    if (~arstn)
      en_data_reg <= 1'b0;
    else
      en_data_reg <= data_en;
  end
  
  always @(posedge clk_b or negedge brstn) begin
    if (~brstn) begin
      en_clap_one <= 1'b0;
      en_clap_two <= 1'b0;
    end
    else begin
      en_clap_one <= en_data_reg;
      en_clap_two <= en_clap_one;
    end
  end
  
  always @(posedge clk_b or negedge brstn) begin
    if (~brstn)
      dataout <= 4'b0;
    else if (en_clap_two)
      dataout <= data_reg;
  end
  
endmodule
module fsm (
  input IN,
  input CLK,
  input RST,
  output reg MATCH
);

  reg [4:0] state;
  reg [4:0] next_state;

  parameter S0 = 5'b00000; // Initial state
  parameter S1 = 5'b00001; // State after detecting 1
  parameter S2 = 5'b00010; // State after detecting 10
  parameter S3 = 5'b00011; // State after detecting 100
  parameter S4 = 5'b00100; // State after detecting 1001
  parameter S5 = 5'b00101; // State after detecting 10011

  always @(posedge CLK or posedge RST) begin
    if (RST) begin
      MATCH <= 0;
      state <= S0;
    end
    else begin
      state <= next_state;
      MATCH <= (state == S5);
    end
  end

  always @(state or IN) begin
    case (state)
      S0: begin
        if (IN)
          next_state = S1;
        else
          next_state = S0;
      end
      S1: begin
        if (IN)
          next_state = S1;
        else
          next_state = S2;
      end
      S2: begin
        if (IN)
          next_state = S1;
        else
          next_state = S3;
      end
      S3: begin
        if (IN)
          next_state = S4;
        else
          next_state = S0;
      end
      S4: begin
        if (IN)
          next_state = S1;
        else
          next_state = S5;
      end
      S5: begin
        if (IN)
          next_state = S1;
        else
          next_state = S5;
      end
      default: next_state = S0;
    endcase
  end

endmodule
module JC_counter (
  input clk,
  input rst_n,
  output reg [63:0] Q
);
  
  always @(posedge clk or negedge rst_n) begin
    if (~rst_n)
      Q <= 64'b0;
    else begin
      if (Q[0] == 1'b0)
        Q <= {Q[62:0], 1'b1};
      else
        Q <= {Q[62:0], 1'b0};
    end
  end
  
endmodule
module adder_pipe_64bit (
  input clk,
  input rst_n,
  input i_en,
  input [63:0] adda,
  input [63:0] addb,
  output reg [64:0] result,
  output reg o_en
);

reg [63:0] stage1, stage2, stage3;
reg [64:0] carry;

always @(posedge clk or negedge rst_n) begin
  if (!rst_n)
    begin
      stage1 <= 64'b0;
      stage2 <= 64'b0;
      stage3 <= 64'b0;
      carry <= 65'b0;
      result <= 65'b0;
      o_en <= 1'b0;
    end
  else
    begin
      if (i_en)
        begin
          stage1 <= adda + addb;
          stage2 <= stage1 + carry[63:0];
          stage3 <= stage2 + carry[64];
          carry <= {stage2[63], stage3[63:1]};
          result <= stage3;
          o_en <= 1'b1;
        end
      else
        begin
          stage1 <= 64'b0;
          stage2 <= 64'b0;
          stage3 <= 64'b0;
          carry <= 65'b0;
          result <= 65'b0;
          o_en <= 1'b0;
        end
    end
end

endmodule
module serial2parallel (
  input wire clk,
  input wire rst_n,
  input wire din_serial,
  input wire din_valid,
  output reg [7:0] dout_parallel,
  output reg dout_valid
);

  reg [3:0] cnt;

  always @(posedge clk or negedge rst_n) begin
    if (~rst_n) begin
      cnt <= 4'b0000;
      dout_parallel <= 8'b0;
      dout_valid <= 1'b0;
    end
    else begin
      if (din_valid) begin
        if (cnt == 4'b0111) begin
          dout_parallel <= {din_serial, dout_parallel[7:1]};
          dout_valid <= 1'b1;
          cnt <= 4'b1000;
        end
        else begin
          dout_valid <= 1'b0;
          cnt <= cnt + 1;
        end
      end
    end
  end

endmodule
module freq_div (
  input CLK_in,
  input RST,
  output reg CLK_50,
  output reg CLK_10,
  output reg CLK_1
);
  
  reg [2:0] cnt_10;
  reg [6:0] cnt_100;
  
  always @(posedge CLK_in or posedge RST) begin
    if (RST)
      CLK_50 <= 1'b0;
    else
      CLK_50 <= ~CLK_50;
  end
  
  always @(posedge CLK_in or posedge RST) begin
    if (RST) begin
      CLK_10 <= 1'b0;
      cnt_10 <= 3'b0;
    end else begin
      if (cnt_10 == 4) begin
        CLK_10 <= ~CLK_10;
        cnt_10 <= 3'b0;
      end else begin
        cnt_10 <= cnt_10 + 1;
      end
    end
  end
  
  always @(posedge CLK_in or posedge RST) begin
    if (RST) begin
      CLK_1 <= 1'b0;
      cnt_100 <= 6'b0;
    end else begin
      if (cnt_100 == 49) begin
        CLK_1 <= ~CLK_1;
        cnt_100 <= 6'b0;
      end else begin
        cnt_100 <= cnt_100 + 1;
      end
    end
  end
  
endmodule
module counter_12 (
  input rst_n,
  input clk,
  input valid_count,
  output reg [3:0] out
);

  always @(posedge clk or negedge rst_n) begin
    if (!rst_n)
      out <= 4'b0000;
    else if (valid_count) begin
      if (out == 4'd11)
        out <= 4'b0000;
      else
        out <= out + 1;
    end
  end

endmodule
module edge_detect (
  input clk,
  input rst_n,
  input a,
  output reg rise,
  output reg down
);

  reg a_prev;

  always @(posedge clk or negedge rst_n) begin
    if (~rst_n) begin
      rise <= 0;
      down <= 0;
      a_prev <= 0;
    end
    else begin
      if (a && ~a_prev)
        rise <= 1;
      else
        rise <= 0;

      if (~a && a_prev)
        down <= 1;
      else
        down <= 0;

      a_prev <= a;
    end
  end

endmodule
module calendar (
  input CLK,
  input RST,
  output reg [5:0] Hours,
  output reg [5:0] Mins,
  output reg [5:0] Secs
);

  always @(posedge CLK or posedge RST) begin
    if (RST)
      Secs <= 6'b0;
    else if (Secs == 6'b111111)
      Secs <= 6'b0;
    else
      Secs <= Secs + 1;
  end

  always @(posedge CLK or posedge RST) begin
    if (RST)
      Mins <= 6'b0;
    else if (Mins == 6'b111111 || (Secs == 6'b111111 && Mins == 6'b111111))
      Mins <= 6'b0;
    else if (Secs == 6'b111111)
      Mins <= Mins + 1;
  end

  always @(posedge CLK or posedge RST) begin
    if (RST)
      Hours <= 6'b0;
    else if ((Hours == 6'b111111 && Mins == 6'b111111 && Secs == 6'b111111) || (Mins == 6'b111111 && Secs == 6'b111111))
      Hours <= 6'b0;
    else if (Mins == 6'b111111 && Secs == 6'b111111)
      Hours <= Hours + 1;
  end

endmodule
module adder_8bit(
  input [7:0] a,
  input [7:0] b,
  input cin,
  output [7:0] sum,
  output cout
);

  wire [7:0] carry;
  wire [7:0] sum_intermediate;

  // First bit-level adder
  full_adder FA0(.a(a[0]), .b(b[0]), .cin(cin), .sum(sum_intermediate[0]), .cout(carry[0]));

  // Intermediate bit-level adders
  genvar i;
  generate
    for (i = 1; i < 8; i = i + 1) begin : GEN_ADDERS
      full_adder FA(.a(a[i]), .b(b[i]), .cin(carry[i-1]), .sum(sum_intermediate[i]), .cout(carry[i]));
    end
  endgenerate

  // Final bit-level adder
  full_adder FA_last(.a(a[7]), .b(b[7]), .cin(carry[6]), .sum(sum[7]), .cout(cout));

  assign sum[6:0] = sum_intermediate[6:0];

endmodule
module full_adder(
  input a,
  input b,
  input cin,
  output sum,
  output cout
);

  assign {cout, sum} = a + b + cin;

endmodule
module signal_generator (
  input wire clk,
  input wire rst_n,
  output reg [4:0] wave
);

  reg [1:0] state;

  always @(posedge clk or negedge rst_n) begin
    if (~rst_n) begin
      state <= 2'b00;
      wave <= 5'b00000;
    end
    else begin
      case (state)
        2'b00: begin
          if (wave == 5'b11111)
            state <= 2'b01;
          else
            wave <= wave + 1;
        end
        2'b01: begin
          if (wave == 5'b00000)
            state <= 2'b00;
          else
            wave <= wave - 1;
        end
      endcase
    end
  end

endmodule
module multi_booth_8bit (
  input clk,
  input reset,
  input [7:0] a,
  input [7:0] b,
  output reg [15:0] p,
  output reg rdy
);

  reg [3:0] ctr;
  reg [7:0] multiplicand;
  reg [7:0] multiplier;
  
  always @(posedge clk or posedge reset) begin
    if (reset)
      ctr <= 4'b0000;
    else if (ctr < 4'b1111) begin
      multiplicand <= multiplicand << 1;
      if (multiplier[ctr] == 1'b1)
        p <= p + multiplicand;
      ctr <= ctr + 1;
    end
    else begin
      rdy <= 1'b1;
    end
  end
  
  always @(posedge clk or posedge reset) begin
    if (reset) begin
      multiplicand <= 8'b0;
      multiplier <= 8'b0;
      p <= 16'b0;
      rdy <= 1'b0;
    end
    else begin
      multiplier <= b;
    end
  end

endmodule
module pe(
  input wire clk,
  input wire rst,
  input wire [31:0] a,
  input wire [31:0] b,
  output wire [31:0] c
);

  reg [31:0] c_reg;

  always @(posedge clk or posedge rst) begin
    if (rst) begin
      c_reg <= 0;
    end else begin
      c_reg <= c_reg + (a * b);
    end
  end

  assign c = c_reg;

endmodule
module pulse_detect (
  input wire clk,
  input wire rst_n,
  input wire data_in,
  output wire data_out
);

  reg [1:0] state;
  reg data_out_reg;
  
  always @(posedge clk or negedge rst_n) begin
    if (~rst_n) begin
      // Reset condition
      state <= 2'b00;
      data_out_reg <= 1'b0;
    end
    else begin
      case (state)
        2'b00: begin
          if (data_in) begin
            state <= 2'b01;
          end
        end
        2'b01: begin
          if (~data_in) begin
            state <= 2'b10;
          end
        end
        2'b10: begin
          if (data_in) begin
            state <= 2'b11;
            data_out_reg <= 1'b1;
          end
          else begin
            state <= 2'b00;
            data_out_reg <= 1'b0;
          end
        end
        2'b11: begin
          if (~data_in) begin
            state <= 2'b00;
            data_out_reg <= 1'b0;
          end
        end
      endcase
    end
  end
  
  assign data_out = data_out_reg;

endmodule
module synchronizer (
  input wire clk_a,
  input wire clk_b,
  input wire arstn,
  input wire brstn,
  input wire [3:0] data_in,
  input wire data_en,
  output reg [3:0] dataout
);

  reg [3:0] data_reg;
  reg en_data_reg;
  reg en_clap_one;
  reg en_clap_two;

  always @(posedge clk_a or negedge arstn) begin
    if (~arstn) begin
      data_reg <= 4'b0;
      en_data_reg <= 0;
    end else begin
      data_reg <= data_in;
      en_data_reg <= data_en;
    end
  end

  always @(posedge clk_b or negedge brstn) begin
    if (~brstn) begin
      en_clap_one <= 0;
      en_clap_two <= 0;
      dataout <= 4'b0;
    end else begin
      en_clap_one <= en_data_reg;
      en_clap_two <= en_clap_one;
      if (en_clap_two)
        dataout <= data_reg;
    end
  end

endmodule
module fsm (
  input IN,
  input CLK,
  input RST,
  output reg MATCH
);

  reg [4:0] state;
  reg [4:0] next_state;

  parameter S0 = 5'b00000;
  parameter S1 = 5'b00001;
  parameter S2 = 5'b00010;
  parameter S3 = 5'b00011;
  parameter S4 = 5'b00100;
  parameter S5 = 5'b00101;

  always @(posedge CLK or posedge RST) begin
    if (RST) begin
      state <= S0;
      MATCH <= 1'b0;
    end else begin
      state <= next_state;
      MATCH <= (state == S4);
    end
  end

  always @(IN, state) begin
    case (state)
      S0: begin
        if (IN)
          next_state = S1;
        else
          next_state = S0;
      end
      S1: begin
        if (IN)
          next_state = S1;
        else
          next_state = S2;
      end
      S2: begin
        if (IN)
          next_state = S3;
        else
          next_state = S0;
      end
      S3: begin
        if (IN)
          next_state = S1;
        else
          next_state = S4;
      end
      S4: begin
        if (IN)
          next_state = S5;
        else
          next_state = S2;
      end
      S5: begin
        if (IN)
          next_state = S5;
        else
          next_state = S0;
      end
      default: next_state = S0;
    endcase
  end

endmodule
module width_8to16 (
  input clk,
  input rst_n,
  input valid_in,
  input [7:0] data_in,
  output reg valid_out,
  output reg [15:0] data_out
);

  reg [7:0] data_lock;

  always @(posedge clk or negedge rst_n) begin
    if (~rst_n) begin
      data_out <= 16'b0;
      data_lock <= 8'b0;
      valid_out <= 1'b0;
    end else begin
      if (valid_in) begin
        data_lock <= data_in;
        valid_out <= 1'b0;
      end else if (valid_out) begin
        data_out <= {data_lock, data_in};
        valid_out <= 1'b0;
      end else begin
        data_out <= 16'b0;
        valid_out <= 1'b0;
      end

      if (valid_in)
        valid_out <= 1'b1;
    end
  end

endmodule
module JC_counter (
  input clk,
  input rst_n,
  output reg [63:0] Q
);

  always @(posedge clk or negedge rst_n) begin
    if (~rst_n) begin
      Q <= 64'b0;
    end else begin
      if (Q[0] == 1'b0) begin
        Q <= {Q[62:0], 1'b1};
      end else begin
        Q <= {Q[62:0], 1'b0};
      end
    end
  end

endmodule
module adder_pipe_64bit (
  input clk,
  input rst_n,
  input i_en,
  input [63:0] adda,
  input [63:0] addb,
  output [64:0] result,
  output o_en
);

  reg [63:0] stage1;
  reg [63:0] stage2;
  reg [63:0] stage3;
  reg o_en_reg;
  
  always @(posedge clk or negedge rst_n) begin
    if (~rst_n)
      stage1 <= 64'b0;
    else
      stage1 <= adda;
  end
  
  always @(posedge clk or negedge rst_n) begin
    if (~rst_n)
      stage2 <= 64'b0;
    else if (i_en)
      stage2 <= stage1 + addb;
  end
  
  always @(posedge clk or negedge rst_n) begin
    if (~rst_n)
      stage3 <= 64'b0;
    else if (i_en)
      stage3 <= stage2;
  end
  
  always @(posedge clk or negedge rst_n) begin
    if (~rst_n)
      o_en_reg <= 1'b0;
    else if (i_en)
      o_en_reg <= 1'b1;
  end
  
  assign result = {stage3, o_en_reg};
  assign o_en = o_en_reg;

endmodule
module right_shifter (
  input clk,
  input d,
  output reg [7:0] q
);

  always @(posedge clk) begin
    q[7:1] <= q[6:0];
    q[0] <= d;
  end

  initial begin
    q = 8'b0;
  end

endmodule
module serial2parallel (
  input clk,
  input rst_n,
  input din_serial,
  input din_valid,
  output reg [7:0] dout_parallel,
  output reg dout_valid
);

  reg [3:0] cnt;

  always @(posedge clk or negedge rst_n) begin
    if (~rst_n) begin
      cnt <= 4'b0000;
      dout_parallel <= 8'b0;
      dout_valid <= 0;
    end else begin
      if (din_valid) begin
        if (cnt == 4'b0111) begin
          dout_parallel <= {din_serial, dout_parallel[7:1]};
          dout_valid <= 1;
          cnt <= 4'b1000;
        end else begin
          dout_valid <= 0;
          cnt <= cnt + 1;
        end
      end
    end
  end

endmodule
module freq_div (
  input CLK_in,
  input RST,
  output reg CLK_50,
  output reg CLK_10,
  output reg CLK_1
);

  reg [2:0] cnt_10;
  reg [5:0] cnt_100;

  always @(posedge CLK_in or negedge RST) begin
    if (~RST) begin
      CLK_50 <= 1'b0;
      CLK_10 <= 1'b0;
      CLK_1 <= 1'b0;
      cnt_10 <= 3'b0;
      cnt_100 <= 6'b0;
    end else begin
      // CLK_50 generation
      CLK_50 <= ~CLK_50;

      // CLK_10 generation
      if (cnt_10 == 4) begin
        CLK_10 <= ~CLK_10;
        cnt_10 <= 0;
      end else begin
        cnt_10 <= cnt_10 + 1;
      end

      // CLK_1 generation
      if (cnt_100 == 49) begin
        CLK_1 <= ~CLK_1;
        cnt_100 <= 0;
      end else begin
        cnt_100 <= cnt_100 + 1;
      end
    end
  end

endmodule
module counter_12 (
  input rst_n,
  input clk,
  input valid_count,
  output reg [3:0] out
);

  always @(posedge clk or negedge rst_n) begin
    if (~rst_n) begin
      out <= 4'b0000;
    end else if (valid_count) begin
      if (out == 4'd11) begin
        out <= 4'b0000;
      end else begin
        out <= out + 1;
      end
    end
  end

endmodule
module edge_detect (
  input clk,
  input rst_n,
  input a,
  output reg rise,
  output reg down
);

  reg a_prev;

  always @(posedge clk or negedge rst_n) begin
    if (~rst_n) begin
      rise <= 1'b0;
      down <= 1'b0;
      a_prev <= 1'b0;
    end else begin
      if (a_prev == 1'b0 && a == 1'b1) begin
        rise <= 1'b1;
      end else if (a_prev == 1'b1 && a == 1'b0) begin
        down <= 1'b1;
      end else begin
        rise <= 1'b0;
        down <= 1'b0;
      end
      a_prev <= a;
    end
  end

endmodule
module calendar (
  input CLK,
  input RST,
  output reg [5:0] Hours,
  output reg [5:0] Mins,
  output reg [5:0] Secs
);

  always @(posedge CLK or posedge RST) begin
    if (RST) begin
      Secs <= 6'b0;
    end else if (Secs == 6'b111111) begin
      Secs <= 6'b0;
    end else begin
      Secs <= Secs + 1;
    end
  end

  always @(posedge CLK or posedge RST) begin
    if (RST) begin
      Mins <= 6'b0;
    end else if (Secs == 6'b111111 && Mins == 6'b111111) begin
      Mins <= 6'b0;
    end else if (Secs == 6'b111111) begin
      Mins <= Mins + 1;
    end
  end

  always @(posedge CLK or posedge RST) begin
    if (RST) begin
      Hours <= 6'b0;
    end else if (Secs == 6'b111111 && Mins == 6'b111111 && Hours == 6'b111111) begin
      Hours <= 6'b0;
    end else if (Secs == 6'b111111 && Mins == 6'b111111) begin
      Hours <= Hours + 1;
    end
  end

endmodule