dakies/OSS_Verilog huggingface dataset:
module RAM #(
  parameter DEPTH = 8,
  parameter WIDTH = 4
) (
  input clk,
  input rst_n,
  input write_en,
  input [WIDTH-1:0] write_addr,
  input [DEPTH-1:0] write_data,
  input read_en,
  input [WIDTH-1:0] read_addr,
  output reg [DEPTH-1:0] read_data
);

  reg [DEPTH-1:0] RAM [0:(2**WIDTH)-1];

  always @(posedge clk or negedge rst_n) begin
    if (~rst_n) begin
      for (integer i = 0; i < 2**WIDTH; i = i + 1) begin
        RAM[i] <= 0;
      end
    end else begin
      if (write_en) begin
        RAM[write_addr] <= write_data;
      end
    end
  end

  always @(posedge clk or negedge rst_n) begin
    if (~rst_n) begin
      read_data <= 0;
    end else begin
      if (read_en) begin
        read_data <= RAM[read_addr];
      end else begin
        read_data <= 0;
      end
    end
  end

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

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

  // Instantiate 8 full adders
  // Connect the carry-in and carry-out signals appropriately
  full_adder fa0(a[0], b[0], cin, sum[0], carry[0]);
  full_adder fa1(a[1], b[1], carry[0], sum[1], carry[1]);
  full_adder fa2(a[2], b[2], carry[1], sum[2], carry[2]);
  full_adder fa3(a[3], b[3], carry[2], sum[3], carry[3]);
  full_adder fa4(a[4], b[4], carry[3], sum[4], carry[4]);
  full_adder fa5(a[5], b[5], carry[4], sum[5], carry[5]);
  full_adder fa6(a[6], b[6], carry[5], sum[6], carry[6]);
  full_adder fa7(a[7], b[7], carry[6], sum[7], carry_out[7]);

  // Assign the carry-out of the last full adder to cout
  assign cout = carry_out[7];

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

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

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

  reg [2:0] cnt;
  reg [3:0] data;

  always @(posedge clk or negedge rst_n) begin
    if (~rst_n) begin
      cnt <= 3'b0;
      data <= 4'b0;
      valid_out <= 1'b0;
      dout <= 1'b0;
    end else begin
      if (cnt == 3'b11) begin
        cnt <= 3'b0;
        data <= d;
        valid_out <= 1'b1;
        dout <= data[3];
      end else begin
        cnt <= cnt + 1;
        valid_out <= 1'b0;
        data <= {data[2:0], 1'b0};
        dout <= data[3];
      end
    end
  end

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

  localparam IDLE = 2'b00;
  localparam SUB = 2'b01;
  localparam SHIFT = 2'b10;
  localparam DONE = 2'b11;

  reg [1:0] current_state;
  reg [1:0] next_state;
  reg [2*DATAWIDTH-1:0] dividend_e;
  reg [2*DATAWIDTH-1:0] divisor_e;
  reg [2*DATAWIDTH-1:0] quotient_e;
  reg [2*DATAWIDTH-1:0] remainder_e;
  reg [3:0] count;

  always @(posedge clk or negedge rstn) begin
    if (~rstn) begin
      current_state <= IDLE;
      next_state <= IDLE;
      dividend_e <= 0;
      divisor_e <= 0;
      quotient_e <= 0;
      remainder_e <= 0;
      count <= 0;
      ready <= 0;
      vld_out <= 0;
    end else begin
      current_state <= next_state;
    end
  end

  always @(*) begin
    case (current_state)
      IDLE: begin
        if (en) begin
          next_state = SUB;
          dividend_e = {dividend, {DATAWIDTH{1'b0}}};
          divisor_e = {divisor, {DATAWIDTH{1'b0}}};
          quotient_e = 0;
          remainder_e = dividend_e;
          count = 0;
          ready = 0;
          vld_out = 0;
        end else begin
          next_state = IDLE;
          ready = 1;
        end
      end
      SUB: begin
        next_state = SHIFT;
        if (remainder_e >= divisor_e) begin
          remainder_e = remainder_e - divisor_e;
          quotient_e = quotient_e + {1'b1, {DATAWIDTH{1'b0}}};
        end else begin
          quotient_e = quotient_e + {1'b0, {DATAWIDTH{1'b0}}};
        end
      end
      SHIFT: begin
        if (count < DATAWIDTH) begin
          next_state = SUB;
          remainder_e = {remainder_e[2*DATAWIDTH-2:DATAWIDTH], remainder_e[DATAWIDTH-1:0]};
          count = count + 1;
        end else begin
          next_state = DONE;
        end
      end
      DONE: begin
        next_state = IDLE;
        ready = 1;
        vld_out = 1;
        quotient = quotient_e[2*DATAWIDTH-1:DATAWIDTH];
        remainder = remainder_e[DATAWIDTH-1:0];
      end
    endcase
  end

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

  reg [9:0] accumulator;
  reg [3:0] count;

  always @(posedge clk or negedge rst_n) begin
    if (~rst_n) begin
      accumulator <= 10'b0;
      count <= 4'b0;
      valid_out <= 1'b0;
    end
    else begin
      if (valid_in) begin
        accumulator <= accumulator + data_in;
        count <= count + 1'b1;
        
        if (count == 4'b11) begin
          data_out <= accumulator;
          valid_out <= 1'b1;
        end
        else begin
          valid_out <= 1'b0;
        end
      end
    end
  end

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

  reg state;

  always @(posedge clk or negedge rst_n) begin
    if (~rst_n) begin
      state <= 0;
      wave <= 0;
    end else begin
      case (state)
        0: begin
          if (wave == 31)
            state <= 1;
          else
            wave <= wave + 1;
        end
        1: begin
          if (wave == 0)
            state <= 0;
          else
            wave <= wave - 1;
        end
        default: state <= 0;
      endcase
    end
  end

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

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

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

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

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

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

  reg [2:0] state;

  always @(posedge clk or negedge rst_n) begin
    if (~rst_n) begin
      state <= 3'b000;
      data_out <= 1'b0;
    end else begin
      case (state)
        3'b000: begin
          if (data_in) begin
            state <= 3'b001;
          end else begin
            state <= 3'b000;
          end
        end
        3'b001: begin
          if (data_in) begin
            state <= 3'b010;
          end else begin
            state <= 3'b000;
          end
        end
        3'b010: begin
          if (data_in) begin
            state <= 3'b011;
          end else begin
            state <= 3'b000;
          end
        end
        3'b011: begin
          if (~data_in) begin
            state <= 3'b100;
            data_out <= 1'b1;
          end else begin
            state <= 3'b011;
          end
        end
        3'b100: begin
          if (~data_in) begin
            state <= 3'b100;
          end else begin
            state <= 3'b000;
            data_out <= 1'b0;
          end
        end
        default: begin
          state <= 3'b000;
          data_out <= 1'b0;
        end
      endcase
    end
  end

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

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

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

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

endmodule
module tb_RCA4;
  wire [3:0] sum;
  wire cout;
  reg [3:0] a, b;
  reg cin;
  
  RCA4 rca4(sum[3:0], cout, a[3:0], b[3:0]);
  
  initial
  begin
    $display("a|b||cout|sum");
  end
  
  initial
  begin
    $monitor("%b|%b||%b|%b", a[3:0], b[3:0], cout, sum[3:0]);
  end
  
  initial
  begin
    a=4'b1010; b=4'b1010;
    #10 a=4'b1000; b=4'b1100;
    #10 a=4'b0011; b=4'b1111;

  end
endmodule
module tb_CSkipA8;
  wire [7:0] sum;
  wire cout;
  reg [7:0] a, b;
  
  CSkipA8 csa8(sum[7:0], cout, a[7:0], b[7:0]);
  
  initial
  begin
    $display("a       |b       ||cout|sum     ");
  end
  
  initial
  begin
    $monitor("%b|%b||%b   |%b", a[7:0], b[7:0], cout, sum[7:0]);
  end
  
  initial
  begin
    a=8'b10100000; b=8'b10100000;
    #10 a=8'b01011000; b=8'b11110100;
    #10 a=8'b00111101; b=8'b00001111;
    #10 a=8'b11001010; b=8'b11001000;
    #10 a=8'b10100110; b=8'b11110100;
    #10 a=8'b11110011; b=8'b11001100;
    #10 a=8'b11110011; b=8'b01010111;

  end
endmodule
module tb_CSkipA16;
  wire [15:0] sum;
  wire cout;
  reg [15:0] a, b;
  
  CSkipA16 csa16(sum[15:0], cout, a[15:0], b[15:0]);
  
  initial
  begin
    $display("a       |b       ||cout|sum     ");
  end
  
  initial
  begin
    $monitor("%b|%b||%b   |%b", a[15:0], b[15:0], cout, sum[15:0]);
  end
  
  initial
  begin
    a=16'b1010000010100000; b=16'b1010000010100000;
    #10 a=16'b0101100011110100; b=16'b1111010011110100;
    #10 a=16'b0000111100111101; b=16'b0000111100001111;
    #10 a=16'b1100100011001010; b=16'b1100100011001010;
  end
endmodule
module tb_CSkipA32;
  wire [31:0] sum;
  wire cout;
  reg [31:0] a, b;
  reg cin;
  
  CSkipA32 sca32(sum[31:0], cout, a[31:0], b[31:0]);
  
  initial
  begin
    $display("a|b||cout|sum");
  end
  
  initial
  begin
    $monitor("%b|%b||%b|%b", a[31:0], b[31:0], cout, sum[31:0]);
  end
  
  initial
  begin
    a='b10100000101000001111111111111111; b='b10100000101111111111111111100000;
    #10 a='b01011000111111111111111111110100; b='b11110100111101001111111111111111;
    #10 a='b11111111111111110000111100111101; b='b00001111000011111111111111111111;
    #10 a='b11011111111111111110100011001010; b='b11001111111111111111100011001010;

  end
endmodule
module tb_CSkipA64;
  wire [63:0] sum;
  wire cout;
  reg [63:0] a, b;
  reg cin;
  
  CSkipA64 csa64(sum[63:0], cout, a[63:0], b[63:0]);
  
  initial
  begin
    $display("a|b||cout|sum");
  end
  
  initial
  begin
    $monitor("%d|%d||%d|%d", a[63:0], b[63:0], cout, sum[63:0]);
  end
  
  initial
  begin
    a=64'd998; b=64'd128;
    #10 a=64'd9998; b=64'd9028;
    #10 a=64'd999909989998; b=64'd769028;

  end
endmodule
module FA(output sum, cout, input a, b, cin);
  wire w0, w1, w2;
  
  xor (w0, a, b);
  xor (sum, w0, cin);
  
  and (w1, w0, cin);
  and (w2, a, b);
  or (cout, w1, w2);
endmodule
module RCA4(output [3:0] sum, output cout, input [3:0] a, b, input cin);
  
  wire [3:1] c;
  
  FA fa0(sum[0], c[1], a[0], b[0], cin);
  FA fa[2:1](sum[2:1], c[3:2], a[2:1], b[2:1], c[2:1]);
  FA fa31(sum[3], cout, a[3], b[3], c[3]);
  
endmodule
module SkipLogic(output cin_next,
  input [3:0] a, b, input cin, cout);
  
  wire p0, p1, p2, p3, P, e;
  
  or (p0, a[0], b[0]);
  or (p1, a[1], b[1]);
  or (p2, a[2], b[2]);
  or (p3, a[3], b[3]);
  
  and (P, p0, p1, p2, p3);
  and (e, P, cin);
  
  or (cin_next, e, cout);

endmodule
module CSkipA8(output [7:0] sum, output cout, input [7:0] a, b);
  
  wire cout0, cout1, e;
  
  RCA4 rca0(sum[3:0], cout0, a[3:0], b[3:0], 0);
  RCA4 rca1(sum[7:4], cout1, a[7:4], b[7:4], e);
  
  SkipLogic skip0(e, a[3:0], b[3:0], 0, cout0);
  SkipLogic skip1(cout, a[7:4], b[7:4], e, cout1);
  
endmodule
module CSkipA16(output [15:0] sum, output cout, input [15:0] a, b);
  
  wire [3:0] couts;
  wire [2:0] e; 
  
  RCA4 rca0(sum[3:0], couts[0], a[3:0], b[3:0], 0);
  RCA4 rca[3:1](sum[15:4], couts[3:1], a[15:4], b[15:4], e[2:0]);
  
  SkipLogic skip0(e[0], a[3:0], b[3:0], 0, couts[0]);
  SkipLogic skip[2:1](e[2:1], a[11:4], b[11:4], e[1:0], couts[2:1]);
  SkipLogic skip3(cout, a[15:12], b[15:12], e[2], couts[3]);

endmodule
module CSkipA32(output [31:0] sum, output cout, input [31:0] a, b);
  
  wire [7:0] couts;
  wire [6:0] e;
  
  RCA4 rca0(sum[3:0], couts[0], a[3:0], b[3:0], 0);
  RCA4 rca[7:1](sum[31:4], couts[7:1], a[31:4], b[31:4], e[6:0]);
  
  SkipLogic skip0(e[0], a[3:0], b[3:0], 0, couts[0]);
  SkipLogic skip[6:1](e[6:1], a[27:4], b[27:4], e[5:0], couts[6:1]);
  SkipLogic skip7(cout, a[31:28], b[31:24], e[6], couts[7]);

endmodule
module CSkipA64(output [63:0] sum, output cout, input [63:0] a, b);
  
  wire [15:0] couts;
  wire [14:0] e;
  
  RCA4 rca0(sum[3:0], couts[0], a[3:0], b[3:0], 0);
  RCA4 rca[15:1](sum[63:4], couts[15:1], a[63:4], b[63:4], e[14:0]);
  
  SkipLogic skip0(e[0], a[3:0], b[3:0], 0, couts[0]);
  SkipLogic skip[14:1](e[14:1], a[59:4], b[59:4], e[13:0], couts[14:1]);
  SkipLogic skip15(cout, a[63:60], b[63:60], e[14], couts[15]);
  
endmodule
module tb_CSelA8;
  wire [7:0] sum;
  wire cout;
  reg [7:0] a, b;
  reg cin;

  CSelA8 csa8(sum[7:0], cout, a[7:0], b[7:0]);

  initial
  begin
    $display("a       |b       ||cout|sum     ");
  end

  initial
  begin
    $monitor("%b|%b||%b   |%b", a[7:0], b[7:0], cout, sum[7:0]);
  end

  initial
  begin
    a=8'b10100000; b=8'b10100000;
    #10 a=8'b01011000; b=8'b11110100;
    #10 a=8'b00111101; b=8'b00001111;
    #10 a=8'b11001010; b=8'b11001000;
    #10 a=8'b10100110; b=8'b11110100;
    #10 a=8'b11110011; b=8'b11001100;
    #10 a=8'b11110011; b=8'b01010111;

  end
endmodule
module tb_CSelA16;
  wire [15:0] sum;
  wire cout;
  reg [15:0] a, b;
  reg cin;
  
  CSelA16 csa16(sum[15:0], cout, a[15:0], b[15:0]);
  
  initial
  begin
    $display("a               |b               ||cout|sum             ");
  end
  
  initial
  begin
    $monitor("%b|%b||%b   |%b", a[15:0], b[15:0], cout, sum[15:0]);
  end
  
  initial
  begin
    a=16'b1010000010100000; b=16'b1010000010100000;
    #10 a=16'b0101100011110100; b=16'b1111010011110100;
    #10 a=16'b0000111100111101; b=16'b0000111100001111;
    #10 a=16'b1100100011001010; b=16'b1100100011001010;

  end
endmodule
module tb_CSelA32;
  wire [31:0] sum;
  wire cout;
  reg [31:0] a, b;
  reg cin;
  
  CSelA32 csa32(sum[31:0], cout, a[31:0], b[31:0]);
  
  initial
  begin
    $display("a|b||cout|sum");
  end
  
  initial
  begin
    $monitor("%h|%h||%b|%h", a[31:0], b[31:0], cout, sum[31:0]);
  end
  
  initial
  begin
    a='b10100000101000001111111111111111; b='b10100000101111111111111111100000;
    #10 a='b01011000111111111111111111110100; b='b11110100111101001111111111111111;
    #10 a='b11111111111111110000111100111101; b='b00001111000011111111111111111111;
    #10 a='b11011111111111111110100011001010; b='b11001111111111111111100011001010;

  end
endmodule
module tb_CSelA64;
  wire [63:0] sum;
  wire cout;
  reg [63:0] a, b;
  reg cin;
  
  CSelA64 csa64(sum[63:0], cout, a[63:0], b[63:0]);
  
  initial
  begin
    $display("a|b||cout|sum");
  end
  
  initial
  begin
    $monitor("%d|%d||%d|%d", a[63:0], b[63:0], cout, sum[63:0]);
  end
  
  initial
  begin
    a=64'd998; b=64'd128;
    #10 a=64'd9998; b=64'd9028;
    #10 a=64'd09989998; b=64'd769028;

  end
endmodule
module FA(output sum, cout, input a, b, cin);
  wire w0, w1, w2;
  
  xor #(2) (w0, a, b);
  xor #(2) (sum, w0, cin);
  
  and #(1) (w1, w0, cin);
  and #(1) (w2, a, b);
  or #(1) (cout, w1, w2);
endmodule
module MUX2to1_w1(output y, input i0, i1, s);

  wire e0, e1;
  not #(1) (sn, s);
  
  and #(1) (e0, i0, sn);
  and #(1) (e1, i1, s);
  
  or #(1) (y, e0, e1);
  
endmodule
module MUX2to1_w4(output [3:0] y, input [3:0] i0, i1, input s);

  wire [3:0] e0, e1;
  not #(1) (sn, s);
  
  and #(1) (e0[0], i0[0], sn);
  and #(1) (e0[1], i0[1], sn);
  and #(1) (e0[2], i0[2], sn);
  and #(1) (e0[3], i0[3], sn);
      
  and #(1) (e1[0], i1[0], s);
  and #(1) (e1[1], i1[1], s);
  and #(1) (e1[2], i1[2], s);
  and #(1) (e1[3], i1[3], s);
  
  or #(1) (y[0], e0[0], e1[0]);
  or #(1) (y[1], e0[1], e1[1]);
  or #(1) (y[2], e0[2], e1[2]);
  or #(1) (y[3], e0[3], e1[3]);
  
endmodule
module CSelA8(output [7:0] sum, output cout, input [7:0] a, b);

  wire [7:0] sum0, sum1;
  wire c1;

  RCA4 rca0_0(sum0[3:0], cout0_0, a[3:0], b[3:0], 0);
  RCA4 rca0_1(sum1[3:0], cout0_1, a[3:0], b[3:0], 1);
  MUX2to1_w4 mux0_sum(sum[3:0], sum0[3:0], sum1[3:0], 0);
  MUX2to1_w1 mux0_cout(c1, cout0_0, cout0_1, 0);

  RCA4 rca1_0(sum0[7:4], cout1_0, a[7:4], b[7:4], 0);
  RCA4 rca1_1(sum1[7:4], cout1_1, a[7:4], b[7:4], 1);
  MUX2to1_w4 mux1_sum(sum[7:4], sum0[7:4], sum1[7:4], c1);
  MUX2to1_w1 mux1_cout(cout, cout1_0, cout1_1, c1);
  
endmodule
module CSelA16(output [15:0] sum, output cout, input [15:0] a, b);

  wire [15:0] sum0, sum1;
  wire c1, c2, c3;

  RCA4 rca0_0(sum0[3:0], cout0_0, a[3:0], b[3:0], 0);
  RCA4 rca0_1(sum1[3:0], cout0_1, a[3:0], b[3:0], 1);
  MUX2to1_w4 mux0_sum(sum[3:0], sum0[3:0], sum1[3:0], 0);
  MUX2to1_w1 mux0_cout(c1, cout0_0, cout0_1, 0);

  RCA4 rca1_0(sum0[7:4], cout1_0, a[7:4], b[7:4], 0);
  RCA4 rca1_1(sum1[7:4], cout1_1, a[7:4], b[7:4], 1);
  MUX2to1_w4 mux1_sum(sum[7:4], sum0[7:4], sum1[7:4], c1);
  MUX2to1_w1 mux1_cout(c2, cout1_0, cout1_1, c1);
  
  RCA4 rca2_0(sum0[11:8], cout2_0, a[11:8], b[11:8], 0);
  RCA4 rca2_1(sum1[11:8], cout2_1, a[11:8], b[11:8], 1);
  MUX2to1_w4 mux2_sum(sum[11:8], sum0[11:8], sum1[11:8], c2);
  MUX2to1_w1 mux2_cout(c3, cout2_0, cout2_1, c1);

  RCA4 rca3_0(sum0[15:12], cout3_0, a[15:12], b[15:12], 0);
  RCA4 rca3_1(sum1[15:12], cout3_1, a[15:12], b[15:12], 1);
  MUX2to1_w4 mux3_sum(sum[15:12], sum0[15:12], sum1[15:12], c3);
  MUX2to1_w1 mux3_cout(cout, cout3_0, cout3_1, c1);

endmodule
module CSelA32(output [31:0] sum, output cout, input [31:0] a, b);

  wire [31:0] sum0, sum1;
  wire [7:1] c;
  wire [7:0] cout0, cout1;

  RCA4 rca0_0(sum0[3:0], cout0[0], a[3:0], b[3:0], 0);
  RCA4 rca0_1(sum1[3:0], cout1[0], a[3:0], b[3:0], 1);
  MUX2to1_w4 mux0_sum(sum[3:0], sum0[3:0], sum1[3:0], 0);
  MUX2to1_w1 mux0_cout(c[1], cout0[0], cout1[0], 0);

  RCA4 rca_other_0[6:1](sum0[27:4], cout0[6:1], a[27:4], b[27:4], 1'b0);
  RCA4 rca_other_1[6:1](sum1[27:4], cout1[6:1], a[27:4], b[27:4], 1'b1);
  MUX2to1_w4 mux_other_sum[6:1](sum[27:4], sum0[27:4], sum1[27:4], c[6:1]);
  MUX2to1_w1 mux_other_cout[6:1](c[7:2], cout0[6:1], cout1[6:1], c[6:1]);

  RCA4 rca_last_0(sum0[31:28], cout0[7], a[31:28], b[31:28], 0);
  RCA4 rca_last_1(sum1[31:28], cout1[7], a[31:28], b[31:28], 1);
  MUX2to1_w4 mux_last_sum(sum[31:28], sum0[31:28], sum1[31:28], c[7]);
  MUX2to1_w1 mux_last_cout(cout, cout0[7], cout1[7], c[7]);

endmodule
module CSelA64(output [63:0] sum, output cout, input [63:0] a, b);

  wire [63:0] sum0, sum1;
  wire [15:1] c;
  wire [15:0] cout0, cout1;

  RCA4 rca0_0(sum0[3:0], cout0[0], a[3:0], b[3:0], 0);
  RCA4 rca0_1(sum1[3:0], cout1[0], a[3:0], b[3:0], 1);
  MUX2to1_w4 mux0_sum(sum[3:0], sum0[3:0], sum1[3:0], 0);
  MUX2to1_w1 mux0_cout(c[1], cout0[0], cout1[0], 0);

  RCA4 rca_other_0[14:1](sum0[59:4], cout0[14:1], a[59:4], b[59:4], 1'b0);
  RCA4 rca_other_1[14:1](sum1[59:4], cout1[14:1], a[59:4], b[59:4], 1'b1);
  MUX2to1_w4 mux_other_sum[14:1](sum[59:4], sum0[59:4], sum1[59:4], c[14:1]);
  MUX2to1_w1 mux_other_cout[14:1](c[15:2], cout0[14:1], cout1[14:1], c[14:1]);

  RCA4 rca_last_0(sum0[63:60], cout0[15], a[63:60], b[63:60], 0);
  RCA4 rca_last_1(sum1[63:60], cout1[15], a[63:60], b[63:60], 1);
  MUX2to1_w4 mux_last_sum(sum[63:60], sum0[63:60], sum1[63:60], c[15]);
  MUX2to1_w1 mux_last_cout(cout, cout0[15], cout1[15], c[15]);

endmodule
module tb_HA8;
  wire [7:0] sum;
  wire cout;
  reg [7:0] a, b;
  reg cin;
  
  HA8 ha8(sum, cout, a, b);
  
  initial
  begin
    $display("a|b||cout|sum");
  end
  
  initial
  begin
    $monitor("%b|%b||%b|%b", a, b, cout, sum);
  end
  
  initial
  begin
    a=8'b11111010; b=8'b11110000;
    #40    a=8'b11111010; b=8'b11110001;
    #40    a=8'b00111000; b=8'b10010000;
    #40    a=8'b11000010; b=8'b10110000;

  end

endmodule
module tb_HA16;
  wire [15:0] sum;
  wire cout;
  reg [15:0] a, b;
  reg cin;
  
  HA16 ha16(sum, cout, a, b);
  
  initial
  begin
    $display("a|b||cout|sum");
  end
  
  initial
  begin
    $monitor("%b|%b||%b|%b", a, b, cout, sum);
  end
  
  initial
  begin
    a=16'b1111101011111010; b=16'b1111101011110000;
    #40    a=16'b1111101000111000; b=16'b0000000011110001;
    #40    a=16'b0011100000111000; b=16'b1001000011110001;
    #40    a=16'b1111110001000010; b=16'b1011111100010000;

  end

endmodule
module tb_HA32;
  wire [31:0] sum;
  wire cout;
  reg [31:0] a, b;
  reg cin;
  
  HA32 ha32(sum, cout, a, b);
  
  initial
  begin
    $display("a|b||cout|sum");
  end
  
  initial
  begin
    $monitor("%b|%b||%b|%b", a, b, cout, sum);
  end
  
  initial
  begin
    a=32'b11111010111110000000011110001111; b=32'b01010101111100000000000011110001;
    #100    a=32'b11111010001110001111111111111111; b=32'b00000000111100101010101001010001;
    #100    a=32'b00111000001110010101010011101010; b=32'b10010000111100000111111100011101;
    #100    a=32'b11111100010011111100000111110010; b=32'b10111111000100111100011100010100;

  end

endmodule
module tb_HA64;
  wire [63:0] sum;
  wire cout;
  reg [63:0] a, b;
  reg cin;
  
  HA64 ha64(sum, cout, a, b);
  
  initial
  begin
    $display("a|b||cout|sum");
  end
  
  initial
  begin
    $monitor("%b|%b||%b|%b", a, b, cout, sum);
  end
  
  initial
  begin
    a=64'b1111111101011111000000001111000111111010111110000000011110001111; b=64'b0101010111110000000111110101111100000000111100011110000011110001;
    #200 a=64'b1111101011111000111110101111100000000111100011110000011110001111; b=64'b0101010111110111110101111100000000111100011110000000000011110001;
  end

endmodule
module tb_FA;
  wire sum, cout;
  reg a, b, cin;
  
  FA fa(sum, cout, a, b, cin);
  
  initial
  begin
    $display("a|b|cin||cout|sum");
  end
  
  initial
  begin
    $monitor("%b|%b|%b  ||%b   |%b  ", a, b, cin, cout, sum);
  end
  
  initial
  begin
    a=0; b=0; cin=0;
    #10 a=0; b=0; cin=1;
    #10 a=0; b=1; cin=0;
    #10 a=0; b=1; cin=1;
    #10 a=1; b=0; cin=0;
    #10 a=1; b=0; cin=1;
    #10 a=1; b=1; cin=0;
    #10 a=1; b=1; cin=1;
  end
endmodule
module tb_RCA8;
  wire [7:0] sum;
  wire cout;
  reg [7:0] a, b;
  reg cin;
  
  reg [15:0] i;
  
  RCA8 rca8(sum[7:0], cout, a[7:0], b[7:0]);
  
  initial
  begin
    $display("a|b||cout|sum");
  end
  
  reg checkCarry;
  reg [7:0] checkSum;
  
  initial
  begin
    for(i=0; i<65536; i=i+1)
    begin
      #20; {checkCarry,checkSum} = a+b;
      $display("a=%b|b=%b||carry=%b|sum=%b", a[7:0], b[7:0], cout, sum[7:0]);
      $display("isCarryOK=%b|isSumOK=%b", ~(checkCarry^cout), ~|(checkSum^sum[7:0]));
      $display("---------------------------");
      {a[7:0], b[7:0]}=i;
      
    end
  end

endmodule
module tb_RCA16;
  wire [15:0] sum;
  wire cout;
  reg [15:0] a, b;
  reg cin;
  
  RCA16 rca16(sum[15:0], cout, a[15:0], b[15:0]);
  
  initial
  begin
    $display("a|b||cout|sum");
  end
  
  initial
  begin
    $monitor("%b|%b||%b   |%b", a[15:0], b[15:0], cout, sum[15:0]);
  end
  
  initial
  begin
    a=16'b1010000010100000; b=16'b1010000010100000;
    #10 a=16'b0101100011110100; b=16'b1111010011110100;
    #10 a=16'b0000111100111101; b=16'b0000111100001111;
    #10 a=16'b1100100011001010; b=16'b1100100011001010;

  end
endmodule
module tb_RCA32;
  wire [31:0] sum;
  wire cout;
  reg [31:0] a, b;
  reg cin;
  
  RCA32 rca32(sum[31:0], cout, a[31:0], b[31:0]);
  
  initial
  begin
    $display("a|b||cout|sum");
  end
  
  initial
  begin
    $monitor("%b|%b||%b|%b", a[31:0], b[31:0], cout, sum[31:0]);
  end
  
  initial
  begin
    a='b10100000101000001111111111111111; b='b10100000101111111111111111100000;
    #10 a='b01011000111111111111111111110100; b='b11110100111101001111111111111111;
    #10 a='b11111111111111110000111100111101; b='b00001111000011111111111111111111;
    #10 a='b11011111111111111110100011001010; b='b11001111111111111111100011001010;

  end
endmodule
module tb_RCA64;
  wire [63:0] sum;
  wire cout;
  reg [63:0] a, b;
  reg cin;
  
  RCA64 rca64(sum[63:0], cout, a[63:0], b[63:0]);
  
  initial
  begin
    $display("a|b||cout|sum");
  end
  
  initial
  begin
    $monitor("%d|%d||%d|%d", a[63:0], b[63:0], cout, sum[63:0]);
  end
  
  initial
  begin
    a=64'd998; b=64'd128;
    #10 a=64'd9998; b=64'd9028;
    #10 a=64'd09989998; b=64'd769028;

  end
endmodule
module FA(output sum, cout, input a, b, cin);
  wire w0, w1, w2;
  
  xor  (w0, a, b);
  xor  (sum, w0, cin);
  
  and  (w1, w0, cin);
  and  (w2, a, b);
  or  (cout, w1, w2);
endmodule
module RCA8(output [7:0] sum, output cout, input [7:0] a, b);
  
  wire [7:1] c;
  
  FA fa0(sum[0], c[1], a[0], b[0], 0);
  FA fa[6:1](sum[6:1], c[7:2], a[6:1], b[6:1], c[6:1]);
  FA fa31(sum[7], cout, a[7], b[7], c[7]);
  
endmodule
module RCA16(output [15:0] sum, output cout, input [15:0] a, b);
  
  wire [15:1] c;
  
  FA fa0(sum[0], c[1], a[0], b[0], 0);
  FA fa[14:1](sum[14:1], c[15:2], a[14:1], b[14:1], c[14:1]);
  FA fa31(sum[15], cout, a[15], b[15], c[15]);

endmodule
module RCA32(output [31:0] sum, output cout, input [31:0] a, b);

  wire [31:1] c;
  
  FA fa0(sum[0], c[1], a[0], b[0], 0);
  FA fa[30:1](sum[30:1], c[31:2], a[30:1], b[30:1], c[30:1]);
  FA fa31(sum[31], cout, a[31], b[31], c[31]);
    
endmodule
module RCA64(output [63:0] sum, output cout, input [63:0] a, b);

  wire [63:1] c;
  
  FA fa0(sum[0], c[1], a[0], b[0], 0);
  FA fa[62:1](sum[62:1], c[63:2], a[62:1], b[62:1], c[62:1]);
  FA fa31(sum[63], cout, a[63], b[63], c[63]);

endmodule
module tb_CLA8;
  wire [7:0] sum;
  wire cout;
  reg [7:0] a, b;
  reg cin;
  
  CLA8 cla8(sum[7:0], cout, a[7:0], b[7:0]);
  
  initial
  begin
    $display("a|b||cout|sum");
  end
  
  initial
  begin
    $monitor("%b|%b||%b|%b", a[7:0], b[7:0], cout, sum[7:0]);
  end
  
  initial
  begin
    a=8'b11111010; b=8'b11110000;
    #10    a=8'b11111010; b=8'b11110001;
    #10    a=8'b00111000; b=8'b10010000;
    #10    a=8'b11000010; b=8'b10110000;

  end

endmodule
module tb_CLA16;
  wire [15:0] sum;
  wire cout;
  reg [15:0] a, b;
  reg cin;
  
  CLA16 cla16(sum[15:0], cout, a[15:0], b[15:0]);
  
  initial
  begin
    $display("a               |b               ||cout|sum             ");
  end
  
  initial
  begin
    $monitor("%b|%b||%b   |%b", a[15:0], b[15:0], cout, sum[15:0]);
  end
  
  initial
  begin
    a=16'b1010000010100000; b=16'b1010000010100000;
    #10 a=16'b0101100011110100; b=16'b1111010011110100;
    #10 a=16'b0000111100111101; b=16'b0000111100001111;
    #10 a=16'b1100100011001010; b=16'b1100100011001010;

  end
endmodule
module tb_CLA32;
  wire [31:0] sum;
  wire cout;
  reg [31:0] a, b;
  reg cin;
  
  CLA32 cla32(sum[31:0], cout, a[31:0], b[31:0]);
  
  initial
  begin
    $display("a|b||cout|sum");
  end
  
  initial
  begin
    $monitor("%d|%d||%d|%d", a[31:0], b[31:0], cout, sum[31:0]);
  end
  
  initial
  begin
    a='d999; b='d98999;

  end
endmodule
module tb_CLA64;
  wire [63:0] sum;
  wire cout;
  reg [63:0] a, b;
  reg cin;
  
  CLA64 cla64(sum[63:0], cout, a[63:0], b[63:0]);
  
  initial
  begin
    $display("a|b||cout|sum");
  end
  
  initial
  begin
    $monitor("%d|%d||%d|%d", a[63:0], b[63:0], cout, sum[63:0]);
  end
  
  initial
  begin
    a=64'd9991; b=64'd8810;

  end
endmodule
module BigCircle(output G, P, input Gi, Pi, GiPrev, PiPrev);
  
  wire e;
  and #(1) (e, Pi, GiPrev);
  or #(1) (G, e, Gi);
  and #(1) (P, Pi, PiPrev);
  
endmodule
module SmallCircle(output Ci, input Gi);
  
  buf #(1) (Ci, Gi);
  
endmodule
module Square(output G, P, input Ai, Bi);
  
  and #(1) (G, Ai, Bi);
  xor #(2) (P, Ai, Bi);
  
endmodule
module Triangle(output Si, input Pi, CiPrev);
  
  xor #(2) (Si, Pi, CiPrev);
  
endmodule
module KSA8(output [7:0] sum, output cout, input [7:0] a, b);
  
  wire cin = 1'b0;
  wire [7:0] c;
  wire [7:0] g, p;
  Square sq[7:0](g, p, a, b);

  // first line of circles
  wire [7:1] g2, p2;
  SmallCircle sc0_0(c[0], g[0]);
  BigCircle bc0[7:1](g2[7:1], p2[7:1], g[7:1], p[7:1], g[6:0], p[6:0]);
  
  // second line of circle
  wire [7:3] g3, p3;
  SmallCircle sc1[2:1](c[2:1], g2[2:1]);
  BigCircle bc1[7:3](g3[7:3], p3[7:3], g2[7:3], p2[7:3], g2[5:1], p2[5:1]);
    
  // third line of circle
  wire [7:7] g4, p4;
  SmallCircle sc2[6:3](c[6:3], g3[6:3]);
  BigCircle bc2_7(g4[7], p4[7], g3[7], p3[7], g3[3], p3[3]);

  // fourth line of circle
  SmallCircle sc3_7(c[7], g4[7]);

  // last line - triangles
  Triangle tr0(sum[0], p[0], cin);
  Triangle tr[7:1](sum[7:1], p[7:1], c[6:0]);
  
  // generate cout
  buf #(1) (cout, c[7]);
  
endmodule
module KSA16(output [15:0] sum, output cout, input [15:0] a, b);
  
  wire cin = 1'b0;
  wire [15:0] c;
  wire [15:0] g, p;
  Square sq[15:0](g, p, a, b);

  // first line of circles
  wire [15:1] g2, p2;
  SmallCircle sc0_0(c[0], g[0]);
  BigCircle bc0[15:1](g2[15:1], p2[15:1], g[15:1], p[15:1], g[14:0], p[14:0]);
  
  // second line of circle
  wire [15:3] g3, p3;
  SmallCircle sc1[2:1](c[2:1], g2[2:1]);
  BigCircle bc1[15:3](g3[15:3], p3[15:3], g2[15:3], p2[15:3], g2[13:1], p2[13:1]);
  
  // third line of circle
  wire [15:7] g4, p4;
  SmallCircle sc2[6:3](c[6:3], g3[6:3]);
  BigCircle bc2[15:7](g4[15:7], p4[15:7], g3[15:7], p3[15:7], g3[11:3], p3[11:3]);

  // fourth line of circle
  wire [15:15] g5, p5;
  SmallCircle sc3[14:7](c[14:7], g4[14:7]);
  BigCircle bc3_15(g5[15], p5[15], g4[15], p4[15], g4[7], p4[7]);  
  
  // fifth line of circle
  SmallCircle sc4_15(c[15], g5[15]);
  
  // last line - triangles
  Triangle tr0(sum[0], p[0], cin);
  Triangle tr[15:1](sum[15:1], p[15:1], c[14:0]);

  // generate cout
  buf #(1) (cout, c[15]);

endmodule
module KSA32(output [31:0] sum, output cout, input [31:0] a, b);
  
  wire cin = 1'b0;
  wire [31:0] c;
  wire [31:0] g, p;
  Square sq[31:0](g, p, a, b);

  // first line of circles
  wire [31:1] g2, p2;
  SmallCircle sc0_0(c[0], g[0]);
  BigCircle bc0[31:1](g2[31:1], p2[31:1], g[31:1], p[31:1], g[30:0], p[30:0]);

  // second line of circles
  wire [31:3] g3, p3;
  SmallCircle sc1[2:1](c[2:1], g2[2:1]);
  BigCircle bc1[31:3](g3[31:3], p3[31:3], g2[31:3], p2[31:3], g2[29:1], p2[29:1]);

  // third line of circles
  wire [31:7] g4, p4;
  SmallCircle sc2[6:3](c[6:3], g3[6:3]);
  BigCircle bc2[31:7](g4[31:7], p4[31:7], g3[31:7], p3[31:7], g3[27:3], p3[27:3]);

  // fourth line of circles
  wire [31:15] g5, p5;
  SmallCircle sc3[14:7](c[14:7], g4[14:7]);
  BigCircle bc3[31:15](g5[31:15], p5[31:15], g4[31:15], p4[31:15], g4[23:7], p4[23:7]);
        
  // fifth line of circles
  wire [31:31] g6, p6;
  SmallCircle sc4[30:15](c[30:15], g5[30:15]);
  BigCircle bc4_31(g6[31], p6[31], g5[31], p5[31], g5[15], p5[15]);
  
  // sixth line of circles
  SmallCircle sc5_31(c[31], g6[31]);
  
  // last line - triangless
  Triangle tr0(sum[0], p[0], cin);
  Triangle tr[31:1](sum[31:1], p[31:1], c[30:0]);

  // generate cout
  buf #(1) (cout, c[31]);

endmodule
module KSA64(output [63:0] sum, output cout, input [63:0] a, b);
  
  wire cin = 1'b0;
  wire [63:0] c;
  wire [63:0] g, p;
  Square sq[63:0](g, p, a, b);

  // first line of circles
  wire [63:1] g2, p2;
  SmallCircle sc0_0(c[0], g[0]);
  BigCircle bc0[63:1](g2[63:1], p2[63:1], g[63:1], p[63:1], g[62:0], p[62:0]);

  // second line of circles
  wire [63:3] g3, p3;
  SmallCircle sc1[2:1](c[2:1], g2[2:1]);
  BigCircle bc1[63:3](g3[63:3], p3[63:3], g2[63:3], p2[63:3], g2[61:1], p2[61:1]);
    
  // third line of circles
  wire [63:7] g4, p4;
  SmallCircle sc2[6:3](c[6:3], g3[6:3]);
  BigCircle bc2[63:7](g4[63:7], p4[63:7], g3[63:7], p3[63:7], g3[59:3], p3[59:3]);
  
  // fourth line of circles
  wire [63:15] g5, p5;
  SmallCircle sc3[14:7](c[14:7], g4[14:7]);
  BigCircle bc3[63:15](g5[63:15], p5[63:15], g4[63:15], p4[63:15], g4[55:7], p4[55:7]);
        
  // fifth line of circles
  wire [63:31] g6, p6;
  SmallCircle sc4[30:15](c[30:15], g5[30:15]);
  BigCircle bc4[63:31](g6[63:31], p6[63:31], g5[63:31], p5[63:31], g5[47:15], p5[47:15]);
  
  // sixth line of circles
  wire [63:63] g7, p7;
  SmallCircle sc5[62:31](c[62:31], g6[62:31]);  
  BigCircle bc4_63(g7[63], p7[63], g6[63], p6[63], g6[31], p6[31]);

  // seventh line of circles
  SmallCircle sc6(c[63], g7[63]);  

  // last line - triangles
  Triangle tr0(sum[0], p[0], cin);
  Triangle tr[63:1](sum[63:1], p[63:1], c[62:0]);

  // generate cout
  buf #(1) (cout, c[63]);

endmodule
module tb_KSA8;
  wire [7:0] sum;
  wire cout;
  reg [7:0] a, b;
  reg cin;
  
  KSA8 ksa8(sum[7:0], cout, a[7:0], b[7:0]);
  
  initial
  begin
    $display("a       |b       ||cout|sum     ");
  end
  
  initial
  begin
    $monitor("%b|%b||%b   |%b", a[7:0], b[7:0], cout, sum[7:0]);
  end
  
  initial
  begin
    a=8'b10100000; b=8'b10100000;
    #10 a=8'b01011000; b=8'b11110100;
    #10 a=8'b00111101; b=8'b00001111;
    #10 a=8'b11001010; b=8'b11001000;
    #10 a=8'b10100110; b=8'b11110100;
    #10 a=8'b11110011; b=8'b11001100;
    #10 a=8'b11110011; b=8'b01010111;

  end
endmodule
module tb_KSA16;
  wire [15:0] sum;
  wire cout;
  reg [15:0] a, b;
  reg cin;
  
  KSA16 ksa16(sum[15:0], cout, a[15:0], b[15:0]);
  
  initial
  begin
    $display("a               |b               ||cout|sum             ");
  end
  
  initial
  begin
    $monitor("%b|%b||%b   |%b", a[15:0], b[15:0], cout, sum[15:0]);
  end
  
  initial
  begin
    a=16'b1010000010100000; b=16'b1010000010100000;
    #10 a=16'b0101100011110100; b=16'b1111010011110100;
    #10 a=16'b0000111100111101; b=16'b0000111100001111;
    #10 a=16'b1100100011001010; b=16'b1100100011001010;

  end
endmodule
module tb_KSA32;
  wire [31:0] sum;
  wire cout;
  reg [31:0] a, b;
  reg cin;
  
  KSA32 ksa32(sum[31:0], cout, a[31:0], b[31:0]);
  
  initial
  begin
    $display("a|b||cout|sum");
  end
  
  initial
  begin
    $monitor("%b|%b||%b|%b", a[31:0], b[31:0], cout, sum[31:0]);
  end
  
  initial
  begin
    a='b10100000101000001111111111111111; b='b10100000101111111111111111100000;
    #10 a='b01011000111111111111111111110100; b='b11110100111101001111111111111111;
    #10 a='b11111111111111110000111100111101; b='b00001111000011111111111111111111;
    #10 a='b11011111111111111110100011001010; b='b11001111111111111111100011001010;

  end
endmodule
module tb_KSA64;
  wire [63:0] sum;
  wire cout;
  reg [63:0] a, b;
  reg cin;
  
  KSA64 ksa64(sum[63:0], cout, a[63:0], b[63:0]);
  
  initial
  begin
    $display("a|b||cout|sum");
  end
  
  initial
  begin
    $monitor("%d|%d||%d|%h", a[63:0], b[63:0], cout, sum[63:0]);
  end
  
  initial
  begin
    a=64'd998; b=64'd128;
    #10 a=64'd9998; b=64'd9028;
    #10 a=64'hfaaaaaaafaaaaaaa; b=64'hfaaaaaaadbbbbbbb;

  end
endmodule
module mm21_SPIMaster(
  input       clock,
  input       reset,
  
  output      tx_ready,
  input       tx_valid,
  input [7:0] tx_byte,

  // whether or not to reset CS after sending data
  input       tx_clear_cs,

  output      sclk,
  output      mosi,
  output      n_cs
);

  localparam STATE_IDLE = 2'd0,
    STATE_CS_ASSERT = 2'd1,
    STATE_TX = 2'd2,
    STATE_CS_DEASSERT = 2'd3;

  localparam TX_COUNTER_MAX = 3'h7;

  // number of cycles-1 to wait after asserting / before deasserting CS 
  localparam CS_COUNTER_MAX = 4'd10;

  reg [1:0] state;
  reg [7:0] tx_byte_reg;
  reg sclk_mask;
  reg mosi_mask;
  reg tx_ready_reg;
  reg [2:0] tx_counter_reg;
  reg n_cs_reg;
  reg tx_clear_cs_reg;
  reg [3:0] cs_delay_counter;

  assign tx_ready = tx_ready_reg;
  assign sclk = ~clock & sclk_mask;
  assign mosi = tx_byte_reg[7] & mosi_mask;
  assign n_cs = n_cs_reg;

  always @(posedge clock) begin
    if (reset) begin

      state <= STATE_IDLE;
      tx_byte_reg <= 8'h0;
      sclk_mask <= 1'b0;
      mosi_mask <= 1'b0;
      tx_ready_reg <= 1'b0;
      tx_counter_reg <= 3'd0;
      n_cs_reg <= 1'b1;
      tx_clear_cs_reg <= 1'b1;
      cs_delay_counter <= 4'd0;

    end else begin

      if (state == STATE_IDLE) begin

        tx_ready_reg <= 1'b1;

        if (tx_valid == 1'b1) begin
          tx_byte_reg <= tx_byte;
          tx_clear_cs_reg <= tx_clear_cs;
          tx_ready_reg <= 1'b0;
          n_cs_reg <= 1'b0;

          if (n_cs_reg == 1'b1) begin
            // CS is not asserted: assert it first
            state <= STATE_CS_ASSERT;
          end else begin
            // CS is already asserted: transition to TX
            state <= STATE_TX;
            sclk_mask <= 1'b1;
            mosi_mask <= 1'b1;
          end
        end

      end else if (state == STATE_CS_ASSERT) begin

        // assert CS before transitioning to TX
        if (cs_delay_counter == CS_COUNTER_MAX) begin

          cs_delay_counter <= 4'd0;
          state <= STATE_TX;
          sclk_mask <= 1'b1;
          mosi_mask <= 1'b1;

        end else begin
          cs_delay_counter <= cs_delay_counter + 4'd1;
        end

      end else if (state == STATE_TX) begin

        tx_byte_reg <= {tx_byte_reg[6:0], 1'b0};

        if (tx_counter_reg == TX_COUNTER_MAX) begin
          tx_counter_reg <= 3'd0;
          sclk_mask <= 1'b0;
          mosi_mask <= 1'b0;

          // check if CS needs to be reset
          if (tx_clear_cs_reg == 1'b1) begin
            state <= STATE_CS_DEASSERT;
          end else begin
            state <= STATE_IDLE;
          end
        end else begin
          tx_counter_reg <= tx_counter_reg + 3'd1;
        end

      end else if (state == STATE_CS_DEASSERT) begin

        // wait before deasserting CS and transitioning to idle

        if (cs_delay_counter == CS_COUNTER_MAX) begin

          if (n_cs_reg == 1'b0) begin

            cs_delay_counter <= 4'd0;
            n_cs_reg <= 1'b1;

          end else begin

            cs_delay_counter <= 4'd0;
            state <= STATE_IDLE;

          end

        end else begin
          cs_delay_counter <= cs_delay_counter + 4'd1;
        end

      end
    end
  end

endmodule
module mm21_LEDColor(
  input [2:0]   row_idx,
  input [2:0]   col_idx,
  input [5:0]   pixel_offset,

  output [7:0]  pixel
);

  wire [2:0] red;
  wire [2:0] green;
  wire [1:0] blue;
  wire is_diagonal;

  wire [5:0] green_sum;
  wire [5:0] blue_sum;

  assign green_sum = {3'd0, col_idx} + pixel_offset;
  assign blue_sum = {3'd0, row_idx} + pixel_offset;

  // generate moving diagonal
  assign is_diagonal = ((row_idx + col_idx) == pixel_offset[2:0]) ? 1'b1 : 1'b0;

  // generate white when on diagonal, otherwise moving blend of green/blue
  assign red = (is_diagonal == 1'b1) ? 3'd7 : 3'd0;
  assign green = (is_diagonal == 1'b1) ? 3'd7 : green_sum[2:0];
  assign blue = (is_diagonal == 1'b1) ? 2'd3 : blue_sum[1:0];

  assign pixel = {red, 5'd0} | {3'd0, green, 2'd0} | {6'd0, blue};

endmodule
module mm21_LEDMatrixDriver(
  input         clock,
  input         reset,
  
  output        sclk,
  output        mosi,
  output        n_cs
);

  localparam STATE_RESET_FRAME_INDEX = 1'd0,
    STATE_SEND_PIXELS = 1'd1;

  // command to reset frame index
  localparam CMD_RESET_FRAME_INDEX = 8'h26;

  localparam PIXEL_MAX = 6'h3f;

  reg [0:0] state;
  reg [1:0] state_rfi;
  reg [1:0] state_sp;

  reg [5:0] pixel_counter;

  reg [5:0] pixel_offset;

  reg tx_valid;
  reg tx_clear_cs;

  wire tx_ready;
  wire [7:0] tx_byte;

  wire [2:0] row_idx;
  wire [2:0] col_idx;
  wire [7:0] pixel;

  assign tx_byte = (state == STATE_RESET_FRAME_INDEX) ? CMD_RESET_FRAME_INDEX : pixel;

  assign row_idx = pixel_counter[5:3];
  assign col_idx = pixel_counter[2:0];

  mm21_SPIMaster spi_master_inst(
    .clock(clock),
    .reset(reset),

    .tx_ready(tx_ready),
    .tx_valid(tx_valid),
    .tx_byte(tx_byte),
    .tx_clear_cs(tx_clear_cs),

    .sclk(sclk),
    .mosi(mosi),
    .n_cs(n_cs)
  );

  mm21_LEDColor led_color_inst(
    .row_idx(row_idx),
    .col_idx(col_idx),
    .pixel_offset(pixel_offset),

    .pixel(pixel)
  );

  always @(posedge clock) begin
    if (reset) begin
      state <= STATE_RESET_FRAME_INDEX;

      pixel_counter <= 6'h0;
      pixel_offset <= 6'h0;

      tx_valid <= 1'b0;
      tx_clear_cs <= 1'b0;
    end else begin

      if (state == STATE_RESET_FRAME_INDEX) begin

        if (tx_ready == 1'b1) begin

          // send command to reset frame index

          tx_valid <= 1'b1;
          tx_clear_cs <= 1'b1;
        end else if (tx_valid == 1'b1) begin
          
          // TX accepted, transition to next state

          state <= STATE_SEND_PIXELS;
          tx_valid <= 1'b0;
        end

      end else if (state == STATE_SEND_PIXELS) begin

        if (tx_ready == 1'b1) begin

          // send pixel data

          tx_valid <= 1'b1;

          if (pixel_counter == PIXEL_MAX) begin
            // sending last pixel, so clear CS after
            tx_clear_cs <= 1'b1;
          end else begin
            tx_clear_cs <= 1'b0;
          end

        end else if (tx_valid == 1'b1) begin

          // TX accepted, transition to next state

          tx_valid <= 1'b0;

          if (pixel_counter == PIXEL_MAX) begin
            // sending last pixel
            state <= STATE_RESET_FRAME_INDEX;
            pixel_counter <= 6'h0;
            pixel_offset <= pixel_offset + 6'h1;
          end else begin
            pixel_counter <= pixel_counter + 6'h1;
          end

        end
      end
    end
  end

endmodule
module mm21_SevenSeg(
  input         clock,
  input         reset,

  output        up,
  output        right,
  output        down,
  output        left
);

  localparam COUNTER_MAX = 8'hff;

  // counter to increment upon every clock
  reg [7:0] counter;

  // state to increment upon every counter wrap
  reg [1:0] state;

  // set outputs using combinational logic based on state
  assign up = (state == 2'd0) ? 1'b1 : 1'b0;
  assign right = (state == 2'd1) ? 1'b1 : 1'b0;
  assign down = (state == 2'd2) ? 1'b1 : 1'b0;
  assign left = (state == 2'd3) ? 1'b1 : 1'b0;

  always @(posedge clock) begin
    if (reset) begin

      counter <= 8'h0;
      state <= 2'h0;
      
    end else begin

      // increment counter upon clock cycle
      counter <= counter + 8'd1;

      // increment state upon counter wrap
      if (counter == COUNTER_MAX) begin
        state <= state + 2'd1;
      end

    end
  end

endmodule
module mm21_AsyncReset(
  input   clock,
  input   reset_async,

  output  reset_sync
);

  reg [2:0] reset_fifo;

  assign reset_sync = reset_fifo[0];

  always @(posedge clock or posedge reset_async) begin
    if (reset_async == 1'b1) begin
      reset_fifo <= 3'h7;
    end else begin
      reset_fifo <= {1'b0, reset_fifo[2:1]};
    end
  end

endmodule
module mm21_LEDMatrixTop(
  input [7:0] io_in,
  output [7:0] io_out
);

  wire clock;
  wire reset_async;
  wire reset_sync;

  // LED matrix wires
  wire sclk;
  wire mosi;
  wire n_cs;

  // 7-seg wires
  wire up;
  wire right;
  wire down;
  wire left;

  assign clock = io_in[0];
  assign reset_async = io_in[1];

  // drive LED matrix
  assign io_out[0] = sclk;
  assign io_out[1] = mosi;
  assign io_out[5] = n_cs;

  // use lower 7-seg LEDs for animation
  assign io_out[6] = up;
  assign io_out[2] = right;
  assign io_out[3] = down;
  assign io_out[4] = left;

  assign io_out[7] = 1'b1;

  mm21_AsyncReset async_reset_inst(
    .clock(clock),
    .reset_async(reset_async),
    .reset_sync(reset_sync)
  );

  mm21_LEDMatrixDriver ledmatrix_driver_inst(
    .clock(clock),
    .reset(reset_sync),

    .sclk(sclk),
    .mosi(mosi),
    .n_cs(n_cs)
  );

  mm21_SevenSeg sevenseg_inst(
    .clock(clock),
    .reset(reset_sync),

    .up(up),
    .right(right),
    .down(down),
    .left(left)
  );

endmodule
module Asma_Mohsin_conv_enc_core(// Inputs
 input [7:0]io_in,
// Output
 output [7:0]io_out
);
parameter [4:0] POLY_1 = 5'b10111 ;
parameter [4:0] POLY_2 = 5'b11001 ;
// Inputs
wire clk ;
wire rst_n ;
wire data_valid ;
wire d_in ;

assign clk = io_in[0];
assign rst_n=io_in[1];
assign data_valid=io_in[2];
assign d_in=io_in[3];

// Output

//output [1:0] enc_dout ;
reg [4:0] shift_reg ;
reg [1:0] codeword ;
wire [1:0] enc_dout ;
// Shift Input Data in 5 bits lenght register
always @(posedge clk or negedge rst_n)
begin
if(~rst_n)
shift_reg <= 5'd0 ;
else if(data_valid)
shift_reg <= {d_in, shift_reg[4:1]} ;
else
shift_reg <= 5'd0 ;
end
always @(shift_reg)
begin
codeword[0] = ^(POLY_2 & shift_reg) ;
codeword[1] = ^(POLY_1 & shift_reg) ;
end
assign io_out = codeword ;
endmodule
module sky130_fd_sc_hd__dlrtp_1(input GATE, RESET_B, D, output reg Q);
    always @*
        if (~RESET_B)
            Q <= 0;
        else if (GATE)
            Q <= D;
endmodule
module sky130_fd_sc_hd__dlxtp_1(input GATE, D, output reg Q);
    always @*
        if (GATE)
            Q <= D;
endmodule
module sky130_fd_sc_hd__and3_1(input A, B, C, output X);
    assign X = A & B & C;
endmodule
module pic_progmem(input clock, write_data, write_strobe, input [3:0] adr, output [11:0] rdata);
    localparam K = 16;

    // the program logic
    reg [27:0] write_sr;
    always @(posedge clock)
        write_sr <= {write_data, write_sr[27:1]};

    wire [11:0] data[0:K-1];
    generate
        genvar ii, jj;
        for (ii = 0; ii < K; ii = ii + 1'b1) begin:word
            for (jj = 0; jj < 12; jj = jj + 1'b1) begin:bits
                sky130_fd_sc_hd__dlxtp_1 rfbit_i (
                    .GATE(write_sr[ii + 12] && write_strobe),
                    .D(write_sr[jj]),
                    .Q(data[ii][jj])
                );
            end
        end
    endgenerate
    assign rdata = data[adr];
endmodule
module tiny_kinda_pic(input [7:0] io_in, output [7:0] io_out);
    wire clk = io_in[0];
    wire reset = io_in[1];

    wire [3:0] prog_adr;
    wire [11:0] prog_data;
    pic10_core pic_i (
        .clock(clk),
        .reset(reset),
        .prog_adr(prog_adr),
        .prog_data(prog_data),
        .gpi(io_in[7:4]),
        .gpo(io_out)
    );

    pic_progmem progmem_i (
        .clock(clk),
        .write_strobe(io_in[2]),
        .write_data(io_in[3]),
        .adr(prog_adr),
        .rdata(prog_data)
    );

endmodule
module github_com_proppy_tt02_xls_popcount(
  input wire [7:0] io_in,
  output wire [7:0] io_out
);
  user_module user_module0(io_in, io_out);
endmodule