dakies/OSS_Verilog huggingface dataset:
module LUT5_D (LO, O, I0, I1, I2, I3, I4);

  parameter INIT = 32'h00000000;

  input I0, I1, I2, I3, I4;

  output LO, O;

  reg O;
  reg tmp;
  wire LO;

  assign LO = O;

  always @( I4 or I3 or  I2 or  I1 or  I0 )  begin
 
    tmp =  I0 ^ I1  ^ I2 ^ I3 ^ I4;

    if ( tmp == 0 || tmp == 1)

        O = INIT[{I4, I3, I2, I1, I0}];

    else 
    
      O =  lut4_mux4 ( 
                        { lut6_mux8 ( INIT[31:24], {I2, I1, I0}),
                          lut6_mux8 ( INIT[23:16], {I2, I1, I0}),
                          lut6_mux8 ( INIT[15:8], {I2, I1, I0}),
                          lut6_mux8 ( INIT[7:0], {I2, I1, I0}) }, { I4, I3});
  end

  function lut6_mux8;
  input [7:0] d;
  input [2:0] s;
   
  begin

       if ((s[2]^s[1]^s[0] ==1) || (s[2]^s[1]^s[0] ==0))
           
           lut6_mux8 = d[s];

         else
           if ( ~(|d))
                 lut6_mux8 = 1'b0;
           else if ((&d))
                 lut6_mux8 = 1'b1;
           else if (((s[1]^s[0] ==1'b1) || (s[1]^s[0] ==1'b0)) && (d[{1'b0,s[1:0]}]===d[{1'b1,s[1:0]}]))
                 lut6_mux8 = d[{1'b0,s[1:0]}];
           else if (((s[2]^s[0] ==1) || (s[2]^s[0] ==0)) && (d[{s[2],1'b0,s[0]}]===d[{s[2],1'b1,s[0]}]))
                 lut6_mux8 = d[{s[2],1'b0,s[0]}];
           else if (((s[2]^s[1] ==1) || (s[2]^s[1] ==0)) && (d[{s[2],s[1],1'b0}]===d[{s[2],s[1],1'b1}]))
                 lut6_mux8 = d[{s[2],s[1],1'b0}];
           else if (((s[0] ==1) || (s[0] ==0)) && (d[{1'b0,1'b0,s[0]}]===d[{1'b0,1'b1,s[0]}]) &&
              (d[{1'b0,1'b0,s[0]}]===d[{1'b1,1'b0,s[0]}]) && (d[{1'b0,1'b0,s[0]}]===d[{1'b1,1'b1,s[0]}]))
                 lut6_mux8 = d[{1'b0,1'b0,s[0]}];
           else if (((s[1] ==1) || (s[1] ==0)) && (d[{1'b0,s[1],1'b0}]===d[{1'b0,s[1],1'b1}]) &&
              (d[{1'b0,s[1],1'b0}]===d[{1'b1,s[1],1'b0}]) && (d[{1'b0,s[1],1'b0}]===d[{1'b1,s[1],1'b1}]))
                 lut6_mux8 = d[{1'b0,s[1],1'b0}];
           else if (((s[2] ==1) || (s[2] ==0)) && (d[{s[2],1'b0,1'b0}]===d[{s[2],1'b0,1'b1}]) &&
              (d[{s[2],1'b0,1'b0}]===d[{s[2],1'b1,1'b0}]) && (d[{s[2],1'b0,1'b0}]===d[{s[2],1'b1,1'b1}]))
                 lut6_mux8 = d[{s[2],1'b0,1'b0}];
           else
                 lut6_mux8 = 1'bx;
   end
  endfunction


  function lut4_mux4;
  input [3:0] d;
  input [1:0] s;
   
  begin

       if ((s[1]^s[0] ==1) || (s[1]^s[0] ==0))

           lut4_mux4 = d[s];

         else if ((d[0] === d[1]) && (d[2] === d[3])  && (d[0] === d[2]) )
           lut4_mux4 = d[0];
         else if ((s[1] == 0) && (d[0] === d[1]))
           lut4_mux4 = d[0];
         else if ((s[1] == 1) && (d[2] === d[3]))
           lut4_mux4 = d[2];
         else if ((s[0] == 0) && (d[0] === d[2]))
           lut4_mux4 = d[0];
         else if ((s[0] == 1) && (d[1] === d[3]))
           lut4_mux4 = d[1];
         else
           lut4_mux4 = 1'bx;

   end
  endfunction

endmodule
module RAM16X1D_1 (DPO, SPO, A0, A1, A2, A3, D, DPRA0, DPRA1, DPRA2, DPRA3, WCLK, WE);

    parameter INIT = 16'h0000;

    output DPO, SPO;

    input  A0, A1, A2, A3, D, DPRA0, DPRA1, DPRA2, DPRA3, WCLK, WE;

    reg  [15:0] mem;
    wire [3:0] adr;

    assign adr = {A3, A2, A1, A0};
    assign SPO = mem[adr];
    assign DPO = mem[{DPRA3, DPRA2, DPRA1, DPRA0}];

    initial 
        mem = INIT;

    always @(negedge WCLK) 
        if (WE == 1'b1)
            mem[adr] <= #100 D;


endmodule
module XOR4 (O, I0, I1, I2, I3);

    output O;

    input  I0, I1, I2, I3;

	xor X1 (O, I0, I1, I2, I3);


endmodule
module CARRY4 (CO, O, CI, CYINIT, DI, S);

    output [3:0] CO;
    output [3:0] O;
    input        CI;
    input        CYINIT;
    input  [3:0] DI;
    input  [3:0] S;

    wire ci_or_cyinit;

//    initial
//       ci_or_cyinit = 0;

    assign O = S ^ {CO[2:0], ci_or_cyinit};
    assign CO[0] = S[0] ? ci_or_cyinit : DI[0];
    assign CO[1] = S[1] ? CO[0] : DI[1];
    assign CO[2] = S[2] ? CO[1] : DI[2];
    assign CO[3] = S[3] ? CO[2] : DI[3];
    assign ci_or_cyinit = CYINIT | CI;

//    always @(CYINIT or CI)
//      if (CYINIT === 1'bz || CYINIT === 1'bx) begin
//           $display("Error: CARRY4 instance, %m, detects CYINIT unconnected. Only one of CI and CYINIT inputs can be used and other one need be grounded.");
//           $finish;
//     end
//      else if (CI=== 1'bz || CI=== 1'bx) begin
//           $display("Error: CARRY4 instance, %m, detects CI unconnected. Only one of CI and CYINIT inputs can be used and other one need be grounded.");
//           $finish;
//     end
//      else 
//           ci_or_cyinit = CYINIT | CI;

endmodule
module IBUFG_SSTL18_II (O, I);

    output O;

    input  I;

	buf B1 (O, I);


endmodule
module OR5 (O, I0, I1, I2, I3, I4);

    output O;

    input  I0, I1, I2, I3, I4;

    or O1 (O, I0, I1, I2, I3, I4);


endmodule
module BUFE (O, E, I);

    output O;

    input  E, I;

	bufif1 B1 (O, I, E);


endmodule
module XORCY_D (LO, O, CI, LI);

    output LO, O;

    input  CI, LI;

	xor X1 (O, CI, LI);
	xor X2 (LO, CI, LI);


endmodule
module IBUFG_HSTL_I_DCI_18 (O, I);

    output O;

    input  I;

	buf B1 (O, I);


endmodule
module IBUF_HSTL_II_18 (O, I);

    output O;

    input  I;

	buf B1 (O, I);


endmodule
module C_MUX_SLICE_BUFE_V4_0 (I, OE, O);

	parameter C_WIDTH = 16;						/* Width of the single input */	

	input [C_WIDTH-1 : 0] I;
	input OE;
	output [C_WIDTH-1 : 0] O;
	 
	reg [C_WIDTH-1 : 0] intO;

	wire [C_WIDTH-1 : 0] #1 O = intO;
	
	initial 
	begin

		if (OE == 1) 
			intO = I;
		else if (OE == 0) 
			intO = `allZs;
		else
			intO = `allXs;			
	end
	
	always@(I or OE)
	begin
		if (OE == 1) 
			intO <= I;
		else if (OE == 0) 
			intO <= `allZs;
		else
			intO <= `allXs;			
	end
		
endmodule
module PIPE_BHV_V5_1 (D, CLK, CE, ACLR, SCLR, Q);
	
	parameter C_HAS_ACLR      = 0;
	parameter C_HAS_CE        = 0;
	parameter C_HAS_SCLR      = 1;
	parameter C_PIPE_STAGES   = 2;
	parameter C_WIDTH         = 16; 		
	
	
	input [C_WIDTH-1 : 0] D;
	input CLK;
	input CE;
	input ACLR;
	input SCLR;
	output [C_WIDTH-1 : 0] Q;
	
	reg [C_WIDTH-1 : 0] pipeliner [0 : C_PIPE_STAGES-1];
	reg [C_WIDTH-1 : 0] intQ;
	// Internal values to drive signals when input is missing
	wire intCE;
	wire intACLR;
	wire intSCLR;
	
	wire [C_WIDTH-1 : 0] #1 Q = intQ;
	
	// Sort out default values for missing ports
	
	assign intCE    = defval(CE,    C_HAS_CE,    1);
	assign intACLR  = defval(ACLR,  C_HAS_ACLR,  0);
	assign intSCLR  = defval(SCLR,  C_HAS_SCLR,  0);
	
	reg lastCLK;
	reg lastintACLR;
	
	integer i;
	
	initial 
		begin
			lastCLK     = 1'b0;
			lastintACLR = 1'b0;
			for(i = 0; i < C_PIPE_STAGES; i = i + 1)
				pipeliner[i] = 'b0;
			if(C_PIPE_STAGES != 0)
				begin
					if(C_HAS_ACLR === 1)
						pipeliner[C_PIPE_STAGES-1] = 'b0;
					else if(C_HAS_SCLR === 1)
						pipeliner[C_PIPE_STAGES-1] = 'b0;
					intQ = pipeliner[C_PIPE_STAGES-1];
				end
			else
				assign intQ = D;
		end
	
	always@(posedge CLK or intACLR)
		begin
			// Do not do anything if there is no pipeline
			if(C_PIPE_STAGES > 0)
				begin
					// deal with synchronous events first
					if (CLK !== lastCLK && CLK !== 1'bx && lastCLK !== 1'bx)
						begin
							// First the pipeline
							if(intCE === 1'bx)
								for(i = 0; i < C_PIPE_STAGES; i = i + 1)
									pipeliner[i] = `allXs;
							else if(intCE === 1'b1)
								for(i = C_PIPE_STAGES-1; i > 0; i = i - 1)
									pipeliner[i] = pipeliner[i-1];
							
							// Unqualified behaviour
							if(intCE === 1'b1)
								pipeliner[0] = D;
							
							// Synchronous controls
							if(intSCLR === 1'bx)
								pipeliner[0] = `allXs;
							else if(intSCLR === 1'b1) //Synchronous clear
								for(i = 0; i < C_PIPE_STAGES; i = i + 1)
									pipeliner[i] = 'b0;
						end
					else if(CLK !== lastCLK && (CLK === 1'bx || lastCLK === 1'bx))
						begin
							if(intCE !== 1'b0)
								for(i = 0; i < C_PIPE_STAGES; i = i + 1)
									pipeliner[i] = `allXs;
						end
					
					//Asynchronous Controls - over ride synchronous effects
					if(intACLR === 1'bx)
						pipeliner[C_PIPE_STAGES-1] = `allXs;
					else if(intACLR === 1'b1)
						for(i = 0; i < C_PIPE_STAGES; i = i + 1)
							pipeliner[i] = 'b0;
					
					intQ <= pipeliner[C_PIPE_STAGES-1];
				end
		end
	
	always@(intACLR)
		begin
			lastintACLR <= intACLR;
			
		end
	
	always@(CLK)
		lastCLK <= CLK;
	
	
	function defval;
		input i;
		input hassig;
		input val;
		begin
			if(hassig == 1)
				defval = i;
			else
				defval = val;
		end
	endfunction
	
	
endmodule
module BLK_MEM_GEN_V2_1_output_stage
  #(parameter C_DATA_WIDTH       = 32,
    parameter C_HAS_SSR          = 1,
    parameter C_SINIT_VAL        = "0",
    parameter C_HAS_REGCE        = 1,
    parameter C_HAS_EN           = 1,
    parameter C_FAMILY           = "virtex5",
    parameter num_stages         = 1,
    parameter flop_delay         = 100)
  (input                         CLK,
   input                         SSR,
   input                         REGCE,
   input                         EN,
   input      [C_DATA_WIDTH-1:0] DIN,
   output reg [C_DATA_WIDTH-1:0] DOUT);

  localparam reg_stages  = (num_stages == 0) ? 0 : num_stages-1;
  reg [C_DATA_WIDTH*reg_stages-1:0] out_regs;
  reg [C_DATA_WIDTH*8-1:0]          sinit_str = C_SINIT_VAL;
  reg [C_DATA_WIDTH-1:0]            sinit_val;

  // Wire off optional inputs based on parameters
  //---------------------------------------------
  wire                              en_i;
  wire                              regce_i;
  wire                              ssr_i;
  assign   en_i    = (C_HAS_EN==0 || EN);
  assign   regce_i = ((C_HAS_REGCE==1) && REGCE) ||
                     ((C_HAS_REGCE==0) && (C_HAS_EN==0 || EN));
  assign   ssr_i   = (C_HAS_SSR==1) && SSR;

  initial begin
    // Power on: load up the output registers and latches
    if (!($sscanf(sinit_str, "%h", sinit_val))) begin
      sinit_val = 0;
    end
    DOUT = sinit_val;
    // This will be one wider than need, but 0 is an error
    out_regs = {(reg_stages+1){sinit_val}};
  end

  generate if (num_stages == 0) begin : zero_stages
    always @* begin
      DOUT = DIN;
    end
  end
  endgenerate

 generate if (num_stages == 1) begin : one_stages
    always @(posedge CLK) begin
        if (regce_i && ssr_i) begin
           DOUT <= #flop_delay sinit_val;
        end else if (regce_i) begin
           DOUT <= #flop_delay DIN;
        end
    end
    end
  endgenerate

 generate if (num_stages > 1) begin : multi_stage
    always @(posedge CLK) begin
        if (regce_i && ssr_i) begin
            DOUT           <= #flop_delay sinit_val;
        end else if (regce_i) begin
           DOUT         <= #flop_delay
                        out_regs[C_DATA_WIDTH*(num_stages-2)+:C_DATA_WIDTH];
        end

      if (en_i) begin
        out_regs <= #flop_delay
                    (out_regs << C_DATA_WIDTH) | DIN;
      end
    end
  end
  endgenerate
endmodule
module C_MUX_SLICE_BUFE_V7_0 (I, OE, O);

	parameter C_WIDTH = 16;						/* Width of the single input */	

	input [C_WIDTH-1 : 0] I;
	input OE;
	output [C_WIDTH-1 : 0] O;
	 
	reg [C_WIDTH-1 : 0] intO;

	wire [C_WIDTH-1 : 0] #1 O = intO;
	
	initial 
	begin

		if (OE == 1) 
			intO = I;
		else if (OE == 0) 
			intO = `allZs;
		else
			intO = `allXs;			
	end
	
	always@(I or OE)
	begin
		if (OE == 1) 
			intO <= I;
		else if (OE == 0) 
			intO <= `allZs;
		else
			intO <= `allXs;			
	end
		
endmodule
module PIPE_BHV_V5_0 (D, CLK, CE, ACLR, SCLR, Q);
	
	parameter C_HAS_ACLR      = 0;
	parameter C_HAS_CE        = 0;
	parameter C_HAS_SCLR      = 1;
	parameter C_PIPE_STAGES   = 2;
	parameter C_WIDTH         = 16; 		
	
	
	input [C_WIDTH-1 : 0] D;
	input CLK;
	input CE;
	input ACLR;
	input SCLR;
	output [C_WIDTH-1 : 0] Q;
	
	reg [C_WIDTH-1 : 0] pipeliner [0 : C_PIPE_STAGES-1];
	reg [C_WIDTH-1 : 0] intQ;
	// Internal values to drive signals when input is missing
	wire intCE;
	wire intACLR;
	wire intSCLR;
	
	wire [C_WIDTH-1 : 0] #1 Q = intQ;
	
	// Sort out default values for missing ports
	
	assign intCE    = defval(CE,    C_HAS_CE,    1);
	assign intACLR  = defval(ACLR,  C_HAS_ACLR,  0);
	assign intSCLR  = defval(SCLR,  C_HAS_SCLR,  0);
	
	reg lastCLK;
	reg lastintACLR;
	
	integer i;
	
	initial 
		begin
			lastCLK     = 1'b0;
			lastintACLR = 1'b0;
			for(i = 0; i < C_PIPE_STAGES; i = i + 1)
				pipeliner[i] = 'b0;
			if(C_PIPE_STAGES != 0)
				begin
					if(C_HAS_ACLR === 1)
						pipeliner[C_PIPE_STAGES-1] = 'b0;
					else if(C_HAS_SCLR === 1)
						pipeliner[C_PIPE_STAGES-1] = 'b0;
					intQ = pipeliner[C_PIPE_STAGES-1];
				end
			else
				assign intQ = D;
		end
	
	always@(posedge CLK or intACLR)
		begin
			// Do not do anything if there is no pipeline
			if(C_PIPE_STAGES > 0)
				begin
					// deal with synchronous events first
					if (CLK !== lastCLK && CLK !== 1'bx && lastCLK !== 1'bx)
						begin
							// First the pipeline
							if(intCE === 1'bx)
								for(i = 0; i < C_PIPE_STAGES; i = i + 1)
									pipeliner[i] = `allXs;
							else if(intCE === 1'b1)
								for(i = C_PIPE_STAGES-1; i > 0; i = i - 1)
									pipeliner[i] = pipeliner[i-1];
							
							// Unqualified behaviour
							if(intCE === 1'b1)
								pipeliner[0] = D;
							
							// Synchronous controls
							if(intSCLR === 1'bx)
								pipeliner[0] = `allXs;
							else if(intSCLR === 1'b1) //Synchronous clear
								for(i = 0; i < C_PIPE_STAGES; i = i + 1)
									pipeliner[i] = 'b0;
						end
					else if(CLK !== lastCLK && (CLK === 1'bx || lastCLK === 1'bx))
						begin
							if(intCE !== 1'b0)
								for(i = 0; i < C_PIPE_STAGES; i = i + 1)
									pipeliner[i] = `allXs;
						end
					
					//Asynchronous Controls - over ride synchronous effects
					if(intACLR === 1'bx)
						pipeliner[C_PIPE_STAGES-1] = `allXs;
					else if(intACLR === 1'b1)
						for(i = 0; i < C_PIPE_STAGES; i = i + 1)
							pipeliner[i] = 'b0;
					
					intQ <= pipeliner[C_PIPE_STAGES-1];
				end
		end
	
	always@(intACLR)
		begin
			lastintACLR <= intACLR;
			
		end
	
	always@(CLK)
		lastCLK <= CLK;
	
	
	function defval;
		input i;
		input hassig;
		input val;
		begin
			if(hassig == 1)
				defval = i;
			else
				defval = val;
		end
	endfunction
	
	
endmodule
module C_MUX_SLICE_BUFT_V4_0 (I, T, O);

	parameter C_WIDTH = 16;						/* Width of the single input */	

	input [C_WIDTH-1 : 0] I;
	input T;
	output [C_WIDTH-1 : 0] O;
	 
	reg [C_WIDTH-1 : 0] intO;

	wire [C_WIDTH-1 : 0] #1 O = intO;
	
	initial 
	begin

		if (T == 0) 
			intO = I;
		else if (T == 1) 
			intO = `allZs;
		else
			intO = `allXs;			
	end
	
	always@(I or T)
	begin
		if (T == 0) 
			intO <= I;
		else if (T == 1) 
			intO <= `allZs;
		else
			intO <= `allXs;			
	end
		
endmodule
module MEM_BLK_V5_0( clk,
                     write_en,
                     read_en,
                     wr_addr,
                     rd_addr,
                     data_in,
                     data_out,
                     rst
                   );

parameter addr_value = 4  ;
parameter data_width = 16 ;
parameter mem_depth      = 16 ;


input                    clk;       // input clk.
input                    write_en;    // Write Signal to put datainto fifo.
input                    read_en ;
input  [(addr_value-1):0]  wr_addr;   // Write Address.
input  [(addr_value-1):0]  rd_addr;   // Read Address.
input  [(data_width-1):0]   data_in;   // DataIn in to Memory Block
input                    rst ;

output [(data_width-1):0]   data_out;  // Data Out from the Memory Block(FIFO)

reg  [(data_width-1):0] data_out;  

reg    [(data_width-1):0] FIFO[0:(mem_depth-1)];


initial begin
data_out = 0 ;
end




always @(posedge clk)
begin
   if (rst == 1'b1)
      data_out <= 0 ; 
   else
      begin
        if (read_en == 1'b1) 
          data_out  <= FIFO[rd_addr];
      end
end

always @(posedge clk)
begin
   if(write_en ==1'b1)
      FIFO[wr_addr] <= data_in;
end

endmodule
module C_MUX_SLICE_BUFT_V5_0 (I, T, O);

	parameter C_WIDTH = 16;						/* Width of the single input */	

	input [C_WIDTH-1 : 0] I;
	input T;
	output [C_WIDTH-1 : 0] O;
	 
	reg [C_WIDTH-1 : 0] intO;

	wire [C_WIDTH-1 : 0] #1 O = intO;
	
	initial 
	begin

		if (T == 0) 
			intO = I;
		else if (T == 1) 
			intO = `allZs;
		else
			intO = `allXs;			
	end
	
	always@(I or T)
	begin
		if (T == 0) 
			intO <= I;
		else if (T == 1) 
			intO <= `allZs;
		else
			intO <= `allXs;			
	end
		
endmodule
module C_MUX_SLICE_BUFE_V5_0 (I, OE, O);

	parameter C_WIDTH = 16;						/* Width of the single input */	

	input [C_WIDTH-1 : 0] I;
	input OE;
	output [C_WIDTH-1 : 0] O;
	 
	reg [C_WIDTH-1 : 0] intO;

	wire [C_WIDTH-1 : 0] #1 O = intO;
	
	initial 
	begin

		if (OE == 1) 
			intO = I;
		else if (OE == 0) 
			intO = `allZs;
		else
			intO = `allXs;			
	end
	
	always@(I or OE)
	begin
		if (OE == 1) 
			intO <= I;
		else if (OE == 0) 
			intO <= `allZs;
		else
			intO <= `allXs;			
	end
		
endmodule
module C_MUX_SLICE_BUFE_V6_0 (I, OE, O);

	parameter C_WIDTH = 16;						/* Width of the single input */	

	input [C_WIDTH-1 : 0] I;
	input OE;
	output [C_WIDTH-1 : 0] O;
	 
	reg [C_WIDTH-1 : 0] intO;

	wire [C_WIDTH-1 : 0] #1 O = intO;
	
	initial 
	begin

		if (OE == 1) 
			intO = I;
		else if (OE == 0) 
			intO = `allZs;
		else
			intO = `allXs;			
	end
	
	always@(I or OE)
	begin
		if (OE == 1) 
			intO <= I;
		else if (OE == 0) 
			intO <= `allZs;
		else
			intO <= `allXs;			
	end
		
endmodule
module C_MUX_SLICE_BUFT_V6_0 (I, T, O);

	parameter C_WIDTH = 16;						/* Width of the single input */	

	input [C_WIDTH-1 : 0] I;
	input T;
	output [C_WIDTH-1 : 0] O;
	 
	reg [C_WIDTH-1 : 0] intO;

	wire [C_WIDTH-1 : 0] #1 O = intO;
	
	initial 
	begin

		if (T == 0) 
			intO = I;
		else if (T == 1) 
			intO = `allZs;
		else
			intO = `allXs;			
	end
	
	always@(I or T)
	begin
		if (T == 0) 
			intO <= I;
		else if (T == 1) 
			intO <= `allZs;
		else
			intO <= `allXs;			
	end
		
endmodule
module C_MUX_SLICE_BUFT_V7_0 (I, T, O);

	parameter C_WIDTH = 16;						/* Width of the single input */	

	input [C_WIDTH-1 : 0] I;
	input T;
	output [C_WIDTH-1 : 0] O;
	 
	reg [C_WIDTH-1 : 0] intO;

	wire [C_WIDTH-1 : 0] #1 O = intO;
	
	initial 
	begin

		if (T == 0) 
			intO = I;
		else if (T == 1) 
			intO = `allZs;
		else
			intO = `allXs;			
	end
	
	always@(I or T)
	begin
		if (T == 0) 
			intO <= I;
		else if (T == 1) 
			intO <= `allZs;
		else
			intO <= `allXs;			
	end
		
endmodule
module div_gen
   (clk,
    dividend,
    divisor,
    input_strobe,
    output_strobe,
    quotient);
  (* X_INTERFACE_INFO = "xilinx.com:signal:clock:1.0 CLK.CLK CLK" *) (* X_INTERFACE_PARAMETER = "XIL_INTERFACENAME CLK.CLK, CLK_DOMAIN div_gen_clk, FREQ_HZ 200000000, INSERT_VIP 0, PHASE 0.000" *) input clk;
  (* X_INTERFACE_INFO = "xilinx.com:signal:data:1.0 DATA.DIVIDEND DATA" *) (* X_INTERFACE_PARAMETER = "XIL_INTERFACENAME DATA.DIVIDEND, LAYERED_METADATA undef" *) input [31:0]dividend;
  (* X_INTERFACE_INFO = "xilinx.com:signal:data:1.0 DATA.DIVISOR DATA" *) (* X_INTERFACE_PARAMETER = "XIL_INTERFACENAME DATA.DIVISOR, LAYERED_METADATA undef" *) input [23:0]divisor;
  input input_strobe;
  output output_strobe;
  (* X_INTERFACE_INFO = "xilinx.com:signal:data:1.0 DATA.QUOTIENT DATA" *) (* X_INTERFACE_PARAMETER = "XIL_INTERFACENAME DATA.QUOTIENT, LAYERED_METADATA undef" *) output [31:0]quotient;

  wire clk_1;
  wire [55:0]div_gen_0_m_axis_dout_tdata;
  wire div_gen_0_m_axis_dout_tvalid;
  wire [31:0]dividend_1;
  wire [23:0]divisor_1;
  wire input_strobe_1;
  wire [31:0]xlslice_0_Dout;

  assign clk_1 = clk;
  assign dividend_1 = dividend[31:0];
  assign divisor_1 = divisor[23:0];
  assign input_strobe_1 = input_strobe;
  assign output_strobe = div_gen_0_m_axis_dout_tvalid;
  assign quotient[31:0] = xlslice_0_Dout;
  div_gen_div_gen_0_0 div_gen_0
       (.aclk(clk_1),
        .m_axis_dout_tdata(div_gen_0_m_axis_dout_tdata),
        .m_axis_dout_tvalid(div_gen_0_m_axis_dout_tvalid),
        .s_axis_dividend_tdata(dividend_1),
        .s_axis_dividend_tvalid(input_strobe_1),
        .s_axis_divisor_tdata(divisor_1),
        .s_axis_divisor_tvalid(input_strobe_1));
  div_gen_xlslice_0_0 xlslice_0
       (.Din(div_gen_0_m_axis_dout_tdata),
        .Dout(xlslice_0_Dout));
endmodule
module axi_master_generic (/*AUTOARG*/
   // Outputs
   awid, awadr, awlen, awsize, awburst, awlock, awcache, awprot,
   awvalid, wid, wrdata, wstrb, wlast, wvalid, bid, bresp, bvalid,
   arid, araddr, arlen, arsize, arlock, arcache, arprot, arvalid,
   rready,
   // Inputs
   aclk, aresetn, awready, wready, bready, arready, rid, rdata, rresp,
   rlast, rvalid
   ) ;
   //
   // Global Signals
   //
   input wire aclk;
   input wire aresetn;   //Active LOW
   
   //
   // Write Address Channel
   //
   output reg [3:0] awid;     // Address Write ID
   output reg [31:0] awadr;   // Write Address
   output reg [3:0]  awlen;   // Burst Length
   output reg [2:0]  awsize;  // Burst Size
   output reg [1:0]  awburst; // Burst Type
   output reg [1:0]  awlock;  // Lock Type
   output reg [3:0]  awcache; // Cache Type
   output reg [2:0]  awprot;  // Protection Type
   output reg        awvalid; // Write Address Valid   
   input wire        awready; // Write Address Ready

   //
   // Write Data Channel
   //
   output reg [3:0]  wid;     // Write ID
   output reg [31:0] wrdata;  // Write Data
   output reg [3:0]  wstrb;   // Write Strobes
   output reg        wlast;   // Write Last
   output reg        wvalid;  // Write Valid   
   input wire        wready;  // Write Ready
   
   //
   // Write Response CHannel
   //
   output reg [3:0]  bid;    // Response ID
   output reg [1:0]  bresp;  // Write Response
   output reg        bvalid; // Write Response Valid   
   input wire        bready; // Response Ready
   
   //
   // Read Address Channel
   //
   output reg [3:0]  arid;    // Read Address ID
   output reg [31:0] araddr;  // Read Address
   output reg [3:0]  arlen;   // Burst Length
   output reg [2:0]  arsize;  // Burst Size
   output reg [1:0]  arlock;  // Lock Type
   output reg [3:0]  arcache; // Cache Type
   output reg [2:0]  arprot;  // Protection Type
   output reg        arvalid; // Read Address Valid   
   input wire        arready; // Read Address Ready
   input wire [3:0]  rid;     // Read ID
   input wire [31:0] rdata;   // Read Data
   input wire [1:0]  rresp;   // Read Response
   input wire        rlast;   // Read Last
   input wire        rvalid;  // Read Valid
   output reg        rready;  // Read Ready
   
endmodule // axi_master_generic
module axi_slave_bfm (/*AUTOARG*/
   // Outputs
   awready, wready, bid, bresp, bvalid, arready, rid, rdata, rresp,
   rlast, rvalid,
   // Inputs
   aclk, aresetn, awid, awadr, awlen, awsize, awburst, awlock,
   awcache, awprot, awvalid, wid, wrdata, wstrb, wlast, wvalid,
   bready, arid, araddr, arlen, arsize, arlock, arcache, arprot,
   arvalid, rready
   ) ;

   //
   // Global Signals
   //
   input wire aclk;
   input wire aresetn;   //Active LOW
   
   //
   // Write Address Channel
   //
   input wire [3:0] awid;     // Address Write ID
   input wire [31:0] awadr;   // Write Address
   input wire [3:0]  awlen;   // Burst Length
   input wire [2:0]  awsize;  // Burst Size
   input wire [1:0]  awburst; // Burst Type
   input wire [1:0]  awlock;  // Lock Type
   input wire [3:0]  awcache; // Cache Type
   input wire [2:0]  awprot;  // Protection Type
   input wire        awvalid; // Write Address Valid
   output reg        awready; // Write Address Ready

   //
   // Write Data Channel
   //
   input wire [3:0]  wid;     // Write ID
   input wire [31:0] wrdata;  // Write Data
   input wire [3:0]  wstrb;   // Write Strobes
   input wire        wlast;   // Write Last
   input wire        wvalid;  // Write Valid
   output reg        wready;  // Write Ready
   
   //
   // Write Response CHannel
   //
   output reg [3:0]  bid;    // Response ID
   output reg [1:0]  bresp;  // Write Response
   output reg        bvalid; // Write Response Valid
   input wire        bready; // Response Ready
   
   //
   // Read Address Channel
   //
   input wire [3:0]  arid;    // Read Address ID
   input wire [31:0] araddr;  // Read Address
   input wire [3:0]  arlen;   // Burst Length
   input wire [2:0]  arsize;  // Burst Size
   input wire [1:0]  arlock;  // Lock Type
   input wire [3:0]  arcache; // Cache Type
   input wire [2:0]  arprot;  // Protection Type
   input wire        arvalid; // Read Address Valid
   output reg        arready; // Read Address Ready
   output reg [3:0]  rid;     // Read ID
   output reg [31:0] rdata;   // Read Data
   output reg [1:0]  rresp;   // Read Response
   output reg        rlast;   // Read Last
   output reg        rvalid;  // Read Valid
   input  wire       rready;  // Read Ready
   
   
   
endmodule // axi_slave_bfm
module testbench2;

reg [31:0] address, data;
reg mode, clk;
wire [31:0] out;

cache_and_ram tb(
	.address(address),
	.data(data),
	.mode(mode),
	.clk(clk),
	.out(out)
);

initial
begin
	clk = 1'b1;
	
	address = 32'b00000000000000000000000000000000;			// 0
	data =    32'b00000000000000000011100011000000;			// 14528
	mode = 1'b1;
	
	#200
	address = 32'b10100111111001011111101111011100;			// 2816867292 % size = 3036
	data =    32'b00000000000010000000100001010101;			// 526421
	mode = 1'b1;
	
	#200
	address = 32'b00000000000000000000000000000000;			// 0
	data =    32'b00000000000000000011100011000000;			// 14528
	mode = 1'b0;
	
	#200
	address = 32'b10100111111001011111101111011100;			// 2816867292 % size = 3036
	data =    32'b00000000000010000000100001010101;			// 526421
	mode = 1'b0;
	
	#200
	address = 32'b00000000000011110100011111010001;			// 1001425 % size = 2001
	data =    32'b00000001100000110001101100010110;			// 25369366
	mode = 1'b1;

	#200
	address = 32'b00000000000011110100011111010001;			// 1001425 % size = 2001
	data =    32'b00000001100000110001101100010110;			// 25369366
	mode = 1'b0;

	#200
	address = 32'b10100111111001011111101111011100;			// 2816867292 % size = 3036
	data =    32'b00000000000000000011100011000000;			// 14528
	mode = 1'b1;

	#200
	address = 32'b00000000000011110100011111010001;			// 1001425 % size = 2001
	data =    32'b00000000000000000011100011000000;			// 14528
	mode = 1'b1;

	#200
	address = 32'b00000000000011110100011111010001;			// 1001425 % size = 2001
	data =    32'b00000000000000000000000000000000;			// 0
	mode = 1'b0;
	
	#200
	address = 32'b10100111111001011111101111011100;			// 2816867292 % size = 3036
	data =    32'b00000000000000000000000000000000;			// 0
	mode = 1'b0;
end

initial
$monitor("address = %d data = %d mode = %d out = %d", address % 4096, data, mode, out);

always #25 clk = ~clk;

endmodule
module ram();

parameter size = 4096; //size of a ram in bits

reg [31:0] ram [0:size-1]; //data matrix for ram

endmodule
module testbench;

reg [31:0] address, data;
reg mode, clk;
wire [31:0] out;

cache_and_ram tb(
	.address(address),
	.data(data),
	.mode(mode),
	.clk(clk),
	.out(out)
);

initial
begin
	clk = 1'b1;
	
	address = 32'b00000000000000000000000000000000;			// 0
	data =    32'b00000000000000000011100011000000;			// 14528
	mode = 1'b1;
	
	#200
	address = 32'b10100111111001011111101111011100;			// 2816867292 % size = 3036
	data =    32'b00000000000010000000100001010101;			// 526421
	mode = 1'b1;
	
	#200
	address = 32'b00000000000011110100011111010001;			// 1001425 % size = 2001
	data =    32'b00000001100000110001101100010110;			// 25369366
	mode = 1'b1;

	#200
	address = 32'b10100111111001011111101111011100;			// 2816867292 % size = 3036
	data =    32'b00000000000000000011100011000000;			// 14528
	mode = 1'b1;

	#200
	address = 32'b00000000000011110100011111010001;			// 1001425 % size = 2001
	data =    32'b00000000000000000011100011000000;			// 14528
	mode = 1'b1;

	#200
	address = 32'b00000000000011110100011111010001;			// 1001425 % size = 2001
	data =    32'b00000000000000000000000000000000;			// 0
	mode = 1'b0;
	
	#200
	address = 32'b10100111111001011111101111011100;			// 2816867292 % size = 3036
	data =    32'b00000000000000000000000000000000;			// 0
	mode = 1'b0;
		
	#200
	address = 32'b00000000000000000000000000000000;			// 0
	data =    32'b00000000000000000011100011000000;			// 14528
	mode = 1'b0;
end

initial
$monitor("address = %d data = %d mode = %d out = %d", address % 4096, data, mode, out);

always #25 clk = ~clk;

endmodule
module cache();

parameter size = 64;		// cache size
parameter index_size = 6;	// index size


reg [31:0] cache [0:size - 1]; //registers for the data in cache
reg [11 - index_size:0] tag_array [0:size - 1]; // for all tags in cache
reg valid_array [0:size - 1]; //0 - there is no data 1 - there is data

initial
	begin: initialization
		integer i;
		for (i = 0; i < size; i = i + 1)
		begin
			valid_array[i] = 1'b0;
			tag_array[i] = 6'b000000;
		end
	end

endmodule
module serializer(
	 input clk,
    input clk35,
	 input notclk35,
    input [6:0] data,
	 input rst,
    output out
    );

reg [6:0] buffer [1:0];	//	14 bits buffer
reg [1:0] shiftdata = 0;

reg datacount = 0; 
reg [2:0] outcount = 0;

reg DataInBuffer = 0;
reg SendOK = 0;

ODDR2 #(
      .DDR_ALIGNMENT("NONE") // Sets output alignment to "NONE", "C0" or "C1" 
   ) clock_forward_inst (
      .Q(out),     // 1-bit DDR output data
      .C0(clk35),  // 1-bit clock input
      .C1(notclk35), // 1-bit clock input
      .CE(1'b1),      // 1-bit clock enable input
      .D0(shiftdata[0]), // 1-bit data input (associated with C0)
      .D1(shiftdata[1]), // 1-bit data input (associated with C1)
      .R(1'b0),   // 1-bit reset input
      .S(1'b0)   // 1-bit set input
   );

always @(posedge clk or posedge rst)
begin
		if(rst == 1'b1)
		begin
			buffer[0] 		<= 7'b0000000;
			buffer[1] 		<= 7'b0000000;
			datacount 	<= 0;
			DataInBuffer <= 0;
		end
		else
		begin
			DataInBuffer <= 1;
			datacount <= datacount + 1;
			buffer[datacount] <= data;
			//buffer[datacount] <= {data[6],data[5],data[4],data[3],data[2],data[1],data[0]};
		end
end

always @(posedge clk35 or posedge rst)
begin
		if(rst == 1'b1)
		begin
			outcount <= 0;
			shiftdata <= 0;
			SendOK <= 0;
		end
		else
		begin
			if(outcount == 6)
				outcount <= 0;
			else
				outcount <= outcount + 1;
				
			if(DataInBuffer && outcount == 6)
					SendOK <= 1;
					
			if(SendOK)
			begin
				case (outcount)
					0:	shiftdata <= { buffer[0][0], buffer[0][1] };
					1:	shiftdata <= { buffer[0][2], buffer[0][3] };
					2:	shiftdata <= { buffer[0][4], buffer[0][5] };
					3:	shiftdata <= { buffer[0][6], buffer[1][0] };
					4:	shiftdata <= { buffer[1][1], buffer[1][2] };
					5:	shiftdata <= { buffer[1][3], buffer[1][4] };
					6:	shiftdata <= { buffer[1][5], buffer[1][6] };
				endcase
			end
		end
end

endmodule
module lvds_clockgen(
    input clk,
    output clk35,
    output nclk35,
	 output rstclk,
	 output dataclock,
    output lvdsclk
    );
	 

// Clock: 1100011

wire clk_lckd;
wire clkdcm;
wire clo;

DCM_SP #(.CLKIN_PERIOD	("15.625"),
	.DESKEW_ADJUST	("0"),	
	.CLKFX_MULTIPLY	(7),
	.CLKFX_DIVIDE	(2))	
dcm_clk (
	.CLKIN   	(clk),
	.CLKFB   	(clo),
	.RST     	(1'b0),
	.CLK0    	(clkdcm),
	.CLKFX   	(clk35),
	.CLKFX180	(nclk35),
	.CLK180		(),
	.CLK270		(),
	.CLK2X		(),
	.CLK2X180	(),
	.CLK90		(),
	.CLKDV		(),
	.PSDONE		(),
	.STATUS		(),
	.DSSEN 		(1'b0),
	.PSINCDEC	(1'b0),
	.PSEN 		(1'b0),
	.PSCLK 		(1'b0),
	.LOCKED  	(clk_lckd)) ;
	
BUFG 	clk_bufg	(.I(clkdcm), 		.O(clo) ) ;

assign not_clk_lckd = ~clk_lckd ;

FDP fd_rst_clk (.D(not_clk_lckd), .C(clo), .Q(rst_clk)) ;

// The LVDS Clock is 4:3, if you need 3:4 you can use 7'b0011100
serializer lvdsclkman (
    .clk(clo), 
    .clk35(clk35), 
    .notclk35(nclk35), 
    .data(7'b1100011),
	 .rst(rst_clk),
	 .out(lvdsclk)
    ); 

assign rstclk = rst_clk;
assign dataclock = clo;
endmodule
module video_lvds(
		input DotClock,
		input HSync,
		input VSync,
		input DataEnable,
		input [5:0] Red,
		input [5:0] Green,
		input [5:0] Blue,
		output channel1_p,
		output channel1_n,
		output channel2_p,
		output channel2_n,
		output channel3_p,
		output channel3_n,
		output clock_p,
		output clock_n
    );
	 
wire clk35, notclk35, c1,c2,c3,lvdsclk, rst_clk, DataClock;
wire [20:0] VideoData;

OBUFDS	#(.IOSTANDARD("LVDS_33")) lvds_channel1_obuf	(.I(c1),   		 .O(channel1_p),    .OB(channel1_n) );
OBUFDS	#(.IOSTANDARD("LVDS_33")) lvds_channel2_obuf	(.I(c2),   	    .O(channel2_p),    .OB(channel2_n) );
OBUFDS	#(.IOSTANDARD("LVDS_33")) lvds_channel3_obuf	(.I(c3),   		 .O(channel3_p),    .OB(channel3_n) );
OBUFDS	#(.IOSTANDARD("LVDS_33")) lvds_clock_obuf		(.I(lvdsclk),   .O(clock_p),	     .OB(clock_n) );


lvds_clockgen clockgenerator (
    .clk(DotClock), 
    .clk35(clk35), 
    .nclk35(notclk35), 
	 .rstclk(rst_clk),
	 .dataclock(DataClock),
    .lvdsclk(lvdsclk)
    );

serializer channel1_ser (
    .clk(DataClock), 
    .clk35(clk35), 
    .notclk35(notclk35), 
    .data(VideoData[6:0]), 
	 .rst(rst_clk),
    .out(c1)
    );
	 
serializer channel2_ser (
    .clk(DataClock), 
    .clk35(clk35), 
    .notclk35(notclk35), 
    .data(VideoData[13:7]), 
	 .rst(rst_clk),
    .out(c2)
    );

serializer channel3_ser (
    .clk(DataClock), 
    .clk35(clk35), 
    .notclk35(notclk35), 
    .data(VideoData[20:14]), 
	 .rst(rst_clk),
    .out(c3)
    );

assign VideoData[20:14]	= {Blue[2],Blue[3],Blue[4],Blue[5],HSync,VSync,DataEnable};
assign VideoData[13:7]  = {Green[1],Green[2],Green[3],Green[4],Green[5],Blue[0],Blue[1]};
assign VideoData[6:0]	= {Red[0],Red[1],Red[2],Red[3],Red[4],Red[5],Green[0]};


endmodule
module hbmc_clk_obuf #
(
    parameter integer DRIVE_STRENGTH = 8,
    parameter         SLEW_RATE      = "SLOW"
)
(
    input   wire    cen,
    input   wire    clk,
    output  wire    hb_ck_p,
    output  wire    hb_ck_n
);

    wire    oddr_clk_p;
    wire    oddr_clk_n;

/*----------------------------------------------------------------------------------------------------------------------------*/
    
    ODDR #
    (
        .DDR_CLK_EDGE ( "SAME_EDGE" ),  // "OPPOSITE_EDGE" or "SAME_EDGE"
        .INIT         ( 1'b0        ),  // Initial value of Q: 1'b0 or 1'b1
        .SRTYPE       ( "ASYNC"     )   // Set/Reset type: "SYNC" or "ASYNC"
    )
    ODDR_ck_p
    (
        .Q  ( oddr_clk_p ),     // 1-bit DDR output
        .C  ( ~clk       ),     // 1-bit clock input
        .CE ( 1'b1       ),     // 1-bit clock enable input
        .D1 ( cen        ),     // 1-bit data input (positive edge)
        .D2 ( 1'b0       ),     // 1-bit data input (negative edge)
        .R  ( 1'b0       ),     // 1-bit reset
        .S  ( 1'b0       )      // 1-bit set
    );
    
    
    OBUF #
    (
        .DRIVE  ( DRIVE_STRENGTH ),     // Specify the output drive strength
        .SLEW   ( SLEW_RATE      )      // Specify the output slew rate
    )
    OBUF_ck_p
    (
        .I  ( oddr_clk_p ),     // Buffer input
        .O  ( hb_ck_p    )      // Buffer output (connect directly to top-level port)
    );
    
/*----------------------------------------------------------------------------------------------------------------------------*/
    
    ODDR #
    (
        .DDR_CLK_EDGE ( "SAME_EDGE" ),  // "OPPOSITE_EDGE" or "SAME_EDGE"
        .INIT         ( 1'b0        ),  // Initial value of Q: 1'b0 or 1'b1
        .SRTYPE       ( "ASYNC"     )   // Set/Reset type: "SYNC" or "ASYNC"
    )
    ODDR_ck_n
    (
        .Q  ( oddr_clk_n ),     // 1-bit DDR output
        .C  ( ~clk       ),     // 1-bit clock input
        .CE ( 1'b1       ),     // 1-bit clock enable input
        .D1 ( ~cen       ),     // 1-bit data input (positive edge)
        .D2 ( 1'b1       ),     // 1-bit data input (negative edge)
        .R  ( 1'b0       ),     // 1-bit reset
        .S  ( 1'b0       )      // 1-bit set
    );
    
    
    OBUF #
    (
        .DRIVE  ( DRIVE_STRENGTH ),     // Specify the output drive strength
        .SLEW   ( SLEW_RATE      )      // Specify the output slew rate
    )
    OBUF_ck_n
    (
        .I  ( oddr_clk_n ),     // Buffer input
        .O  ( hb_ck_n    )      // Buffer output (connect directly to top-level port)
    );

endmodule
module hbmc_bit_sync #
(
    parameter integer C_SYNC_STAGES = 3,
    parameter         C_RESET_STATE = 1'b0
)
(
    input   wire    arst,
    input   wire    clk,
    input   wire    d,
    output  wire    q
);

    (* shreg_extract = "no", ASYNC_REG = "TRUE" *)  reg [C_SYNC_STAGES - 1:0] d_sync;
    
    
    always @(posedge clk or posedge arst) begin
        if (arst) begin
            d_sync <= {C_SYNC_STAGES{C_RESET_STATE}};
        end else begin
            d_sync <= {d_sync[C_SYNC_STAGES - 2:0], d};
        end 
    end
    
    
    assign q = d_sync[C_SYNC_STAGES - 1];
    
endmodule
module hbmc_bus_sync #
(
    parameter integer C_SYNC_STAGES = 3,
    parameter integer C_DATA_WIDTH  = 8
)
(
    input   wire                            src_clk,
    input   wire                            src_rst,
    input   wire    [C_DATA_WIDTH - 1 : 0]  src_data,
    input   wire                            src_req,
    output  wire                            src_ack,

    input   wire                            dst_clk,
    input   wire                            dst_rst,
    output  reg     [C_DATA_WIDTH - 1 : 0]  dst_data,
    output  reg                             dst_req,
    input   wire                            dst_ack
);

/*----------------------------------------------------------------------------------------------------------------------------*/
    
    wire    src_req_sync;
    
    
    hbmc_bit_sync #
    (
        .C_SYNC_STAGES  ( C_SYNC_STAGES ),
        .C_RESET_STATE  ( 1'b0          )
    )
    hbmc_bit_sync_inst_0
    (
        .arst   ( dst_rst      ),
        .clk    ( dst_clk      ),
        .d      ( src_req      ),
        .q      ( src_req_sync )
    );

/*----------------------------------------------------------------------------------------------------------------------------*/

    reg     src_ack_async;
    
    
    hbmc_bit_sync #
    (
        .C_SYNC_STAGES  ( C_SYNC_STAGES ),
        .C_RESET_STATE  ( 1'b0          )
    )
    hbmc_bit_sync_inst_1
    (
        .arst   ( src_rst       ),
        .clk    ( src_clk       ),
        .d      ( src_ack_async ),
        .q      ( src_ack       )
    );

/*----------------------------------------------------------------------------------------------------------------------------*/

    localparam  ST_GET = 1'b0,
                ST_SET = 1'b1;

    reg         state;


    always @(posedge dst_clk or posedge dst_rst) begin
        if (dst_rst) begin
            src_ack_async <= 1'b0;
            dst_req       <= 1'b0;
            dst_data      <= {C_DATA_WIDTH{1'b0}};
            state         <= ST_GET;
        end else begin
            case (state)
                ST_GET: begin
                    if (src_req_sync & ~dst_ack) begin
                        src_ack_async <= 1'b1;
                        dst_req       <= 1'b1;
                        dst_data      <= src_data;
                        state         <= ST_SET;
                    end
                end
                
                ST_SET: begin
                    if (dst_ack) begin
                        dst_req <= 1'b0;
                    end
                    
                    if (~src_req_sync) begin
                        src_ack_async <= 1'b0;
                    end
                    
                    if (~dst_req & ~src_ack_async) begin
                        state <= ST_GET;
                    end
                end
            endcase
        end
    end
    
endmodule
module hbmc_arst_sync #
(
    parameter integer C_SYNC_STAGES = 3
)
(
    input   wire    clk,
    input   wire    arst,
    output  wire    rst
);
    
    hbmc_bit_sync #
    (
        .C_SYNC_STAGES  ( C_SYNC_STAGES ),
        .C_RESET_STATE  ( 1'b1          )
    )
    hbmc_bit_sync_inst
    (
        .arst   ( arst ),
        .clk    ( clk  ),
        .d      ( 1'b0 ),
        .q      ( rst  )
    );
    
endmodule
module top
(
    input   wire            clkin,
    
    output  wire            hram_ck_p,
    output  wire            hram_ck_n,
    output  wire            hram_reset_n,
    output  wire            hram_cs_n,
    inout   wire            hram_rwds,
    inout   wire    [7:0]   hram_dq
);
    
/*----------------------------------------------------------------------------------------------------------------------------*/

    SoC
    SoC_inst
    (
        .clkin               ( clkin        ),
        .resetn              ( 1'b1         ),
        .HyperBus_hb_ck_p    ( hram_ck_p    ),
        .HyperBus_hb_ck_n    ( hram_ck_n    ),
        .HyperBus_hb_cs_n    ( hram_cs_n    ),
        .HyperBus_hb_dq      ( hram_dq      ),
        .HyperBus_hb_reset_n ( hram_reset_n ),
        .HyperBus_hb_rwds    ( hram_rwds    )
    );

endmodule
module testbench;
	reg clk = 1;
	reg resetn = 0;
	wire trap;

	always #5 clk = ~clk;

	initial begin
		repeat (100) @(posedge clk);
		resetn <= 1;
	end

	wire mem_valid;
	wire mem_instr;
	reg  mem_ready;
	wire [31:0] mem_addr;
	wire [31:0] mem_wdata;
	wire [3:0]  mem_wstrb;
	reg  [31:0] mem_rdata;

	picorv32 #(
		.BARREL_SHIFTER(1),
		.ENABLE_FAST_MUL(1),
		.ENABLE_DIV(1),
		.PROGADDR_RESET('h10000),
		.STACKADDR('h10000)
	) uut (
		.clk         (clk        ),
		.resetn      (resetn     ),
		.trap        (trap       ),
		.mem_valid   (mem_valid  ),
		.mem_instr   (mem_instr  ),
		.mem_ready   (mem_ready  ),
		.mem_addr    (mem_addr   ),
		.mem_wdata   (mem_wdata  ),
		.mem_wstrb   (mem_wstrb  ),
		.mem_rdata   (mem_rdata  )
	);

	reg [7:0] memory [0:256*1024-1];
	initial $readmemh("dhry.hex", memory);

	always @(posedge clk) begin
		mem_ready <= 1'b0;

		mem_rdata[ 7: 0] <= 'bx;
		mem_rdata[15: 8] <= 'bx;
		mem_rdata[23:16] <= 'bx;
		mem_rdata[31:24] <= 'bx;

		if (mem_valid & !mem_ready) begin
			if (|mem_wstrb) begin
				mem_ready <= 1'b1;

				case (mem_addr)
					32'h1000_0000: begin
						$write("%c", mem_wdata);
						$fflush();
					end
					default: begin
						if (mem_wstrb[0]) memory[mem_addr + 0] <= mem_wdata[ 7: 0];
						if (mem_wstrb[1]) memory[mem_addr + 1] <= mem_wdata[15: 8];
						if (mem_wstrb[2]) memory[mem_addr + 2] <= mem_wdata[23:16];
						if (mem_wstrb[3]) memory[mem_addr + 3] <= mem_wdata[31:24];
					end
				endcase
			end
			else begin
				mem_ready <= 1'b1;

				mem_rdata[ 7: 0] <= memory[mem_addr + 0];
				mem_rdata[15: 8] <= memory[mem_addr + 1];
				mem_rdata[23:16] <= memory[mem_addr + 2];
				mem_rdata[31:24] <= memory[mem_addr + 3];
			end
		end
	end

	initial begin
		$dumpfile("testbench_nola.vcd");
		$dumpvars(0, testbench);
	end

	always @(posedge clk) begin
		if (resetn && trap) begin
			repeat (10) @(posedge clk);
			$display("TRAP");
			$finish;
		end
	end
endmodule
module testbench;
	reg clk = 1;
	reg resetn = 0;
	wire trap;

	always #5 clk = ~clk;

	initial begin
		repeat (100) @(posedge clk);
		resetn <= 1;
	end

	wire mem_valid;
	wire mem_instr;
	wire mem_ready;
	wire [31:0] mem_addr;
	wire [31:0] mem_wdata;
	wire [3:0] mem_wstrb;
	reg  [31:0] mem_rdata;

	wire mem_la_read;
	wire mem_la_write;
	wire [31:0] mem_la_addr;
	wire [31:0] mem_la_wdata;
	wire [3:0] mem_la_wstrb;

	wire trace_valid;
	wire [35:0] trace_data;

	picorv32 #(
		.BARREL_SHIFTER(1),
		.ENABLE_FAST_MUL(1),
		.ENABLE_DIV(1),
		.PROGADDR_RESET('h10000),
		.STACKADDR('h10000),
		.ENABLE_TRACE(1)
	) uut (
		.clk         (clk        ),
		.resetn      (resetn     ),
		.trap        (trap       ),
		.mem_valid   (mem_valid  ),
		.mem_instr   (mem_instr  ),
		.mem_ready   (mem_ready  ),
		.mem_addr    (mem_addr   ),
		.mem_wdata   (mem_wdata  ),
		.mem_wstrb   (mem_wstrb  ),
		.mem_rdata   (mem_rdata  ),
		.mem_la_read (mem_la_read ),
		.mem_la_write(mem_la_write),
		.mem_la_addr (mem_la_addr ),
		.mem_la_wdata(mem_la_wdata),
		.mem_la_wstrb(mem_la_wstrb),
		.trace_valid (trace_valid),
		.trace_data  (trace_data )
	);

	reg [7:0] memory [0:256*1024-1];
	initial $readmemh("dhry.hex", memory);

	assign mem_ready = 1;

	always @(posedge clk) begin
		mem_rdata[ 7: 0] <= mem_la_read ? memory[mem_la_addr + 0] : 'bx;
		mem_rdata[15: 8] <= mem_la_read ? memory[mem_la_addr + 1] : 'bx;
		mem_rdata[23:16] <= mem_la_read ? memory[mem_la_addr + 2] : 'bx;
		mem_rdata[31:24] <= mem_la_read ? memory[mem_la_addr + 3] : 'bx;
		if (mem_la_write) begin
			case (mem_la_addr)
				32'h1000_0000: begin
`ifndef TIMING
					$write("%c", mem_la_wdata);
					$fflush();
`endif
				end
				default: begin
					if (mem_la_wstrb[0]) memory[mem_la_addr + 0] <= mem_la_wdata[ 7: 0];
					if (mem_la_wstrb[1]) memory[mem_la_addr + 1] <= mem_la_wdata[15: 8];
					if (mem_la_wstrb[2]) memory[mem_la_addr + 2] <= mem_la_wdata[23:16];
					if (mem_la_wstrb[3]) memory[mem_la_addr + 3] <= mem_la_wdata[31:24];
				end
			endcase
		end
	end

	initial begin
		$dumpfile("testbench.vcd");
		$dumpvars(0, testbench);
	end

	integer trace_file;

	initial begin
		if ($test$plusargs("trace")) begin
			trace_file = $fopen("testbench.trace", "w");
			repeat (10) @(posedge clk);
			while (!trap) begin
				@(posedge clk);
				if (trace_valid)
					$fwrite(trace_file, "%x\n", trace_data);
			end
			$fclose(trace_file);
			$display("Finished writing testbench.trace.");
		end
	end

	always @(posedge clk) begin
		if (resetn && trap) begin
			repeat (10) @(posedge clk);
			$display("TRAP");
			$finish;
		end
	end

`ifdef TIMING
	initial begin
		repeat (100000) @(posedge clk);
		$finish;
	end
	always @(posedge clk) begin
		if (uut.dbg_next)
			$display("## %-s %d", uut.dbg_ascii_instr ? uut.dbg_ascii_instr : "pcpi", uut.count_cycle);
	end
`endif
endmodule
module testbench;
	reg clk;
	always #5 clk = (clk === 1'b0);

	localparam ser_half_period = 53;
	event ser_sample;

	initial begin
		$dumpfile("testbench.vcd");
		$dumpvars(0, testbench);

		repeat (6) begin
			repeat (50000) @(posedge clk);
			$display("+50000 cycles");
		end
		$finish;
	end

	integer cycle_cnt = 0;

	always @(posedge clk) begin
		cycle_cnt <= cycle_cnt + 1;
	end

	wire [7:0] leds;

	wire ser_rx;
	wire ser_tx;

	wire flash_csb;
	wire flash_clk;
	wire flash_io0;
	wire flash_io1;
	wire flash_io2;
	wire flash_io3;

	always @(leds) begin
		#1 $display("%b", leds);
	end

	hx8kdemo uut (
		.clk      (clk      ),
		.leds     (leds     ),
		.ser_rx   (ser_rx   ),
		.ser_tx   (ser_tx   ),
		.flash_csb(flash_csb),
		.flash_clk(flash_clk),
		.flash_io0(flash_io0),
		.flash_io1(flash_io1),
		.flash_io2(flash_io2),
		.flash_io3(flash_io3)
	);

	spiflash spiflash (
		.csb(flash_csb),
		.clk(flash_clk),
		.io0(flash_io0),
		.io1(flash_io1),
		.io2(flash_io2),
		.io3(flash_io3)
	);

	reg [7:0] buffer;

	always begin
		@(negedge ser_tx);

		repeat (ser_half_period) @(posedge clk);
		-> ser_sample; // start bit

		repeat (8) begin
			repeat (ser_half_period) @(posedge clk);
			repeat (ser_half_period) @(posedge clk);
			buffer = {ser_tx, buffer[7:1]};
			-> ser_sample; // data bit
		end

		repeat (ser_half_period) @(posedge clk);
		repeat (ser_half_period) @(posedge clk);
		-> ser_sample; // stop bit

		if (buffer < 32 || buffer >= 127)
			$display("Serial data: %d", buffer);
		else
			$display("Serial data: '%c'", buffer);
	end
endmodule