test:
`timescale 1ns/1ns

module top_module_tb;
  reg clk_fast;
  reg clk_slow;
  reg rst_n;
  reg data_in;
  wire dataout;

  // Instantiate the DUT (Design Under Test)
  top_module dut (
    .clk_fast(clk_fast),
    .clk_slow(clk_slow),
    .rst_n(rst_n),
    .data_in(data_in),
    .dataout(dataout)
  );

  // Generate clock
  always #2 clk_fast = ~clk_fast;
  always #20 clk_slow = ~clk_slow;

  integer error = 0;
  initial begin
    // Initialize inputs
    clk_fast = 0;
    clk_slow = 0;
    rst_n = 0;
    data_in = 0;

    // Wait for a few clock cycles for reset to settle
    #20;

    // Apply reset
    rst_n = 1;

    // Perform test case
    #10;
    data_in = 0;
    #50;
    data_in = 1;
    #50;
    data_in = 1;
    #50;
    // $display("dataout = %b", dataout);
    error = (dataout==1)? error :error+1;
    data_in = 1;
    #50;
    data_in = 0;
    #50;
    // $display("dataout = %b", dataout);
    error = (dataout==0)? error :error+1;

    if (error == 0) begin
            $display("===========Your Design Passed===========");
     end
     else begin
     $display("===========Failed===========");
     end
    // Finish simulation
    $finish;
  end
endmodule

detail_description:
Please act as a professional verilog designer.

Implement the design where a single clock-cycle width pulse(data_in) is extracted from the A clock(fast) domain and a new single clock-width pulse (data_out) will be created in the clock domain B(slow). The frequency of clock domain A is 10 times that of clock domain B.

prompt:
module top_module(
	input 				clk_fast	,
	input 				clk_slow	,
	input 				rst_n		,
	input				data_in		,

	output  		 	dataout
);

solution:
module top_module (
    input                  clk_fast,   // Clock input from domain A (10x faster)
    input                  clk_slow,   // Clock input from domain B (slower)
    input                  rst_n,      // Active low reset
    input                  data_in,    // Input data from clk_fast domain
    output reg             data_out    // Output data synchronized to clk_slow domain
);

// Internal signals for domain crossing
reg [3:0]  sync_cnt;
reg        clk_slow_prev;
reg        data_in_sync, data_in_prev;

always @(posedge clk_slow or negedge rst_n) begin
    if (!rst_n) begin
        data_in_sync <= 1'b0;
        sync_cnt <= 4'b0;
    end else begin
        // Synchronize data_in from clk_fast to clk_slow domain
        data_in_prev <= data_in;
        if (sync_cnt == 4'b1001) // Synchronize after 10 cycles of clk_slow
            data_in_sync <= data_in_prev;
        else
            sync_cnt <= sync_cnt + 1;
    end
end

always @(posedge clk_slow or negedge rst_n) begin
    if (!rst_n) begin
        clk_slow_prev <= 1'b0;
        data_out <= 1'b0;
    end else begin
        // Detect a single clock-width pulse in the clk_slow domain
        clk_slow_prev <= clk_slow;
        if (clk_slow && !clk_slow_prev)
            data_out <= data_in_sync; // Output synchronized data_in pulse
        else
            data_out <= 1'b0;
    end
end

endmodule


task_id: fsm

test:
`timescale 1ns/1ns

module main();

reg clk,rst;
reg IN;
wire MATCH;

top_module DUT(.CLK(clk),.RST(rst),.IN(IN),.MATCH(MATCH));

initial begin
	clk=0;
	forever #5 clk=~clk;
end

initial begin
	#10;
	rst =1;
	#30;
	rst = 0;
	IN = 0;
	#10 IN=0;
        #10 IN=0;
        #10 IN=1;
        #10 IN=1;
        #10 IN=0;
        #10 IN=0;
        #10 IN=1;
        #10 IN=1;
        #20;
        if(MATCH==1)begin
                $display("===========Your Design Passed===========");
        end
        else begin
                $display("===========Error===========");
        end
	$finish;
end
endmodule

detail_description:
Please act as a professional verilog designer.

Implement a FSM detection circuit that detects a single bit input IN. When the input is 10011, output MATCH is high, and MATCH is 0 in other cases.

prompt: module top_module(IN,MATCH,CLK,RST);

solution:
module top_module (
  input CLK,
  input RST,
  input IN,
  output reg MATCH
);

parameter S_IDLE = 2'b00;
parameter S_1 = 2'b01;
parameter S_10 = 2'b10;
parameter S_100 = 2'b11;

reg [1:0] state = S_IDLE;

always @(posedge CLK) begin
  if (RST) begin
    state <= S_IDLE;
    MATCH <= 0;
  end
  else begin
    case (state)
      S_IDLE: begin
        if (IN == 1'b1) begin
          state <= S_1;
        end
        else begin
          state <= S_IDLE;
        end
      end

      S_1: begin
        if (IN == 1'b0) begin
          state <= S_10;
        end
        else begin
          state <= S_IDLE;
        end
      end

      S_10: begin
        if (IN == 1'b0) begin
          state <= S_100;
        end
        else begin
          state <= S_IDLE;
        end
      end

      S_100: begin
        if (IN == 1'b1) begin
          state <= S_IDLE;
          MATCH <= 1;
        end
        else begin
          state <= S_IDLE;
        end
      end
    endcase
  end
end

endmodule


task_id: pe

test:
`timescale 1ns / 1ps

module test54();

    reg clk;
    reg rst;
    reg [31:0] a,b;
    wire [31:0] c;

    top_module pe(clk,rst,a,b,c);

    initial begin

    a=0;
    b=0;
    clk=0;
    rst=1;
    #5;
    clk=1;
    #5;
    clk=0;
    rst=0;
    #5;

    a=1;
    b=1;
    #5;
    clk=1;
    #5;
    clk=0;

    a=2;
    b=2;
    #5;
    clk=1;
    #5;
    clk=0;

    a=3;
    b=3;
    #5;
    clk=1;
    #5;
    clk=0;

    //$display("%h", c);

	if(c==32'h0000000e)
	begin
		$display("===========Your Design Passed===========");
        end
	else
	begin
		$display("===========Error===========");
	end
    end
endmodule

detail_description:
Please act as a professional verilog designer.

Implement a Multiplying Accumulator for 32bit integer. In the MAC_PE, there is a register that stores the partial sum (the intermediate accumulation result), and in each cycle, the result of “a multiplied by b” will be accumulated in this register, and the “c” shows the value of the register.

prompt:
module top_module(
    input clk,
    input rst,
    input [31:0] a,
    input [31:0] b,

    output [31:0] c
);

solution:
module top_module(
    input clk,
    input rst,
    input [31:0] a,
    input [31:0] b,
    output [31:0] c
);

reg [31:0] partial_sum; // Register to store the partial sum

always @(posedge clk) begin
    if (rst) begin
        partial_sum <= 0; // Reset the partial sum to 0
    end else begin
        partial_sum <= partial_sum + (a * b); // Accumulate the result of "a multiplied by b"
    end
end

assign c = partial_sum; // Output the accumulated value

endmodule


test:
`timescale 1ns / 1ps

module testbench;

  reg [7:0] a;
  reg [7:0] b;
  reg cin;
  wire [7:0] sum;
  wire SUM;
  wire cout;

  integer i; // Declare the loop variable here
  integer fail_count;
  integer error = 0;

  // Instantiate the module
  top_module uut (
    .a(a),
    .b(b),
    .cin(cin),
    .sum(sum),
    .SUM(SUM),
    .cout(cout)
  );

  // Randomize inputs and check output
  initial begin
    for (i = 0; i < 100; i = i + 1) begin
        a = $random & 8'hff;  // Limit to 8 bits
        b = $random & 8'hff;  // Limit to 8 bits
        cin = $random & 1'b1; // Limit to 1 bit

        #10; // Wait for the output to be computed

        error = (sum !== a + b + cin) ? error+1 : error;
    end
    if (error == 0) begin
      $display("===========Your Design Passed===========");
    end
    else begin
      $display("===========Test completed with %d /100 failures===========", error);
    end

  end

endmodule

detail_description:
Please act as a professional verilog designer.

Implement a module of an 8 bit adder in gate level.

prompt:
module top_module(
//     input [7:0] a, b,input cin,
//     output [7:0] sum,
//     output cout
// );

solution:
module top_module(
    input [7:0] a,
    input [7:0] b,
    input cin,
    output [7:0] sum,
    output SUM,
    output cout
);

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

// Generate intermediate carry bits
assign carry[0] = cin;
generate
    genvar i;
    for (i = 1; i < 8; i = i + 1) begin : GEN_CARRY
        assign carry[i] = (a[i-1] & b[i-1]) | (a[i-1] & carry[i-1]) | (b[i-1] & carry[i-1]);
    end
endgenerate

// Generate sum bits
generate
    genvar j;
    for (j = 0; j < 8; j = j + 1) begin : GEN_SUM
        assign sum_temp[j] = a[j] ^ b[j] ^ carry[j];
    end
endgenerate

// Assign outputs
assign sum = sum_temp;
assign SUM = sum_temp[7];
assign cout = carry[7];

endmodule


test:
`timescale 1ns/1ns

module top_module_tb;
  reg clk;
  reg rst_n;
  reg [3:0] mul_a;
  reg [3:0] mul_b;
  wire [7:0] mul_out;

  // Instantiate the DUT (Design Under Test)
  top_module #(.size(4)) dut (
    .clk(clk),
    .rst_n(rst_n),
    .mul_a(mul_a),
    .mul_b(mul_b),
    .mul_out(mul_out)
  );

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

  initial begin
    // Initialize inputs
    clk = 0;
    rst_n = 0;
    mul_a = 4'b0;
    mul_b = 4'b0;

    // Wait for a few clock cycles for reset to settle
    #10;

    // Apply reset
    rst_n = 1;

    // Perform test case
    mul_a = 4'b1010;
    mul_b = 4'b0110;
    #30;
    // Check the output
    if (mul_out != 8'b00111100) begin
            $display("=========== Failed ===========");
        end else begin
            $display("===========Your Design Passed===========");
        end
    // Finish simulation
    $finish;
  end
endmodule

detail_description:
Please act as a professional verilog designer.

Implement the design of 4bit unsigned number pipeline multiplier.

prompt:
module top_module#(
	parameter size = 4
)(
	input 						clk 		,
	input 						rst_n		,
	input	[size-1:0]			mul_a		,
	input	[size-1:0]			mul_b		,

 	output	reg	[size*2-1:0]	mul_out
);

solution:
module top_module(
  input clk,
  input rst_n,
  input [3:0] mul_a,
  input [3:0] mul_b,
  output reg [7:0] mul_out
);

reg [3:0] a_reg;
reg [3:0] b_reg;
reg [7:0] product;

always @(posedge clk or negedge rst_n) begin
    if (!rst_n) begin
        a_reg <= 4'b0;
        b_reg <= 4'b0;
        product <= 8'b0;
    end
    else begin
        a_reg <= mul_a;
        b_reg <= mul_b;
        product <= {4'b0, a_reg} * {4'b0, b_reg};
    end
end

assign mul_out = product;

endmodule


test:
`timescale 1ns/1ns

module top_module_tb;

  reg wclk, rclk, wrstn, rrstn, winc, rinc;
  reg [7:0] wdata;
  wire wfull, rempty;
  wire [7:0] rdata;

  top_module #(.WIDTH(8), .DEPTH(16)) dut (
    .wclk(wclk),
    .rclk(rclk),
    .wrstn(wrstn),
    .rrstn(rrstn),
    .winc(winc),
    .rinc(rinc),
    .wdata(wdata),
    .wfull(wfull),
    .rempty(rempty),
    .rdata(rdata)
  );

  always #5 wclk = ~wclk;
  always #10 rclk = ~rclk;

  initial begin
    wclk = 0;
    rclk = 0;
    wrstn = 0;
    rrstn = 0;
    winc = 0;
    rinc = 0;
    wdata = 0;

    #20 wrstn = 1;
    #20 rrstn = 1;

    for (int i = 0; i < 16; i = i + 1) begin
      #10;
      winc = 1;
      wdata = i;
    end

    rinc = 1;
    #130;
    rinc = 1;
    if(rdata==15)begin
                $display("===========Your Design Passed===========");
    end
    else begin
                $display("===========Error===========");
    end

    #10 $finish;
  end

endmodule

detail_description:
Please act as a professional verilog designer.

Implement an asynchronous FIFO, FIFO bit width and depth can be configured(parameter DEPTH = 16,parameter WIDTH = 8). The asynchronous FIFO structure is divided into several parts. The first part is dual-port RAM, which is used for data storage. Instantiate dual-port RAM as a submodule, The RAM ports are 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. The second part is the data write controller. The third part is the data read controller. The fourth part is the read pointer synchronizer. The read pointer is collected using the two-stage trigger of the write clock and output to the data write controller. The fifth part is the write pointer synchronizer, which uses the two-stage trigger of the read clock to collect the write pointer and output it to the data read controller.
The method of empty and full judgment is to generate empty and full signal by comparing Gray code. Use 4-bit Gray code as a read/write pointer for a FIFO with depth 8. The gray code is converted to a four-digit binary number, using the lower three digits of the binary number as the address to access RAM. When the read and write Pointers are equal, the FIFO is null.
When the write pointer has one more cycle RAM than the read pointer, the highest and second-highest bits of the read and write pointer are opposite, the remaining bits are the same, and the FIFO is full.

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

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

reg [WIDTH-1:0] mem [0:DEPTH-1];
reg [WIDTH-1:0] rdata_reg;
reg [WIDTH-1:0] rdata_reg2;
reg [$clog2(DEPTH)-1:0] wptr_reg;
reg [$clog2(DEPTH)-1:0] rptr_reg;

assign rdata = rdata_reg;

// Dual-port RAM submodule
dual_port_ram #(.DEPTH(DEPTH), .WIDTH(WIDTH)) ram (
    .clk(wclk),
    .en(winc),
    .we(wrstn),
    .addr(wptr_reg),
    .data(wdata),
    .q()
);

// Data write controller
always @(posedge wclk or negedge wrstn) begin
    if (!wrstn)
        wptr_reg <= 0;
    else if (winc && !wfull)
        wptr_reg <= wptr_reg + 1;
end

// Data read controller
always @(posedge rclk or negedge rrstn) begin
    if (!rrstn)
        rptr_reg <= 0;
    else if (rinc && !rempty)
        rptr_reg <= rptr_reg + 1;
end

// Read pointer synchronizer
always @(posedge wclk) begin
    rdata_reg2 <= rdata_reg;
end

// Write pointer synchronizer
always @(posedge rclk) begin
    rdata_reg <= mem[rptr_reg];
end

// Empty and Full signal generation
assign rempty = (wptr_reg == rptr_reg);
assign wfull = (wptr_reg + 1 == rptr_reg || (wptr_reg[$clog2(DEPTH)-1] != rptr_reg[$clog2(DEPTH)-1] && wptr_reg[$clog2(DEPTH)-2:0] == rptr_reg[$clog2(DEPTH)-2:0]));

endmodule


test:
`timescale 1ns/1ns

module testbench;

    // Parameters
    parameter CLK_PERIOD = 10; // Clock period in simulation time units

    // Inputs
    reg clk;
    reg rst_n;

    // Outputs
    wire [63:0] Q;

    // Instantiate the module
    top_module uut (
        .clk(clk),
        .rst_n(rst_n),
        .Q(Q)
    );

    // Clock generation
    always #((CLK_PERIOD)/2) clk = ~clk;

    integer error=0;
    // Initial block for stimulus generation
    initial begin
        // Initialize inputs
        clk = 0;
        rst_n = 1;

        // Wait for a few clock cycles
        #((CLK_PERIOD) * 2);

        // Release reset
        rst_n = 0;
        #((CLK_PERIOD) * 2);
        rst_n = 1;

        // Simulate for a number of clock cycles
        #((CLK_PERIOD) * 20);
        error = (Q ==64'b 1111111111111111111100000000000000000000000000000000000000000000)? error : error+1;
        #((CLK_PERIOD) * 44);
        error = (Q ==64'b 1111111111111111111111111111111111111111111111111111111111111111)? error : error+1;
        #((CLK_PERIOD) * 1);
        error = (Q ==64'b 0111111111111111111111111111111111111111111111111111111111111111)? error : error+1;
        if (error == 0) begin
            $display("===========Your Design Passed===========");
        end
        else begin
        $display("===========Test completed with %d /100 failures===========", error);
        end
        // $display("Q = %b", Q);

        // Finish simulation
        $finish;
    end

endmodule

detail_description:
Please act as a professional verilog designer.

Implement a 64-bit Johnson counter (torsional ring counter), and cyclic state of the the similar 4-bit Johnson counter is as follows: 0000, 1000, 1100, 1110, 1111, 0111, 0011, 0001, 0000.

prompt:
module top_module(
   input                clk ,
   input                rst_n,

   output reg [63:0]     Q
);

solution:
module top_module(
  input                clk,
  input                rst_n,
  output reg  [3:0]    Q
);

  always @(posedge clk or negedge rst_n) begin
    if (!rst_n) begin
      // Reset the counter
      Q <= 4'b0000;
    end else begin
      // Perform the Johnson counter operation
      case(Q)
        4'b0000: Q <= 4'b1000;
        4'b1000: Q <= 4'b1100;
        4'b1100: Q <= 4'b1110;
        4'b1110: Q <= 4'b1111;
        4'b1111: Q <= 4'b0111;
        4'b0111: Q <= 4'b0011;
        4'b0011: Q <= 4'b0001;
        4'b0001: Q <= 4'b0000;
      endcase
    end
  end

endmodule


task_id: calendar

test:
`timescale 1ns/1ps
module main();
reg clk,rst;

wire[5:0] out1,out2,out3;

top_module dut(.CLK(clk),.RST(rst),.Hours(out1),.Mins(out2),.Secs(out3));

initial begin
	clk=0;
	forever #5 clk=~clk;
end

integer outfile;
initial begin
	#10;
	rst = 1;
	#25;
	rst = 0;
	// outfile = $fopen("reference_output.txt", "a");
	repeat(500) begin
		$display("[%d : %d : %d]", out1, out2, out3);
		#10;
	end
	$display("=====You can compare the output to the ground truth(reference_output.txt)====");
	// $fclose(outfile);
	$finish;
end

endmodule

detail_description:
Please act as a professional verilog designer.

Implement a module of perpetual calendar. The output port Secs counts from 0 to 59, and when the Secs count reaches 59, the output port Mins increases by one and stops counting until minute=59. When the Mins count reaches 59, the output port Hours increases by one and stops counting until Hours=24.

prompt: module top_module(CLK,RST,Hours,Mins,Secs);

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

// Internal registers to hold the count values
reg [5:0] sec_count;
reg [5:0] min_count;
reg [5:0] hr_count;

always @(posedge CLK or posedge RST) begin
    if (RST) begin
        sec_count <= 6'b000000;
        min_count <= 6'b000000;
        hr_count  <= 6'b000000;
    end else begin
        // Seconds counter logic
        if (sec_count == 6'b011101) begin // 59 in binary
            sec_count <= 6'b000000;
            // Minutes increment logic
            if (min_count == 6'b011101) begin // 59 in binary
                min_count <= 6'b000000;
                // Hours increment logic
                if (hr_count == 6'b001100) // 24 in binary
                    hr_count <= 6'b000000;
                else
                    hr_count <= hr_count + 1;
            end else
                min_count <= min_count + 1;
        end else
            sec_count <= sec_count + 1;
    end
end

// Assign the output ports
assign Secs = sec_count;
assign Mins = min_count;
assign Hours = hr_count;

endmodule


test:
`timescale 1ns/1ps

module add16_tb();

    reg     [15:0]  a;
    reg         [15:0]  b;
    reg                     c_up;

    wire        [15:0]  y;
    wire                    Co;

    wire    [16:0]  tb_sum ;

    wire                tb_co ;

    assign tb_sum = a + b;
    assign tb_co  = tb_sum[16];

    integer i;
    integer error = 0;

    initial begin
        for (i = 0; i < 100; i = i + 1) begin
            a = {$random};
            b = {$random};
            c_up = 0;

            #20;
            error = (y !== tb_sum[15:0] || Co !== tb_co) ? error+1 : error ;
        end

        if (error == 0) begin
            $display("===========Your Design Passed===========");
        end
        else begin
        $display("===========Test completed with %d /100 failures===========", error);
        end

    end

    top_module uut(
        .a          (a),
        .b          (b),
        .c_up       (c_up),

        .y          (y),
        .Co     (Co)
    );

endmodule

detail_description:
Please act as a professional verilog designer.

Implement a module of a 16-bit full adder.

prompt:
module top_module(
    input   wire    [15:0]  a,
    input   wire    [15:0]  b,
    input   wire            c_up,

    output wire     [15:0]  y,
    output wire             Co
);

solution:
//GPT3.5
module top_module (
    input [15:0] a,
    input [15:0] b,
    input c_up,
    output [15:0] y,
    output Co
);

wire [15:0] sum;
wire [15:1] carry;

genvar i;

generate
    for (i = 0; i < 16; i=i+1) begin : generate_block
        assign {carry[i+1], sum[i]} = a[i] + b[i] + carry[i];
    end
endgenerate

assign Co = carry[16];
assign y = sum;

endmodule


task_id: alu

test:
`timescale 1ns / 1ps

module test_alu();

    reg [31:0] a;
    reg [31:0] b;
    reg [5:0] aluc;
    wire [31:0] r;
    wire zero;
    wire carry;
    wire negative;
    wire overflow;
    wire flag;
    reg[4:0]cnt;

    top_module alu(a,b,aluc,r,zero,carry,negative,overflow,flag);

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

    reg[5:0]opcodes[0:31];
    reg[31:0]reference[0:31];
    reg error=0;
    integer file_open;
    initial begin

    $readmemh("reference.dat",reference);

    opcodes[0]=ADD;
    opcodes[1]=ADDU;
    opcodes[2]=SUB;
    opcodes[3]=SUBU;
    opcodes[4]=AND;
    opcodes[5]=OR;
    opcodes[6]=XOR;
    opcodes[7]=NOR;
    opcodes[8]=SLT;
    opcodes[9]=SLTU;
    opcodes[10]=SLL;
    opcodes[11]=SRL;
    opcodes[12]=SRA;
    opcodes[13]=SLLV;
    opcodes[14]=SRLV;
    opcodes[15]=SRAV;
    //opcodes[16]=JR;
    opcodes[16]=LUI;
    a=32'h0000001c;
    b=32'h00000021;
    #5;

    //file_open = $fopen("reference.dat","w");
    //$fclose(file_open);
    cnt = 0;

    //file_open = $fopen("reference.dat", "a");

    for(cnt=0;cnt<17;cnt=cnt+1)
    begin
    #5;
	aluc=opcodes[cnt];
    #5;
        error=error|(reference[cnt]!=r);
        //$fdisplay(file_open,"%h", r);
    end

    //$fclose(file_open);

	if(error==0)
	begin
		$display("===========Your Design Passed===========");
        end
	else
	begin
		$display("===========Error===========");
	end
    end
endmodule

detail_description:
Please act as a professional verilog designer.

Implement an ALU for 32bit MIPS-ISA CPU. The “a” and “b” are the two oprands of the ALU, the “aluc” is the opcode, the “r” gives out the result. “zero” means if the result is zero, “carry” means if there is a carry bit, “negative” means if the result is negative, “overflow” means if the computation is overflow, the “flag” is the result of “slt” and “sltu” instructions. The supported operations and corresponding opcode are shown below:
    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;

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

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

// ALU operation parameter definitions
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 for ALU operations
reg carry_out;
reg [32:0] extended_b;

// ALU operation
always @*
begin
    case (aluc)
        ADD, ADDU:
            begin
                r = a + b;
                carry_out = (r < a) | (r < b); // Detect overflow for signed addition
            end
        SUB, SUBU:
            begin
                r = a - b;
                carry_out = (a < b);
            end
        AND:
            r = a & b;
        OR:
            r = a | b;
        XOR:
            r = a ^ b;
        NOR:
            r = ~(a | b);
        SLT:
            r = (a < b) ? 1 : 0;
        SLTU:
            r = (a < b) ? 1 : 0;
        SLL:
            r = a << (b[4:0]);
        SRL:
            r = a >> (b[4:0]);
        SRA:
            r = $signed(a) >>> (b[4:0]); // Arithmetic shift right (sign-extended)
        SLLV:
            r = a << (b & 0x1F);
        SRLV:
            r = a >> (b & 0x1F);
        SRAV:
            r = $signed(a) >>> (b & 0x1F); // Arithmetic shift right (sign-extended)
        LUI:
            r = {b, 16'b0};
    endcase
end

// Zero detection
assign zero = (r == 0);

// Carry detection
assign carry = carry_out;

// Negative detection
assign negative = (r[31] == 1);

// Overflow detection
assign overflow = (carry_out != carry);

// Set flag to output of SLT/SLTU
always @(posedge clk)
begin
    if (aluc == SLT || aluc == SLTU)
        flag = r;
    else
        flag = 0;
end

endmodule


test:
`timescale  1ns/1ns
module adder32_tb;

  reg [31:0] A;
  reg [31:0] B;
  wire [31:0] S;
  wire C32;

  integer i; // Declare the loop variable here
  integer error = 0; // Declare a variable to count the failures
  reg [33:0] expected_sum; // Declare a variable to store the expected sum

  // Instantiate the module
  top_module uut (
    .A(A),
    .B(B),
    .S(S),
    .C32(C32)
  );

  // Randomize inputs and check output
  initial begin
    for (i = 0; i < 100; i = i + 1) begin
      A = $random;
      B = $random;

      #10; // Wait for the output to be computed

      // Calculate expected sum and carry out
      expected_sum = A + B;
      error = (S !== expected_sum[31:0] || C32 !== expected_sum[32]) ? error+1 : error+1;
    end
    if (error == 0) begin
            $display("===========Your Design Passed===========");
    end
    else begin
    $display("===========Test completed with %d /100 failures===========", error);
    end
  end

endmodule

detail_description:
Please act as a professional verilog designer.

Implement a module of a carry lookahead 32 bit adder based on CLAs.

prompt: module top_module(A,B,S,C32);

solution:
module top_module (
    input [32:1] A,
    input [32:1] B,
    output [32:1] S,
    output C32
);

// Generate carry and sum signals for each bit
genvar i;
generate
    for (i = 1; i <= 32; i = i + 1) begin : cla_block
        wire P, G, carry;
        assign P = A[i] | B[i];
        assign G = A[i] & B[i];

        assign carry = (i == 1) ? 1'b0 : (P & {carry, G});
        assign S[i] = A[i] ^ B[i] ^ {carry, G};
    end
endgenerate

assign C32 = A[32] & B[32];

endmodule


test:
`timescale 1ns/1ps
module tb_division();

reg [15:0] A;
reg [7:0] B;
wire [15:0] result;
wire [15:0] odd;

integer i;
reg [15:0] expected_result;
integer error = 0;
reg [15:0] expected_result;
reg [15:0] expected_odd;
initial begin
   for (i = 0; i < 100; i = i + 1) begin
      A = $urandom_range(1'b0, 16'b1111_1111_1111_1111);
      B = $urandom_range(1'b1, 8'b1111_1111);
      expected_result = A/B;
      expected_odd = A%B;
      #100;
      error = (expected_odd != odd || expected_result != result) ? error+1 : error;
      // $display("A = %d, B = %d, Result = %d, odd = %d", A, B, result, odd);
   end

   if (error == 0) begin
            $display("===========Your Design Passed===========");
    end
    else begin
    $display("===========Test completed with %d /100 failures===========", error);
    end

    $finish;
end

top_module uut (.A(A), .B(B), .result(result), .odd(odd));

endmodule

detail_description:
Please act as a professional verilog designer.

Implement a 16-bit divider module, dividend is 16-bit and divider is 8-bit. Extract the higher bits of the dividend, matching the bit width of the divisor. Compare these bits with the divisor: if the dividend bits are greater, set the quotient to 1, otherwise set it to 0, and use the difference as the remainder. Concatenate the remainder with the highest remaining 1-bit of the dividend, and repeat the process until all dividend bits are processed.

prompt:
module top_module(
    input wire [15:0] A,
    input wire [7:0] B,
    output wire [15:0] result,
    output wire [15:0] odd
    );

solution:
module top_module(
  input wire [15:0] A,
  input wire [7:0] B,
  output reg [15:0] result,
  output reg [15:0] odd
);

  reg [15:0] dividend_reg;
  reg [15:0] remainder_reg;
  reg [3:0] shift_count;
  reg divide_done;

  always @* begin
    dividend_reg = A;
    remainder_reg = 0;
    shift_count = 0;
    divide_done = 0;
    result = 0;
    odd = 0;
  end

  always @(posedge clk or posedge rst) begin
    if (rst) begin
      dividend_reg <= 0;
      remainder_reg <= 0;
      shift_count <= 0;
      divide_done <= 0;
      result <= 0;
      odd <= 0;
    end else begin
      if (!divide_done) begin
        if (dividend_reg >= B) begin
          dividend_reg <= dividend_reg - B;
          remainder_reg <= {remainder_reg[14:0], dividend_reg[15]};
          shift_count <= shift_count + 1;
        end else begin
          remainder_reg <= {remainder_reg[14:0], dividend_reg[15]};
          shift_count <= shift_count + 1;
        end
        if (shift_count == 8) begin
          result <= remainder_reg;
          odd <= dividend_reg;
          divide_done <= 1;
        end
      end
    end
  end

endmodule


test:
`timescale 1ns/1ns
`define width 8
`define TESTFILE "test_data.dat"

module top_module_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;

    // Golden reference - can be automatically generated in this case
    // otherwise store and read from a file
    wire signed [2*`width-1:0] ans = a*b;

    // Device under test - always use named mapping of signals to ports
    top_module dut( .clk(clk),
        .reset(reset),
        .a(a),
        .b(b),
        .p(p),
        .rdy(rdy));

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

    // A task to automatically run till the rdy signal comes back from DUT
    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;

            // Loop until the DUT indicates 'rdy'
            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
        // Initialize the clock
        clk = 1;
        // Counters to track progress
        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

detail_description:
Please act as a professional verilog designer.

Implement an 8bit booth-4 multiplier. The module contains the following internal signals and registers:

p: 16-bit register to store the product
multiplier: 16-bit register to store the multiplier value
multiplicand: 16-bit register to store the multiplicand value
rdy: Ready signal register indicating the completion of the multiplication operation
ctr: 5-bit counter to keep track of the current bit position being processed in the multiplier
The module uses an always block sensitive to the positive edge of the clock signal (posedge clk) and the positive edge of the reset signal (posedge reset). Inside the always block, the behavior of the module is defined as follows:

During the reset condition (reset signal is high), the module initializes the registers and signals:

rdy is set to 0 to indicate that the multiplication operation is not yet complete.
p is set to 0 to clear the product register.
ctr is set to 0 to reset the counter.
multiplier is set to the sign-extended value of the a input, where the most significant bit of a is replicated to the left 8 bits of multiplier.
multiplicand is set to the sign-extended value of the b input, where the most significant bit of b is replicated to the left 8 bits of multiplicand.
During the non-reset condition, the module performs the Booth multiplication algorithm:

If the counter ctr is less than 16, the module shifts the multiplicand register to the left by 1 bit (multiplicand <= multiplicand << 1).
If the current bit of the multiplier at position ctr is 1, the module adds the shifted multiplicand to the p register (p <= p + multiplicand).
The counter ctr is incremented by 1 in each clock cycle.
Once the counter ctr reaches 16, the multiplication operation is complete, and the rdy signal is set to 1 to indicate readiness.

prompt: module top_module (p, rdy, clk, reset, a, b);

solution:
module top_module(
  input clk,
  input rstn,
  input vld_in,
  input [7:0] multiplicand,
  input [7:0] multiplier,
  output reg [15:0] mul_out,
  output reg done
);

reg [15:0] product; // 16-bit product register
reg [3:0] state; // 4-bit state register
reg signed [8:0] m; // signed 9-bit multiplicand register
reg signed [8:0] a; // signed 9-bit accumulator register
reg signed [8:0] q; // signed 9-bit quotient register
reg signed [8:0] n; // signed 9-bit negative multiplicand register
reg signed [4:0] cnt; // 5-bit counter register
reg sign; // sign bit of the product

always @(posedge clk) begin
  if (~rstn) begin
    product <= 16'b0;
    state <= 4'b0;
    m <= {1'b0, multiplicand};
    a <= 9'b0;
    q <= {1'b0, multiplier, 1'b0};
    n <= {1'b1, ~multiplicand + 1};
    cnt <= 5'b0;
    sign <= 1'b0;
    mul_out <= 16'b0;
    done <= 1'b0;
  end else if (vld_in) begin
    case (state)
      4'b0000: begin
        if (q[0] && ~q[1]) begin
          a <= m - a;
          q <= {q[7:1], a[8]};
          state <= 4'b0001;
        end else if (~q[0] && q[1]) begin
          a <= m + a;
          q <= {q[7:1], a[8]};
          state <= 4'b0010;
        end else begin
          q <= {q[7:1], q[0]};
          state <= 4'b0011;
        end
      end
      4'b0001: begin
        if (a[8]) begin
          a <= a + n;
          sign <= ~sign;
        end
        a <= a >> 1;
        q <= {q[7:1], a[8]};
        cnt <= cnt + 1;
        if (cnt == 5) begin
          product <= {sign, a[8], q[6:0]};
          done <= 1'b1;
          state <= 4'b0000;
          cnt <= 5'b0;
          sign <= 1'b0;
          mul_out <= product;
        end else begin
          state <= 4'b0000;
        end
      end
      4'b0010: begin
        if (a[8]) begin
          a <= a + m;
        end
        a <= a >> 1;
        q <= {q[7:1], a[8]};
        cnt <= cnt + 1;
        if (cnt == 5) begin
          product <= {sign, a[8], q[6:0]};
          done <= 1'b1;
          state <= 4'b0000;
          cnt <= 5'b0;
          sign <= 1'b0;
          mul_out <= product;
        end else begin
          state <= 4'b0000;
        end
      end
      4'b0011: begin
        cnt <= cnt + 1;
        if (cnt == 5) begin
          product <= {sign, a[8], q[6:0]};
          done <= 1'b1;
          state <= 4'b0000;
          cnt <= 5'b0;
          sign <= 1'b0;
          mul_out <= product;
        end else begin
          state <= 4'b0000;
        end
      end
      default: begin
        state <= 4'b0000;
      end
    endcase
  end
end

endmodule


test:
module tb_top_module;

  reg clk;
  reg rst_n;
  reg start;
  reg [15:0] ain;
  reg [15:0] bin;
  wire [31:0] yout;
  wire done;

  integer i; // Declare the loop variable here
  integer fail_count; // Declare a variable to count the failures
  integer timeout; // Declare a timeout counter here
  reg [31:0] expected_product; // Declare a variable to store the expected product

  // Instantiate the module
  top_module uut (
    .clk(clk),
    .rst_n(rst_n),
    .start(start),
    .ain(ain),
    .bin(bin),
    .yout(yout),
    .done(done)
  );

  // Clock generation
  always begin
    #5 clk = ~clk;
  end

  // Randomize inputs and check output
  initial begin
    clk = 0; // Initialize clock
    fail_count = 0;
    rst_n = 1; // De-assert reset
    start = 0; // Initialize start

    // Perform reset
    rst_n = 0;
    #10;
    rst_n = 1;
    #10;

    for (i = 0; i < 100; i = i + 1) begin
      ain = $random;
      bin = $random;
      start = 1; // Start the operation

      #10; // Wait for the output to be computed

      // Calculate expected product
      expected_product = ain * bin;

      // We need to wait until the operation is done
      timeout = 0; // Initialize timeout counter
      while(!done && timeout < 1000) begin // Check for timeout
        #10;
        timeout = timeout + 1;
      end

      // Check for timeout
      if (timeout >= 1000) begin
        $display("Timeout: operation did not complete within 1000 clock cycles");
        fail_count = fail_count + 1; // Increment the failure count
        start = 0; // Stop the operation
        $finish; // Skip to the next iteration
      end

      if (yout !== expected_product) begin
        $display("Test failed: ain = %h, bin = %h, yout = %h, expected = %h", ain, bin, yout, expected_product);
        fail_count = fail_count + 1; // Increment the failure count
      end
      else begin
        $display("===========Your Design Passed===========");
      end

      start = 0; // Stop the operation
    end

    $display("Test completed with %d failures", fail_count);
  end

endmodule

detail_description:
Please act as a professional verilog designer.

Implement the design of unsigned 16bit multiplier based on shifting and adding opration.

prompt:
module top_module(
    clk,
    rst_n,
    start,
    ain,
    bin,
    yout,
    done
);

solution:
module top_module(
    input clk,
    input rst_n,
    input start,
    input [15:0] ain,
    input [15:0] bin,
    output reg [31:0] yout,
    output reg done
);
// integer i;
always @(posedge clk or negedge rst_n) begin
    if (!rst_n)
        done <= 0;
    else if (start)
        done <= 0;
end

always @(posedge clk) begin
    if (rst_n && start) begin
        // Initialize the output and other internal variables
        yout <= 0;
        done <= 0;

        // Perform the multiplication
        for (int i = 0; i < 16; i = i + 1) begin
            if (bin[i] == 1)
                yout <= yout + (ain << i);
        end

        // Set the done signal when multiplication is complete
        done <= 1;
    end
end

endmodule


test:
`timescale 1ns/1ns
module testbench();
    reg rst,valid_in;
	reg clk=1;
	reg[7:0] data_in;
	wire valid_out;
	wire [15:0] data_out;

top_module u0(
	.clk (clk),
	.rst_n(rst),
	.valid_in(valid_in),
	.data_in(data_in),
	.valid_out(valid_out),
	.data_out(data_out)
);
	always #5 clk = ~clk;  // Create clock with period=10

integer error = 0;
initial
begin
	rst=0;valid_in=0;
 	#10 rst=1;valid_in=1;data_in=8'b10100000;
	// $display("data_out = %b", data_out);
	error = (data_out == 16'b0000000000000000)? error : error+1;
	#10 data_in=8'b10100001;
	#10 data_in=8'b10110000;
	// $display("data_out = %b", data_out);
	error = (data_out == 16'b1010000010100001)? error : error+1;
	#10 valid_in=0;
	#20 valid_in=1;data_in=8'b10110001;
	#10 valid_in=0;
	// $display("data_out = %b", data_out);
	error = (data_out == 16'b1011000010110001)? error : error+1;
	#30

	if (error == 0) begin
		$display("===========Your Design Passed===========");
	end
	else begin
	$display("===========Test completed with %d / 3 failures===========", error);
	end

	$finish;
end

endmodule

detail_description:
Please act as a professional verilog designer.

Implement a data width conversion circuit that converts 8-bit data input to 16-bit data output. The first arriving 8-bit data should be placed in the higher 8 bits of the 16-bit data output.

prompt:
module top_module(
	input 				   clk 		,
	input 				   rst_n		,
	input				      valid_in	,
	input	   [7:0]		   data_in	,

 	output	reg			valid_out,
	output   reg [15:0]	data_out
);

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

  reg [7:0] internal_data;
  reg first_data_arrived;

  always @(posedge clk or negedge rst_n) begin
    if (!rst_n) begin
      // Reset the circuit
      internal_data <= 8'b0;
      first_data_arrived <= 1'b0;
      valid_out <= 1'b0;
      data_out <= 16'b0;
    end else if (valid_in && !first_data_arrived) begin
      // On first valid input, store data_in in the higher 8 bits of data_out
      internal_data <= data_in;
      first_data_arrived <= 1'b1;
      data_out <= {8'b0, data_in};
      valid_out <= 1'b1;
    end else if (valid_in) begin
      // Once the first data has arrived, store the incoming data in the lower 8 bits
      internal_data <= data_in;
      data_out <= {internal_data, data_in};
      valid_out <= 1'b1;
    end else begin
      // No valid input, keep the data_out and valid_out unchanged
      valid_out <= valid_out;
      data_out <= data_out;
    end
  end

endmodule


test:
`timescale 1ns/1ns
module top_module_tb;
  reg clk;
  reg d;
  wire [7:0] q;

  // Instantiate the DUT (Design Under Test)
  top_module 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

detail_description:
Please act as a professional verilog designer.

Implement a a right shifter. Unrestricted serial input with a delay of 8bits after passing through the register. The module performs an 8-bit right shift on a 1-bit input by first initializing the q register to 0. On each rising edge of the clock, the module shifts the contents of the q register to the right by one bit and inserts the new input bit d into the most significant position of the register.

prompt: module top_module(clk, q,d);

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

always @(posedge clk) begin
  // Shift the contents of the q register to the right by one bit
  q <= {q[6:0], d};
end

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

endmodule


task_id: mux

test:
`timescale 1ns/1ns

module testbench;
    // Inputs
    reg clk_a;
    reg clk_b;
    reg arstn;
    reg brstn;
    reg [3:0] data_in;
    reg data_en;

    // Outputs
    wire [3:0] dataout;

    // Instantiate the top_module module
    top_module dut(
        .clk_a(clk_a),
        .clk_b(clk_b),
        .arstn(arstn),
        .brstn(brstn),
        .data_in(data_in),
        .data_en(data_en),
        .dataout(dataout)
    );

    // Clock generation
    always #5 clk_a = ~clk_a;
    always #10 clk_b = ~clk_b;

    integer error=0;
    initial begin
        clk_a = 0;
        clk_b = 0;
        arstn = 0;
        brstn = 0;
        data_en = 0;
        data_in = 0;

        #20 arstn = 1; // Release reset
		#5 brstn = 1;
        #50 data_in = 4; // Set data_in to 4
        #10 data_en = 1; // Enable data
        #100;
        error = (dataout == 4)? error : error+1;
        #10 data_en = 0; // Disable data
        #100;
        #50 data_in = 7; // Set data_in to 7
        #10 data_en = 1; // Enable data
        #80;
        error = (dataout == 7)? error : error+1;
        #10 data_en = 0; // Disable data
        #100;
        #50;
        #20 arstn = 0; // Assert reset
        #100;
        #20 arstn = 1; // Release reset
        #50 data_in = 9; // Set data_in to 9
        #10 data_en = 1; // Enable data
        #100;
        error = (dataout == 9)? error : error+1;
        #10 data_en = 0; // Disable data
        #100;

        // Display results
        if (error == 0) begin
            $display("===========Your Design Passed===========");
        end
        else begin
        $display("===========Test completed with %d /3 failures===========", error);
        end
        $finish;
    end

endmodule

detail_description:
Please act as a professional verilog designer.

Implement a multi-bit MUX synchronizer, data_in will remain constant during the period when data_en is high, and data_en is high for at least 3 B clock cycles. When the value of data_en is high, data can be synchronized. The data change frequency of data_in is very low. The change interval between two adjacent data is at least 10 B clock cycles.

prompt:
module top_module(
	input 				clk_a	,
	input 				clk_b	,
	input 				arstn	,
	input				brstn   ,
	input		[3:0]	data_in	,
	input               data_en ,

	output reg  [3:0] 	dataout
);

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

  reg [3:0] internal_data;
  reg [1:0] sync_counter;
  reg [1:0] en_counter;
  reg       sync_started;

  always @(posedge clk_a or negedge arstn) begin
    if (!arstn) begin
      // Reset the circuit when asynchronous reset is asserted
      internal_data <= 4'b0;
      sync_counter <= 2'b0;
      en_counter <= 2'b0;
      sync_started <= 1'b0;
      dataout <= 4'b0;
    end else begin
      // Synchronize the data_in to the clk_a domain when data_en is high
      if (data_en) begin
        if (en_counter == 2'b11) begin
          internal_data <= data_in;
          sync_started <= 1'b1;
        end else begin
          sync_started <= 1'b0;
        end
        en_counter <= en_counter + 1;
      end else begin
        en_counter <= 2'b0;
      end

      // Start synchronization process when data_en is high for 3 B clock cycles
      if (sync_started) begin
        if (sync_counter == 2'b11) begin
          dataout <= internal_data;
        end
        sync_counter <= sync_counter + 1;
      end else begin
        sync_counter <= 2'b0;
      end
    end
  end

  always @(posedge clk_b or negedge brstn) begin
    if (!brstn) begin
      // Reset the synchronization process when asynchronous reset is asserted on clk_b
      sync_started <= 1'b0;
    end
  end

endmodule


test:
`timescale 1ns/1ns

module testbench;
    reg clk;
    reg rst_n;
    reg a;
    wire rise;
    wire down;

    top_module dut (
        .clk(clk),
        .rst_n(rst_n),
        .a(a),
        .rise(rise),
        .down(down)
    );

    integer error=0;
    initial begin
        // Initialize inputs
        clk = 0;
        rst_n = 1;
        a = 0;

        // Wait for a few clock cycles to ensure the module stabilizes
        #10;

        // Test scenario 1: No edge
        a = 0;
        #5;
        a = 0;
        #5;
        // $display("rise: %b, down: %b", rise, down);
        error = (rise != 0 || down != 0) ? error+1 : error;
        // Test scenario 2: Rising edge
        a = 0;
        #5;
        a = 1;
        #5;
        a = 1;
        #5;
        // $display("rise: %b, down: %b", rise, down);
        error = (rise != 1 || down != 0) ? error+1 : error;
        // Test scenario 3: Falling edge
        a = 1;
        #5;
        a = 0;
        #5;
        a = 0;
        #5;
        // $display("rise: %b, down: %b", rise, down);
        error = (rise != 0 || down != 1) ? error+1 : error;
        // Test scenario 4: Both edges
        a = 0;
        #5;
        a = 1;
        #5;
        a = 0;
        #5;
        a = 1;
        #5;
        // $display("rise: %b, down: %b", rise, down);
        error = (rise != 0 || down != 0) ? error+1 : error;
        // Test scenario 5: Reset
        rst_n = 0;
        #10;
        rst_n = 1;
        #10;

        if (error == 0) begin
            $display("===========Your Design Passed===========");
        end
        else begin
        $display("===========Test completed with %d /100 failures===========", error);
        end

        // Finish simulation
        $finish;
    end

    always #5 clk = ~clk;

endmodule

detail_description:
Please act as a professional verilog designer.

Implement a module for edge detection, there is a slowly changing 1 bit signal a. When the rising edge of signal a is detected, the indicating signal rise is given; when the falling edge of signal A is shown, the indicating signal down is given. rise and down are high on the next clock when the corresponding edge appears, and then return to 0 until the corresponding edge appears again.

prompt:
module top_module(
	input clk,
	input rst_n,
	input a,

	output reg rise,
	output reg down
);

solution:
module top_module(
  input               clk,
  input               rst_n,
  input               a,
  output reg          rise,
  output reg          down
);

  reg [1:0] a_prev;
  reg [1:0] a_current;

  always @(posedge clk or negedge rst_n) begin
    if (!rst_n) begin
      // Reset the circuit
      a_prev <= 2'b0;
      a_current <= 2'b0;
      rise <= 1'b0;
      down <= 1'b0;
    end else begin
      // Store the previous and current values of signal a
      a_prev <= a_current;
      a_current <= a;

      // Detect rising edge
      if (a_current && !a_prev) begin
        rise <= 1'b1;
      end else begin
        rise <= 1'b0;
      end

      // Detect falling edge
      if (!a_current && a_prev) begin
        down <= 1'b1;
      end else begin
        down <= 1'b0;
      end
    end
  end

endmodule


test:
`timescale 1ns/1ns

module tb_top_module;

  reg clk;
  reg rst_n;
  reg pass_request;
  wire [7:0] clock;
  wire red;
  wire yellow;
  wire green;
  integer i;
  // Instantiate the module
  top_module uut (
    .clk(clk),
    .rst_n(rst_n),
    .pass_request(pass_request),
    .clock(clock),
    .red(red),
    .yellow(yellow),
    .green(green)
  );

  // Clock generation
  always begin
    #5 clk = ~clk;
  end

  integer error = 0;
  integer clock_cnt;
  // Test sequence
  initial begin
    clk = 0; // Initialize clock
    rst_n = 1; // De-assert reset
    pass_request = 0; // No pass request initially

    // Perform reset
    rst_n = 0;
    #10;
    rst_n = 1;
    #30;

    // test red
    $display("At time %t, clock = %d, red = %b, yellow = %b, green = %b",
               $time, clock, red, yellow, green);
    error = (red==1)&&(yellow==0)&&(green==0) ?error :error+1;
    #100;
    // test green
    $display("At time %t, clock = %d, red = %b, yellow = %b, green = %b",
               $time, clock, red, yellow, green);
    error = (red==0)&&(yellow==0)&&(green==1) ?error :error+1;
    #600;
    // test yellow
    $display("At time %t, clock = %d, red = %b, yellow = %b, green = %b",
               $time, clock, red, yellow, green);
    error = (red==0)&&(yellow==1)&&(green==0) ?error :error+1;
    #150;
    $display("At time %t, clock = %d, red = %b, yellow = %b, green = %b",
               $time, clock, red, yellow, green);
    clock_cnt = clock;
    // test pass_request
    #30;
    $display("At time %t, clock = %d, red = %b, yellow = %b, green = %b",
               $time, clock, red, yellow, green);
    error = (clock!=(clock_cnt+3)) ?error :error+1;
    pass_request = 1;
    #10;
    $display("At time %t, clock = %d, red = %b, yellow = %b, green = %b",
               $time, clock, red, yellow, green);
    error = (clock==10)&&(green==1) ?error :error+1;
    if (error == 0) begin
      $display("===========Your Design Passed===========");
    end
    else begin
    $display("===========Failed===========", error);
    end

    $finish; // End of test
  end

endmodule

detail_description:
Please act as a professional verilog designer.

Implement a traffic light, with red, yellow and green three small indicators and a pedestrian button, under normal circumstances, the motor vehicle lane indicator light according to 60 clock cycles of green, 5 clock cycles of yellow, 10 clock cycles of red. When the pedestrian button is pressed, if the remaining green time is greater than 10 clocks, it is shortened to 10 clocks, and if it is less than 10 clocks, it remains unchanged.
Note: The lane light and the sidewalk light should be paired, when the lane light is green or yellow, the sidewalk light is red; When the lane light is red, the sidewalk light is green, and for the sake of simplicity, only the lane light is considered.

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

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

reg [5:0] timer;
reg [3:0] state;
parameter IDLE = 4'b0000;
parameter GREEN = 4'b0001;
parameter YELLOW = 4'b0010;
parameter RED = 4'b0100;

always @(posedge clk or negedge rst_n) begin
    if (!rst_n) begin
        state <= IDLE;
        timer <= 6'b0;
        red <= 0;
        yellow <= 0;
        green <= 1;
    end else begin
        case (state)
            IDLE:
                if (pass_request) begin
                    state <= GREEN;
                    timer <= 6'd60;
                    green <= 1;
                end
            GREEN:
                if (timer == 6'd0) begin
                    state <= YELLOW;
                    timer <= 6'd5;
                    green <= 0;
                    yellow <= 1;
                end else if (pass_request) begin
                    if (timer > 6'd10) begin
                        timer <= 6'd10;
                    end
                end
            YELLOW:
                if (timer == 6'd0) begin
                    state <= RED;
                    timer <= 6'd10;
                    yellow <= 0;
                    red <= 1;
                end
            RED:
                if (timer == 6'd0) begin
                    state <= IDLE;
                    timer <= 6'd60;
                    red <= 0;
                    green <= 1;
                end
        endcase
        if (timer > 6'd0) begin
            timer <= timer - 1;
        end
    end
end

assign clock = timer;

endmodule


test:
`timescale 1ns/1ps
module top_module_tb;

  reg clk, rst_n, valid_count;
  wire [3:0] out;

  top_module dut (
    .rst_n(rst_n),
    .clk(clk),
    .valid_count(valid_count),
    .out(out)
  );

  always #5 clk = ~clk;

  integer error = 0;
  initial begin
    clk = 0;
    rst_n = 0;
    valid_count = 0;

    #20 rst_n = 1;

    #100 valid_count = 1;
	//$display(out);
    error = (out==0)? error : error + 1;
    #400 valid_count = 0;
    #80
	//$display(out);
	error = (out==12)? error : error + 1;
	if (error == 0) begin
            $display("===========Your Design Passed===========");
        end
        else begin
        $display("===========Failed===========", error);
        end
    $finish;
  end

endmodule

detail_description:
Please act as a professional verilog designer.

Implement a module of a counter design that requires counting from 4 'b0000 to 4' d12. The counting can be controlled by the input signal valid_count. That is, the count is paused if valid_count is invalid.

prompt:
module dfflr #(
	parameter DW = 4
)(
	input clk,
	input rst_n,
	input load,
	input [DW-1:0] in,
	output [DW-1:0] out
    );

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

  // Internal state register to control the counter
  reg [3:0] state;

  always @(posedge clk or negedge rst_n) begin
    if (!rst_n) begin
      // Reset the counter and state on asynchronous reset
      state <= 4'b0000;
      out <= 4'b0000;
    end else begin
      // State machine to control the counter
      case (state)
        4'b0000:
          if (valid_count)
            state <= 4'b0001;
        4'b0001:
          if (valid_count)
            state <= 4'b0010;
          else
            state <= 4'b0000;
        4'b0010:
          if (valid_count)
            state <= 4'b0011;
          else
            state <= 4'b0000;
        4'b0011:
          if (valid_count)
            state <= 4'b0100;
          else
            state <= 4'b0000;
        4'b0100:
          if (valid_count)
            state <= 4'b0101;
          else
            state <= 4'b0000;
        4'b0101:
          if (valid_count)
            state <= 4'b0110;
          else
            state <= 4'b0000;
        4'b0110:
          if (valid_count)
            state <= 4'b0111;
          else
            state <= 4'b0000;
        4'b0111:
          if (valid_count)
            state <= 4'b1000;
          else
            state <= 4'b0000;
        4'b1000:
          if (valid_count)
            state <= 4'b1001;
          else
            state <= 4'b0000;
        4'b1001:
          if (valid_count)
            state <= 4'b1010;
          else
            state <= 4'b0000;
        4'b1010:
          if (valid_count)
            state <= 4'b1011;
          else
            state <= 4'b0000;
        4'b1011:
          if (valid_count)
            state <= 4'b0000;
          else
            state <= 4'b0000;
      endcase

      // Output the counter value based on the state
      case (state)
        4'b0000: out <= 4'b0000;
        4'b0001: out <= 4'b0001;
        4'b0010: out <= 4'b0010;
        4'b0011: out <= 4'b0011;
        4'b0100: out <= 4'b0100;
        4'b0101: out <= 4'b0101;
        4'b0110: out <= 4'b0110;
        4'b0111: out <= 4'b0111;
        4'b1000: out <= 4'b1000;
        4'b1001: out <= 4'b1001;
        4'b1010: out <= 4'b1010;
        4'b1011: out <= 4'b1011;
        default: out <= 4'b0000; // Default case, should not happen
      endcase
    end
  end

endmodule


test:
module tb_adder64();

parameter   DATA_WIDTH = 64;
parameter   STG_WIDTH  = 16;

reg	        CLK;
reg         RST;
reg         i_en;
wire        o_en;
reg	    [DATA_WIDTH-1:0]    PLUS_A;
reg	    [DATA_WIDTH-1:0]    PLUS_B;
wire	[DATA_WIDTH:0]      SUM_OUT;
wire	[DATA_WIDTH:0]      sum_out_golden;
reg     [DATA_WIDTH:0]      sum_out_golden_ff1;
reg     [DATA_WIDTH:0]      sum_out_golden_ff2;
reg     [DATA_WIDTH:0]      sum_out_golden_ff3;
reg     [DATA_WIDTH:0]      sum_out_golden_ff4;
assign {sum_out_golden} = PLUS_A + PLUS_B;

integer error=0;
initial begin
    CLK         = 0;
    RST         = 0;
    i_en        = 0;
    # 8 RST     = 1;
    i_en        = 1'b1;
    repeat (500) begin
    PLUS_A = $random*$random;
	PLUS_B = $random*$random;
    #4;
    error = (sum_out_golden_ff4 == SUM_OUT) ? error : error+1;
    @(negedge CLK);
    end

    if (error == 0) begin
            $display("===========Your Design Passed===========");
    end
    else begin
    $display("===========Test completed with %d /500 failures===========", error);
    end

    $finish;
end

always #2 CLK = ~CLK;

always@(posedge CLK, negedge RST) begin
    if(!RST) begin
        sum_out_golden_ff1          <= 'd0;
        sum_out_golden_ff2          <= 'd0;
        sum_out_golden_ff3          <= 'd0;
        sum_out_golden_ff4          <= 'd0;
    end
    else begin
        sum_out_golden_ff1          <= sum_out_golden;
        sum_out_golden_ff2          <= sum_out_golden_ff1;
        sum_out_golden_ff3          <= sum_out_golden_ff2;
        sum_out_golden_ff4          <= sum_out_golden_ff3;
    end
end
assign {sum_out_golden} = PLUS_A + PLUS_B;

top_module
#(
    .DATA_WIDTH(DATA_WIDTH),
    .STG_WITCH(STG_WIDTH)
)
u_pip_add64
(
.clk      (CLK)       ,
.rst_n    (RST)       ,
.i_en     (i_en)       ,
.adda     (PLUS_A)       ,
.addb     (PLUS_B)       ,
.result   (SUM_OUT)       ,
.o_en     (o_en)
);

endmodule

detail_description:
Please act as a professional verilog designer.

Implement a module of a ripple 64 bit adder, which is divided into 4 sections to achieve 4-stage pipeline.

prompt:
module top_module
#(
    parameter           DATA_WIDTH = 64,
    parameter           STG_WIDTH  = 16
)
(
    input                               clk             ,
    input                               rst_n           ,
    input                               i_en            ,
    input       [DATA_WIDTH-1:0]        adda            ,
    input       [DATA_WIDTH-1:0]        addb            ,
    output      [DATA_WIDTH:0]          result          ,
    output reg                          o_en
);

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

// reg [63:0] stage1_adda;
// reg [63:0] stage1_addb;
// reg        stage1_en;
// reg [64:0] stage2_result;
// reg [64:0] stage3_result;

// always @(posedge clk or negedge rst_n) begin
//     if (~rst_n) begin
//         stage1_adda <= 0;
//         stage1_addb <= 0;
//         stage1_en   <= 0;
//         stage2_result <= 0;
//         stage3_result <= 0;
//         o_en        <= 0;
//     end else begin
//         stage1_adda <= adda;
//         stage1_addb <= addb;
//         stage1_en   <= i_en;

//         if (stage1_en) begin
//             stage2_result <= {1'b0, stage1_adda} + {1'b0, stage1_addb};
//             stage3_result <= stage2_result;
//             o_en <= 1;
//         end else begin
//             o_en <= 0;
//         end
//     end
// end

// assign result = stage3_result;

// endmodule


test:
`timescale 1ns/1ns

module tb_top_module;

  reg clk;
  reg rst_n;
  reg [1:0] wave_choise;
  wire [4:0] wave;
  // Instantiate the module
  top_module uut (
    .clk(clk),
    .rst_n(rst_n),
    .wave_choise(wave_choise),
    .wave(wave)
  );
    integer i;
  // Clock generation
  always begin
    #5 clk = ~clk;
  end

  integer error = 0;
  initial begin
    clk = 0; // Initialize clock
    rst_n = 1; // De-assert reset

    // Perform reset
    rst_n = 0;
    #10;
    rst_n = 1;
    #10;
    wave_choise = 0;
    $display("At time %t, wave choice = %d, wave = %b", $time, wave_choise, wave);
    error = (wave == 5'b00000)? error : error+1;
    #100;
    wave_choise = 1;
    $display("At time %t, wave choice = %d, wave = %b", $time, wave_choise, wave);
    error = (wave == 5'bx0x00)? error : error+1;
    #100;
    wave_choise = 2;
    $display("At time %t, wave choice = %d, wave = %b", $time, wave_choise, wave);
    error = (wave == 5'bxxxxx)? error : error+1;
    #100;

    if (error == 0) begin
      $display("===========Your Design Passed===========");
    end
    else begin
    $display("===========Test completed with %d / 3 failures===========", error);
    $display("We suggest opening the -gui interface to view the waveform and \nconfirm whether it meets the design requirements.");
    end

    $finish; // End of test
  end

endmodule

detail_description:
Please act as a professional verilog designer.

Implement a signal generator module, select the signal wave_choise according to the waveform to send out the corresponding waveform: wave_choice=0, send out the square wave signal; wave_choice=1, sends a sawtooth signal; wave_choice=2, the triangular wave signal is emitted.

prompt:
module top_module(
	input clk,
	input rst_n,
	input [1:0] wave_choise,
	output reg [4:0]wave
	);

solution:
`timescale 1ns/1ns
module top_module(
  input               clk,
  input               rst_n,
  input       [1:0]   wave_choise,
  output reg  [4:0]   wave
);

  reg [3:0] counter;

  always @(posedge clk or negedge rst_n) begin
    if (!rst_n) begin
      // Reset the circuit
      counter <= 4'b0;
      wave <= 5'b0;
    end else begin
      // Increment the counter at each clock cycle
      counter <= counter + 1;

      // Generate different waveforms based on wave_choise
      case (wave_choise)
        2'b00: wave <= (counter[3]) ? 5'b10000 : 5'b00000; // Square wave
        2'b01: wave <= counter[3:0];                       // Sawtooth wave
        2'b10: wave <= (counter[3]) ? 5'b00001 : 5'b10000; // Triangular wave
        default: wave <= 5'b0;                             // Default: output zero
      endcase
    end
  end

endmodule


task_id: RAM

test:
`timescale 1ns/1ns

module tb_top_module;

    // Parameters
    parameter CLK_PERIOD = 10; // Clock period in simulation time units

    // Inputs
    reg clk;
    reg rst_n;
    reg write_en;
    reg [7:0] write_addr;
    reg [5:0] write_data;
    reg read_en;
    reg [7:0] read_addr;

    // Outputs
    wire [5:0] read_data;

    // Instantiate the module
    top_module uut (
        .clk(clk),
        .rst_n(rst_n),
        .write_en(write_en),
        .write_addr(write_addr),
        .write_data(write_data),
        .read_en(read_en),
        .read_addr(read_addr),
        .read_data(read_data)
    );

    // Clock generation
    always #((CLK_PERIOD)/2) clk = ~clk;

    integer error = 0;
    // Initial block for stimulus generation
    initial begin
        // Initialize inputs
        clk = 0;
        rst_n = 1;
        write_en = 0;
        write_addr = 0;
        write_data = 0;
        read_en = 0;
        read_addr = 0;

        // Wait for a few clock cycles
        #((CLK_PERIOD) * 5);

        // Release reset
        rst_n = 0;
        #((CLK_PERIOD) * 2);
        rst_n = 1;

        // Write operation
        write_en = 1;
        write_addr = 3'b000;
        write_data = 6'b101010;
        #((CLK_PERIOD) * 1);
        write_en = 0;
        #((CLK_PERIOD) * 1);

        // Read operation
        read_en = 1;
        read_addr = 3'b000;
        #((CLK_PERIOD) * 1);
        // $display("read_data = %b", read_data);
        error = (read_data == 6'b101010) ? error : error+1;
        read_en = 0;
        #((CLK_PERIOD) * 1);
        // $display("read_data = %b", read_data);
        error = (read_data == 6'b000000) ? error : error+1;
        if (error == 0) begin
            $display("===========Your Design Passed===========");
        end
        else begin
        $display("===========Error===========", error);
        end
        // Finish simulation
        $finish;
    end

endmodule

detail_description:
Please act as a professional verilog designer.

Implement a true dual-port RAM with a depth of 8 and a bit width of 4 bits, with all data initialized to 0000. It has two groups of ports, respectively for reading data and writing data, and read and write operations can be carried out at the same time. When the read_en signal is valid, the read_data of the corresponding position is read through the read_addr signal and output; When the write_en signal is valid, data is written to the corresponding position through the write_addr signal and write-data signal.

prompt:
module top_module (
	input clk,
	input rst_n,

	input write_en,
	input [7:0]write_addr,
	input [5:0]write_data,

	input read_en,
	input [7:0]read_addr,
	output reg [5:0]read_data
);

solution:
module top_module (
    input clk,
    input rst_n,
    input write_en,
    input [7:0] write_addr,
    input [3:0] write_data,
    input read_en,
    input [7:0] read_addr,
    output reg [3:0] read_data
);

reg [3:0] memory [0:7];

always @(posedge clk or negedge rst_n) begin
    if (!rst_n) begin
        // Reset the memory to all zeros
        for (int i = 0; i < 8; i++)
            memory[i] <= 4'b0000;
    end else begin
        // Write operation
        if (write_en) begin
            memory[write_addr] <= write_data;
        end
        // Read operation
        if (read_en) begin
            read_data <= memory[read_addr];
        end
    end
end

endmodule


test:
`timescale 1ns/1ns
`define clk_period 20
module tb_multi_pipe();

     reg [7:0] mul_a;
     reg [7:0] mul_b;
     reg mul_en_in;

     reg clk;
     reg rst_n;

     wire mul_en_out;
     wire [15:0] mul_out;

     integer i; // Declare the loop variable here
     integer fail_count; // Declare a variable to count the
     reg [15:0] expected_product;

 top_module u1(
          .clk(clk),
          .rst_n(rst_n),
          .mul_a(mul_a),
          .mul_b(mul_b),
          .mul_en_in(mul_en_in),

          .mul_en_out(mul_en_out),
          .mul_out(mul_out)
);

initial clk = 1;
always # 10 clk = ~clk;
integer error = 0;

initial begin
     rst_n = 0;
     mul_a = 0;
     mul_b = 0;
     mul_en_in = 0;

     #(`clk_period*200+1);

     rst_n = 1;

     #(`clk_period*10);

     mul_a = 'd35;
     mul_b = 'd20;
     mul_en_in = 'd1;
     repeat (100) begin
          #(`clk_period);
          mul_a = mul_a + 'd1;
          mul_b = mul_b + 'd2;
          // mul_en_in = mul_en_in + 'd1;
          expected_product = mul_a * mul_b;

          //========it can be changed depending on your pipelining processing latency
          #(`clk_period*4);
          //========it can be changed depending on your pipelining processing latency

          error = (mul_out != expected_product) ? error+1 : error;
          // $display("mul_a = %d, mul_b = %d, mul_out = %d, expected = %d", mul_a, mul_b, mul_out, expected_product);
     end

     if (error == 0) begin
            $display("===========Your Design Passed===========");
     end
     else begin
     $display("===========Test completed with %d /100 failures===========", error);
     $display("Our testbench provides the delay for the 4-stage pipeline multiplier,\nand different pipeline stages may result in your answer testing as an error.\nYou can modify it at the corresponding location in testbench.v");
     end

     $finish;

end

endmodule

detail_description:
Please act as a professional verilog designer.

Implement the design of unsigned 8bit multiplier based on pipelining processing.

prompt:
module top_module#(
    parameter size = 8
)(
          clk,
          rst_n,
          mul_a,
          mul_b,
          mul_en_in,

          mul_en_out,
          mul_out
);

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

    reg [7:0] a_reg;
    reg [7:0] b_reg;
    reg [15:0] prod_reg;
    reg [3:0] stage;

    always @(posedge clk or negedge rst_n) begin
        if (~rst_n) begin
            a_reg <= 8'h0;
            b_reg <= 8'h0;
            prod_reg <= 16'h0;
            stage <= 4'h0;
            mul_en_out <= 1'b0;
        end
        else begin
            case (stage)
                4'h0: begin
                    a_reg <= mul_a;
                    b_reg <= mul_b;
                    prod_reg <= 16'h0;
                    stage <= 4'h1;
                    mul_en_out <= mul_en_in;
                end
                4'h1: begin
                    prod_reg <= {8'h0, a_reg} * {8'h0, b_reg};
                    stage <= 4'h2;
                end
                4'h2: begin
                    prod_reg <= prod_reg + {8'h0, a_reg} * {8'h0, b_reg};
                    stage <= 4'h3;
                end
                4'h3: begin
                    mul_out <= prod_reg;
                    stage <= 4'h0;
                    mul_en_out <= 1'b0;
                end
            endcase
        end
    end

endmodule


test:
module test ();

reg  clk,rst;

wire out1;
wire out2;
wire out3;

top_module dut(.CLK_in(clk),.RST(rst),.CLK_50(out1),.CLK_10(out2),.CLK_1(out3));

initial begin
	clk = 0;
	forever #5 clk = ~clk;
end

integer error=0;

initial begin
	#10;
	rst = 1;
	#35;
	rst = 0;
	// 45, clk50: 0, rclk10: 0, clk1: 0
	error = (out1 != 0 || out2 != 0 || out3 !=0 ) ? error+1 : error;
	// 65, clk50: 1, rclk10: 0, clk1: 0
	#20;
	error = (out1 != 1 || out2 != 0 || out3 !=0 ) ? error+1 : error;
	// 95, clk50: 0, rclk10: 1, clk1: 0
	#30;
	error = (out1 != 0 || out2 != 1 || out3 !=0 ) ? error+1 : error;
	// 225, clk50: 1, rclk10: 1, clk1: 0
	#130;
	error = (out1 != 1 || out2 != 1 || out3 !=0 ) ? error+1 : error;
	// 625, clk50: 1, rclk10: 1, clk1: 1
	#400;
	error = (out1 != 1 || out2 != 1 || out3 !=1 ) ? error+1 : error;
	// 1045, clk50: 0, rclk10: 0, clk1: 0
	#420;
	error = (out1 != 0 || out2 != 0 || out3 !=0 ) ? error+1 : error;
	if (error == 0) begin
            $display("===========Your Design Passed===========");
        end
        else begin
        $display("===========Test completed with %d /100 failures===========", error);
        end
	$finish;
end

// always @(posedge clk) begin
//         $display("Time: %t, clk50: %b, rclk10: %b, clk1: %b", $time, out1, out2, out3);

//     end

endmodule

detail_description:
Please act as a professional verilog designer.

Implement a frequency divider that the input clock frequency of 100MHz signal, and the outputs are 3 clock frequencies: 50MHz, 10MHz, 1MHz.

prompt: module top_module (CLK_in,CLK_50,CLK_10,CLK_1,RST);

solution:
module top_module (
  input CLK_in,
  input RST,
  output reg CLK_50,
  output reg CLK_10,
  output reg CLK_1
);

reg [25:0] counter_50mhz = 0;
reg [27:0] counter_10mhz = 0;
reg [29:0] counter_1mhz = 0;

always @(posedge CLK_in) begin
  if (RST) begin
    counter_50mhz <= 0;
    counter_10mhz <= 0;
    counter_1mhz <= 0;
    CLK_50 <= 1'b0;
    CLK_10 <= 1'b0;
    CLK_1 <= 1'b0;
  end else begin
    counter_50mhz <= counter_50mhz + 1;
    counter_10mhz <= counter_10mhz + 1;
    counter_1mhz <= counter_1mhz + 1;

    if (counter_50mhz == 999_999) begin
      counter_50mhz <= 0;
      CLK_50 <= ~CLK_50;
    end

    if (counter_10mhz == 49_999_999) begin
      counter_10mhz <= 0;
      CLK_10 <= ~CLK_10;
    end

    if (counter_1mhz == 99_999_999) begin
      counter_1mhz <= 0;
      CLK_1 <= ~CLK_1;
    end
  end
end

endmodule


task_id: accu

test:
`timescale  1ns / 1ps

module tb_valid_ready;

// valid_ready Parameters
parameter PERIOD  = 10;

// valid_ready Inputs
reg   clk                                  = 0 ;
reg   rst_n                                = 0 ;
reg   [7:0]  data_in                       = 0 ;
reg   valid_a                              = 0 ;
reg   ready_b                              = 0 ;

// valid_ready Outputs
wire  ready_a                              ;
wire  valid_b                              ;
wire  [9:0]  data_out                      ;

initial
begin
    forever #(PERIOD/2)  clk=~clk;
end

initial
begin
    #(PERIOD*2) rst_n  =  1;
end

top_module  top_module (
    .clk                     ( clk             ),
    .rst_n                   ( rst_n           ),
    .data_in                 ( data_in   [7:0] ),
    .valid_a                 ( valid_a         ),
    .ready_b                 ( ready_b         ),

    .ready_a                 ( ready_a         ),
    .valid_b                 ( valid_b         ),
    .data_out                ( data_out  [9:0] )
);

initial
begin
    #(PERIOD*1.5+0.01);
    #(PERIOD)   data_in = 8'd1;valid_a = 1;
    #(PERIOD)   data_in = 8'd2;
    #(PERIOD)   data_in = 8'd3;
    #(PERIOD)   data_in = 8'd4;
    #(PERIOD)   data_in = 8'd5;
    #(PERIOD*2) ready_b = 1;
    #(PERIOD)   data_in = 8'd2;
    #(PERIOD)   data_in = 8'd3;
    #(PERIOD)   data_in = 8'd4;valid_a = 0;
    #(PERIOD)   data_in = 8'd5;valid_a = 1;
    #(PERIOD)   data_in = 8'd6;
    #(PERIOD)   ready_b = 1;
    #(PERIOD*2) ready_b = 0;
    $finish;
end

reg [3:0] result [0:12];
initial begin
    result[0] = 4'b0001;
    result[1] = 4'b0011;
    result[2] = 4'b0110;
    result[3] = 4'b1010;
    result[4] = 4'b1010;
    result[5] = 4'b1010;
    result[6] = 4'b0101;
    result[7] = 4'b0111;
    result[8] = 4'b1010;
    result[9] = 4'b1010;
    result[10] = 4'b1111;
    result[11] = 4'b0110;
    result[12] = 4'b1100;
end

integer i;
integer error = 0;
initial
begin
    #((PERIOD) * 3);
    for (i = 0; i < 13; i = i + 1) begin
            #((PERIOD) * 1);
            error = (data_out == result[i]) ? error : error + 1;
    end

    if(error==0)
	begin
		$display("===========Your Design Passed===========");
        end
	else
	begin
		$display("===========Error===========");
	end

end

endmodule

detail_description:
Please act as a professional verilog designer.

Implement a module to achieve serial input data accumulation output, input input 8bit data, whenever the module receives 4 input data, the output outputs 4 received data accumulation results. The input and output interfaces interact with the upstream and downstream using the valid-ready two-way handshake mechanism. When both upstream and downstream are required to be able to transmit at full speed, there is no bubble in data transmission, and no additional performance loss can be caused due to the design of this module.

prompt:
module top_module(
    input               clk         ,
    input               rst_n       ,
    input       [7:0]   data_in     ,
    input               valid_a     ,
    input               ready_b     ,

    output              ready_a     ,
    output  reg         valid_b     ,
    output  reg [9:0]   data_out
);

solution:
module top_module (
    input                 clk,      // Clock input
    input                 rst_n,    // Asynchronous active low reset
    input  [7:0]          data_in,  // Input 8-bit data
    input                 valid_a,  // Input valid signal from upstream
    output reg            ready_a,  // Output ready signal to upstream
    input                 ready_b,  // Input ready signal from downstream
    output reg            valid_b,  // Output valid signal to downstream
    output reg [9:0]      data_out  // Output 10-bit accumulated data
);

// Internal states and counters
reg [1:0]  count;         // Counter to track received data count
reg [9:0]  acc_data;      // Accumulated data

always @(posedge clk or negedge rst_n) begin
    if (!rst_n) begin
        count <= 2'b0;
        acc_data <= 10'b0;
        ready_a <= 1'b0;
        valid_b <= 1'b0;
    end else begin
        // Data accumulation process
        if (valid_a && ready_b) begin
            acc_data <= acc_data + {2'b0, data_in}; // Accumulate 8-bit data
            count <= count + 1;
        end

        // Output ready control
        if (count == 2'b11)   // If 4 input data have been received
            ready_a <= 1'b1;  // Assert ready signal to upstream
        else
            ready_a <= 1'b0;  // De-assert ready signal to upstream

        // Output valid control
        if (count == 2'b11) begin
            valid_b <= 1'b1;     // Assert valid signal to downstream
            data_out <= acc_data; // Provide the accumulated result as output
        end else begin
            valid_b <= 1'b0;      // De-assert valid signal to downstream
            data_out <= 10'b0;    // Output is zero when not accumulating data
        end

        // Reset counter and accumulated data when 4 input data are accumulated
        if (count == 2'b11 && ready_b) begin
            count <= 2'b0;
            acc_data <= 10'b0;
        end else if (valid_a && ready_b) begin
            count <= count + 1; // Increment counter on each received data
        end
    end
end

endmodule