dakies/OSS_Verilog huggingface dataset:
module tb;

    localparam n = 30;

    reg         clk;
    reg         rst;
    wire  [3:0] data;
    wire        en;

    reg   [7:0] gap_from;
    reg   [7:0] gap_to;

    wire  [3:0] expected;
    wire        failure;

    tb_sender sender (clk, rst, data, en, gap_from, gap_to);
    tb_receiver receiver (clk, rst, en, data, expected, failure);

    initial
    begin
        clk = 0;

        forever
            # 10 clk = ! clk;
    end

    initial
    begin
        rst <= 1;
        repeat (2) @ (posedge clk);
        rst <= 0;
    end

    initial
    begin
        $dumpvars;

        gap_from <= 0;
        gap_to   <= 0;

        @ (negedge rst);

        // Slow sender

        gap_from <= 5;
        gap_to   <= 5;

        repeat (n) @ (posedge clk);

        // Fast sender

        gap_from <= 0;
        gap_to   <= 0;

        repeat (n) @ (posedge clk);

        // Random sender

        gap_from <= 0;
        gap_to   <= 10;

        repeat (n) @ (posedge clk);

        `ifdef MODEL_TECH  // Mentor ModelSim and Questa
            $stop;
        `else
            $finish;
        `endif
    end

endmodule
module tb_receiver
(
    input            clk,
    input            rst,
    input            en,
    input      [3:0] data,
    output reg [3:0] expected,
    output reg       failure
);

    always @ (posedge clk or posedge rst)
        if (rst)
        begin
            expected <= 1;
            failure  <= 0;
        end
        else if (en)
        begin
            if (data == expected)
            begin
                $display ("Receive %d", data);
                failure <= 0;
            end
            else
            begin
                $display ("Failure: receive %d, expected %d",
                    data, expected);

                failure <= 1;
            end

            expected <= expected + 1;
        end
        else
        begin
            failure <= 0;
        end

endmodule
module pulse_to_toggle
(
    input      clk,
    input      rst,
    input      pulse,
    output reg toggle
);

    always @ (posedge clk or posedge rst)
        if (rst)
            toggle <= 0;
        else
            toggle <= toggle ^ pulse;

endmodule
module tb;

    localparam n = 1000;

    reg         clk;
    reg         rst;
    wire  [3:0] data;
    wire        en;
    reg   [7:0] gap_from;
    reg   [7:0] gap_to;

    reg         f_clk;
    wire        f_en;
    wire  [3:0] f_expected;
    wire        f_failure;

    reg         s_clk;
    wire        s_en;
    wire  [3:0] s_expected;
    wire        s_failure;

    tb_sender   sender        (clk, rst, data, en, gap_from, gap_to);
    tb_receiver fast_receiver (f_clk, rst, f_en, data, f_expected, f_failure);
    tb_receiver slow_receiver (s_clk, rst, s_en, data, s_expected, s_failure);

    wire toggle, f_toggle, s_toggle;

    pulse_to_toggle i_pulse_to_toggle    (clk, rst, en, toggle);

    sync2           i_f_sync2            (f_clk, rst, toggle, f_toggle);
    toggle_to_pulse i_f_toggle_to_pulse  (f_clk, rst, f_toggle, f_en);

    sync2           i_s_sync2            (s_clk, rst, toggle, s_toggle);
    toggle_to_pulse i_s_toggle_to_pulse  (s_clk, rst, s_toggle, s_en);

    initial
    begin
        clk = 0;

        forever
            # 10 clk = ! clk;
    end

    initial
    begin
        f_clk = 0;

        forever
            # 9 f_clk = ! f_clk;
    end

    initial
    begin
        s_clk = 0;

        forever
            # 11 s_clk = ! s_clk;
    end

    initial
    begin
        rst <= 1;
        repeat (2) @ (posedge clk);
        rst <= 0;
    end

    initial
    begin
        $dumpvars;

        gap_from <= 0;
        gap_to   <= 0;

        @ (negedge rst);

        // Slow sender

        gap_from <= 5;
        gap_to   <= 5;

        repeat (n) @ (posedge clk);

        // Fast sender

        gap_from <= 0;
        gap_to   <= 0;

        repeat (n) @ (posedge clk);

        // Random sender

        gap_from <= 0;
        gap_to   <= 10;

        repeat (n) @ (posedge clk);

        `ifdef MODEL_TECH  // Mentor ModelSim and Questa
            $stop;
        `else
            $finish;
        `endif
    end

endmodule
module toggle_to_pulse
(
    input  clk,
    input  rst,
    input  toggle,
    output pulse
);

    reg r_toggle;

    always @ (posedge clk or posedge rst)
        if (rst)
            r_toggle <= 0;
        else
            r_toggle <= toggle;

    assign pulse = toggle ^ r_toggle;

endmodule
module sync2
(
    input      clk,
    input      rst,
    input      in,
    output reg out
);

    reg r;

    always @ (posedge clk or posedge rst)
        if (rst)
            { out, r } <= 0;
        else
            { out, r } <= { r, in };

endmodule
module tb;

    localparam n_cycles_in_series = 100;

    integer s_clk_period;
    integer r_clk_period;

    reg         s_clk;
    reg         rst;
    wire  [3:0] data;
    wire        s_en;
    reg   [7:0] s_gap_from;
    reg   [7:0] s_gap_to;

    reg         r_clk;
    wire        r_en;
    wire  [3:0] r_expected;
    wire        r_failure;

    tb_sender   sender   (s_clk, rst, data, s_en, s_gap_from, s_gap_to);
    tb_receiver receiver (r_clk, rst, r_en, data, r_expected, r_failure);

    wire s_toggle, r_toggle;

    pulse_to_toggle       i_pulse_to_toggle       (s_clk, rst, s_en, s_toggle);
    sync2_toggle_to_pulse i_sync2_toggle_to_pulse (r_clk, rst, s_toggle, r_en, r_toggle);

    initial
    begin
        s_clk = 0;

        forever
            # (s_clk_period / 2) s_clk = ! s_clk;
    end

    initial
    begin
        r_clk = 0;

        forever
            # (r_clk_period / 2) r_clk = ! r_clk;
    end

    task run_series;
    begin
        rst <= 1;
        repeat (10) @ (posedge s_clk);
        rst <= 0;
        repeat (n_cycles_in_series) @ (posedge s_clk);
    end
    endtask

    task test_for_receiver_clock_period (input [31:0] period);
    begin
        r_clk_period = period;

        // Slow sender

        s_gap_from <= 5;
        s_gap_to   <= 5;

        run_series;

        // Fast sender

        s_gap_from <= 0;
        s_gap_to   <= 0;

        run_series;

        // Random sender

        s_gap_from <= 0;
        s_gap_to   <= 10;

        run_series;
    end
    endtask

    initial
    begin
        $dumpvars;

        s_clk_period = 20;

        test_for_receiver_clock_period (20);
        test_for_receiver_clock_period (18);
        test_for_receiver_clock_period (22);

        `ifdef MODEL_TECH  // Mentor ModelSim and Questa
            $stop;
        `else
            $finish;
        `endif
    end

endmodule
module sync2_toggle_to_pulse
(
    input      clk,
    input      rst,
    input      toggle,
    output     pulse,
    output reg out_toggle
);

    wire s_toggle;

    sync2 i_sync2 (clk, rst, toggle, s_toggle);

    always @ (posedge clk or posedge rst)
        if (rst)
            out_toggle <= 0;
        else
            out_toggle <= s_toggle;

    assign pulse = s_toggle ^ out_toggle;

endmodule
module tb;

    localparam n = 1000;

    reg         clk;
    reg         rst;
    wire  [3:0] data;
    wire        en;
    reg   [7:0] gap_from;
    reg   [7:0] gap_to;

    reg         f_clk;
    wire        f_en;
    wire  [3:0] f_expected;
    wire        f_failure;

    reg         s_clk;
    wire        s_en;
    wire  [3:0] s_expected;
    wire        s_failure;

    tb_sender   sender        (clk, rst, data, en, gap_from, gap_to);
    tb_receiver fast_receiver (f_clk, rst, f_en, data, f_expected, f_failure);
    tb_receiver slow_receiver (s_clk, rst, s_en, data, s_expected, s_failure);

    wire toggle;

    pulse_to_toggle       i_pulse_to_toggle         (clk, rst, en, toggle);
    sync2_toggle_to_pulse i_f_sync2_toggle_to_pulse (f_clk, rst, toggle, f_en, );
    sync2_toggle_to_pulse i_s_sync2_toggle_to_pulse (s_clk, rst, toggle, s_en, );

    initial
    begin
        clk = 0;

        forever
            # 10 clk = ! clk;
    end

    initial
    begin
        f_clk = 0;

        forever
            # 9 f_clk = ! f_clk;
    end

    initial
    begin
        s_clk = 0;

        forever
            # 11 s_clk = ! s_clk;
    end

    initial
    begin
        rst <= 1;
        repeat (2) @ (posedge clk);
        rst <= 0;
    end

    initial
    begin
        $dumpvars;

        gap_from <= 0;
        gap_to   <= 0;

        @ (negedge rst);

        // Slow sender

        gap_from <= 5;
        gap_to   <= 5;

        repeat (n) @ (posedge clk);

        // Fast sender

        gap_from <= 0;
        gap_to   <= 0;

        repeat (n) @ (posedge clk);

        // Random sender

        gap_from <= 0;
        gap_to   <= 10;

        repeat (n) @ (posedge clk);

        `ifdef MODEL_TECH  // Mentor ModelSim and Questa
            $stop;
        `else
            $finish;
        `endif
    end

endmodule
module tb;

    localparam n = 50;

    reg         clk;
    reg         rst;
    wire  [3:0] data;
    wire        en;
    reg   [7:0] gap_from;
    reg   [7:0] gap_to;

    reg         f_clk;
    wire  [3:0] f_expected;
    wire        f_failure;

    reg         s_clk;
    wire  [3:0] s_expected;
    wire        s_failure;

    tb_sender   sender        (clk, rst, data, en, gap_from, gap_to);
    tb_receiver fast_receiver (f_clk, rst, en, data, f_expected, f_failure);
    tb_receiver slow_receiver (s_clk, rst, en, data, s_expected, s_failure);

    initial
    begin
        clk = 0;

        forever
            # 10 clk = ! clk;
    end

    initial
    begin
        f_clk = 0;

        forever
            # 9 f_clk = ! f_clk;
    end

    initial
    begin
        s_clk = 0;

        forever
            # 11 s_clk = ! s_clk;
    end

    initial
    begin
        rst <= 1;
        repeat (2) @ (posedge clk);
        rst <= 0;
    end

    initial
    begin
        $dumpvars;

        gap_from <= 0;
        gap_to   <= 0;

        @ (negedge rst);

        // Slow sender

        gap_from <= 5;
        gap_to   <= 5;

        repeat (n) @ (posedge clk);

        // Fast sender

        gap_from <= 0;
        gap_to   <= 0;

        repeat (n) @ (posedge clk);

        // Random sender

        gap_from <= 0;
        gap_to   <= 10;

        repeat (n) @ (posedge clk);

        `ifdef MODEL_TECH  // Mentor ModelSim and Questa
            $stop;
        `else
            $finish;
        `endif
    end

endmodule
module tb_receiver
(
    input            clk,
    input            rst,
    input            en,
    input      [3:0] data,
    output reg [3:0] expected,
    output reg       failure
);

    always @ (posedge clk or posedge rst)
        if (rst)
        begin
            expected <= 1;
            failure  <= 0;
        end
        else if (en)
        begin
            if (data == expected)
            begin
                $display ("Receive %d %d", data, $time);
                failure <= 0;
            end
            else
            begin
                $display ("Failure: receive %d, expected %d %d",
                    data, expected, $time);

                failure <= 1;
            end

            expected <= expected + 1;
        end
        else
        begin 
            failure <= 0;
        end

endmodule
module tb_sender
(
    input            clk,
    input            rst,
    output reg [3:0] data,
    output reg       en,
    input            ack,

    input      [7:0] gap_from,
    input      [7:0] gap_to
);

    reg can_send;

    always @ (posedge clk or posedge rst)
        if (rst)
            can_send <= 1;
        else if (ack)
            can_send <= 1;
        else if (en)
            can_send <= 0;

    reg [7:0] cnt;

    always @ (posedge clk or posedge rst)
        if (rst)
        begin
            data <= 0;
            en   <= 0;
            cnt  <= 0;
        end
        else if (cnt != 0)
        begin
            cnt  <= cnt - 1;
            en   <= 0;
        end
        else if (! en && can_send)
        begin
            $display ("Sending %d", data + 1);

            data <= data + 1;
            en   <= 1;

            cnt  <= $urandom_range (gap_from, gap_to);
        end
        else
        begin
            en   <= 0;
        end

endmodule
module tb;

    localparam n_cycles_in_series = 1000;

    integer s_clk_period;
    integer r_clk_period;

    reg         s_clk;
    reg         rst;
    wire  [3:0] data;
    wire        s_en;
    wire        s_ack;
    reg   [7:0] s_gap_from;
    reg   [7:0] s_gap_to;

    reg         r_clk;
    wire        r_en;
    wire  [3:0] r_expected;
    wire        r_failure;

    tb_sender   sender   (s_clk, rst, data, s_en, s_ack, s_gap_from, s_gap_to);
    tb_receiver receiver (r_clk, rst, r_en, data, r_expected, r_failure);

    wire s_toggle, r_toggle;

    pulse_to_toggle       i_pulse_to_toggle         (s_clk, rst, s_en, s_toggle);
    sync2_toggle_to_pulse i_r_sync2_toggle_to_pulse (r_clk, rst, s_toggle, r_en, r_toggle);
    sync2_toggle_to_pulse i_s_sync2_toggle_to_pulse (s_clk, rst, r_toggle, s_ack, );

    initial
    begin
        s_clk = 0;

        forever
            # (s_clk_period / 2) s_clk = ! s_clk;
    end

    initial
    begin
        r_clk = 0;

        forever
            # (r_clk_period / 2) r_clk = ! r_clk;
    end

    task run_series;
    begin
        rst <= 1;
        repeat (10) @ (posedge s_clk);
        rst <= 0;
        repeat (n_cycles_in_series) @ (posedge s_clk);
    end
    endtask

    task test_for_receiver_clock_period (input [31:0] period);
    begin
        r_clk_period = period;

        // Slow sender

        s_gap_from <= 5;
        s_gap_to   <= 5;

        run_series;

        // Fast sender

        s_gap_from <= 0;
        s_gap_to   <= 0;

        run_series;

        // Random sender

        s_gap_from <= 0;
        s_gap_to   <= 10;

        run_series;
    end
    endtask

    initial
    begin
        $dumpvars;

        s_clk_period = 20;

        test_for_receiver_clock_period (20);
        test_for_receiver_clock_period (18);
        test_for_receiver_clock_period (22);

        `ifdef MODEL_TECH  // Mentor ModelSim and Questa
            $stop;
        `else
            $finish;
        `endif
    end

endmodule
module axis_register_slice_32 (
  aclk,
  aresetn,
  s_axis_tvalid,
  s_axis_tready,
  s_axis_tdata,
  m_axis_tvalid,
  m_axis_tready,
  m_axis_tdata
);

(* X_INTERFACE_PARAMETER = "XIL_INTERFACENAME CLKIF, FREQ_HZ 10000000, FREQ_TOLERANCE_HZ 0, PHASE 0.000, INSERT_VIP 0" *)
(* X_INTERFACE_INFO = "xilinx.com:signal:clock:1.0 CLKIF CLK" *)
input wire aclk;
(* X_INTERFACE_PARAMETER = "XIL_INTERFACENAME RSTIF, POLARITY ACTIVE_LOW, INSERT_VIP 0" *)
(* X_INTERFACE_INFO = "xilinx.com:signal:reset:1.0 RSTIF RST" *)
input wire aresetn;
(* X_INTERFACE_INFO = "xilinx.com:interface:axis:1.0 S_AXIS TVALID" *)
input wire s_axis_tvalid;
(* X_INTERFACE_INFO = "xilinx.com:interface:axis:1.0 S_AXIS TREADY" *)
output wire s_axis_tready;
(* X_INTERFACE_PARAMETER = "XIL_INTERFACENAME S_AXIS, TDATA_NUM_BYTES 32, TDEST_WIDTH 0, TID_WIDTH 0, TUSER_WIDTH 0, HAS_TREADY 1, HAS_TSTRB 0, HAS_TKEEP 0, HAS_TLAST 0, FREQ_HZ 100000000, PHASE 0.000, LAYERED_METADATA undef, INSERT_VIP 0" *)
(* X_INTERFACE_INFO = "xilinx.com:interface:axis:1.0 S_AXIS TDATA" *)
input wire [255 : 0] s_axis_tdata;
(* X_INTERFACE_INFO = "xilinx.com:interface:axis:1.0 M_AXIS TVALID" *)
output wire m_axis_tvalid;
(* X_INTERFACE_INFO = "xilinx.com:interface:axis:1.0 M_AXIS TREADY" *)
input wire m_axis_tready;
(* X_INTERFACE_PARAMETER = "XIL_INTERFACENAME M_AXIS, TDATA_NUM_BYTES 32, TDEST_WIDTH 0, TID_WIDTH 0, TUSER_WIDTH 0, HAS_TREADY 1, HAS_TSTRB 0, HAS_TKEEP 0, HAS_TLAST 0, FREQ_HZ 100000000, PHASE 0.000, LAYERED_METADATA undef, INSERT_VIP 0" *)
(* X_INTERFACE_INFO = "xilinx.com:interface:axis:1.0 M_AXIS TDATA" *)
output wire [255 : 0] m_axis_tdata;

  axis_register_slice_v1_1_22_axis_register_slice #(
    .C_FAMILY("kintexuplus"),
    .C_AXIS_TDATA_WIDTH(256),
    .C_AXIS_TID_WIDTH(1),
    .C_AXIS_TDEST_WIDTH(1),
    .C_AXIS_TUSER_WIDTH(1),
    .C_AXIS_SIGNAL_SET(32'B00000000000000000000000000000011),
    .C_REG_CONFIG(8),
    .C_NUM_SLR_CROSSINGS(0),
    .C_PIPELINES_MASTER(0),
    .C_PIPELINES_SLAVE(0),
    .C_PIPELINES_MIDDLE(0)
  ) inst (
    .aclk(aclk),
    .aclk2x(1'H0),
    .aresetn(aresetn),
    .aclken(1'H1),
    .s_axis_tvalid(s_axis_tvalid),
    .s_axis_tready(s_axis_tready),
    .s_axis_tdata(s_axis_tdata),
    .s_axis_tstrb(32'HFFFFFFFF),
    .s_axis_tkeep(32'HFFFFFFFF),
    .s_axis_tlast(1'H1),
    .s_axis_tid(1'H0),
    .s_axis_tdest(1'H0),
    .s_axis_tuser(1'H0),
    .m_axis_tvalid(m_axis_tvalid),
    .m_axis_tready(m_axis_tready),
    .m_axis_tdata(m_axis_tdata),
    .m_axis_tstrb(),
    .m_axis_tkeep(),
    .m_axis_tlast(),
    .m_axis_tid(),
    .m_axis_tdest(),
    .m_axis_tuser()
  );
endmodule
module game_timer # ( parameter width = 32 )
(
    input                    clk,
    input                    reset,
    input      [width - 1:0] value,
    input                    start,
    output reg               running
);

    reg [width - 1:0] counter;

    always @(posedge clk or posedge reset)
        if (reset)
        begin
            running <= 1'b0;
        end
        else if (start)
        begin
            counter <= value;
            running <= 1'b1;
        end
        else if (running)
        begin
           if (counter == { width, 1'b0 })
               running <= 1'b0;

            counter <= counter - 1;
        end

endmodule
module pmod_als_spi_receiver
(
    input             clock,
    input             reset,
    output            cs,
    output            sck,
    input             sdo,
    output reg [15:0] value
);

    reg [21:0] cnt;
    reg [15:0] shift;

    always @ (posedge clock or posedge reset)
    begin       
        if (reset)
            cnt <= 22'b100;
        else
            cnt <= cnt + 22'b1;
    end

    assign sck = ~ cnt [3];
    assign cs  =   cnt [8];

    wire sample_bit = ( cs == 1'b0 && cnt [3:0] == 4'b1111 );
    wire value_done = ( cnt [21:0] == 22'b0 );

    always @ (posedge clock or posedge reset)
    begin       
        if (reset)
        begin       
            shift <= 16'h0000;
            value <= 16'h0000;
        end
        else if (sample_bit)
        begin       
            shift <= (shift << 1) | sdo;
        end
        else if (value_done)
        begin       
            value <= shift;
        end
    end

endmodule
module lfsr_fibonacci #(
    parameter WIDTH  = 16,
              TAPS   = 16'b1000000001011,
              INVERT = 0
             )
(
    input                    clk,
    input                    reset,
    input                    enable,
    output reg [WIDTH - 1:0] out
);
    wire feedback = (^(out & TAPS)) ^ INVERT;
    
    always @(posedge clk or posedge reset)
        if (reset) 
            out <= { { WIDTH - 1 { 1'b0 } }, 1'b1 };
        else if (enable) 
            out <= { feedback, out [WIDTH - 1:1] };
            
endmodule
module game_mixer
(
    input            clk,
    input            reset,

    input            display_on,

    input            sprite_target_rgb_en,
    input      [2:0] sprite_target_rgb,

    input            sprite_torpedo_rgb_en,
    input      [2:0] sprite_torpedo_rgb,

    input            game_won,
    input            end_of_game_timer_running,
    input            random,

    output reg [2:0] rgb
);

    always @ (posedge clk or posedge reset)
        if (reset)
            rgb <= 3'b000;
        else if (! display_on)
            rgb <= 3'b000;
        else if (end_of_game_timer_running)
            rgb <= { 1'b1, ~ game_won, random };
        else if (sprite_torpedo_rgb_en)
            rgb <= sprite_torpedo_rgb;
        else if (sprite_target_rgb_en)
            rgb <= sprite_target_rgb;
        else
            rgb <= 3'b000;

endmodule
module game_strobe # ( parameter width = 32 )
(
    input      clk,
    input      reset,
    output reg strobe
);

    reg [width - 1:0] counter;

    always @(posedge clk or posedge reset)
        if (reset)
        begin
            counter <= { width, 1'b0 };
            strobe  <= 1'b0;
        end
        else
        begin
            counter <= counter + 1'b1;
            strobe  <= & counter;
        end

endmodule
module game_overlap
(
    input                       clk,
    input                       reset,

    input      [`X_WIDTH - 1:0] left_1,
    input      [`X_WIDTH - 1:0] right_1,
    input      [`Y_WIDTH - 1:0] top_1,
    input      [`Y_WIDTH - 1:0] bottom_1,

    input      [`X_WIDTH - 1:0] left_2,
    input      [`X_WIDTH - 1:0] right_2,
    input      [`Y_WIDTH - 1:0] top_2,
    input      [`Y_WIDTH - 1:0] bottom_2,

    output reg                  overlap
);

    always @ (posedge clk or posedge reset)
        if (reset)
            overlap <= 1'b0;
        else
            overlap <= ! (    right_1  < left_2
                           || right_2  < left_1
                           || bottom_1 < top_2
                           || bottom_2 < top_1  );

endmodule
module color_square
# (
    parameter HPOS_WIDTH          = 10,
              VPOS_WIDTH          = 10,

              // Display constants
              H_DISPLAY           = 640,  // Horizontal display width
              V_DISPLAY           = 480   // Vertical display height
)

(
    input                          clk,
    input                          reset,
    input                          display_on,
    input                    [3:0] key_sw,
    input       [HPOS_WIDTH - 1:0] hpos,
    input       [VPOS_WIDTH - 1:0] vpos,
    output reg  [2:0]              rgb
);

    always @ (posedge clk or posedge reset)
        if (reset)
            rgb <= 3'b000;
        else if (! display_on)
            rgb <= 3'b000;
            else if (key_sw[3])
                rgb <= 3'b100;
            else if (key_sw[2])
                rgb <= 3'b010;
            else if (key_sw[1])
                rgb <= 3'b001;
            else
                if  (key_sw[0]) 
                    if (vpos < V_DISPLAY/3)
                        if (hpos < H_DISPLAY/3)
                            rgb <= 3'b100;
                        else if (hpos < H_DISPLAY*2/3)
                            rgb <= 3'b010;
                        else
                            rgb <= 3'b001;
                            
                    else if (vpos < V_DISPLAY*2/3)
                        if (hpos < H_DISPLAY/3)
                            rgb <= 3'b110;
                        else if (hpos < H_DISPLAY*2/3)
                            rgb <= 3'b011;
                        else
                            rgb <= 3'b101;
                            
                    else
                        if (hpos < H_DISPLAY/3)
                            rgb <= 3'b000;
                        else if (hpos < H_DISPLAY*2/3)
                            rgb <= 3'b111;
                        else
                            rgb <= 3'b000;
            else 
                rgb <= 3'b000;

endmodule
module lfsr_galois 
# (
    parameter WIDTH  = 16,
              TAPS   = 16'b1000000001011,
              INVERT = 0
)
(
    input                    clk,
    input                    reset,
    input                    enable,
    output reg [WIDTH - 1:0] out
);
    wire feedback = out [WIDTH - 1] ^ INVERT;
    
    always @(posedge clk or posedge reset)
        if (reset) 
            out <= { { WIDTH - 1 { 1'b0 } }, 1'b1 };
        else if (enable) 
            out <= { out [WIDTH - 2:0], 1'b0 } ^ (feedback ? TAPS : 0);
endmodule
module pmod_mic3_spi_receiver
(
    input             clock,
    input             reset,
    output            cs,
    output            sck,
    input             sdo,
    output reg [15:0] value
);

    reg [ 6:0] cnt;
    reg [15:0] shift;

    always @ (posedge clock or posedge reset)
    begin
        if (reset)
            cnt <= 7'b100;
        else
            cnt <= cnt + 7'b1;
    end

    assign sck = ~ cnt [1];
    assign cs  =   cnt [6];

    wire sample_bit = ( cs == 1'b0 && cnt [1:0] == 2'b11 );
    wire value_done = ( cnt [6:0] == 7'b0 );

    always @ (posedge clock or posedge reset)
    begin
        if (reset)
        begin
            shift <= 16'h0000;
            value <= 16'h0000;
        end
        else if (sample_bit)
        begin
            shift <= (shift << 1) | sdo;
        end
        else if (value_done)
        begin
            value <= shift;
        end
    end

endmodule
module game_random
(
    input             clk,
    input             reset,
    output reg [15:0] random
);

    // Uses LFSR, Linear Feedback Shift Register

    always @(posedge clk or posedge reset)
        if (reset)
            random <= 16'b1111111111111;
        else
            random <=   { random [14:0], 1'b0 }
                      ^ ( random [15] ? 16'b1000000001011 : 16'b0);

endmodule
module game_sprite_control
#(
    parameter DX_WIDTH = 2,  // X speed width in bits
              DY_WIDTH = 2,  // Y speed width in bits

              strobe_to_update_xy_counter_width = 20
)

//----------------------------------------------------------------------------

(
    input                    clk,
    input                    reset,

    input                    sprite_write_xy,
    input                    sprite_write_dxy,

    input  [`X_WIDTH  - 1:0] sprite_write_x,
    input  [`Y_WIDTH  - 1:0] sprite_write_y,

    input  [ DX_WIDTH - 1:0] sprite_write_dx,
    input  [ DY_WIDTH - 1:0] sprite_write_dy,

    input                    sprite_enable_update,

    output [`X_WIDTH  - 1:0] sprite_x,
    output [`Y_WIDTH  - 1:0] sprite_y
);

    wire strobe_to_update_xy;

    game_strobe
    # (.width (strobe_to_update_xy_counter_width))
    strobe_generator
    (clk, reset, strobe_to_update_xy);

    reg [`X_WIDTH  - 1:0] x;
    reg [`Y_WIDTH  - 1:0] y;

    reg [ DX_WIDTH - 1:0] dx;
    reg [ DY_WIDTH - 1:0] dy;

    always @ (posedge clk or posedge reset)
        if (reset)
        begin
            x  <= 1'b0;
            y  <= 1'b0;
        end
        else if (sprite_write_xy)
        begin
            x  <= sprite_write_x;
            y  <= sprite_write_y;
        end
        else if (sprite_enable_update && strobe_to_update_xy)
        begin
            // Add with signed-extended dx and dy

            x <= x + { { `X_WIDTH - DX_WIDTH { dx [DX_WIDTH - 1] } }, dx };
            y <= y + { { `Y_WIDTH - DY_WIDTH { dy [DY_WIDTH - 1] } }, dy };
        end

    always @ (posedge clk or posedge reset)
        if (reset)
        begin
            dx <= 1'b0;
            dy <= 1'b0;
        end
        else if (sprite_write_dxy)
        begin
            dx <= sprite_write_dx;
            dy <= sprite_write_dy;
        end


    assign sprite_x = x;
    assign sprite_y = y;

endmodule
module top
# (
    parameter clk_mhz = 100,
              strobe_to_update_xy_counter_width = 20
)
(
    input        clk,

    input        btnC,
    input        btnU,
    input        btnL,
    input        btnR,
    input        btnD,

    output       Hsync,
    output       Vsync,
    output [3:0] vgaRed,
    output [3:0] vgaGreen,
    output [3:0] vgaBlue
);

    wire r,g,b;

    assign vgaRed   = { 4 { r } };
    assign vgaGreen = { 4 { g } };
    assign vgaBlue  = { 4 { b } };

    wire any_key = btnC | btnU | btnL | btnR;

    game_top
    # (
        .clk_mhz (clk_mhz),

        .strobe_to_update_xy_counter_width
        (strobe_to_update_xy_counter_width)
    )
    i_game_top
    (
        .clk              (   clk           ),
        .reset            ( ~ btnD          ),

        .launch_key       (   launch        ),
        .left_right_keys  ( { btnL , btnR } ),

        .hsync            (   Hsync         ),
        .vsync            (   Vsync         ),
        .rgb              ( { r, g, b }     )
    );

endmodule
module testbench;

    reg       clk;
    reg       reset_n;
    reg [3:0] key_sw;

    top
    # (
        .clk_mhz (1),
        .strobe_to_update_xy_counter_width (1)
    )
    i_top
    (
        .clk     ( clk     ),
        .reset_n ( reset_n ),
        .key_sw  ( key_sw  )
    );

    initial
    begin
        clk = 1'b0;

        forever
            # 10 clk = ! clk;
    end

    initial
    begin
        reset_n <= 1'bx;
        repeat (2) @ (posedge clk);
        reset_n <= 1'b0;
        repeat (2) @ (posedge clk);
        reset_n <= 1'b1;
    end

    initial
    begin
        #0
        $dumpvars;

        key_sw <= 4'b0;

        @ (posedge reset_n);

        repeat (1000)
        begin
            @ (posedge clk);

            key_sw <= $random;
        end

        `ifdef MODEL_TECH  // Mentor ModelSim and Questa
            $stop;
        `else
            $finish;
        `endif
    end

endmodule
module top
# (
    parameter clk_mhz = 50,
              strobe_to_update_xy_counter_width = 20
)
(
    input        clk,
    input        reset_n,
    
    input  [3:0] key_sw,
    output [3:0] led,

    output [7:0] abcdefgh,
    output [3:0] digit,

    output       buzzer,

    output       hsync,
    output       vsync,
    output [2:0] rgb
);

    assign led       = key_sw;
    assign abcdefgh  = { key_sw, key_sw };
    assign digit     = 4'b0;
    assign buzzer    = 1'b0;

    wire launch_key = key_sw != 4'b1111;  // Any key is pressed
    
    // Either of two leftmost keys is pressed
    wire left_key   = key_sw [3:2] != 2'b11;

    // Either of two rightmost keys is pressed
    wire right_key  = key_sw [1:0] != 2'b11;

    game_top
    # (
        .clk_mhz (clk_mhz),

        .strobe_to_update_xy_counter_width
        (strobe_to_update_xy_counter_width)
    )
    i_game_top
    (
        .clk              (   clk                   ),
        .reset            ( ~ reset_n               ),

        .launch_key       (   launch_key            ),
        .left_right_keys  ( { left_key, right_key } ),

        .hsync            (   hsync                 ),
        .vsync            (   vsync                 ),
        .rgb              (   rgb                   )
    );

endmodule
module top
# (
    parameter clk_mhz = 50
)
(
    input        clk,
    input        reset_n,
    
    input  [3:0] key_sw,
    output [3:0] led,
    
    output [7:0] abcdefgh,
    output [3:0] digit,

    output       buzzer,

    output       hsync,
    output       vsync,
    output [2:0] rgb
);

    assign led       = key_sw;
    assign abcdefgh  = 8'hff;
    assign digit     = 4'hf;
    assign buzzer    = 1'b0;

    wire       display_on;
    wire [9:0] hpos;
    wire [9:0] vpos;

    vga i_vga
    (
        .clk        ( clk           ),
        .reset      ( ! reset_n     ),
        .hsync      ( hsync         ),
        .vsync      ( vsync         ),
        .display_on ( display_on    ),
        .hpos       ( hpos          ),
        .vpos       ( vpos          )
    );

    wire [2:0] rgb_squares
        = hpos ==  0 || hpos == 639 || vpos ==  0 || vpos == 479 ? 3'b100 :
          hpos ==  5 || hpos == 634 || vpos ==  5 || vpos == 474 ? 3'b010 :
          hpos == 10 || hpos == 629 || vpos == 10 || vpos == 469 ? 3'b001 :
          hpos <  20 || hpos >  619 || vpos <  20 || vpos >= 459 ? 3'b000 :
          { 1'b0, vpos [4], hpos [3] ^ vpos [3] };
			 
    wire        lfsr_enable = ! hpos [9:8] & ! vpos [9:8];
    wire [15:0] lfsr_out;

//    select Fibonacci or Galois lfsr
//    uncomment one string and comment other

    lfsr_fibonacci #(16, 16'b1000000001011, 0) i_lfsr_fibonacci   
//    lfsr_galois #(16, 16'b1000000001011, 0) i_lfsr_galois
    (
        .clk    ( clk           ),
        .reset  ( ! reset_n     ),
        .enable ( lfsr_enable   ),
        .out    ( lfsr_out      )
    );

    wire star_on = & lfsr_out [15:9];
    assign rgb = lfsr_enable ? (star_on ? lfsr_out [2:0] : 3'b0) : rgb_squares;


endmodule
module top
# (
    parameter X_WIDTH = 10,
              Y_WIDTH = 10,
              clk_mhz = 50
)
(
    input        clk,
    input        reset_n,
    
    input  [3:0] key_sw,
    output [3:0] led,
    
    output [7:0] abcdefgh,
    output [3:0] digit,

    output       buzzer,

    output       hsync,
    output       vsync,
    output [2:0] rgb
);

    assign led       = key_sw;
    assign abcdefgh  = 8'hff;
    assign digit     = 4'hf;
    assign buzzer    = 1'b0;

    //------------------------------------------------------------------------

    wire                 display_on;
    wire [X_WIDTH - 1:0] pixel_x;
    wire [Y_WIDTH - 1:0] pixel_y;
 
    vga
    # (
        .HPOS_WIDTH ( X_WIDTH    ),
        .VPOS_WIDTH ( Y_WIDTH    ),
        
        .CLK_MHZ    ( clk_mhz    )
    )
    i_vga
    (
        .clk        ( clk        ), 
        .reset      ( ~reset_n   ),
        .hsync      ( hsync      ),
        .vsync      ( vsync      ),
        .display_on ( display_on ),
        .hpos       ( pixel_x    ),
        .vpos       ( pixel_y    )
    );

    //------------------------------------------------------------------------

    color_square 
    # (
       .HPOS_WIDTH  ( X_WIDTH    ),
       .VPOS_WIDTH  ( Y_WIDTH    )
    )
    i_color_square
    (
        .clk        (   clk        ),
        .reset      ( ~ reset_n    ),
        .display_on (   display_on ),
        .key_sw     ( ~ key_sw     ),
        .hpos       (   pixel_x    ),
        .vpos       (   pixel_y    ),
        .rgb        (   rgb        )
    );

endmodule
module testbench;

    reg       clk;
    reg [3:0] key;
    reg [3:0] sw;

    top
    # (
        .clk_mhz (1),
        .strobe_to_update_xy_counter_width (1)
    )
    i_top
    (
        .clk ( clk ),
        .key ( key ),
        .sw  ( sw  )
    );

    initial
    begin
        clk = 1'b0;

        forever
            # 10 clk = ! clk;
    end

    reg reset;
    
    always @*
        key [3] = ~ reset;

    initial
    begin
        reset <= 'bx;
        repeat (2) @ (posedge clk);
        reset <= 1;
        repeat (2) @ (posedge clk);
        reset <= 0;
    end

    initial
    begin
        #0
        $dumpvars;

        key [2:0] <= 'b0;
        sw        <= 'b0;

        @ (negedge reset);

        repeat (10000)
        begin
            @ (posedge clk);

            key [2:0] <= $random;
            sw        <= $random;
        end

        `ifdef MODEL_TECH  // Mentor ModelSim and Questa
            $stop;
        `else
            $finish;
        `endif
    end

endmodule
module testbench;

    reg       clk;
    reg [3:0] key;
    reg [3:0] sw;

    top
    # (
        .clk_mhz (1)
    )
    i_top
    (
        .clk ( clk ),
        .key ( key ),
        .sw  ( sw  )
    );

    initial
    begin
        clk = 1'b0;

        forever
            # 1 clk = ! clk;
    end

    reg reset;

    always @*
        key [3] = ~ reset;

    initial
    begin
        reset <= 'bx;
        repeat (2) @ (posedge clk);
        reset <= 1;
        repeat (2) @ (posedge clk);
        reset <= 0;
    end

    initial
    begin
        #0
        $dumpvars;

        #100000

        `ifdef MODEL_TECH  // Mentor ModelSim and Questa
            $stop;
        `else
            $finish;
        `endif
    end

endmodule
module lut
# (
    parameter y_width = 16
)
(
    input            [2:0] octave,
    input            [3:0] note,
    input            [7:0] x,       // Current sample
    output           [7:0] x_max,   // Last sample in a period
    output [y_width - 1:0] y
);

    wire   [y_width - 1:0] lut_y [11:0];
    wire             [7:0] lut_x;
    wire             [7:0] lut_x_max [11:0];

    assign lut_x = x << octave;
    assign x_max = (note < 8'd12) ? (lut_x_max [note] >> octave) : 8'b0;
    assign y = (note < 8'd12) ? (lut_y [note]) : 8'b0;

    lut_C  lut_C  ( .x(lut_x), .y(lut_y [0] ), .x_max(lut_x_max [0] ));
    lut_Cs lut_Cs ( .x(lut_x), .y(lut_y [1] ), .x_max(lut_x_max [1] ));
    lut_D  lut_D  ( .x(lut_x), .y(lut_y [2] ), .x_max(lut_x_max [2] ));
    lut_Ds lut_Ds ( .x(lut_x), .y(lut_y [3] ), .x_max(lut_x_max [3] ));
    lut_E  lut_E  ( .x(lut_x), .y(lut_y [4] ), .x_max(lut_x_max [4] ));
    lut_F  lut_F  ( .x(lut_x), .y(lut_y [5] ), .x_max(lut_x_max [5] ));
    lut_Fs lut_Fs ( .x(lut_x), .y(lut_y [6] ), .x_max(lut_x_max [6] ));
    lut_G  lut_G  ( .x(lut_x), .y(lut_y [7] ), .x_max(lut_x_max [7] ));
    lut_Gs lut_Gs ( .x(lut_x), .y(lut_y [8] ), .x_max(lut_x_max [8] ));
    lut_A  lut_A  ( .x(lut_x), .y(lut_y [9] ), .x_max(lut_x_max [9] ));
    lut_As lut_As ( .x(lut_x), .y(lut_y [10]), .x_max(lut_x_max [10]));
    lut_B  lut_B  ( .x(lut_x), .y(lut_y [11]), .x_max(lut_x_max [11]));

endmodule
module i2s
(
    input       clk,    // CLK - 50 MHz
    input       reset,
    input [2:0] octave,
    input [3:0] note,
    output      mclk,   // MCLK - 12.5 MHz
    output      bclk,   // BCLK - 3.125 MHz serial clock - for a 48 KHz Sample Rate
    output      lrclk,  // LRCLK - 32-bit L, 32-bit R
    output      sdata
);

    reg   [9:0] clk_div;
    reg  [31:0] shift;
    reg   [7:0] cnt;
    wire [15:0] value;
    wire  [7:0] cnt_max;
    wire [15:0] lut_y;

    always @ (posedge clk or posedge reset)
        if (reset)
            clk_div <= 0;
        else
            clk_div <= clk_div + 10'b1;

    assign mclk  = clk_div [1];
    assign bclk  = clk_div [3];
    assign lrclk = clk_div [9];

    always @ (posedge clk or posedge reset)
        if (reset)
            cnt <= 0;
        else if (clk_div [9:0] == 10'b11_1111_1111)
            cnt <= (cnt == cnt_max) ? 8'b0 : cnt + 8'b1;

    assign sdata = shift [31];

    always @ (posedge clk or posedge reset)
        if (reset)
            shift <= 0;
        else
        begin
            if (clk_div [8:0] == 9'b1_1111_1111)
                shift <= value << 16;
            else if (clk_div [3:0] == 4'b1111)
                shift <= shift << 1;
        end

    /*
     * TODO: Exercise 1:
     * Decrease sound level.
     */
    assign value = lut_y;

    lut lut
    (
        .octave ( octave  ),
        .note   ( note    ),
        .x      ( cnt     ),
        .x_max  ( cnt_max ),
        .y      ( lut_y   )
    );

endmodule
module i2s
(
    input       clk,    // CLK - 50 MHz
    input       reset,
    input [2:0] octave,
    input [3:0] note,
    output      mclk,   // MCLK - 12.5 MHz
    output      bclk,   // BCLK - 3.125 MHz serial clock - for a 48 KHz Sample Rate
    output      lrclk,  // LRCLK - 32-bit L, 32-bit R
    output      sdata
);

    reg   [9:0] clk_div;
    reg  [31:0] shift;
    reg   [7:0] cnt;
    wire [15:0] value;
    wire  [7:0] cnt_max;

    always @ (posedge clk or posedge reset)
        if (reset)
            clk_div <= 0;
        else
            clk_div <= clk_div + 10'b1;

    assign mclk  = clk_div [1];
    assign bclk  = clk_div [3];
    assign lrclk = clk_div [9];

    always @ (posedge clk or posedge reset)
        if (reset)
            cnt <= 0;
        else if (clk_div [9:0] == 10'b11_1111_1111)
            cnt <= (cnt == cnt_max) ? 8'b0 : cnt + 8'b1;

    assign sdata = shift [31];

    always @ (posedge clk or posedge reset)
        if (reset)
            shift <= 0;
        else
        begin
            if (clk_div [8:0] == 9'b1_1111_1111)
                shift <= value << 16;
            else if (clk_div [3:0] == 4'b1111)
                shift <= shift << 1;
        end

    lut lut
    (
        .octave ( octave  ),
        .note   ( note    ),
        .x      ( cnt     ),
        .x_max  ( cnt_max ),
        .y      ( value   )
    );

endmodule
module top
(
    input             clk,
    input      [ 3:0] key_sw,
    output     [ 3:0] led,

    output reg [ 7:0] abcdefgh,
    output     [ 3:0] digit,

    inout      [13:0] gpio,

    input             reset_n
);
    wire   reset  = ~ reset_n;

    wire  [2:0] octave = 3'b0;
    wire  [3:0] note   = key_sw [3:0];

    assign led  = note;

    wire mclk;
    wire bclk;
    wire lrclk;
    wire sdata;

    assign gpio [1]     = lrclk;
    assign gpio [3]     = sdata;
    assign gpio [5]     = mclk;
    assign gpio [7]     = bclk;

    i2s i2s
    (
        .clk    ( clk       ),
        .reset  ( reset     ),
        .octave ( octave    ),
        .note   ( note      ),
        .mclk   ( mclk      ),
        .bclk   ( bclk      ),
        .lrclk  ( lrclk     ),
        .sdata  ( sdata     )
    );

    assign digit = 8'b1111_1110;

    always @ (posedge clk or posedge reset)
        if (reset)
            abcdefgh <= 8'b11111111;
        else
            case (note)
            4'd0:    abcdefgh <= 8'b01100011;  // C   // abcdefgh
            4'd1:    abcdefgh <= 8'b01100010;  // C#
            4'd2:    abcdefgh <= 8'b10000101;  // D   //   --a--
            4'd3:    abcdefgh <= 8'b10000100;  // D#  //  |     |
            4'd4:    abcdefgh <= 8'b01100001;  // E   //  f     b
            4'd5:    abcdefgh <= 8'b01110001;  // F   //  |     |
            4'd6:    abcdefgh <= 8'b01110000;  // F#  //   --g--
            4'd7:    abcdefgh <= 8'b01000011;  // G   //  |     |
            4'd8:    abcdefgh <= 8'b01000010;  // G#  //  e     c
            4'd9:    abcdefgh <= 8'b00010001;  // A   //  |     |
            4'd10:   abcdefgh <= 8'b00010000;  // A#  //   --d--  h
            4'd11:   abcdefgh <= 8'b11000001;  // B
            default: abcdefgh <= 8'b11111111;
            endcase

endmodule
module top
# (
    parameter clk_mhz = 100,
              strobe_to_update_xy_counter_width = 20
)
(
    input        CLK100MHZ,
    input        CPU_RESETN,

    input        BTNC,
    input        BTNU,
    input        BTNL,
    input        BTNR,
    input        BTND,

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

    wire r,g,b;

    assign VGA_R = { 4 { r } };
    assign VGA_G = { 4 { g } };
    assign VGA_B = { 4 { b } };

    wire any_key = BTNC | BTNU | BTNL | BTNR | BTND;

    game_top
    # (
        .clk_mhz (clk_mhz),

        .strobe_to_update_xy_counter_width
        (strobe_to_update_xy_counter_width)
    )
    i_game_top
    (
        .clk              (   CLK100MHZ     ),
        .reset            ( ~ CPU_RESETN    ),

        .launch_key       (   any_key       ),
        .left_right_keys  ( { BTNL , BTNR } ),

        .hsync            (   VGA_HS        ),
        .vsync            (   VGA_VS        ),
        .rgb              ( { r, g, b }     )
    );

endmodule
module testbench;

    reg       clk;
    reg [3:0] key;
    reg [3:0] sw;

    top
    # (
        .clk_mhz (1),
        .strobe_to_update_xy_counter_width (1)
    )
    i_top
    (
        .clk ( clk ),
        .key ( key ),
        .sw  ( sw  )
    );

    initial
    begin
        clk = 1'b0;

        forever
            # 10 clk = ! clk;
    end

    reg reset;
    
    always @*
        key [3] = ~ reset;

    initial
    begin
        reset <= 'bx;
        repeat (2) @ (posedge clk);
        reset <= 1;
        repeat (2) @ (posedge clk);
        reset <= 0;
    end

    initial
    begin
        #0
        $dumpvars;

        key [2:0] <= 'b0;
        sw        <= 'b0;

        @ (negedge reset);

        repeat (1000)
        begin
            @ (posedge clk);

            key [2:0] <= $random;
            sw        <= $random;
        end

        `ifdef MODEL_TECH  // Mentor ModelSim and Questa
            $stop;
        `else
            $finish;
        `endif
    end

endmodule
module top
# (
    parameter clk_mhz = 50,
              strobe_to_update_xy_counter_width = 20
)
(
    input         clk,
    input  [ 3:0] key,
    input  [ 3:0] sw,
    output [ 7:0] led,

    output [ 7:0] abcdefgh,
    output [ 7:0] digit,

    output        vsync,
    output        hsync,
    output [ 2:0] rgb,

    output        buzzer,
    inout  [15:0] gpio
);

    wire   reset       = ~ key [3];

    assign led         =   { sw, key };
    assign abcdefgh    =   { sw, key };
    assign digit       =   { sw, key };
    assign buzzer      = ~ reset;

    wire   launch_key  = ~ key [1] | ~ key [0];
    wire   left_key    = ~ key [1];
    wire   right_key   = ~ key [0];

    game_top
    # (
        .clk_mhz (clk_mhz),

        .strobe_to_update_xy_counter_width
        (strobe_to_update_xy_counter_width)
    )
    i_game_top
    (
        .clk              (   clk                   ),
        .reset            (   reset                 ),

        .launch_key       (   launch_key            ),
        .left_right_keys  ( { left_key, right_key } ),

        .hsync            (   hsync                 ),
        .vsync            (   vsync                 ),
        .rgb              (   rgb                   )
    );

endmodule
module top
# (
    parameter clk_mhz = 50
)
(
    input         clk,
    input  [ 3:0] key,
    input  [ 3:0] sw,
    output [ 7:0] led,

    output [ 7:0] abcdefgh,
    output [ 7:0] digit,

    output        vsync,
    output        hsync,
    output [ 2:0] rgb,

    output        buzzer,
    inout  [15:0] gpio
);

    wire   reset       = ~ key [3];

    assign led         =   { sw, key };
    assign abcdefgh    =   { sw, key };
    assign digit       =   { sw, key };
    assign buzzer      = ~ reset;

    wire       display_on;
    wire [9:0] hpos;
    wire [9:0] vpos;

    vga i_vga
    (
        .clk        ( clk           ),
        .reset      ( reset         ),
        .hsync      ( hsync         ),
        .vsync      ( vsync         ),
        .display_on ( display_on    ),
        .hpos       ( hpos          ),
        .vpos       ( vpos          )
    );

    wire [2:0] rgb_squares
        = hpos ==  0 || hpos == 639 || vpos ==  0 || vpos == 479 ? 3'b100 :
          hpos ==  5 || hpos == 634 || vpos ==  5 || vpos == 474 ? 3'b010 :
          hpos == 10 || hpos == 629 || vpos == 10 || vpos == 469 ? 3'b001 :
          hpos <  20 || hpos >  619 || vpos <  20 || vpos >= 459 ? 3'b000 :
          { 1'b0, vpos [4], hpos [3] ^ vpos [3] };
			 
    wire        lfsr_enable = ! hpos [9:8] & ! vpos [9:8];
    wire [15:0] lfsr_out;

//    select Fibonacci or Galois lfsr
//    uncomment one string and comment other

    lfsr_fibonacci #(16, 16'b1000000001011, 0) i_lfsr_fibonacci   
//    lfsr_galois #(16, 16'b1000000001011, 0) i_lfsr_galois
    (
        .clk    ( clk           ),
        .reset  ( reset         ),
        .enable ( lfsr_enable   ),
        .out    ( lfsr_out      )
    );

    wire star_on = & lfsr_out [15:9];
    assign rgb = lfsr_enable ? (star_on ? lfsr_out [2:0] : 3'b0) : rgb_squares;


endmodule
module top
# (
    parameter clk_mhz = 50,
              strobe_to_update_xy_counter_width = 20
)
(
    input         clk,
    input  [ 3:0] key,
    input  [ 3:0] sw,
    output [ 7:0] led,

    output [ 7:0] abcdefgh,
    output [ 7:0] digit,

    output        vsync,
    output        hsync,
    output [ 2:0] rgb,

    output        buzzer,
    inout  [15:0] gpio
);

    wire   reset  = ~ key [3];
    assign buzzer = ~ reset;

    //------------------------------------------------------------------------

    wire [15:0] value;

    pmod_als_spi_receiver i_light_sensor
    (
        .clock ( clk        ),
        .reset ( reset      ),
        .cs    ( gpio  [14] ),
        .sck   ( gpio  [ 8] ),
        .sdo   ( gpio  [10] ),
        .value ( value      )
    );

    assign gpio [4] = 1'b1;  // VCC
    assign gpio [6] = 1'b0;  // GND

    //------------------------------------------------------------------------

    seven_segment_8_digits i_display
    (
        .clock    ( clk      ),
        .reset    ( reset    ),
        .number   ( value    ),

        .abcdefgh ( abcdefgh ),
        .digit    ( digit    )
    );

    //------------------------------------------------------------------------

    assign led = ~ value [15:6];

endmodule