dakies/OSS_Verilog huggingface dataset:
module oh_fifo_cdc
  #(parameter N      = 32,           // fifo width
    parameter DEPTH  = 32,           // fifo depth
    parameter TARGET = "DEFAULT",    // synthesis/sim target
    parameter AW     = $clog2(DEPTH) // rd_count width (derived)
    )
   (
    input 	   nreset,     // async active low reset
    //Write Side
    input 	   clk_in,     // write clock
    input 	   valid_in,   // write valid
    input [N-1:0]  packet_in,  // write packet
    output 	   ready_out,  // write pushback
    //Read Side
    input 	   clk_out,    // read clock
    output reg 	   valid_out,  // read valid
    output [N-1:0] packet_out, // read packet
    input 	   ready_in,   // read pushback
    //Status
    output 	   prog_full, // fifo is half full
    output 	   full,      // fifo is full
    output 	   empty      // fifo is empty
    );

   // wire declarations
   wire   wr_en;
   wire   rd_en;
   wire   wr_almost_full;
   wire   wr_full;
   wire   wr_prog_full;
   wire   nreset_out;

   // FIFO control logic
   assign wr_en    = valid_in;
   assign rd_en    = ~empty & ready_in;
   assign ready_out = ~(wr_almost_full | wr_full | wr_prog_full);

   //async asser, sync deassert of reset
   oh_rsync #(.TARGET(TARGET))
   sync_reset(.nrst_out  (nreset_out),
              .clk       (clk_out),
              .nrst_in   (nreset));

   //align valid signal with FIFO read delay
   always @ (posedge clk_out or negedge nreset_out)
     if(!nreset_out)
       valid_out <= 1'b0;
     else if(ready_in)
       valid_out <= rd_en;

   // parametric async fifo
   oh_fifo_async  #(.TARGET(TARGET),
		    .DEPTH(DEPTH),
		    .N(N))
   oh_fifo_async (.rd_clk		(clk_out),
		  .rd_dout		(packet_out[N-1:0]),
		  .wr_clk		(clk_in),
		  .wr_din		(packet_in[N-1:0]),
		  .wr_count		(),
		  .rd_count		(),
		  .rd_empty		(empty),
		  /*AUTOINST*/
		  // Outputs
		  .wr_full		(wr_full),
		  .wr_almost_full	(wr_almost_full),
		  .wr_prog_full		(wr_prog_full),
		  // Inputs
		  .nreset		(nreset),
		  .wr_en		(wr_en),
		  .rd_en		(rd_en));

endmodule // oh_fifo_cdc
module oh_dpram
  #(parameter N       = 32,           // FIFO width
    parameter DEPTH   = 32,           // FIFO depth
    parameter REG     = 1,            // Register fifo output
    parameter TARGET  = "DEFAULT",    // pass through variable for hard macro
    parameter SHAPE   = "SQUARE",     // hard macro shape (square, tall, wide)
    parameter AW      = $clog2(DEPTH) // rd_count width (derived)
    )
   (// Memory interface (dual port)
    input 	   wr_clk, //write clock
    input 	   wr_en, //write enable
    input [N-1:0]  wr_wem, //per bit write enable
    input [AW-1:0] wr_addr,//write address
    input [N-1:0]  wr_din, //write data
    input 	   rd_clk, //read clock
    input 	   rd_en, //read enable
    input [AW-1:0] rd_addr,//read address
    output [N-1:0] rd_dout,//read output data
    // BIST interface
    input 	   bist_en, // bist enable
    input 	   bist_we, // write enable global signal
    input [N-1:0]  bist_wem, // write enable vector
    input [AW-1:0] bist_addr, // address
    input [N-1:0]  bist_din, // data input
    // Power/repair (hard macro only)
    input 	   shutdown, // shutdown signal
    input 	   vss, // ground signal
    input 	   vdd, // memory array power
    input 	   vddio, // periphery/io power
    input [7:0]    memconfig, // generic memory config
    input [7:0]    memrepair // repair vector
    );

   generate
      if(TARGET == "DEFAULT") begin
	 //#########################################
	 // Generic RAM for synthesis
	 //#########################################
	 //local variables
	 reg [N-1:0]        ram    [0:DEPTH-1];
	 wire [N-1:0] 	    rdata;
	 integer 	    i;

	 //write port
	 always @(posedge wr_clk)
	   for (i=0;i<N;i=i+1)
	     if (wr_en & wr_wem[i])
               ram[wr_addr[AW-1:0]][i] = wr_din[i];

	 //read port
	 assign rdata[N-1:0] = ram[rd_addr[AW-1:0]];

	 //Configurable output register
	 reg [N-1:0] 	     rd_reg;
	 always @ (posedge rd_clk)
	   if(rd_en)
	     rd_reg[N-1:0] <= rdata[N-1:0];

	 //Drive output from register or RAM directly
	 assign rd_dout[N-1:0] = (REG==1) ? rd_reg[N-1:0] : rdata[N-1:0];
      end // block: soft
      else begin
	 asic_memory_dp #(.N(N),
			  .DEPTH(DEPTH),
			  .SHAPE(SHAPE),
			  .REG(REG))
	 asic_memory_dp ();
      end // block: hard
   endgenerate
endmodule // oh_memory_dp
module oh_mx2 #(parameter DW = 1 ) // array width
   (
    input [DW-1:0]  d0,
    input [DW-1:0]  d1,
    input [DW-1:0]  s,
    output [DW-1:0] z
    );
   
   assign z = (d0 & ~s) | (d1 & s);
   
endmodule
module oh_xnor4 #(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_sdffrq #(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] q
    );
   
   always @ (posedge clk or negedge nreset)
     if(!nreset)
       q <= 'b0;
     else
       q <= se ? si : d;
      
endmodule
module oh_regfile
  # (parameter REGS  = 8,          // number of registeres
     parameter RW    = 16,         // register width
     parameter RP    = 5,          // read ports
     parameter WP    = 3,          // write prots
     parameter RAW   = $clog2(REGS)// (derived) rf addr width
     )
   (//Control inputs
    input 	       clk,
    // Write Ports (concatenated)
    input [WP-1:0]     wr_valid, // write access
    input [WP*RAW-1:0] wr_addr, // register address
    input [WP*RW-1:0]  wr_data, // write data
    // Read Ports (concatenated)
    input [RP-1:0]     rd_valid, // read access
    input [RP*RAW-1:0] rd_addr, // register address
    output [RP*RW-1:0] rd_data // output data
    );


   reg [RW-1:0]        mem[0:REGS-1];
   wire [WP-1:0]       write_en [0:REGS-1];
   wire [RW-1:0]       datamux [0:REGS-1];

   genvar 	       i,j;

   //TODO: Make an array of cells

   //#########################################
   // write ports
   //#########################################

   //One hote write enables
   for(i=0;i<REGS;i=i+1)
     begin: gen_regwrite
	for(j=0;j<WP;j=j+1)
	  begin: gen_wp
	     assign write_en[i][j] = wr_valid[j] & (wr_addr[j*RAW+:RAW] == i);
	  end
     end

   //Multi Write-Port Mux
   for(i=0;i<REGS;i=i+1)
     begin: gen_wrmux
	oh_mux #(.N(RW), .M(WP))
	iwrmux(.out (datamux[i][RW-1:0]),
	       .sel (write_en[i][WP-1:0]),
	       .in  (wr_data[WP*RW-1:0]));
     end

   //Memory Array Write
   for(i=0;i<REGS;i=i+1)
     begin: gen_reg
	always @ (posedge clk)
	  if (|write_en[i][WP-1:0])
	    mem[i] <= datamux[i];
end


   //#########################################
   // read ports
   //#########################################

   for (i=0;i<RP;i=i+1) begin: gen_rdport
      assign rd_data[i*RW+:RW] = {(RW){rd_valid[i]}} &
				mem[rd_addr[i*RAW+:RAW]];
   end

endmodule // oh_regfile
module oh_pwr_buf #( parameter N = 1) // width of data inputs
 (
  input 	 vdd, // supply (set to 1 if valid)
  input 	 vss, // ground (set to 0 if valid)
  input [N-1:0]  in, // input signal
  output [N-1:0] out    // buffered output signal
  );

`ifdef TARGET_SIM
   assign out[N-1:0] = ((vdd===1'b1) && (vss===1'b0)) ? in[N-1:0]:
		       {(N){1'bX}};
`else
   assign out[N-1:0] = in[N-1:0];
`endif


endmodule // oh_pwr_buf
module oh_sdffsqn #(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] 	nset,
    output reg [DW-1:0] qn
    );
   
   always @ (posedge clk or negedge nset)
     if(!nset)
       qn <= 'b0;   
     else
       qn <= se ? ~si : ~d;
   
endmodule
module oh_dffnq #(parameter DW = 1) // array width
   (
    input [DW-1:0] 	d,
    input [DW-1:0] 	clk,
    output reg [DW-1:0] q
    );
   
   always @ (negedge clk)
     q <= d;
      
endmodule
module oh_mux7 #(parameter N = 1 ) // width of mux
   (
    input 	    sel6,
    input 	    sel5,
    input 	    sel4,
    input 	    sel3,
    input 	    sel2,
    input 	    sel1,
    input 	    sel0,
    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]);


endmodule // oh_mux7
module oh_oai32 #(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_oddr
  #(parameter N    =  1,       // vector width
    parameter SYN  = "TRUE",   // synthesizable (or not)
    parameter TYPE = "DEFAULT" // scell type/size
    )
   (
    input 	   clk, // clock input
    input [N-1:0]  in1, // negedge input
    input [N-1:0]  in2, // posedge input
    output [N-1:0] out  // ddr output
    );

   generate
      if(SYN == "TRUE") begin
	 //regs("sl"=stable low, "sh"=stable high)
	 reg [N-1:0]     in2_sh;

	 always @ (negedge clk)
	   in2_sh[N-1:0] <= in2[N-1:0];

	 assign out[N-1:0] = ~clk ? in1[N-1:0] : in2_sh[N-1:0];
      end
      else begin
	 for (i=0;i<N;i=i+1) begin
	    asic_oddr #(.TYPE(TYPE))
	    asic_oddr(// Outputs
		      .out		(out[N-1:0]),
		      // Inputs
		      .clk		(clk),
		      .in1		(in1[N-1:0]),
		      .in2		(in2[N-1:0]));
	 end
      end // else: !if(SYN == "TRUE")
   endgenerate

endmodule // oh_oddr
module oh_xnor3 #(parameter DW = 1 ) // array width
   (
    input [DW-1:0]  a,
    input [DW-1:0]  b,
    input [DW-1:0]  c,
    output [DW-1:0] z
    );
   
   assign z =  ~(a ^ b ^ c);
   
endmodule
module oh_iddr
  #(parameter N    = 1,        // vector width
    parameter SYN  = "TRUE",   // synthesizable (or not)
    parameter TYPE = "DEFAULT" // scell type/size
    )
   (
    input 		 clk, // clock
    input 		 en0, // 1st cycle enable
    input 		 en1, // 2nd cycle enable
    input [N-1:0] 	 in, // data input sampled on both edges of clock
    output reg [2*N-1:0] out // iddr aligned
    );

   generate
      if(SYN == "TRUE") begin

	 //regs("sl"=stable low, "sh"=stable high)
	 reg [N-1:0]     in_sl;
	 reg [N-1:0] 	 in_sh;
	 reg 		 en0_negedge;

	 //########################
	 // Pipeline valid for negedge
	 //########################
	 always @ (negedge clk)
	   en0_negedge <= en0;

	 //########################
	 // Dual edge sampling
	 //########################

	 always @ (posedge clk)
	   if(en0)
	     in_sl[N-1:0] <= in[N-1:0];
	 always @ (negedge clk)
	   if(en0_negedge)
	     in_sh[N-1:0] <= in[N-1:0];

	 //########################
	 // Aign pipeline
	 //########################
	 always @ (posedge clk)
	   if(en1)
	     out[2*N-1:0] <= {in_sh[N-1:0],
			      in_sl[N-1:0]};

      end
      else begin
	 for (i=0;i<N;i=i+1) begin
	    asic_iddr #(.TYPE(TYPE))
	    asic_iddr(// Outputs
		      .out	(out[2*N-1:0]),
		      // Inputs
		      .clk	(clk),
		      .en0	(en0),
		      .en1	(en1),
		      .in	(in[N-1:0]));
	 end
      end
   endgenerate

endmodule // oh_iddr
module oh_or3 #(parameter DW = 1 ) // array width
   (
    input [DW-1:0]  a,
    input [DW-1:0]  b,
    input [DW-1:0]  c,
    output [DW-1:0] z
    );
   
   assign z = a | b | c ;
   
endmodule
module oh_oa31 #(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_dffsq #(parameter DW = 1) // array width
   (
    input [DW-1:0]     d,
    input [DW-1:0]     clk,
    input [DW-1:0]     nset,
    output reg [DW-1:0] q
    );
   
   always @ (posedge clk or negedge nset)
     if(!nset)
       q <= {DW{1'b1}};
     else
       q <= d;
      
endmodule
module oh_dffrq #(parameter DW = 1) // array width
   (
    input [DW-1:0] 	d,
    input [DW-1:0] 	clk,
    input [DW-1:0] 	nreset,
    output reg [DW-1:0] q
    );
   
   always @ (posedge clk or negedge nreset)
     if(!nreset)
       q <= 'b0;
     else
       q <= d;
      
endmodule
module oh_oa21 #(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_csa42
  #(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 	    cin,  // intra stage carry in
     output 	    cout, // intra stage carry out (2x sum)
     output [N-1:0] s,    // sum
     output [N-1:0] c     // carry (=2x sum)
     );

   generate
      if(SYN == "TRUE") begin

	 wire [N-1:0]     sum_int;
	 wire [N:0] 	  carry_int;

	 //Edges
	 assign carry_int[0] = cin;
	 assign cout         = carry_int[N];

	 //Full Adders
	 oh_csa32 #(.N(N))
	 fa0 (//inputs
	      .in0(in0[N-1:0]),
	      .in1(in1[N-1:0]),
	      .in2(in2[N-1:0]),
	      //outputs
	      .c(carry_int[N:1]),
	      .s(sum_int[N-1:0]));

	 oh_csa32 #(.N(N))
	 fa1 (//inputs
	      .in0(in3[N-1:0]),
	      .in1(sum_int[N-1:0]),
	      .in2(carry_int[N-1:0]),
	      //outputs
	      .c(c[N-1:0]),
	      .s(s[N-1:0]));
      end
      else begin

	 wire [N-1:0] carry_out;
	 wire [N-1:0] carry_in;

	 assign carry_in[N-1:0] = {carry_out[N-1:1],cin};

	 for (i=1;i<N;i=i+1) begin
	    asic_csa42 #(.TYPE(TYPE))
	    asic_csa42(// Outputs
		       .cout	(carry_out[i]),
		       .s	(s[i]),
		       .c	(c[i]),
		       // Inputs
		       .in0	(in0[i]),
		       .in1	(in1[i]),
		       .in2	(in2[i]),
		       .in3	(in3[i]),
		       .cin	({carry_in[i]}));
	 end

	 assign cout = carry[N-1];

      end
   endgenerate
endmodule // oh_csa42
module oh_aoi222 #(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_nand4 #(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_rsync
  #(parameter SYNCPIPE = 2,        // number of sync stages
    parameter TARGET   = "DEFAULT" // scell type/size
    )
   (
    input  clk,
    input  nrst_in,
    output nrst_out
    );

   generate
      if(TARGET == "DEFAULT")
	begin
	   reg [SYNCPIPE-1:0] sync_pipe;
	   always @ (posedge clk or negedge nrst_in)
	     if(!nrst_in)
	       sync_pipe[SYNCPIPE-1:0] <= 'b0;
	     else
	       sync_pipe[SYNCPIPE-1:0] <= {sync_pipe[SYNCPIPE-2:0],1'b1};
	   assign nrst_out = sync_pipe[SYNCPIPE-1];
	end
      else
	begin
	   asic_rsync #(.TARGET(TARGET),
			.SYNCPIPE(SYNCPIPE))
	   asic_rsync (.clk(clk),
		       .nrst_in(nrst_in),
		       .nrst_out(nrst_out));
	end
   endgenerate
endmodule // oh_rsync
module oh_7seg_decode
  (
    input [3:0] bcd, // 0-9
    output 	a,   // a segment (1=0ff)
    output 	b,   // b segment
    output 	c,   // c segment
    output 	d,   // d segment
    output 	e,   // e segment
    output 	f,   // f segment
    output 	g    // g segment
    );

   assign a = (bcd[3:0] == 4'h1) | (bcd[3:0] == 4'h4);

   assign b = (bcd[3:0] == 4'h5) | (bcd[3:0] == 4'h6);

   assign c = (bcd[3:0] == 4'h2);

   assign d = (bcd[3:0] == 4'h1) | (bcd[3:0] == 4'h4)|
              (bcd[3:0] == 4'h7) | (bcd[3:0] == 4'h9);

   assign e = (bcd[3:0] == 4'h1) | (bcd[3:0] == 4'h3)|
	      (bcd[3:0] == 4'h4) | (bcd[3:0] == 4'h5)|
	      (bcd[3:0] == 4'h7) | (bcd[3:0] == 4'h9);

   assign f = (bcd[3:0] == 4'h1) | (bcd[3:0] == 4'h2)|
	      (bcd[3:0] == 4'h3) | (bcd[3:0] == 4'h7);


   assign g = (bcd[3:0] == 4'h0) | (bcd[3:0] == 4'h1) |
	      (bcd[3:0] == 4'h7);

endmodule
module oh_pll #(parameter N = 8) // number of clocks
   ( input            clkin,    // primary clock input
     input 	      nreset, // async active low reset
     input 	      clkfb, // feedback clock
     input 	      pll_en, // enable pll   
     input [N*8-1:0]  clkdiv, // clock divider settings (per clock)
     input [N*16-1:0] clkphase, // clock phase setting (rise/fall edge)
     input [7:0]      clkmult, // feedback clock multiplier 	       
     output [N-1:0]   clkout, // output clocks
     output 	      locked // PLL locked status
     );

`ifdef TARGET_SIM

   //insert PLL simulation model
   
`endif
      
endmodule // oh_pll
module oh_rise2pulse #(parameter N = 1) // data width

   (  input           clk,     // clock
      input 	      nreset, // async active low reset
      input [N-1:0]  in, // edge input
      output [N-1:0] out     // one cycle pulse
      );

   reg [N-1:0]    in_reg;

   always @ (posedge clk or negedge nreset)
     if(!nreset)
       in_reg[N-1:0]  <= 'b0 ;
     else
       in_reg[N-1:0]  <= in[N-1:0] ;

   assign out[N-1:0]  = in[N-1:0] & ~in_reg[N-1:0] ;

endmodule // oh_rise2pulse
module oh_reg1
  #(parameter N    = 1,        // vector width
    parameter SYN  = "TRUE",   // synthesizable (or not)
    parameter TYPE = "DEFAULT" // scell type/size
    )
   ( input          nreset, //async active low reset
     input 	    clk,    // clk
     input 	    en,     // write enable
     input [N-1:0]  in,     // input data
     output [N-1:0] out     // output data (stable/latched when clk=1)
     );

   //TODO: Implement all classes of flip-flops
   generate
      if(SYN == "TRUE") begin
	 reg [N-1:0]      out_reg;
	 always @ (posedge clk or negedge nreset)
	   if(!nreset)
	     out_reg[N-1:0] <= 'b0;
	   else if(en)
	     out_reg[N-1:0] <= in[N-1:0];
	 assign out[N-1:0] = out_reg[N-1:0];
      end
      else begin
	 genvar 	     i;
	 for (i=0;i<N;i=i+1) begin
	    asic_reg1 #(.TYPE(TYPE))
	    asic_reg1  (// Outputs
			.out	(out[i]),
			// Inputs
			.nreset	(nreset),
			.clk	(clk),
			.en	(en),
			.in	(in[i]));
	 end
      end
   endgenerate
endmodule
module oh_sdffsq #(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] 	nset,
    output reg [DW-1:0] q
    );
   
   always @ (posedge clk or negedge nset)
     if(!nset)
       q <= {DW{1'b1}};
     else
       q <= se ? si : d;
      
endmodule
module oh_mx4 #(parameter DW = 1 ) // array width
   (
    input [DW-1:0]  d0,
    input [DW-1:0]  d1,
    input [DW-1:0]  d2,
    input [DW-1:0]  d3,
    input [DW-1:0]  s0,
    input [DW-1:0]  s1,
    output [DW-1:0] z
    );
   
   assign z = (d0 & ~s1 & ~s0) |
	      (d1 & ~s1 &  s0) |
	      (d2 &  s1 & ~s0) |
	      (d2 &  s1 &  s0);
   
endmodule
module oh_ao221 #(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_arbiter
  #( parameter N    = 1,
     parameter TYPE = "FIXED" // or ROUNDROBIN, FAIR
     )
   (
    input [N-1:0]  requests, //request vector
    output [N-1:0] grants    //grant (one hot)
    );

   wire [N-1:0]   waitmask;
   genvar 	  j;
   generate
      if(TYPE=="FIXED")
	begin : arbiter_fixed
	   assign waitmask[0]   = 1'b0;
	   for (j=N-1; j>=1; j=j-1)
	     begin : gen_arbiter
		assign waitmask[j] = |requests[j-1:0];
	     end
	end
   endgenerate

   //grant circuit
   assign grants[N-1:0] = requests[N-1:0] & ~waitmask[N-1:0];

endmodule // oh_arbiter
module oh_oai221 #(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_ao33 #(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_oa32 #(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_sdffqn #(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, 
    output reg [DW-1:0] qn
    );
   
   always @ (posedge clk)
     qn <= se ? ~si : ~d;
      
endmodule
module oh_edge2pulse
  #( parameter N      = 1) // width of data inputs
   (
    input 	   clk,    // clock
    input 	   nreset, // async active low reset
    input [N-1:0]  in,     // edge input
    output [N-1:0] out     // one cycle pulse
    );

   reg [N-1:0]    in_reg;

   always @ (posedge clk or negedge nreset)
     if(!nreset)
       in_reg[N-1:0]  <= 'b0 ;
     else
       in_reg[N-1:0]  <= in[N-1:0] ;

   assign out[N-1:0]  = in_reg[N-1:0]  ^ in[N-1:0] ;

endmodule // oh_edge2pulse
module oh_csa32
  #(parameter N    = 1,        // vector width
    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
     output [N-1:0] s,   // sum
     output [N-1:0] c    // carry
     );

   generate
      if(SYN == "TRUE") begin
	 assign s[N-1:0] = in0[N-1:0] ^ in1[N-1:0] ^ in2[N-1:0];

	 assign c[N-1:0] = (in0[N-1:0] & in1[N-1:0]) |
			   (in1[N-1:0] & in2[N-1:0]) |
			   (in2[N-1:0] & in0[N-1:0] );
      end
      else begin
	 genvar 	     i;
	 for (i=0;i<N;i=i+1) begin
	    asic_csa32 #(.TYPE(TYPE))
	    asic_csa32  (.s(s[i]),
			 .c(c[i]),
			 .in2(in2[i]),
			 .in1(in1[i]),
			 .in0(in0[i]));
	 end
      end
   endgenerate
endmodule
module oh_datagate
  #(parameter N    = 2,        // number of sync stages
    parameter SYN  = "TRUE",   // synthesizable (or not)
    parameter TYPE = "DEFAULT" // scell type/size
    )
   (
    input 	   clk, // clock
    input 	   en, // data valid
    input [N-1:0]  in, // data input
    output [N-1:0] out // data output
    );

   generate
      if(SYN == "TRUE") begin

	 reg [N-1:0] 	   enable_pipe;
	 wire 		   enable;

	 always @ (posedge clk)
	   enable_pipe[N-1:0] <= {enable_pipe[N-2:0], en};

	 //Mask to 0 if no valid for last N cycles
	 assign enable = en | (|enable_pipe[N-1:0]);

	 assign out[N-1:0] = {(N){enable}} & in[N-1:0];
      end // if (SYN == "TRUE")
      else begin
	 genvar i;
	 for (i=1;i<N;i=i+1) begin
	    asic_datagate  #(.TYPE(TYPE))
	    asic_datagate (// Outputs
			   .out	(out[N-1:0]),
			   // Inputs
			   .clk	(clk),
			   .en	(en),
			   .in	(in[N-1:0]));

	 end
      end
   endgenerate
endmodule
module oh_xnor2 #(parameter DW = 1 ) // array width
   (
    input [DW-1:0]  a,
    input [DW-1:0]  b,
    output [DW-1:0] z
    );
   
   assign z =  ~(a ^ b);
   
endmodule
module oh_par2ser #(parameter PW = 32, // parallel packet width
		    parameter SW = 1,  // serial packet width
		    parameter CW = $clog2(PW/SW)  // serialization factor
		    )
   (
    input 	    clk, // sampling clock
    input 	    nreset, // async active low reset
    input [PW-1:0]  din, // parallel data
    output [SW-1:0] dout, // serial output data
    output 	    access_out,// output data valid
    input 	    load, // load parallel data (priority)
    input 	    shift, // shift data
    input [7:0]     datasize, // size of data to shift
    input 	    lsbfirst, // lsb first order
    input 	    fill, // fill bit
    input 	    wait_in, // wait input
    output 	    wait_out // wait output (wait in | serial wait)
    );

   // local wires
   reg [PW-1:0]    shiftreg;
   reg [CW-1:0]    count;
   wire 	   start_transfer;
   wire 	   busy;

   // start serialization
   assign start_transfer = load &  ~wait_in & ~busy;

   //transfer counter
   always @ (posedge clk or negedge nreset)
     if(!nreset)
       count[CW-1:0] <= 'b0;
     else if(start_transfer)
       count[CW-1:0] <= datasize[CW-1:0];  //one "SW sized" transfers
     else if(shift & busy)
       count[CW-1:0] <= count[CW-1:0] - 1'b1;

   //output data is valid while count > 0
   assign busy = |count[CW-1:0];

   //data valid while shifter is busy
   assign access_out = busy;

   //wait until valid data is finished
   assign wait_out  = wait_in | busy;

   // shift register
   always @ (posedge clk or negedge nreset)
     if(!nreset)
       shiftreg[PW-1:0] = 'b0;
     else if(start_transfer)
       shiftreg[PW-1:0] = din[PW-1:0];
     else if(shift & lsbfirst)
       shiftreg[PW-1:0] = {{(SW){fill}}, shiftreg[PW-1:SW]};
     else if(shift)
       shiftreg[PW-1:0] = {shiftreg[PW-SW-1:0],{(SW){fill}}};


   assign dout[SW-1:0] = lsbfirst ? shiftreg[SW-1:0] :
			            shiftreg[PW-1:PW-SW];

endmodule // oh_par2ser
module oh_mult
  #(parameter N    = 32,        // block width
    parameter SYN  = "TRUE",    // synthesizable
    parameter TYPE = "DEFAULT"  // implementation type
    )
   (
    //Inputs
    input [N-1:0]    a,       // a input (multiplier)
    input [N-1:0]    b,       // b input (multiplicand)
    input 	      asigned, // a operand is signed
    input 	      bsigned, // b oeprand is signed
    //Outputs
    output [2*N-1:0] product, // a*b final product
    output [2*N-1:0] sum,     // a*b partial sum
    output [2*N-1:0] carry    // a*b partial carry
    );

   generate
      if(SYN=="TRUE")  begin
	 wire a_sext = asigned & a[N-1];
	 wire b_sext = bsigned & b[N-1];
	 assign product[2*N-1:0] = $signed({a_sext,a[N-1:0]}) *
				    $signed({b_sext,b[N-1:0]});
      end
      else begin
	 asic_mult #(.TYPE(TYPE),
		     .N(N))
	 asic_mult (// Outputs
		    .product	(product[2*N-1:0]),
		    .sum	(sum[2*N-1:0]),
		    .carry	(carry[2*N-1:0]),
		    // Inputs
		    .a		(a[N-1:0]),
		    .b		(b[N-1:0]),
		    .asigned	(asigned),
		    .bsigned	(bsigned));

      end
   endgenerate
endmodule
module oh_xor3 #(parameter DW = 1 ) // array width
   (
    input [DW-1:0]  a,
    input [DW-1:0]  b,
    input [DW-1:0]  c,
    output [DW-1:0] z
    );
   
   assign z =  a ^ b ^ c;
   
endmodule
module oh_clockmux
  #(parameter N    = 2,        // number of clock inputs)
    parameter SYN  = "TRUE",   // synthesizable (or not)
    parameter TYPE = "DEFAULT" // implementation type
    )
   (
    input [N-1:0] en,    // one hot enable vector (needs to be stable!)
    input [N-1:0] clkin, // one hot clock inputs (only one is active!)
    output 	  clkout // clock output
    );

   generate
      if(SYN == "TRUE") begin
	 assign clkout = |(clkin[N-1:0] & en[N-1:0]);
      end
      else begin
	 asic_clockmux #(.TYPE(TYPE),
			 .N(N))
	 asic_clockmux(// Outputs
		       .clkout		(clkout),
		       // Inputs
		       .en		(en[N-1:0]),
		       .clkin		(clkin[N-1:0]));
      end
   endgenerate
endmodule
module oh_oai31 #(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_and2  #(parameter N  = 1,        // block width
		  parameter SYN  = "TRUE",    // synthesizable
		  parameter TYPE = "DEFAULT"  // implementation type
		  )
   (
    input [N-1:0]  a,
    input [N-1:0]  b,
    output [N-1:0] z
    );

   generate
      if(SYN == "TRUE")  begin
	 assign z = a & b;
      end
      else begin

	 oh_and2 #(.TYPE(TYPE))
	 oh_and2 (/*AUTOINST*/
		  // Outputs
		  .z			(z[N-1:0]),
		  // Inputs
		  .a			(a[N-1:0]),
		  .b			(b[N-1:0]));
      end
   endgenerate
endmodule
module oh_aoi221 #(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 ohr_reg0 #(parameter N = 1)       // data width
   ( input          nreset, //async active low reset
     input 	    clk, // clk, latch when clk=0
     input [N-1:0]  in, // input data
     output [N-1:0] out  // output data (stable/latched when clk=1)
     );

`ifdef CFG_ASIC
   asic_reg0 ireg [N-1:0] (.nreset(nreset),
			    .clk(clk),
			    .in(in[N-1:0]),
			    .out(out[N-1:0]));
`else
   reg [N-1:0]      out_reg;
   always @ (negedge clk or negedge nreset)
     if(~nreset)
       out_reg[N-1:0] <= 'b0;
     else
       out_reg[N-1:0] <= in[N-1:0];
   assign out[N-1:0] = out_reg[N-1:0];
`endif

endmodule // ohr_reg0
module oh_dffrqn #(parameter DW = 1) // array width
   (
    input [DW-1:0] 	d,
    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 <= ~d;
   
endmodule
module oh_sdffq #(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,
    output reg [DW-1:0] q
    );

   always @ (posedge clk)
       q <= se ? si : d;
   
endmodule
module oh_buffer
  #(parameter N    = 1,         // vector width
    parameter SYN  = "TRUE",    // synthesize buffer
    parameter TYPE = "DEFAULT") // buffer type
   (
     input [N-1:0]  in, // input
     output [N-1:0] out // output
     );
   generate
      if(SYN == "TRUE") begin
	 assign out[N-1:0] = in[N-1:0];
      end
      else begin
	 genvar 	     i;
	 for (i=0;i<N;i=i+1) begin
	    asic_buffer #(.TYPE(TYPE))
	    asic_buffer (.out (out[N-1:0]),
			 .in  (in[N-1:0]));
	 end
      end
   endgenerate
endmodule // oh_buffer
module oh_bin2gray
  #(parameter N = 32 // width of data inputs
    )
   (
    input [N-1:0]  in, //binary encoded input
    output [N-1:0] out //gray encoded output
    );

   assign out[N-1:0] =  in[N-1:0] ^ {1'b0, in[N-1:1]};

endmodule // oh_bin2gray
module oh_edgealign (/*AUTOARG*/
   // Outputs
   firstedge,
   // Inputs
   fastclk, slowclk
   );
   
   input  fastclk;
   input  slowclk;
   output firstedge;

   reg 	  clk45;
   reg 	  clk90;
   reg 	  firstedge;

   always @ (negedge fastclk) 
     clk45     <= slowclk;

   always @ (posedge fastclk) 
     begin
	clk90     <= clk45;
	firstedge <= ~clk45 & clk90;
     end
   
endmodule // oh_edgealign
module oh_mux6 #(parameter N = 1 ) // width of mux
   (
    input 	    sel5,
    input 	    sel4,
    input 	    sel3,
    input 	    sel2,
    input 	    sel1,
    input 	    sel0,
    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]);


endmodule // oh_mux6
module oh_mxi2 #(parameter DW = 1 ) // array width
   (
    input [DW-1:0]  d0,
    input [DW-1:0]  d1,
    input [DW-1:0]  s,
    output [DW-1:0] z
    );
   
   assign z = ~((d0 & ~s) | (d1 & s));
   
endmodule
module oh_stretcher #(parameter CYCLES = 5) // "wakeup" cycles
   ( input  clk, // clock
     input  in, // input pulse
     input  nreset, // async active low reset
     output out // stretched output pulse
     );

   reg [CYCLES-1:0] valid;

   always @ (posedge clk or negedge nreset)
     if(!nreset)
       valid[CYCLES-1:0] <='b0;
     else if(in)
       valid[CYCLES-1:0] <={(CYCLES){1'b1}};
     else
       valid[CYCLES-1:0] <={valid[CYCLES-2:0],1'b0};

   assign out = valid[CYCLES-1];

endmodule // oh_stretcher
module oh_mxi4 #(parameter DW = 1 ) // array width
   (
    input [DW-1:0]  d0,
    input [DW-1:0]  d1,
    input [DW-1:0]  d2,
    input [DW-1:0]  d3,
    input [DW-1:0]  s0,
    input [DW-1:0]  s1,
    output [DW-1:0] z
    );
   
   assign z = ~((d0 & ~s1 & ~s0) |
		(d1 & ~s1 &  s0) |
		(d2 &  s1 & ~s0) |
		(d2 &  s1 &  s0));
   
endmodule
module oh_mxi3 #(parameter DW = 1 ) // array width
   (
    input [DW-1:0]  d0,
    input [DW-1:0]  d1,
    input [DW-1:0]  d2,
    input [DW-1:0]  s0,
    input [DW-1:0]  s1,
    output [DW-1:0] z
    );
   
   assign z = ~((d0 & ~s0 & ~s1) |
		(d1 & s0  & ~s1) |
		(d2 & s1));
   
endmodule
module oh_mux
  #(parameter N   = 32,        // vector width
    parameter M   = 2,         // number of vectors
    parameter SYN  = "TRUE",    // synthesizable (or not)
    parameter TYPE = "DEFAULT"  // implementation type
    )
   (
    input [M-1:0]   sel, // select vector
    input [M*N-1:0] in,  // concatenated input {..,in1[N-1:0],in0[N-1:0]
    output [N-1:0]  out  // output
    );

   generate
      if(SYN == "TRUE") begin
	 reg [N-1:0]     mux;
	 integer 	 i;
	 always @*
	   begin
	      mux[N-1:0] = 'b0;
	      for(i=0;i<M;i=i+1)
		mux[N-1:0] = mux[N-1:0] | {(N){sel[i]}} & in[((i+1)*N-1)-:N];
	   end
	 assign out[N-1:0] = mux[N-1:0];
      end
      else begin
	 //TODO: implement
	 asic_mux #(.TYPE(TYPE),
		    .N(N))
	 asic_mux(.out	(out),
		  .sel  (sel[N-1:0]),
		  .in	(in[N-1:0]));
      end
   endgenerate
endmodule
module oh_aoi32 #(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_aoi33 #(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_clockmux2
  #(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]  clkin0, // clock input
    input [N-1:0]  clkin1, // 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);
      end
      else begin
	 genvar 	     i;
	 for (i=0;i<N;i=i+1) begin
	    asic_clockmux2 #(.TYPE(TYPE))
	    asic_clockmux2(// Outputs
			   .clkout	(clkout[N-1:0]),
			   // Inputs
			   .en0		(en0[N-1:0]),
			   .en1		(en1[N-1:0]),
			   .clkin0	(clkin0[N-1:0]),
			   .clkin1	(clkin1[N-1:0]));
	 end
      end
   endgenerate
endmodule
module oh_buf #(parameter DW = 1 ) // array width
   (
    input [DW-1:0]  a,
    output [DW-1:0] z
    );
   
   assign z = a;
      
endmodule
module oh_mux9 #( parameter N = 1 ) // width of mux
   (
    input 	    sel8,
    input 	    sel7,
    input 	    sel6,
    input 	    sel5,
    input 	    sel4,
    input 	    sel3,
    input 	    sel2,
    input 	    sel1,
    input 	    sel0,
    input [N-1:0]  in8,
    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] |
			 {(N){sel8}} & in8[N-1:0]);

endmodule // oh_mux9
module oh_nand3 #(parameter DW = 1 ) // array width
   (
    input [DW-1:0]  a,
    input [DW-1:0]  b,
    input [DW-1:0]  c, 
    output [DW-1:0] z
    );
   
   assign z = ~(a & b & c);
   
endmodule
module oh_header
  #(parameter SYN   = "TRUE",   // true=synthesizable
    parameter TYPE  = "DEFAULT" // scell type/size
    )
   (
    input  npower, // active low power on
    input  vdd, // input supply
    output vddg     // gated output supply
    );

   generate
      if(SYN == "TRUE")	begin
      end
      else begin
	 asic_header #(.TYPE(TYPE))
	 asic_header (.npower(npower),
		      .vdd(vdd),
		      .vddg(vddg));
      end
   endgenerate

endmodule // oh_pwr_gate
module oh_oa211 #(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_parity #( parameter N      = 2 // data width
		 )
   (
    input [N-1:0] in,  // data input
    output 	   out // calculated parity bit
    );

  assign  parity = ^in[N-1:0];

endmodule // oh_parity
module oh_csa62
  #(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]  cin0,//carry in
     input [N-1:0]  cin1,//carry in
     input [N-1:0]  cin2,//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
     );

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

   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_csa42  #(.N(N),
	       .TYPE(TYPE),
	       .SYN(SYN))
   csa42 (.in0(s_int0[N-1:0]),
	  .in1(s_int1[N-1:0]),
	  .in2(cin0[N-1:0]),
	  .in3(cin1[N-1:0]),
	  .cin(cin2[N-1:0]),
	  .cout(cout2[N-1:0]),
	  .c(c[N-1:0]),
	  .s(s[N-1:0]));

endmodule // oh_csa62
module oh_and3 #(parameter DW = 1 ) // array width
   (
    input [DW-1:0]  a,
    input [DW-1:0]  b,
    input [DW-1:0]  c, 
    output [DW-1:0] z
    );
   
   assign z = a & b & c;
   
endmodule
module oh_standby
  #(parameter PD       = 5,       // cycles to stay awake after "wakeup"
    parameter SYNCPIPE = 2,       // depth of synchronization pipeline
    parameter SYN      = "TRUE",  // TRUE is synthesizable
    parameter DELAY    = 5        // cycles delay of irq_reset after posedge
    )
   (//inputs
    input  clkin, //clock input
    input  nreset,//async active low reset
    input  testenable,//disable standby (static signal)
    input  wakeup, //wake up (level, active high)
    input  idle, //idle indicator
    //outputs
    output resetout,//synchronous one clock reset pulse
    output clkout //clock output
    );

   //Wire declarations
   reg [PD-1:0]             wakeup_pipe;
   wire 		    sync_reset;
   wire 		    sync_reset_pulse;
   wire 		    wakeup_now;
   wire 		    clk_en;
   wire [$clog2(DELAY)-1:0] delay_sel;

   //####################################################################
   // -Creating an edge one clock cycle pulse on rising edge of reset
   // -Event can be used to boot a CPU and any other master as an example
   // -Given the clock dependancies, it was deemed safest to put this
   //  function here
   //####################################################################

   // Synchronizing reset to clock to avoid metastability
   oh_dsync #(.SYNCPIPE(SYNCPIPE))
   oh_dsync (//outputs
	     .dout(sync_reset),
	     //inputs
	     .nreset(nreset),
	     .din(nreset),
	     .clk(clkin)
	     );

   // Detecting rising edge of delayed reset
   oh_edge2pulse oh_edge2pulse  (//outputs
				 .out	 (sync_reset_pulse),
				 //inputs
				 .clk	 (clkin),
				 .nreset (nreset),
				 .in	 (sync_reset));

   // Delay irq event by N clock cycles
   assign delay_sel = DELAY;
   oh_delay #(.N(1),
	      .MAXDELAY(DELAY))
   oh_delay (//outputs
	     .out	 (resetout),
	     //inputs
	     .in	 (sync_reset_pulse),
	     .sel	 (delay_sel),
	     .clk	 (clkin));

   //####################################################################
   // Clock gating circuit for output clock
   // EVent can be used to boot a CPU andcany other master as an example
   //####################################################################

   //Adding reset to wakeup signal
   assign wakeup_now = sync_reset_pulse | wakeup;

   // Stay awake for PD cycles
   always @ (posedge clkin or negedge nreset)
     if(!nreset)
       wakeup_pipe[PD-1:0] <= 'b0;
     else
       wakeup_pipe[PD-1:0] <= {wakeup_pipe[PD-2:0], wakeup_now};

   // Clock enable
   assign  clk_en    =  wakeup                 | //immediate wakeup
                        (|wakeup_pipe[PD-1:0]) | //anything in pipe
		        ~idle;                   //core not in idle

   // Clock gating cell
   oh_clockgate oh_clockgate  (.eclk(clkout),
			       .clk(clkin),
			       .en(clk_en),
     			       .te(testenable));

endmodule // oh_standby
module oh_mux2 #(parameter N = 1 ) // width of mux
   (
    input 	    sel1,
    input 	    sel0,
    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]);


endmodule // oh_mux2
module oh_oa311 #(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_pulse
  #(parameter N = 32 //width of counter (max value)
    )
   (
    input 	  clk,
    input 	  nreset,
    input 	  en, //enable pulse generator
    input [N-1:0] mask, //mask output to limit range
    output reg 	  out  //random output pulse
    );

   wire [N-1:0]   random;
   reg [N-1:0] 	  counter;
   wire 	  match;

   oh_random oh_random(//output
		       .out	(random[N-1:0]),
		       // Inputs
		       .clk	(clk),
		       .mask    (mask[N-1:0]),
		       .nreset	(nreset),
		       .en	(match));

   assign match = (random[N-1:0] == counter[N-1:0]);

   always @ (posedge clk or negedge nreset)
     if(~nreset)
       counter[N-1:0] <= 'b0;
     else if(match)
       counter[N-1:0] <= 'b0;
     else
       counter[N-1:0] <= counter[N-1:0] + 1;

   always @ (posedge clk or negedge nreset)
     if(~nreset)
       out <= 'b0;
     else
       out <= out ^ match;

endmodule // oh_pulse
module oh_ram
  #(parameter N       = 32,           // FIFO width
    parameter DEPTH   = 32,           // FIFO depth
    parameter REG     = 1,            // Register fifo output
    parameter SYN     = "TRUE",       // hard (macro) or soft (rtl)
    parameter TYPE    = "DEFAULT",    // pass through variable for hard macro
    parameter SHAPE   = "SQUARE",     // hard macro shape (square, tall, wide)
    parameter AW      = $clog2(DEPTH) // rd_count width (derived)
    )
   (// Memory interface (dual port)
    input 	   clk, //write clock
    input 	   en, //write enable
    input [N-1:0]  wem, //per bit write enable
    input [AW-1:0] addr,//write address
    input [N-1:0]  din, //write data
    output [N-1:0] dout,//read output data
    // BIST interface
    input 	   bist_en, // bist enable
    input 	   bist_we, // write enable global signal
    input [N-1:0]  bist_wem, // write enable vector
    input [AW-1:0] bist_addr, // address
    input [N-1:0]  bist_din, // data input
    // Power/repair (hard macro only)
    input 	   shutdown, // shutdown signal
    input 	   vss, // ground signal
    input 	   vdd, // memory array power
    input 	   vddio, // periphery/io power
    input [7:0]    memconfig, // generic memory config
    input [7:0]    memrepair // repair vector
    );

   generate

      if(SYN == "TRUE") begin: rtl
	 // Generic RTL RAM
	 reg [N-1:0] 	   ram    [0:DEPTH-1];
	 wire [N-1:0] 	   rdata;
	 integer 	   i;

	 //write port
	 always @(posedge clk)
	   for (i=0;i<N;i=i+1)
	     if (en & wem[i])
               ram[addr[AW-1:0]][i] <= din[i];

	 //read port
	 assign rdata[N-1:0] = ram[addr[AW-1:0]];

	 //configurable output register
	 reg [N-1:0] 	     rd_reg;
	 always @ (posedge clk)
	   if(en)
	     rd_reg[N-1:0] <= rdata[N-1:0];

	 //Drive output from register or RAM directly
	 assign dout[N-1:0] = (REG==1) ? rd_reg[N-1:0] : rdata[N-1:0];

      end // block: rtl
      else begin: hard
	 // Hard macro ASIC RAM
	 asic_memory_sp #(.N(N),
			  .DEPTH(DEPTH),
			  .SHAPE(SHAPE),
			  .REG(REG))
	 asic_memory_sp ();
      end // block: hard
   endgenerate
endmodule // oh_memory_dp
module oh_xor2 #(parameter DW = 1 ) // array width
   (
    input [DW-1:0]  a,
    input [DW-1:0]  b,
    output [DW-1:0] z
    );
   
   assign z =  a ^ b;
   
endmodule
module oh_isobuflo
  #(parameter N     = 1,        // width of data inputs
    parameter SYN   = "TRUE",   // true=synthesizable
    parameter TYPE  = "DEFAULT" // scell type/size
    )
   (
    input 	   iso,// active low isolation signal
    input [N-1:0]  in, // input signal
    output [N-1:0] out  // out = ~iso & in
    );

   generate
      if(SYN == "TRUE")	begin
	 assign out[N-1:0] = {(N){~iso}} | in[N-1:0];
      end
      else begin
	 genvar 	     i;
	 for (i=0;i<N;i=i+1) begin
	    asic_isobuflo #(.TYPE(TYPE))
	    asic_isobuflo (.iso(iso),
			   .in(in[i]),
			   .out(out[i]));
	 end
      end
   endgenerate

endmodule
module oh_isobufhi
  #(parameter N     = 1,        // width of data inputs
    parameter SYN   = "TRUE",   // true=synthesizable
    parameter TYPE  = "DEFAULT" // scell type/size
    )
   (
    input 	   iso,// active low isolation signal
    input [N-1:0]  in, // input signal
    output [N-1:0] out // out = iso | in
    );
   generate
      if(SYN == "TRUE")	begin
	 assign out[N-1:0] = {(N){iso}} | in[N-1:0];
      end
      else begin
	 genvar 	     i;
	 for (i=0;i<N;i=i+1) begin
	    asic_isobufhi #(.TYPE(TYPE))
	    asic_isobufhi (.iso(iso),
			 .in(in[i]),
			 .out(out[i]));
	 end
      end
   endgenerate
endmodule
module oh_dffsqn #(parameter DW = 1) // array width
   (
    input [DW-1:0] 	d,
    input [DW-1:0] 	clk,
    input [DW-1:0] 	nset,
    output reg [DW-1:0] qn
    );
   
   always @ (posedge clk or negedge nset)
     if(!nset)
       qn <= 'b0;
     else
       qn <= ~d;
   
endmodule
module oh_oai222 #(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_nor2 #(parameter DW = 1 ) // array width
   (
    input [DW-1:0]  a,
    input [DW-1:0]  b,
    output [DW-1:0] z
    );
   
   assign z = ~(a | b);
   
endmodule
module oh_ao22 #(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_nor4 #(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