dakies/OSS_Verilog huggingface dataset:
module fm_3d_frcp (
  clk_core,
  i_en,
  i_a,
  o_c
);

////////////////////////////
// I/O definition
////////////////////////////
    input         clk_core;
    input         i_en;
    input  [21:0] i_a;          // input A
    output [21:0] o_c;          // result


///////////////////////////////////////////
//  register definition
///////////////////////////////////////////
    reg    [21:0] r_c;           // result

    reg           r_a_sign;
    reg    [4:0]  r_ce_tmp;
    reg    [7:0]  r_a_frac_l;

///////////////////////////////////////////
//  wire 
///////////////////////////////////////////
    wire          w_a_sign;
    wire   [4:0]  w_a_exp;
    wire   [15:0] w_a_fraction;
    wire   [4:0]  w_2bias;
    wire   [4:0]  w_ce_tmp;
    wire   [15:0] w_cf_tmp;
    wire   [31:0] w_rom_out;
    wire   [15:0] w_rom_base;
    wire   [15:0] w_rom_diff;
    wire   [6:0]  w_rom_address;
    wire   [7:0]  w_a_frac_l;
    //wire   [31:0] w_rom_correct;
    wire   [23:0] w_rom_correct;
    wire   [21:0] w_c;
    wire          w_zero_flag;
///////////////////////////////////////////
//  assign
///////////////////////////////////////////
    assign w_a_sign = i_a[21];
    assign w_a_exp = i_a[20:16];
    assign w_a_fraction = i_a[15:0];
    assign w_2bias = 5'h1e;  // x2
    assign w_ce_tmp = w_2bias - w_a_exp;

    assign w_rom_address = w_a_fraction[14:8];
    assign w_a_frac_l = w_a_fraction[7:0];
/* // original implementation 
    assign w_rom_base = w_rom_out[31:16];   // 1.15
    assign w_rom_diff = w_rom_out[15:0];    // 0.16
    assign w_rom_correct = w_rom_diff * {r_a_frac_l,8'b0};
    assign w_cf_tmp = w_rom_base - {1'b0,w_rom_correct[31:17]};
*/
    // timing improvement
    assign w_rom_base = w_rom_out[31:16];   // 1.15
    assign w_rom_diff = w_rom_out[15:0];    // 0.16
    assign w_rom_correct = w_rom_diff * r_a_frac_l;
    assign w_cf_tmp = w_rom_base - {1'b0,w_rom_correct[23:9]};

    assign w_zero_flag = (w_a_exp == 5'h0);

    // output port
    assign o_c = r_c;

///////////////////////////////////////////
//  always statement
///////////////////////////////////////////

    always @(posedge clk_core) begin
        if (i_en) begin
            r_a_sign <= w_a_sign;
            r_ce_tmp <= w_ce_tmp;
            r_a_frac_l <= w_a_frac_l;
        end
    end
 
    always @(posedge clk_core) begin
        if (i_en) begin
            r_c <= (w_zero_flag) ? 16'h0 : w_c;
        end
    end


///////////////////////////////////////////
//  module instance
///////////////////////////////////////////
// table rom
    fm_3d_frcp_rom frcp_rom (
        .clk_core(clk_core),
        .i_a(w_rom_address),
        .o_c(w_rom_out)
    );
// normalize
    fm_3d_norm norm (
        .i_s(r_a_sign),
        .i_e(r_ce_tmp),
        .i_f({1'b0,w_cf_tmp[15:0]}),
        .o_b(w_c)
    );

endmodule
module fm_line_mem (
  clk_vi,
  rst_x,
  i_clear,
  i_dt,
  i_renable,
  o_dt
);

// set default parameters
parameter P_WIDTH = 16;
parameter P_RANGE = 10;
parameter P_DEPTH = 640;
////////////////////////////
// I/O definition
////////////////////////////
input         clk_vi;       // system clock
input         rst_x;        // system reset
input         i_clear;      // write strobe
input  [P_WIDTH-1:0] i_dt;  // write data
input         i_renable;    // read enable
output [P_WIDTH-1:0] o_dt;  // read data

/////////////////////////
//  Register definition
/////////////////////////
reg [P_RANGE-1:0] r_write_counter;
reg [P_RANGE-1:0] r_read_counter;
/////////////////////////
//  wire definition
/////////////////////////
wire             w_we;
wire             w_re;
wire [P_RANGE-1:0] w_read_counter_inc;
wire [P_RANGE-1:0] w_read_counter;
/////////////////////////
//  assign statement
/////////////////////////

assign w_read_counter_inc = r_read_counter + 1'b1;
assign w_read_counter = (w_re) ? w_read_counter_inc : r_read_counter;
assign w_we = i_renable;
assign w_re = i_renable;
////////////////////////
// always statement
///////////////////////
  // write side
  always @(posedge clk_vi or negedge rst_x) begin
    if (~rst_x) begin
      r_write_counter <= 'd0;
    end else begin
      if (i_clear)  r_write_counter <= 'd0;
      else if (w_we) r_write_counter <= r_write_counter + 1'b1;
    end
  end

  // read side
  always @(posedge clk_vi or negedge rst_x) begin
    if (~rst_x) begin
      r_read_counter <= 'd0;
    end else begin
      if (i_clear)   r_read_counter <= 'd0;
      else if (w_re) r_read_counter <= w_read_counter_inc;
    end
  end

///////////////////
// module instance
///////////////////
    fm_cmn_bram_01 #(P_WIDTH, P_RANGE) bram_00 (
        .clk(clk_vi),
        .we(w_we),
        .a(r_write_counter),
        .dpra(w_read_counter),
        .di(i_dt),
        .spo(),
        .dpo(o_dt)
    );
endmodule
module fm_afifo (
  clk_core,
  clk_vi,
  rst_x,
  i_wstrobe,
  i_dt,
  o_full,
  i_renable,
  o_dt,
  o_empty,
  o_dnum
);

// set default parameters
parameter P_RANGE = 7;
parameter P_DEPTH = 1 << P_RANGE;  // 128
`include "polyphony_params.v"
////////////////////////////
// I/O definition
////////////////////////////
input         clk_core;       // system clock
input         clk_vi;
input         rst_x;          // system reset
input         i_wstrobe;      // write strobe
input  [P_IB_DATA_WIDTH-1:0]
              i_dt;           // write data
output        o_full;         // write data full
input         i_renable;      // read enable
output [15:0] o_dt;           // read data
output        o_empty;        // read data empty
output [P_RANGE:0] o_dnum;     // written data number

/////////////////////////
//  Register definition
/////////////////////////
reg [P_RANGE-1:0] r_write_counter;
reg [P_RANGE-1:0] r_read_counter;
// data registers
`ifdef PP_BUSWIDTH_64
reg [1:0]        r_select_hw;
`else
reg              r_select_hw;
`endif
/////////////////////////
//  wire definition
/////////////////////////
wire             o_full;
wire             o_empty;
wire [15:0]      o_dt;
wire             w_we;
wire             w_re;
wire [P_IB_DATA_WIDTH-1:0]
                 w_dt;
wire [P_RANGE-1:0] w_read_counter_inc;
wire [P_RANGE-1:0] w_read_counter;
/////////////////////////
//  assign statement
/////////////////////////
`ifdef PP_BUSWIDTH_64
assign o_dt = (r_select_hw == 'd1) ? w_dt[31:16] :
              (r_select_hw == 'd2) ? w_dt[47:32] :
              (r_select_hw == 'd3) ? w_dt[63:48] :
               w_dt[15:0];
`else
assign o_dt = (r_select_hw) ? w_dt[31:16] : w_dt[15:0];
`endif
assign o_dnum = 0;
assign o_full = 1'b0;
assign o_empty = 1'b0;
assign w_we = i_wstrobe;
`ifdef PP_BUSWIDTH_64
assign w_re = i_renable & (r_select_hw == 'd3);
`else
assign w_re = i_renable & r_select_hw;
`endif

assign w_read_counter_inc = r_read_counter + 1'b1;
assign w_read_counter = (w_re) ? w_read_counter_inc : r_read_counter;

////////////////////////
// always 
///////////////////////
  // write side (clk_core)
  always @(posedge clk_core or negedge rst_x) begin
    if (~rst_x) begin
      r_write_counter <= 'd0;
    end else begin
      if (w_we) begin
        r_write_counter <= r_write_counter + 1'b1;
      end
    end
  end

  // read side (clk_vi)
  always @(posedge clk_vi or negedge rst_x) begin
    if (~rst_x) begin
      r_read_counter <= 'd0;
    end else begin
      if (w_re) begin
        r_read_counter <= w_read_counter_inc;
      end
    end
  end

  // select half word
  always @(posedge clk_vi or negedge rst_x) begin
    if (~rst_x) begin
      r_select_hw <= 'd0;
    end else begin
        if (i_renable) r_select_hw <= r_select_hw + 1'b1;
    end
  end

///////////////////
// module instance
///////////////////
    fm_cmn_bram_02 #(P_IB_DATA_WIDTH, P_RANGE) bram_00 (
        .clka(clk_core),
        .clkb(clk_vi),
        .wea(w_we),
        .addra(r_write_counter),
        .addrb(w_read_counter),
        .dia(i_dt),
        .doa(),
        .dob(w_dt)
    );

endmodule
module fm_hvc_aa_filter_core (
    clk_vi,
    // configuration
    i_fb_blend_en,
    // incoming color
    i_base,
    i_br,
    i_bl,
    i_tr,
    i_tl,
    // outgoing color
    o_c
);

//////////////////////////////////
// I/O port definition
//////////////////////////////////
    input          clk_vi;     // 25MHz
    // configuration
    input          i_fb_blend_en;
    // incoming color
    input  [7:0]   i_base; // 7.1 or 8.0
    input  [7:0]   i_br;   // 5.3
    input  [7:0]   i_bl;   // 5.3
    input  [7:0]   i_tr;   // 5.3 or 8.0
    input  [7:0]   i_tl;   // 5.3

    // outgoing color
    output [7:0]   o_c;
//////////////////////////////////
// reg
//////////////////////////////////
    //reg    [7:0]   r_c;
//////////////////////////////////
// wire
//////////////////////////////////
    wire   [8:0]   w_b;  // intermediate 6.3
    wire   [8:0]   w_t;  // intermediate 6.3
    wire   [9:0]   w_m;  // intermediate 7.3
    wire   [10:0]  w_f;  // intermediate 8.3
    wire   [8:0]   w_ff; // intermediate 9.0
    wire   [7:0]   w_r;  // rounded final color

    // for buffer blend function
    wire   [8:0]   w_ff_a; // intermediate 9.0
    wire   [8:0]   w_ff_b; // intermediate 9.0
//////////////////////////////////
// assign
//////////////////////////////////
    assign w_b = i_br + i_bl;  // 6.3
    assign w_t = i_tr + i_tl;  // 6.3
    assign w_m = w_b + w_t;    // 7.3
    assign w_f = w_m + {i_base,2'b00}; // 8.3
    assign w_ff_a = (w_f[2]) ? w_f[10:3] : w_f[10:3] + 1'b1;  // 9.0 for aa
    assign w_ff_b = i_base + i_tr;  // 9.0 for blend
    assign w_ff = (!i_fb_blend_en) ? w_ff_a : w_ff_b;
    assign w_r = (w_ff[8]) ? 8'hff : w_ff[7:0];

//    assign o_c = r_c;
    assign o_c = w_r;
//////////////////////////////////
// always
//////////////////////////////////
/*
    always @(posedge clk_vi) begin
        r_c = w_r;
    end
*/

endmodule
module const_mult 
(
  Clock,
  ClockEnable,
  Reset,
  Color,
  Color_Out
);

  parameter IN_SIZE   =  8;
  parameter OUT_SIZE  = 16;  // output size width (integer)
  parameter CST_MULT  = 66;  // constant multiplicand (integer)

  input Clock; 
  input ClockEnable; 
  input Reset; 
  input [ (IN_SIZE - 1):0] Color; 
  output[(OUT_SIZE - 1):0] Color_Out; 

  reg   [(OUT_SIZE - 1):0] Color_Out;

// ------------------------------
// RTL code for COLOR_KCM process
// ------------------------------
  always @(posedge Clock or posedge Reset)
  begin : COLOR_KCM
    if (Reset)
      Color_Out <= 0; 
    else if (ClockEnable)
      Color_Out <= CST_MULT * Color; 
   end 


endmodule
module fm_ycbcr(
    clk_v,
    rst_x,
    i_r,
    i_g,
    i_b,
    o_y,
    o_cb,
    o_cr
);

//////////////////////////////////
// I/O port definition
//////////////////////////////////
    input          clk_v;     // 27MHz
    input          rst_x;
    input  [7:0]   i_r;
    input  [7:0]   i_g;
    input  [7:0]   i_b;
    output [7:0]   o_y;
    output [7:0]   o_cb;
    output [7:0]   o_cr;


//////////////////////////////////
// module instantiation
//////////////////////////////////
 csc_top csc_top (
    .Clock(clk_v),
    .ClockEnable(1'b1),
    .Reset(~rst_x),
    .Red(i_r),
    .Green(i_g),
    .Blue(i_b),
    .Y(o_y),
    .Cb(o_cb),
    .Cr(o_cr)
);

endmodule
module fm_444_422 (
  clk_v,
  rst_x,
  // video in
  i_state,
  i_y,
  i_cr,
  i_cb,
  // video out
  o_y,
  o_cr,
  o_cb
);
  input  clk_v;
  input  rst_x;

  input i_state;
  // video in
  input [7:0] i_y;
  input [7:0] i_cr;
  input [7:0] i_cb;
  // video out
  output [7:0] o_y;
  output [7:0] o_cr;
  output [7:0] o_cb;

//////////////////////////////////
// wire
//////////////////////////////////
  wire [8:0]   w_cb;
  wire [8:0]   w_cr;
//////////////////////////////////
// reg
//////////////////////////////////
  reg [7:0]   r_y_1z;
  reg [7:0]   r_y_2z;
  reg [7:0]   r_cr_1z;
  reg [7:0]   r_cb_1z;
  reg [7:0]   r_cr;
  reg [7:0]   r_cb;
//////////////////////////////////
// assign
//////////////////////////////////
  assign w_cr = i_cr + r_cr_1z;
  assign w_cb = i_cb + r_cb_1z;

  assign o_y = r_y_2z;
  assign o_cr = r_cr;
  assign o_cb = r_cb;
//////////////////////////////////
// module instantiation
//////////////////////////////////

always @(posedge clk_v) begin
  r_y_1z <= i_y;
  r_y_2z <= r_y_1z;
  r_cr_1z <= i_cr;
  r_cb_1z <= i_cb;
  if (i_state)  begin
     r_cr <= w_cr[8:1];
     r_cb <= w_cb[8:1];
  end
end

endmodule
module csc_top
(
  Clock,
  ClockEnable,
  Reset,
  Red,
  Green,
  Blue,
  Y,
  Cb,
  Cr
);

  parameter TOP_OUT_SIZE  =  8; // uncomment to get  8-bit input & output...
//  parameter TOP_OUT_SIZE  = 10; // uncomment to get 10-bit input & output...

  input  Clock; 
  input  ClockEnable; 
  input  Reset; 
  input  [(TOP_OUT_SIZE - 1):0] Red; 
  input  [(TOP_OUT_SIZE - 1):0] Green; 
  input  [(TOP_OUT_SIZE - 1):0] Blue; 
  output [(TOP_OUT_SIZE - 1):0] Y; 
  output [(TOP_OUT_SIZE - 1):0] Cb; 
  output [(TOP_OUT_SIZE - 1):0] Cr; 

  reg [(TOP_OUT_SIZE - 1):0] Y;
  reg [(TOP_OUT_SIZE - 1):0] Cb;
  reg [(TOP_OUT_SIZE - 1):0] Cr;

  // Define internal signals
  reg [(TOP_OUT_SIZE - 1):0] R; 
  reg [(TOP_OUT_SIZE - 1):0] G; 
  reg [(TOP_OUT_SIZE - 1):0] B; 

  wire [(TOP_OUT_SIZE - 1):0] Y_sig; 
  wire [(TOP_OUT_SIZE - 1):0] Cb_sig; 
  wire [(TOP_OUT_SIZE - 1):0] Cr_sig; 

  // Input registers (should be pushed into IOBs)
  always @(posedge Clock or posedge Reset)
  begin : In_Reg
    if (Reset)
    begin
      R <= 0;
      G <= 0;
      B <= 0;
    end
    else if (ClockEnable)
    begin
      R <= Red ; 
      G <= Green ; 
      B <= Blue ; 
    end 
  end 

  // Output registers (should be pushed into IOBs)
  always @(posedge Clock or posedge Reset)
  begin : Out_Reg
    if (Reset)
    begin
      Y  <= 0;
      Cb <= 0;
      Cr <= 0;
    end
    else if (ClockEnable)
    begin
      Y  <= Y_sig ; 
      Cb <= Cb_sig ; 
      Cr <= Cr_sig ; 
    end 
  end 


  // CSC instantiation
  csc  #(TOP_OUT_SIZE) CSC_module
  (
    .Clock(Clock),
    .ClockEnable(ClockEnable),
    .Reset(Reset),
    .R(R),
    .G(G),
    .B(B),
    .Y(Y_sig),
    .Cb(Cb_sig),
    .Cr(Cr_sig)
  );


endmodule
module fm_vout_delay (
    i_in,
    o_out,
    clk_sys,
    rst_x
);
parameter P_WIDTH     = 4;
// P_NUM_DELAY should be greater than 1
parameter P_NUM_DELAY = 6;

//////////////////////////////////
// I/O port definition
//////////////////////////////////
    input  [P_WIDTH-1:0] i_in;
    output [P_WIDTH-1:0] o_out;
    input                clk_sys;
    input                rst_x;
//////////////////////////////////
// regs 
//////////////////////////////////
    reg    [P_WIDTH-1:0] r_delay[0:P_NUM_DELAY-1];

//////////////////////////////////
// assign statement
//////////////////////////////////
    assign o_out = r_delay[P_NUM_DELAY-1];

//////////////////////////////////
// always statement
//////////////////////////////////
    always @(posedge clk_sys or negedge rst_x) begin
        if (~rst_x) begin
            r_delay[0] <= {P_WIDTH{1'b0}};
        end else begin
            r_delay[0] <= i_in;
        end
    end

    // delay register connection
    integer i;
    always @(posedge clk_sys or negedge rst_x) begin
        if (~rst_x) begin
            for ( i = 1; i < P_NUM_DELAY; i = i + 1) begin
                r_delay[i] <= {P_WIDTH{1'b0}};
            end
        end else begin
            for ( i = 1; i < P_NUM_DELAY; i = i + 1) begin
                r_delay[i] <= r_delay[i-1];
            end
        end
    end


endmodule
module fm_dispatch (
    clk_core,
    rst_x,
    // local interface
    i_req,
    i_wr,
    i_adrs,
    o_ack,
    i_be,
    i_wd,
    o_rstr,
    o_rd,
    // internal side
    o_req_sys,
    o_req_3d,
    o_wr,
    o_adrs,
    i_ack_sys,
    i_ack_3d,
    o_be,
    o_wd,
    i_rstr_sys,
    i_rstr_3d,
    i_rd_sys,
    i_rd_3d,
    // I2C wishbone
    o_wb_adr,
    o_wb_dat,
    i_wb_dat,
    o_wb_we,
    o_wb_stb,
    o_wb_cyc,
    i_wb_ack
);
//////////////////////////////////
// I/O port definition
//////////////////////////////////
    input           clk_core;
    input           rst_x;
    // sh4 local interface
    input           i_req;
    input           i_wr;
    input  [23:0]   i_adrs;
    output          o_ack;
    input  [3:0]    i_be;
    input  [31:0]   i_wd;
    output          o_rstr;
    output [31:0]   o_rd;
    // internal side
    output          o_req_sys;
    output          o_req_3d;
    output          o_wr;
    output [21:0]   o_adrs;
    input           i_ack_sys;
    input           i_ack_3d;
    output [3:0]    o_be;
    output [31:0]   o_wd;
    input           i_rstr_sys;
    input           i_rstr_3d;
    input  [31:0]   i_rd_sys;
    input  [31:0]   i_rd_3d;
    // wishbone signals
    output [2:0] o_wb_adr;     // lower address bits
    output [7:0] o_wb_dat;     // databus input
    input  [7:0] i_wb_dat;     // databus output
    output       o_wb_we;      // write enable input
    output       o_wb_stb;     // stobe/core select signal
    output       o_wb_cyc;     // valid bus cycle input
    input        i_wb_ack;     // bus cycle acknowledge output
//////////////////////////////////
// reg
//////////////////////////////////
//////////////////////////////////
// wire
//////////////////////////////////
    wire            w_sys_hit;
    wire            w_3d_hit;
    wire            w_i2c_hit;

    wire   [23:0]   w_adrs;
    wire            w_req;

    wire            w_rstr_i2c;
//////////////////////////////////
// assign
//////////////////////////////////
    assign     w_adrs = i_adrs;
    assign     w_req = i_req;

    assign     w_sys_hit = (w_adrs[9:8] == 2'b00);  // byte address
    assign     w_i2c_hit = (w_adrs[9:8] == 2'b01);
    assign     w_3d_hit = (w_adrs[9] == 1'b1);

    assign     o_ack = (w_sys_hit & i_ack_sys)|
                       (w_i2c_hit & i_wb_ack)|
                       (w_3d_hit &i_ack_3d);
    assign     o_rstr = i_rstr_sys | i_rstr_3d | w_rstr_i2c;
    assign     o_rd = (i_rstr_sys) ? i_rd_sys :
                      (i_rstr_3d)  ? i_rd_3d :
                      (w_rstr_i2c) ? {24'h0,i_wb_dat} :
                                     32'h0;
    assign     o_req_sys = w_req & w_sys_hit;
    assign     o_req_3d = w_req & w_3d_hit;
    assign     o_adrs = w_adrs[21:0];
    assign     o_wr = i_wr;
    assign     o_be = i_be;
    assign     o_wd = i_wd;

    assign o_wb_adr[2:0] = i_adrs[4:2];
    assign o_wb_dat = i_wd[7:0];
    assign o_wb_we = i_wr;
    assign o_wb_stb = w_req & w_i2c_hit;
    assign o_wb_cyc = o_wb_stb;
    assign w_rstr_i2c = o_wb_stb & (!o_wb_we) & i_wb_ack;

endmodule
module async_counter_30(clk, count);
  input			clk;
  output 	[29:0]	count;
  reg		[14:0] 	count_a;
  reg           [14:0]  count_b;  

  initial count_a = 15'b0;
  initial count_b = 15'b0;

always @(negedge clk)
	count_a <= count_a + 1'b1;

always @(negedge count_a[14])
	count_b <= count_b + 1'b1;

assign count = {count_b, count_a};

endmodule
module I2C_Controller (
	input  CLOCK,
	input  [23:0]I2C_DATA,	
	input  GO,
	input  RESET,	
	input  W_R,
 	inout  I2C_SDAT,	
	output I2C_SCLK,
	output END,	
	output ACK
);

wire SDAO ; 

assign I2C_SDAT = SDAO?1'bz :0  ; 

I2C_WRITE_WDATA  wrd(
   .RESET_N  ( RESET),
	.PT_CK    ( CLOCK),
	.GO       ( GO   ),
	.END_OK   ( END  ),
	.ACK_OK   ( ACK  ),
	.BYTE_NUM ( 2    ),  //2byte	
	.SDAI     ( I2C_SDAT ),//IN
	.SDAO     ( SDAO     ),//OUT
	.SCLO     ( I2C_SCLK ),	
	.SLAVE_ADDRESS( I2C_DATA[23:16] ),
	.REG_DATA     ( I2C_DATA[15:0]  )	
);	
	
	

endmodule
module vga_pll (
		input  wire  refclk,   //  refclk.clk
		input  wire  rst,      //   reset.reset
		output wire  outclk_0, // outclk0.clk
		output wire  outclk_1, // outclk1.clk
		output wire  locked    //  locked.export
	);

	vga_pll_0002 vga_pll_inst (
		.refclk   (refclk),   //  refclk.clk
		.rst      (rst),      //   reset.reset
		.outclk_0 (outclk_0), // outclk0.clk
		.outclk_1 (outclk_1), // outclk1.clk
		.locked   (locked)    //  locked.export
	);

endmodule
module  vga_pll_0002(

	// interface 'refclk'
	input wire refclk,

	// interface 'reset'
	input wire rst,

	// interface 'outclk0'
	output wire outclk_0,

	// interface 'outclk1'
	output wire outclk_1,

	// interface 'locked'
	output wire locked
);

	altera_pll #(
		.fractional_vco_multiplier("false"),
		.reference_clock_frequency("50.0 MHz"),
		.operation_mode("direct"),
		.number_of_clocks(2),
		.output_clock_frequency0("65.000000 MHz"),
		.phase_shift0("0 ps"),
		.duty_cycle0(50),
		.output_clock_frequency1("130.000000 MHz"),
		.phase_shift1("0 ps"),
		.duty_cycle1(50),
		.output_clock_frequency2("0 MHz"),
		.phase_shift2("0 ps"),
		.duty_cycle2(50),
		.output_clock_frequency3("0 MHz"),
		.phase_shift3("0 ps"),
		.duty_cycle3(50),
		.output_clock_frequency4("0 MHz"),
		.phase_shift4("0 ps"),
		.duty_cycle4(50),
		.output_clock_frequency5("0 MHz"),
		.phase_shift5("0 ps"),
		.duty_cycle5(50),
		.output_clock_frequency6("0 MHz"),
		.phase_shift6("0 ps"),
		.duty_cycle6(50),
		.output_clock_frequency7("0 MHz"),
		.phase_shift7("0 ps"),
		.duty_cycle7(50),
		.output_clock_frequency8("0 MHz"),
		.phase_shift8("0 ps"),
		.duty_cycle8(50),
		.output_clock_frequency9("0 MHz"),
		.phase_shift9("0 ps"),
		.duty_cycle9(50),
		.output_clock_frequency10("0 MHz"),
		.phase_shift10("0 ps"),
		.duty_cycle10(50),
		.output_clock_frequency11("0 MHz"),
		.phase_shift11("0 ps"),
		.duty_cycle11(50),
		.output_clock_frequency12("0 MHz"),
		.phase_shift12("0 ps"),
		.duty_cycle12(50),
		.output_clock_frequency13("0 MHz"),
		.phase_shift13("0 ps"),
		.duty_cycle13(50),
		.output_clock_frequency14("0 MHz"),
		.phase_shift14("0 ps"),
		.duty_cycle14(50),
		.output_clock_frequency15("0 MHz"),
		.phase_shift15("0 ps"),
		.duty_cycle15(50),
		.output_clock_frequency16("0 MHz"),
		.phase_shift16("0 ps"),
		.duty_cycle16(50),
		.output_clock_frequency17("0 MHz"),
		.phase_shift17("0 ps"),
		.duty_cycle17(50),
		.pll_type("General"),
		.pll_subtype("General")
	) altera_pll_i (
		.rst	(rst),
		.outclk	({outclk_1, outclk_0}),
		.locked	(locked),
		.fboutclk	( ),
		.fbclk	(1'b0),
		.refclk	(refclk)
	);
endmodule
module audio_fifo (
	aclr,
	data,
	rdclk,
	rdreq,
	wrclk,
	wrreq,
	q,
	rdempty,
	wrfull);

	input	  aclr;
	input	[31:0]  data;
	input	  rdclk;
	input	  rdreq;
	input	  wrclk;
	input	  wrreq;
	output	[31:0]  q;
	output	  rdempty;
	output	  wrfull;
`ifndef ALTERA_RESERVED_QIS
// synopsys translate_off
`endif
	tri0	  aclr;
`ifndef ALTERA_RESERVED_QIS
// synopsys translate_on
`endif

	wire  sub_wire0;
	wire  sub_wire1;
	wire [31:0] sub_wire2;
	wire  rdempty = sub_wire0;
	wire  wrfull = sub_wire1;
	wire [31:0] q = sub_wire2[31:0];

	dcfifo	dcfifo_component (
				.wrclk (wrclk),
				.rdreq (rdreq),
				.aclr (aclr),
				.rdclk (rdclk),
				.wrreq (wrreq),
				.data (data),
				.rdempty (sub_wire0),
				.wrfull (sub_wire1),
				.q (sub_wire2)
				// synopsys translate_off
				,
				.rdfull (),
				.rdusedw (),
				.wrempty (),
				.wrusedw ()
				// synopsys translate_on
				);
	defparam
		dcfifo_component.intended_device_family = "Cyclone IV E",
		dcfifo_component.lpm_numwords = 256,
		dcfifo_component.lpm_showahead = "OFF",
		dcfifo_component.lpm_type = "dcfifo",
		dcfifo_component.lpm_width = 32,
		dcfifo_component.lpm_widthu = 8,
		dcfifo_component.overflow_checking = "ON",
		dcfifo_component.rdsync_delaypipe = 5,
		dcfifo_component.underflow_checking = "ON",
		dcfifo_component.use_eab = "ON",
		dcfifo_component.write_aclr_synch = "ON",
		dcfifo_component.wrsync_delaypipe = 5;


endmodule
module TERASIC_IRM(
	clk,  // must be 50 MHZ
	reset_n,
	
	// interrrupt
	irq,
	
	// avalon slave
	s_cs_n,
	s_read,
	s_readdata,
	s_write,
	s_writedata,
	
	// export
	ir
	
);


input			clk;
input			reset_n;
output	reg		irq;
input			s_cs_n;
input			s_read;
output	[31:0]	s_readdata;
input			s_write;
input	[31:0]	s_writedata;
input			ir;

// write to clear interrupt
wire data_ready;
//always @ (posedge clk or posedge data_ready or negedge reset_n)
reg	pre_data_ready;
always @ (posedge clk or negedge reset_n)
begin
	if (~reset_n)
		pre_data_ready <= 1'b0;
	else
		pre_data_ready <= data_ready;
end

always @ (posedge clk or negedge reset_n)
begin
	if (~reset_n)
		irq <= 1'b0;
	else if (~pre_data_ready & data_ready)
		irq <= 1'b1;
	else if (~s_cs_n & s_write)
		irq <= 1'b0; // write any valud to clear interrupt flga
end


IRDA_RECEIVE_Terasic IRDA_RECEIVE_Terasic_inst(
					.iCLK(clk),         //clk   50MHz
					.iRST_n(reset_n),       //reset
					
					.iIRDA(ir),        //IRDA code input
					.iREAD(~s_cs_n & s_read),        //read command
					
					.oDATA_REAY(data_ready),	  //data ready
					.oDATA(s_readdata)         //decode data output
					);


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

    full_adder FA0 (.a(a[0]), .b(b[0]), .cin(cin), .sum(sum[0]), .cout(c[0]));
    full_adder FA1 (.a(a[1]), .b(b[1]), .cin(c[0]), .sum(sum[1]), .cout(c[1]));
    full_adder FA2 (.a(a[2]), .b(b[2]), .cin(c[1]), .sum(sum[2]), .cout(c[2]));
    full_adder FA3 (.a(a[3]), .b(b[3]), .cin(c[2]), .sum(sum[3]), .cout(c[3]));
    full_adder FA4 (.a(a[4]), .b(b[4]), .cin(c[3]), .sum(sum[4]), .cout(c[4]));
    full_adder FA5 (.a(a[5]), .b(b[5]), .cin(c[4]), .sum(sum[5]), .cout(c[5]));
    full_adder FA6 (.a(a[6]), .b(b[6]), .cin(c[5]), .sum(sum[6]), .cout(c[6]));
    full_adder FA7 (.a(a[7]), .b(b[7]), .cin(c[6]), .sum(sum[7]), .cout(c[7]));

    assign cout = c[7]; 
endmodule
module full_adder (input a, b, cin, output sum, cout);
    assign {cout, sum} = a + b + cin;
endmodule
module testbench;
  
  reg [7:0] a;
  reg [7:0] b;
  reg cin;
  wire [7:0] sum;
  wire cout;
  
  integer i; // Declare the loop variable here
  integer fail_count;
  integer error = 0;
  
  // Instantiate the module
  adder_8bit uut (
    .a(a), 
    .b(b), 
    .cin(cin), 
    .sum(sum), 
    .cout(cout)
  );
  
  // Randomize inputs and check output
  initial begin
    for (i = 0; i < 100; i = i + 1) begin
        a = $random & 8'hff;
        b = $random & 8'hff;
        cin = $random & 1'b1;
        #10;
        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
module verified_edge_detect(
	input clk,
	input rst_n,
	input a,
	
	output reg rise,
	output reg down
);
	reg a0;
    always@(posedge clk or negedge rst_n) begin
        if(~rst_n) begin
            rise <= 1'b0;
            down <= 1'b0;
        end 
        else begin
            if(a & ~a0) begin
                rise <= 1;
                down <= 0;
            end 
            else if (~a & a0) begin
                rise <= 0;
                down <= 1;
            end else begin
                rise <= 0;
                down <= 0;
            end
        end
    end
    
    always@(posedge clk or negedge rst_n) begin
        if(~rst_n) 
            a0 <= 0;
        else 
            a0 <= a;
    end
endmodule
module testbench;
    reg clk;
    reg rst_n;
    reg a;
    wire rise;
    wire down;

    edge_detect 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
        #5;

        // Test scenario 1: No edge
        a = 0;
        #10;
        a = 0;
        #10;
        // $display("rise: %b, down: %b", rise, down);
        error = (rise != 0 && down != 0) ? error+1 : error;
        // Test scenario 2: Rising edge
        a = 0;
        #10;
        a = 1;
        #10;
        a = 1;
        // $display("rise: %b, down: %b", rise, down);
        error = (rise != 1 && down != 0) ? error+1 : error;
        // Test scenario 3: Falling edge
        a = 1;
        #10;
        a = 0;
        #10;
        a = 0;
        // $display("rise: %b, down: %b", rise, down);
        error = (rise != 0 && down != 1) ? error+1 : error;
       // Test scenario 4: Reset
        rst_n = 0;
        #10;
        rst_n = 1;
        #10;
        // $display("rise: %b, down: %b", rise, down);
        error = (rise != 0 && down != 0) ? error+1 : error;
        
        if (error == 0) begin
            $display("===========Your Design Passed===========");
        end
        else begin
        $display("===========Error===========", error);
        end

        // Finish simulation
        $finish;
    end

    always #5 clk = ~clk;
    
endmodule
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 mux module
    synchronizer 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
        // $display(dataout);
        #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
        // $display(dataout);
        #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
        // $display(dataout);
        #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
module verified_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;
always@(posedge clk_a or negedge arstn)
begin
	if(!arstn)	data_reg <= 0;
		else	data_reg <= data_in;
end
reg en_data_reg;	
always@(posedge clk_a or negedge arstn)
begin
	if(!brstn)	en_data_reg <= 0;
		else	en_data_reg <= data_en;   
end

reg	en_clap_one;	//1
reg en_clap_two;	//2
always@(posedge clk_b or negedge brstn)
begin
	if(!brstn)	en_clap_one <= 0;
		else	en_clap_one <= en_data_reg;	
end
always@(posedge clk_b or negedge brstn)
begin
	if(!brstn)	en_clap_two <= 0;
		else	en_clap_two <= en_clap_one;
end

always@(posedge clk_b or negedge brstn)
begin
	if(!brstn)	dataout <= 0;
		else	dataout <= (en_clap_two) ? data_reg : dataout;
end

endmodule
module verified_adder_16bit (
    input wire [15:0] a,
    input wire [15:0] b,
    input wire Cin,
    output wire [15:0] y,
    output wire Co
);
 
    wire Co_temp;
 
    add8 add8_inst1 (
        .a(a[15:8]),
        .b(b[15:8]),
        .Cin(Co_temp), 
        .y(y[15:8]),
        .Co(Co)
    );
 
    add8 add8_inst2 (
        .a(a[7:0]),
        .b(b[7:0]),
        .Cin(Cin),
        .y(y[7:0]),
        .Co(Co_temp)
    ); 
 
endmodule
module add8 (
    input wire [7:0] a,
    input wire [7:0] b,
    input wire Cin,
    output wire [7:0] y,
    output wire Co
);
 
    wire Co_temp;
 
    add4 add4_inst1 (
        .a(a[7:4]),
        .b(b[7:4]),
        .Cin(Co_temp),
        .y(y[7:4]),
        .Co(Co)
    );
 
    add4 add4_inst2 (
        .a(a[3:0]),
        .b(b[3:0]),
        .Cin(Cin),
        .y(y[3:0]),
        .Co(Co_temp)
    );
 
endmodule
module add4 (
    input wire [3:0] a,
    input wire [3:0] b,
    input wire Cin,
    output wire [3:0] y,
    output wire Co
);
 
    wire Co_temp;
 
    add2 add2_inst1 (
        .a(a[3:2]),
        .b(b[3:2]),
        .Cin(Co_temp),
        .y(y[3:2]),
        .Co(Co)
    );
 
    add2 add2_inst2 (
        .a(a[1:0]),
        .b(b[1:0]),
        .Cin(Cin),
        .y(y[1:0]),
        .Co(Co_temp)
    ); 
 
endmodule
module add2 (
    input wire [1:0] a,
    input wire [1:0] b,
    input wire Cin,
    output wire [1:0] y,
    output wire Co
);
 
    wire Co_temp;

    add1 add1_inst1 (
        .a(a[1]),
        .b(b[1]),
        .Cin(Co_temp),
        .y(y[1]),
        .Co(Co)
    );
 
    add1 add1_inst2 (
        .a(a[0]),
        .b(b[0]),
        .Cin(Cin),
        .y(y[0]),
        .Co(Co_temp)
    );
         
endmodule
module add1 (
    input wire a,
    input wire b,
    input wire Cin,
    output wire y,
    output wire Co
);
    assign y = ((~a) & (~b) & Cin | (~a) & b & (~Cin) | a & (~b) & (~Cin) | (a & b & Cin));
    assign Co = ((~a & b & Cin) | (a & ~b & Cin) | (a & b & ~Cin) | (a & b & Cin));

endmodule
module add16_tb();

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

    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};
            Cin = 0;

            #10;
            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

    adder_16bit uut (
        .a(a),
        .b(b),
        .Cin(Cin),

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

endmodule
module verified_radix2_div(
    input wire clk,
    input wire rst,
    input wire [7:0] dividend,    
    input wire [7:0] divisor,    
    input wire sign,       

    input wire opn_valid,   
    output reg res_valid,   
    input wire res_ready,   
    output wire [15:0] result
);

    reg [7:0] dividend_save, divisor_save;
    reg [15:0] SR;                  
    reg [8 :0] NEG_DIVISOR;        
    wire [7:0] REMAINER, QUOTIENT;
    assign REMAINER = SR[15:8];
    assign QUOTIENT = SR[7: 0];

    wire [7:0] divident_abs;
    wire [8:0] divisor_abs;
    wire [7:0] remainer, quotient;

    assign divident_abs = (sign & dividend[7]) ? ~dividend + 1'b1 : dividend;
    assign remainer = (sign & dividend_save[7]) ? ~REMAINER + 1'b1 : REMAINER;
    assign quotient = sign & (dividend_save[7] ^ divisor_save[7]) ? ~QUOTIENT + 1'b1 : QUOTIENT;
    assign result = {remainer,quotient};

    wire CO;
    wire [8:0] sub_result;
    wire [8:0] mux_result;

    assign {CO,sub_result} = {1'b0,REMAINER} + NEG_DIVISOR;

    assign mux_result = CO ? sub_result : {1'b0,REMAINER};

    reg [3:0] cnt;
    reg start_cnt;
    always @(posedge clk) begin
        if(rst) begin
            SR <= 0;
            dividend_save <= 0;
            divisor_save <= 0;

            cnt <= 0;
            start_cnt <= 1'b0;
        end
        else if(~start_cnt & opn_valid & ~res_valid) begin
            cnt <= 1;
            start_cnt <= 1'b1;
        
            dividend_save <= dividend;
            divisor_save <= divisor;

            SR[15:0] <= {7'b0,divident_abs,1'b0}; 
            NEG_DIVISOR <= (sign & divisor[7]) ? {1'b1,divisor} : ~{1'b0,divisor} + 1'b1; 
        end
        else if(start_cnt) begin
            if(cnt[3]) begin    
                cnt <= 0;
                start_cnt <= 1'b0;
                
                SR[15:8] <= mux_result[7:0];
                SR[0] <= CO;
            end
            else begin
                cnt <= cnt + 1;

                SR[15:0] <= {mux_result[6:0],SR[7:1],CO,1'b0}; 
            end
        end
    end

    wire data_go;
    assign data_go = res_valid & res_ready;
    always @(posedge clk) begin
        res_valid <= rst     ? 1'b0 :
                     cnt[3]  ? 1'b1 :
                     data_go ? 1'b0 : res_valid;
    end
endmodule
module radix2_div_tb;
    reg clk;
    reg rst;
    reg [7:0] dividend, divisor;
    reg sign;
    reg opn_valid;
    reg res_ready;
    wire res_valid;
    wire [15:0] result;

    // Instantiate the radix2_div module
    radix2_div uut (
        .clk(clk),
        .rst(rst),
        .dividend(dividend),
        .divisor(divisor),
        .sign(sign),
        .opn_valid(opn_valid),
        .res_valid(res_valid),
        .res_ready(res_ready),
        .result(result)
    );

    integer i;
    integer error = 0;
    reg [7:0] a_test [0:7];
    reg [7:0] b_test [0:7];
    reg [15:0] expected_result [0:7];
    reg sign_test [0:7];

    initial begin
        // Initialize test vectors
        a_test[0] = 8'd100; b_test[0] = 8'd10; sign_test[0] = 0; expected_result[0] = {8'd0, 8'd10}; 
        a_test[1] = -8'd100; b_test[1] = 8'd10; sign_test[1] = 1; expected_result[1] = {8'd0, -8'd10};
        a_test[2] = 8'd100; b_test[2] = -8'd10; sign_test[2] = 1; expected_result[2] = {8'd0, -8'd10};
        a_test[3] = -8'd100; b_test[3] = -8'd10; sign_test[3] = 1; expected_result[3] = {8'd0, 8'd10};
        a_test[4] = 8'd123; b_test[4] = 8'd123; sign_test[4] = 0; expected_result[4] = {8'd0, 8'd1};
        a_test[5] = 8'd0; b_test[5] = 8'd123; sign_test[5] = 0; expected_result[5] = {8'd0, 8'd0};
        a_test[6] = 8'd123; b_test[6] = 8'd251; sign_test[6] = 0; expected_result[6] = {8'd123, 8'd0};
        a_test[7] = 8'd255; b_test[7] = 8'd7; sign_test[7] = 0; expected_result[7] = {8'd3, 8'd36};

        // Generate clock signal
        clk = 0;
        forever #5 clk = ~clk;
    end

    initial begin
        // Initialize
        rst = 1;
        opn_valid = 0;
        res_ready = 1;
        #20;
        rst = 0;

        for (i = 0; i < 8; i = i + 1) begin
            // Apply test vectors
            dividend = a_test[i];
            divisor = b_test[i];
            sign = sign_test[i];
            opn_valid = 1;
            #10;
            opn_valid = 0;

            // Wait for result
            wait(res_valid);
            #10;

            // Check result
            if (result !== expected_result[i]) begin
                error = error + 1;
                $display("Error: dividend=%d, divisor=%d, expected=%h, got=%h", a_test[i], b_test[i], expected_result[i], result);
            end

            res_ready = 1;
            #10;
        end

        // Display final result
        if (error == 0) begin
            $display("===========Your Design Passed===========");
        end else begin
            $display("===========Failed===========", error);
        end

        $finish;
    end
endmodule
module verified_traffic_light
    (
		input rst_n, 
      input clk, 
      input pass_request,
		  output wire[7:0]clock,
      output reg red,
		  output reg yellow,
		  output reg green
    );
	
	parameter 	idle = 2'd0,
				s1_red = 2'd1,
				s2_yellow = 2'd2,
				s3_green = 2'd3;
	reg [7:0] cnt;
	reg [1:0] state;
	reg p_red,p_yellow,p_green;	


always @(posedge clk or negedge rst_n) 
    begin
        if(!rst_n)
        begin
			state <= idle;
			p_red <= 1'b0;
			p_green <= 1'b0;
			p_yellow <= 1'b0;			
        end
        else case(state)
		idle:
			begin
				p_red <= 1'b0;
				p_green <= 1'b0;
				p_yellow <= 1'b0;
				state <= s1_red;
			end
		s1_red:
			begin
				p_red <= 1'b1;
				p_green <= 1'b0;
				p_yellow <= 1'b0;
				if (cnt == 3) 
					state <= s3_green;
				else
					state <= s1_red;
			end
		s2_yellow:
			begin
				p_red <= 1'b0;
				p_green <= 1'b0;
				p_yellow <= 1'b1;
				if (cnt == 3) 
					state <= s1_red;
				else
					state <= s2_yellow;
			end
		s3_green:
			begin
				p_red <= 1'b0;
				p_green <= 1'b1;
				p_yellow <= 1'b0;
				if (cnt == 3) 
					state <= s2_yellow;
				else
					state <= s3_green;
			end
		endcase
	end
 
always @(posedge clk or negedge rst_n) 
      if(!rst_n)
			cnt <= 7'd10;
		else if (pass_request&&green&&(cnt>10))
			cnt <= 7'd10;
		else if (!green&&p_green)
			cnt <= 7'd60;
		else if (!yellow&&p_yellow)
			cnt <= 7'd5;
		else if (!red&&p_red)
			cnt <= 7'd10;	
		else cnt <= cnt -1;
 assign clock = cnt;

always @(posedge clk or negedge rst_n) 
        if(!rst_n)
			begin
				yellow <= 1'd0;
				red <= 1'd0;
				green <= 1'd0;
			end
		else 
			begin
				yellow <= p_yellow;
				red <= p_red;
				green <= p_green;
			end		

endmodule
module tb_traffic_light;
  
  reg clk;
  reg rst_n;
  reg pass_request;
  wire [7:0] clock;
  wire red;
  wire yellow;
  wire green;
  integer i;
  // Instantiate the module
  traffic_light 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
module verified_alu(
    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
    );
    

    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;
      
    
    wire signed [31:0] a_signed;
    wire signed [31:0] b_signed;
    
  
    reg [32:0] res;
    
    
    assign a_signed = a;
    assign b_signed = b;
    assign r = res[31:0];
    
    assign flag = (aluc == SLT || aluc == SLTU) ? ((aluc == SLT) ? (a_signed < b_signed) : (a < b)) : 1'bz; 
    assign zero = (res == 32'b0) ? 1'b1 : 1'b0;
    
    always @ (a or b or aluc)
    begin
        case(aluc)
            ADD: begin
                res <= a_signed + b_signed;
            end
            ADDU: begin
                res <= a + b;
            end
            SUB: begin 
                res <= a_signed - b_signed;
            end
            SUBU: begin 
                res <= a - b;
            end
            AND: begin
                res <= a & b;
            end
            OR: begin
                res <= a | b;
            end
            XOR: begin
                res <= a ^ b;
            end
            NOR: begin
                res <= ~(a | b);
            end
            SLT: begin
                res <= a_signed < b_signed ? 1 : 0;
            end
            SLTU: begin
                res <= a < b ? 1 : 0;
            end
            SLL: begin
                res <= b << a;
            end
            SRL: begin
                res <= b >> a;
            end
            SRA: begin
                res <= b_signed >>> a_signed;
            end
            SLLV: begin
                res <= b << a[4:0];
            end
            SRLV: begin
                res <= b >> a[4:0];
            end
            SRAV: begin
                res <= b_signed >>> a_signed[4:0];
            end
            LUI: begin
                res <= {a[15:0], 16'h0000};
            end
            default:
            begin
                res <= 32'bz;
            end
        endcase
    end
endmodule
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;
    
    alu uut(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;

    cnt = 0;

    
    for(cnt=0;cnt<17;cnt=cnt+1)
        begin
        #5;
        aluc=opcodes[cnt];
        #5;
        error=error|(reference[cnt]!=r);
    end

	if(error==0)
	begin
		$display("===========Your Design Passed===========");
        end
	else
	begin
		$display("===========Error===========");
	end
    $finish;
    end
endmodule
module verified_adder_32bit(A,B,S,C32);
     input [32:1] A;
     input [32:1] B;
     output [32:1] S;
     output C32;

     wire px1,gx1,px2,gx2;
     wire c16;

  CLA_16 CLA1(
      .A(A[16:1]),
        .B(B[16:1]),
        .c0(0),
        .S(S[16:1]),
        .px(px1),
        .gx(gx1)
    );

  CLA_16 CLA2(
        .A(A[32:17]),
          .B(B[32:17]),
          .c0(c16),
          .S(S[32:17]),
          .px(px2),
          .gx(gx2)
    );

  assign c16 = gx1 ^ (px1 && 0), //c0 = 0
         C32 = gx2 ^ (px2 && c16);
endmodule
module CLA_16(A,B,c0,S,px,gx);
    input [16:1] A;
    input [16:1] B;
    input c0;
    output gx,px;
    output [16:1] S;

    wire c4,c8,c12;
    wire Pm1,Gm1,Pm2,Gm2,Pm3,Gm3,Pm4,Gm4;

    adder_4 adder1(
         .x(A[4:1]),
          .y(B[4:1]),
          .c0(c0),
          .c4(),
          .F(S[4:1]),
          .Gm(Gm1),
          .Pm(Pm1)
    );

    adder_4 adder2(
         .x(A[8:5]),
          .y(B[8:5]),
          .c0(c4),
          .c4(),
          .F(S[8:5]),
          .Gm(Gm2),
          .Pm(Pm2)
    );

    adder_4 adder3(
         .x(A[12:9]),
          .y(B[12:9]),
          .c0(c8),
          .c4(),
          .F(S[12:9]),
          .Gm(Gm3),
          .Pm(Pm3)
    );

    adder_4 adder4(
         .x(A[16:13]),
          .y(B[16:13]),
          .c0(c12),
          .c4(),
          .F(S[16:13]),
          .Gm(Gm4),
          .Pm(Pm4)
    );

    assign   c4 = Gm1 ^ (Pm1 & c0),
             c8 = Gm2 ^ (Pm2 & Gm1) ^ (Pm2 & Pm1 & c0),
             c12 = Gm3 ^ (Pm3 & Gm2) ^ (Pm3 & Pm2 & Gm1) ^ (Pm3 & Pm2 & Pm1 & c0);

    assign  px = Pm1 & Pm2 & Pm3 & Pm4,
            gx = Gm4 ^ (Pm4 & Gm3) ^ (Pm4 & Pm3 & Gm2) ^ (Pm4 & Pm3 & Pm2 & Gm1);
endmodule