dakies/OSS_Verilog huggingface dataset:
module oh_clockmux4
  #(parameter N    = 1,        // vector width
    parameter SYN  = "TRUE",   // synthesizable (or not)
    parameter TYPE = "DEFAULT" // implementation type
    )
   (
    input [N-1:0]  en0, // clkin0 enable (stable high)
    input [N-1:0]  en1, // clkin1 enable (stable high)
    input [N-1:0]  en2, // clkin1 enable (stable high)
    input [N-1:0]  en3, // clkin1 enable (stable high)
    input [N-1:0]  clkin0, // clock input
    input [N-1:0]  clkin1, // clock input
    input [N-1:0]  clkin2, // clock input
    input [N-1:0]  clkin3, // clock input
    output [N-1:0] clkout // clock output
    );

   generate
      if(SYN == "TRUE") begin
	 assign clkout[N-1:0] = (en0[N-1:0] & clkin0[N-1:0]) |
				(en1[N-1:0] & clkin1[N-1:0]) |
				(en2[N-1:0] & clkin2[N-1:0]) |
				(en3[N-1:0] & clkin3[N-1:0]);
      end
      else begin
	 genvar 	     i;
	 for (i=0;i<N;i=i+1) begin
	    asic_clockmux4 #(.TYPE(TYPE))
	    asic_clockmux4(// Outputs
			   .clkout	(clkout[N-1:0]),
			   // Inputs
			   .en0		(en0[N-1:0]),
			   .en1		(en1[N-1:0]),
			   .en2		(en2[N-1:0]),
			   .en3		(en3[N-1:0]),
			   .clkin0	(clkin0[N-1:0]),
			   .clkin1	(clkin1[N-1:0]),
			   .clkin2	(clkin2[N-1:0]),
			   .clkin3	(clkin3[N-1:0]));
	 end
      end
   endgenerate
endmodule
module oh_csa92
  #(parameter N    = 1,        // number of sync stages
    parameter SYN  = "TRUE",   // synthesizable (or not)
    parameter TYPE = "DEFAULT" // scell type/size
    )
   ( input [N-1:0]  in0, //input
     input [N-1:0]  in1,//input
     input [N-1:0]  in2,//input
     input [N-1:0]  in3,//input
     input [N-1:0]  in4,//input
     input [N-1:0]  in5,//input
     input [N-1:0]  in6,//input
     input [N-1:0]  in7,//input
     input [N-1:0]  in8,//input
     input [N-1:0]  cin0,//carry in
     input [N-1:0]  cin1,//carry in
     input [N-1:0]  cin2,//carry in
     input [N-1:0]  cin3,//carry in
     input [N-1:0]  cin4,//carry in
     input [N-1:0]  cin5,//carry in
     output [N-1:0] s, //sum
     output [N-1:0] c, //carry
     output [N-1:0] cout0, //carry out
     output [N-1:0] cout1, //carry out
     output [N-1:0] cout2, //carry out
     output [N-1:0] cout3, //carry out
     output [N-1:0] cout4, //carry out
     output [N-1:0] cout5  //carry out
     );


   wire [N-1:0]     s_int0;
   wire [N-1:0]     s_int1;
   wire [N-1:0]     s_int2;

   oh_csa32 #(.N(N),
	      .TYPE(TYPE),
	      .SYN(SYN))
   csa32_0 (.in0(in0[N-1:0]),
	    .in1(in1[N-1:0]),
	    .in2(in2[N-1:0]),
	    .c(cout0[N-1:0]),
	    .s(s_int0[N-1:0]));

   oh_csa32 #(.N(N),
	      .TYPE(TYPE),
	      .SYN(SYN))
   csa32_1 (.in0(in3[N-1:0]),
	    .in1(in4[N-1:0]),
	    .in2(in5[N-1:0]),
	    .c(cout1[N-1:0]),
	    .s(s_int1[N-1:0]));

   oh_csa32 #(.N(N),
	      .TYPE(TYPE),
	      .SYN(SYN))
   csa32_2 (.in0(in6[N-1:0]),
	    .in1(in7[N-1:0]),
	    .in2(in8[N-1:0]),
	    .c(cout2[N-1:0]),
	    .s(s_int2[N-1:0]));

   oh_csa62 #(.N(N),
	      .TYPE(TYPE),
	      .SYN(SYN))
   csa62 (.in0(s_int0[N-1:0]),
	  .in1(s_int1[N-1:0]),
	  .in2(s_int2[N-1:0]),
	  .in3(cin0[N-1:0]),
	  .in4(cin1[N-1:0]),
	  .in5(cin2[N-1:0]),
	  .cin0(cin3[N-1:0]),
	  .cin1(cin4[N-1:0]),
	  .cin2(cin5[N-1:0]),
	  .cout0(cout3[N-1:0]),
	  .cout1(cout4[N-1:0]),
	  .cout2(cout5[N-1:0]),
	  .c(c[N-1:0]),
	  .s(s[N-1:0]));

endmodule // oh_csa92
module oh_ao211 #(parameter DW = 1 ) // array width
   (
    input [DW-1:0]  a0,
    input [DW-1:0]  a1,
    input [DW-1:0]  b0,
    input [DW-1:0]  c0, 
    output [DW-1:0] z
    );
   
   assign z = (a0 & a1) | b0 | c0;
   
endmodule
module oh_oai21 #(parameter DW = 1 ) // array width
   (
    input [DW-1:0]  a0,
    input [DW-1:0]  a1,
    input [DW-1:0]  b0, 
    output [DW-1:0] z
    );
   
   assign z = ~((a0 | a1) & b0);
   
endmodule
module oh_bitreverse
  #(parameter N = 32 // width of data inputs
    )
   (
    input [N-1:0]  in, // data input
    output [N-1:0] out // bit reversed output
    );

   genvar 	   i;

   generate
      for (i=0;i<N;i=i+1)
	assign out[i] = in[N-1-i];
   endgenerate

endmodule // oh_bitreverse
module oh_ao222 #(parameter DW = 1 ) // array width
   (
    input [DW-1:0]  a0,
    input [DW-1:0]  a1,
    input [DW-1:0]  b0,
    input [DW-1:0]  b1,
    input [DW-1:0]  c0,
    input [DW-1:0]  c1, 
    output [DW-1:0] z
    );
   
   assign z = (a0 & a1) | (b0 & b1) | (c0 & c1);
   
endmodule
module oh_gray2bin #(parameter N = 32) // width of data inputs
   (
    input [N-1:0]  in,  //gray encoded input
    output [N-1:0] out  //binary encoded output
    );

   reg [N-1:0]     bin;
   wire [N-1:0]    gray;

   integer 	   i,j;

   assign gray[N-1:0] = in[N-1:0];
   assign out[N-1:0]  = bin[N-1:0];

   always @*
     begin
	bin[N-1] = gray[N-1];
	for (i=0; i<(N-1); i=i+1)
	  begin
	     bin[i] = 1'b0;
	     for (j=i; j<N; j=j+1)
	       bin[i] = bin[i] ^ gray [j];
	  end
     end

endmodule // oh_gray2bin
module oh_bin2onehot
  #(parameter  N  = 2, // output vector width
    parameter  NB = $clog2(N) // binary encoded input
    )
   (
    input [NB-1:0] in, // unsigned binary input
    output [N-1:0] out   // one hot output vector
    );

   genvar 	   i;
   for(i=0;i<N;i=i+1) begin: gen_onehot
      assign out[i] = (in[NB-1:0] == i);
   end
endmodule // oh_bin2onehot
module oh_add
  #(parameter N    = 32,        // block width
    parameter SYN  = "TRUE",    // synthesizable
    parameter TYPE = "DEFAULT"  // implementation type
    )
   (//inputs
    input [N-1:0]  a, // first operand
    input [N-1:0]  b, // second operand
    input [N-1:0]  k, // carrry kill signal (active high)
    input 	   cin,// carry in
    //outputs
    output [N-1:0] sum,// sum
    output [N-1:0] carry,// complete carry out vector
    output 	   cout// carry out from msb
    );

   generate
      if(SYN == "TRUE")  begin
	 assign {cout,sum[N-1:0]} = a[N-1:0] + b[N-1:0] + cin;
	 //TODO: FIX
	 assign carry = 'b0;
      end
      else begin
	 asic_add #(.TYPE(TYPE),
		    .N(N))
	 asic_add (// Outputs
		   .sum		(sum[N-1:0]),
		   .carry	(carry[N-1:0]),
		   .cout	(cout),
		   // Inputs
		   .a		(a[N-1:0]),
		   .b		(b[N-1:0]),
		   .k		(k[N-1:0]),
		   .cin		(cin));

      end
   endgenerate
endmodule
module oh_dffqn #(parameter DW = 1) // array width
   (
    input [DW-1:0] 	d,
    input [DW-1:0] 	clk,
    output reg [DW-1:0] qn
    );
   
   always @ (posedge clk)
     qn <= ~d;
      
endmodule
module oh_clockgate
  #(parameter SYN  = "TRUE",    // synthesizable
    parameter TYPE = "DEFAULT"  // implementation type
    )
(
 input 	clk, // clock input
 input 	te,  // test enable
 input 	en,  // enable (from positive edge FF)
 output eclk // enabled clock output
 );

   generate
      if(SYN == "TRUE") begin

	 wire     en_sh;
	 wire     en_sl;

	 //Stable low/valid rising edge enable
	 assign   en_sl = en | te;

	 //Stable high enable signal
	 oh_lat0 lat0 (.out (en_sh),
		       .in  (en_sl),
		       .clk (clk));

	 assign eclk =  clk & en_sh;

      end
      else begin
	 asic_clockgate #(.TYPE(TYPE))
	 asic_clockgate (// Outputs
			 .eclk		(eclk),
			 // Inputs
			 .clk		(clk),
			 .te		(te),
			 .en		(en));
      end
   endgenerate
endmodule
module oh_mux5 #(parameter N = 1 ) // width of mux
   (
    input 	    sel4,
    input 	    sel3,
    input 	    sel2,
    input 	    sel1,
    input 	    sel0,
    input [N-1:0]  in4,
    input [N-1:0]  in3,
    input [N-1:0]  in2,
    input [N-1:0]  in1,
    input [N-1:0]  in0,
    output [N-1:0] out  //selected data output
    );

   assign out[N-1:0] = ({(N){sel0}} & in0[N-1:0] |
			 {(N){sel1}} & in1[N-1:0] |
			 {(N){sel2}} & in2[N-1:0] |
			 {(N){sel3}} & in3[N-1:0] |
			 {(N){sel4}} & in4[N-1:0]);

endmodule // mux5
module oh_delay
  #(parameter N        = 1,               // width of data
    parameter MAXDELAY = 4,               // maximum delay cycles
    parameter M        = $clog2(MAXDELAY) // delay selctor
    )
   (
    input 	   clk, //clock input
    input [N-1:0]  in, // input vector
    input [M-1:0]  sel, // delay selector
    output [N-1:0] out  // output vector
    );


   //Delay pipeline
   reg [N-1:0]     sync_pipe[MAXDELAY-1:0];
   genvar 	    i;
   generate
      always @ (posedge clk)
	sync_pipe[0]<=in[N-1:0];
      for(i=1;i<MAXDELAY;i=i+1) begin: gen_pipe
         always @ (posedge clk)
	   sync_pipe[i]<=sync_pipe[i-1];
      end
   endgenerate

   //Delay selector
   assign out[N-1:0] = sync_pipe[sel[M-1:0]];

endmodule
module oh_counter
  #(parameter N   = 32,       // width of data inputs
    parameter SYN = "TRUE",   // synthesizable
    parameter TYPE = "DEFAULT"// implementation type
    )
   (
    //inputs
    input 	       clk, // clk input
    input 	       in, // input to count
    input 	       en, // enable counter
    input 	       dec,//1=decrement, 0 = increment
    input 	       autowrap, //auto wrap counter
    input 	       load, // load counter
    input [N-1:0]      load_data, // input data to load
    //outputs
    output reg [N-1:0] count, // count value
    output 	       wraparound // wraparound indicator
    );

   wire [N-1:0]	 inb;
   wire [N-1:0]  count_in;

   //Increment decrement option
   assign inb[N-1:0] = dec ? {{(N-1){1'b1}},~in} : {{(N-1){1'b0}},in};
   assign cin        = dec ? 1'b1 : 1'b0;

   // counter
   always @(posedge clk)
     if(load)
       count[N-1:0] <= load_data[N-1:0];
     else if (en & ~(wraparound & ~autowrap))
       count[N-1:0] <= count_in[N-1:0];

   assign wraparound = (dec & en & ~(|count[N-1:0])) |
		       (~dec & en & (&count[N-1:0]));

   // Soft/hard adder
   generate
      if(SYN == "TRUE")  begin
	 assign count_in[N-1:0] =count[N-1:0] + inb[N-1:0];
      end
      else begin
	 asic_add #(.TYPE(TYPE),
		    .N(N))
	 asic_add (// Outputs
		   .sum		(cout_in[N-1:0]),
		   .carry	(),
		   .cout	(),
		   // Inputs
		   .a		(count[N-1:0]),
		   .b		(in_mux[N-1:0]),
		   .k		({(N){1'b0}}),
		   .cin		(cin));
      end
   endgenerate

endmodule // oh_counter
module oh_dffq #(parameter DW = 1) // array width
   (
    input [DW-1:0] 	d,
    input [DW-1:0] 	clk,
    output reg [DW-1:0] q
    );
   
   always @ (posedge clk)
     q <= d;
   
endmodule
module oh_lat0
  #(parameter N    = 1,        // number of sync stages
    parameter SYN  = "TRUE",   // synthesizable (or not)
    parameter TYPE = "DEFAULT" // scell type/size
    )
   (input 	   clk, // clk
    input [N-1:0]  in,  // input data
    output [N-1:0] out  // output data
     );

   genvar i;

   generate
      if(SYN == "TRUE") begin
	 reg [N-1:0]      out_reg;
	 always @ (clk or in)
	   if (!clk)
	     out_reg[N-1:0] <= in[N-1:0];
	 assign out[N-1:0] = out_reg[N-1:0];
      end
      else begin
	 for (i=0;i<N;i=i+1) begin
	    asic_lat0 #(.TYPE(TYPE))
	    asic_lat0 (.clk(clk),
		       .in(in[i]),
		       .out(out[i]));
	 end
      end
   endgenerate

endmodule // oh_lat0
module oh_ao21 #(parameter DW = 1 ) // array width
   (
    input [DW-1:0]  a0,
    input [DW-1:0]  a1,
    input [DW-1:0]  b0, 
    output [DW-1:0] z
    );
   
   assign z = (a0 & a1) | b0;
   
endmodule
module oh_sdffrqn #(parameter DW = 1) // array width
   (
    input [DW-1:0] 	d,
    input [DW-1:0] 	si,
    input [DW-1:0] 	se,
    input [DW-1:0] 	clk,
    input [DW-1:0] 	nreset,
    output reg [DW-1:0] qn
    );
   
   always @ (posedge clk or negedge nreset)
     if(!nreset)
       qn <= {DW{1'b1}};
     else
       qn <=  se ? ~si : ~d;
   
endmodule
module oh_oa221 #(parameter DW = 1 ) // array width
   (
    input [DW-1:0]  a0,
    input [DW-1:0]  a1,
    input [DW-1:0]  b0,
    input [DW-1:0]  b1,
    input [DW-1:0]  c0, 
    output [DW-1:0] z
    );
   
   assign z = (a0 | a1) & (b0 | b1) & (c0);
   
endmodule
module oh_abs
  #(parameter N    = 32,        // block width
    parameter SYN  = "TRUE",    // synthesizable
    parameter TYPE = "DEFAULT"  // implementation type
    )
   (
    input [N-1:0]  in,       // input operand
    output [N-1:0] out,      // out = abs(in) (signed two's complement)
    output 	   overflow  // high for max negative #
    );

   generate
      if(SYN == "TRUE")  begin
	 assign out[N-1:0] = in[N-1] ? ~in[N-1:0] + 1'b1 : in[N-1:0];
	 assign overflow   = in[N-1] & ~(|in[N-2:0]);
      end
      else begin
	 asic_abs #(.TYPE(TYPE),
		    .N(N))
	 asic_abs(// Outputs
		  .out	    (out[N-1:0]),
		  .overflow (overflow),
		  // Inputs
		  .in	    (in[N-1:0]));
      end

   endgenerate
endmodule
module oh_shift
  #(parameter N   = 32,         // Operator width (8,16,32,64,128)
    parameter S    = $clog2(N), // stages=shift width
    parameter SYN = "TRUE"       // TRUE is synthesizable
    )
   (
    input [N-1:0]  in,         // data to be shifted
    input 	    arithmetic, // shifts in in[N-1] instead of 0
    input 	    right,      // shift right (default is left shift)
    input [S-1:0]   shamt,      // shift amount (unsigned)
    output [N-1:0] out         //shifted output
    );

   generate
      if(SYN=="TRUE")  begin: gbehavioral

	 wire [2*N-1:0] in_sext;
	 wire [N-1:0] 	 sr_result;
	 wire [N-1:0] 	 sl_result;

	 assign shift_in          = arithmetic & in[N-1];

	 assign in_sext[2*N-1:0] = {{(N){shift_in}},in[N-1:0]};

	 assign sr_result[N-1:0] = in_sext[2*N-1:0] >> shamt[S-1:0];

	 assign sl_result[N-1:0] = in[N-1:0]        << shamt[S-1:0];

	 assign out[N-1:0]       = right ? sr_result[N-1:0] :
				            sl_result[N-1:0];

      end // block: gbehavioral
      else begin
	 asic_shift #(.TYPE(TYPE),
		      .N(N))
	 asic_shift (// Outputs
		     .out	 (out[N-1:0]),
		     // Inputs
		     .in	 (in[N-1:0]),
		     .arithmetic (arithmetic),
		     .right      (right),
		     .shamt	 (shamt[S-1:0]));

      end
   endgenerate
endmodule
module oh_oai33 #(parameter DW = 1 ) // array width
   (
    input [DW-1:0]  a0,
    input [DW-1:0]  a1,
    input [DW-1:0]  a2,
    input [DW-1:0]  b0,
    input [DW-1:0]  b1,
    input [DW-1:0]  b2, 
    output [DW-1:0] z
    );
   
   assign z = ~((a0 | a1 | a2) & (b0 | b1 | b2));
   
endmodule
module oh_ao32 #(parameter DW = 1 ) // array width
   (
    input [DW-1:0]  a0,
    input [DW-1:0]  a1,
    input [DW-1:0]  a2,
    input [DW-1:0]  b0,
    input [DW-1:0]  b1, 
    output [DW-1:0] z
    );
   
   assign z = (a0 & a1 & a2) | (b0 & b1);
   
endmodule
module oh_verify
  #(parameter N = 32  // width of verifier
    )
   (
    input 	   clk,
    input 	   nreset, //async reset
    input 	   en, // enable random counter
    input [N-1:0]  seed, // seed
    input [N-1:0]  in, // input data
    output [N-1:0] out, // generated random number
    output 	   error // difference found
    );

   // Recreate random number
   oh_random oh_random(.mask	({(PW){1'b1}}),
		       .taps	({(PW){1'b1}}),
		       .entaps	(1'b0),
		       /*AUTOINST*/
		       // Outputs
		       .out		(out[N-1:0]),
		       // Inputs
		       .clk		(clk),
		       .nreset		(nreset),
		       .en		(en),
		       .seed		(seed[N-1:0]));


   // Compare random number to data
   // TODO: add
   assign error = (out[N-1:0] != in[N-1:0]);


endmodule // oh_random
module oh_oa222 #(parameter DW = 1 ) // array width
   (
    input [DW-1:0]  a0,
    input [DW-1:0]  a1,
    input [DW-1:0]  b0,
    input [DW-1:0]  b1,
    input [DW-1:0]  c0,
    input [DW-1:0]  c1,
    output [DW-1:0] z
    );
   
   assign z = (a0 | a1) & (b0 | b1) & (c0 | c1);
   
endmodule
module oh_clockor
  #(parameter N    = 2,        // number of clock inputs)
    parameter SYN  = "TRUE",   // synthesizable (or not)
    parameter TYPE = "DEFAULT" // implementation type
    )
   (
    input [N-1:0] clkin, // clock input
    output 	  clkout // clock output
    );

   generate
      if(SYN == "TRUE") begin
	 assign clkout = |(clkin[N-1:0]);
      end
      else begin
	 asic_clockor #(.TYPE(TYPE),
			.N(N))
	 asic_clockor(// Outputs
		      .clkout		(clkout),
		      // Inputs
		      .clkin		(clkin[N-1:0]));
      end
   endgenerate
endmodule
module oh_oa33 #(parameter DW = 1 ) // array width
   (
    input [DW-1:0]  a0,
    input [DW-1:0]  a1,
    input [DW-1:0]  a2,
    input [DW-1:0]  b0,
    input [DW-1:0]  b1,
    input [DW-1:0]  b2, 
    output [DW-1:0] z
    );
   
   assign z = (a0 | a1 | a2) & (b0 | b1 | b2);
   
endmodule
module oh_tristate
  #(parameter N    = 1,         // block width
    parameter SYN  = "TRUE",    // synthesizable
    parameter TYPE = "DEFAULT"  // implementation type
    )
   (
    input [N-1:0]  in, // signal to io
    input [N-1:0]  oe, // output enable (1 = drive, 0 = high-z)
    output [N-1:0] out // output
    );

   genvar 	    i;
    generate
      if(SYN=="TRUE") begin
	 for (i = 0; i < N; i = i + 1) begin
	    assign out[i] = oe[i] ? in[i] : 1'bz;
	 end
      end
      else begin
	 asic_tristate #(.TYPE(TYPE),
			 .N(N))
	 asic_tristate (// Outputs
			.out	(out[N-1:0]),
			// Inputs
			.in	(in[N-1:0]),
			.ie	(ie[N-1:0]));
      end
    endgenerate
endmodule
module oh_or4 #(parameter DW = 1 ) // array width
   (
    input [DW-1:0]  a,
    input [DW-1:0]  b,
    input [DW-1:0]  c,
    input [DW-1:0]  d, 
    output [DW-1:0] z
    );
   
   assign z = a | b | c | d;
   
endmodule
module oh_aoi311 #(parameter DW = 1 ) // array width
   (
    input [DW-1:0]  a0,
    input [DW-1:0]  a1,
    input [DW-1:0]  a2,
    input [DW-1:0]  b0,
    input [DW-1:0]  c0, 
    output [DW-1:0] z
    );
   
   assign z = ~((a0 & a1 & a2) | b0 | c0);
   
endmodule
module oh_ser2par #(parameter PW = 64, // parallel packet width
		    parameter SW = 1,   // serial packet width
		    parameter CW = $clog2(PW/SW)  // serialization factor (for counter)
		    )
   (
    input 		clk, // sampling clock   
    input [SW-1:0] 	din, // serial data
    output reg [PW-1:0] dout, // parallel data  
    input 		lsbfirst, // lsb first order
    input 		shift      // shift the shifter
    );
   
   reg [CW-1:0]    count;
   wire [PW-1:0]   shiftdata;

   always @ (posedge clk)
     if(shift & lsbfirst)
       dout[PW-1:0] <= {din[SW-1:0],dout[PW-1:SW]};
     else if(shift)
       dout[PW-1:0] <= {dout[PW-SW-1:0],din[SW-1:0]};
   
endmodule // oh_ser2par
module oh_mux8 #(parameter N = 1 ) // width of mux
   (
    input 	    sel7,
    input 	    sel6,
    input 	    sel5,
    input 	    sel4,
    input 	    sel3,
    input 	    sel2,
    input 	    sel1,
    input 	    sel0,
    input [N-1:0]  in7,
    input [N-1:0]  in6,
    input [N-1:0]  in5,
    input [N-1:0]  in4,
    input [N-1:0]  in3,
    input [N-1:0]  in2,
    input [N-1:0]  in1,
    input [N-1:0]  in0,
    output [N-1:0] out  //selected data output
    );

   assign out[N-1:0] = ({(N){sel0}} & in0[N-1:0] |
			 {(N){sel1}} & in1[N-1:0] |
			 {(N){sel2}} & in2[N-1:0] |
			 {(N){sel3}} & in3[N-1:0] |
			 {(N){sel4}} & in4[N-1:0] |
			 {(N){sel5}} & in5[N-1:0] |
			 {(N){sel6}} & in6[N-1:0] |
			 {(N){sel7}} & in7[N-1:0]);


endmodule // oh_mux8
module oh_oa22 #(parameter DW = 1 ) // array width
   (
    input [DW-1:0]  a0,
    input [DW-1:0]  a1,
    input [DW-1:0]  b0,
    input [DW-1:0]  b1, 
    output [DW-1:0] z
    );
   
   assign z = (a0 | a1) & (b0 | b1);
   
endmodule
module oh_ao31 #(parameter DW = 1 ) // array width
   (
    input [DW-1:0]  a0,
    input [DW-1:0]  a1,
    input [DW-1:0]  a2,
    input [DW-1:0]  b0, 
    output [DW-1:0] z
    );
   
   assign z = (a0 & a1 & a2) | b0;
   
endmodule
module oh_mux3 #(parameter N = 1 ) // width of mux
   (
    input 	    sel2,
    input 	    sel1,
    input 	    sel0,
    input [N-1:0]  in2,
    input [N-1:0]  in1,
    input [N-1:0]  in0,
    output [N-1:0] out  //selected data output
    );

   assign out[N-1:0] = ({(N){sel0}} & in0[N-1:0] |
			 {(N){sel1}} & in1[N-1:0] |
			 {(N){sel2}} & in2[N-1:0]);

endmodule // oh_mux3
module usb_hid_host_rom(clk, adr, data);
	input clk;
	input [13:0] adr;
	output [3:0] data;
	reg [3:0] data; 
	reg [3:0] mem [536];
	initial $readmemh("usb_hid_host_rom.hex", mem);
	always @(posedge clk) data <= mem[adr];
endmodule
module clock
(
    input clkin, // 48 MHz, 0 deg
    output clk12, // 12 MHz, 0 deg
    output locked
);

(* FREQUENCY_PIN_CLKI="48" *)
(* FREQUENCY_PIN_CLKOP="12" *)
(* ICP_CURRENT="12" *) (* LPF_RESISTOR="8" *) (* MFG_ENABLE_FILTEROPAMP="1" *) (* MFG_GMCREF_SEL="2" *)
EHXPLLL #(
        .PLLRST_ENA("DISABLED"),
        .INTFB_WAKE("DISABLED"),
        .STDBY_ENABLE("DISABLED"),
        .DPHASE_SOURCE("DISABLED"),
        .OUTDIVIDER_MUXA("DIVA"),
        .OUTDIVIDER_MUXB("DIVB"),
        .OUTDIVIDER_MUXC("DIVC"),
        .OUTDIVIDER_MUXD("DIVD"),
        .CLKI_DIV(4),
        .CLKOP_ENABLE("ENABLED"),
        .CLKOP_DIV(50),
        .CLKOP_CPHASE(24),
        .CLKOP_FPHASE(0),
        .FEEDBK_PATH("CLKOP"),
        .CLKFB_DIV(1)
    ) pll_i (
        .RST(1'b0),
        .STDBY(1'b0),
        .CLKI(clkin),
        .CLKOP(clk12),
        .CLKFB(clk12),
        .CLKINTFB(),
        .PHASESEL0(1'b0),
        .PHASESEL1(1'b0),
        .PHASEDIR(1'b1),
        .PHASESTEP(1'b1),
        .PHASELOADREG(1'b1),
        .PLLWAKESYNC(1'b0),
        .ENCLKOP(1'b0),
        .LOCK(locked)
	);
endmodule
module top (
    input sys_clk,
    // input sys_resetn,
    // input s1,

    // UART
    input UART_RXD,
    output UART_TXD,

    // LEDs
    output led,

    // USB
    inout usbdm,
    inout usbdp
);

wire sys_resetn;
wire clk_usb;
wire [1:0] usb_type;
wire [7:0] key_modifiers, key1, key2, key3, key4;
wire [7:0] mouse_btn;
wire signed [7:0] mouse_dx, mouse_dy;
wire [63:0] hid_report;
wire usb_report, usb_conerr, game_l, game_r, game_u, game_d, game_a, game_b, game_x, game_y;
wire game_sel, game_sta;
wire [13:0] dbg_pc;
wire [3:0] dbg_inst;

clock clock(
    .clkin(sys_clk),
    .clk12(clk_usb),       // 12Mhz usb clock
    .locked(sys_resetn)
);

usb_hid_host usb (
    .usbclk(clk_usb), .usbrst_n(sys_resetn),
    .usb_dm(usbdm), .usb_dp(usbdp),	
    .typ(usb_type), .report(usb_report),
    .key_modifiers(key_modifiers), .key1(key1), .key2(key2), .key3(key3), .key4(key4),
    .mouse_btn(mouse_btn), .mouse_dx(mouse_dx), .mouse_dy(mouse_dy),
    .game_l(game_l), .game_r(game_r), .game_u(game_u), .game_d(game_d),
    .game_a(game_a), .game_b(game_b), .game_x(game_x), .game_y(game_y), 
    .game_sel(game_sel), .game_sta(game_sta),
    .conerr(usb_conerr), .dbg_hid_report(hid_report)
);

hid_printer prt (
    .clk(clk_usb), .resetn(sys_resetn),
    .uart_tx(UART_TXD), .usb_type(usb_type), .usb_report(usb_report),
    .key_modifiers(key_modifiers), .key1(key1), .key2(key2), .key3(key3), .key4(key4),
    .mouse_btn(mouse_btn), .mouse_dx(mouse_dx), .mouse_dy(mouse_dy),
    .game_l(game_l), .game_r(game_r), .game_u(game_u), .game_d(game_d),
    .game_a(game_a), .game_b(game_b), .game_x(game_x), .game_y(game_y), 
    .game_sel(game_sel), .game_sta(game_sta)
);

reg report_toggle;      // blinks whenever there's a report
always @(posedge clk_usb) if (usb_report) report_toggle <= ~report_toggle;

assign led = report_toggle;
//assign leds[7:0] = ~{6'b0, usb_type};
//assign leds[15:8] = ~8'b0;

endmodule
module usb_hid_host_demo (
    input sys_clk,
    // input sys_resetn,
    input s1,

    // UART
    input UART_RXD,
    output UART_TXD,

    // LEDs
    output [1:0] led,

    // USB
    inout usbdm,
    inout usbdp

);

reg sys_resetn = 0;
always @(posedge clk) begin
    sys_resetn <= 1;
end

wire clk = sys_clk;
wire clk_sdram = ~sys_clk;  
wire clk_usb;

// USB clock 12Mhz
gowin_pll_usb pll_usb (
    .clkin(sys_clk),
    .clkout(clk_usb)       // 12Mhz usb clock
);

wire [1:0] usb_type;
wire [7:0] key_modifiers, key1, key2, key3, key4;
wire [7:0] mouse_btn;
wire signed [7:0] mouse_dx, mouse_dy;
wire [63:0] hid_report;
wire [7:0] hid_regs [7];

usb_hid_host usb (
    .usbclk(clk_usb), .usbrst_n(sys_resetn),
    .usb_dm(usbdm), .usb_dp(usbdp),	
    .typ(usb_type), .report(usb_report),
    .key_modifiers(key_modifiers), .key1(key1), .key2(key2), .key3(key3), .key4(key4),
    .mouse_btn(mouse_btn), .mouse_dx(mouse_dx), .mouse_dy(mouse_dy),
    .game_l(game_l), .game_r(game_r), .game_u(game_u), .game_d(game_d),
    .game_a(game_a), .game_b(game_b), .game_x(game_x), .game_y(game_y), 
    .game_sel(game_sel), .game_sta(game_sta),
    .conerr(usb_conerr), .dbg_hid_report(hid_report)
);

hid_printer prt (
    .clk(clk_usb), .resetn(sys_resetn),
    .uart_tx(UART_TXD), .usb_type(usb_type), .usb_report(usb_report),
    .key_modifiers(key_modifiers), .key1(key1), .key2(key2), .key3(key3), .key4(key4),
    .mouse_btn(mouse_btn), .mouse_dx(mouse_dx), .mouse_dy(mouse_dy),
    .game_l(game_l), .game_r(game_r), .game_u(game_u), .game_d(game_d),
    .game_a(game_a), .game_b(game_b), .game_x(game_x), .game_y(game_y), 
    .game_sel(game_sel), .game_sta(game_sta)
);

reg report_toggle;      // blinks whenever there's a report
always @(posedge clk_usb) if (usb_report) report_toggle <= ~report_toggle;

assign led = ~{usb_conerr, report_toggle};

endmodule
module uart_tx_V2(
    input wire clk,
    input wire [7:0] din,
    input wire wr_en,
    output wire tx_busy,

    output reg tx_p    
);

initial begin
    tx_p = 1'b1;
end

parameter clk_freq = 12000000;
parameter uart_freq = 115200;

localparam STATE_IDLE	= 2'b00;
localparam STATE_START	= 2'b01;
localparam STATE_DATA	= 2'b10;
localparam STATE_STOP	= 2'b11;

reg[7:0] localdin;
reg localwr_en;

//always@(posedge clk)begin
always@(*)begin	
    localdin<=din;
    localwr_en<=wr_en;
end

reg [7:0] data= 8'h00;
reg [2:0] bitpos= 3'h0;
reg [1:0] state= STATE_IDLE;

wire tx_clk;

localparam TX_CLK_MAX = (clk_freq / uart_freq)-1;

reg[$clog2(TX_CLK_MAX+1)+1:0] tx_clkcnt;

assign tx_clk = (tx_clkcnt == 0);

initial tx_clkcnt=0;

always @(posedge clk) begin
    if (tx_clkcnt >= TX_CLK_MAX)
        tx_clkcnt <= 0;
    else
        tx_clkcnt <= tx_clkcnt + 1;
end
    

always @(posedge clk) begin
    case (state)
    STATE_IDLE: begin
        if (localwr_en) begin
            state <= STATE_START;
            data <= localdin;
            bitpos <= 3'h0;
        end
    end
    STATE_START: begin
        if (tx_clk) begin
            tx_p <= 1'b0;
            state <= STATE_DATA;
        end
    end
    STATE_DATA: begin
        if (tx_clk) begin
            if (bitpos == 3'h7)
                state <= STATE_STOP;
            else
                bitpos <= bitpos + 3'h1;
            tx_p <= data[bitpos];
        end
    end
    STATE_STOP: begin
        if (tx_clk) begin
            tx_p <= 1'b1;
            state <= STATE_IDLE;
        end
    end
    default: begin
        tx_p <= 1'b1;
        state <= STATE_IDLE;
    end
    endcase
end

assign tx_busy = (state != STATE_IDLE);

endmodule
module clock
(
    input clkin,    // 25 MHz
    output clk12,   // 12 MHz
    output clk100,  // 100 Mhz
    output locked
);

// pll0 raises 25Mhz to 100Mhz
// pll1 produces 12Mhz from 100Mhz
wire locked0;

(* FREQUENCY_PIN_CLKI="25" *)
(* FREQUENCY_PIN_CLKOP="100" *)
(* ICP_CURRENT="12" *) (* LPF_RESISTOR="8" *) (* MFG_ENABLE_FILTEROPAMP="1" *) (* MFG_GMCREF_SEL="2" *)
EHXPLLL #(
        .PLLRST_ENA("DISABLED"),
        .INTFB_WAKE("DISABLED"),
        .STDBY_ENABLE("DISABLED"),
        .DPHASE_SOURCE("DISABLED"),
        .OUTDIVIDER_MUXA("DIVA"),
        .OUTDIVIDER_MUXB("DIVB"),
        .OUTDIVIDER_MUXC("DIVC"),
        .OUTDIVIDER_MUXD("DIVD"),
        .CLKI_DIV(1),
        .CLKOP_ENABLE("ENABLED"),
        .CLKOP_DIV(6),
        .CLKOP_CPHASE(2),
        .CLKOP_FPHASE(0),
        .FEEDBK_PATH("CLKOP"),
        .CLKFB_DIV(4)
    ) pll0 (
        .RST(1'b0),
        .STDBY(1'b0),
        .CLKI(clkin),
        .CLKOP(clk100),
        .CLKFB(clk100),
        .CLKINTFB(),
        .PHASESEL0(1'b0),
        .PHASESEL1(1'b0),
        .PHASEDIR(1'b1),
        .PHASESTEP(1'b1),
        .PHASELOADREG(1'b1),
        .PLLWAKESYNC(1'b0),
        .ENCLKOP(1'b0),
        .LOCK(locked0)
	);

(* FREQUENCY_PIN_CLKI="100" *)
(* FREQUENCY_PIN_CLKOP="12" *)
(* ICP_CURRENT="12" *) (* LPF_RESISTOR="8" *) (* MFG_ENABLE_FILTEROPAMP="1" *) (* MFG_GMCREF_SEL="2" *)
EHXPLLL #(
        .PLLRST_ENA("DISABLED"),
        .INTFB_WAKE("DISABLED"),
        .STDBY_ENABLE("DISABLED"),
        .DPHASE_SOURCE("DISABLED"),
        .OUTDIVIDER_MUXA("DIVA"),
        .OUTDIVIDER_MUXB("DIVB"),
        .OUTDIVIDER_MUXC("DIVC"),
        .OUTDIVIDER_MUXD("DIVD"),
        .CLKI_DIV(25),
        .CLKOP_ENABLE("ENABLED"),
        .CLKOP_DIV(50),
        .CLKOP_CPHASE(24),
        .CLKOP_FPHASE(0),
        .FEEDBK_PATH("CLKOP"),
        .CLKFB_DIV(3)
    ) pll1 (
        .RST(~locked0),
        .STDBY(1'b0),
        .CLKI(clk100),
        .CLKOP(clk12),
        .CLKFB(clk12),
        .CLKINTFB(),
        .PHASESEL0(1'b0),
        .PHASESEL1(1'b0),
        .PHASEDIR(1'b1),
        .PHASESTEP(1'b1),
        .PHASELOADREG(1'b1),
        .PLLWAKESYNC(1'b0),
        .ENCLKOP(1'b0),
        .LOCK(locked)
	);

endmodule
module top (
    input sys_clk,
    // input sys_resetn,
    // input s1,

    // UART
    input UART_RXD,
    output UART_TXD,

    // LEDs
    output led,
    output [15:0] leds,

    // USB
    inout usbdm,
    inout usbdp
);

wire sys_resetn;
wire clk_usb;
wire [1:0] usb_type;
wire [7:0] key_modifiers, key1, key2, key3, key4;
wire [7:0] mouse_btn;
wire signed [7:0] mouse_dx, mouse_dy;
wire [63:0] hid_report;
wire usb_report, usb_conerr, game_l, game_r, game_u, game_d, game_a, game_b, game_x, game_y;
wire game_sel, game_sta;
wire [13:0] dbg_pc;
wire [3:0] dbg_inst;

clock clock(
    .clkin(sys_clk),
    .clk12(clk_usb),       // 12Mhz usb clock
    .clk100(),
    .locked(sys_resetn)
);

usb_hid_host usb (
    .usbclk(clk_usb), .usbrst_n(sys_resetn),
    .usb_dm(usbdm), .usb_dp(usbdp),	
    .typ(usb_type), .report(usb_report),
    .key_modifiers(key_modifiers), .key1(key1), .key2(key2), .key3(key3), .key4(key4),
    .mouse_btn(mouse_btn), .mouse_dx(mouse_dx), .mouse_dy(mouse_dy),
    .game_l(game_l), .game_r(game_r), .game_u(game_u), .game_d(game_d),
    .game_a(game_a), .game_b(game_b), .game_x(game_x), .game_y(game_y), 
    .game_sel(game_sel), .game_sta(game_sta),
    .conerr(usb_conerr), .dbg_hid_report(hid_report)
);

hid_printer prt (
    .clk(clk_usb), .resetn(sys_resetn),
    .uart_tx(UART_TXD), .usb_type(usb_type), .usb_report(usb_report),
    .key_modifiers(key_modifiers), .key1(key1), .key2(key2), .key3(key3), .key4(key4),
    .mouse_btn(mouse_btn), .mouse_dx(mouse_dx), .mouse_dy(mouse_dy),
    .game_l(game_l), .game_r(game_r), .game_u(game_u), .game_d(game_d),
    .game_a(game_a), .game_b(game_b), .game_x(game_x), .game_y(game_y), 
    .game_sel(game_sel), .game_sta(game_sta)
);

reg report_toggle;      // blinks whenever there's a report
always @(posedge clk_usb) if (usb_report) report_toggle <= ~report_toggle;

assign led = report_toggle;
assign leds[7:0] = ~{6'b0, usb_type};
assign leds[15:8] = ~8'b0;

endmodule
module clock(
	input  clkin,
	output clk24,
	output locked
	);

SB_PLL40_CORE #(
		.FEEDBACK_PATH("SIMPLE"),
		.DIVR(4'b0000),		// DIVR =  0
		.DIVF(7'b0001111),	// DIVF = 15
		.DIVQ(3'b101),		// DIVQ =  5
		.FILTER_RANGE(3'b100)	// FILTER_RANGE = 4
	) uut (
		.LOCK(locked),
		.RESETB(1'b1),
		.BYPASS(1'b0),
		.REFERENCECLK(clkin),
		.PLLOUTCORE(clk24)
		);

endmodule
module top (
    input sys_clk,
    // input sys_resetn,
    // input s1,

    // UART
    input UART_RXD,
    output UART_TXD,

    // LEDs
    output led,

    // USB
    inout usbdm,
    inout usbdp
);

always @(posedge clk_24) begin
	clk_usb <= !clk_usb;
end

wire sys_resetn;
reg clk_usb;
wire clk_24;
wire [1:0] usb_type;
wire [7:0] key_modifiers, key1, key2, key3, key4;
wire [7:0] mouse_btn;
wire signed [7:0] mouse_dx, mouse_dy;
wire [63:0] hid_report;
wire usb_report, usb_conerr, game_l, game_r, game_u, game_d, game_a, game_b, game_x, game_y;
wire game_sel, game_sta;
wire [13:0] dbg_pc;
wire [3:0] dbg_inst;

clock clock(
    .clkin(sys_clk),
    .clk24(clk_24),
    .locked(sys_resetn)
);

usb_hid_host usb (
    .usbclk(clk_usb), .usbrst_n(sys_resetn),
    .usb_dm(usbdm), .usb_dp(usbdp),	
    .typ(usb_type), .report(usb_report),
    .key_modifiers(key_modifiers), .key1(key1), .key2(key2), .key3(key3), .key4(key4),
    .mouse_btn(mouse_btn), .mouse_dx(mouse_dx), .mouse_dy(mouse_dy),
    .game_l(game_l), .game_r(game_r), .game_u(game_u), .game_d(game_d),
    .game_a(game_a), .game_b(game_b), .game_x(game_x), .game_y(game_y), 
    .game_sel(game_sel), .game_sta(game_sta),
    .conerr(usb_conerr), .dbg_hid_report(hid_report)
);

hid_printer prt (
    .clk(clk_usb), .resetn(sys_resetn),
    .uart_tx(UART_TXD), .usb_type(usb_type), .usb_report(usb_report),
    .key_modifiers(key_modifiers), .key1(key1), .key2(key2), .key3(key3), .key4(key4),
    .mouse_btn(mouse_btn), .mouse_dx(mouse_dx), .mouse_dy(mouse_dy),
    .game_l(game_l), .game_r(game_r), .game_u(game_u), .game_d(game_d),
    .game_a(game_a), .game_b(game_b), .game_x(game_x), .game_y(game_y), 
    .game_sel(game_sel), .game_sta(game_sta)
);

reg report_toggle;      // blinks whenever there's a report
always @(posedge clk_usb) if (usb_report) report_toggle <= ~report_toggle;

assign led = report_toggle;
//assign leds[7:0] = ~{6'b0, usb_type};
//assign leds[15:8] = ~8'b0;

endmodule
module top (
    input sys_clk,
    input sys_resetn,
    // input s1,

    // UART
    input UART_RXD,
    output UART_TXD,

    // LEDs
    output led,

    // USB
    inout usbdm,
    inout usbdp
);

wire [1:0] usb_type;
wire [7:0] key_modifiers, key1, key2, key3, key4;
wire [7:0] mouse_btn;
wire signed [7:0] mouse_dx, mouse_dy;
wire [63:0] hid_report;
wire usb_report, usb_conerr, game_l, game_r, game_u, game_d, game_a, game_b, game_x, game_y;
wire game_sel, game_sta;
wire [13:0] dbg_pc;
wire [3:0] dbg_inst;

usb_hid_host usb (
    .usbclk(sys_clk), .usbrst_n(sys_resetn),
    .usb_dm(usbdm), .usb_dp(usbdp),	
    .typ(usb_type), .report(usb_report),
    .key_modifiers(key_modifiers), .key1(key1), .key2(key2), .key3(key3), .key4(key4),
    .mouse_btn(mouse_btn), .mouse_dx(mouse_dx), .mouse_dy(mouse_dy),
    .game_l(game_l), .game_r(game_r), .game_u(game_u), .game_d(game_d),
    .game_a(game_a), .game_b(game_b), .game_x(game_x), .game_y(game_y), 
    .game_sel(game_sel), .game_sta(game_sta),
    .conerr(usb_conerr), .dbg_hid_report(hid_report)
);

hid_printer prt (
    .clk(sys_clk), .resetn(sys_resetn),
    .uart_tx(UART_TXD), .usb_type(usb_type), .usb_report(usb_report),
    .key_modifiers(key_modifiers), .key1(key1), .key2(key2), .key3(key3), .key4(key4),
    .mouse_btn(mouse_btn), .mouse_dx(mouse_dx), .mouse_dy(mouse_dy),
    .game_l(game_l), .game_r(game_r), .game_u(game_u), .game_d(game_d),
    .game_a(game_a), .game_b(game_b), .game_x(game_x), .game_y(game_y), 
    .game_sel(game_sel), .game_sta(game_sta)
);

reg report_toggle;      // blinks whenever there's a report
always @(posedge sys_clk) if (usb_report) report_toggle <= ~report_toggle;

assign led = report_toggle;
//assign leds[7:0] = ~{6'b0, usb_type};
//assign leds[15:8] = ~8'b0;

endmodule
module gowin_pll_usb (clkout, clkoutp, lock, reset, clkin);

output clkout;
output clkoutp;
output lock;
input reset;
input clkin;

wire clkoutd_o;
wire clkoutd3_o;
wire gw_gnd;

assign gw_gnd = 1'b0;

rPLL rpll_inst (
    .CLKOUT(clkout),
    .LOCK(lock),
    .CLKOUTP(clkoutp),
    .CLKOUTD(clkoutd_o),
    .CLKOUTD3(clkoutd3_o),
    .RESET(reset),
    .RESET_P(gw_gnd),
    .CLKIN(clkin),
    .CLKFB(gw_gnd),
    .FBDSEL({gw_gnd,gw_gnd,gw_gnd,gw_gnd,gw_gnd,gw_gnd}),
    .IDSEL({gw_gnd,gw_gnd,gw_gnd,gw_gnd,gw_gnd,gw_gnd}),
    .ODSEL({gw_gnd,gw_gnd,gw_gnd,gw_gnd,gw_gnd,gw_gnd}),
    .PSDA({gw_gnd,gw_gnd,gw_gnd,gw_gnd}),
    .DUTYDA({gw_gnd,gw_gnd,gw_gnd,gw_gnd}),
    .FDLY({gw_gnd,gw_gnd,gw_gnd,gw_gnd})
);

// 27 -> 12 Mhz low-speed USB clock
defparam rpll_inst.FCLKIN = "27";
defparam rpll_inst.IDIV_SEL = 8;
defparam rpll_inst.FBDIV_SEL = 3;
defparam rpll_inst.ODIV_SEL = 64;

defparam rpll_inst.DYN_IDIV_SEL = "false";
defparam rpll_inst.DYN_FBDIV_SEL = "false";
defparam rpll_inst.DYN_ODIV_SEL = "false";
defparam rpll_inst.PSDA_SEL = "1000";
defparam rpll_inst.DYN_DA_EN = "false";
defparam rpll_inst.DUTYDA_SEL = "1000";
defparam rpll_inst.CLKOUT_FT_DIR = 1'b1;
defparam rpll_inst.CLKOUTP_FT_DIR = 1'b1;
defparam rpll_inst.CLKOUT_DLY_STEP = 0;
defparam rpll_inst.CLKOUTP_DLY_STEP = 0;
defparam rpll_inst.CLKFB_SEL = "internal";
defparam rpll_inst.CLKOUT_BYPASS = "false";
defparam rpll_inst.CLKOUTP_BYPASS = "false";
defparam rpll_inst.CLKOUTD_BYPASS = "false";
defparam rpll_inst.DYN_SDIV_SEL = 2;
defparam rpll_inst.CLKOUTD_SRC = "CLKOUT";
defparam rpll_inst.CLKOUTD3_SRC = "CLKOUT";
defparam rpll_inst.DEVICE = "GW2AR-18";

endmodule //Gowin_rPLL
module complex_propagation(input x, input y, output o);
    wire w1;
    wire w2;
    
    LOGIC1_X1 _01_ (w1);
    LOGIC0_X1 _02_ (w2);

    simple_module1 _03_ (x, y, w1, w2, o);
endmodule
module simple_module1(input x, input y, input z1, input z2, output o);
    wire o1;
    wire o2;

    simple_module2 _01_ (x, z1, o1);
    simple_module3 _02_ (y, z2, o1, o2);
    simple_module4 _03_ (o2, z1, o);
endmodule
module simple_module2(input x, input y, output o);
    AND2_X1 _02_(x, y, o);
endmodule
module simple_module3(input x, input y, input z, output o);
    AND3_X1 _02_(x, y, z, o);
endmodule
module simple_module4(input x, input y, output o);
    wire w1;
    simple_module5 _01_(x, y, w1);
    OR2_X1 _02_(x, w1, o);
endmodule
module simple_module5(input x, input y, output o);
    OR2_X1 _02_(x, y, o);
endmodule
module simple_propagation(input x, input y, output o);
    wire w1;
    LOGIC1_X1 _01_ (w1);
    simple_module mod(x, y, w1, o);
endmodule
module simple_module(input x, input y, input z, output o);
    wire o1;
    AND2_X1 _01_ (x, y, o1);
    OR2_X1 _02_(o1, z, o);
endmodule
module loaded (
	in1, 
	in2,
	clk,
	out
);
	input in1;
	input in2;
	input clk;
	output [15: 0] out;

	AND2_X1 g1(
		.A1(in1),
		.A2(in2), 
		.ZN(g1z)
	);
	AND2_X1 g2(
		.A1(in1),
		.A2(in2), 
		.ZN(g2z)
	);

	AND2_X1 g3(
		.A1(g1z),
		.A2(g2z), 
		.ZN(g3z)
	);

	DFF_X1 r1 (
		.Q(out[0]),
		.D(g3z),
		.CK(clk)
	);
	DFF_X1 r2 (
		.Q(out[1]),
		.D(g3z),
		.CK(clk)
	);
	DFF_X1 r3 (
		.Q(out[2]),
		.D(g3z),
		.CK(clk)
	);
	DFF_X1 r4 (
		.Q(out[3]),
		.D(g3z),
		.CK(clk)
	);
	DFF_X1 r5 (
		.Q(out[4]),
		.D(g3z),
		.CK(clk)
	);
	DFF_X1 r6 (
		.Q(out[5]),
		.D(g3z),
		.CK(clk)
	);
	DFF_X1 r7 (
		.Q(out[6]),
		.D(g3z),
		.CK(clk)
	);
	DFF_X1 r8 (
		.Q(out[7]),
		.D(g3z),
		.CK(clk)
	);
	DFF_X1 r9 (
		.Q(out[8]),
		.D(g3z),
		.CK(clk)
	);
	DFF_X1 r10 (
		.Q(out[9]),
		.D(g3z),
		.CK(clk)
	);
	DFF_X1 r11 (
		.Q(out[10]),
		.D(g3z),
		.CK(clk)
	);
	DFF_X1 r12 (
		.Q(out[11]),
		.D(g3z),
		.CK(clk)
	);
	DFF_X1 r13 (
		.Q(out[12]),
		.D(g3z),
		.CK(clk)
	);
	DFF_X1 r14 (
		.Q(out[13]),
		.D(g3z),
		.CK(clk)
	);
	DFF_X1 r15 (
		.Q(out[14]),
		.D(g3z),
		.CK(clk)
	);
	DFF_X1 r16 (
		.Q(out[15]),
		.D(g3z),
		.CK(clk)
	);
endmodule
module Constants(input clock, input [5:0] io_wide_bus, output reduced, output [2: 0] out);

  reg reduce_it;
  assign reduced = reduce_it;

  AndOr mod(reduce_it, 1'b0, 1'b1, out[0], out[1], out[2]);
  
  always @(posedge clock) begin
    reduce_it = |io_wide_bus;
  end
endmodule
module AndOr(input a, input b, input c, output d, output e, output f);
    AndModule x(a, b, d);
    OrWrapper y(b, c, e, h);
    OrModule  z(1'b1, h, f);
endmodule
module AndModule(input a, input b, output c);
    assign c = a & b;
endmodule
module OrWrapper(input a, input b, output c, output d);
    OrModule z(a, b, c);
    assign d = ~a | b;
endmodule
module OrModule(input a, input b, output c);
    assign c = a | b;
endmodule
module xc_rf_fwd_4 (

input  wire        clock        ,
input  wire        resetn       ,
           
input  wire [ 4:0] rs1_addr     ,
output wire [31:0] rs1_rdata    ,
           
input  wire [ 4:0] rs2_addr     ,
output wire [31:0] rs2_rdata    ,
           
input  wire        fwd_0_wen    ,
input  wire        fwd_0_wide   ,
input  wire [ 4:0] fwd_0_addr   ,
input  wire [31:0] fwd_0_wdata  ,
input  wire [31:0] fwd_0_wdata_hi,

input  wire        fwd_1_wen    ,
input  wire        fwd_1_wide   ,
input  wire [ 4:0] fwd_1_addr   ,
input  wire [31:0] fwd_1_wdata  , 
input  wire [31:0] fwd_1_wdata_hi,
           
input  wire        rd_wen       ,
input  wire        rd_wide      ,
input  wire [ 4:0] rd_addr      ,
input  wire [31:0] rd_wdata     ,
input  wire [31:0] rd_wdata_hi   

);

wire [31:0] gpr_rs1_rdata  ;
wire [31:0] gpr_rs2_rdata  ;

wire [31:0] fwd_0_d = fwd_0_addr[0] ? fwd_0_wdata_hi : fwd_0_wdata;
wire [31:0] fwd_1_d = fwd_1_addr[0] ? fwd_1_wdata_hi : fwd_1_wdata;
wire [31:0] fwd_gpr = rd_addr   [0] ? rd_wdata_hi    : rd_wdata   ;

wire    fwd_rs1_0 = rs1_addr[4:1] == fwd_0_addr[4:1] && |rs1_addr;
wire    fwd_rs2_0 = rs2_addr[4:1] == fwd_0_addr[4:1] && |rs2_addr;

wire    fwd_rs1_1 = rs1_addr[4:1] == fwd_1_addr[4:1] && |rs1_addr;
wire    fwd_rs2_1 = rs2_addr[4:1] == fwd_1_addr[4:1] && |rs2_addr;

wire    fwd_rs1_g = rs1_addr == rd_addr    && |rs1_addr;
wire    fwd_rs2_g = rs2_addr == rd_addr    && |rs2_addr;

assign rs1_rdata = fwd_rs1_0 ? fwd_0_d          :
                   fwd_rs1_1 ? fwd_1_d          :
                   fwd_rs1_g ? fwd_gpr          :
                               gpr_rs1_rdata    ;


assign rs2_rdata = fwd_rs2_0 ? fwd_0_d          :
                   fwd_rs2_1 ? fwd_1_d          :
                   fwd_rs2_g ? fwd_gpr          :
                               gpr_rs2_rdata    ;

xc_rf_4 i_xc_rf_4(
.clock      (clock          ),
.resetn     (resetn         ),
.rs1_addr   (rs1_addr       ),
.rs1_rdata  (gpr_rs1_rdata  ),
.rs2_addr   (rs2_addr       ),
.rs2_rdata  (gpr_rs2_rdata  ),
.rd_wen     (rd_wen         ),
.rd_wide    (rd_wide        ),
.rd_addr    (rd_addr        ),
.rd_wdata   (rd_wdata       ),
.rd_wdata_hi(rd_wdata_hi    )
);

endmodule
module xc_rf_fwd_2 (

input  wire        clock      ,
input  wire        resetn     ,
           
input  wire [ 4:0] rs1_addr   ,
output wire [31:0] rs1_rdata  ,
           
input  wire [ 4:0] rs2_addr   ,
output wire [31:0] rs2_rdata  ,
           
input  wire [ 4:0] rs3_addr   ,
output wire [31:0] rs3_rdata  ,

input  wire        fwd_0_wen  ,
input  wire [ 4:0] fwd_0_addr ,
input  wire [31:0] fwd_0_wdata,

input  wire        fwd_1_wen  ,
input  wire [ 4:0] fwd_1_addr ,
input  wire [31:0] fwd_1_wdata, 
           
input  wire        rd_wen     ,
input  wire [ 4:0] rd_addr    ,
input  wire [31:0] rd_wdata    

);

wire [31:0] gpr_rs1_rdata  ;
wire [31:0] gpr_rs2_rdata  ;
wire [31:0] gpr_rs3_rdata  ;

wire    fwd_rs1_0 = rs1_addr == fwd_0_addr && |rs1_addr;
wire    fwd_rs2_0 = rs2_addr == fwd_0_addr && |rs2_addr;
wire    fwd_rs3_0 = rs3_addr == fwd_0_addr && |rs3_addr;

wire    fwd_rs1_1 = rs1_addr == fwd_1_addr && |rs1_addr;
wire    fwd_rs2_1 = rs2_addr == fwd_1_addr && |rs2_addr;
wire    fwd_rs3_1 = rs3_addr == fwd_1_addr && |rs3_addr;

wire    fwd_rs1_g = rs1_addr == rd_addr    && |rs1_addr;
wire    fwd_rs2_g = rs2_addr == rd_addr    && |rs2_addr;
wire    fwd_rs3_g = rs3_addr == rd_addr    && |rs3_addr;

assign rs1_rdata = fwd_rs1_0 ? fwd_0_wdata      :
                   fwd_rs1_1 ? fwd_1_wdata      :
                   fwd_rs1_g ? rd_wdata         :
                               gpr_rs1_rdata    ;


assign rs2_rdata = fwd_rs2_0 ? fwd_0_wdata      :
                   fwd_rs2_1 ? fwd_1_wdata      :
                   fwd_rs2_g ? rd_wdata         :
                               gpr_rs2_rdata    ;

assign rs3_rdata = fwd_rs3_0 ? fwd_0_wdata      :
                   fwd_rs3_1 ? fwd_1_wdata      :
                   fwd_rs3_g ? rd_wdata         :
                               gpr_rs3_rdata    ;

xc_rf_2 i_xc_rf_2(
.clock      (clock          ),
.resetn     (resetn         ),
.rs1_addr   (rs1_addr       ),
.rs1_rdata  (gpr_rs1_rdata  ),
.rs2_addr   (rs2_addr       ),
.rs2_rdata  (gpr_rs2_rdata  ),
.rs3_addr   (rs3_addr       ),
.rs3_rdata  (gpr_rs3_rdata  ),
.rd_wen     (rd_wen         ),
.rd_addr    (rd_addr        ),
.rd_wdata   (rd_wdata       ) 
);

endmodule
module xc_rf_fwd_0 (

input  wire        clock      ,
input  wire        resetn     ,
           
input  wire [ 4:0] rs1_addr   ,
output wire [31:0] rs1_rdata  ,
           
input  wire [ 4:0] rs2_addr   ,
output wire [31:0] rs2_rdata  ,

input  wire        fwd_0_wen  ,
input  wire [ 4:0] fwd_0_addr ,
input  wire [31:0] fwd_0_wdata,

input  wire        fwd_1_wen  ,
input  wire [ 4:0] fwd_1_addr ,
input  wire [31:0] fwd_1_wdata, 
           
input  wire        rd_wen     ,
input  wire [ 4:0] rd_addr    ,
input  wire [31:0] rd_wdata    

);

wire [31:0] gpr_rs1_rdata  ;
wire [31:0] gpr_rs2_rdata  ;

wire    fwd_rs1_0 = rs1_addr == fwd_0_addr && |rs1_addr;
wire    fwd_rs2_0 = rs2_addr == fwd_0_addr && |rs2_addr;

wire    fwd_rs1_1 = rs1_addr == fwd_1_addr && |rs1_addr;
wire    fwd_rs2_1 = rs2_addr == fwd_1_addr && |rs2_addr;

wire    fwd_rs1_g = rs1_addr == rd_addr    && |rs1_addr;
wire    fwd_rs2_g = rs2_addr == rd_addr    && |rs2_addr;

assign rs1_rdata = fwd_rs1_0 ? fwd_0_wdata      :
                   fwd_rs1_1 ? fwd_1_wdata      :
                   fwd_rs1_g ? rd_wdata         :
                               gpr_rs1_rdata    ;


assign rs2_rdata = fwd_rs2_0 ? fwd_0_wdata      :
                   fwd_rs2_1 ? fwd_1_wdata      :
                   fwd_rs2_g ? rd_wdata         :
                               gpr_rs2_rdata    ;

xc_rf_0 i_xc_rf_0(
.clock      (clock          ),
.resetn     (resetn         ),
.rs1_addr   (rs1_addr       ),
.rs1_rdata  (gpr_rs1_rdata  ),
.rs2_addr   (rs2_addr       ),
.rs2_rdata  (gpr_rs2_rdata  ),
.rd_wen     (rd_wen         ),
.rd_addr    (rd_addr        ),
.rd_wdata   (rd_wdata       ) 
);

endmodule
module xc_rf_fwd_1 (

input  wire        clock      ,
input  wire        resetn     ,
           
input  wire [ 4:0] rs1_addr   ,
output wire [31:0] rs1_rdata  ,
           
input  wire [ 4:0] rs2_addr   ,
output wire [31:0] rs2_rdata  ,
           
input  wire [ 4:0] rs3_addr   ,
output wire [31:0] rs3_rdata  ,

input  wire        fwd_0_wen  ,
input  wire [ 4:0] fwd_0_addr ,
input  wire [31:0] fwd_0_wdata,

input  wire        fwd_1_wen  ,
input  wire [ 4:0] fwd_1_addr ,
input  wire [31:0] fwd_1_wdata, 
           
input  wire        rd_wen     ,
input  wire [ 4:0] rd_addr    ,
input  wire [31:0] rd_wdata    

);

wire [31:0] gpr_rs1_rdata  ;
wire [31:0] gpr_rs2_rdata  ;
wire [31:0] gpr_rs3_rdata  ;

wire    fwd_rs1_0 = rs1_addr == fwd_0_addr && |rs1_addr;
wire    fwd_rs2_0 = rs2_addr == fwd_0_addr && |rs2_addr;
wire    fwd_rs3_0 = rs3_addr == fwd_0_addr && |rs3_addr;

wire    fwd_rs1_1 = rs1_addr == fwd_1_addr && |rs1_addr;
wire    fwd_rs2_1 = rs2_addr == fwd_1_addr && |rs2_addr;
wire    fwd_rs3_1 = rs3_addr == fwd_1_addr && |rs3_addr;

wire    fwd_rs1_g = rs1_addr == rd_addr    && |rs1_addr;
wire    fwd_rs2_g = rs2_addr == rd_addr    && |rs2_addr;
wire    fwd_rs3_g = rs3_addr == rd_addr    && |rs3_addr;

assign rs1_rdata = fwd_rs1_0 ? fwd_0_wdata      :
                   fwd_rs1_1 ? fwd_1_wdata      :
                   fwd_rs1_g ? rd_wdata         :
                               gpr_rs1_rdata    ;


assign rs2_rdata = fwd_rs2_0 ? fwd_0_wdata      :
                   fwd_rs2_1 ? fwd_1_wdata      :
                   fwd_rs2_g ? rd_wdata         :
                               gpr_rs2_rdata    ;

assign rs3_rdata = fwd_rs3_0 ? fwd_0_wdata      :
                   fwd_rs3_1 ? fwd_1_wdata      :
                   fwd_rs3_g ? rd_wdata         :
                               gpr_rs3_rdata    ;

xc_rf_1 i_xc_rf_1(
.clock      (clock          ),
.resetn     (resetn         ),
.rs1_addr   (rs1_addr       ),
.rs1_rdata  (gpr_rs1_rdata  ),
.rs2_addr   (rs2_addr       ),
.rs2_rdata  (gpr_rs2_rdata  ),
.rs3_addr   (rs3_addr       ),
.rs3_rdata  (gpr_rs3_rdata  ),
.rd_wen     (rd_wen         ),
.rd_addr    (rd_addr        ),
.rd_wdata   (rd_wdata       ) 
);

endmodule