redone fastforward and pause handling to fix sdram access and refresh bugs and increase fastforward speed, some fixes to simulation

This commit is contained in:
RobertPeip
2020-12-19 12:28:19 +01:00
committed by GitHub
parent 0a89fd5445
commit 65d6e59cc2
7 changed files with 172 additions and 88 deletions

View File

@@ -151,7 +151,7 @@ assign AUDIO_MIX = status[8:7];
// 0 1 2 3
// 01234567890123456789012345678901
// 0123456789ABCDEFGHIJKLMNOPQRSTUV
// XXXXXXXXXXXXXXXXXXXXX XXXXX
// XXXXXXXXXXXXXXXXXXXXX XXXX
`include "build_id.v"
localparam CONF_STR = {
@@ -180,8 +180,8 @@ localparam CONF_STR = {
"OB,Boot,Normal,Fast;",
"O6,Link Port,Disabled,Enabled;",
"-;",
"OPQ,FastForward Sound,Normal,Hack,Off;",
"OR,Pause when OSD is open,Off,On;",
"OP,FastForward Sound,On,Off;",
"OQ,Pause when OSD is open,Off,On;",
"-;",
"R0,Reset;",
"J1,A,B,Select,Start,FastForward;",
@@ -286,6 +286,8 @@ wire [15:0] sdram_di = cart_download ? ioctl_dout : 16'd0;
wire [23:0] sdram_addr = cart_download? ioctl_addr[24:1]: {2'b00, mbc_bank, cart_addr[12:1]};
wire sdram_oe = ~cart_download & cart_rd & ~cram_rd;
wire sdram_we = cart_download & dn_write;
wire sdram_refresh_force;
wire sdram_autorefresh = !fastforward;
assign SDRAM_CKE = 1;
@@ -312,6 +314,8 @@ sdram sdram (
.ds ( sdram_ds ),
.we ( sdram_we ),
.oe ( sdram_oe ),
.autorefresh ( sdram_autorefresh ),
.refresh ( sdram_refresh_force ),
.dout ( sdram_do )
);
@@ -583,7 +587,6 @@ gb gb (
.clk_sys ( clk_sys ),
.ce ( ce_cpu ), // the whole gameboy runs on 4mhnz
.ce_2x ( ce_cpu2x ), // ~8MHz in dualspeed mode (GBC)
.ce_sound ( ce_sound ), // ~8Mhz if not fastforward
.fast_boot ( status[11] ),
@@ -631,8 +634,8 @@ gb gb (
.gg_available(gg_available)
);
assign AUDIO_L = (joystick_0[8] && status[26]) ? 16'd0 : GB_AUDIO_L;
assign AUDIO_R = (joystick_0[8] && status[26]) ? 16'd0 : GB_AUDIO_R;
assign AUDIO_L = (joystick_0[8] && status[25]) ? 16'd0 : GB_AUDIO_L;
assign AUDIO_R = (joystick_0[8] && status[25]) ? 16'd0 : GB_AUDIO_R;
// the lcd to vga converter
wire [7:0] video_r, video_g, video_b;
@@ -765,22 +768,28 @@ video_mixer #(.LINE_LENGTH(200), .GAMMA(1)) video_mixer
//////////////////////////////// CE ////////////////////////////////////
wire ce_cpu, ce_cpu2x, ce_sound, ce_soundhack;
wire ce_cpu, ce_cpu2x;
wire cart_act = cart_wr | cart_rd;
wire fastforward = joystick_0[8] && !ioctl_download && !OSD_STATUS;
reg paused;
always_ff @(posedge clk_sys) begin
paused <= status[26] && OSD_STATUS && !ioctl_download && !reset;
end
speedcontrol speedcontrol
(
.clk_sys (clk_sys),
.pause (status[27] && OSD_STATUS && !ioctl_download),
.speedup (joystick_0[8] && !ioctl_download && !OSD_STATUS),
.speed (speed),
.pause (paused),
.speedup (fastforward),
.cart_act (cart_act),
.ce (ce_cpu),
.ce_2x (ce_cpu2x),
.ce_2xNormal (ce_soundhack)
.refresh (sdram_refresh_force)
);
assign ce_sound = status[25] ? ce_soundhack : ce_cpu2x;
///////////////////////////// GBC BIOS /////////////////////////////////
wire [7:0] bios_do;

View File

@@ -25,7 +25,6 @@ module gb (
input clk_sys,
input ce,
input ce_2x,
input ce_sound,
input fast_boot,
input [7:0] joystick,
@@ -268,7 +267,7 @@ wire audio_wr = !cpu_wr_n && sel_audio;
gbc_snd audio (
.clk ( clk_sys ),
.ce ( ce_sound ),
.ce ( ce_2x ),
.reset ( reset_r ),
.is_gbc ( isGBC ),

View File

@@ -50,7 +50,9 @@ module sdram
input [23:0] addr, // 24 bit word address
input [1:0] ds, // upper/lower data strobe
input oe, // cpu/chipset requests read
input we // cpu/chipset requests write
input we, // cpu/chipset requests write
input autorefresh,// autorefresh when no read or write required
input refresh // force refresh when core is paused or fastforward
);
localparam RASCAS_DELAY = 3'd2; // tRCD=20ns -> 3 cycles@128MHz
@@ -122,11 +124,15 @@ reg [2:0] stage;
always @(posedge clk) begin
reg [12:0] addr_r;
reg old_sync;
reg old_oe;
if(|stage) stage <= stage + 1'd1;
old_sync <= sync;
if(~old_sync & sync) stage <= 1;
old_oe <= oe;
if(~old_sync && sync && autorefresh) stage <= 1; // normal operation with read/write and refresh
if(refresh && stage == STATE_FIRST) stage <= 1; // forced refresh when paused or fastforward
if(~old_oe && oe && ~autorefresh) stage <= 1; // react on request only with fastforward
sd_cmd <= CMD_INHIBIT; // default: idle
sd_data <= 16'hZZZZ;
@@ -163,7 +169,7 @@ always @(posedge clk) begin
din_r <= din;
addr_r <= { we ? ~ds : 2'b00, 2'b10, addr[22], addr[7:0] }; // auto precharge
end
else begin
else if (autorefresh || refresh) begin
sd_cmd <= CMD_AUTO_REFRESH;
mode <= 0;
end

View File

@@ -5,69 +5,138 @@ use IEEE.numeric_std.all;
entity speedcontrol is
port
(
clk_sys : in std_logic;
pause : in std_logic;
speedup : in std_logic;
cart_act : in std_logic;
ce : out std_logic := '0';
ce_2x : out std_logic := '0';
ceNormal : out std_logic := '0';
ce_2xNormal : out std_logic := '0'
clk_sys : in std_logic;
speed : in std_logic;
pause : in std_logic;
speedup : in std_logic;
cart_act : in std_logic;
ce : out std_logic := '0';
ce_2x : buffer std_logic := '0';
refresh : out std_logic := '0'
);
end entity;
architecture arch of speedcontrol is
signal clkdiv : unsigned(2 downto 0) := (others => '0');
signal nextdiv : unsigned(2 downto 0) := (others => '0');
signal clkdivNormal : unsigned(2 downto 0) := (others => '0');
signal cart_act_1 : std_logic := '0';
signal clkdiv : unsigned(2 downto 0) := (others => '0');
signal cart_act_1 : std_logic := '0';
signal unpause_cnt : integer range 0 to 15 := 0;
signal fastforward_cnt : integer range 0 to 15 := 0;
signal refreshcnt : integer range 0 to 127 := 0;
signal sdram_busy : integer range 0 to 1 := 0;
type tstate is
(
NORMAL,
PAUSED,
FASTFORWARDSTART,
FASTFORWARD,
FASTFORWARDEND,
RAMACCESS
);
signal state : tstate := NORMAL;
begin
process(clk_sys)
begin
if falling_edge(clk_sys) then
if (pause = '1') then
ce <= '0';
ce_2x <= '0';
refresh <= '0';
ce <= '0';
ce_2x <= '0';
ceNormal <= '0';
ce_2xNormal <= '0';
else
clkdiv <= clkdiv + 1;
clkdivNormal <= clkdivNormal + 1;
-- generation for speed depending on speedup
cart_act_1 <= cart_act;
if (clkdiv = "000") then ce <= '1'; else ce <= '0'; end if;
if ((nextdiv = "111" and clkdiv(1 downto 0) = "00") or nextdiv = "001") then ce_2x <= '1'; else ce_2x <= '0'; end if;
if (clkdiv = nextdiv and (clkdiv = "111" or cart_act = '0')) then
clkdiv <= "000";
if (speedup = '1') then
nextdiv <= "001";
else
nextdiv <= "111";
end if;
end if;
if (cart_act = '1' and cart_act_1 = '0') then
nextdiv <= "111";
end if;
-- generation for non speed up base, used e.g. for sound hack
if (clkdivNormal = "000") then ceNormal <= '1'; else ceNormal <= '0'; end if;
if (clkdivNormal(1 downto 0) = "00") then ce_2xNormal <= '1'; else ce_2xNormal <= '0'; end if;
cart_act_1 <= cart_act;
if (refreshcnt > 0) then
refreshcnt <= refreshcnt - 1;
end if;
case (state) is
when NORMAL =>
if (pause = '1' and clkdiv = "111") then
if (cart_act = '0') then
state <= PAUSED;
unpause_cnt <= 0;
end if;
elsif (speedup = '1' and pause = '0') then
state <= FASTFORWARDSTART;
fastforward_cnt <= 0;
else
clkdiv <= clkdiv + 1;
if (clkdiv = "000") then
ce <= '1';
end if;
if (clkdiv(1 downto 0) = "00") then
ce_2x <= '1';
end if;
end if;
when PAUSED =>
if (unpause_cnt = 0) then
refresh <= '1';
end if;
if (pause = '0') then
if (unpause_cnt = 15) then
state <= NORMAL;
else
unpause_cnt <= unpause_cnt + 1;
end if;
end if;
when FASTFORWARDSTART =>
if (fastforward_cnt = 15) then
state <= FASTFORWARD;
else
fastforward_cnt <= fastforward_cnt + 1;
end if;
when FASTFORWARD =>
if (pause = '1' or speedup = '0') then
state <= FASTFORWARDEND;
fastforward_cnt <= 0;
end if;
if (cart_act = '1' and cart_act_1 = '0') then
state <= RAMACCESS;
sdram_busy <= 1;
elsif (cart_act = '0' and refreshcnt = 0) then
refreshcnt <= 127;
refresh <= '1';
state <= RAMACCESS;
sdram_busy <= 1;
else
clkdiv(0) <= not clkdiv(0);
if (clkdiv(0) = '0') then
ce <= '1';
end if;
ce_2x <= '1';
end if;
when FASTFORWARDEND =>
if (fastforward_cnt = 15) then
state <= NORMAL;
else
fastforward_cnt <= fastforward_cnt + 1;
end if;
when RAMACCESS =>
if (sdram_busy > 0) then
sdram_busy <= sdram_busy - 1;
else
state <= FASTFORWARD;
end if;
end case;
end if;
end process;
end architecture;

View File

@@ -65,7 +65,6 @@ begin
wait until rising_edge(clk);
if (cart_rd = '1') then
cart_do <= x"FF";
wait until rising_edge(clk);
wait until rising_edge(clk);
wait until rising_edge(clk);

View File

@@ -24,6 +24,7 @@ architecture arch of etb is
signal reset : std_logic := '1';
signal clksys : std_logic := '1';
signal clkram : std_logic := '1';
signal clkdiv : unsigned(2 downto 0) := (others => '0');
signal nextdiv : unsigned(2 downto 0) := (others => '0');
@@ -31,6 +32,8 @@ architecture arch of etb is
signal ce : std_logic := '1';
signal ce_2x : std_logic := '1';
signal speed : std_logic;
signal command_in : std_logic;
signal command_out : std_logic;
signal command_out_filter : std_logic;
@@ -62,6 +65,8 @@ architecture arch of etb is
signal pixel_out_we : std_logic := '0';
signal is_CGB : std_logic := '1';
-- settings
signal GB_on : std_logic_vector(Reg_GB_on.upper downto Reg_GB_on.lower) := (others => '0');
@@ -69,7 +74,8 @@ architecture arch of etb is
begin
reset <= not GB_on(0);
clksys <= not clksys after 15 ns;
clksys <= not clksys after 14 ns;
clkram <= not clkram after 7 ns;
clk100 <= not clk100 after 5 ns;
@@ -82,6 +88,7 @@ begin
port map
(
clk_sys => clksys,
speed => speed,
pause => '0',
speedup => '1',
cart_act => cart_act,
@@ -89,24 +96,15 @@ begin
ce_2x => ce_2x
);
isdram_model : entity tb.sdram_model
port map
(
clk => clksys,
clk => clkram,
cart_addr => cart_addr,
cart_rd => cart_rd,
cart_do => cart_do
);
--itetris : entity gameboy.tetris
--port map
--(
-- clk => clksys,
-- address => cart_addr(14 downto 0),
-- data => cart_do
--);
igb : entity gameboy.gb
port map
(
@@ -115,12 +113,11 @@ begin
clk_sys => clksys,
ce => ce,
ce_2x => ce_2x,
--ce_sound => ce_2x,
fast_boot => '1',
joystick => x"00",
isGBC => '0',
isGBC_game => '0',
isGBC => is_CGB,
isGBC_game => is_CGB,
-- cartridge interface
-- can adress up to 1MB ROM
@@ -148,7 +145,7 @@ begin
joy_p54 => open,
joy_din => "0000",
speed => open, --GBC
speed => speed, --GBC
gg_reset => reset,
gg_en => '0',
@@ -167,7 +164,7 @@ begin
port map
(
clk => clksys,
address => gbc_bios_addr(7 downto 0),
address => gbc_bios_addr,
data => gbc_bios_do
);
@@ -195,13 +192,17 @@ begin
end if;
end if;
case (lcd_data(1 downto 0)) is
when "00" => pixel_out_data <= "11111" & "11111" & "11111";
when "01" => pixel_out_data <= "10000" & "10000" & "10000";
when "10" => pixel_out_data <= "01000" & "01000" & "01000";
when "11" => pixel_out_data <= "00000" & "00000" & "00000";
when others => pixel_out_data <= "00000" & "00000" & "11111";
end case;
if (is_CGB = '0') then
case (lcd_data(1 downto 0)) is
when "00" => pixel_out_data <= "11111" & "11111" & "11111";
when "01" => pixel_out_data <= "10000" & "10000" & "10000";
when "10" => pixel_out_data <= "01000" & "01000" & "01000";
when "11" => pixel_out_data <= "00000" & "00000" & "00000";
when others => pixel_out_data <= "00000" & "00000" & "11111";
end case;
else
pixel_out_data <= lcd_data;
end if;
end if;
end process;

View File

@@ -3,6 +3,7 @@ vcom -93 -quiet -work sim/tb ^
src/tb/globals.vhd
vcom -93 -quiet -work sim/mem ^
src/mem/SyncRamDualByteEnable.vhd ^
src/mem/SyncFifo.vhd
vcom -quiet -work sim/rs232 ^