From 39459cdc4006b7af87402f43dfd63524ef0bb9f3 Mon Sep 17 00:00:00 2001 From: leozqi Date: Sun, 23 Feb 2025 10:43:25 -0500 Subject: [PATCH 01/10] Add gamepad-pmod --- src/gamepad_pmod.v | 309 +++++++++++++++++++++++++++++++++++++++++++++ src/project.v | 52 ++++++-- 2 files changed, 347 insertions(+), 14 deletions(-) create mode 100644 src/gamepad_pmod.v diff --git a/src/gamepad_pmod.v b/src/gamepad_pmod.v new file mode 100644 index 0000000..42b5270 --- /dev/null +++ b/src/gamepad_pmod.v @@ -0,0 +1,309 @@ +// Vendored from: https://github.com/psychogenic/gamepad-pmod/blob/main/verilog/gamepad_pmod.v + +/* + * Copyright (c) 2025 Pat Deegan + * https://psychogenic.com + * SPDX-License-Identifier: Apache-2.0 + * + * Interfacing code for the Gamepad Pmod from Psycogenic Technologies, + * designed for Tiny Tapeout. + * + * There are two high-level modules that most users will be interested in: + * - gamepad_pmod_single: for a single controller; + * - gamepad_pmod_dual: for two controllers. + * + * There are also two lower-level modules that you can use if you want to + * handle the interfacing yourself: + * - gamepad_pmod_driver: interfaces with the Pmod and provides the raw data; + * - gamepad_pmod_decoder: decodes the raw data into button states. + * + * The docs, schematics, PCB files, and firmware code for the Gamepad Pmod + * are available at https://github.com/psychogenic/gamepad-pmod. + */ + +/** + * gamepad_pmod_driver -- Serial interface for the Gamepad Pmod. + * + * This module reads raw data from the Gamepad Pmod *serially* + * and stores it in a shift register. When the latch signal is received, + * the data is transferred into `data_reg` for further processing. + * + * Functionality: + * - Synchronizes the `pmod_data`, `pmod_clk`, and `pmod_latch` signals + * to the system clock domain. + * - Captures serial data on each falling edge of `pmod_clk`. + * - Transfers the shifted data into `data_reg` when `pmod_latch` goes low. + * + * Parameters: + * - `BIT_WIDTH`: Defines the width of `data_reg` (default: 24 bits). + * + * Inputs: + * - `rst_n`: Active-low reset. + * - `clk`: System clock. + * - `pmod_data`: Serial data input from the Pmod. + * - `pmod_clk`: Serial clock from the Pmod. + * - `pmod_latch`: Latch signal indicating the end of data transmission. + * + * Outputs: + * - `data_reg`: Captured parallel data after shifting is complete. + */ +module gamepad_pmod_driver #( + parameter BIT_WIDTH = 24 +) ( + input wire rst_n, + input wire clk, + input wire pmod_data, + input wire pmod_clk, + input wire pmod_latch, + output reg [BIT_WIDTH-1:0] data_reg +); + + reg pmod_clk_prev; + reg pmod_latch_prev; + reg [BIT_WIDTH-1:0] shift_reg; + + // Sync Pmod signals to the clk domain: + reg [1:0] pmod_data_sync; + reg [1:0] pmod_clk_sync; + reg [1:0] pmod_latch_sync; + + always @(posedge clk) begin + if (~rst_n) begin + pmod_data_sync <= 2'b0; + pmod_clk_sync <= 2'b0; + pmod_latch_sync <= 2'b0; + end else begin + pmod_data_sync <= {pmod_data_sync[0], pmod_data}; + pmod_clk_sync <= {pmod_clk_sync[0], pmod_clk}; + pmod_latch_sync <= {pmod_latch_sync[0], pmod_latch}; + end + end + + always @(posedge clk) begin + if (~rst_n) begin + /* set data and shift registers to all ones + * such that it is detected as "not present" yet. + */ + data_reg <= {BIT_WIDTH{1'b1}}; + shift_reg <= {BIT_WIDTH{1'b1}}; + pmod_clk_prev <= 1'b0; + pmod_latch_prev <= 1'b0; + end + begin + pmod_clk_prev <= pmod_clk_sync[1]; + pmod_latch_prev <= pmod_latch_sync[1]; + + // Capture data on rising edge of pmod_latch: + if (pmod_latch_sync[1] & ~pmod_latch_prev) begin + data_reg <= shift_reg; + end + + // Sample data on rising edge of pmod_clk: + if (pmod_clk_sync[1] & ~pmod_clk_prev) begin + shift_reg <= {shift_reg[BIT_WIDTH-2:0], pmod_data_sync[1]}; + end + end + end + +endmodule + + +/** + * gamepad_pmod_decoder -- Decodes raw data from the Gamepad Pmod. + * + * This module takes a 12-bit parallel data register (`data_reg`) + * and decodes it into individual button states. It also determines + * whether a controller is connected. + * + * Functionality: + * - If `data_reg` contains all `1's` (`0xFFF`), it indicates that no controller is connected. + * - Otherwise, it extracts individual button states from `data_reg`. + * + * Inputs: + * - `data_reg [11:0]`: Captured button state data from the gamepad. + * + * Outputs: + * - `b, y, select, start, up, down, left, right, a, x, l, r`: Individual button states (`1` = pressed, `0` = released). + * - `is_present`: Indicates whether a controller is connected (`1` = connected, `0` = not connected). + */ +module gamepad_pmod_decoder ( + input wire [11:0] data_reg, + output wire b, + output wire y, + output wire select, + output wire start, + output wire up, + output wire down, + output wire left, + output wire right, + output wire a, + output wire x, + output wire l, + output wire r, + output wire is_present +); + + // When the controller is not connected, the data register will be all 1's + wire reg_empty = (data_reg == 12'hfff); + assign is_present = reg_empty ? 0 : 1'b1; + assign {b, y, select, start, up, down, left, right, a, x, l, r} = reg_empty ? 0 : data_reg; + +endmodule + + +/** + * gamepad_pmod_single -- Main interface for a single Gamepad Pmod controller. + * + * This module provides button states for a **single controller**, reducing + * resource usage (fewer flip-flops) compared to a dual-controller version. + * + * Inputs: + * - `pmod_data`, `pmod_clk`, and `pmod_latch` are the signals from the PMOD interface. + * + * Outputs: + * - Each button's state is provided as a single-bit wire (e.g., `start`, `up`, etc.). + * - `is_present` indicates whether the controller is connected (`1` = connected, `0` = not detected). + */ +module gamepad_pmod_single ( + input wire rst_n, + input wire clk, + input wire pmod_data, + input wire pmod_clk, + input wire pmod_latch, + + output wire b, + output wire y, + output wire select, + output wire start, + output wire up, + output wire down, + output wire left, + output wire right, + output wire a, + output wire x, + output wire l, + output wire r, + output wire is_present +); + + wire [11:0] gamepad_pmod_data; + + gamepad_pmod_driver #( + .BIT_WIDTH(12) + ) driver ( + .rst_n(rst_n), + .clk(clk), + .pmod_data(pmod_data), + .pmod_clk(pmod_clk), + .pmod_latch(pmod_latch), + .data_reg(gamepad_pmod_data) + ); + + gamepad_pmod_decoder decoder ( + .data_reg(gamepad_pmod_data), + .b(b), + .y(y), + .select(select), + .start(start), + .up(up), + .down(down), + .left(left), + .right(right), + .a(a), + .x(x), + .l(l), + .r(r), + .is_present(is_present) + ); + +endmodule + + +/** + * gamepad_pmod_dual -- Main interface for the Pmod gamepad. + * This module provides button states for two controllers using + * 2-bit vectors for each button (e.g., start[1:0], up[1:0], etc.). + * + * Each button state is represented as a 2-bit vector: + * - Index 0 corresponds to the first controller (e.g., up[0], y[0], etc.). + * - Index 1 corresponds to the second controller (e.g., up[1], y[1], etc.). + * + * The `is_present` signal indicates whether a controller is connected: + * - `is_present[0] == 1` when the first controller is connected. + * - `is_present[1] == 1` when the second controller is connected. + * + * Inputs: + * - `pmod_data`, `pmod_clk`, and `pmod_latch` are the 3 wires coming from the Pmod interface. + * + * Outputs: + * - Button state vectors for each controller. + * - Presence detection via `is_present`. + */ +module gamepad_pmod_dual ( + input wire rst_n, + input wire clk, + input wire pmod_data, + input wire pmod_clk, + input wire pmod_latch, + + output wire [1:0] b, + output wire [1:0] y, + output wire [1:0] select, + output wire [1:0] start, + output wire [1:0] up, + output wire [1:0] down, + output wire [1:0] left, + output wire [1:0] right, + output wire [1:0] a, + output wire [1:0] x, + output wire [1:0] l, + output wire [1:0] r, + output wire [1:0] is_present +); + + wire [23:0] gamepad_pmod_data; + + gamepad_pmod_driver driver ( + .rst_n(rst_n), + .clk(clk), + .pmod_data(pmod_data), + .pmod_clk(pmod_clk), + .pmod_latch(pmod_latch), + .data_reg(gamepad_pmod_data) + ); + + gamepad_pmod_decoder decoder1 ( + .data_reg(gamepad_pmod_data[11:0]), + .b(b[0]), + .y(y[0]), + .select(select[0]), + .start(start[0]), + .up(up[0]), + .down(down[0]), + .left(left[0]), + .right(right[0]), + .a(a[0]), + .x(x[0]), + .l(l[0]), + .r(r[0]), + .is_present(is_present[0]) + ); + + gamepad_pmod_decoder decoder2 ( + .data_reg(gamepad_pmod_data[23:12]), + .b(b[1]), + .y(y[1]), + .select(select[1]), + .start(start[1]), + .up(up[1]), + .down(down[1]), + .left(left[1]), + .right(right[1]), + .a(a[1]), + .x(x[1]), + .l(l[1]), + .r(r[1]), + .is_present(is_present[1]) + ); + +endmodule diff --git a/src/project.v b/src/project.v index 5620973..d5802f1 100644 --- a/src/project.v +++ b/src/project.v @@ -6,7 +6,7 @@ `default_nettype none module tt_um_uwasic_dinogame ( - input wire [7:0] ui_in, // Dedicated inputs + input wire [7:0] ui_in, // Dedicated inputs: 4-6 are gamepad output wire [7:0] uo_out, // Dedicated outputs input wire [7:0] uio_in, // IOs: Input path output wire [7:0] uio_out, // IOs: Output path @@ -30,20 +30,44 @@ module tt_um_uwasic_dinogame ( wire button_up; wire button_down; - button_debounce button_up_debounce ( + // Gamepad Pmod support + wire gamepad_pmod_latch = ui_in[4]; + wire gamepad_pmod_clk = ui_in[5]; + wire gamepad_pmod_data = ui_in[6]; + wire gamepad_is_present; // HIGH when gamepad is connected + wire gamepad_left; + wire gamepad_right; + wire gamepad_up; + wire gamepad_down; + wire gamepad_start; // Can leverage start, select from SNES + wire gamepad_select; + + // Synchronizes pmod_data, pmod_clk, pmod_latch signals to system clock + // domain. + gamepad_pmod_single gamepad_pmod ( + // Inputs: .clk(clk), .rst_n(rst_n), - .countdown_en(debounce_countdown_en), - .button_in(ui_in[0]), - .button_out(button_up) - ); + .pmod_latch(gamepad_pmod_latch), + .pmod_clk(gamepad_pmod_clk), + .pmod_data(gamepad_pmod_data), + + // Outputs: + .is_present(gamepad_is_present), + .left(gamepad_left), + .right(gamepad_right), + .up(gamepad_up), + .down(gamepad_down), + .start(gamepad_start), + .select(gamepad_select), - button_debounce button_down_debounce ( - .clk(clk), - .rst_n(rst_n), - .countdown_en(debounce_countdown_en), - .button_in(ui_in[1]), - .button_out(button_down) + // unused outputs + .a(), + .b(), + .x(), + .y(), + .l(), + .r() ); // GAME STATE SIGNALS @@ -65,8 +89,8 @@ module tt_um_uwasic_dinogame ( .clk(clk), .rst_n(rst_n), .game_tick(game_tick_20hz), - .button_up(button_up), - .button_down(button_down), + .button_up(gamepad_up), + .button_down(gamepad_down), .crash(crash), .player_position(player_position), .game_start_pulse(game_start_pulse), From e99562fd472f45763992ed75e199c3789dfeba73 Mon Sep 17 00:00:00 2001 From: leozqi Date: Sun, 23 Feb 2025 10:43:25 -0500 Subject: [PATCH 02/10] Add gamepad-pmod --- src/dino_game_top.v | 61 +++++---- src/gamepad_pmod.v | 309 ++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 348 insertions(+), 22 deletions(-) create mode 100644 src/gamepad_pmod.v diff --git a/src/dino_game_top.v b/src/dino_game_top.v index 0a32789..32ed954 100644 --- a/src/dino_game_top.v +++ b/src/dino_game_top.v @@ -19,24 +19,41 @@ module tt_um_uwasic_dinogame #(parameter CONV = 2) ( wire game_tick_60hz; wire [1:0] game_tick_20hz; // two consecutive pulses generated ([0] and then [1]), enabling pipelining - wire debounce_countdown_en; // pulse on rising edge of 5th vpos bit - wire button_up; - wire button_down; - - button_debounce button_up_debounce ( + // Gamepad Pmod support + wire gamepad_pmod_latch = ui_in[4]; + wire gamepad_pmod_clk = ui_in[5]; + wire gamepad_pmod_data = ui_in[6]; + wire gamepad_is_present; // HIGH when gamepad is connected + wire gamepad_up; + wire gamepad_down; + wire gamepad_start; // Can leverage start, select from SNES + + // Synchronizes pmod_data, pmod_clk, pmod_latch signals to system clock + // domain. + gamepad_pmod_single gamepad_pmod ( + // Inputs: .clk(clk), .rst_n(rst_n), - .countdown_en(debounce_countdown_en), - .button_in(ui_in[0]), - .button_out(button_up) - ); - - button_debounce button_down_debounce ( - .clk(clk), - .rst_n(rst_n), - .countdown_en(debounce_countdown_en), - .button_in(ui_in[1]), - .button_out(button_down) + .pmod_latch(gamepad_pmod_latch), + .pmod_clk(gamepad_pmod_clk), + .pmod_data(gamepad_pmod_data), + + // Outputs: + .is_present(gamepad_is_present), + .up(gamepad_up), + .down(gamepad_down), + .start(gamepad_start), + + // unused outputs + .left(), + .right(), + .select(), + .a(), + .b(), + .x(), + .y(), + .l(), + .r() ); // GAME STATE SIGNALS @@ -64,9 +81,9 @@ module tt_um_uwasic_dinogame #(parameter CONV = 2) ( .clk(clk), .rst_n(rst_n), .game_tick(game_tick_20hz), - .button_start(button_up), - .button_up(button_up), - .button_down(button_down), + .button_start(gamepad_start), + .button_up(gamepad_up), + .button_down(gamepad_down), .crash(crash), .player_position(player_position), .game_start_pulse(game_start_pulse), @@ -114,7 +131,7 @@ module tt_um_uwasic_dinogame #(parameter CONV = 2) ( obs_rom obs_rom_inst_2 (.clk(clk), .rst(~rst_n), .i_rom_counter(obs_rom_counter_2), .i_obs_type(obstacle2_type), .o_sprite_color(obs_color_2)); wire [15:0] score; - + score_render #(.CONV(CONV), .OFFSET(120)) score_inst_1 ( .clk(clk), .rst(~rst_n), @@ -123,7 +140,7 @@ module tt_um_uwasic_dinogame #(parameter CONV = 2) ( .i_vpos(vpos), .o_score_color(score_color_1) ); - + score_render #(.CONV(CONV), .OFFSET(110)) score_inst_2 ( .clk(clk), .rst(~rst_n), @@ -229,6 +246,6 @@ module tt_um_uwasic_dinogame #(parameter CONV = 2) ( assign uio_oe = 8'b10000000; // List all unused inputs to prevent warnings - wire _unused = &{ena, ui_in[7:2], uio_in, 1'b0}; + wire _unused = &{ena, ui_in[7], ui_in[3:0], uio_in, 1'b0}; endmodule diff --git a/src/gamepad_pmod.v b/src/gamepad_pmod.v new file mode 100644 index 0000000..42b5270 --- /dev/null +++ b/src/gamepad_pmod.v @@ -0,0 +1,309 @@ +// Vendored from: https://github.com/psychogenic/gamepad-pmod/blob/main/verilog/gamepad_pmod.v + +/* + * Copyright (c) 2025 Pat Deegan + * https://psychogenic.com + * SPDX-License-Identifier: Apache-2.0 + * + * Interfacing code for the Gamepad Pmod from Psycogenic Technologies, + * designed for Tiny Tapeout. + * + * There are two high-level modules that most users will be interested in: + * - gamepad_pmod_single: for a single controller; + * - gamepad_pmod_dual: for two controllers. + * + * There are also two lower-level modules that you can use if you want to + * handle the interfacing yourself: + * - gamepad_pmod_driver: interfaces with the Pmod and provides the raw data; + * - gamepad_pmod_decoder: decodes the raw data into button states. + * + * The docs, schematics, PCB files, and firmware code for the Gamepad Pmod + * are available at https://github.com/psychogenic/gamepad-pmod. + */ + +/** + * gamepad_pmod_driver -- Serial interface for the Gamepad Pmod. + * + * This module reads raw data from the Gamepad Pmod *serially* + * and stores it in a shift register. When the latch signal is received, + * the data is transferred into `data_reg` for further processing. + * + * Functionality: + * - Synchronizes the `pmod_data`, `pmod_clk`, and `pmod_latch` signals + * to the system clock domain. + * - Captures serial data on each falling edge of `pmod_clk`. + * - Transfers the shifted data into `data_reg` when `pmod_latch` goes low. + * + * Parameters: + * - `BIT_WIDTH`: Defines the width of `data_reg` (default: 24 bits). + * + * Inputs: + * - `rst_n`: Active-low reset. + * - `clk`: System clock. + * - `pmod_data`: Serial data input from the Pmod. + * - `pmod_clk`: Serial clock from the Pmod. + * - `pmod_latch`: Latch signal indicating the end of data transmission. + * + * Outputs: + * - `data_reg`: Captured parallel data after shifting is complete. + */ +module gamepad_pmod_driver #( + parameter BIT_WIDTH = 24 +) ( + input wire rst_n, + input wire clk, + input wire pmod_data, + input wire pmod_clk, + input wire pmod_latch, + output reg [BIT_WIDTH-1:0] data_reg +); + + reg pmod_clk_prev; + reg pmod_latch_prev; + reg [BIT_WIDTH-1:0] shift_reg; + + // Sync Pmod signals to the clk domain: + reg [1:0] pmod_data_sync; + reg [1:0] pmod_clk_sync; + reg [1:0] pmod_latch_sync; + + always @(posedge clk) begin + if (~rst_n) begin + pmod_data_sync <= 2'b0; + pmod_clk_sync <= 2'b0; + pmod_latch_sync <= 2'b0; + end else begin + pmod_data_sync <= {pmod_data_sync[0], pmod_data}; + pmod_clk_sync <= {pmod_clk_sync[0], pmod_clk}; + pmod_latch_sync <= {pmod_latch_sync[0], pmod_latch}; + end + end + + always @(posedge clk) begin + if (~rst_n) begin + /* set data and shift registers to all ones + * such that it is detected as "not present" yet. + */ + data_reg <= {BIT_WIDTH{1'b1}}; + shift_reg <= {BIT_WIDTH{1'b1}}; + pmod_clk_prev <= 1'b0; + pmod_latch_prev <= 1'b0; + end + begin + pmod_clk_prev <= pmod_clk_sync[1]; + pmod_latch_prev <= pmod_latch_sync[1]; + + // Capture data on rising edge of pmod_latch: + if (pmod_latch_sync[1] & ~pmod_latch_prev) begin + data_reg <= shift_reg; + end + + // Sample data on rising edge of pmod_clk: + if (pmod_clk_sync[1] & ~pmod_clk_prev) begin + shift_reg <= {shift_reg[BIT_WIDTH-2:0], pmod_data_sync[1]}; + end + end + end + +endmodule + + +/** + * gamepad_pmod_decoder -- Decodes raw data from the Gamepad Pmod. + * + * This module takes a 12-bit parallel data register (`data_reg`) + * and decodes it into individual button states. It also determines + * whether a controller is connected. + * + * Functionality: + * - If `data_reg` contains all `1's` (`0xFFF`), it indicates that no controller is connected. + * - Otherwise, it extracts individual button states from `data_reg`. + * + * Inputs: + * - `data_reg [11:0]`: Captured button state data from the gamepad. + * + * Outputs: + * - `b, y, select, start, up, down, left, right, a, x, l, r`: Individual button states (`1` = pressed, `0` = released). + * - `is_present`: Indicates whether a controller is connected (`1` = connected, `0` = not connected). + */ +module gamepad_pmod_decoder ( + input wire [11:0] data_reg, + output wire b, + output wire y, + output wire select, + output wire start, + output wire up, + output wire down, + output wire left, + output wire right, + output wire a, + output wire x, + output wire l, + output wire r, + output wire is_present +); + + // When the controller is not connected, the data register will be all 1's + wire reg_empty = (data_reg == 12'hfff); + assign is_present = reg_empty ? 0 : 1'b1; + assign {b, y, select, start, up, down, left, right, a, x, l, r} = reg_empty ? 0 : data_reg; + +endmodule + + +/** + * gamepad_pmod_single -- Main interface for a single Gamepad Pmod controller. + * + * This module provides button states for a **single controller**, reducing + * resource usage (fewer flip-flops) compared to a dual-controller version. + * + * Inputs: + * - `pmod_data`, `pmod_clk`, and `pmod_latch` are the signals from the PMOD interface. + * + * Outputs: + * - Each button's state is provided as a single-bit wire (e.g., `start`, `up`, etc.). + * - `is_present` indicates whether the controller is connected (`1` = connected, `0` = not detected). + */ +module gamepad_pmod_single ( + input wire rst_n, + input wire clk, + input wire pmod_data, + input wire pmod_clk, + input wire pmod_latch, + + output wire b, + output wire y, + output wire select, + output wire start, + output wire up, + output wire down, + output wire left, + output wire right, + output wire a, + output wire x, + output wire l, + output wire r, + output wire is_present +); + + wire [11:0] gamepad_pmod_data; + + gamepad_pmod_driver #( + .BIT_WIDTH(12) + ) driver ( + .rst_n(rst_n), + .clk(clk), + .pmod_data(pmod_data), + .pmod_clk(pmod_clk), + .pmod_latch(pmod_latch), + .data_reg(gamepad_pmod_data) + ); + + gamepad_pmod_decoder decoder ( + .data_reg(gamepad_pmod_data), + .b(b), + .y(y), + .select(select), + .start(start), + .up(up), + .down(down), + .left(left), + .right(right), + .a(a), + .x(x), + .l(l), + .r(r), + .is_present(is_present) + ); + +endmodule + + +/** + * gamepad_pmod_dual -- Main interface for the Pmod gamepad. + * This module provides button states for two controllers using + * 2-bit vectors for each button (e.g., start[1:0], up[1:0], etc.). + * + * Each button state is represented as a 2-bit vector: + * - Index 0 corresponds to the first controller (e.g., up[0], y[0], etc.). + * - Index 1 corresponds to the second controller (e.g., up[1], y[1], etc.). + * + * The `is_present` signal indicates whether a controller is connected: + * - `is_present[0] == 1` when the first controller is connected. + * - `is_present[1] == 1` when the second controller is connected. + * + * Inputs: + * - `pmod_data`, `pmod_clk`, and `pmod_latch` are the 3 wires coming from the Pmod interface. + * + * Outputs: + * - Button state vectors for each controller. + * - Presence detection via `is_present`. + */ +module gamepad_pmod_dual ( + input wire rst_n, + input wire clk, + input wire pmod_data, + input wire pmod_clk, + input wire pmod_latch, + + output wire [1:0] b, + output wire [1:0] y, + output wire [1:0] select, + output wire [1:0] start, + output wire [1:0] up, + output wire [1:0] down, + output wire [1:0] left, + output wire [1:0] right, + output wire [1:0] a, + output wire [1:0] x, + output wire [1:0] l, + output wire [1:0] r, + output wire [1:0] is_present +); + + wire [23:0] gamepad_pmod_data; + + gamepad_pmod_driver driver ( + .rst_n(rst_n), + .clk(clk), + .pmod_data(pmod_data), + .pmod_clk(pmod_clk), + .pmod_latch(pmod_latch), + .data_reg(gamepad_pmod_data) + ); + + gamepad_pmod_decoder decoder1 ( + .data_reg(gamepad_pmod_data[11:0]), + .b(b[0]), + .y(y[0]), + .select(select[0]), + .start(start[0]), + .up(up[0]), + .down(down[0]), + .left(left[0]), + .right(right[0]), + .a(a[0]), + .x(x[0]), + .l(l[0]), + .r(r[0]), + .is_present(is_present[0]) + ); + + gamepad_pmod_decoder decoder2 ( + .data_reg(gamepad_pmod_data[23:12]), + .b(b[1]), + .y(y[1]), + .select(select[1]), + .start(start[1]), + .up(up[1]), + .down(down[1]), + .left(left[1]), + .right(right[1]), + .a(a[1]), + .x(x[1]), + .l(l[1]), + .r(r[1]), + .is_present(is_present[1]) + ); + +endmodule From d9e0761d30d7caf2a610b63dc12126bb84cd56b1 Mon Sep 17 00:00:00 2001 From: Penguronik Date: Sun, 2 Mar 2025 16:00:39 -0500 Subject: [PATCH 03/10] delete project.v --- src/project.v | 0 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100644 src/project.v diff --git a/src/project.v b/src/project.v deleted file mode 100644 index e69de29..0000000 From 12748c5f267910eaf5456e904501740689e94897 Mon Sep 17 00:00:00 2001 From: Penguronik Date: Sun, 2 Mar 2025 16:03:59 -0500 Subject: [PATCH 04/10] remove vpos[5] for debounce --- src/dino_game_top.v | 1 - src/graphics_top.v | 4 ---- 2 files changed, 5 deletions(-) diff --git a/src/dino_game_top.v b/src/dino_game_top.v index 32ed954..fa10146 100644 --- a/src/dino_game_top.v +++ b/src/dino_game_top.v @@ -217,7 +217,6 @@ module tt_um_uwasic_dinogame #(parameter CONV = 2) ( .o_game_tick_60hz(game_tick_60hz), .o_game_tick_20hz(game_tick_20hz[0]), .o_game_tick_20hz_r(game_tick_20hz[1]), - .o_vpos_5_r(debounce_countdown_en), .o_collision(crash) ); diff --git a/src/graphics_top.v b/src/graphics_top.v index f797b8a..34a92f9 100644 --- a/src/graphics_top.v +++ b/src/graphics_top.v @@ -18,14 +18,12 @@ module graphics_top #(parameter CONV = 0)( output reg o_game_tick_60hz, output reg o_game_tick_20hz, output reg o_game_tick_20hz_r, - output reg o_vpos_5_r, output reg o_collision ); // ============== HVSYNC ============= // TODO can change hpos to increment by 2 to reduce bits reg [9:0] hpos; reg [9:0] vpos; - reg vpos_5_r; reg display_on; // TODO can remove this pipeline stage if we don't need it reg hsync; @@ -57,7 +55,6 @@ module graphics_top #(parameter CONV = 0)( end else begin // vsync_r <= vsync; // hsync_r <= hsync; - vpos_5_r <= vpos[5]; // display_on_r <= display_on; end end @@ -118,7 +115,6 @@ module graphics_top #(parameter CONV = 0)( o_game_tick_60hz = (vpos == 0) && (hpos == 0); o_game_tick_20hz = frame_counter == 1 && o_game_tick_60hz; o_game_tick_20hz_r = game_tick_r; - o_vpos_5_r = (vpos[5] == 1) && (vpos_5_r == 0); o_collision = i_color_obstacle && i_color_player; end From 6d8853009d59a44bff43fea9ff625b14063524cf Mon Sep 17 00:00:00 2001 From: Penguronik Date: Sun, 2 Mar 2025 16:04:57 -0500 Subject: [PATCH 05/10] actually remove vpos[5] --- src/graphics_top.v | 1 - 1 file changed, 1 deletion(-) diff --git a/src/graphics_top.v b/src/graphics_top.v index 34a92f9..05b7c4f 100644 --- a/src/graphics_top.v +++ b/src/graphics_top.v @@ -50,7 +50,6 @@ module graphics_top #(parameter CONV = 0)( if (rst) begin // hsync_r <= 1'b0; // vsync_r <= 1'b0; - vpos_5_r <= 1'b0; // display_on_r <= 1'b0; end else begin // vsync_r <= vsync; From 688fba4d46f75ae17a72564d8a8de9549add6acf Mon Sep 17 00:00:00 2001 From: Penguronik Date: Sun, 2 Mar 2025 16:09:50 -0500 Subject: [PATCH 06/10] set unused gamepad --- src/dino_game_top.v | 11 ----------- src/gamepad_pmod.v | 2 ++ 2 files changed, 2 insertions(+), 11 deletions(-) diff --git a/src/dino_game_top.v b/src/dino_game_top.v index fa10146..e2ba49e 100644 --- a/src/dino_game_top.v +++ b/src/dino_game_top.v @@ -43,17 +43,6 @@ module tt_um_uwasic_dinogame #(parameter CONV = 2) ( .up(gamepad_up), .down(gamepad_down), .start(gamepad_start), - - // unused outputs - .left(), - .right(), - .select(), - .a(), - .b(), - .x(), - .y(), - .l(), - .r() ); // GAME STATE SIGNALS diff --git a/src/gamepad_pmod.v b/src/gamepad_pmod.v index 42b5270..16ef8aa 100644 --- a/src/gamepad_pmod.v +++ b/src/gamepad_pmod.v @@ -143,6 +143,8 @@ module gamepad_pmod_decoder ( output wire is_present ); + wire _unused = &{b, y, select, left, right, a, x, l, r}; + // When the controller is not connected, the data register will be all 1's wire reg_empty = (data_reg == 12'hfff); assign is_present = reg_empty ? 0 : 1'b1; From 210a3481a169cf0f6c50804de6e3e4699dbe6ca4 Mon Sep 17 00:00:00 2001 From: Penguronik Date: Sun, 2 Mar 2025 16:15:29 -0500 Subject: [PATCH 07/10] missing comma --- src/dino_game_top.v | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/dino_game_top.v b/src/dino_game_top.v index e2ba49e..274512d 100644 --- a/src/dino_game_top.v +++ b/src/dino_game_top.v @@ -42,7 +42,7 @@ module tt_um_uwasic_dinogame #(parameter CONV = 2) ( .is_present(gamepad_is_present), .up(gamepad_up), .down(gamepad_down), - .start(gamepad_start), + .start(gamepad_start) ); // GAME STATE SIGNALS From f8e228e5b2597334ca690b1ac524ee77d8bb80be Mon Sep 17 00:00:00 2001 From: Penguronik Date: Sun, 2 Mar 2025 16:20:39 -0500 Subject: [PATCH 08/10] added to info.yaml --- info.yaml | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/info.yaml b/info.yaml index 5aa6301..a88946e 100644 --- a/info.yaml +++ b/info.yaml @@ -17,12 +17,16 @@ project: # Source files must be in ./src and you must list each source file separately, one per line. # Don't forget to also update `PROJECT_SOURCES` in test/Makefile. source_files: + - "audio_interface.v" - "debounce.v" - "dino_game_top.v" - "dino_render.v" - "dino_rom.v" + - "gamepad_pmod.v" + - "game_over_sound_player.v" - "graphics_top.v" - "hvsync_generator.v" + - "jump_sound_player.v" - "lfsr.v" - "obs_render.v" - "obs_rom.v" @@ -31,9 +35,6 @@ project: - "player_physics.v" - "score.v" - "score_render.v" - - "audio_interface.v" - - "jump_sound_player.v" - - "game_over_sound_player.v" # The pinout of your project. Leave unused pins blank. DO NOT delete or add any pins. From 7848307015e39657ca6f3450bba30e4694726b59 Mon Sep 17 00:00:00 2001 From: Roni Kant <35043400+Penguronik@users.noreply.github.com> Date: Mon, 10 Mar 2025 00:47:14 -0400 Subject: [PATCH 09/10] fix unused errors --- src/dino_game_top.v | 22 ++++++++++++++++++++-- 1 file changed, 20 insertions(+), 2 deletions(-) diff --git a/src/dino_game_top.v b/src/dino_game_top.v index 6b10a24..e16ea56 100644 --- a/src/dino_game_top.v +++ b/src/dino_game_top.v @@ -27,6 +27,15 @@ module tt_um_uwasic_dinogame #(parameter CONV = 2) ( wire gamepad_up; wire gamepad_down; wire gamepad_start; // Can leverage start, select from SNES + wire gamepad_b; + wire gamepad_y; + wire gamepad_select; + wire gamepad_left; + wire gamepad_right; + wire gamepad_a; + wire gamepad_x; + wire gamepad_l; + wire gamepad_r; // Synchronizes pmod_data, pmod_clk, pmod_latch signals to system clock // domain. @@ -42,7 +51,16 @@ module tt_um_uwasic_dinogame #(parameter CONV = 2) ( .is_present(gamepad_is_present), .up(gamepad_up), .down(gamepad_down), - .start(gamepad_start) + .start(gamepad_start), + .b(gamepad_b), + .y(gamepad_y), + .select(gamepad_select), + .left(gamepad_left), + .right(gamepad_right), + .a(gamepad_a), + .x(gamepad_x), + .l(gamepad_l), + .r(gamepad_r) ); // GAME STATE SIGNALS @@ -240,6 +258,6 @@ module tt_um_uwasic_dinogame #(parameter CONV = 2) ( assign uio_oe = 8'b10000000; // List all unused inputs to prevent warnings - wire _unused = &{ena, ui_in[7], ui_in[3:0], uio_in, 1'b0}; + wire _unused = &{ena, ui_in[7], ui_in[3:0], uio_in, gamepad_start, gamepad_b, gamepad_y, gamepad_select, gamepad_left, gamepad_right, gamepad_a, gamepad_x, gamepad_l, gamepad_r, 1'b0}; endmodule From 653226b8a15d4a849ecf64dd8abb5f6db0f0f0cc Mon Sep 17 00:00:00 2001 From: Roni Kant <35043400+Penguronik@users.noreply.github.com> Date: Mon, 10 Mar 2025 00:50:11 -0400 Subject: [PATCH 10/10] Update dino_game_top.v --- src/dino_game_top.v | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/dino_game_top.v b/src/dino_game_top.v index e16ea56..649e7fa 100644 --- a/src/dino_game_top.v +++ b/src/dino_game_top.v @@ -258,6 +258,6 @@ module tt_um_uwasic_dinogame #(parameter CONV = 2) ( assign uio_oe = 8'b10000000; // List all unused inputs to prevent warnings - wire _unused = &{ena, ui_in[7], ui_in[3:0], uio_in, gamepad_start, gamepad_b, gamepad_y, gamepad_select, gamepad_left, gamepad_right, gamepad_a, gamepad_x, gamepad_l, gamepad_r, 1'b0}; + wire _unused = &{ena, ui_in[7], ui_in[3:0], uio_in, gamepad_start, gamepad_b, gamepad_y, gamepad_select, gamepad_left, gamepad_right, gamepad_a, gamepad_x, gamepad_l, gamepad_r, gamepad_is_present, 1'b0}; endmodule