1
0
mirror of https://github.com/Gehstock/Mist_FPGA.git synced 2026-01-20 09:44:38 +00:00

Dotron: update CTC, common inputs

This commit is contained in:
Gyorgy Szombathelyi 2020-01-06 21:58:11 +01:00
parent ea33c889ed
commit c963036524
7 changed files with 111 additions and 478 deletions

View File

@ -41,7 +41,7 @@
# ========================
set_global_assignment -name PROJECT_OUTPUT_DIRECTORY output_files
set_global_assignment -name NUM_PARALLEL_PROCESSORS ALL
set_global_assignment -name LAST_QUARTUS_VERSION 13.1
set_global_assignment -name LAST_QUARTUS_VERSION "13.1 SP4.26"
set_global_assignment -name PRE_FLOW_SCRIPT_FILE "quartus_sh:rtl/build_id.tcl"
# Pin & Location Assignments
@ -214,7 +214,7 @@ set_global_assignment -name PARTITION_NETLIST_TYPE SOURCE -section_id Top
set_global_assignment -name PARTITION_FITTER_PRESERVATION_LEVEL PLACEMENT_AND_ROUTING -section_id Top
set_global_assignment -name PARTITION_COLOR 16764057 -section_id Top
set_global_assignment -name ENABLE_SIGNALTAP OFF
set_global_assignment -name USE_SIGNALTAP_FILE output_files/reset.stp
set_global_assignment -name USE_SIGNALTAP_FILE output_files/dot.stp
set_global_assignment -name CYCLONEII_OPTIMIZATION_TECHNIQUE SPEED
set_global_assignment -name SYNTH_TIMING_DRIVEN_SYNTHESIS ON
set_global_assignment -name OPTIMIZE_HOLD_TIMING "ALL PATHS"
@ -225,8 +225,6 @@ set_global_assignment -name SMART_RECOMPILE ON
set_global_assignment -name ALLOW_SYNCH_CTRL_USAGE ON
set_global_assignment -name SYSTEMVERILOG_FILE rtl/DiscsOfTron_MiST.sv
set_global_assignment -name VHDL_FILE rtl/DiscsOfTron.vhd
set_global_assignment -name VHDL_FILE rtl/ctc_counter.vhd
set_global_assignment -name VHDL_FILE rtl/ctc_controler.vhd
set_global_assignment -name VHDL_FILE rtl/tapper_sound_board.vhd
set_global_assignment -name VHDL_FILE rtl/YM2149_linmix_sep.vhd
set_global_assignment -name VHDL_FILE rtl/gen_ram.vhd
@ -236,6 +234,7 @@ set_global_assignment -name VHDL_FILE rtl/rom/dotron_bg_bits_2.vhd
set_global_assignment -name VHDL_FILE rtl/rom/midssio_82s123.vhd
set_global_assignment -name SYSTEMVERILOG_FILE rtl/sdram.sv
set_global_assignment -name VHDL_FILE rtl/pll_mist.vhd
set_global_assignment -name QIP_FILE ../../../common/IO/Z80CTC/z80ctc.qip
set_global_assignment -name QIP_FILE ../../../common/CPU/T80/T80.qip
set_global_assignment -name QIP_FILE ../../../common/mist/mist.qip
set_instance_assignment -name PARTITION_HIERARCHY root_partition -to | -section_id Top

View File

@ -1,20 +1,20 @@
Discs of Tron MiST port
- DOTRON.ROM is needed on the SD Card.
- DOTRON.ROM is needed on the SD Card
Aim Left : F
Aim Right : G
Level Up : F3
Level Down : F4
Forward : Up
Backward : Down
Left : Left
Right : Right
Coin : ESC
1 Player : F1
2 Player : F2
Block : Alt
Fire : Space
Joy/keyboard MAME key
Forward : Up
Backward : Down
Left : Left
Right : Right
Coin : ESC 5,6
1 Player : F1 1
2 Player : F2 2
Fire : Button A Space
Block : Button B Alt
Aim Left : Button X,L Z,C
Aim Right : Button Y,R X,V
Aim Up : Button C Ctrl
Aim Down : Button D LShift

View File

@ -209,31 +209,15 @@ architecture struct of DiscsOfTron is
signal cpu_ioreq_n : std_logic;
signal cpu_irq_n : std_logic;
signal cpu_m1_n : std_logic;
signal ctc_controler_we : std_logic;
signal ctc_controler_do : std_logic_vector(7 downto 0);
signal ctc_int_ack : std_logic;
signal cpu_int_ack_n : std_logic;
signal ctc_counter_0_we : std_logic;
-- signal ctc_counter_0_trg : std_logic;
signal ctc_counter_0_do : std_logic_vector(7 downto 0);
signal ctc_counter_0_int : std_logic;
signal ctc_ce : std_logic;
signal ctc_do : std_logic_vector(7 downto 0);
signal ctc_counter_1_we : std_logic;
-- signal ctc_counter_1_trg : std_logic;
signal ctc_counter_1_do : std_logic_vector(7 downto 0);
signal ctc_counter_1_int : std_logic;
signal ctc_counter_2_we : std_logic;
-- signal ctc_counter_2_trg : std_logic;
signal ctc_counter_2_do : std_logic_vector(7 downto 0);
signal ctc_counter_2_int : std_logic;
signal ctc_counter_3_we : std_logic;
signal ctc_counter_1_trg : std_logic;
signal ctc_counter_2_trg : std_logic;
signal ctc_counter_3_trg : std_logic;
signal ctc_counter_3_do : std_logic_vector(7 downto 0);
signal ctc_counter_3_int : std_logic;
-- signal cpu_rom_do : std_logic_vector( 7 downto 0);
signal wram_we : std_logic;
@ -431,8 +415,8 @@ begin
vcnt >= 1 and vcnt < 241 then video_blankn <= '1';end if;
if hs_cnt = 0 then hsync0 <= '0';
elsif hs_cnt = 47 then hsync0 <= '1';
if hs_cnt = 0 then hsync0 <= '0'; video_hs <= '0';
elsif hs_cnt = 47 then hsync0 <= '1'; video_hs <= '1';
end if;
if hs_cnt = 0 then hsync1 <= '0';
@ -491,7 +475,7 @@ end process;
-- "111" for test & tilt & unused
input_0 <= not service & "11" & not fire & not start2 & not start1 & not coin2 & not coin1;
input_1 <= '1' & angle;
input_2 <= '1' & not deflect & not level_down & not level_up & not back & not forward & not right & not left;
input_2 <= '1' & not deflect & not level_up & not level_down & not back & not forward & not right & not left;
input_3 <= "1111111" & coin_meters;
input_4 <= x"FF";
@ -503,24 +487,17 @@ cpu_di <= cpu_rom_do when cpu_mreq_n = '0' and cpu_addr(15 downto 12) < X"E
wram_do when cpu_mreq_n = '0' and (cpu_addr and X"F800") = x"E000" else -- E000-E7FF
sp_ram_cache_do_r when cpu_mreq_n = '0' and (cpu_addr and x"FC00") = x"E800" else -- sprite ram E800-E9FF + mirroring 0200
bg_ram_do_r when cpu_mreq_n = '0' and (cpu_addr and x"F800") = x"F000" else -- video ram F000-F7FF
ctc_controler_do when cpu_ioreq_n = '0' and cpu_m1_n = '0' else -- ctc ctrl (interrupt vector)
ctc_do when cpu_int_ack_n = '0' or ctc_ce = '1' else -- ctc (interrupt vector or counter data)
ssio_do when cpu_ioreq_n = '0' and cpu_addr(7 downto 5) = "000" else -- 0x00-0x1F
ctc_counter_3_do when cpu_ioreq_n = '0' and cpu_addr(7 downto 0) = X"F3" else
ctc_counter_2_do when cpu_ioreq_n = '0' and cpu_addr(7 downto 0) = X"F2" else
ctc_counter_1_do when cpu_ioreq_n = '0' and cpu_addr(7 downto 0) = X"F1" else
ctc_counter_0_do when cpu_ioreq_n = '0' and cpu_addr(7 downto 0) = X"F0" else
X"FF";
------------------------------------------------------------------------
-- Misc registers : ctc write enable / interrupt acknowledge
------------------------------------------------------------------------
ctc_counter_3_trg <= '1' when (vcnt = 246 and tv15Khz_mode = '1') or (vcnt = 493 and tv15Khz_mode = '0')else '0';
ctc_counter_3_we <= '1' when cpu_wr_n = '0' and cpu_ioreq_n = '0' and cpu_addr(7 downto 0) = X"F3" else '0';
ctc_counter_2_we <= '1' when cpu_wr_n = '0' and cpu_ioreq_n = '0' and cpu_addr(7 downto 0) = X"F2" else '0';
ctc_counter_1_we <= '1' when cpu_wr_n = '0' and cpu_ioreq_n = '0' and cpu_addr(7 downto 0) = X"F1" else '0';
ctc_counter_0_we <= '1' when cpu_wr_n = '0' and cpu_ioreq_n = '0' and cpu_addr(7 downto 0) = X"F0" else '0';
ctc_controler_we <= '1' when cpu_wr_n = '0' and cpu_ioreq_n = '0' and cpu_addr(7 downto 0) = X"F0" else '0'; -- only channel 0 receive int vector
ctc_int_ack <= '1' when cpu_ioreq_n = '0' and cpu_m1_n = '0' else '0';
cpu_int_ack_n <= cpu_ioreq_n or cpu_m1_n;
ctc_ce <= '1' when cpu_ioreq_n = '0' and cpu_addr(7 downto 4) = x"F" else '0';
ctc_counter_2_trg <= '1' when (vcnt >= 240 and vcnt <= 262 and tv15Khz_mode = '1') or (vcnt >= 480 and tv15Khz_mode = '0') else '0';
ctc_counter_3_trg <= '1' when top_frame = '1' and ((vcnt = 246 and tv15Khz_mode = '1') or (vcnt = 493 and tv15Khz_mode = '0')) else '0';
------------------------------------------
-- write enable / ram access from CPU --
@ -590,7 +567,7 @@ begin
sp_graphx32_do_r <= sp_graphx32_do; -- latch incoming sprite data
sp_addr <= sp_code(7 downto 0) & (sp_line xor sp_vflip) & (sp_byte_cnt+1 xor sp_hflip); -- advance graphics rom addr
sp_on_line <= '1';
when "010010"|"011010"|"100010" => -- 18,26,34
when "010010"|"011010"|"100010" => -- 18,26,34
sp_graphx32_do_r <= sp_graphx32_do; -- latch incoming sprite data
sp_addr <= sp_code(7 downto 0) & (sp_line xor sp_vflip) & (sp_byte_cnt+2 xor sp_hflip); -- advance graphics rom addr
sp_byte_cnt <= sp_byte_cnt + 1;
@ -639,16 +616,16 @@ sp_graphx_b <= sp_graphx_do(3 downto 0) when sp_hflip(0) = '1' else sp_graphx_do
sp_graphx_a_ok <= '1' when sp_graphx_a /= x"0" else '0';
sp_graphx_b_ok <= '1' when sp_graphx_b /= x"0" else '0';
sp_buffer_ram1a_di <= sp_attr(3 downto 0) & sp_graphx_a when sp_buffer_sel = '1' else x"00";
sp_buffer_ram1b_di <= sp_attr(3 downto 0) & sp_graphx_b when sp_buffer_sel = '1' else x"00";
sp_buffer_ram1_addr <= sp_hcnt(8 downto 1) when sp_buffer_sel = '1' else hflip(8 downto 1) - x"04";
sp_buffer_ram1_addr <= sp_hcnt(8 downto 1) when sp_buffer_sel = '1' else hflip(8 downto 1) + x"0C";
sp_buffer_ram1a_we <= not sp_hcnt(0) and sp_on_line and sp_graphx_a_ok when sp_buffer_sel = '1' else hcnt(0);
sp_buffer_ram1b_we <= not sp_hcnt(0) and sp_on_line and sp_graphx_b_ok when sp_buffer_sel = '1' else hcnt(0);
sp_buffer_ram2a_di <= sp_attr(3 downto 0) & sp_graphx_a when sp_buffer_sel = '0' else x"00";
sp_buffer_ram2b_di <= sp_attr(3 downto 0) & sp_graphx_b when sp_buffer_sel = '0' else x"00";
sp_buffer_ram2_addr <= sp_hcnt(8 downto 1) when sp_buffer_sel = '0' else hflip(8 downto 1) - x"04";
sp_buffer_ram2_addr <= sp_hcnt(8 downto 1) when sp_buffer_sel = '0' else hflip(8 downto 1) + x"0C";
sp_buffer_ram2a_we <= not sp_hcnt(0) and sp_on_line and sp_graphx_a_ok when sp_buffer_sel = '0' else hcnt(0);
sp_buffer_ram2b_we <= not sp_hcnt(0) and sp_on_line and sp_graphx_b_ok when sp_buffer_sel = '0' else hcnt(0);
@ -751,92 +728,28 @@ port map(
DO => cpu_do
);
-- CTC interrupt controler Z80-CTC (MK3882)
ctc_controler : entity work.ctc_controler
port map(
clock => clock_vid,
clock_ena => cpu_ena,
reset => reset,
d_in => cpu_do,
load_data => ctc_controler_we,
int_ack => ctc_int_ack,
int_pulse_0 => ctc_counter_0_int,
int_pulse_1 => ctc_counter_1_int,
int_pulse_2 => ctc_counter_2_int,
int_pulse_3 => ctc_counter_3_int,
d_out => ctc_controler_do,
int_n => cpu_irq_n
);
ctc_counter_0 : entity work.ctc_counter
port map(
clock => clock_vid,
clock_ena => cpu_ena,
reset => reset,
d_in => cpu_do,
load_data => ctc_counter_0_we,
clk_trg => '0',
d_out => ctc_counter_0_do,
zc_to => open, -- zc/to #0 (pin 7) connected to clk_trg #1 (pin 22) on schematics (seems to be not used)
int_pulse => ctc_counter_0_int
);
ctc_counter_1 : entity work.ctc_counter
port map(
clock => clock_vid,
clock_ena => cpu_ena,
reset => reset,
d_in => cpu_do,
load_data => ctc_counter_1_we,
clk_trg => '0',
d_out => ctc_counter_1_do,
zc_to => open,
int_pulse => ctc_counter_1_int
);
ctc_counter_2 : entity work.ctc_counter
port map(
clock => clock_vid,
clock_ena => cpu_ena,
reset => reset,
d_in => cpu_do,
load_data => ctc_counter_2_we,
clk_trg => '0',
d_out => ctc_counter_2_do,
zc_to => open,
int_pulse => ctc_counter_2_int
);
ctc_counter_3 : entity work.ctc_counter
port map(
clock => clock_vid,
clock_ena => cpu_ena,
reset => reset,
d_in => cpu_do,
load_data => ctc_counter_3_we,
clk_trg => ctc_counter_3_trg,
d_out => ctc_counter_3_do,
zc_to => open,
int_pulse => ctc_counter_3_int
-- Z80-CTC (MK3882)
z80ctc : entity work.z80ctc_top
port map (
clock => clock_vid,
clock_ena => cpu_ena,
reset => reset,
din => cpu_do,
cpu_din => cpu_di,
dout => ctc_do,
ce_n => not ctc_ce,
cs => cpu_addr(1 downto 0),
m1_n => cpu_m1_n,
iorq_n => cpu_ioreq_n,
rd_n => cpu_rd_n,
int_n => cpu_irq_n,
trg0 => '0',
to0 => ctc_counter_1_trg,
trg1 => ctc_counter_1_trg,
to1 => open,
trg2 => ctc_counter_2_trg,
to2 => open,
trg3 => ctc_counter_3_trg
);
cpu_rom_addr <= cpu_addr(15 downto 0);

View File

@ -50,14 +50,16 @@ module DiscsOfTron_MiST(
localparam CONF_STR = {
"DOTRON;;",
"O2,Rotate Controls,Off,On;",
"O34,Scanlines,Off,25%,50%,75%;",
"O5,Blend,Off,On;",
"O6,Service,Off,On;",
"O7,Swap Joystick,Off,On;",
"T0,Reset;",
"V,v1.1.",`BUILD_DATE
};
wire rotate = status[2];
wire blend = status[5];
wire service = status[6];
assign LED = ~ioctl_downl;
assign SDRAM_CLK = clk_mem;
assign SDRAM_CKE = 1;
@ -75,14 +77,18 @@ pll_mist pll(
wire [31:0] status;
wire [1:0] buttons;
wire [1:0] switches;
wire [7:0] joy_0;
wire [7:0] joy_1;
wire [15:0] joystick_0;
wire [15:0] joystick_1;
wire scandoublerD;
wire ypbpr;
wire [15:0] audio_l, audio_r;
wire hs, vs, cs;
wire blankn;
wire [2:0] g, r, b;
wire key_pressed;
wire [7:0] key_code;
wire key_strobe;
wire [15:0] rom_addr;
wire [15:0] rom_do;
wire [13:0] snd_addr;
@ -183,26 +189,27 @@ DiscsOfTron DiscsOfTron(
.video_vs(vs),
.video_csync(cs),
.tv15Khz_mode(scandoublerD),
.separate_audio(1'b0),
.separate_audio(1'b1),
.audio_out_l(audio_l),
.audio_out_r(audio_r),
.coin1(btn_coin),
.coin2(1'b0),
.start2(btn_two_players),
.start1(btn_one_player),
.level_up(btn_lup),
.level_down(btn_ldown),
.coin_meters(1),
.service(service),
.coin1(m_coin1),
.coin2(m_coin2),
.start2(m_two_players),
.start1(m_one_player),
.left(m_left),
.right(m_right),
.forward(m_up),
.back(m_down),
.fire(m_fire),
.deflect(m_bomb),
.buttonf(btn_f),
.buttong(btn_g),
.coin_meters(1),
.service(status[6]),
.fire(m_fireA),
.deflect(m_fireB),
.buttonf(m_fireF | m_fireH), // X or L
.buttong(m_fireE | m_fireG), // Y or R
.level_up(m_fireD),
.level_down(m_fireC),
.cpu_rom_addr ( rom_addr ),
.cpu_rom_do ( rom_addr[0] ? rom_do[15:8] : rom_do[7:0] ),
@ -232,12 +239,12 @@ mist_video #(.COLOR_DEPTH(3), .SD_HCNT_WIDTH(10)) mist_video(
.VGA_B ( VGA_B ),
.VGA_VS ( vs_out ),
.VGA_HS ( hs_out ),
.rotate ( {1'b1,status[2]} ),
.rotate ( { 1'b1,rotate } ),
.ce_divider ( 1 ),
.blend ( status[5] ),
.blend ( blend ),
.scandoubler_disable(1),//scandoublerD ),
.no_csync ( 1'b1 ),
.scanlines ( status[4:3] ),
.scanlines ( ),
.ypbpr ( ypbpr )
);
@ -257,8 +264,8 @@ user_io(
.key_strobe (key_strobe ),
.key_pressed (key_pressed ),
.key_code (key_code ),
.joystick_0 (joy_0 ),
.joystick_1 (joy_1 ),
.joystick_0 (joystick_0 ),
.joystick_1 (joystick_1 ),
.status (status )
);
@ -280,54 +287,24 @@ dac_r(
.dac_o(AUDIO_R)
);
wire [7:0] joystick_0 = status[7] ? joy_1 : joy_0;
wire [7:0] joystick_1 = status[7] ? joy_0 : joy_1;
wire m_up, m_down, m_left, m_right, m_fireA, m_fireB, m_fireC, m_fireD, m_fireE, m_fireF, m_fireG, m_fireH;
wire m_up2, m_down2, m_left2, m_right2, m_fire2A, m_fire2B, m_fire2C, m_fire2D, m_fire2E, m_fire2F, m_fire2G, m_fire2H;
wire m_tilt, m_coin1, m_coin2, m_coin3, m_coin4, m_one_player, m_two_players, m_three_players, m_four_players;
wire m_up = btn_up | joystick_0[3] | joystick_1[3];
wire m_down = btn_down | joystick_0[2] | joystick_1[2];
wire m_left = btn_left | joystick_0[1] | joystick_1[1];
wire m_right = btn_right | joystick_0[0] | joystick_1[0];
wire m_fire = btn_fire1 | joystick_0[4] | joystick_1[4];
wire m_bomb = btn_fire2 | joystick_0[5] | joystick_1[5];
//wire m_lup = btn_lup | joystick_0[6] | joystick_1[6];
//wire m_ldown = btn_ldown | joystick_0[7] | joystick_1[7];
reg btn_one_player = 0;
reg btn_two_players = 0;
reg btn_left = 0;
reg btn_right = 0;
reg btn_down = 0;
reg btn_up = 0;
reg btn_f = 0;
reg btn_g = 0;
reg btn_lup = 0;
reg btn_ldown = 0;
reg btn_fire1 = 0;
reg btn_fire2 = 0;
reg btn_coin = 0;
wire key_pressed;
wire [7:0] key_code;
wire key_strobe;
always @(posedge clk_sys) begin
if(key_strobe) begin
case(key_code)
'h34: btn_f <= key_pressed; // f
'h2B: btn_g <= key_pressed; // g
'h04: btn_lup <= key_pressed; // F3
'h0C: btn_ldown <= key_pressed; // F4
'h75: btn_up <= key_pressed; // up
'h72: btn_down <= key_pressed; // down
'h6B: btn_left <= key_pressed; // left
'h74: btn_right <= key_pressed; // right
'h76: btn_coin <= key_pressed; // ESC
'h05: btn_one_player <= key_pressed; // F1
'h06: btn_two_players <= key_pressed; // F2
'h11: btn_fire2 <= key_pressed; // alt
'h29: btn_fire1 <= key_pressed; // Space
endcase
end
end
arcade_inputs inputs (
.clk ( clk_sys ),
.key_strobe ( key_strobe ),
.key_pressed ( key_pressed ),
.key_code ( key_code ),
.joystick_0 ( joystick_0 ),
.joystick_1 ( joystick_1 ),
.rotate ( rotate ),
.orientation ( 2'b10 ),
.joyswap ( 1'b0 ),
.oneplayer ( 1'b1 ),
.controls ( {m_tilt, m_coin4, m_coin3, m_coin2, m_coin1, m_four_players, m_three_players, m_two_players, m_one_player} ),
.player1 ( {m_fireH, m_fireG, m_fireF, m_fireE, m_fireD, m_fireC, m_fireB, m_fireA, m_up, m_down, m_left, m_right} ),
.player2 ( {m_fire2H, m_fire2G, m_fire2F, m_fire2E, m_fire2D, m_fire2C, m_fire2B, m_fire2A, m_up2, m_down2, m_left2, m_right2} )
);
endmodule

View File

@ -1,106 +0,0 @@
---------------------------------------------------------------------------------
-- Z80-CTC controler by Dar (darfpga@aol.fr) (19/10/2019)
-- http://darfpga.blogspot.fr
---------------------------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
use ieee.numeric_std.all;
entity ctc_controler is
port(
clock : in std_logic;
clock_ena : in std_logic;
reset : in std_logic;
d_in : in std_logic_vector( 7 downto 0);
load_data : in std_logic;
int_ack : in std_logic;
int_pulse_0 : in std_logic;
int_pulse_1 : in std_logic;
int_pulse_2 : in std_logic;
int_pulse_3 : in std_logic;
d_out : out std_logic_vector( 7 downto 0);
int_n : out std_logic
);
end ctc_controler;
architecture struct of ctc_controler is
signal int_vector : std_logic_vector(4 downto 0);
signal wait_for_time_constant : std_logic;
signal load_data_r : std_logic; -- make sure load_data toggles to get one new data
signal int_reg_0 : std_logic;
signal int_reg_1 : std_logic;
signal int_reg_2 : std_logic;
signal int_reg_3 : std_logic;
signal int_ack_r : std_logic;
begin
int_n <= '0' when (int_reg_0 or int_reg_1 or int_reg_2 or int_reg_3) = '1' else '1';
d_out <= int_vector & "000" when int_reg_0 = '1' else
int_vector & "010" when int_reg_1 = '1' else
int_vector & "100" when int_reg_2 = '1' else
int_vector & "110" when int_reg_3 = '1' else (others => '0');
process (reset, clock)
begin
if reset = '1' then -- hardware and software reset
wait_for_time_constant <= '0';
int_reg_0 <= '0';
int_reg_1 <= '0';
int_reg_2 <= '0';
int_reg_3 <= '0';
load_data_r <= load_data;
int_vector <= (others => '0');
else
if rising_edge(clock) then
if clock_ena = '1' then
load_data_r <= load_data;
int_ack_r <= int_ack;
if load_data = '1' and load_data_r = '0' then
if wait_for_time_constant = '1' then
wait_for_time_constant <= '0';
else
if d_in(0) = '1' then -- check if its a control world
wait_for_time_constant <= d_in(2);
-- if d_in(1) = '1' then -- software reset
-- wait_for_time_constant <= '0';
-- end if;
else -- its an interrupt vector
int_vector <= d_in(7 downto 3);
end if;
end if;
end if;
if int_pulse_0 = '1' then int_reg_0 <= '1'; end if;
if int_pulse_1 = '1' then int_reg_1 <= '1'; end if;
if int_pulse_2 = '1' then int_reg_2 <= '1'; end if;
if int_pulse_3 = '1' then int_reg_3 <= '1'; end if;
if int_ack_r = '1' and int_ack = '0' then
if int_reg_0 = '1' then int_reg_0 <= '0';
elsif int_reg_1 = '1' then int_reg_1 <= '0';
elsif int_reg_2 = '1' then int_reg_2 <= '0';
elsif int_reg_3 = '1' then int_reg_3 <= '0'; end if;
end if;
end if;
end if;
end if;
end process;
end struct;

View File

@ -1,152 +0,0 @@
---------------------------------------------------------------------------------
-- Z80-CTC counter by Dar (darfpga@aol.fr) (19/10/2019)
-- http://darfpga.blogspot.fr
---------------------------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
use ieee.numeric_std.all;
entity ctc_counter is
port(
clock : in std_logic;
clock_ena : in std_logic;
reset : in std_logic;
d_in : in std_logic_vector( 7 downto 0);
load_data : in std_logic;
clk_trg : in std_logic;
d_out : out std_logic_vector(7 downto 0);
zc_to : out std_logic;
int_pulse : out std_logic
);
end ctc_counter;
architecture struct of ctc_counter is
signal control_word : std_logic_vector(7 downto 0);
signal wait_for_time_constant : std_logic;
signal time_constant_loaded : std_logic;
signal restart_on_next_clock : std_logic;
signal restart_on_next_trigger : std_logic;
signal prescale_max : std_logic_vector(7 downto 0);
signal prescale_in : std_logic_vector(7 downto 0) := (others => '0');
signal count_max : std_logic_vector(8 downto 0);
signal count_in : std_logic_vector(8 downto 0) := (others => '0');
signal zc_to_in : std_logic;
signal clk_trg_r : std_logic;
signal trigger : std_logic;
signal count_ena : std_logic;
signal load_data_r : std_logic; -- make sure load_data toggles to get one new data
begin
prescale_max <=
(others => '0') when control_word(6) = '1' else -- counter mode (prescale max = 0)
X"0F" when control_word(6 downto 5) = "00" else -- timer mode prescale 16
X"FF"; -- timer mode prescale 256
trigger <=
'1' when (clk_trg = '0' and clk_trg_r = '1' and control_word(4) = '0') or -- falling edge
(clk_trg = '1' and clk_trg_r = '0' and control_word(4) = '1') else '0'; -- rising edge
d_out <= count_in(7 downto 0);
zc_to <= zc_to_in;
int_pulse <= zc_to_in when control_word(7) = '1' else '0';
process (reset, clock)
begin
if reset = '1' then -- hardware reset
count_ena <= '0';
wait_for_time_constant <= '0';
time_constant_loaded <= '0';
restart_on_next_clock <= '0';
restart_on_next_trigger <= '0';
count_in <= (others=> '0');
zc_to_in <= '0';
clk_trg_r <= clk_trg;
else
if rising_edge(clock) then
if clock_ena = '1' then
clk_trg_r <= clk_trg;
load_data_r <= load_data;
if (restart_on_next_trigger = '1' and trigger = '1') or (restart_on_next_clock = '1') then
restart_on_next_clock <= '0';
restart_on_next_trigger <= '0';
count_ena <= '1';
count_in <= count_max;
prescale_in <= prescale_max;
end if;
if load_data = '1' and load_data_r = '0' then
if wait_for_time_constant = '1' then
wait_for_time_constant <= '0';
time_constant_loaded <= '1';
if d_in = X"00" then
count_max <= '1'&X"00";
else
count_max <= '0'&d_in;
end if;
if control_word(6) = '0' and count_ena = '0' then -- in timer mode, if count was stooped
if control_word(3) = '0' then -- auto start when time_constant loaded
restart_on_next_clock <= '1';
else -- wait for trigger to start
restart_on_next_trigger <= '1';
end if;
end if;
else -- not waiting for time constant
if d_in(0) = '1' then -- check if its a control world
control_word <= d_in;
wait_for_time_constant <= d_in(2);
restart_on_next_clock <= '0';
restart_on_next_trigger <= '0';
if d_in(1) = '1' then -- software reset
count_ena <= '0';
time_constant_loaded <= '0';
zc_to_in <= '0';
-- zc_to_in_r <= '0';
clk_trg_r <= clk_trg;
end if;
end if;
end if;
end if; -- end load data
-- counter
zc_to_in <= '0';
if ((control_word(6) = '1' and trigger = '1' ) or
(control_word(6) = '0' and count_ena = '1') ) and time_constant_loaded = '1' then
if prescale_in = 0 then
prescale_in <= '0'&prescale_max(7 downto 1); -- test divide by 2 !
if count_in = 0 then
zc_to_in <= '1';
count_in <= count_max;
else
count_in <= count_in - '1';
end if;
else
prescale_in <= prescale_in - '1';
end if;
end if;
end if;
end if;
end if;
end process;
end struct;

View File

@ -63,6 +63,8 @@ module sdram (
output reg [31:0] sp_q
);
parameter MHZ = 16'd80; // 80 MHz default clock, set it to proper value to calculate refresh rate
localparam RASCAS_DELAY = 3'd2; // tRCD=20ns -> 2 cycles@<100MHz
localparam BURST_LENGTH = 3'b001; // 000=1, 001=2, 010=4, 011=8
localparam ACCESS_TYPE = 1'b0; // 0=sequential, 1=interleaved
@ -72,8 +74,8 @@ localparam NO_WRITE_BURST = 1'b1; // 0= write burst enabled, 1=only single acc
localparam MODE = { 3'b000, NO_WRITE_BURST, OP_MODE, CAS_LATENCY, ACCESS_TYPE, BURST_LENGTH};
// 64ms/8192 rows = 7.8us -> 842 cycles@108MHz
localparam RFRSH_CYCLES = 10'd842;
// 64ms/8192 rows = 7.8us
localparam RFRSH_CYCLES = 16'd78*MHZ/4'd10;
// ---------------------------------------------------------------------
// ------------------------ cycle state machine ------------------------
@ -81,7 +83,7 @@ localparam RFRSH_CYCLES = 10'd842;
/*
SDRAM state machine for 2 bank interleaved access
1 word burst, CL2
2 words burst, CL2
cmd issued registered
0 RAS0 cas1 - data0 read burst terminated
1 ras0