dakies/OSS_Verilog huggingface dataset:
module apple1_de0_top #(
    parameter BASIC_FILENAME      = "../../../roms/basic.hex",
    parameter FONT_ROM_FILENAME   = "../../../roms/vga_font_bitreversed.hex",
    parameter RAM_FILENAME        = "../../../roms/ram.hex",
    parameter VRAM_FILENAME       = "../../../roms/vga_vram.bin",
    parameter WOZMON_ROM_FILENAME = "../../../roms/wozmon.hex"
) (
    input   CLOCK_50,       // the 50 MHz DE0 master clock

    // UART I/O signals
    output  UART_TXD,       // UART transmit pin on DE0 board
    input   UART_RXD,       // UART receive pin on DE0 board
    output  UART_CTS,       // UART clear-to-send pin on DE0 board
    
    output  [7:0] LEDG,     // monitoring for lower 8 address bits
    input   [2:0] BUTTON,   // BUTTON[0] for reset
    output  [6:0] HEX0_D,
    output  [6:0] HEX1_D,
    output  [6:0] HEX2_D,
    output  [6:0] HEX3_D,
    
    input   PS2_KBCLK,
    input   PS2_KBDAT,

    output  [3:0] VGA_R,
    output  [3:0] VGA_G,
    output  [3:0] VGA_B,
    output  VGA_HS,
    output  VGA_VS    
);

    //////////////////////////////////////////////////////////////////////////    
    // Registers and Wires
    reg clk25;
    wire [15:0] pc_monitor;

    // generate 25MHz clock from 50MHz master clock
    always @(posedge CLOCK_50)
    begin
        clk25 <= ~clk25;
    end
    
    wire r_bit, g_bit, b_bit;
    
    //////////////////////////////////////////////////////////////////////////    
    // Core of system
    apple1 #(
        .BASIC_FILENAME (BASIC_FILENAME),
        .FONT_ROM_FILENAME (FONT_ROM_FILENAME),
        .RAM_FILENAME (RAM_FILENAME),
        .VRAM_FILENAME (VRAM_FILENAME),
        .WOZMON_ROM_FILENAME (WOZMON_ROM_FILENAME)
    ) apple1_top(
        .clk25(clk25),
        .rst_n(BUTTON[0]),       // we don't have any reset pulse..
        .uart_rx(UART_RXD),
        .uart_tx(UART_TXD),
        .uart_cts(UART_CTS),
        .ps2_clk(PS2_KBCLK),
        .ps2_din(PS2_KBDAT),
        .ps2_select(1'b1),
        .vga_h_sync(VGA_HS),
        .vga_v_sync(VGA_VS),
        .vga_red(r_bit),
        .vga_grn(g_bit),
        .vga_blu(b_bit),
        .pc_monitor(pc_monitor)
    );

    // set the monochrome base colour here.. 
    assign VGA_R[3:0] = {4{r_bit}};
    assign VGA_G[3:0] = {4{g_bit}};
    assign VGA_B[3:0] = {4{b_bit}};

    //////////////////////////////////////////////////////////////////////////    
    // Display 6502 address on 7-segment displays
    
    segmentdisplay seg1(
        .clk(clk25),
        .latch(1'b1),
        .hexdigit_in(pc_monitor[3:0]),
        .display_out(HEX0_D)
    );

    segmentdisplay seg2(
        .clk(clk25),
        .latch(1'b1),
        .hexdigit_in(pc_monitor[7:4]),
        .display_out(HEX1_D)
    );
    
    segmentdisplay seg3(
        .clk(clk25),
        .latch(1'b1),
        .hexdigit_in(pc_monitor[11:8]),
        .display_out(HEX2_D)
    );

    segmentdisplay seg4(
        .clk(clk25),
        .latch(1'b1),
        .hexdigit_in(pc_monitor[15:12]),
        .display_out(HEX3_D)
    );
      
    assign LEDG = 0;
    
endmodule
module Max2AudioDac(clk, mute, din, bclk, wclk, lout, rout);

	output [23:0] lout;
	output [23:0] rout;
	
	input clk;
	input din;
	input bclk;
	input wclk;
	input mute;
	
	reg [23:0] leftReg;
	reg [23:0] rightReg;
	reg [0:23] shift;
	reg [1:0]  bclkState;
	reg [4:0]  counter;
	reg wsd = 0;
	reg wsdEdge = 0;
	
	wire bclkRise = (bclkState == 2'b01);
	wire bclkFall = (bclkState == 2'b10);
	wire wsp = wsd ^ wsdEdge;
	
	assign lout = leftReg;
	assign rout = rightReg;
	
	initial leftReg = 0;
	initial rightReg = 0;
	
	always @(posedge clk)
	begin
		bclkState <= {bclkState, bclk};
	end
	 
	always @(posedge clk)
	begin
		if (bclkRise)
		begin
			wsd <= wclk;
		end
	end

	always @(posedge clk)
	begin
		if (bclkRise)
		begin
			wsdEdge <= wsd;
		end
	end
  
	always @(posedge clk)
	begin
		if (bclkFall)
		begin
			if (wsp)
			begin
				counter <= 0;
			end
			else if (counter < 24)
			begin
				counter <= counter + 1;
			end
		end
	end
  
	always @(posedge clk)
	begin
		if (bclkRise)
		begin
			if (wsp)
			begin
				shift <= 0;
			end
			
			if (counter < 24)
			begin
				shift[counter] <= din;
			end
		end
	end

	always @(posedge clk)
	begin
		if (mute)
		begin
			leftReg <= 0;
		end
		else
		begin
			if (bclkRise)
			begin
				if (wsd && wsp)
				begin
					leftReg <= {~shift[0], shift[1:23]};
				end
			end
		end
	end

	always @(posedge clk)
	begin
		if (mute)
		begin
			rightReg <= 0;
		end
		else
		begin
			if (bclkRise)
			begin
				if (!wsd && wsp)
				begin
					rightReg <= {~shift[0], shift[1:23]};
				end
			end
		end
	end
			
endmodule
module multiplier_tb();

reg            clk;
reg            rst;
reg    [31:0]   input_a;
reg    [31:0]   input_b;
reg             input_a_stb;
reg             input_b_stb;
reg            output_z_ack;
wire            input_a_ack;
wire            input_b_ack;
wire            output_z_stb;
wire   [31:0]  output_z;
initial begin 
  clk = 1;
  rst = 1;
  input_a_stb = 0;  
  input_b_stb = 0;
  output_z_ack = 0;
  #10
  rst = 0;
////////////////////////////  
  input_a_stb = 1;  
  input_b_stb = 1;
  output_z_ack = 1;
//  #5
  input_a = 32'h3f000000;
  input_b = 32'h00000000;
  #80
  // input_a_stb = 0;  
  // input_b_stb = 0;
  // output_z_ack = 0;
  // #10
////////////////////////////  
  
  // input_a_stb = 1;  
  // input_b_stb = 1;
  // output_z_ack = 1;
  // #5 
  input_a = 32'h3f000000;
  input_b = 32'hbf000000;
  #80
//     input_a_stb = 0;  
//   input_b_stb = 0;
//   output_z_ack = 0;
// ////////////////////////////  
//   #10
  //   input_a_stb = 1;  
  // input_b_stb = 1;
  // output_z_ack = 1;
  // #5
  input_a = 32'h3f000000;
  input_b = 32'h3f800000;
end

multiplier DUT (        
        input_a,
        input_b,
        input_a_stb,
        input_b_stb,
        output_z_ack,
        clk,
        rst,
        output_z,
        output_z_stb,
        input_a_ack,
        input_b_ack);

always 
#5 clk = ~clk;

endmodule // multiplier_tb
module Neg #(
  parameter WIDTH = 32
) (
  input wire logic signed [WIDTH-1:0] in,
  output wire logic signed [WIDTH-1:0] out
);
  assign out = -in;
endmodule
module FP_Mult_NoPipe (
    input [31:0] a,
    input [31:0] b,
    output exception,
    output overflow,
    output underflow,
    output [31:0] res
);

  wire sign, round, normalised, zero;
  wire [8:0] exponent, sum_exponent, exp_norm;
  wire [22:0] product_mantissa;
  wire [23:0] op_a, op_b;
  wire [47:0] product, product_normalised;


  assign sign = a[31] ^ b[31];  // XOR of 32nd bit
  assign exception = (&a[30:23]) | (&b[30:23]);											// Execption sets to 1 when exponent of any a or b is 255
  // If exponent is 0, hidden bit is 0

  assign op_a = (|a[30:23]) ? {1'b1, a[22:0]} : {1'b0, a[22:0]};
  assign op_b = (|b[30:23]) ? {1'b1, b[22:0]} : {1'b0, b[22:0]};

  assign product = op_a * op_b;  // Product
  assign normalised = product[47] ? 1'b1 : 1'b0;
  assign product_normalised = normalised ? product : product << 1;								// Normalized value based on 48th bit

  assign round = |product_normalised[22:0];  // Last 22 bits are ORed for rounding off purpose
  assign product_mantissa = product_normalised[46:24] + (product_normalised[23] & round); 					// Mantissa

  assign sum_exponent = a[30:23] + b[30:23];
  assign exp_norm = sum_exponent - 8'd127;
  assign exponent = exp_norm + normalised;
  assign overflow = (exponent[8] & !exception & !exponent[7]) ; 									// Overall exponent is greater than 255 then Overflow
  assign underflow = (exponent[8] & !exception & exponent[7]) ; 							// Sum of exponents is less than 255 then Underflow
  assign res = exception ? {sign,31'd0} :
               overflow ? {sign,8'hFF,23'd0} :
               underflow ? {sign,31'd0} :
               {sign,exponent[7:0],product_mantissa};

endmodule
module aib_osc_clk (
		    output logic osc_clk
                   ); 
initial  osc_clk = 1'b0;
always #(500)       osc_clk = ~osc_clk;

endmodule // aib_osc_clk
module dll 
   (
   input       clkp, clkn,
   input       rstb,
   output wire     rx_clk_tree_in,
   input       ms_rx_dll_lock_req,
   output wire ms_rx_dll_lock,
   input       sl_rx_dll_lock_req,
   output wire sl_rx_dll_lock,
   input       ms_nsl,
   input       atpg_mode
    );


wire  rstb_sync;
reg   ms_rx_dll_lock_r, sl_rx_dll_lock_r;
wire  ms_rx_dll_lock_w, sl_rx_dll_lock_w;
wire  ms_rx_dll_lock_req_sync, sl_rx_dll_lock_req_sync;

assign ms_rx_dll_lock = ms_rx_dll_lock_r;
assign sl_rx_dll_lock = sl_rx_dll_lock_r;

assign ms_rx_dll_lock_w = !ms_rx_dll_lock_req_sync ? 1'b0 :
                          (ms_nsl & ms_rx_dll_lock_req_sync ) ? 1'b1 : ms_rx_dll_lock_r;
assign sl_rx_dll_lock_w = !sl_rx_dll_lock_req_sync ? 1'b0 :
                          (!ms_nsl & sl_rx_dll_lock_req_sync ) ? 1'b1 : sl_rx_dll_lock_r;


aib_rstnsync aib_rstnsync
  (
    .clk(clkp),            // Destination clock of reset to be synced
    .i_rst_n(rstb),        // Asynchronous reset input
    .scan_mode(atpg_mode),      // Scan bypass for reset
    .sync_rst_n(rstb_sync)      // Synchronized reset output

   );

       aib_bitsync i_msrxdlllockreq
           (
           .clk(clkp),
           .rst_n(rstb_sync), 
           .data_in(ms_rx_dll_lock_req),
           .data_out(ms_rx_dll_lock_req_sync)
           );

       aib_bitsync i_slrxdlllockreq
           (
           .clk(clkp),
           .rst_n(rstb_sync), 
           .data_in(sl_rx_dll_lock_req),
           .data_out(sl_rx_dll_lock_req_sync)
           );

always @(posedge clkp or negedge rstb_sync) begin
  if (~rstb_sync)
   begin
    ms_rx_dll_lock_r <= 1'b0;
    sl_rx_dll_lock_r <= 1'b0;
   end
  else
   begin
    ms_rx_dll_lock_r <= ms_rx_dll_lock_w;
    sl_rx_dll_lock_r <= sl_rx_dll_lock_w;
   end
end

assign #(100) rx_clk_tree_in = clkp;
 
endmodule // dll
module  c3lib_or2_lcell( 

  // Functional IOs
  input  logic	in0,
  input	 logic	in1,
  output logic	out

); 

c3lib_or2_svt_2x u_c3lib_or2_svt_2x(

  .in0	( in0 ),
  .in1	( in1 ),
  .out	( out )

);

endmodule
module  c3lib_and2_lcell( 

  // Functional IOs
  input  logic	in0,
  input	 logic	in1,
  output logic	out

); 

c3lib_and2_svt_4x u_c3lib_and2_svt_4x(

  .in0	( in0 ),
  .in1	( in1 ),
  .out	( out )

);

endmodule
module c3lib_tiel_lcell(

  output logic	out

); 

c3lib_tie0_svt_1x c3lib_tie0_svt_1x(

  .out	( out )

);

endmodule
module  c3lib_tieh_lcell(

  output logic	out

); 

c3lib_tie1_svt_1x c3lib_tie1_svt_1x(

  .out	( out )

);

endmodule
module  c3lib_mtiel_lcell(

  output logic	out

); 

c3lib_mtie0_ds u_c3lib_mtie0_ds(

  .out	( out )

);

endmodule
module  c3lib_nand2_lcell(

  // Functional IOs
  input  logic	in0,
  input	 logic	in1,
  output logic	out

); 

c3lib_nand2_svt_2x u_c3lib_nand2_svt_2x(

  .in0	( in0 ),
  .in1	( in1 ),
  .out	( out )

);

endmodule
module c3lib_buf_lcell(

  input	 logic	in,
  output logic	out

); 

c3lib_buf_svt_4x u_c3lib_buf_svt_4x( 

  .in	( in  ),
  .out	( out )

); 

endmodule
module c3lib_dff_scan_lcell( 

  clk, 
  rst_n, 
  data_in,
  data_out,

  scan_in,
  scan_en

  ); 

input		clk; 
input		rst_n; 
input		data_in;
output		data_out;

input		scan_in;
input		scan_en;

  c3lib_dff0_scan_reset_svt_2x u_c3lib_dff0_scan_reset_svt_2x( 

    .data_in	( data_in  ),
    .clk	( clk      ),
    .data_out	( data_out ),
    .rst_n	( rst_n    ),
    .scan_en	( scan_en  ),
    .scan_in	( scan_in  )

  );

endmodule
module  c3lib_mtieh_lcell(

  output logic	out

); 

c3lib_mtie1_ds u_c3lib_mtie1_ds(

  .out	( out )

);

endmodule
module  c3lib_mux2_lcell( 

  input  logic	in0,
  input	 logic	in1,
  input  logic	sel,
  output logic	out

); 

c3lib_mux2_svt_2x u_c3lib_mux2_svt_2x( 

  .in0	( in0 ),
  .in1	( in1 ),
  .sel	( sel ),
  .out	( out )

);

endmodule
module  c3lib_sync3_reset_ulvt_gate( 

  clk, 
  rst_n, 
  data_in,
  data_out

  ); 

input	clk; 
input	rst_n; 
input	data_in;
output	data_out;

`ifdef USER_MACROS_ON
 //replace this section with user technology cell
 //for the purpose of cell hardening, synthesis don't touch
`else

  c3lib_sync_metastable_behav_gate #(

    .RESET_VAL	( 0 ),
    .SYNC_STAGES( 3 )

  ) u_c3lib_sync2_reset_lvt_gate ( 

    .clk	( clk      ),
    .rst_n	( rst_n    ),
    .data_in	( data_in  ),
    .data_out	( data_out )

  );

`endif

endmodule
module c3lib_sync2_set_lvt_gate( 

  clk, 
  rst_n, 
  data_in,
  data_out

  ); 

input		clk; 
input		rst_n; 
input		data_in;
output		data_out;

`ifdef USER_MACROS_ON
 //replace this section with user technology cell
 //for the purpose of cell hardening, synthesis don't touch
`else

  c3lib_sync_metastable_behav_gate #(

    .RESET_VAL	( 1 ),
    .SYNC_STAGES( 2 )

  ) u_c3lib_sync2_reset_lvt_gate ( 

    .clk	( clk      ),
    .rst_n	( rst_n    ),
    .data_in	( data_in  ),
    .data_out	( data_out )

  );

`endif

endmodule
module c3lib_ckinv_lvt_12x(

  in,
  out

  ); 

input		in;
output		out;

`ifdef USER_MACROS_ON
 //replace this section with user technology cell
 //for the purpose of cell hardening, synthesis don't touch
`else
  assign out = ~in;
`endif

endmodule
module c3lib_or2_svt_2x(

  in0,
  in1,
  out

  ); 

input		in0;
input		in1;
output		out;

`ifdef USER_MACROS_ON
 //replace this section with user technology cell
 //for the purpose of cell hardening, synthesis don't touch
`else

  assign out = in0 | in1;

`endif
endmodule
module c3lib_buf_svt_4x( 

  in,
  out

); 

input		in;
output		out;

`ifdef USER_MACROS_ON
 //replace this section with user technology cell
 //for the purpose of cell hardening, synthesis don't touch
`else
  assign out = in;
`endif

endmodule
module c3lib_sync2_set_ulvt_gate( 

  clk, 
  rst_n, 
  data_in,
  data_out

  ); 

input		clk; 
input		rst_n; 
input		data_in;
output		data_out;

`ifdef USER_MACROS_ON
 //replace this section with user technology cell
 //for the purpose of cell hardening, synthesis don't touch
`else

  c3lib_sync_metastable_behav_gate #(

    .RESET_VAL	( 1 ),
    .SYNC_STAGES( 2 )

  ) u_c3lib_sync2_reset_lvt_gate ( 

    .clk	( clk      ),
    .rst_n	( rst_n    ),
    .data_in	( data_in  ),
    .data_out	( data_out )

  );

`endif

endmodule
module c3lib_and2_svt_2x( 

  in0,
  in1,
  out

  ); 

input		in0;
input		in1;
output		out;

`ifdef USER_MACROS_ON
 //replace this section with user technology cell 
 //for the purpose of cell hardening, synthesis don't touch 
`else
  assign out = in0 & in1;
`endif

endmodule
module c3lib_and2_svt_4x( 

  in0,
  in1,
  out

  ); 

input		in0;
input		in1;
output		out;

`ifdef USER_MACROS_ON
 //replace this section with user technology cell
 //for the purpose of cell hardening, synthesis don't touch
`else
  assign out = in0 & in1;
`endif

endmodule
module c3lib_sync2_reset_lvt_gate( 

  clk, 
  rst_n, 
  data_in,
  data_out

  ); 

input		clk; 
input		rst_n; 
input		data_in;
output		data_out;

`ifdef USER_MACROS_ON
 //replace this section with user technology cell
 //for the purpose of cell hardening, synthesis don't touch
`else

  c3lib_sync_metastable_behav_gate #(

    .RESET_VAL	( 0 ),
    .SYNC_STAGES( 2 )

  ) u_c3lib_sync2_reset_lvt_gate ( 

    .clk	( clk      ),
    .rst_n	( rst_n    ),
    .data_in	( data_in  ),
    .data_out	( data_out )

  );

`endif

endmodule
module c3lib_sync2_reset_ulvt_gate( 

  clk, 
  rst_n, 
  data_in,
  data_out

  ); 

input		clk; 
input		rst_n; 
input		data_in;
output		data_out;

`ifdef USER_MACROS_ON
 //replace this section with user technology cell
 //for the purpose of cell hardening, synthesis don't touch
`else

  c3lib_sync_metastable_behav_gate #(

    .RESET_VAL	( 0 ),
    .SYNC_STAGES( 2 )

  ) u_c3lib_sync2_reset_lvt_gate ( 

    .clk	( clk      ),
    .rst_n	( rst_n    ),
    .data_in	( data_in  ),
    .data_out	( data_out )

  );

`endif

endmodule
module c3lib_ckinv_svt_8x( 

  in,
  out

  ); 

input		in;
output		out;

`ifdef USER_MACROS_ON
 //replace this section with user technology cell
 //for the purpose of cell hardening, synthesis don't touch
`else

  assign out = ~in;
`endif
endmodule
module  c3lib_sync3_set_ulvt_gate ( 

  clk, 
  rst_n, 
  data_in,
  data_out

  ); 

input	clk; 
input	rst_n; 
input 	data_in;
output	data_out;

`ifdef USER_MACROS_ON
 //replace this section with user technology cell
 //for the purpose of cell hardening, synthesis don't touch
`else

  c3lib_sync_metastable_behav_gate #(

    .RESET_VAL	( 1 ),
    .SYNC_STAGES( 3 )

  ) u_c3lib_sync2_reset_lvt_gate ( 

    .clk	( clk      ),
    .rst_n	( rst_n    ),
    .data_in	( data_in  ),
    .data_out	( data_out )

  );

`endif

endmodule
module  c3lib_mtie1_ds( 

  out

  ); 

output	out;

`ifdef USER_MACROS_ON
 //replace this section with user technology cell
 //for the purpose of cell hardening, synthesis don't touch
`else

  assign out = 1'b1;

`endif

endmodule
module c3lib_tie0_svt_1x( 

  out

  ); 

output	out;

`ifdef USER_MACROS_ON
 //replace this section with user technology cell
 //for the purpose of cell hardening, synthesis don't touch
`else

  assign out = 1'b0;

`endif
endmodule
module  c3lib_mtie0_ds( 

  out

  ); 

output	out;

`ifdef USER_MACROS_ON
 //replace this section with user technology cell
 //for the purpose of cell hardening, synthesis don't touch
`else

  assign out = 1'b0;

`endif
endmodule
module  c3lib_ckbuf_lvt_4x(

  in,
  out

  ); 

input  		in;
output 		out;

`ifdef USER_MACROS_ON
 //replace this section with user technology cell
 //for the purpose of cell hardening, synthesis don't touch
`else
  assign out = in;
`endif

endmodule
module c3lib_tie1_svt_1x(

  out

);

output	out;

`ifdef USER_MACROS_ON
 //replace this section with user technology cell
 //for the purpose of cell hardening, synthesis don't touch
`else

  assign out = 1'b1;

`endif
endmodule
module c3lib_nand2_svt_2x( 

  in0,
  in1,
  out

); 

input		in0;
input		in1;
output		out;

`ifdef USER_MACROS_ON
 //replace this section with user technology cell
 //for the purpose of cell hardening, synthesis don't touch
`else

  assign out = ~(in0 & in1);

`endif

endmodule
module  c3lib_bintogray #(

  parameter	WIDTH = 2 // Data width 

) (

   // Inputs
   input  wire [WIDTH-1:0]	data_in,

   // Outputs
   output wire  [WIDTH-1:0]	data_out

);


assign data_out = (data_in>>1) ^ data_in;

endmodule
module  c3lib_graytobin #(

  parameter	WIDTH = 2	// Data width 

) (

   // Inputs
   input  wire [WIDTH-1:0]	data_in,

   // Outputs
   output wire  [WIDTH-1:0]	data_out

);

  genvar	i;
   
  generate

    for (i = 0; i <= WIDTH-1; i = i+1) begin: GRAY_TO_BIN
      assign data_out[i] = ^(data_in >> i);            
    end

  endgenerate

endmodule
module c3lib_sync2_lvt_bitsync #(

  parameter	DWIDTH		= 1,		// Width of bus to be sync'ed
  parameter	RESET_VAL	= 0		// Reset value is LOW if set to 0, otherwise HIGH

) (

  input  logic				clk, 
  input  logic				rst_n, 

  input  logic[ (DWIDTH-1) : 0 ]	data_in,
  output logic[ (DWIDTH-1) : 0 ]	data_out

); 

  generate

    if (RESET_VAL == 0)
      c3lib_sync2_reset_lvt_gate u_c3lib_sync2_reset_lvt_gate[ (DWIDTH-1) : 0 ] ( .clk( clk ), .rst_n( rst_n ), .data_in( data_in ), .data_out( data_out ) );
    else
      c3lib_sync2_set_lvt_gate u_c3lib_sync2_set_lvt_gate[ (DWIDTH-1) : 0 ] ( .clk( clk ), .rst_n( rst_n ), .data_in( data_in ), .data_out( data_out ) );

  endgenerate

endmodule
module c3lib_sync2_ulvt_bitsync #(

  parameter	DWIDTH            = 1,		// Width of bus to be sync'ed
  parameter	RESET_VAL         = 0		// Reset value is LOW if set to 0, otherwise HIGH

) (

  input  logic				clk, 
  input  logic				rst_n, 

  input  logic[ (DWIDTH-1) : 0 ]	data_in,
  output logic[ (DWIDTH-1) : 0 ]	data_out

); 

  generate

    if (RESET_VAL == 0)
      c3lib_sync2_reset_ulvt_gate u_c3lib_sync2_reset_ulvt_gate[ (DWIDTH-1) : 0 ] ( .clk( clk ), .rst_n( rst_n ), .data_in( data_in ), .data_out( data_out ) );
    else
      c3lib_sync2_set_ulvt_gate u_c3lib_sync2_set_ulvt_gate[ (DWIDTH-1) : 0 ] ( .clk( clk ), .rst_n( rst_n ), .data_in( data_in ), .data_out( data_out ) );

  endgenerate

endmodule
module  c3lib_bitsync #(

  parameter	DWIDTH            = 1,		// Width of bus to be sync'ed
  parameter	RESET_VAL         = 0,		// Reset value is LOW if set to 0, otherwise HIGH
  parameter	DST_CLK_FREQ_MHZ  = 500,	// Clock frequency for destination domain in MHz
  parameter	SRC_DATA_FREQ_MHZ = 100		// Average source data 'frequency' in MHz

) (

  input  logic				clk, 
  input  logic				rst_n, 

  input  logic[ (DWIDTH-1) : 0 ]	data_in,
  output logic[ (DWIDTH-1) : 0 ]	data_out

); 

  generate

    if (DST_CLK_FREQ_MHZ > 500) begin : DST_CLK_GREATER_THAN_500MHZ

      if (RESET_VAL == 0) begin : ULVT_RESET
        c3lib_sync2_reset_ulvt_gate u_c3lib_sync2_reset_ulvt_gate[ (DWIDTH-1) : 0 ] ( .clk( clk ), .rst_n( rst_n), .data_in( data_in), .data_out( data_out ) );
      end
      else begin : ULVT_SET
        c3lib_sync2_set_ulvt_gate u_c3lib_sync2_set_ulvt_gate[ (DWIDTH-1) : 0 ] ( .clk( clk ), .rst_n( rst_n ), .data_in( data_in), .data_out( data_out ) );
      end

    end
    else begin : DST_CLK_LESS_THAN_OR_EQUAL_TO_500MHZ
  
      if (RESET_VAL == 0) begin : LVT_RESET
        c3lib_sync2_reset_lvt_gate u_c3lib_sync2_reset_lvt_gate[ (DWIDTH-1) : 0 ] ( .clk( clk ), .rst_n( rst_n ), .data_in( data_in ), .data_out( data_out ) );
      end
      else begin : LVT_SET
        c3lib_sync2_set_lvt_gate u_c3lib_sync2_set_lvt_gate[ (DWIDTH-1) : 0 ] ( .clk( clk ), .rst_n( rst_n ), .data_in( data_in ), .data_out( data_out ) );
      end

    end

  endgenerate

endmodule
module c3lib_sync3_ulvt_bitsync #(

  parameter	DWIDTH            = 1,		// Width of bus to be sync'ed
  parameter	RESET_VAL         = 0		// Reset value is LOW if set to 0, otherwise HIGH

) (

  input  logic				clk, 
  input  logic				rst_n, 

  input  logic[ (DWIDTH-1) : 0 ]	data_in,
  output logic[ (DWIDTH-1) : 0 ]	data_out

); 

  generate

    if (RESET_VAL == 0)
      c3lib_sync3_reset_ulvt_gate u_c3lib_sync3_reset_ulvt_gate[ (DWIDTH-1) : 0 ] ( .clk( clk ), .rst_n( rst_n ), .data_in( data_in ), .data_out( data_out ) );
    else
      c3lib_sync3_set_ulvt_gate u_c3lib_sync3_set_ulvt_gate[ (DWIDTH-1) : 0 ] ( .clk( clk ), .rst_n( rst_n ), .data_in( data_in ), .data_out( data_out ) );

  endgenerate

endmodule
module  c3lib_mux4_ctn( 

  input  logic	ck0,
  input	 logic	ck1,
  input	 logic	ck2,
  input  logic	ck3,
  input  logic	s0,
  input	 logic	s1,
  output logic	ck_out

); 

  c3lib_ckmux4_lvt_gate c3lib_ckmux4_gate( 

    // Functional IOs
    .ck0	( ck0    ),
    .ck1	( ck1    ),
    .ck2	( ck2    ),
    .ck3	( ck3    ),
    .s0		( s0     ),
    .s1		( s1     ),
    .ck_out	( ck_out ),

    // Scan IOs
    .tst_override	( 1'b0 ),
    .tst_s0		( 1'b0 ),
    .tst_s1		( 1'b0 )

  ); 

endmodule
module c3lib_mux2_ctn(

  input  logic	ck0,
  input	 logic	ck1,
  input  logic	s0,
  output logic	ck_out

); 

  c3lib_ckmux4_lvt_gate c3lib_ckmux4_gate( 

    // Functional IOs
    .ck0	( ck0    ),
    .ck1	( ck1    ),
    .ck2	( 1'b0   ),
    .ck3	( 1'b0   ),
    .s0		( s0     ),
    .s1		( 1'b0   ),
    .ck_out	( ck_out ),

    // Scan IOs
    .tst_override	( 1'b0 ),
    .tst_s0		( 1'b0 ),
    .tst_s1		( 1'b0 )

  ); 

endmodule
module c3lib_mux3_ctn( 

  input  logic	ck0,
  input	 logic	ck1,
  input	 logic	ck2,
  input  logic	s0,
  input	 logic	s1,
  output logic	ck_out

); 

  c3lib_ckmux4_lvt_gate c3lib_ckmux4_gate( 

    // Functional IOs
    .ck0	( ck0    ),
    .ck1	( ck1    ),
    .ck2	( ck2    ),
    .ck3	( 1'bx   ),
    .s0		( s0     ),
    .s1		( s1     ),
    .ck_out	( ck_out ),

    // Scan IOs
    .tst_override	( 1'b0 ),
    .tst_s0		( 1'b0 ),
    .tst_s1		( 1'b0 )

  ); 

endmodule
module  c3lib_ckinv_ctn( 

  input  logic	in,
  output logic	out

); 

c3lib_ckinv_svt_8x u_c3lib_ckinv_svt_8x( 

  .in	( in  ),
  .out	( out )

);

endmodule
module c3lib_ckand2_ctn(

  input  logic	clk_in0,
  input	 logic	clk_in1,
  output logic	clk_out

); 

c3lib_and2_svt_4x u_c3lib_and2_svt_4x(

  .in0	( clk_in0 ),
  .in1	( clk_in1 ),
  .out	( clk_out )

);

endmodule
module  c3lib_ckbuf_ctn( 

  input  logic	in,
  output logic	out

); 

c3lib_buf_svt_4x u_c3lib_buf_svt_4x(

  .in	( in  ),
  .out	( out )

); 

endmodule
module c3lib_ckg_posedge_ctn(

  input  logic	tst_en,
  input  logic	clk_en,
  input  logic	clk,
  output logic	gated_clk

); 

c3lib_ckg_lvt_8x c3lib_ckg_lvt_8x(

  .tst_en	( tst_en    ),
  .clk_en	( clk_en    ),
  .clk		( clk       ),
  .gated_clk	( gated_clk )

); 

endmodule
module c3routing_chnl_edge(
// right edge
  output [31:0]o_rdata,
  output       o_rdatavalid,
  output       o_waitreq,
  output [12:0]o_aibdftdll2adjch,
  output       o_red_idataselb_chain1,
  output       o_red_idataselb_chain2,
  output       o_txen_chain1,
  output       o_txen_chain2,
  output       o_red_shift_en_out_chain1,
  output       o_red_shift_en_out_chain2,
  input        i_jtag_last_bs_chain_in,
  output       o_jtag_last_bs_chain_out,        
  output       o_directout_data_chain1_out,     
  output       o_directout_data_chain2_out,     
  input        i_jtag_bs_scanen_in,
  input        i_jtag_clkdr_in,                 
  input        i_jtag_clksel_in,                
  input        i_jtag_intest_in,                
  input        i_jtag_mode_in,                  
  input        i_jtag_rstb_en_in,               
  input        i_jtag_rstb_in,                  
  input        i_jtag_weakpdn_in,               
  input        i_jtag_weakpu_in
// left edge
);
`ifndef CRETE3_STUB
//Static tie cells to terminate the AVMM chain
  assign o_rdata      = 32'd0;
  assign o_rdatavalid = 1'b0;
  assign o_waitreq    = 1'b1;
  assign o_aibdftdll2adjch = 13'd0;
  assign o_red_idataselb_chain1 = 1'b0;
  assign o_red_idataselb_chain2 = 1'b0;
  assign o_txen_chain1 = 1'b1;
  assign o_txen_chain2 = 1'b1;
  assign o_red_shift_en_out_chain1 = 1'b0;
  assign o_red_shift_en_out_chain2 = 1'b0;

  assign o_jtag_last_bs_chain_out = i_jtag_last_bs_chain_in;
  assign o_directout_data_chain1_out = '0;
  assign o_directout_data_chain2_out = '0;

`endif

endmodule
module tb_top;
   
   parameter debug = 0;
   
   logic               clk = 1'b0;
   logic               rst, rst_in;
   logic		led_blue;
   logic		led_green;
   logic		led_red;
   logic [2:0] gpio;   
   
   top #(/*AUTOINSTPARAM*/)
   dut 
   (/*AUTOINST*/
    // Outputs
    .gpio				(gpio[2:0]),
    .led_red				(led_red),
    .led_green				(led_green),
    .led_blue				(led_blue)
   );   

   // Stimulus
   always #10 clk = ~clk;

   initial begin
      $display("Starting simulation");
      $dumpfile("tb_top.vcd");
      $dumpvars;
      
      // Log the memories
      //for (int i=0; i<32; i++) $dumpvars(0, dut.image_mem[i]);
      
      #50000000;
      $display("Finishing simulation");
      $finish;
      
   end
   
   
endmodule // tb_spi_slave
module servo
#(
    // Declare the clock frequency to get the 50Hz update rate
    parameter CLK_FREQUENCY = 12000000
)
(
    input logic clk,
    input logic rst,
    input logic [7:0] pos,
    output logic pwm
);

    localparam CLK_COUNT = CLK_FREQUENCY/(256*1000);

    // Design consists of a 256*50Hz generator followed by a simple comparator
    logic [7:0] clk_ctr;
    logic tick;

    // Generate pulses every 1/(256) of a ms for sufficient resolution
    always @(posedge clk) tick <= (clk_ctr == CLK_COUNT-2);

    always @(posedge clk) 
    if (rst | tick)
        clk_ctr <= '0;
    else
        clk_ctr <= clk_ctr + 'd1;

    // PWM counter
    logic [11:0] pwm_ctr;
    always @(posedge clk)
    if (rst)
        pwm_ctr <= '0;
    else if (tick)
        pwm_ctr <= pwm_ctr + 'd1;

    // Generate PWM output
    always @(posedge clk)
        pwm <= (pwm_ctr < {4'b0001, pos});    

endmodule
module top (
                  
        // SPI lines
        input logic         spi_sck,
        input logic         gpio_23,
        output logic         spi_mosi,
        input logic        spi_miso,
        
        output logic led_red,
        output logic led_blue,
        output logic led_green
        );
    
    
    logic clk, rst_n, rst;
    logic spi_reset_out;
    logic [22:0] counter;

    // Internal oscillator
    SB_HFOSC #(.CLKHF_DIV("0b01")) SB_HFOSC_inst(.CLKHFEN(1'b1), .CLKHFPU(1'b1), .CLKHF(clk) );

    // Reset
    ice40_resetn u_reset_n (.clk(clk), .resetn(rst_n));
    assign rst = ~rst_n; // | spi_reset_out;

    // Wishbone signals
    logic wb_cyc, wb_stb, wb_we, wb_ack;
    logic [23:0] wb_adr;
    logic [31:0] wb_dat_m2s, wb_dat_s2m;
    
    // SPI Slave
    wb_spi_slave u_wb_spi_slave (
        .sck(spi_sck),
        .ssn(gpio_23),
        .mosi(spi_miso),
        .miso(spi_mosi),

            .o_wb_cyc(wb_cyc),
            .o_wb_stb(wb_stb),
            .o_wb_adr(wb_adr),
            .o_wb_dat(wb_dat_m2s),
            .o_wb_we(wb_we),
            .i_wb_ack(wb_ack),
            .i_wb_dat(wb_dat_s2m),
        
            .reset_out(spi_reset_out),
            .spi_id(counter[22:15]),
            .spi_status(counter[15:8]),
            .spi_start(),
            .spi_busy(),
            .tx_overrun(),
    .*);        
    
    // Wishbone peripheral
    logic [31:0] mem[255:0];
    logic [31:0] my_reg;
    logic i_ack;
    assign wb_ack = i_ack & wb_stb;
    
    always @(posedge clk) begin
        i_ack <= wb_stb & wb_cyc;

        if (wb_cyc & wb_stb) begin
            if (wb_we) begin
                if (wb_adr == 'h0)
                    my_reg <= wb_dat_m2s;
                else
                    mem[wb_adr[7:0]] <= wb_dat_m2s;
            end else begin
                if (wb_adr == 'h0)
                    wb_dat_s2m <= my_reg;
                else
                    wb_dat_s2m <= mem[wb_adr[7:0]];
            end
        end
        
    end

    // Drive some LED's for fun!
    logic toggle;
    
    always @(posedge clk) begin
        counter <= counter + 'd1;
    end
    assign toggle = counter[22];
   
    logic       duty_cycle;
    assign duty_cycle = ~& counter[3:0];
   
    SB_RGBA_DRV u_led_driver(
            .CURREN(1'b1), 
            .RGBLEDEN(1'b1),
            .RGB0PWM(my_reg[0] & toggle), 
            .RGB1PWM(my_reg[1] & toggle), 
            .RGB2PWM(my_reg[2] & toggle), 
            .RGB0(led_red),
            .RGB1(led_green), 
            .RGB2(led_blue)
        );
    defparam u_led_driver.CURRENT_MODE = "0b0" ;
    defparam u_led_driver.RGB0_CURRENT = "0b000001";
    defparam u_led_driver.RGB1_CURRENT = "0b000001";
    defparam u_led_driver.RGB2_CURRENT = "0b000001";

endmodule
module pipeline_stomach
# (
    parameter width = 8
)
(
    input                    clock,
    input                    reset_n,

    input      [width - 1:0] up_data,
    input                    up_valid,
    output                   up_ready,

    output     [width - 1:0] down_data,
    output                   down_valid,
    input                    down_ready
);

    wire stomach_load, dataout_load, dataout_unload;
    reg  mux_select;

    wire [width - 1:0] data_in;
    reg  [width - 1:0] stomach_out, mux_out, data_out;

    reg data_in_dataout, data_in_stomach;

    assign data_in = up_data;

    assign down_valid = data_in_dataout;

    assign dataout_unload = down_valid & down_ready;

    assign dataout_load =
           (up_valid & (! data_in_dataout | dataout_unload))
         | (data_in_stomach & dataout_unload);

    assign stomach_load =
            up_valid
        & ! data_in_stomach
        &   (data_in_dataout & ! dataout_unload);

    assign up_ready = ! data_in_stomach;

    always @ (posedge clock or negedge reset_n)
        if (! reset_n)
        begin
            data_in_stomach <= 1'b0;
            data_in_dataout <= 1'b0;
        end
        else
        begin
            data_in_stomach <=    stomach_load
                               | (data_in_stomach & ! dataout_unload);

            data_in_dataout <=    dataout_load
                               |  data_in_stomach
                               | (data_in_dataout & ! dataout_unload);
        end

    always @ (posedge clock or negedge reset_n)
        if (! reset_n)
            mux_select <= 1'b0;
        else
            mux_select <= stomach_load | (mux_select & ! dataout_load);

    always @ (posedge clock or negedge reset_n)
        if (! reset_n)
            stomach_out <= { width { 1'b0 } };
        else if (stomach_load)
            stomach_out <= data_in;
    
    always @*
        mux_out = mux_select ? stomach_out : data_in;

    always @ (posedge clock or negedge reset_n)
        if (! reset_n)
            data_out <= { width { 1'b0 } };
        else if (dataout_load)
            data_out <= mux_out;

    assign down_data = data_out;

endmodule
module top
# (
    parameter width = 8
)
(
    input                    clock,
    input                    reset_n,

    input      [width - 1:0] up_data,
    input                    up_valid,
    output                   up_ready,

    output     [width - 1:0] down_data,
    output                   down_valid,
    input                    down_ready
);

    pipeline_stomach      # (.width (width))
    pipeline_stomach_inst (.*);
/*
        clock,
        reset_n,

        up_data,
        up_valid,
        up_ready,

        down_data,
        down_valid,
        down_ready
*/

endmodule
module top
# (
    parameter width = 8
)
(
    input                    clock,
    input                    reset_n,

    input      [width - 1:0] up_data,
    input                    up_valid,
    output                   up_ready,

    output     [width - 1:0] down_data,
    output                   down_valid,
    input                    down_ready
);

    wire       [width - 1:0] i12_data;
    wire                     i12_valid;
    wire                     i12_ready;

    pipeline_stomach # (.width (width))
    pipeline_stomach_inst_1
    (
        .down_data  ( i12_data  ),
        .down_valid ( i12_valid ),
        .down_ready ( i12_ready ),

        .*
    );

    pipeline_stomach # (.width (width))
    pipeline_stomach_inst_2
    (
        .up_data    ( i12_data  ),
        .up_valid   ( i12_valid ),
        .up_ready   ( i12_ready ),

        .*
    );

endmodule
module dummy_tb;
    initial begin
        $display("Hello, Verilator!");
        $finish;
    end
endmodule
module i2s_tb;
    localparam CLK_HALF_PERIOD = 1/real'(CLK_FREQ)*1000e6/2;
    localparam GATE_DELAY = 2; // in ns

    bit clk;
    wire sample_clk_en;
    bit [DAC_OUTPUT_WIDTH-1:0] left_channel = 0;
    bit [DAC_OUTPUT_WIDTH-1:0] right_channel = 2**16/2;
    wire i2s_sclk;
    wire i2s_ws;
    wire i2s_sd;

    always begin
        #CLK_HALF_PERIOD clk = 0;
        #CLK_HALF_PERIOD clk = 1;
    end

    clk_div #(
        .INPUT_CLK_FREQ(CLK_FREQ),
        .OUTPUT_CLK_EN_FREQ(ACTUAL_SAMPLE_FREQ)
    ) sample_clk_gen_inst (
        .clk_en(sample_clk_en),
        .*
    );

    i2s i2s_inst (
        .*
    );

    always_ff @(posedge clk)
        if (sample_clk_en) begin
            left_channel <= left_channel + 1;
            right_channel <= right_channel + 1;
        end
endmodule
module ibex_csr #(
  parameter int unsigned    Width      = 32,
  parameter bit             ShadowCopy = 1'b0,
  parameter bit [Width-1:0] ResetValue = '0
 ) (
  input  logic             clk_i,
  input  logic             rst_ni,

  input  logic [Width-1:0] wr_data_i,
  input  logic             wr_en_i,
  output logic [Width-1:0] rd_data_o,

  output logic             rd_error_o
);

  logic [Width-1:0] rdata_q;

  always_ff @(posedge clk_i or negedge rst_ni) begin
    if (!rst_ni) begin
      rdata_q <= ResetValue;
    end else if (wr_en_i) begin
      rdata_q <= wr_data_i;
    end
  end

  assign rd_data_o = rdata_q;

  if (ShadowCopy) begin : gen_shadow
    logic [Width-1:0] shadow_q;

    always_ff @(posedge clk_i or negedge rst_ni) begin
      if (!rst_ni) begin
        shadow_q <= ~ResetValue;
      end else if (wr_en_i) begin
        shadow_q <= ~wr_data_i;
      end
    end

    assign rd_error_o = rdata_q != ~shadow_q;

  end else begin : gen_no_shadow
    assign rd_error_o = 1'b0;
  end

  `ASSERT_KNOWN(IbexCSREnValid, wr_en_i)

endmodule
module wishbone (
    input wire clk_74a,
    input wire clk,

    input wire reset,

    input wire [29:0] addr,
    // Wishbone registered feedback flags
    // Burst style extension. Specifies the type of burst
    input wire [1:0] bte,
    // Cycle type identifier. Indicates what kind of burst cycle is being used
    input wire [2:0] cti,
    // Cycle. High during the duration of the bus operations
    input wire cyc,
    input wire [31:0] data_write,
    // Which bytes are active in read/write
    input wire [3:0] sel,
    // Strobe. Need to assert ack or err after this
    input wire stb,
    // Write enable
    input wire we,

    output reg ack = 0,
    output reg [31:0] data_read = 0,
    // output wire [31:0] data_read,
    output reg err = 0
);

  reg [31:0] ram[16];
  //  = '{
  //     32'h102938,
  //     32'h02832,
  //     32'h89493,
  //     32'h09472,
  //     32'h29083,
  //     32'h09848,
  //     32'h8282,
  //     32'h9480,
  //     32'h1234,
  //     32'h9876,
  //     32'h9628,
  //     32'h1,
  //     32'h2,
  //     32'h3,
  //     32'h4,
  //     32'h5
  // };

  reg initialized = 0;
  reg [3:0] init_addr = 0;

  always @(posedge clk) begin
    if (reset) begin
      initialized <= 0;
      init_addr   <= 0;
    end else begin
      if (~initialized) begin
        ram[init_addr] <= {28'h0, init_addr};

        init_addr <= init_addr + 4'h1;

        if (init_addr == 4'hF) begin
          initialized <= 1;
        end
      end
    end
  end

  // assign data_read = 32'hDEADBEEF;

  always @(posedge clk) begin
    ack <= 0;

    if (stb && cyc) begin
      // Strobe
      if (we) begin
        // Write
        ram[addr[3:0]] <= data_write;
      end else begin
        data_read <= ram[addr[3:0]];
      end

      ack <= 1;
    end
  end

endmodule
module audio (
    input wire clk_74b,
    input wire clk_sys,

    input wire reset,

    input wire [31:0] audio_bus_in,
    input wire audio_bus_wr,

    input wire audio_playback_en,
    input wire audio_flush,

    output wire [11:0] audio_buffer_fill,

    output wire audio_mclk,  //! Serial Master Clock
    output wire audio_lrck,  //! Left/Right clock
    output wire audio_dac    //! Serialized data
);

  ////////////////////////////////////////////////////////////////////////////////////////
  // Audio PLL

  wire audio_sclk;

  mf_audio_pll audio_pll (
      .refclk  (clk_74b),
      .rst     (0),
      .outclk_0(audio_mclk),
      .outclk_1(audio_sclk)
  );

  ////////////////////////////////////////////////////////////////////////////////////////
  // FIFO

  wire audio_playback_en_s;

  synch_3 settings_synch (
      audio_playback_en,
      audio_playback_en_s,
      audio_mclk
  );

  wire [15:0] audio_l;
  wire [15:0] audio_r;

  wire empty;

  dcfifo dcfifo_component (
      .wrclk(clk_sys),
      .rdclk(audio_mclk),

      .data (audio_bus_in),
      .wrreq(audio_bus_wr),

      .q({audio_l, audio_r}),
      .rdreq(audio_req && audio_playback_en_s),

      .rdempty(empty),
      .wrusedw(audio_buffer_fill),

      .aclr(reset || audio_flush)
      // .eccstatus(),
      // .rdfull(),
      // .rdusedw(),
      // .wrempty(),
      // .wrfull()
  );
  defparam dcfifo_component.intended_device_family = "Cyclone V",
      dcfifo_component.lpm_numwords = 4096, dcfifo_component.lpm_showahead = "OFF",
      dcfifo_component.lpm_type = "dcfifo", dcfifo_component.lpm_width = 32,
      dcfifo_component.lpm_widthu = 12, dcfifo_component.overflow_checking = "ON",
      dcfifo_component.rdsync_delaypipe = 5, dcfifo_component.underflow_checking = "ON",
      dcfifo_component.use_eab = "ON", dcfifo_component.wrsync_delaypipe = 5;

  reg audio_req = 0;

  reg [7:0] mclk_div = 8'hFF;

  always @(posedge audio_mclk) begin
    // MClk is 12.288 MHz, we want 48kHz
    audio_req <= 0;

    if (mclk_div > 0) begin
      mclk_div <= mclk_div - 8'h1;
    end else begin
      mclk_div  <= 8'hFF;

      audio_req <= 1;
    end
  end

  ////////////////////////////////////////////////////////////////////////////////////////
  // i2s Generation

  sound_i2s #(
      .SIGNED_INPUT(1)
  ) sound_i2s (
      .audio_sclk(audio_sclk),

      .audio_l(audio_playback_en_s && ~empty ? audio_l : 16'h0),
      .audio_r(audio_playback_en_s && ~empty ? audio_r : 16'h0),

      .audio_lrck(audio_lrck),
      .audio_dac (audio_dac)
  );


endmodule
module data_loader #(
    // Upper 4 bits of address
    parameter ADDRESS_MASK_UPPER_4 = 0,
    parameter ADDRESS_SIZE = 28
) (
    input wire clk_74a,
    input wire clk_memory,

    input wire bridge_wr,
    input wire bridge_endian_little,
    input wire [31:0] bridge_addr,
    input wire [31:0] bridge_wr_data,

    // These outputs are synced to the memory clock
    output reg write_en = 0,
    output wire [ADDRESS_SIZE-1:0] write_addr,
    output wire [31:0] write_data
);

  wire mem_empty;
  wire [59:0] fifo_out;

  assign {write_addr, write_data} = fifo_out;

  dcfifo dcfifo_component (
      .wrclk(clk_74a),
      .rdclk(clk_memory),

      .wrreq(wrreq),
      .data ({bridge_addr[27:0], bridge_wr_data}),

      .rdreq(~mem_empty),
      .q(fifo_out),

      .rdempty(mem_empty)
      // .wrempty(),
      // .aclr(),
      // .eccstatus(),
      // .rdfull(),
      // .rdusedw(),
      // .wrfull(),
      // .wrusedw()
  );
  defparam dcfifo_component.clocks_are_synchronized = "FALSE",
      dcfifo_component.intended_device_family = "Cyclone V", dcfifo_component.lpm_numwords = 4,
      dcfifo_component.lpm_showahead = "OFF", dcfifo_component.lpm_type = "dcfifo",
      dcfifo_component.lpm_width = 60, dcfifo_component.lpm_widthu = 2,
      dcfifo_component.overflow_checking = "OFF", dcfifo_component.rdsync_delaypipe = 5,
      dcfifo_component.underflow_checking = "OFF", dcfifo_component.use_eab = "OFF",
      dcfifo_component.wrsync_delaypipe = 5;

  reg prev_bridge_wr = 0;

  wire wrreq = ~prev_bridge_wr && bridge_wr && bridge_addr[31:28] == ADDRESS_MASK_UPPER_4;

  // Receive APF writes and write to FIFO
  always @(posedge clk_74a) begin
    prev_bridge_wr <= bridge_wr;
  end

  always @(posedge clk_memory) begin
    // Delay write_en by one cycle so FIFO read finishes
    write_en <= ~mem_empty;
  end

endmodule
module sync_fifo #(
    parameter WIDTH = 2
) (
    input wire clk_write,
    input wire clk_read,

    input wire write_en,
    input wire [WIDTH - 1:0] data,
    output reg [WIDTH - 1:0] data_s = 0,
    output reg write_en_s = 0
);

  reg read_req = 0;
  wire empty;

  wire [WIDTH - 1:0] fifo_out;

  dcfifo dcfifo_component (
      .data(data),
      .rdclk(clk_read),
      .rdreq(read_req),
      .wrclk(clk_write),
      .wrreq(write_en),
      .q(fifo_out),
      .rdempty(empty),
      .aclr(),
      .eccstatus(),
      .rdfull(),
      .rdusedw(),
      .wrempty(),
      .wrfull(),
      .wrusedw()
  );
  defparam dcfifo_component.intended_device_family = "Cyclone V", dcfifo_component.lpm_numwords = 4,
      dcfifo_component.lpm_showahead = "OFF", dcfifo_component.lpm_type = "dcfifo",
      dcfifo_component.lpm_width = WIDTH, dcfifo_component.lpm_widthu = 2,
      dcfifo_component.overflow_checking = "ON", dcfifo_component.rdsync_delaypipe = 5,
      dcfifo_component.underflow_checking = "ON", dcfifo_component.use_eab = "ON",
      dcfifo_component.wrsync_delaypipe = 5;

  reg [1:0] read_state = 0;

  localparam READ_DELAY = 1;
  localparam READ_WRITE = 2;

  always @(posedge clk_read) begin
    read_req   <= 0;
    write_en_s <= 0;

    if (~empty) begin
      read_state <= READ_DELAY;
      read_req   <= 1;
    end

    case (read_state)
      READ_DELAY: begin
        read_state <= READ_WRITE;
      end
      READ_WRITE: begin
        read_state <= 0;

        data_s <= fifo_out;
        write_en_s <= 1;
      end
    endcase
  end

endmodule
module rgb565_to_rgb888 (
    input  wire [15:0] rgb565,
    output wire [23:0] rgb888
);

  // Constants taken from https://stackoverflow.com/a/9069480
  wire [13:0] red = {2'b0, rgb565[15:11]} * 10'd527 + 14'd23;
  wire [13:0] green = {1'b0, rgb565[10:5]} * 10'd259 + 14'd33;
  wire [13:0] blue = {2'b0, rgb565[4:0]} * 10'd527 + 14'd23;

  assign rgb888[23:16] = red[13:6];
  assign rgb888[15:8]  = green[13:6];
  assign rgb888[7:0]   = blue[13:6];

endmodule
module VX_elastic_adapter (
    input wire  clk,
    input wire  reset,

    input wire  valid_in,
    output wire ready_in,
        
    input wire  ready_out,
    output wire valid_out,

    input wire  busy,
    output wire strobe
);
    wire push = valid_in && ready_in;
    wire pop = valid_out && ready_out;

    reg loaded;

    always @(posedge clk) begin
        if (reset) begin
            loaded  <= 0;
        end else begin
            if (push) begin
                loaded <= 1;
            end
            if (pop) begin                
                loaded <= 0;
            end
        end
    end

    assign ready_in  = ~loaded;
    assign valid_out = loaded && ~busy;
    assign strobe    = push;

endmodule
module VX_priority_arbiter #(
    parameter NUM_REQS     = 1,
    parameter LOG_NUM_REQS = `LOG2UP(NUM_REQS)
) (
    input  wire [NUM_REQS-1:0]      requests,
    output wire [LOG_NUM_REQS-1:0]  grant_index,
    output wire [NUM_REQS-1:0]      grant_onehot,
    output wire                     grant_valid
);
    if (NUM_REQS == 1)  begin

        assign grant_index  = '0;
        assign grant_onehot = requests;
        assign grant_valid  = requests[0];

    end else begin

        VX_priority_encoder #(
            .N (NUM_REQS)
        ) priority_encoder (
            .data_in   (requests),
            .index     (grant_index),
            .onehot    (grant_onehot),
            .valid_out (grant_valid)
        );

    end

endmodule
module VX_sp_ram #(
    parameter DATAW       = 1,
    parameter SIZE        = 1,
    parameter ADDR_MIN    = 0,
    parameter WRENW       = 1,
    parameter OUT_REG     = 0,
    parameter NO_RWCHECK  = 0,
    parameter LUTRAM      = 0,
    parameter INIT_ENABLE = 0,
    parameter INIT_FILE   = "",
    parameter [DATAW-1:0] INIT_VALUE = 0,
    parameter ADDRW       = `LOG2UP(SIZE)
) (
    input wire               clk,
    input wire               read,
    input wire               write,
    input wire [WRENW-1:0]   wren,
    input wire [ADDRW-1:0]   addr,
    input wire [DATAW-1:0]   wdata,
    output wire [DATAW-1:0]  rdata
);
    VX_dp_ram #(
        .DATAW (DATAW),
        .SIZE (SIZE),
        .ADDR_MIN (ADDR_MIN),
        .WRENW (WRENW),
        .OUT_REG (OUT_REG),
        .NO_RWCHECK (NO_RWCHECK),
        .LUTRAM (LUTRAM),
        .INIT_ENABLE (INIT_ENABLE),
        .INIT_FILE (INIT_FILE),
        .INIT_VALUE (INIT_VALUE),
        .ADDRW (ADDRW)
    ) dp_ram (
        .clk   (clk),
        .read  (read),
        .write (write),
        .wren  (wren),
        .waddr (addr),
        .wdata (wdata),
        .raddr (addr),
        .rdata (rdata)
    );

endmodule
module VX_om_compare #(
    parameter DATAW = 24
) (
    // Inputs
    input wire [`VX_OM_DEPTH_FUNC_BITS-1:0] func,
    input wire [DATAW-1:0] a,
    input wire [DATAW-1:0] b,

    // Outputs
    output wire result
);
    wire [DATAW:0] sub = (a - b);
    wire equal = (0 == sub);
    wire less  = sub[DATAW];

    reg result_r;

    always @(*) begin
        case (func)
            `VX_OM_DEPTH_FUNC_NEVER    : result_r = 0;
            `VX_OM_DEPTH_FUNC_LESS     : result_r = less;
            `VX_OM_DEPTH_FUNC_EQUAL    : result_r = equal;
            `VX_OM_DEPTH_FUNC_LEQUAL   : result_r = less || equal;
            `VX_OM_DEPTH_FUNC_GREATER  : result_r = ~(less || equal);
            `VX_OM_DEPTH_FUNC_NOTEQUAL : result_r = ~equal;
            `VX_OM_DEPTH_FUNC_GEQUAL   : result_r = ~less;
            `VX_OM_DEPTH_FUNC_ALWAYS   : result_r = 1;
            default                    : result_r = 'x;
        endcase        
    end

    assign result = result_r;

endmodule