dakies/OSS_Verilog huggingface dataset:
module div_16bit(
    input [15:0] A,   // 16-bit dividend
    input [7:0] B,    // 8-bit divisor
    output reg [15:0] result, // 16-bit quotient
    output reg [15:0] odd     // 16-bit remainder
);

    // Internal signals for the operation
    reg [15:0] dividend;
    reg [8:0] divisor; // 9 bits to accommodate subtraction
    reg [15:0] quotient;
    reg [15:0] remainder;
    integer i;

    always @(*) begin
        // Initialize the internal signals
        dividend = A;
        divisor = {1'b0, B}; // Extend divisor to 9 bits for subtraction
        quotient = 0;
        remainder = 0;

        // Perform division operation
        for (i = 15; i >= 0; i = i - 1) begin
            // Shift the remainder to the left by 1 bit
            remainder = remainder << 1;
            // Bring down the next bit from the dividend
            remainder[0] = dividend[i];

            // Compare the upper bits of the remainder with the divisor
            if (remainder[8:1] >= divisor) begin
                // If remainder is greater or equal, subtract divisor from remainder
                remainder = remainder - divisor;
                // Set the quotient bit to 1
                quotient[i] = 1'b1;
            end
            else begin
                // Otherwise, the quotient bit remains 0
                quotient[i] = 1'b0;
            end
        end

        // Set the output values
        result = quotient;
        odd = remainder;
    end

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

    // Internal state register to control the direction of the count
    reg state;

    // Define the state values for clarity
    localparam STATE_UP = 1'b0;
    localparam STATE_DOWN = 1'b1;

    // Reset and waveform generation are handled on the rising edge of the clock
    always @(posedge clk or negedge rst_n) begin
        if (~rst_n) begin
            // Resetting the module
            wave <= 5'b00000;
            state <= STATE_UP; // Start by incrementing
        end else begin
            case (state)
                STATE_UP: begin
                    // Check if wave reached the max value
                    if (wave == 5'b11111) begin
                        state <= STATE_DOWN; // Change state to down
                        wave <= wave - 1'b1;
                    end else begin
                        wave <= wave + 1'b1; // Increment wave
                    end
                end
                STATE_DOWN: begin
                    // Check if wave reached the min value
                    if (wave == 5'b00000) begin
                        state <= STATE_UP; // Change state to up
                        wave <= wave + 1'b1;
                    end else begin
                        wave <= wave - 1'b1; // Decrement wave
                    end
                end
                default: begin
                    // In case of an undefined state, reset to known state
                    state <= STATE_UP;
                    wave <= 5'b00000;
                end
            endcase
        end
    end
endmodule
module multi_booth_8bit (
    input wire clk,
    input wire reset,
    input wire [7:0] a,
    input wire [7:0] b,
    output reg [15:0] p,
    output reg rdy
);

    // Internal signals
    reg [7:0] multiplicand;  // Extended multiplicand
    reg [8:0] multiplier;    // Extended multiplier and an extra bit for the algorithm
    reg [4:0] ctr;           // 5-bit counter (for 8-bit multiplication, we need 8*2 steps)
    reg [16:0] product;      // Extended product to hold intermediate values (1 extra bit)
    reg neg;

    // Booth multiplier control logic
    always @(posedge clk or posedge reset) begin
        if (reset) begin
            // Reset the multiplier
            multiplicand <= 0;
            multiplier <= {1'b0, b};
            product <= 0;
            ctr <= 0;
            rdy <= 0;
            neg <= 0;
        end else begin
            if (ctr < 9) begin
                // Radix-2 Booth's algorithm operations
                case ({multiplier[1], multiplier[0]})
                    2'b01: product[16:1] <= product[16:1] + {a, 1'b0};
                    2'b10: product[16:1] <= product[16:1] - {a, 1'b0};
                    default: ; // No operation for 00 and 11
                endcase
                
                // Prepare for the next iteration
                product <= product >> 1; // Arithmetic shift right
                product[16] <= product[15]; // Sign extension
                multiplier <= multiplier >> 1; // Logical shift right
                ctr <= ctr + 1;
            end else if (ctr == 9) begin
                // Final step: adjust for sign extension if needed
                if (neg) begin
                    product <= product - {a, 8'h00};
                end
                p <= product[16:1]; // Assign the final product
                rdy <= 1; // Indicate completion
                ctr <= ctr + 1; // Increment counter to stop the process
            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
);

// Multiplication and accumulation
always @(posedge clk or posedge rst) begin
    if (rst) begin
        // Synchronous reset: set the accumulator to zero
        c <= 32'd0;
    end else begin
        // Multiply and accumulate
        c <= c + (a * b);
    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
);

    // Opcodes for the operations
    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;

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

    always @(*) begin
        carry = 1'b0;
        overflow = 1'b0;
        negative = 1'b0;
        flag = 1'b0;

        case (aluc)
            ADD: begin
                {carry, r} = a + b;
                overflow = (a[31] & b[31] & ~r[31]) | (~a[31] & ~b[31] & r[31]);
            end
            ADDU: begin
                r = a + b; // Carry is ignored in ADDU.
            end
            SUB: begin
                {carry, r} = a - b;
                overflow = (~a[31] & b[31] & r[31]) | (a[31] & ~b[31] & ~r[31]);
            end
            SUBU: begin
                r = a - b; // Carry is ignored in SUBU.
            end
            AND: r = a & b;
            OR: r = a | b;
            XOR: r = a ^ b;
            NOR: r = ~(a | b);
            SLT: begin
                r = $signed(a) < $signed(b);
                flag = r[0];
            end
            SLTU: begin
                r = a < b;
                flag = r[0];
            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'hz; // High-impedance for undefined operations
        endcase

        negative = r[31]; // Set the negative flag based on the result's sign bit.
    end

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

    // State definitions (one-hot encoding for clarity)
    localparam [2:0] IDLE = 3'b001,
                     PULSE_START = 3'b010,
                     PULSE_END = 3'b100;

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

    // Sequential logic for state transition
    always @(posedge clk or negedge rst_n) begin
        if (!rst_n) begin
            // Synchronous reset (active low)
            current_state <= IDLE;
            data_out <= 1'b0;
        end else begin
            current_state <= next_state; // State transition
        end
    end

    // Combinatorial logic for next state and output
    always @(*) begin
        // Default assignments
        next_state = current_state; 
        data_out = 1'b0;

        case (current_state)
            IDLE: begin
                // Waiting for pulse start
                if (data_in == 1'b1) begin
                    next_state = PULSE_START;
                end
            end
            PULSE_START: begin
                // Pulse started, waiting for pulse end
                if (data_in == 1'b0) begin
                    next_state = PULSE_END;
                end
            end
            PULSE_END: begin
                // End of pulse detected, generate output pulse
                data_out = 1'b1;
                // Wait for next pulse
                if (data_in == 1'b0) begin
                    next_state = IDLE;
                end else if (data_in == 1'b1) begin
                    // Handle case where pulse remains high and goes back to low
                    next_state = PULSE_START;
                end
            end
            default: begin
                // Should not reach here, but return to a known state
                next_state = IDLE;
            end
        endcase
    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
);

    // Register to store the input data
    reg [3:0] data_reg;

    // Register to store the input enable signal
    reg en_data_reg;

    // Registers to synchronize the enable signal with clk_b
    reg en_clk_b_one;
    reg en_clk_b_two;

    // Synchronize data_in with clk_a
    always @(posedge clk_a or negedge arstn) begin
        if (~arstn) begin
            data_reg <= 4'b0000;  // Clear data register on reset
        end else if (data_en) begin
            data_reg <= data_in;  // Update data register when data_en is high
        end
    end

    // Synchronize data_en with clk_a
    always @(posedge clk_a or negedge arstn) begin
        if (~arstn) begin
            en_data_reg <= 1'b0;  // Clear enable data register on reset
        end else begin
            en_data_reg <= data_en;  // Update enable data register
        end
    end

    // Two-stage synchronizer for enable signal with clk_b
    always @(posedge clk_b or negedge brstn) begin
        if (~brstn) begin
            en_clk_b_one <= 1'b0;
            en_clk_b_two <= 1'b0;
        end else begin
            en_clk_b_one <= en_data_reg;       // First D flip-flop stage
            en_clk_b_two <= en_clk_b_one;      // Second D flip-flop stage
        end
    end

    // Dataout based on the synchronized enable signal
    always @(posedge clk_b or negedge brstn) begin
        if (~brstn) begin
            dataout <= 4'b0000;  // Clear output data on reset
        end else if (en_clk_b_two) begin
            dataout <= data_reg;  // Update output data when enable signal is high
        end
    end

endmodule
module calendar (
    input CLK,  // Clock input
    input 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)
);

    // Update seconds
    always @(posedge CLK or posedge RST) begin
        if (RST) begin
            // Reset seconds to 0
            Secs <= 6'd0;
        end else if (Secs == 6'd59) begin
            // Reset seconds and increment minutes
            Secs <= 6'd0;
        end else begin
            // Increment seconds
            Secs <= Secs + 6'd1;
        end
    end

    // Update minutes
    always @(posedge CLK or posedge RST) begin
        if (RST) begin
            // Reset minutes to 0
            Mins <= 6'd0;
        end else if (Secs == 6'd59) begin
            if (Mins == 6'd59) begin
                // Reset minutes when seconds and minutes are both 59
                Mins <= 6'd0;
            end else begin
                // Increment minutes
                Mins <= Mins + 6'd1;
            end
        end
        // If Secs is not 59, keep Mins unchanged
    end

    // Update hours
    always @(posedge CLK or posedge RST) begin
        if (RST) begin
            // Reset hours to 0
            Hours <= 6'd0;
        end else if ((Mins == 6'd59) && (Secs == 6'd59)) begin
            if (Hours == 6'd23) begin
                // Reset hours when seconds, minutes, and hours are at their max
                Hours <= 6'd0;
            end else begin
                // Increment hours
                Hours <= Hours + 6'd1;
            end
        end
        // If Secs is not 59 or Mins is not 59, keep Hours unchanged
    end

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

    // State declarations
    parameter idle = 2'b00, s1_red = 2'b01, s2_yellow = 2'b10, s3_green = 2'b11;

    // Internal counter
    reg [7:0] cnt;

    // Current state
    reg [1:0] state;

    // Next state logic
    always @(posedge clk or negedge rst_n) begin
        if (!rst_n) begin
            state <= idle;
        end else begin
            case (state)
                idle: state <= s1_red; // Start with red
                s1_red: if (cnt == 0) state <= s3_green; // Move to green after red
                s2_yellow: if (cnt == 0) state <= s1_red; // Move to red after yellow
                s3_green: if (cnt == 0) state <= s2_yellow; // Move to yellow after green
                default: state <= idle;
            endcase
        end
    end

    // Counter logic to handle timing and pedestrian button
    always @(posedge clk or negedge rst_n) begin
        if (!rst_n) begin
            cnt <= 10; // Reset to 10 at start
        end else begin
            if (cnt == 0) begin
                // Set the counter based on the current state when count reaches 0
                case (state)
                    s1_red: cnt <= 60;
                    s2_yellow: cnt <= 5;
                    s3_green: cnt <= 10;
                    default: cnt <= 10;
                endcase
            end else if (pass_request && state == s3_green && cnt > 10) begin
                cnt <= 10; // Shorten green time if pass_request is active
            end else begin
                cnt <= cnt - 1; // Normal countdown
            end
        end
    end

    // Assign the current count value to the clock output
    always @(cnt) begin
        clock <= cnt;
    end

    // Output logic for the traffic light signals
    always @(posedge clk or negedge rst_n) begin
        if (!rst_n) begin
            red <= 1'b0;
            yellow <= 1'b0;
            green <= 1'b0;
        end else begin
            case (state)
                s1_red: begin
                    red <= 1'b1;
                    yellow <= 1'b0;
                    green <= 1'b0;
                end
                s2_yellow: begin
                    red <= 1'b0;
                    yellow <= 1'b1;
                    green <= 1'b0;
                end
                s3_green: begin
                    red <= 1'b0;
                    yellow <= 1'b0;
                    green <= 1'b1;
                end
                default: begin
                    red <= 1'b0;
                    yellow <= 1'b0;
                    green <= 1'b0;
                end
            endcase
        end
    end

endmodule
module dual_port_RAM #(
    parameter DEPTH = 16,
    parameter WIDTH = 8
)(
    input wclk,
    input wenc,
    input [$clog2(DEPTH)-1:0] waddr,
    input [WIDTH-1:0] wdata,
    input rclk,
    input renc,
    input [$clog2(DEPTH)-1:0] raddr,
    output reg [WIDTH-1:0] rdata
);

    // Memory array
    reg [WIDTH-1:0] RAM_MEM [0:DEPTH-1];

    // Handle write operation
    always @(posedge wclk) begin
        if (wenc) begin
            RAM_MEM[waddr] <= wdata;
        end
    end

    // Handle read operation
    always @(posedge rclk) begin
        if (renc) begin
            rdata <= RAM_MEM[raddr];
        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
);

    // Intermediate storage for the first 8-bit data
    reg [7:0] data_lock;
    // Flag to indicate that the first data byte has been stored and is waiting for the second byte
    reg data_lock_valid;

    // Synchronous process for capturing and concatenating input data
    always @(posedge clk or negedge rst_n) begin
        if (!rst_n) begin
            // Synchronous reset
            data_out <= 16'b0;
            valid_out <= 1'b0;
            data_lock <= 8'b0;
            data_lock_valid <= 1'b0;
        end else begin
            if (valid_in) begin
                if (data_lock_valid) begin
                    // If we have valid data locked, concatenate it with new data
                    data_out <= {data_lock, data_in};
                    valid_out <= 1'b1; // Output is valid now
                    data_lock_valid <= 1'b0; // Clear the lock flag as data is now used
                end else begin
                    // If no valid data is locked, lock the current input and wait for the next
                    data_lock <= data_in;
                    data_lock_valid <= 1'b1; // Set the lock flag
                    valid_out <= 1'b0; // Output is not valid until we get the second byte
                end
            end else if (!data_lock_valid) begin
                // If input is not valid and no data is locked, maintain the output as invalid
                valid_out <= 1'b0;
            end
            // No else clause for data_lock_valid and !valid_in, since we want to keep the locked data
        end
    end

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

    // Johnson counter sequence update
    always @(posedge clk or negedge rst_n) begin
        if (!rst_n) begin
            // Reset condition
            Q <= 64'b0; // Set all bits to 0
        end else begin
            // Normal operation
            if (Q[0] == 1'b0) begin
                // If the LSB is 0, shift left and insert 1 at MSB
                Q <= {Q[62:0], 1'b1};
            end else begin
                // If the LSB is 1, shift left and insert 0 at MSB
                Q <= {Q[62:0], 1'b0};
            end
        end
    end

endmodule
module adder_pipe_64bit(
    input clk,          // Clock input
    input rst_n,        // Active low reset signal
    input i_en,         // Enable signal for addition operation
    input [63:0] adda,  // 64-bit input operand A
    input [63:0] addb,  // 64-bit input operand B
    output reg [64:0] result, // 65-bit output representing the sum of adda and addb
    output reg o_en           // Output enable signal
);

    // Intermediate registers for pipeline stages
    reg [63:0] reg_adda_stage1, reg_addb_stage1;
    reg [64:0] reg_sum_stage2;
    reg reg_i_en_stage1, reg_i_en_stage2;

    // Combinational logic for addition
    wire [64:0] sum_stage1; // 65-bit to store sum and carry out

    // First stage addition
    assign sum_stage1 = reg_adda_stage1 + reg_addb_stage1;

    // Sequential logic for registers
    always @(posedge clk or negedge rst_n) begin
        if (!rst_n) begin
            // Reset all registers and output enable
            reg_adda_stage1 <= 0;
            reg_addb_stage1 <= 0;
            reg_sum_stage2 <= 0;
            reg_i_en_stage1 <= 0;
            reg_i_en_stage2 <= 0;
            o_en <= 0;
            result <= 0;
        end else begin
            // Pipeline stage 1
            if (i_en) begin
                reg_adda_stage1 <= adda; // Load inputs into pipeline stage 1
                reg_addb_stage1 <= addb;
                reg_i_en_stage1 <= i_en; // Enable signal for stage 1
            end

            // Pipeline stage 2
            reg_sum_stage2 <= sum_stage1; // Output of adder goes into stage 2
            reg_i_en_stage2 <= reg_i_en_stage1; // Enable signal for stage 2

            // Result and output enable
            result <= reg_sum_stage2; // Result is stored in output register
            o_en <= reg_i_en_stage2;  // Output enable signal
        end
    end

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

    // Initialize the shift 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]}; // Concatenate new bit 'd' at the MSB and shift right
    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
);

    // 4-bit counter to count the number of bits received
    reg [2:0] cnt;

    // On every positive edge of the clock, perform the series to parallel conversion
    always @(posedge clk or negedge rst_n) begin
        if (!rst_n) begin
            // If reset is active, clear the counter and output registers
            cnt <= 3'd0;
            dout_parallel <= 8'd0;
            dout_valid <= 1'b0;
        end else if (din_valid) begin
            // If the input data is valid, shift in the serial data
            dout_parallel <= {din_serial, dout_parallel[7:1]};
            
            // Increment the counter
            cnt <= cnt + 1;
            
            // If 8 bits have been received, indicate that output is valid
            if (cnt == 3'd7) begin
                dout_valid <= 1'b1;
                cnt <= 3'd0; // reset the counter after 8 bits
            end else begin
                dout_valid <= 1'b0;
            end
        end else begin
            // If din_valid is not high, do not shift in new data
            // and clear the valid flag
            dout_valid <= 1'b0;
        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 [15:0] areg, breg;
    reg [4:0] i; // 5 bits to represent the count from 0 to 16
    reg [31:0] yout_r;
    reg done_r;
    
    // Reset and start conditions
    always @(posedge clk or negedge rst_n) begin
        if (!rst_n) begin
            // Reset condition
            areg <= 16'b0;
            breg <= 16'b0;
            yout_r <= 32'b0;
            i <= 5'b0;
            done <= 1'b0;
        end else begin
            if (start) begin
                if (i < 17) begin
                    if (i == 0) begin
                        // Load the registers with the inputs
                        areg <= ain;
                        breg <= bin;
                        yout_r <= 32'b0;
                    end else begin
                        // Shift and accumulate
                        yout_r <= yout_r + ({16'b0, areg[0] ? breg : 16'b0} << (i - 1));
                        areg <= areg >> 1; // Shift the multiplicand right
                    end
                    i <= i + 1'b1;
                    done <= 1'b0;
                end else begin
                    // Multiplication is done
                    done <= 1'b1;
                    i <= 5'b0; // Reset the counter for the next operation
                end
            end else begin
                // Start is not active, reset the counter
                i <= 5'b0;
                done <= 1'b0;
            end
        end
    end
    
    // Assign the internal register to the output
    always @(posedge clk or negedge rst_n) begin
        if (!rst_n) begin
            yout <= 32'b0;
        end else begin
            if (done) begin
                yout <= yout_r;
            end
        end
    end

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

    // Counters for the 10MHz and 1MHz clocks
    reg [3:0] cnt_10 = 0; // 4-bit counter for 10MHz
    reg [6:0] cnt_100 = 0; // 7-bit counter for 1MHz

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

    // CLK_10 generation
    always @(posedge CLK_in or posedge RST) begin
        if (RST) begin
            CLK_10 <= 0;
            cnt_10 <= 0;
        end else begin
            if (cnt_10 == 4'd4) begin
                CLK_10 <= ~CLK_10;
                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
            CLK_1 <= 0;
            cnt_100 <= 0;
        end else begin
            if (cnt_100 == 7'd49) begin
                CLK_1 <= ~CLK_1;
                cnt_100 <= 0;
            end else begin
                cnt_100 <= cnt_100 + 1;
            end
        end
    end

endmodule
module counter_12 (
    input wire rst_n,       // Active low reset
    input wire clk,         // Clock signal
    input wire valid_count, // Enable counting
    output reg [3:0] out    // 4-bit count output
);

    always @(posedge clk or negedge rst_n) begin
        if (!rst_n) begin
            // Reset condition
            out <= 4'b0000;
        end else if (valid_count) begin
            if (out == 4'd11) begin
                // Wrap counter back to 0 after reaching 11
                out <= 4'b0000;
            end else begin
                // Increment counter
                out <= out + 4'd1;
            end
        end
        // If valid_count is 0, do nothing (counter is paused)
    end

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

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

    // Edge detection logic
    always @(posedge clk or negedge rst_n) begin
        if (!rst_n) begin
            // Reset condition, set everything to zero
            a_prev <= 1'b0;
            rise <= 1'b0;
            down <= 1'b0;
        end else begin
            // Detect rising edge
            rise <= (a == 1'b1) && (a_prev == 1'b0);
            // Detect falling edge
            down <= (a == 1'b0) && (a_prev == 1'b1);
            // Update previous state of 'a'
            a_prev <= a;
        end
    end

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

    // Internal wires for the carry bits
    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 wire a,
    input wire b,
    input wire cin,
    output wire sum,
    output wire cout
);
    // Sum is the XOR of the three inputs
    assign sum = a ^ b ^ cin;
    // Carry out is the majority function of the three inputs
    assign cout = (a & b) | (b & cin) | (cin & a);
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
);

// Define internal registers
reg [7:0] reg_mul_a, reg_mul_b;
reg [15:0] reg_mul_out;
reg [7:0] partial_products[7:0];
reg [15:0] sum[6:0]; // 7 stages of addition
reg [7:0] mul_en_pipeline;

// Input register stage
always @(posedge clk or negedge rst_n) begin
    if (!rst_n) begin
        reg_mul_a <= 0;
        reg_mul_b <= 0;
        mul_en_pipeline <= 0;
    end else if (mul_en_in) begin
        reg_mul_a <= mul_a;
        reg_mul_b <= mul_b;
        mul_en_pipeline <= {mul_en_pipeline[6:0], mul_en_in}; // Shift enable signal through the pipeline
    end
end

// Generate partial products
integer i;
always @(posedge clk) begin
    for (i = 0; i < 8; i = i + 1) begin
        partial_products[i] <= reg_mul_a & {8{reg_mul_b[i]}};
    end
end

// Addition pipeline stages
always @(posedge clk or negedge rst_n) begin
    if (!rst_n) begin
        sum[0] <= 0;
        sum[1] <= 0;
        sum[2] <= 0;
        sum[3] <= 0;
        sum[4] <= 0;
        sum[5] <= 0;
        sum[6] <= 0;
        reg_mul_out <= 0;
    end else begin
        // Perform the additions in a pipelined manner
        sum[0] <= partial_products[0] + (partial_products[1] << 1);
        sum[1] <= partial_products[2] + (partial_products[3] << 2);
        sum[2] <= partial_products[4] + (partial_products[5] << 4);
        sum[3] <= partial_products[6] + (partial_products[7] << 6);
        sum[4] <= sum[0] + (sum[1] << 2);
        sum[5] <= sum[2] + (sum[3] << 4);
        sum[6] <= sum[4] + (sum[5] << 4);
        reg_mul_out <= sum[6];
    end
end

// Output stage
always @(posedge clk or negedge rst_n) begin
    if (!rst_n) begin
        mul_out <= 0;
        mul_en_out <= 0;
    end else begin
        mul_out <= reg_mul_out;
        mul_en_out <= mul_en_pipeline[7];
    end
end

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

    // Internal registers
    reg [3:0] data_reg;
    reg [1:0] cnt; // 2-bit counter to handle 4 clock cycles for 4 bits

    // On every positive edge of the clock
    always @(posedge clk or negedge rst_n) begin
        if (!rst_n) begin
            // Resetting all registers when rst_n is 0
            data_reg <= 4'b0000;
            cnt <= 2'b00;
            valid_out <= 1'b0;
            dout <= 1'b0;
        end else begin
            // If counter is 3, indicating the last bit is being outputted, load new data
            if (cnt == 2'b11) begin
                data_reg <= d; // Load the parallel data
                cnt <= 2'b00; // Reset the counter
                valid_out <= 1'b1; // Set valid_out high as data is ready to be outputted
            end else begin
                cnt <= cnt + 1; // Increment the counter
                data_reg <= {data_reg[2:0], 1'b0}; // Shift left the data register
                valid_out <= (cnt == 2'b00) ? 1'b1 : 1'b0; // valid_out high only when cnt is 0
            end
            dout <= data_reg[3]; // Assign MSB of data_reg to dout
        end
    end

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 reg ready,
    output reg [DATAWIDTH-1:0] quotient,
    output reg [DATAWIDTH-1:0] remainder,
    output reg vld_out
);

    // State encoding
    localparam IDLE  = 2'b00,
               SUB   = 2'b01,
               SHIFT = 2'b10,
               DONE  = 2'b11;

    // Registers for state machine
    reg [1:0] current_state, next_state;

    // Extended registers for computation
    reg [DATAWIDTH-1:0] dividend_e, divisor_e;
    reg [DATAWIDTH-1:0] quotient_e, remainder_e;
    reg [DATAWIDTH-1:0] count;

    // State machine logic
    always @(posedge clk or negedge rstn) begin
        if (!rstn) begin
            current_state <= IDLE;
        end else begin
            current_state <= next_state;
        end
    end

    // State transition and output logic
    always @(*) begin
        // Default assignments
        ready = 1'b0;
        vld_out = 1'b0;
        next_state = current_state;

        case (current_state)
            IDLE: begin
                if (en) begin
                    next_state = SUB;
                    quotient_e = 0;
                    dividend_e = dividend;
                    divisor_e = divisor << (DATAWIDTH - 1);
                    count = DATAWIDTH;
                end else begin
                    ready = 1'b1;
                end
            end
            SUB: begin
                // Perform subtraction if possible
                if (dividend_e >= divisor_e) begin
                    dividend_e = dividend_e - divisor_e;
                    quotient_e = (quotient_e << 1) | 1'b1;
                end else begin
                    quotient_e = (quotient_e << 1);
                end
                next_state = SHIFT;
            end
            SHIFT: begin
                if (count > 0) begin
                    divisor_e = divisor_e >> 1; // Shift right the divisor
                    count = count - 1;
                    next_state = SUB; // Go back to SUB to attempt another subtraction
                end else begin
                    next_state = DONE;
                end
            end
            DONE: begin
                quotient = quotient_e;
                remainder = dividend_e;
                vld_out = 1'b1;
                next_state = IDLE; // Return to IDLE after completion
            end
        endcase
    end

    // Asynchronous reset logic
    always @(negedge rstn) begin
        if (!rstn) begin
            current_state <= IDLE;
            quotient <= 0;
            remainder <= 0;
            count <= 0;
            dividend_e <= 0;
            divisor_e <= 0;
            quotient_e <= 0;
            remainder_e <= 0;
            ready <= 1'b1;
            vld_out <= 1'b0;
        end
    end

endmodule
module accu(
    input clk,             // Clock input
    input rst_n,           // Active-low reset
    input [7:0] data_in,   // 8-bit input data
    input valid_in,        // Input data valid signal
    output reg valid_out,  // Output valid signal
    output reg [9:0] data_out  // 10-bit accumulated output data
);

    // Internal signals
    reg [9:0] accu_sum;           // Accumulator for the sum
    reg [1:0] count;              // Counter for the input data

    always @(posedge clk or negedge rst_n) begin
        if (!rst_n) begin
            // Reset logic
            accu_sum <= 10'd0;
            count <= 2'd0;
            valid_out <= 1'b0;
            data_out <= 10'd0;
        end else begin
            if (valid_in) begin
                // When valid_in is high, accumulate the sum
                if (count == 3'd3) begin
                    // If 4 data points have been received, output the sum
                    accu_sum <= accu_sum + data_in;
                    data_out <= accu_sum + data_in; // Include the current data_in in the sum
                    valid_out <= 1'b1; // Output is valid
                    count <= 2'd0; // Reset the counter for next cycle
                    accu_sum <= 10'd0; // Reset the accumulator
                end else begin
                    // If fewer than 4 data points have been received, keep accumulating
                    accu_sum <= accu_sum + data_in;
                    count <= count + 2'd1;
                    valid_out <= 1'b0; // Output is not valid yet
                end
            end else begin
                // If valid_in is low, do nothing
                valid_out <= 1'b0; // Maintain output as invalid
            end
        end
    end
endmodule
module div_16bit(
    input [15:0] A,      // 16-bit dividend
    input [7:0] B,       // 8-bit divisor
    output reg [15:0] result, // 16-bit quotient
    output reg [15:0] odd     // 16-bit remainder
);

    // Temporary registers to hold intermediate values and shifted divisor
    reg [15:0] dividend;
    reg [15:0] divisor;
    reg [15:0] remainder;

    integer i;

    always @* begin
        // Initialize the values
        dividend = A;
        divisor = {B, 8'd0}; // Align the divisor with the higher bits of the dividend
        remainder = 0;
        result = 0;

        // Loop to process each bit from MSB to LSB
        for (i = 0; i < 16; i = i + 1) begin
            // Shift remainder and bring down the next bit of the dividend
            remainder = (remainder << 1) | (dividend[15] & 1'b1);
            dividend = dividend << 1; // Shift the dividend

            // Compare the upper bits of the dividend with the divisor
            if (remainder >= divisor) begin
                remainder = remainder - divisor;
                result = (result << 1) | 1'b1;
            end else begin
                result = result << 1;
            end
        end

        // Assign the final remainder value
        odd = remainder;
    end

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

    // Define state register
    reg state;

    // Define states for readability
    localparam STATE_UP = 1'b0;
    localparam STATE_DOWN = 1'b1;

    // Waveform generation always block
    always @(posedge clk or negedge rst_n) begin
        if (!rst_n) begin
            // Synchronous reset
            wave <= 5'd0;
            state <= STATE_UP;
        end else begin
            case (state)
                STATE_UP: begin
                    // Increment the wave
                    if (wave == 5'd31) begin
                        // Transition to STATE_DOWN if maximum is reached
                        state <= STATE_DOWN;
                        wave <= wave - 5'd1;
                    end else begin
                        // Continue incrementing
                        wave <= wave + 5'd1;
                    end
                end
                STATE_DOWN: begin
                    // Decrement the wave
                    if (wave == 5'd0) begin
                        // Transition to STATE_UP if minimum is reached
                        state <= STATE_UP;
                        wave <= wave + 5'd1;
                    end else begin
                        // Continue decrementing
                        wave <= wave - 5'd1;
                    end
                end
                default: begin
                    // In case of an undefined state, reset to known state
                    state <= STATE_UP;
                    wave <= 5'd0;
                end
            endcase
        end
    end

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

    reg [7:0] multiplicand, multiplier;
    reg [4:0] count; // 4 bits to count up to 8 iterations
    reg [1:0] booth_code;
    reg [16:0] product; // 1 extra bit for sign extension

    wire [1:0] next_booth_code = {multiplier[1], multiplier[0]};
    
    always @(posedge clk or posedge reset) begin
        if (reset) begin
            // Initialize registers
            product <= 0;
            multiplicand <= a;
            multiplier <= b;
            count <= 0;
            rdy <= 0;
        end else begin
            case (next_booth_code)
                2'b01: product = product + (multiplicand << count);
                2'b10: product = product - (multiplicand << count);
                default: product = product; // 2'b00 or 2'b11 means no operation
            endcase
            
            // Prepare for the next iteration
            count = count + 1;
            multiplier = multiplier >> 2; // Shift by 2 for Radix-4 Booth

            // Check if multiplication is complete
            if (count == 4'b1000) begin // After 8 iterations
                rdy <= 1;
                p <= product[15:0]; // Assign the lower 16 bits to output
            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 full width of the product to avoid overflow during accumulation
    reg [63:0] product;

    always @(posedge clk or posedge rst) begin
        if (rst) begin
            // Reset the accumulator register 'c' to 0
            c <= 32'b0;
        end else begin
            // Perform multiplication
            product <= a * b;
            // Accumulate the result
            c <= c + product[31:0]; // Assuming you want to 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 negative,
    output reg overflow,
    output reg flag
);

    // Define 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;

    // Internal signals
    reg [32:0] extended_result; // 32-bit result with carry
    wire [31:0] b_negated;
    wire set;
    wire unsigned_set;

    assign b_negated = ~b + 1'b1; // Two's complement for subtraction
    assign set = r[31]; // Negative flag for SLT
    assign unsigned_set = !r[31]; // Unsigned comparison for SLTU
    assign zero = (r == 32'b0); // Zero flag
    assign negative = r[31]; // Negative flag

    always @(*) begin
        carry = 0; // Default carry
        overflow = 0; // Default overflow
        flag = 0; // Default flag

        case (aluc)
            ADD: {carry, r} = {1'b0, a} + {1'b0, b};
            ADDU: r = a + b;
            SUB: {carry, r} = {1'b0, a} + {1'b0, b_negated};
            SUBU: r = a - b;
            AND: r = a & b;
            OR: r = a | b;
            XOR: r = a ^ b;
            NOR: r = ~(a | b);
            SLT: begin
                r = set;
                flag = set;
            end
            SLTU: begin
                r = unsigned_set;
                flag = unsigned_set;
            end
            SLL: r = b << a[4:0];
            SRL: r = b >> a[4:0];
            SRA: r = $signed(b) >>> a[4:0];
            SLLV: r = b << (a[4:0]);
            SRLV: r = b >> (a[4:0]);
            SRAV: r = $signed(b) >>> (a[4:0]);
            LUI: r = {b[15:0], 16'b0};
            default: r = 32'bz; // High-impedance for undefined operations
        endcase

        // Check for overflow in signed addition and subtraction
        if (aluc == ADD || aluc == SUB) begin
            overflow = (a[31] && b[31] && !r[31]) || (!a[31] && !b[31] && r[31]);
        end
    end

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

    // Define states for the FSM
    parameter IDLE = 2'b00,
              DETECT_RISE = 2'b01,
              DETECT_FALL = 2'b10;

    // State register
    reg [1:0] state;
    reg [1:0] next_state;

    // Sequential block for state transition
    always @(posedge clk or negedge rst_n) begin
        if (!rst_n) begin
            state <= IDLE;
        end else begin
            state <= next_state;
        end
    end

    // Combinational block for next state logic and output assignment
    always @(*) begin
        // Default assignments
        next_state = state;
        data_out = 1'b0;

        case (state)
            IDLE: begin
                // If a rising edge is detected, move to DETECT_RISE state
                if (data_in == 1'b1) begin
                    next_state = DETECT_RISE;
                end
            end
            DETECT_RISE: begin
                // If data_in is 0 after being 1, we have detected a falling edge
                if (data_in == 1'b0) begin
                    next_state = DETECT_FALL;
                end
            end
            DETECT_FALL: begin
                // Detected a pulse, so output should be high
                data_out = 1'b1;
                // Look for the next pulse
                next_state = IDLE;
            end
            default: begin
                // In case of an undefined state, go back to IDLE
                next_state = IDLE;
            end
        endcase
    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
);

    // Data Register
    reg [3:0] data_reg;

    // Enable Data Register
    reg en_data_reg;

    // Enable Control Registers
    reg en_clap_one;
    reg en_clap_two;

    // Register data_in with clk_a
    always @(posedge clk_a or negedge arstn) begin
        if (!arstn) begin
            data_reg <= 4'b0000;
        end else if (data_en) begin
            data_reg <= data_in;
        end
    end

    // Register data_en with clk_a
    always @(posedge clk_a or negedge arstn) begin
        if (!arstn) begin
            en_data_reg <= 1'b0;
        end else begin
            en_data_reg <= data_en;
        end
    end

    // Synchronize the enable signal with clk_b
    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

    // Output assignment
    always @(posedge clk_b or negedge brstn) begin
        if (!brstn) begin
            dataout <= 4'b0000;
        end else if (en_clap_two) begin
            dataout <= data_reg;
        end
    end

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

    // Define the maximum values for seconds, minutes, and hours
    localparam MAX_SECS = 6'd59;
    localparam MAX_MINS = 6'd59;
    localparam MAX_HOURS = 5'd23;

    // Seconds always block
    always @(posedge CLK or posedge RST) begin
        if (RST) begin
            Secs <= 0; // Reset seconds to 0
        end else if (Secs == MAX_SECS) begin
            Secs <= 0; // Reset seconds to 0 when it reaches the max value
        end else begin
            Secs <= Secs + 1; // Increment seconds
        end
    end

    // Minutes always block
    always @(posedge CLK or posedge RST) begin
        if (RST) begin
            Mins <= 0; // Reset minutes to 0
        end else if (Secs == MAX_SECS) begin
            if (Mins == MAX_MINS) begin
                Mins <= 0; // Reset minutes to 0 when it and seconds reach the max value
            end else begin
                Mins <= Mins + 1; // Increment minutes
            end
        end
    end

    // Hours always block
    always @(posedge CLK or posedge RST) begin
        if (RST) begin
            Hours <= 0; // Reset hours to 0
        end else if (Mins == MAX_MINS && Secs == MAX_SECS) begin
            if (Hours == MAX_HOURS) begin
                Hours <= 0; // Reset hours to 0 when it, minutes, and seconds reach the max value
            end else begin
                Hours <= Hours + 1; // Increment hours
            end
        end
    end

endmodule