dakies/OSS_Verilog huggingface dataset:
module booth4_mul_tb () ;
    reg signed [`width-1:0] a, b;
    reg             clk, reset;

    wire signed [2*`width-1:0] p;
    wire           rdy;

    integer total, err;
    integer i, s, fp, numtests;

    wire signed [2*`width-1:0] ans = a*b;

    multi_booth_8bit dut( .clk(clk),
        .reset(reset),
        .a(a),
        .b(b),
        .p(p),
        .rdy(rdy));

    // Set up 10ns clock
    always #5 clk = ~clk;

    task apply_and_check;
        input [`width-1:0] ain;
        input [`width-1:0] bin;
        begin
            // Set the inputs
            a = ain;
            b = bin;
            // Reset the DUT for one clock cycle
            reset = 1;
            @(posedge clk);
            // Remove reset 
            #1 reset = 0;

            while (rdy == 0) begin
                @(posedge clk); // Wait for one clock cycle
            end
            if (p == ans) begin
                // $display($time, " Passed %d * %d = %d", a, b, p);
            end else begin
                // $display($time, " Fail %d * %d: %d instead of %d", a, b, p, ans);
                err = err + 1;
            end
            total = total + 1;
        end
    endtask // apply_and_check

    initial begin
        clk = 1;
        total = 0;
        err = 0;

        // Get all inputs from file: 1st line has number of inputs
        fp = $fopen(`TESTFILE, "r");
        s = $fscanf(fp, "%d\n", numtests);
        // Sequences of values pumped through DUT 
        for (i=0; i<numtests; i=i+1) begin
            s = $fscanf(fp, "%d %d\n", a, b);
            apply_and_check(a, b);
        end
        if (err > 0) begin
            $display("=========== Failed ===========");
        end else begin
            $display("===========Your Design Passed===========");
        end
        $finish;
    end

endmodule
module right_shifter_tb;
  reg clk;
  reg d;
  wire [7:0] q;

  // Instantiate the DUT (Design Under Test)
  right_shifter dut (
    .clk(clk),
    .d(d),
    .q(q)
  );

  // Generate clock
  always #5 clk = ~clk;

  initial begin
    // Initialize inputs
    clk = 0;
    d = 0;
    #20;
    d = 1;
    #10;
    d = 0;
    #10;
    d = 1;
    #10;
    d = 0;
    #10;
    d = 1;
    #10;
    d = 1;
    #10;
    d = 1;
    #10;
    
    // Check the output
    if(q==8'b11101010) begin
      $display("===========Your Design Passed===========");
    end
    else begin
      $display("===========Failed===========");
    end
    // Finish simulation
    $finish;
  end
endmodule
module verified_right_shifter(clk, q,d);  

    input  clk;  
    input d;  
    output  [7:0] q;  
    reg   [7:0]  q; 
    initial q = 0;

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

endmodule
module calendar(
    input wire CLK,  // Clock input
    input wire RST,  // Active high reset signal
    output reg [5:0] Hours,  // 6-bit output for hours (0-23)
    output reg [5:0] Mins,   // 6-bit output for minutes (0-59)
    output reg [5:0] Secs    // 6-bit output for seconds (0-59)
);

    // Always block for seconds
    always @(posedge CLK or posedge RST) begin
        if (RST) begin
            // Reset seconds to 0
            Secs <= 0;
        end else if (Secs == 59) begin
            // Wrap around and increment minutes
            Secs <= 0;
        end else begin
            // Increment seconds
            Secs <= Secs + 1;
        end
    end

    // Always block for minutes
    always @(posedge CLK or posedge RST) begin
        if (RST) begin
            // Reset minutes to 0
            Mins <= 0;
        end else if (Secs == 59 && Mins == 59) begin
            // Wrap around and increment hours
            Mins <= 0;
        end else if (Secs == 59) begin
            // Increment minutes
            Mins <= Mins + 1;
        end
        // No else part needed, minutes stay the same if Secs is not 59
    end

    // Always block for hours
    always @(posedge CLK or posedge RST) begin
        if (RST) begin
            // Reset hours to 0
            Hours <= 0;
        end else if (Secs == 59 && Mins == 59 && Hours == 23) begin
            // Wrap around to 0 after 23:59:59
            Hours <= 0;
        end else if (Secs == 59 && Mins == 59) begin
            // Increment hours
            Hours <= Hours + 1;
        end
        // No else part needed, hours stay the same if Secs and Mins are not 59
    end

endmodule
module traffic_light(
    input wire rst_n,
    input wire clk,
    input wire pass_request,
    output reg red,
    output reg yellow,
    output reg green,
    output [7:0] clock
);

    // State encoding
    parameter s1_red = 2'b00,
              s2_yellow = 2'b01,
              s3_green = 2'b10;

    // Internal variables
    reg [7:0] cnt;
    reg [1:0] state, next_state;

    // Counter logic
    always @(posedge clk or negedge rst_n) begin
        if (!rst_n) begin
            cnt <= 8'd60; // Reset count to default green time
        end else if (state == s3_green && pass_request && cnt > 10) begin
            cnt <= 8'd10; // Pedestrian request, shorten green if > 10
        end else if (cnt == 0) begin
            case (state)
                s1_red:    cnt <= 8'd60; // Red to green
                s2_yellow: cnt <= 8'd10; // Yellow to red
                s3_green:  cnt <= 8'd5;  // Green to yellow
                default:   cnt <= 8'd60;
            endcase
        end else begin
            cnt <= cnt - 1; // Decrement counter
        end
    end

    // FSM logic for state transitions
    always @(posedge clk or negedge rst_n) begin
        if (!rst_n) begin
            state <= s1_red; // Reset to red state
        end else begin
            state <= next_state;
        end
    end

    // FSM next state logic
    always @(*) begin
        case (state)
            s1_red:    next_state = (cnt == 0) ? s3_green : s1_red;
            s2_yellow: next_state = (cnt == 0) ? s1_red : s2_yellow;
            s3_green:  next_state = (cnt == 0 || (pass_request && cnt <= 10)) ? s2_yellow : s3_green;
            default:   next_state = s1_red;
        endcase
    end

    // Output logic
    always @(posedge clk or negedge rst_n) begin
        if (!rst_n) begin
            red <= 1;
            yellow <= 0;
            green <= 0;
        end else begin
            case (state)
                s1_red: begin
                    red <= 1;
                    yellow <= 0;
                    green <= 0;
                end
                s2_yellow: begin
                    red <= 0;
                    yellow <= 1;
                    green <= 0;
                end
                s3_green: begin
                    red <= 0;
                    yellow <= 0;
                    green <= 1;
                end
            endcase
        end
    end

    // Assign the internal counter to an output port for monitoring
    assign clock = cnt;

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
);

// Internal register to store the first half of the data
reg [7:0] data_lock;
reg data_lock_valid;

always @(posedge clk or negedge rst_n) begin
    if (!rst_n) begin
        // Reset the output and internal registers
        data_out <= 16'd0;
        valid_out <= 1'b0;
        data_lock <= 8'd0;
        data_lock_valid <= 1'b0;
    end else begin
        if (valid_in) begin
            if (data_lock_valid) begin
                // If we have valid data locked, concatenate with new data
                data_out <= {data_lock, data_in};
                data_lock <= 8'd0; // Clear the lock register
                valid_out <= 1'b1; // Set output valid
                data_lock_valid <= 1'b0; // Clear the lock valid flag
            end else begin
                // Store the first half of the data
                data_lock <= data_in;
                data_lock_valid <= 1'b1; // Set the lock valid flag
                valid_out <= 1'b0; // Clear the output valid as we wait for next data
            end
        end else if (data_lock_valid) begin
            // If no new valid data, but we have data locked
            // we don't update the output
            valid_out <= 1'b0;
        end
        // If no valid input and no data locked, maintain the current state
    end
end

endmodule
module JC_counter(
    input clk,        // Clock signal
    input rst_n,      // Active-low reset
    output reg [63:0] Q  // 64-bit counter value
);

    // Counter update logic
    always @(posedge clk or negedge rst_n) begin
        if (~rst_n) begin
            // Reset condition
            Q <= 64'b0;
        end else begin
            if (Q[0] == 1'b0) begin
                // Increment (shift left and append '1' at LSB)
                Q <= {Q[62:0], 1'b1};
            end else begin
                // Decrement (shift left and append '0' at LSB)
                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
);

    // Pipeline stage registers
    reg [63:0] stage_adda;
    reg [63:0] stage_addb;
    reg stage_i_en;

    // Temp register for the sum of A and B
    reg [64:0] sum;

    // Pipeline registers for the sum
    reg [64:0] stage_sum;
    reg stage_sum_valid;

    // Synchronous reset and pipeline register control
    always @(posedge clk or negedge rst_n) begin
        if (!rst_n) begin
            // Reset all pipeline registers
            stage_adda <= 64'd0;
            stage_addb <= 64'd0;
            stage_i_en <= 1'b0;
            stage_sum <= 65'd0;
            stage_sum_valid <= 1'b0;
            result <= 65'd0;
            o_en <= 1'b0;
        end else begin
            // Move data through the pipeline on each clock edge
            if (i_en) begin
                // Latch inputs into the pipeline
                stage_adda <= adda;
                stage_addb <= addb;
                stage_i_en <= i_en;
            end

            // Perform addition in the first pipeline stage
            sum <= stage_adda + stage_addb;

            // Move result to the next pipeline stage
            stage_sum <= sum;
            stage_sum_valid <= stage_i_en;

            // The final result and output enable are updated in the last pipeline stage
            result <= stage_sum;
            o_en <= stage_sum_valid;
        end
    end

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

    // Initialize the register 'q' to 0
    initial q = 8'b00000000;

    // On each rising edge of the clock, perform the right shift operation
    always @(posedge clk) begin
        q <= {d, q[7:1]}; // Insert input 'd' into the MSB position after the shift
    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
);

    // 3-bit counter to count up to 8 bits
    reg [2:0] cnt;

    // Reset and count logic
    always @(posedge clk or negedge rst_n) begin
        if (!rst_n) begin
            // Asynchronous reset
            cnt <= 3'd0;
            dout_parallel <= 8'd0;
            dout_valid <= 1'b0;
        end
        else if (din_valid) begin
            if (cnt < 3'd7) begin
                // Shift in the serial data starting from the MSB
                dout_parallel <= {din_serial, dout_parallel[7:1]};
                cnt <= cnt + 3'd1;
                dout_valid <= 1'b0;  // Not valid until 8 bits are received
            end
            else begin
                // Shift in the last bit and assert the valid signal
                dout_parallel <= {din_serial, dout_parallel[7:1]};
                dout_valid <= 1'b1;
                cnt <= 3'd0;  // Reset the counter
            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 done
);

    reg [3:0] i; // Shift count register
    reg [15:0] areg, breg; // Registers for multiplicand and multiplier
    reg [31:0] yout_r; // Register for the product
    reg done_r; // Register for the done signal

    // Initialize the output and internal registers
    initial begin
        i = 0;
        areg = 0;
        breg = 0;
        yout_r = 0;
        done_r = 0;
        yout = 0;
    end

    // Assign the done signal to the done_r register
    assign done = done_r;

    // Control logic for multiplication
    always @(posedge clk or negedge rst_n) begin
        if (!rst_n) begin
            // Reset condition
            i <= 0;
            areg <= 0;
            breg <= 0;
            yout_r <= 0;
            done_r <= 0;
        end else if (start) begin
            if (i == 0) begin
                // Load the input values into registers
                areg <= ain;
                breg <= bin;
                yout_r <= 0; // Clear the accumulator
            end else if (i < 17) begin
                // Perform shift and accumulate if the corresponding bit in areg is set
                if (areg[i-1])
                    yout_r <= yout_r + (breg << (i - 1));
            end

            // Increment the shift count register
            if (i < 17) begin
                i <= i + 1;
            end

            // Update the done flag
            done_r <= (i == 16);
        end else begin
            // If start is not active, reset the shift count and done flag
            i <= 0;
            done_r <= 0;
        end
    end

    // Update the output register at the end of multiplication
    always @(posedge clk) begin
        if (done_r) begin
            yout <= yout_r; // Assign the accumulated product to the output
        end
    end

endmodule
module multi_pipe_4bit #(
    parameter size = 4
) (
    input wire clk,
    input wire rst_n,
    input wire [size-1:0] mul_a,
    input wire [size-1:0] mul_b,
    output wire [2*size-1:0] mul_out
);

    // Intermediate registers for pipeline stages
    reg [2*size-1:0] partial_products[size-1:0];
    reg [2*size-1:0] sum_stage1;
    reg [2*size-1:0] sum_stage2;
    reg [2*size-1:0] final_product;

    // Output assignment
    assign mul_out = final_product;

    // Generate block to create partial products
    genvar i;
    generate
        for (i = 0; i < size; i = i + 1) begin : gen_partial_products
            always @(posedge clk or negedge rst_n) begin
                if (!rst_n) begin
                    partial_products[i] <= 0;
                end else begin
                    // If the corresponding bit in the multiplier is 1,
                    // left-shift the multiplicand by i positions.
                    // Otherwise, the partial product is 0.
                    partial_products[i] <= mul_b[i] ? (mul_a << i) : 0;
                end
            end
        end
    endgenerate

    // Pipeline stage 1: Add partial products
    always @(posedge clk or negedge rst_n) begin
        if (!rst_n) begin
            sum_stage1 <= 0;
        end else begin
            sum_stage1 <= partial_products[0] + partial_products[1] +
                          partial_products[2] + partial_products[3];
        end
    end

    // Pipeline stage 2: Store the result of addition
    always @(posedge clk or negedge rst_n) begin
        if (!rst_n) begin
            sum_stage2 <= 0;
        end else begin
            sum_stage2 <= sum_stage1;
        end
    end

    // Final product calculation
    always @(posedge clk or negedge rst_n) begin
        if (!rst_n) begin
            final_product <= 0;
        end else begin
            final_product <= sum_stage2;
        end
    end

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

    // Internal counters for CLK_10 and CLK_1 generation
    reg [3:0] cnt_10 = 0;
    reg [6:0] cnt_100 = 0;

    // CLK_50 generation
    always @(posedge CLK_in or posedge RST) begin
        if (RST) begin
            CLK_50 <= 0;
        end else begin
            CLK_50 <= ~CLK_50; // Toggle the CLK_50 output
        end
    end

    // CLK_10 generation
    always @(posedge CLK_in or posedge RST) begin
        if (RST) begin
            cnt_10 <= 0;
            CLK_10 <= 0;
        end else begin
            if (cnt_10 == 4) begin
                CLK_10 <= ~CLK_10; // Toggle the CLK_10 output
                cnt_10 <= 0;
            end else begin
                cnt_10 <= cnt_10 + 1;
            end
        end
    end

    // CLK_1 generation
    always @(posedge CLK_in or posedge RST) begin
        if (RST) begin
            cnt_100 <= 0;
            CLK_1 <= 0;
        end else begin
            if (cnt_100 == 49) begin
                CLK_1 <= ~CLK_1; // Toggle the CLK_1 output
                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
);

    // Define the maximum count value as a parameter for easy changes
    parameter MAX_COUNT = 4'd11;

    always @(posedge clk or negedge rst_n) begin
        if (!rst_n) begin
            // Active low reset signal
            out <= 4'b0000;
        end else if (valid_count) begin
            // Only increment the counter if valid_count is high
            if (out == MAX_COUNT) begin
                // Reset to 0 if the counter reaches the maximum count value
                out <= 4'b0000;
            end else begin
                // Increment the counter
                out <= out + 1;
            end
        end
        // If valid_count is 0, do nothing (counter is paused)
    end

endmodule
module edge_detect(
    input wire clk,     // Clock signal
    input wire rst_n,   // Active low reset
    input wire a,       // Input signal
    output reg rise,    // Output signal for rising edge
    output reg down     // Output signal for falling edge
);

    // Register to hold the previous state of `a`
    reg a_prev;

    // On every positive edge of the clock, check for edges
    always @(posedge clk or negedge rst_n) begin
        if (!rst_n) begin
            // Active low reset: reset all the outputs and previous state
            rise <= 0;
            down <= 0;
            a_prev <= 0;
        end else begin
            // Reset the rise and down signals on every clock cycle
            rise <= 0;
            down <= 0;

            // Check for a rising edge
            if (a == 1 && a_prev == 0) begin
                rise <= 1;
            end

            // Check for a falling edge
            if (a == 0 && a_prev == 1) begin
                down <= 1;
            end

            // Update previous state of `a`
            a_prev <= a;
        end
    end

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

// Internal wires for the carry bits between full adders
wire [6:0] carry;

// Instantiate the full adders
full_adder fa0 (.a(a[0]), .b(b[0]), .cin(cin),     .sum(sum[0]), .cout(carry[0]));
full_adder fa1 (.a(a[1]), .b(b[1]), .cin(carry[0]), .sum(sum[1]), .cout(carry[1]));
full_adder fa2 (.a(a[2]), .b(b[2]), .cin(carry[1]), .sum(sum[2]), .cout(carry[2]));
full_adder fa3 (.a(a[3]), .b(b[3]), .cin(carry[2]), .sum(sum[3]), .cout(carry[3]));
full_adder fa4 (.a(a[4]), .b(b[4]), .cin(carry[3]), .sum(sum[4]), .cout(carry[4]));
full_adder fa5 (.a(a[5]), .b(b[5]), .cin(carry[4]), .sum(sum[5]), .cout(carry[5]));
full_adder fa6 (.a(a[6]), .b(b[6]), .cin(carry[5]), .sum(sum[6]), .cout(carry[6]));
full_adder fa7 (.a(a[7]), .b(b[7]), .cin(carry[6]), .sum(sum[7]), .cout(cout));

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

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

endmodule
module multi_pipe_8bit(
    input wire clk,
    input wire rst_n,
    input wire mul_en_in,
    input wire [7:0] mul_a,
    input wire [7:0] mul_b,
    output reg mul_en_out,
    output reg [15:0] mul_out
);

    reg [7:0] mul_a_reg, mul_b_reg;
    reg mul_en_in_reg;
    reg [15:0] partials[7:0]; // Array to store partial products
    reg [15:0] partial_sum;   // Register to store partial sum

    // Pipeline stage registers
    reg [15:0] stage1, stage2, stage3, stage4, stage5, stage6, stage7;

    // Input control logic
    always @(posedge clk or negedge rst_n) begin
        if (!rst_n) begin
            mul_a_reg <= 0;
            mul_b_reg <= 0;
            mul_en_in_reg <= 0;
        end else if (mul_en_in) begin
            mul_a_reg <= mul_a;
            mul_b_reg <= mul_b;
            mul_en_in_reg <= mul_en_in;
        end
    end

    // Generate partial products
    integer i;
    always @(posedge clk or negedge rst_n) begin
        if (!rst_n) begin
            for (i = 0; i < 8; i = i + 1)
                partials[i] <= 0;
        end else if (mul_en_in_reg) begin
            for (i = 0; i < 8; i = i + 1)
                partials[i] <= mul_b_reg[i] ? (mul_a_reg << i) : 0;
        end
    end

    // Calculate partial sums and pipeline them through the stages
    always @(posedge clk or negedge rst_n) begin
        if (!rst_n) begin
            partial_sum <= 0;
            stage1 <= 0;
            stage2 <= 0;
            stage3 <= 0;
            stage4 <= 0;
            stage5 <= 0;
            stage6 <= 0;
            stage7 <= 0;
        end else begin
            partial_sum <= partials[0] + partials[1];
            stage1 <= partial_sum + partials[2];
            stage2 <= stage1 + partials[3];
            stage3 <= stage2 + partials[4];
            stage4 <= stage3 + partials[5];
            stage5 <= stage4 + partials[6];
            stage6 <= stage5 + partials[7];
            stage7 <= stage6;
        end
    end

    // Output logic
    always @(posedge clk or negedge rst_n) begin
        if (!rst_n) begin
            mul_out <= 0;
            mul_en_out <= 0;
        end else begin
            mul_out <= stage7;
            mul_en_out <= mul_en_in_reg;
        end
    end

endmodule
module parallel2serial(
    input wire clk,
    input wire rst_n,
    input wire [3:0] d,
    output reg valid_out,
    output reg dout
);

    // State representation
    reg [1:0] cnt; // 2-bit counter to keep track of the shifting
    reg [3:0] data; // Register to hold the current data

    always @(posedge clk or negedge rst_n) begin
        if (!rst_n) begin
            // Synchronous reset: reset counter and output
            cnt <= 2'b00;
            valid_out <= 1'b0;
            dout <= 1'b0;
            data <= 4'd0;
        end else begin
            if (cnt == 3) begin
                // Last bit was shifted out, load new data and reset counter
                data <= d;
                cnt <= 2'b00;
                valid_out <= 1'b1; // Indicate that valid data is available
                dout <= d[3]; // Output MSB
            end else begin
                // Shift data and increment counter
                data <= data << 1; // Shift left by 1 bit
                dout <= data[3]; // Output next bit
                cnt <= cnt + 1'b1;
                valid_out <= (cnt == 2'b00)? 1'b1 : 1'b0; // Set valid_out only when new data is loaded
            end
        end
    end

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

    // FSM states
    localparam IDLE = 2'b00,
               SUB = 2'b01,
               SHIFT = 2'b10,
               DONE = 2'b11;
    
    // Registers for FSM, counters and extended operands
    reg [1:0] current_state, next_state;
    reg [DATAWIDTH:0] dividend_e, divisor_e, remainder_e;
    reg [DATAWIDTH-1:0] quotient_e;
    reg [DATAWIDTH-1:0] count;

    // FSM state transition and data computation
    always @(posedge clk or negedge rstn) begin
        if (!rstn) begin
            current_state <= IDLE;
            quotient_e <= 0;
            remainder_e <= 0;
            dividend_e <= 0;
            divisor_e <= 0;
            count <= 0;
            ready <= 1;
            vld_out <= 0;
        end else begin
            case (current_state)
                IDLE: begin
                    if (en) begin
                        current_state <= SUB;
                        dividend_e <= {1'b0, dividend};
                        divisor_e <= {1'b0, divisor};
                        quotient_e <= 0;
                        remainder_e <= 0;
                        count <= DATAWIDTH;
                        ready <= 0;
                        vld_out <= 0;
                    end
                end
                SUB: begin
                    if (dividend_e >= divisor_e) begin
                        remainder_e <= dividend_e - divisor_e;
                        quotient_e[0] <= 1;
                    end else begin
                        remainder_e <= dividend_e;
                        quotient_e[0] <= 0;
                    end
                    current_state <= SHIFT;
                end
                SHIFT: begin
                    if (count > 0) begin
                        count <= count - 1;
                        quotient_e <= {quotient_e[DATAWIDTH-2:0], 1'b0};
                        dividend_e <= {remainder_e[DATAWIDTH-2:0], dividend_e[0], 1'b0};
                        current_state <= SUB;
                    end else begin
                        current_state <= DONE;
                    end
                end
                DONE: begin
                    quotient <= quotient_e;
                    remainder <= remainder_e[DATAWIDTH-1:0];
                    ready <= 1;
                    vld_out <= 1;
                    if (!en) current_state <= IDLE;
                end
            endcase
        end
    end

    // Output assignments
    always @(*) begin
        case (current_state)
            IDLE: begin
                ready = 1'b1;
            end
            DONE: begin
                vld_out = 1'b1;
            end
            default: begin
                ready = 1'b0;
                vld_out = 1'b0;
            end
        endcase
    end

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

// Internal variables
reg [9:0] sum; // 10-bit sum to hold the accumulated value
reg [1:0] count; // Counter to count the number of valid inputs

always @(posedge clk or negedge rst_n) begin
    if (!rst_n) begin
        // Reset all registers when reset is active
        sum <= 10'd0;
        count <= 2'd0;
        data_out <= 10'd0;
        valid_out <= 1'b0;
    end else if (valid_in) begin
        // If valid_in is high, accumulate the data_in
        if (count == 3) begin
            // If already received 3 inputs, then this is the 4th one
            sum <= sum + data_in; // Add the current data to the sum
            data_out <= sum + data_in; // Update the data_out with the full sum
            valid_out <= 1'b1; // Set the valid_out high for one cycle
            count <= 2'd0; // Reset the count for the next set of inputs
            sum <= 10'd0; // Reset the sum for the next set of inputs
        end else begin
            // If count is less than 3, accumulate the sum
            sum <= sum + data_in; // Add the current data to the sum
            count <= count + 1'b1; // Increment the count
            valid_out <= 1'b0; // Make sure valid_out is low
        end
    end else begin
        // If valid_in is not high, do not accumulate and keep valid_out low
        valid_out <= 1'b0;
    end
end

endmodule
module div_16bit (
    input [15:0] A,
    input [7:0] B,
    output reg [15:0] result,
    output reg [15:0] odd
);

    // Temporary variables for intermediate values
    reg [15:0] temp_dividend;
    reg [7:0] temp_divisor;
    reg [15:0] temp_result;
    reg [15:0] temp_odd;

    integer i;

    always @* begin
        // Initial assignments
        temp_dividend = A;
        temp_divisor = B;
        temp_result = 0;
        temp_odd = 0;

        // Check for divide by zero case
        if (temp_divisor != 0) begin
            for (i = 15; i >= 0; i = i - 1) begin
                // Shift left the odd to make room for the new bit
                temp_odd = temp_odd << 1;
                // Bring down the next bit from the dividend
                temp_odd[0] = temp_dividend[i];
                // Compare the higher bits of dividend with the divisor
                if (temp_odd >= {8'b0, temp_divisor}) begin
                    // Subtract the divisor from the current portion of the dividend
                    temp_odd = temp_odd - {8'b0, temp_divisor};
                    // Set the current bit in the quotient
                    temp_result[i] = 1'b1;
                end
            end
        end else begin
            // If B is 0, it's an undefined operation, typically handled separately
            // For this example, just set result and odd to all zeros
            temp_result = 16'b0;
            temp_odd = 16'b0;
        end

        // Assign the results to the outputs
        result = temp_result;
        odd = temp_odd;
    end

endmodule
module signal_generator (
    input clk,
    input rst_n,
    output reg [4:0] wave // 5-bit output for wave
);

    // State register declaration
    reg state;
    
    // Define states for readability
    localparam STATE_INCREASING = 1'b0;
    localparam STATE_DECREASING = 1'b1;

    // Waveform generation and state management
    always @(posedge clk or negedge rst_n) begin
        if (!rst_n) begin
            // Reset condition
            wave <= 5'd0;
            state <= STATE_INCREASING;
        end else begin
            case (state)
                STATE_INCREASING: begin
                    if (wave == 5'd31) begin
                        // Transition to decreasing state
                        state <= STATE_DECREASING;
                        wave <= wave - 5'd1;
                    end else begin
                        // Increment wave
                        wave <= wave + 5'd1;
                    end
                end
                STATE_DECREASING: begin
                    if (wave == 5'd0) begin
                        // Transition to increasing state
                        state <= STATE_INCREASING;
                        wave <= wave + 5'd1;
                    end else begin
                        // Decrement wave
                        wave <= wave - 5'd1;
                    end
                end
                default: begin
                    // Just in case we get into an unknown state, reset to a known state
                    state <= STATE_INCREASING;
                    wave <= 5'd0;
                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 [8:0] multiplier; // Extra bit for the Booth algorithm
    reg [3:0] ctr;       // Counter for iterations
    reg [1:0] booth_code;

    always @(posedge clk or posedge reset) begin
        if (reset) begin
            // Initialize the multiplier module
            multiplicand <= 0;
            multiplier <= {1'b0, b};
            p <= 0;
            ctr <= 0;
            rdy <= 0;
        end else begin
            // Check if the multiplication process is completed
            if (ctr < 8) begin
                booth_code <= {multiplier[1:0], 1'b0}; // Radix-4 Booth encoding
                
                case (booth_code)
                    3'b001, 3'b010: p <= p + (multiplicand << (2 * ctr)); // +A operation
                    3'b101, 3'b110: p <= p - (multiplicand << (2 * ctr)); // -A operation
                    // For 3'b000, 3'b011, 3'b100, and 3'b111, no operation is performed on p
                endcase

                // Prepare for the next iteration
                multiplier <= multiplier >> 2; // Radix-4 right shift
                ctr <= ctr + 1;
            end else if (ctr == 8) begin
                // Indicate that the multiplication process is completed
                rdy <= 1;
                ctr <= ctr + 1; // Increment ctr to stop the operation
            end
        end
    end

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

    // Intermediate register to store the product of a and b
    reg [63:0] product;

    always @(posedge clk or posedge rst) begin
        if (rst) begin
            // Reset the accumulator to 0 when rst is high
            c <= 32'd0;
        end else begin
            // Perform the multiply-accumulate operation
            product <= a * b; // Multiply a by b
            c <= c + product[31:0]; // Accumulate the lower 32 bits of the product
        end
    end

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

    // Define the operation parameters
    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;

    // Set the zero flag
    assign zero = (r == 32'b0);

    always @(*) begin
        // Initialize outputs
        carry = 0;
        overflow = 0;
        negative = 0;
        flag = 0;
        
        case (aluc)
            ADD: begin
                // Signed addition
                {carry, r} = a + b;
                overflow = (a[31] & b[31] & ~r[31]) | (~a[31] & ~b[31] & r[31]);
                negative = r[31];
            end
            ADDU: begin
                // Unsigned addition
                {carry, r} = a + b;
                // No overflow for unsigned addition
            end
            SUB: begin
                // Signed subtraction
                {carry, r} = a - b;
                overflow = (~a[31] & b[31] & r[31]) | (a[31] & ~b[31] & ~r[31]);
                negative = r[31];
            end
            SUBU: begin
                // Unsigned subtraction
                {carry, r} = a - b;
                // No overflow for unsigned subtraction
            end
            AND: r = a & b;
            OR: r = a | b;
            XOR: r = a ^ b;
            NOR: r = ~(a | b);
            SLT: begin
                // Set flag if a < b (signed)
                flag = $signed(a) < $signed(b);
                r = flag;
                negative = r[31];
            end
            SLTU: begin
                // Set flag if a < b (unsigned)
                flag = a < b;
                r = flag;
            end
            SLL: r = b << a[4:0];
            SRL: r = b >> a[4:0];
            SRA: r = $signed(b) >>> a[4:0];
            SLLV: r = b << a;
            SRLV: r = b >> a;
            SRAV: r = $signed(b) >>> a;
            LUI: r = {b[15:0], 16'b0};
            default: r = 32'bx; // Undefined operation
        endcase
    end

endmodule
module full_adder_1bit(
    input a,
    input b,
    input cin,
    output sum,
    output cout
);
    assign {cout, sum} = a + b + cin;
endmodule
module adder_8bit(
    input [7:0] a,
    input [7:0] b,
    input cin,
    output [7:0] sum,
    output cout
);
    wire[6:0] carry;

    genvar i;
    generate
        for(i = 0; i < 7; i = i + 1) begin : gen_full_adder
            if (i == 0) begin
                full_adder_1bit fa(a[i], b[i], cin, sum[i], carry[i]);
            end else begin
                full_adder_1bit fa(a[i], b[i], carry[i-1], sum[i], carry[i]);
            end
        end
    endgenerate

    full_adder_1bit fa_last(a[7], b[7], carry[6], sum[7], cout);
endmodule
module adder_16bit(
    input [15:0] a,
    input [15:0] b,
    input Cin,
    output [15:0] y,
    output Co
);
    wire cout_first; // Carry out from the first 8-bit adder

    // First 8-bit adder
    adder_8bit adder_lower(
        .a(a[7:0]),
        .b(b[7:0]),
        .cin(Cin),
        .sum(y[7:0]),
        .cout(cout_first)
    );

    // Second 8-bit adder
    adder_8bit adder_upper(
        .a(a[15:8]),
        .b(b[15:8]),
        .cin(cout_first),
        .sum(y[15:8]),
        .cout(Co)
    );

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

    // State definition
    parameter IDLE = 2'b00;
    parameter PULSE_START = 2'b01;
    parameter PULSE_END = 2'b11;

    // State register
    reg [1:0] current_state, next_state;

    // State transition logic
    always @(posedge clk or negedge rst_n) begin
        if (~rst_n) begin
            // Reset condition
            current_state <= IDLE;
        end else begin
            // Update state
            current_state <= next_state;
        end
    end

    // Next state logic
    always @(*) begin
        // Default assignment
        next_state = current_state;
        case (current_state)
            IDLE: begin
                if (data_in == 1'b1) begin
                    next_state = PULSE_START;
                end
            end
            PULSE_START: begin
                if (data_in == 1'b0) begin
                    next_state = PULSE_END;
                end
            end
            PULSE_END: begin
                next_state = IDLE;
            end
            default: next_state = IDLE;
        endcase
    end

    // Output logic
    always @(posedge clk or negedge rst_n) begin
        if (~rst_n) begin
            // Reset condition
            data_out <= 1'b0;
        end else begin
            // Generate output based on current state
            case (current_state)
                PULSE_START: data_out <= 1'b0;
                PULSE_END: data_out <= 1'b1;
                default: data_out <= 1'b0;
            endcase
        end
    end

endmodule
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
);

    // Data and enable registers for clk_a domain
    reg [3:0] data_reg;
    reg en_data_reg;

    // Double-registering for en_data_reg in clk_b domain for synchronization
    reg en_clap_one;
    reg en_clap_two;

    // Register data_in on clk_a domain
    always @(posedge clk_a or negedge arstn) begin
        if (!arstn) begin
            data_reg <= 4'd0;
            en_data_reg <= 1'b0;
        end else begin
            data_reg <= data_in;
            en_data_reg <= data_en;
        end
    end

    // Synchronize the enable signal to clk_b domain
    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; // First D flip-flop for en_data_reg
            en_clap_two <= en_clap_one;  // Second D flip-flop for en_data_reg
        end
    end

    // Assign dataout based on synchronized enable signal (en_clap_two)
    always @(posedge clk_b or negedge brstn) begin
        if (!brstn) begin
            dataout <= 4'd0;
        end else if (en_clap_two) begin
            // Only update dataout when the enable signal has been stable high for two clk_b cycles
            dataout <= data_reg;
        end
        // If en_clap_two is low, retain the previous value (no need for an else statement)
    end

endmodule
module calendar(
    input CLK,   // Clock input
    input RST,   // Active high reset signal
    output reg [5:0] Hours, // 6-bit output for hours
    output reg [5:0] Mins,  // 6-bit output for minutes
    output reg [5:0] Secs   // 6-bit output for seconds
);

    // Update seconds
    always @(posedge CLK or posedge RST) begin
        if (RST) begin
            Secs <= 0;
        end else if (Secs == 59) begin
            Secs <= 0;
        end else begin
            Secs <= Secs + 1;
        end
    end

    // Update minutes
    always @(posedge CLK or posedge RST) begin
        if (RST) begin
            Mins <= 0;
        end else if (Secs == 59 && Mins == 59) begin
            Mins <= 0;
        end else if (Secs == 59) begin
            Mins <= Mins + 1;
        end
    end

    // Update hours
    always @(posedge CLK or posedge RST) begin
        if (RST) begin
            Hours <= 0;
        end else if (Secs == 59 && Mins == 59 && Hours == 23) begin
            Hours <= 0;
        end else if (Secs == 59 && Mins == 59) begin
            Hours <= Hours + 1;
        end
    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
);

// Internal signal to store the first half of the data
reg [7:0] data_lock;
// Flag to indicate that the first half is stored
reg flag;

// Data handling and output generation
always @(posedge clk or negedge rst_n) begin
    if (!rst_n) begin
        // Reset the output and internal registers
        data_out <= 16'd0;
        valid_out <= 1'b0;
        data_lock <= 8'd0;
        flag <= 1'b0;
    end else if (valid_in) begin
        if (flag) begin
            // If we have a stored first half, concatenate with the new input
            data_out <= {data_lock, data_in};
            valid_out <= 1'b1; // Output is now valid
            flag <= 1'b0; // Clear the flag as we've used the stored half
        end else begin
            // Store the first half of the data
            data_lock <= data_in;
            flag <= 1'b1;
            valid_out <= 1'b0; // Output is not valid until we get the second half
        end
    end else if (!valid_in && flag) begin
        // If no valid input and we have a stored first half, do not change the state
        valid_out <= 1'b0;
    end
end

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

    // Johnson counter update logic
    always @(posedge clk or negedge rst_n) begin
        if (!rst_n) begin
            // Active-low reset is asserted, initialize the counter
            Q <= 64'b0;
        end else begin
            // Shift the counter and append bits at the ends according to the pattern
            Q <= {Q[62:0], ~Q[63]};
        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
);

// Internal signals for pipeline stages
reg [63:0] adda_reg, addb_reg;
reg [64:0] sum_reg;
reg i_en_reg, i_en_reg2; // Registered versions of i_en to create pipeline stages

// Pipeline stage 1: Register inputs and i_en
always @(posedge clk or negedge rst_n) begin
    if (!rst_n) begin
        adda_reg <= 0;
        addb_reg <= 0;
        i_en_reg <= 0;
    end else begin
        if (i_en) begin
            adda_reg <= adda;
            addb_reg <= addb;
        end
        i_en_reg <= i_en; // Capture the enable signal
    end
end

// Pipeline stage 2: Perform addition
always @(posedge clk or negedge rst_n) begin
    if (!rst_n) begin
        sum_reg <= 0;
        i_en_reg2 <= 0;
    end else begin
        if (i_en_reg) begin
            sum_reg <= adda_reg + addb_reg; // Perform the addition
        end
        i_en_reg2 <= i_en_reg; // Move enable signal down the pipeline
    end
end

// Pipeline stage 3: Output result and o_en
always @(posedge clk or negedge rst_n) begin
    if (!rst_n) begin
        result <= 0;
        o_en <= 0;
    end else begin
        result <= sum_reg; // Pass the sum to the output
        o_en <= i_en_reg2; // Output enable signal goes high when the result is valid
    end
end

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

    // Initialize the q register to 0
    initial begin
        q = 8'b00000000;
    end

    // Perform the shift operation on the rising edge of the clock
    always @(posedge clk) begin
        q <= {d, q[7:1]}; // Shift right q and insert d at the MSB
    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
);

// Internal counter to track the number of received bits
reg [2:0] cnt; // 3 bits to count up to 8

always @(posedge clk or negedge rst_n) begin
    if (!rst_n) begin
        // Asynchronous reset: clear the counter and output registers
        cnt <= 3'b000;
        dout_parallel <= 8'b00000000;
        dout_valid <= 1'b0;
    end else if (din_valid) begin
        // If input is valid, shift in the new bit and increment the counter
        dout_parallel <= {din_serial, dout_parallel[7:1]};
        cnt <= cnt + 1'b1;
        
        // Check if 8 bits have been shifted in
        if (cnt == 3'b111) begin
            // Indicate that the output is valid on the 8th bit
            dout_valid <= 1'b1;
            cnt <= 3'b000; // Reset the counter for the next cycle
        end else begin
            // Output is not yet valid
            dout_valid <= 1'b0;
        end
    end else begin
        // If input is not valid, just clear the valid output signal
        dout_valid <= 1'b0;
    end
end

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

    reg [31:0] product;
    reg [4:0] count;
    reg [15:0] multiplicand, multiplier;
    reg multiply_started;

    // Control logic for starting the multiplication
    always @(posedge clk or negedge rst_n) begin
        if (!rst_n) begin
            multiply_started <= 1'b0;
            count <= 5'b0;
            done <= 1'b0;
        end else if (start && !multiply_started) begin
            multiply_started <= 1'b1;
            multiplicand <= ain;
            multiplier <= bin;
            product <= 32'b0;
            count <= 5'b0;
            done <= 1'b0;
        end else if (multiply_started) begin
            if (count < 16) begin
                // Shift and accumulate
                if (multiplier[0]) begin
                    product <= product + (multiplicand << count);
                end
                multiplier <= multiplier >> 1;
                count <= count + 1;
            end else begin
                // Finish the multiplication
                multiply_started <= 1'b0;
                done <= 1'b1;
            end
        end else if (done) begin
            done <= 1'b0; // Clear the done flag once multiplication is complete
        end
    end

    // Assign the product to the output
    always @(posedge clk) begin
        if (done) begin
            yout <= product; // Output the final product
        end
    end

endmodule