dakies/OSS_Verilog huggingface dataset:
module alarm(
    input CLK,
    input enable,
    output reg BUZZER
    );

reg [25:0] count;

always @(posedge CLK) 
begin
  count <= count + 1;
  if ((count == 26'd50000) & enable) // 1kHz
  begin
    BUZZER <= ~ BUZZER;
    count <= 0;
  end
end

endmodule
module servo_tester(
    input CLK,
    input switch_up,
    input switch_dn,
    output CONTROL_PIN
    );

wire s_up, s_dn;
debouncer d1(.CLK (CLK), .switch_input (switch_up), .trans_up (s_up));
debouncer d2(.CLK (CLK), .switch_input (switch_dn), .trans_up (s_dn));

reg [15:0] pulse_len = 500; // microseconds

servo p(.CLK (CLK), .pulse_len (pulse_len), .CONTROL_PIN (CONTROL_PIN));

always @(posedge CLK)
begin
  if (s_up)
  begin
    pulse_len <= pulse_len + 100;
  end
  if (s_dn)
  begin
    pulse_len <= pulse_len - 100;
  end  
end

endmodule
module wav_player(
    input CLK,
    input switch_play,
    output reg audio_out
    );

localparam MEM_SIZE = 19783; // 

reg [7:0] memory[MEM_SIZE-1:0];
initial begin
  $readmemh("01_03_b19783.txt", memory);
end

wire s_start;debouncer d1(.CLK (CLK), .switch_input (switch_play), .trans_up (s_start));

reg play = 0;
reg [3:0] prescaler; 
reg [7:0] counter;
reg [19:0] address;
reg [7:0] value;

always @(posedge CLK)
begin
  if (play)
  begin
    prescaler <= prescaler + 1;
    if (prescaler == 15)  // 8kHz x 256 steps = 2.048 MHz
    begin
      prescaler <= 0;
	   counter <= counter + 1;
      value <= memory[address];
      audio_out <= (value > counter);
      if (counter == 255)
      begin
        address <= address + 1;
        if (address == MEM_SIZE)
        begin
          play <= 0;
          address <= 0;
        end			 
      end		
    end
  end
  if (s_start)
  begin
    play <= 1;
  end	 
end


endmodule
module tone_tester(
    input CLK,
    output tone_1khz,
    output tone_100hz,
    output tone_12khz
    );

reg [31:0] period_1khz = 1000;
reg [31:0] period_100hz = 10000;
reg [31:0] period_12khz = 80;

tone #(32) t1(.CLK (CLK), .period (period_1khz), .tone_out (tone_1khz));
tone #(32) t2(.CLK (CLK), .period (period_100hz), .tone_out (tone_100hz));
tone #(32) t3(.CLK (CLK), .period (period_12khz), .tone_out (tone_12khz));

endmodule
module vga(
    input CLK,  // Papilio 32MHz
    output HS, VS,
    output [9:0] x,
    output reg [9:0] y,
    output blank
    );

reg [9:0] xc;
 
// Horizontal 640 + fp 24 + HS 40 + bp 128 = 832 pixel clocks
// Vertical, 480 + fp 9 lines vs 3 lines bp 28 lines 
assign blank = ((xc < 192) | (xc > 832) | (y > 479));
assign HS = ~ ((xc > 23) & (xc < 65));
assign VS = ~ ((y > 489) & (y < 493));
assign x = ((xc < 192)?0:(xc - 192));

always @(posedge CLK)
begin
  if (xc == 832)
  begin
    xc <= 0;
    y <= y + 1;
  end
  else begin
    xc <= xc + 1;
  end
  if (y == 520)
  begin
    y <= 0; 
  end
end

endmodule
module timer(
    input CLK,
    input switch_up,
    input switch_dn,
    input switch_cancel,
    input switch_start_stop,
    output [7:0] SEG,
    output [3:0] DIGIT,
    output BUZZER
    );
	 
wire s_up, s_dn, s_cancel, s_start_stop;
debouncer d1(.CLK (CLK), .switch_input (switch_up), .trans_up (s_up));
debouncer d2(.CLK (CLK), .switch_input (switch_dn), .trans_up (s_dn));
debouncer d3(.CLK (CLK), .switch_input (switch_cancel), .trans_up (s_cancel));
debouncer d4(.CLK (CLK), .switch_input (switch_start_stop), .trans_up (s_start_stop));

reg alarm_on = 0;
alarm a(.CLK (CLK), .BUZZER (BUZZER), .enable (alarm_on));

reg [3:0] secs = 0;
reg [3:0] ten_secs = 0;
reg [3:0] mins = 1;
reg [3:0] mins_stored;
reg [3:0] unused_digit = 4'd10; // digits above 9 not displayed
reg [25:0] prescaler = 0;

display_7_seg display(.CLK (CLK), 
		.units (secs), .tens (ten_secs), .hundreds (mins), .thousands (unused_digit),
		.SEG (SEG), .DIGIT (DIGIT));

// States
localparam SETTING = 0, RUNNING = 1, BEEPING = 2;
reg [1:0] state = SETTING; 

always @(posedge CLK) 
begin
  case (state)
    SETTING : begin
      handle_settings();
      if (s_start_stop)
      begin
        mins_stored <= mins;
        state <= RUNNING;
      end
    end
    RUNNING : begin
      decrement_time();
      if (s_start_stop)
      begin
        state <= SETTING;
      end
      if (s_cancel)
      begin
        reset_time();
        state <= SETTING;
      end
      if ((secs == 0) & (ten_secs == 0) & (mins == 0))
      begin
        alarm_on <= 1;
        state <= BEEPING;
      end
    end
    BEEPING : begin
      if (s_cancel)
      begin
        alarm_on <= 0;
        state <= SETTING;
        reset_time();
		end
	 end
  endcase
end

task handle_settings;
begin
  if (s_up)
  begin
    mins <= mins + 1;
    if (mins == 9)
    begin
      mins <= 1;
    end
  end
  if (s_dn)
  begin
	 mins <= mins - 1;
    if (mins == 1)
    begin
      mins <= 9;
    end
  end
end
endtask

task decrement_time;
begin
  prescaler <= prescaler + 1;
  if (prescaler == 26'd31999999) // 32 MHz to 1Hz
  begin
    prescaler <= 0;
    secs <= secs - 1;
    if (secs < 1)
    begin
      secs <= 9;
      ten_secs <= ten_secs - 1;
      if (ten_secs < 1)
      begin
        ten_secs <= 5;
        mins <= mins - 1;
      end
    end
  end
end
endtask


task reset_time;
begin
  secs <= 0;
  ten_secs <= 0;
  mins <= mins_stored;
end
endtask

endmodule
module alarm(
    input CLK,
    input enable,
    output reg BUZZER
    );

reg [25:0] count;

always @(posedge CLK) 
begin
  count <= count + 1;
  if ((count == 26'd31999) & enable) // 1kHz
  begin
    BUZZER <= ~ BUZZER;
    count <= 0;
  end
end

endmodule
module seg_test(
   input CLK,
   input [3:0] D,
   output [7:0] SEG,
   output [3:0]DIGIT
   );	
	
assign DIGIT = 4'b1110;

decoder_7_seg decoder(.CLK (CLK), .SEG	(SEG), .D (D));  

endmodule
module alarm(
    input CLK,
    input enable,
    output reg BUZZER
    );

reg [25:0] count;

always @(posedge CLK) 
begin
  count <= count + 1;
  if ((count == 26'd32000) & enable) // 1kHz
  begin
    BUZZER <= ~ BUZZER;
    count <= 0;
  end
end

endmodule
module servo_tester(
    input CLK,
    output CONTROL_PIN
    );

reg [24:0] prescaler;
reg [15:0] pulse_len = 500; // microseconds

servo #(32) p(.CLK (CLK), .pulse_len (pulse_len), .CONTROL_PIN (CONTROL_PIN));

always @(posedge CLK)
begin
  prescaler <= prescaler + 1;
  if (prescaler == 32000000) // 1Hz
  begin
    pulse_len <= pulse_len + 100;
    if (pulse_len == 2500)
    begin
      pulse_len <= 500;
    end		
  end  
end

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

	pll_0002 pll_inst (
		.refclk   (refclk),   //  refclk.clk
		.rst      (rst),      //   reset.reset
		.outclk_0 (outclk_0), // outclk0.clk
		.outclk_1 (outclk_1), // outclk1.clk
		.locked   ()          // (terminated)
	);

endmodule
module  pll_0002(

	// interface 'refclk'
	input wire refclk,

	// interface 'reset'
	input wire rst,

	// interface 'outclk0'
	output wire outclk_0,

	// interface 'outclk1'
	output wire outclk_1,

	// interface 'locked'
	output wire locked
);

	altera_pll #(
		.fractional_vco_multiplier("true"),
		.reference_clock_frequency("50.0 MHz"),
		.operation_mode("normal"),
		.number_of_clocks(2),
		.output_clock_frequency0("25.174999 MHz"),
		.phase_shift0("0 ps"),
		.duty_cycle0(50),
		.output_clock_frequency1("107.892852 MHz"),
		.phase_shift1("0 ps"),
		.duty_cycle1(50),
		.output_clock_frequency2("0 MHz"),
		.phase_shift2("0 ps"),
		.duty_cycle2(50),
		.output_clock_frequency3("0 MHz"),
		.phase_shift3("0 ps"),
		.duty_cycle3(50),
		.output_clock_frequency4("0 MHz"),
		.phase_shift4("0 ps"),
		.duty_cycle4(50),
		.output_clock_frequency5("0 MHz"),
		.phase_shift5("0 ps"),
		.duty_cycle5(50),
		.output_clock_frequency6("0 MHz"),
		.phase_shift6("0 ps"),
		.duty_cycle6(50),
		.output_clock_frequency7("0 MHz"),
		.phase_shift7("0 ps"),
		.duty_cycle7(50),
		.output_clock_frequency8("0 MHz"),
		.phase_shift8("0 ps"),
		.duty_cycle8(50),
		.output_clock_frequency9("0 MHz"),
		.phase_shift9("0 ps"),
		.duty_cycle9(50),
		.output_clock_frequency10("0 MHz"),
		.phase_shift10("0 ps"),
		.duty_cycle10(50),
		.output_clock_frequency11("0 MHz"),
		.phase_shift11("0 ps"),
		.duty_cycle11(50),
		.output_clock_frequency12("0 MHz"),
		.phase_shift12("0 ps"),
		.duty_cycle12(50),
		.output_clock_frequency13("0 MHz"),
		.phase_shift13("0 ps"),
		.duty_cycle13(50),
		.output_clock_frequency14("0 MHz"),
		.phase_shift14("0 ps"),
		.duty_cycle14(50),
		.output_clock_frequency15("0 MHz"),
		.phase_shift15("0 ps"),
		.duty_cycle15(50),
		.output_clock_frequency16("0 MHz"),
		.phase_shift16("0 ps"),
		.duty_cycle16(50),
		.output_clock_frequency17("0 MHz"),
		.phase_shift17("0 ps"),
		.duty_cycle17(50),
		.pll_type("General"),
		.pll_subtype("General")
	) altera_pll_i (
		.rst	(rst),
		.outclk	({outclk_1, outclk_0}),
		.locked	(locked),
		.fboutclk	( ),
		.fbclk	(1'b0),
		.refclk	(refclk)
	);
endmodule
module string_rom 
#( parameter A_WIDTH   = 13,
   parameter D_WIDTH   = 16,
   parameter INIT_FILE = "2.mif"
)
(
	clock,
	address,
	q);

	input	[A_WIDTH-1:0]  address;
	input	  clock;
	output	[D_WIDTH-1:0]  q;
`ifndef ALTERA_RESERVED_QIS
// synopsys translate_off
`endif
	tri1	  clock;
`ifndef ALTERA_RESERVED_QIS
// synopsys translate_on
`endif

	wire [D_WIDTH-1:0] sub_wire0;
	wire [D_WIDTH-1:0] q = sub_wire0[D_WIDTH-1:0];

	altsyncram	altsyncram_component (
				.address_a (address),
				.clock0 (clock),
				.q_a (sub_wire0),
				.aclr0 (1'b0),
				.aclr1 (1'b0),
				.address_b (1'b1),
				.addressstall_a (1'b0),
				.addressstall_b (1'b0),
				.byteena_a (1'b1),
				.byteena_b (1'b1),
				.clock1 (1'b1),
				.clocken0 (1'b1),
				.clocken1 (1'b1),
				.clocken2 (1'b1),
				.clocken3 (1'b1),
				.data_a ({D_WIDTH{1'b1}}),
				.data_b (1'b1),
				.eccstatus (),
				.q_b (),
				.rden_a (1'b1),
				.rden_b (1'b1),
				.wren_a (1'b0),
				.wren_b (1'b0));
	defparam
		altsyncram_component.address_aclr_a = "NONE",
		altsyncram_component.clock_enable_input_a = "BYPASS",
		altsyncram_component.clock_enable_output_a = "BYPASS",
		altsyncram_component.init_file = INIT_FILE,
		altsyncram_component.intended_device_family = "Cyclone V",
		altsyncram_component.lpm_hint = "ENABLE_RUNTIME_MOD=NO",
		altsyncram_component.lpm_type = "altsyncram",
		altsyncram_component.numwords_a = 2**A_WIDTH,
		altsyncram_component.operation_mode = "ROM",
		altsyncram_component.outdata_aclr_a = "NONE",
		altsyncram_component.outdata_reg_a = "UNREGISTERED",
		altsyncram_component.widthad_a = A_WIDTH,
		altsyncram_component.width_a = D_WIDTH,
		altsyncram_component.width_byteena_a = 1;


endmodule
module user_input_fifo 
#( 
  parameter DWIDTH = 8 
)
(
	aclr,
	data,
	rdclk,
	rdreq,
	wrclk,
	wrreq,
	q,
	rdempty,
	wrfull);

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

	wire [DWIDTH-1:0] sub_wire0;
	wire  sub_wire1;
	wire  sub_wire2;
	wire [DWIDTH-1:0] q = sub_wire0[DWIDTH-1:0];
	wire  rdempty = sub_wire1;
	wire  wrfull = sub_wire2;

	dcfifo	dcfifo_component (
				.aclr (aclr),
				.data (data),
				.rdclk (rdclk),
				.rdreq (rdreq),
				.wrclk (wrclk),
				.wrreq (wrreq),
				.q (sub_wire0),
				.rdempty (sub_wire1),
				.wrfull (sub_wire2),
				.rdfull (),
				.rdusedw (),
				.wrempty (),
				.wrusedw ());
	defparam
		dcfifo_component.intended_device_family = "Cyclone V",
		dcfifo_component.lpm_hint = "RAM_BLOCK_TYPE=MLAB",
		dcfifo_component.lpm_numwords = 8,
		dcfifo_component.lpm_showahead = "ON",
		dcfifo_component.lpm_type = "dcfifo",
		dcfifo_component.lpm_width = DWIDTH,
		dcfifo_component.lpm_widthu = 3,
		dcfifo_component.overflow_checking = "ON",
		dcfifo_component.rdsync_delaypipe = 4,
		dcfifo_component.read_aclr_synch = "ON",
		dcfifo_component.underflow_checking = "ON",
		dcfifo_component.use_eab = "ON",
		dcfifo_component.write_aclr_synch = "ON",
		dcfifo_component.wrsync_delaypipe = 4;


endmodule
module dvi_generator(
    input  wire i_pix_clk,          // pixel clock
    input  wire i_pix_clk_5x,       // 5 x pixel clock for DDR serialization
    input  wire i_rst,              // reset (active high)
    input  wire i_de,               // display enable (draw video)
    input  wire [7:0] i_data_ch0,   // channel 0 - 8-bit colour data
    input  wire [7:0] i_data_ch1,   // channel 1 - 8-bit colour data
    input  wire [7:0] i_data_ch2,   // channel 2 - 8-bit colour data
    input  wire [1:0] i_ctrl_ch0,   // channel 0 - 2-bit control data
    input  wire [1:0] i_ctrl_ch1,   // channel 1 - 2-bit control data
    input  wire [1:0] i_ctrl_ch2,   // channel 2 - 2-bit control data
    output wire o_tmds_ch0_serial,  // channel 0 - serial TMDS
    output wire o_tmds_ch1_serial,  // channel 1 - serial TMDS
    output wire o_tmds_ch2_serial,  // channel 2 - serial TMDS
    output wire o_tmds_chc_serial   // channel clock - serial TMDS
    );

    wire [9:0] tmds_ch0, tmds_ch1, tmds_ch2;

    tmds_encoder_dvi encode_ch0 (
        .i_clk(i_pix_clk),
        .i_rst(i_rst),
        .i_data(i_data_ch0),
        .i_ctrl(i_ctrl_ch0),
        .i_de(i_de),
        .o_tmds(tmds_ch0)
    );

    tmds_encoder_dvi encode_ch1 (
        .i_clk(i_pix_clk),
        .i_rst(i_rst),
        .i_data(i_data_ch1),
        .i_ctrl(i_ctrl_ch1),
        .i_de(i_de),
        .o_tmds(tmds_ch1)
    );

    tmds_encoder_dvi encode_ch2 (
        .i_clk(i_pix_clk),
        .i_rst(i_rst),
        .i_data(i_data_ch2),
        .i_ctrl(i_ctrl_ch2),
        .i_de(i_de),
        .o_tmds(tmds_ch2)
    );

    // common async reset for serdes
    wire rst_oserdes;
    async_reset async_reset_instance (
        .i_clk(i_pix_clk),
        .i_rst(i_rst),
        .o_rst(rst_oserdes)
    );

    serializer_10to1 serialize_ch0 (
        .i_clk(i_pix_clk),
        .i_clk_hs(i_pix_clk_5x),
        .i_rst_oserdes(rst_oserdes),
        .i_data(tmds_ch0),
        .o_data(o_tmds_ch0_serial)
    );

    serializer_10to1 serialize_ch1 (
        .i_clk(i_pix_clk),
        .i_clk_hs(i_pix_clk_5x),
        .i_rst_oserdes(rst_oserdes),
        .i_data(tmds_ch1),
        .o_data(o_tmds_ch1_serial)
    );

    serializer_10to1 serialize_ch2 (
        .i_clk(i_pix_clk),
        .i_clk_hs(i_pix_clk_5x),
        .i_rst_oserdes(rst_oserdes),
        .i_data(tmds_ch2),
        .o_data(o_tmds_ch2_serial)
    );

    serializer_10to1 serialize_chc (
        .i_clk(i_pix_clk),
        .i_clk_hs(i_pix_clk_5x),
        .i_rst_oserdes(rst_oserdes),
        .i_data(10'b0000011111),
        .o_data(o_tmds_chc_serial)
    );

endmodule
module async_reset(
    input  wire i_clk,      // clock
    input  wire i_rst,      // reset (active high)
    output reg  o_rst       // output reset
    );

    (* ASYNC_REG = "TRUE" *) reg [1:0] rst_shf;  // reset shift reg

    initial o_rst = 1'b1;       // start off with reset asserted
    initial rst_shf = 2'b11;    //  and reset shift reg populated

    always @(posedge i_clk or posedge i_rst)
    if (i_rst)
        {o_rst, rst_shf} <= 3'b111;
    else
        {o_rst, rst_shf} <= {rst_shf, 1'b0};

endmodule
module tmds_encode_dvi_tb();

    reg rst;
    reg clk;

    reg [7:0] data;
    reg [1:0] ctrl;
    reg de;
    wire [9:0] tmds;
    reg [8:0] cycle;

    // encoded TMDS data $display(...) is within tmds_encoder_dvi.v
    initial begin
        $display("\t               1s    B   O");
        clk = 1;
        rst = 1;
        de = 0;
        ctrl = 2'b00;

        #10
        rst = 0;

        #10
        de = 1;
    end

    tmds_encoder_dvi tmds_test (
        .i_clk(clk),
        .i_rst(rst),
        .i_data(data),
        .i_ctrl(ctrl),
        .i_de(de),
        .o_tmds(tmds)
    );

    always @ (posedge clk or posedge rst)
    begin
        if (rst)
        begin
            cycle <= 0;
            data <= 0;
        end
        else
        begin
            cycle <= cycle + 1;
            data <= cycle[7:0];
        end
    end

    always
       #5 clk = ~clk;

endmodule
module serializer_10to1_tb();

    reg rst;
    reg clk;
    reg clk_5x;
    reg clk_lock;  // clocks locked?

    wire rst_oserdes;
    reg [9:0] tmds_data_1;
    reg [9:0] tmds_data_2;
    reg [9:0] tmds_data_3;
    wire tmds_data_1_serial;
    wire tmds_data_2_serial;
    wire tmds_data_3_serial;

    initial begin
        $display($time, " << Starting Simulation >>");
        clk = 0;
        clk_5x = 0;
        rst = 0;
        clk_lock = 0;

        #1.5
        rst = 1;  // assert reset async

        #18.5
        rst = 0;

        #20
        clk_lock = 1;
        tmds_data_1 = 10'b0110100110;
        tmds_data_2 = 10'b1001011001;
        tmds_data_3 = 10'b1100000010;

        #100
        tmds_data_1 = 10'b1111111111;
        tmds_data_2 = 10'b1010101010;
        tmds_data_3 = 10'b0000000000;

        #2
        clk_lock = 0;  // simulate loss of clock lock

        #23
        clk_lock = 1;

        #125
        tmds_data_1 = 10'b0110100110;
        tmds_data_2 = 10'b1001011001;
        tmds_data_3 = 10'b1100000010;

        #101.25
        rst = 1;  // assert reset async

        #11.5
        rst = 0;  // de-assert reset async
    end

    // common async reset for serdes
    async_reset async_reset_instance (
        .i_clk(clk),
        .i_rst(rst | ~clk_lock),
        .o_rst(rst_oserdes)
    );

    serializer_10to1 serialize_data_1 (
        .i_clk(clk),
        .i_clk_hs(clk_5x),
        .i_rst_oserdes(rst_oserdes),
        .i_data(tmds_data_1),
        .o_data(tmds_data_1_serial)
    );

    serializer_10to1 serialize_data_2 (
        .i_clk(clk),
        .i_clk_hs(clk_5x),
        .i_rst_oserdes(rst_oserdes),
        .i_data(tmds_data_2),
        .o_data(tmds_data_2_serial)
    );

     serializer_10to1 serialize_data_3 (
        .i_clk(clk),
        .i_clk_hs(clk_5x),
        .i_rst_oserdes(rst_oserdes),
        .i_data(tmds_data_3),
        .o_data(tmds_data_3_serial)
    );

    always
        #5 clk = ~clk;

    always
        #1 clk_5x = ~clk_5x;

endmodule
module display_timings_tb();

    // Display timings: 640x480p60
    reg rst_480p;
    reg clk_480p;

    wire [15:0] sx_480p; // horizontal screen position
    wire [15:0] sy_480p; // vertical screen position
    wire h_sync_480p;    // horizontal sync
    wire v_sync_480p;    // vertical sync
    wire de_480p;        // display enable: high during active video
    wire frame_480p;     // high for one tick at the start of each frame

    display_timings #(
        .H_RES(640),
        .V_RES(480),
        .H_FP(16),
        .H_SYNC(96),
        .H_BP(48),
        .V_FP(10),
        .V_SYNC(2),
        .V_BP(33),
        .H_POL(0),
        .V_POL(0)
    )
    display_timings_480p (
        .i_pix_clk(clk_480p),
        .i_rst(rst_480p),
        .o_hs(h_sync_480p),
        .o_vs(v_sync_480p),
        .o_de(de_480p),
        .o_frame(frame_480p),
        .o_sx(sx_480p),
        .o_sy(sy_480p)
    );


    // Display timings: 1280x720p60
    reg rst_720p;
    reg clk_720p;

    wire [15:0] sx_720p; // horizontal screen position
    wire [15:0] sy_720p; // vertical screen position
    wire h_sync_720p;    // horizontal sync
    wire v_sync_720p;    // vertical sync
    wire de_720p;        // display enable: high during active video
    wire frame_720p;     // high for one tick at the start of each frame

    display_timings #(
        .H_RES(1280),
        .V_RES(720),
        .H_FP(110),
        .H_SYNC(40),
        .H_BP(220),
        .V_FP(5),
        .V_SYNC(5),
        .V_BP(20),
        .H_POL(1),
        .V_POL(1)
    )
    display_timings_720p (
        .i_pix_clk(clk_720p),
        .i_rst(rst_720p),
        .o_hs(h_sync_720p),
        .o_vs(v_sync_720p),
        .o_de(de_720p),
        .o_frame(frame_720p),
        .o_sx(sx_720p),
        .o_sy(sy_720p)
    );


    initial begin
        $display($time, " << Starting Simulation >>");
        clk_480p = 1;
        rst_480p = 1;
        clk_720p = 1;
        rst_720p = 1;

        #10
        rst_480p = 0;
        rst_720p = 0;
    end

    always
       #19.84 clk_480p = ~clk_480p;  // 39.68 ns clock cycle (25.2 MHz)

    always
       #6.73 clk_720p = ~clk_720p;  // 13.47 ns clock cycle (74.5 MHz)

endmodule
module async_reset_tb();

    reg rst;
    reg clk;

    wire rst_output;
    async_reset async_reset_instance (
        .i_clk(clk),
        .i_rst(rst),
        .o_rst(rst_output)
    );

    initial begin
        $display($time, " << Starting Simulation >>");
        clk = 1;
        rst = 0;

        #3.14159
        rst = 1;

        #27.1828
        rst = 0;

        #40
        rst = 1;

        #15
        rst = 0;
    end

    always
        #5 clk = ~clk;

endmodule
module display_clocks_tb();

    reg rst;
    reg clk;

    // Display clocks: 640x480p60
    wire pix_clk_480p;
    wire pix_clk_5x_480p;
    wire clk_lock_480p;

    display_clocks #(
        .MULT_MASTER(31.5),
        .DIV_MASTER(5),
        .DIV_5X(5.0),
        .DIV_1X(25),
        .IN_PERIOD(10.0)
    )
    display_clocks_480p
    (
       .i_clk(clk),
       .i_rst(rst),
       .o_clk_1x(pix_clk_480p),
       .o_clk_5x(pix_clk_5x_480p),
       .o_locked(clk_lock_480p)
    );


    // Display clocks: 800x600p60
    wire pix_clk_600p;
    wire pix_clk_5x_600p;
    wire clk_lock_600p;

    display_clocks #(
        .MULT_MASTER(10.0),
        .DIV_MASTER(1),
        .DIV_5X(5.0),
        .DIV_1X(25),
        .IN_PERIOD(10.0)
    )
    display_clocks_600p
    (
       .i_clk(clk),
       .i_rst(rst),
       .o_clk_1x(pix_clk_600p),
       .o_clk_5x(pix_clk_5x_600p),
       .o_locked(clk_lock_600p)
    );


    // Display clocks: 1280x720p60
    wire pix_clk_720p;
    wire pix_clk_5x_720p;
    wire clk_lock_720p;

    display_clocks #(
        .MULT_MASTER(37.125),
        .DIV_MASTER(5),
        .DIV_5X(2.0),
        .DIV_1X(10),
        .IN_PERIOD(10.0)
    )
    display_clocks_720p
    (
       .i_clk(clk),
       .i_rst(rst),
       .o_clk_1x(pix_clk_720p),
       .o_clk_5x(pix_clk_5x_720p),
       .o_locked(clk_lock_720p)
    );


    // Display clocks: 1920x1080p60
    wire pix_clk_1080p;
    wire pix_clk_5x_1080p;
    wire clk_lock_1080p;

    display_clocks #(
        .MULT_MASTER(37.125),
        .DIV_MASTER(5),
        .DIV_5X(1.0),
        .DIV_1X(5),
        .IN_PERIOD(10.0)
    )
    display_clocks_1080p
    (
       .i_clk(clk),
       .i_rst(rst),
       .o_clk_1x(pix_clk_1080p),
       .o_clk_5x(pix_clk_5x_1080p),
       .o_locked(clk_lock_1080p)
    );


    initial begin
        $display($time, " << Starting Simulation >>");
        clk = 1;
        rst = 1;
        #10
        rst = 0;
        #10000
        $display($time, " << Simulation Complete >>");
    end

    always
       #5 clk = ~clk;

endmodule
module test_card_gradient (
    input wire [5:0] i_x,
    input wire [7:0] i_y,
    output wire [7:0] o_red,
    output wire [7:0] o_green,
    output wire [7:0] o_blue
    );

    localparam base_red     = 8'h00;
    localparam base_green   = 8'h10;
    localparam base_blue    = 8'h4C;

    assign o_red    = base_red + i_y + {2'b0, i_x};
    assign o_green  = base_green + i_y;
    assign o_blue   = base_blue + i_y;
endmodule
module clock_counter #(
    parameter REFCLK_SECOND_COUNTER = `CLOCK_RATE
)(
    input               clock_ref,
    input               rst,
    input               clock_input,
    output  reg  [31:0] value
);

//Local Parameters

//Registers/Wires
reg [31:0]  ref_count;
reg         capture;
wire        cc_capture;
reg [31:0]  counter;
reg         data_ready_strobe;
wire        ref_data_ready;
reg [31:0]  input_value;


//Submodules
cross_clock_strobe ccc(
    .rst            (rst                ),
    .in_clk         (clock_ref          ),
    .in_stb         (capture            ),

    .out_clk        (clock_input        ),
    .out_stb        (cc_strobe          )

);

cross_clock_strobe ccd(
    .rst            (rst                ),
    .in_clk         (clock_input        ),
    .in_stb         (data_ready_strobe  ),

    .out_clk        (clock_ref          ),
    .out_stb        (ref_data_ready     )
);

//Asynchronous Logic

//Synchronous Logic
always @ (posedge clock_ref) begin
    if (rst) begin
        capture         <=  0;
        ref_count       <=  0;
        value           <=  0;
    end
    else begin
        capture         <=  0;
        if (ref_count < REFCLK_SECOND_COUNTER) begin
            ref_count   <=  ref_count + 32'h01;
        end
        else begin
            ref_count   <=  0;
            capture     <=  1;
        end
        if (ref_data_ready) begin
            value       <= input_value;
        end
    end
end

always @ (posedge clock_input) begin
    if (rst) begin
        counter             <= 0;
        input_value         <= 0;
        data_ready_strobe   <= 0;
    end
    else begin
        data_ready_strobe   <= 0;
        counter <= counter + 1;
        if (cc_strobe) begin
            input_value         <= counter;
            data_ready_strobe   <= 1;
            counter               <= 0;
        end
    end
end

endmodule
module TEMPLATE (
  input                     clk,
  input                     rst
  //output  reg   [7:0]       o_reg_example
  //input         [7:0]       i_reg_example

);
//local parameters
localparam     PARAM1  = 32'h00000000;
//registes/wires
//submodules
//asynchronous logic
//synchronous logic



endmodule
module adapter_axi_stream_2_block_fifo #(
  parameter                         DATA_WIDTH = 32,
  parameter                         STROBE_WIDTH = DATA_WIDTH / 8,
  parameter                         USE_KEEP = 0
)(
  input                             rst,

  //AXI Stream Input
  input                             i_axi_clk,
  output                            o_axi_ready,
  input       [DATA_WIDTH - 1:0]    i_axi_data,
  input       [STROBE_WIDTH - 1:0]  i_axi_keep,
  input                             i_axi_last,
  input                             i_axi_valid,

  //Ping Pong FIFO Write Controller
  output                            o_block_fifo_clk,
  input                             i_block_fifo_rdy,
  output  reg                       o_block_fifo_act,
  input       [23:0]                i_block_fifo_size,
  output  reg                       o_block_fifo_stb,
  output  reg [DATA_WIDTH - 1:0]    o_block_fifo_data
);
//local parameters
localparam      IDLE        = 0;
localparam      READY       = 1;
localparam      RELEASE     = 2;
//registes/wires
wire                        clk;  //Convenience Signal
reg           [3:0]         state;
reg           [23:0]        r_count;
//submodules
//asynchronous logic

//This is a little strange to just connect the output clock with the input clock but if this is done
//Users do not need to figure out how to hook up the clocks
assign  o_block_fifo_clk    = i_axi_clk;
assign  clk             = i_axi_clk;
assign  o_axi_ready     = o_block_fifo_act && (r_count < i_block_fifo_size);
//synchronous logic

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

  if (rst) begin
    r_count                 <=  0;
    o_block_fifo_act        <=  0;
    o_block_fifo_data       <=  0;
    state                   <=  IDLE;
  end
  else begin
    case (state)
      IDLE: begin
        o_block_fifo_act        <=  0;
        if (i_block_fifo_rdy && !o_block_fifo_act) begin
          r_count           <=  0;
          o_block_fifo_act  <=  1;
          state             <=  READY;
        end
      end
      READY: begin
        if (r_count < i_block_fifo_size) begin
          if (i_axi_valid) begin
            o_block_fifo_stb    <=  1;
            o_block_fifo_data   <=  i_axi_data;

            r_count         <=  r_count + 1;
          end
        end
        //Conditions to release the FIFO or stop a transaction
        else begin
          state             <=  RELEASE;
        end
        if (i_axi_last) begin
          state             <=  RELEASE;
        end
      end
      RELEASE: begin
        o_block_fifo_act        <=  0;
        state               <=  IDLE;
      end
      default: begin
      end
    endcase
  end
end

endmodule
module bram #(
parameter DATA_WIDTH        = 32,
parameter ADDR_WIDTH        = 10,
parameter MEM_FILE          = "NOTHING",
parameter MEM_FILE_LENGTH   = -1

)(
input                             clk,
input                             rst,

input                             en,
input                             we,
input       [(ADDR_WIDTH - 1):0]  write_address,
input       [(ADDR_WIDTH - 1):0]  read_address,
input       [(DATA_WIDTH - 1):0]  data_in,
output reg  [(DATA_WIDTH - 1):0]  data_out
);


//synthesis attribute ram_style of mem is block
reg [(DATA_WIDTH - 1):0] mem [0:((1 << ADDR_WIDTH) - 1)]; //pragma attribute mem ram_block TRUE
reg [(ADDR_WIDTH - 1):0] read_address_reg;

initial begin
  if (MEM_FILE != "NOTHING") begin
    $display("Loading file...");
    $readmemh(MEM_FILE, mem, 0, MEM_FILE_LENGTH - 1);
  end
end

always @ (posedge clk) begin
	if (rst) begin
		data_out <= 0;
	end
	else begin
		if (en) begin
			read_address_reg <= read_address;

			if (we) begin
				mem[write_address] <= data_in;
			end
			data_out <= mem[read_address_reg];
		end
	end
end

endmodule
module video_to_block_fifo #(
    parameter BUFFER_SIZE = 9
)(
input               clk,
input               rst,


input               i_enable,

input               i_video_hsync,
input               i_video_sof_stb,
input       [7:0]   i_red,
input       [7:0]   i_green,
input       [7:0]   i_blue,

//Memory FIFO Interface
input               i_rfifo_clk,
input               i_rfifo_rst,
output              o_rfifo_ready,
input               i_rfifo_activate,
input               i_rfifo_strobe,
output      [24:0]  o_rfifo_data,
output      [23:0]  o_rfifo_size
);

//Local Parameters
//Registers/Wires
wire                w_write_ready;
reg                 r_write_activate;
wire  [23:0]        w_write_fifo_size;
reg                 r_write_stb;
reg   [24:0]        r_write_data;
reg                 r_used;
reg   [23:0]        r_count;  //XXX: Don't need this in the final design but it's good for debugging

//Submodules
block_fifo #(
  .DATA_WIDTH       (25                 ),
  .ADDRESS_WIDTH    (BUFFER_SIZE        )
) bf (
  .reset            (rst | i_rfifo_rst  ),

  //write side
  .write_clock      (clk                ),
  .write_ready      (w_write_ready      ),
  .write_activate   (r_write_activate   ),
  .write_fifo_size  (w_write_fifo_size  ),
  .write_strobe     (r_write_stb        ),
  .write_data       (r_write_data       ),

  //read size
  .read_clock       (i_rfifo_clk        ),
  .read_strobe      (i_rfifo_strobe     ),
  .read_ready       (o_rfifo_ready      ),
  .read_activate    (i_rfifo_activate   ),
  .read_count       (o_rfifo_size       ),
  .read_data        (o_rfifo_data       )
);

//Asynchronous Logic
//Synchronous Logic
always @ (posedge clk) begin
  r_write_stb                       <=  0;
  if (rst) begin
    r_write_activate                <=  0;
    r_write_stb                     <=  0;
    r_write_data                    <=  0;
    r_used                          <=  0;
    r_count                         <=  0;
  end
  else begin
    if (i_enable && !r_write_activate && w_write_ready) begin
      r_write_activate              <=  1;
      r_used                        <=  0;
      r_count                       <=  0;
    end
    if (r_write_activate) begin
      if (i_video_hsync) begin
        r_write_data                <=  {i_video_sof_stb, i_red, i_green, i_blue};
        r_write_stb                 <=  1;
        r_used                      <=  1;
        r_count                     <=  r_count + 1;
      end
      else if (r_used) begin
  
        r_write_activate            <=  0;
      end
    end
  end
end
endmodule
module blk_mem #(
  parameter DATA_WIDTH      = 8,
  parameter ADDRESS_WIDTH   = 4,
  parameter INC_NUM_PATTERN = 0
)(
  input                             clka,
  input                             wea,
  input   [ADDRESS_WIDTH - 1  :0]   addra,
  input   [DATA_WIDTH - 1:0]        dina,
  input                             clkb,
  input   [ADDRESS_WIDTH - 1:0]     addrb,
  output  [DATA_WIDTH - 1:0]        doutb
);

//Parameters
//Registers/Wires
reg [DATA_WIDTH - 1:0] mem [0:2 ** ADDRESS_WIDTH];
reg [DATA_WIDTH - 1:0] dout;

//Submodules
//Asynchronous Logic
assign doutb = dout;

//Synchronous Logic
//write only on the A side
`ifdef SIMULATION
integer i;
initial begin
  i = 0;
  for (i = 0; i < (2 ** ADDRESS_WIDTH); i = i + 1) begin
    if (INC_NUM_PATTERN) begin
        mem[i]  <=  i;
    end
    else begin
        //Zero Everything Out
        mem[i]  <=  0;
    end
  end
end
`endif

always @ (posedge clka)
begin
  if ( wea ) begin
     mem[addra] <= dina;
  end
end

//read only on the b side
always @ (posedge clkb)
begin
     dout <= mem[addrb];
end


endmodule
module startup #(
  parameter         RESET_TIMEOUT = 32'h0000FFFF
)(
  input             clk,
  output  reg       startup_rst = 1
);

//Local Parameters
//Registers/Wires
reg   [31:0]        startup_count;
//Submodules
//Asynchronous Logic
//Synchronous Logic
always @ (posedge clk) begin
  if (startup_count < RESET_TIMEOUT) begin
    startup_count <=  startup_count + 1;
    startup_rst   <=  1;
  end
  else begin
    startup_rst   <= 0;
  end
end

endmodule
module adapter_axi_stream_2_ppfifo #(
  parameter                         DATA_WIDTH = 32,
  parameter                         STROBE_WIDTH = DATA_WIDTH / 8,
  parameter                         USE_KEEP = 0
)(
  input                             rst,

  //AXI Stream Input
  input                             i_axi_clk,
  output                            o_axi_ready,
  input       [DATA_WIDTH - 1:0]    i_axi_data,
  input       [STROBE_WIDTH - 1:0]  i_axi_keep,
  input                             i_axi_last,
  input                             i_axi_valid,

  //Ping Pong FIFO Write Controller
  output                            o_ppfifo_clk,
  input       [1:0]                 i_ppfifo_rdy,
  output  reg [1:0]                 o_ppfifo_act,
  input       [23:0]                i_ppfifo_size,
  output  reg                       o_ppfifo_stb,
  output  reg [DATA_WIDTH - 1:0]    o_ppfifo_data
);
//local parameters
localparam      IDLE        = 0;
localparam      READY       = 1;
localparam      RELEASE     = 2;
//registes/wires
wire                        clk;  //Convenience Signal
reg           [3:0]         state;
reg           [23:0]        r_count;
//submodules
//asynchronous logic

//This is a little strange to just connect the output clock with the input clock but if this is done
//Users do not need to figure out how to hook up the clocks
assign  o_ppfifo_clk    = i_axi_clk;
assign  clk             = i_axi_clk;
assign  o_axi_ready     = (o_ppfifo_act > 0) && (r_count < i_ppfifo_size);
//synchronous logic

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

  if (rst) begin
    r_count                 <=  0;
    o_ppfifo_act            <=  0;
    o_ppfifo_data           <=  0;
    state                   <=  IDLE;
  end
  else begin
    case (state)
      IDLE: begin
        o_ppfifo_act        <=  0;
        if ((i_ppfifo_rdy > 0) && (o_ppfifo_act == 0)) begin
          r_count           <=  0;
          if (i_ppfifo_rdy[0]) begin
            o_ppfifo_act[0] <=  1;
          end
          else begin
            o_ppfifo_act[1] <=  1;
          end
          state             <=  READY;
        end
      end
      READY: begin
        if (r_count < i_ppfifo_size) begin
          if (i_axi_valid) begin
            o_ppfifo_stb    <=  1;
            o_ppfifo_data   <=  i_axi_data;

            r_count         <=  r_count + 1;
          end
        end
        //Conditions to release the FIFO or stop a transaction
        else begin
          state             <=  RELEASE;
        end
        if (i_axi_last) begin
          state             <=  RELEASE;
        end
      end
      RELEASE: begin
        o_ppfifo_act        <=  0;
        state               <=  IDLE;
      end
      default: begin
      end
    endcase
  end
end

endmodule
module pwm (
  input               clk,
  input               rst,

  input               en,

  input       [31:0]  period,
  input       [31:0]  duty_cycle,

  output  reg          out
);

//Local Parameters
//Registers/Wires
reg   [31:0]            count;
//Submodules
//Asynchronous Logic
//Synchronous Logic
always @ (posedge clk) begin
  if (rst || !en) begin
    count           <=  0;
    out             <=  0;
  end
  else begin
    if (count < period) begin
      count         <=  count + 1;
    end
    else begin
      count         <=  0;
    end

    if (count < duty_cycle) begin
      out           <=  1;
    end
    else begin
      out           <=  0;
    end
  end
end
endmodule
module dual_port_bram #(
  parameter DATA_WIDTH = 32,
  parameter ADDR_WIDTH = 10,
  parameter MEM_FILE  = "NOTHING",
  parameter MEM_FILE_LENGTH = 0
) (
  //Port A
  a_clk,
  a_wr,
  a_addr,
  a_din,
  a_dout,

  b_clk,
  b_wr,
  b_addr,
  b_din,
  b_dout
);

input                             a_clk;
input                             a_wr;
input   wire  [ADDR_WIDTH - 1: 0] a_addr;
input   wire  [DATA_WIDTH - 1: 0] a_din;
output  reg   [DATA_WIDTH - 1: 0] a_dout;

input                             b_clk;
input                             b_wr;
input   wire  [ADDR_WIDTH - 1: 0] b_addr;
input   wire  [DATA_WIDTH - 1: 0] b_din;
output  reg   [DATA_WIDTH - 1: 0] b_dout;

//Shared Memory
reg     [DATA_WIDTH - 1: 0]       mem [(1 << ADDR_WIDTH) - 1: 0];

generate
if (MEM_FILE != "NOTHING") begin
initial begin
    $readmemh(MEM_FILE, mem, 0, MEM_FILE_LENGTH - 1);
end
end
endgenerate

//Port A
always @ (posedge a_clk) begin
  a_dout          <=              mem[a_addr];
  if (a_wr) begin
    a_dout        <=  a_din;
    mem[a_addr]   <=  a_din;
  end
end


//Port B
always @ (posedge b_clk) begin
  b_dout          <=              mem[b_addr];
  if (b_wr) begin
    b_dout        <=              b_din;
    mem[b_addr]   <=              b_din;
  end
end

endmodule
module dpb #(
  parameter DATA_WIDTH = 32,
  parameter ADDR_WIDTH = 10,
  parameter MEM_FILE  = "NOTHING",
  parameter MEM_FILE_LENGTH = 0,
  parameter INITIALIZE = 0
) (
    input                             clka,
    input                             wea,
    input   wire  [ADDR_WIDTH - 1: 0] addra,
    input   wire  [DATA_WIDTH - 1: 0] dina,
    output  reg   [DATA_WIDTH - 1: 0] douta = 0,

    input                             clkb,
    input                             web,
    input   wire  [ADDR_WIDTH - 1: 0] addrb,
    input   wire  [DATA_WIDTH - 1: 0] dinb,
    output  reg   [DATA_WIDTH - 1: 0] doutb = 0
);

//Shared Memory
reg     [DATA_WIDTH - 1: 0]       mem [(1 << ADDR_WIDTH) - 1: 0];

integer i;
generate
if (MEM_FILE != "NOTHING") begin
  initial begin
    $readmemh(MEM_FILE, mem, 0, MEM_FILE_LENGTH - 1);
  end
end
else begin
  initial begin
    if (INITIALIZE == 1) begin
      for (i = 0; i < (1 << ADDR_WIDTH); i = i + 1) begin
        mem[i]      <= 0;
      end
    end
  end
end
endgenerate

//Port A
always @ (posedge clka) begin
  douta          <=              mem[addra];
  if (wea) begin
    douta        <=  dina;
    mem[addra]   <=  dina;
  end
end


//Port B
always @ (posedge clkb) begin
  doutb          <=              mem[addrb];
  if (web) begin
    doutb        <=              dinb;
    mem[addrb]   <=              dinb;
  end
end

endmodule
module adapter_ppfifo_2_axi_stream #(
  parameter                                     DATA_WIDTH          = 24,
  parameter                                     STROBE_WIDTH        = DATA_WIDTH / 8,
  parameter                                     USE_KEEP            = 0
)(
  input                                         rst,

  //Ping Poing FIFO Read Interface
  input                                         i_ppfifo_rdy,
  output  reg                                   o_ppfifo_act,
  input       [23:0]                            i_ppfifo_size,
  input       [(DATA_WIDTH + 1) - 1:0]          i_ppfifo_data,
  output                                        o_ppfifo_stb,

  //AXI Stream Output

  input                                         i_axi_clk,
  output      [3:0]                             o_axi_user,
  input                                         i_axi_ready,
  output      [DATA_WIDTH - 1:0]                o_axi_data,
  output                                        o_axi_last,
  output  reg                                   o_axi_valid,

  output      [31:0]                            o_debug
);

//local parameters
localparam      IDLE        = 0;
localparam      READY       = 1;
localparam      RELEASE     = 2;

//registes/wires
reg     [3:0]               state;
reg     [23:0]              r_count;

//submodules
//asynchronous logic
assign  o_axi_data      = i_ppfifo_data[DATA_WIDTH - 1: 0];
assign  o_ppfifo_stb    = (i_axi_ready & o_axi_valid);

assign  o_axi_user[0]   = (r_count < i_ppfifo_size) ? i_ppfifo_data[DATA_WIDTH] : 1'b0;
assign  o_axi_user[3:1] = 3'h0;

assign  o_axi_last      = ((r_count + 1) >= i_ppfifo_size) & o_ppfifo_act  & o_axi_valid;
//synchronous logic

assign  o_debug[3:0]    = state;
assign  o_debug[4]      = (r_count < i_ppfifo_size) ? i_ppfifo_data[DATA_WIDTH]: 1'b0;
assign  o_debug[5]      = o_ppfifo_act;
assign  o_debug[6]      = i_ppfifo_rdy;
assign  o_debug[7]      = (r_count > 0);
assign  o_debug[8]      = (i_ppfifo_size > 0);
assign  o_debug[9]      = (r_count == i_ppfifo_size);
assign  o_debug[15:10]  = 0;
assign  o_debug[23:16]  = r_count[7:0];
assign  o_debug[31:24]  = 0;

always @ (posedge i_axi_clk) begin
  o_axi_valid           <=  0;

  if (rst) begin
    state               <=  IDLE;
    o_ppfifo_act        <=  0;
    r_count             <=  0;
  end
  else begin
    case (state)
      IDLE: begin
        o_ppfifo_act    <=  0;
        if (i_ppfifo_rdy && !o_ppfifo_act) begin
          r_count       <=  0;
          o_ppfifo_act  <=  1;
          state         <=  READY;
        end
      end
      READY: begin
        if (r_count < i_ppfifo_size) begin
          o_axi_valid         <=  1;
          if (i_axi_ready && o_axi_valid) begin
            r_count         <= r_count + 1;
            if ((r_count + 1) >= i_ppfifo_size) begin
              o_axi_valid     <=  0;
            end
          end
        end
        else begin
          o_ppfifo_act      <=  0;
          state             <=  RELEASE;
        end
      end
      RELEASE: begin
        state               <=  IDLE;
      end
      default: begin
      end
    endcase
  end
end

endmodule
module GrayCounter
   #(parameter   COUNTER_WIDTH = 4)
   
    (output reg  [COUNTER_WIDTH-1:0]    gray_count_out,  //'Gray' code count output.
    
     input wire                         en,  //Count enable.
     input wire                         rst,   //Count reset.
    
     input wire                         clk);

    /////////Internal connections & variables///////
    reg    [COUNTER_WIDTH-1:0]         binary_count;

    /////////Code///////////////////////
    
    always @ (posedge clk)
        if (rst) begin
            binary_count   <= {COUNTER_WIDTH{1'b 0}} + 1;  //Gray count begins @ '1' with
            gray_count_out <= {COUNTER_WIDTH{1'b 0}};      // first 'en'.
        end
        else if (en) begin
            binary_count   <= binary_count + 1;
            gray_count_out <= {binary_count[COUNTER_WIDTH-1],
                              binary_count[COUNTER_WIDTH-2:0] ^ binary_count[COUNTER_WIDTH-1:1]};
        end
    
endmodule
module sync_fifo #(
  parameter MEM_DEPTH   = 8,
  parameter DATA_WIDTH  = 32
)(
  input                           wr_clk,
  input                           rd_clk,
  input                           rst,

  output                          o_wr_full,
  //output  reg                     o_rd_empty,
  output                          o_rd_empty,

  input       [DATA_WIDTH - 1: 0] i_wr_data,
  input                           i_wr_stb,

  input                           i_rd_stb,
  output                          o_rd_last,
  output      [DATA_WIDTH - 1: 0] o_rd_data
);

//localparameters
localparam  MEM_SIZE = (2 ** (MEM_DEPTH));
//Registers/Wires
reg [DATA_WIDTH - 1: 0] mem[0:MEM_SIZE];
reg [MEM_DEPTH - 1: 0]      r_in_pointer;
reg [MEM_DEPTH - 1: 0]      r_out_pointer;
wire                        w_o_rd_empty;

wire  [MEM_DEPTH - 1: 0]    w_next_wr_addr;

//Submodules
//Asynchronous Logic
assign  w_next_wr_addr  = (r_in_pointer + 1) & (MEM_SIZE - 1);
//assign  w_o_rd_empty = (r_in_pointer == r_out_pointer);
assign  o_rd_empty = (r_in_pointer == r_out_pointer);
assign  o_rd_last  = ((r_out_pointer + 1) == r_in_pointer);
//assign  o_wr_full  = (r_out_pointer == 0) ? (r_in_pointer == (MEM_SIZE - 1)) : ((r_in_pointer + 1) == r_out_pointer);
assign  o_wr_full  = (w_next_wr_addr == r_out_pointer);
assign  o_rd_data  = mem[r_out_pointer];
//Synchronous Logic

always @ (posedge wr_clk) begin
  if (rst) begin
    r_in_pointer  <=  0;
  end
  else begin
    if (i_wr_stb) begin
      mem[r_in_pointer] <=  i_wr_data;
      if (!o_wr_full) begin
        r_in_pointer      <=  r_in_pointer + 1;
      end
    end
  end
end

always @ (posedge rd_clk) begin
  if (rst) begin
    r_out_pointer <=  0;
    //o_rd_empty         <=  1;
  end
  else begin
    //o_rd_empty               <=  w_o_rd_empty;
    if(i_rd_stb && !o_rd_empty) begin
      r_out_pointer     <=  r_out_pointer + 1;
    end
  end
end
 
endmodule
module cross_clock_strobe (
  input         rst,
  input         in_clk,
  input         in_stb,

  input         out_clk,
  output        out_stb
);

//parameters
//registers/wires
reg             toggle_stb;
reg       [2:0] sync_out_clk;
//submodules
//asynchronous logic
assign          out_stb = (sync_out_clk[2] ^ sync_out_clk[1]);
//synchronous logic

always @ (posedge in_clk) begin
  if (rst) begin
    toggle_stb    <=  0;
  end
  else begin
    if (in_stb) begin
      toggle_stb  <=  ~toggle_stb;
    end
  end
end

always @ (posedge out_clk) begin
  if (rst) begin
    sync_out_clk  <=  0;
  end
  else begin
    sync_out_clk  <=  {sync_out_clk[1:0], toggle_stb};
  end
end

endmodule
module wishbone_mem_interconnect (
  //Control Signals
  input               clk,
  input               rst,

  //Master Signals
  input               i_m_we,
  input               i_m_stb,
  input               i_m_cyc,
  input       [3:0]   i_m_sel,
  input       [31:0]  i_m_adr,
  input       [31:0]  i_m_dat,
  output reg  [31:0]  o_m_dat,
  output reg          o_m_ack,
  output reg          o_m_int,

  //Slave 0
  output              o_s0_we,
  output              o_s0_cyc,
  output              o_s0_stb,
  output    [3:0]     o_s0_sel,
  input               i_s0_ack,
  output    [31:0]    o_s0_dat,
  input     [31:0]    i_s0_dat,
  output    [31:0]    o_s0_adr,
  input               i_s0_int

);


parameter MEM_SEL_0 = 0;
parameter MEM_OFFSET_0  =  0;
parameter MEM_SIZE_0  =  8388607;


reg [31:0] mem_select;

always @(rst or i_m_adr or mem_select) begin
  if (rst) begin
    //nothing selected
    mem_select <= 32'hFFFFFFFF;
  end
  else begin
    if ((i_m_adr >= MEM_OFFSET_0) && (i_m_adr < (MEM_OFFSET_0 + MEM_SIZE_0))) begin
      mem_select <= MEM_SEL_0;
    end
    else begin
      mem_select <= 32'hFFFFFFFF;
    end
  end
end


//data in from slave
always @ (mem_select or i_s0_dat) begin
  case (mem_select)
    MEM_SEL_0: begin
      o_m_dat <= i_s0_dat;
    end
    default: begin
      o_m_dat <= 32'h0000;
    end
  endcase
end



//ack in from mem slave
always @ (mem_select or i_s0_ack) begin
  case (mem_select)
    MEM_SEL_0: begin
      o_m_ack <= i_s0_ack;
    end
    default: begin
      o_m_ack <= 1'h0;
    end
  endcase
end



//int in from slave
always @ (mem_select or i_s0_int) begin
  case (mem_select)
    MEM_SEL_0: begin
      o_m_int <= i_s0_int;
    end
    default: begin
      o_m_int <= 1'h0;
    end
  endcase
end



assign o_s0_we   =  (mem_select == MEM_SEL_0) ? i_m_we: 1'b0;
assign o_s0_stb  =  (mem_select == MEM_SEL_0) ? i_m_stb: 1'b0;
assign o_s0_sel  =  (mem_select == MEM_SEL_0) ? i_m_sel: 4'b0;
assign o_s0_cyc  =  (mem_select == MEM_SEL_0) ? i_m_cyc: 1'b0;
assign o_s0_adr  =  (mem_select == MEM_SEL_0) ? i_m_adr: 32'h0;
assign o_s0_dat  =  (mem_select == MEM_SEL_0) ? i_m_dat: 32'h0;



endmodule