1
0
mirror of https://github.com/Gehstock/Mist_FPGA.git synced 2026-02-17 13:06:59 +00:00
Files
Gehstock.Mist_FPGA/Arcade_MiST/Gremlin Blockade Hardware/rtl/pause.v
2022-03-10 22:06:25 +01:00

114 lines
4.0 KiB
Verilog

//============================================================================
// Generic pause handling for MiSTer cores.
//
// https://github.com/JimmyStones/Pause_MiSTer
//
// Copyright (c) 2021 Jim Gregory
//
// This program is free software; you can redistribute it and/or modify it
// under the terms of the GNU General Public License as published by the Free
// Software Foundation; either version 3 of the License, or (at your option)
// any later version.
//
// This program is distributed in the hope that it will be useful, but WITHOUT
// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
// more details.
//
// You should have received a copy of the GNU General Public License along
// with this program; if not, write to the Free Software Foundation, Inc.,
// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
//============================================================================
/*
Features:
- Pause can be triggered by user input, hiscore module or OSD opening (optionally controlled by setting in OSD)
- When paused the RGB outputs will be halved after 10 seconds to reduce burn-in (optionally controlled by setting in OSD)
- Reset signal will cancel user triggered pause
Version history:
0001 - 2021-03-15 - First marked release
0002 - 2021-08-28 - Add optional output of dim_video signal
0003 - 2021-09-22 - Convert dim_video to sequential logic to ease timing issues
0004 - 2021-10-07 - Convert pause_cpu to sequential logic to ease timing issues
============================================================================
*/
module pause #(
parameter RW=8, // Width of red channel
parameter GW=8, // Width of green channel
parameter BW=8, // Width of blue channel
parameter CLKSPD = 12 // Main clock speed in MHz
)
(
input clk_sys, // Core system clock (should match HPS module)
input reset, // CPU reset signal (active-high)
input user_button, // User pause button signal (active-high)
input pause_request, // Pause requested by other code (active-high)
input [1:0] options, // Pause options from OSD
// [0] = pause in OSD (active-high)
// [1] = dim video (active-high)
input OSD_STATUS, // OSD is open (active-high)
input [(RW-1):0] r, // Red channel
input [(GW-1):0] g, // Green channel
input [(BW-1):0] b, // Blue channel
output reg pause_cpu, // Pause signal to CPU (active-high)
`ifdef PAUSE_OUTPUT_DIM
output reg dim_video, // Dim video requested (active-high)
`endif
output [(RW+GW+BW-1):0] rgb_out // RGB output to arcade_video module
);
// Option constants
localparam pause_in_osd = 1'b0; // Index in options for Pause when in OSD
localparam dim_video_timer= 1'b1; // Index in options for Dim video after 10 seconds
localparam dim_timeout = (CLKSPD*10000000); // Time until video output dim (10 seconds @ CLKSPD Mhz)
reg pause_toggle = 1'b0; // User paused (active-high)
reg [31:0] pause_timer = 1'b0; // Time since pause
`ifndef PAUSE_OUTPUT_DIM
reg dim_video; // Dim video requested (active-high)
`endif
always @(posedge clk_sys) begin
// Track user pause button down
reg user_button_last;
user_button_last <= user_button;
if(!user_button_last & user_button) pause_toggle <= ~pause_toggle;
// Clear user pause on reset
if(pause_toggle && reset) pause_toggle <= 0;
if(reset)
begin
pause_cpu <= 1'b0;
end
else
begin
pause_cpu <= (pause_request | pause_toggle | (OSD_STATUS & options[pause_in_osd]));
end
if(pause_cpu && options[dim_video_timer])
begin
// Track pause duration for video dim
if(pause_timer<dim_timeout)
begin
pause_timer <= pause_timer + 1'b1;
dim_video <= 1'b0;
end
else
begin
dim_video <= 1'b1;
end
end
else
begin
dim_video <= 1'b0;
pause_timer <= 1'b0;
end
end
assign rgb_out = dim_video ? {r >> 1,g >> 1, b >> 1} : {r,g,b};
endmodule