1
0
mirror of https://github.com/Gehstock/Mist_FPGA.git synced 2026-01-22 18:31:06 +00:00

Moon Patrol: change clocking, fix display output, fix timings

This commit is contained in:
Gyorgy Szombathelyi 2019-05-28 22:04:04 +02:00
parent 8be5d1876d
commit 448d84bd73
31 changed files with 1199 additions and 1206 deletions

8
.gitignore vendored
View File

@ -1,4 +1,10 @@
PLLJ_PLLSPE_INFO.txt
db/
incremental_db/
output_files/
greybox_tmp/
build_id.v
*.bak
Robotron - Z1013_MiST/Z1013_Mist.pti_db_list.ddb
Robotron - Z1013_MiST/Z1013_Mist.tis_db_list.ddb
Sharp - MZ-80K_MiST/mz80k.qws

View File

@ -0,0 +1 @@
Output/

View File

@ -81,45 +81,34 @@ set_location_assignment PIN_127 -to SPI_SS2
set_location_assignment PIN_91 -to SPI_SS3
set_location_assignment PIN_90 -to SPI_SS4
set_location_assignment PIN_13 -to CONF_DATA0
set_location_assignment PIN_49 -to SDRAM_A[0]
set_location_assignment PIN_44 -to SDRAM_A[1]
set_location_assignment PIN_42 -to SDRAM_A[2]
set_location_assignment PIN_39 -to SDRAM_A[3]
set_location_assignment PIN_4 -to SDRAM_A[4]
set_location_assignment PIN_6 -to SDRAM_A[5]
set_location_assignment PIN_8 -to SDRAM_A[6]
set_location_assignment PIN_10 -to SDRAM_A[7]
set_location_assignment PIN_11 -to SDRAM_A[8]
set_location_assignment PIN_28 -to SDRAM_A[9]
set_location_assignment PIN_50 -to SDRAM_A[10]
set_location_assignment PIN_30 -to SDRAM_A[11]
set_location_assignment PIN_32 -to SDRAM_A[12]
set_location_assignment PIN_83 -to SDRAM_DQ[0]
set_location_assignment PIN_79 -to SDRAM_DQ[1]
set_location_assignment PIN_77 -to SDRAM_DQ[2]
set_location_assignment PIN_76 -to SDRAM_DQ[3]
set_location_assignment PIN_72 -to SDRAM_DQ[4]
set_location_assignment PIN_71 -to SDRAM_DQ[5]
set_location_assignment PIN_69 -to SDRAM_DQ[6]
set_location_assignment PIN_68 -to SDRAM_DQ[7]
set_location_assignment PIN_86 -to SDRAM_DQ[8]
set_location_assignment PIN_87 -to SDRAM_DQ[9]
set_location_assignment PIN_98 -to SDRAM_DQ[10]
set_location_assignment PIN_99 -to SDRAM_DQ[11]
set_location_assignment PIN_100 -to SDRAM_DQ[12]
set_location_assignment PIN_101 -to SDRAM_DQ[13]
set_location_assignment PIN_103 -to SDRAM_DQ[14]
set_location_assignment PIN_104 -to SDRAM_DQ[15]
set_location_assignment PIN_58 -to SDRAM_BA[0]
set_location_assignment PIN_51 -to SDRAM_BA[1]
set_location_assignment PIN_85 -to SDRAM_DQMH
set_location_assignment PIN_67 -to SDRAM_DQML
set_location_assignment PIN_60 -to SDRAM_nRAS
set_location_assignment PIN_64 -to SDRAM_nCAS
set_location_assignment PIN_66 -to SDRAM_nWE
set_location_assignment PIN_59 -to SDRAM_nCS
set_location_assignment PIN_33 -to SDRAM_CKE
set_location_assignment PIN_43 -to SDRAM_CLK
set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to VGA_R[5]
set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to VGA_R[4]
set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to VGA_R[3]
set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to VGA_R[2]
set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to VGA_R[1]
set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to VGA_R[0]
set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to VGA_G[5]
set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to VGA_G[4]
set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to VGA_G[3]
set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to VGA_G[2]
set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to VGA_G[1]
set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to VGA_G[0]
set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to VGA_B[5]
set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to VGA_B[4]
set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to VGA_B[3]
set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to VGA_B[2]
set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to VGA_B[1]
set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to VGA_B[0]
set_instance_assignment -name CURRENT_STRENGTH_NEW "MAXIMUM CURRENT" -to VGA_HS
set_instance_assignment -name CURRENT_STRENGTH_NEW "MAXIMUM CURRENT" -to VGA_VS
set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to LED
set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to AUDIO_R
set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to AUDIO_L
set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to SPI_DO
# Classic Timing Assignments
# ==========================
@ -165,7 +154,7 @@ set_global_assignment -name GENERATE_RBF_FILE ON
# SignalTap II Assignments
# ========================
set_global_assignment -name ENABLE_SIGNALTAP ON
set_global_assignment -name ENABLE_SIGNALTAP OFF
set_global_assignment -name USE_SIGNALTAP_FILE stp1.stp
# Advanced I/O Timing Assignments
@ -183,9 +172,9 @@ set_global_assignment -name OUTPUT_IO_TIMING_FAR_END_VMEAS "HALF SIGNAL SWING" -
# Incremental Compilation Assignments
# ===================================
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 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
# end DESIGN_PARTITION(Top)
# -------------------------
@ -196,9 +185,15 @@ set_global_assignment -name DEVICE_FILTER_PACKAGE TQFP
set_global_assignment -name DEVICE_FILTER_SPEED_GRADE 8
set_global_assignment -name CYCLONEIII_CONFIGURATION_SCHEME "PASSIVE SERIAL"
set_global_assignment -name FORCE_CONFIGURATION_VCCIO ON
set_global_assignment -name POWER_PRESET_COOLING_SOLUTION "23 MM HEAT SINK WITH 200 LFPM AIRFLOW"
set_global_assignment -name POWER_PRESET_COOLING_SOLUTION "NO HEAT SINK WITH STILL AIR"
set_global_assignment -name POWER_BOARD_THERMAL_MODEL "NONE (CONSERVATIVE)"
set_global_assignment -name VHDL_FILE src/bitmapctl_e.vhd
set_global_assignment -name VHDL_FILE src/tilemapctl_e.vhd
set_global_assignment -name VHDL_FILE src/target_pkg.vhd
set_global_assignment -name VHDL_FILE src/project_pkg.vhd
set_global_assignment -name VHDL_FILE src/platform_pkg.vhd
set_global_assignment -name VHDL_FILE src/mpatrol.vhd
set_global_assignment -name VHDL_FILE src/video_mixer.vhd
set_global_assignment -name VHDL_FILE src/platform_variant_pkg.vhd
set_global_assignment -name VHDL_FILE src/spritereg.vhd
set_global_assignment -name VHDL_FILE src/spritectl.vhd
@ -218,7 +213,6 @@ set_global_assignment -name VHDL_FILE src/t80/T80_Pack.vhd
set_global_assignment -name VHDL_FILE src/t80/T80_MCode.vhd
set_global_assignment -name VHDL_FILE src/t80/T80_ALU.vhd
set_global_assignment -name VHDL_FILE src/t80/T80.vhd
set_global_assignment -name VHDL_FILE src/video_mixer.vhd
set_global_assignment -name VHDL_FILE src/dac.vhd
set_global_assignment -name VHDL_FILE src/YM2149_linmix_sep.vhd
set_global_assignment -name VHDL_FILE src/sprom.vhd
@ -237,9 +231,8 @@ set_global_assignment -name VHDL_FILE src/bitmap2_ctl.vhd
set_global_assignment -name VHDL_FILE src/bitmap1_ctl.vhd
set_global_assignment -name VHDL_FILE src/i82c55.vhd
set_global_assignment -name VERILOG_FILE src/keyboard.v
set_global_assignment -name SYSTEMVERILOG_FILE src/hq2x.sv
set_global_assignment -name VERILOG_FILE src/scandoubler.v
set_global_assignment -name SYSTEMVERILOG_FILE src/video_mist.sv
set_global_assignment -name SYSTEMVERILOG_FILE src/rgb2ypbpr.sv
set_global_assignment -name VERILOG_FILE src/osd.v
set_global_assignment -name VERILOG_FILE src/mist_io.v
set_global_assignment -name VHDL_FILE src/sprite_array.vhd

View File

@ -0,0 +1,126 @@
## Generated SDC file "vectrex_MiST.out.sdc"
## Copyright (C) 1991-2013 Altera Corporation
## Your use of Altera Corporation's design tools, logic functions
## and other software and tools, and its AMPP partner logic
## functions, and any output files from any of the foregoing
## (including device programming or simulation files), and any
## associated documentation or information are expressly subject
## to the terms and conditions of the Altera Program License
## Subscription Agreement, Altera MegaCore Function License
## Agreement, or other applicable license agreement, including,
## without limitation, that your use is for the sole purpose of
## programming logic devices manufactured by Altera and sold by
## Altera or its authorized distributors. Please refer to the
## applicable agreement for further details.
## VENDOR "Altera"
## PROGRAM "Quartus II"
## VERSION "Version 13.1.0 Build 162 10/23/2013 SJ Web Edition"
## DATE "Sun Jun 24 12:53:00 2018"
##
## DEVICE "EP3C25E144C8"
##
# Clock constraints
# Automatically constrain PLL and other generated clocks
derive_pll_clocks -create_base_clocks
# Automatically calculate clock uncertainty to jitter and other effects.
derive_clock_uncertainty
# tsu/th constraints
# tco constraints
# tpd constraints
#**************************************************************
# Time Information
#**************************************************************
set_time_format -unit ns -decimal_places 3
#**************************************************************
# Create Clock
#**************************************************************
create_clock -name {SPI_SCK} -period 41.666 -waveform { 20.8 41.666 } [get_ports {SPI_SCK}]
#**************************************************************
# Create Generated Clock
#**************************************************************
#**************************************************************
# Set Clock Latency
#**************************************************************
#**************************************************************
# Set Clock Uncertainty
#**************************************************************
#**************************************************************
# Set Input Delay
#**************************************************************
set_input_delay -add_delay -clock_fall -clock [get_clocks {CLOCK_27}] 1.000 [get_ports {CLOCK_27}]
set_input_delay -add_delay -clock_fall -clock [get_clocks {SPI_SCK}] 1.000 [get_ports {CONF_DATA0}]
set_input_delay -add_delay -clock_fall -clock [get_clocks {SPI_SCK}] 1.000 [get_ports {SPI_DI}]
set_input_delay -add_delay -clock_fall -clock [get_clocks {SPI_SCK}] 1.000 [get_ports {SPI_SCK}]
set_input_delay -add_delay -clock_fall -clock [get_clocks {SPI_SCK}] 1.000 [get_ports {SPI_SS2}]
set_input_delay -add_delay -clock_fall -clock [get_clocks {SPI_SCK}] 1.000 [get_ports {SPI_SS3}]
#**************************************************************
# Set Output Delay
#**************************************************************
set_output_delay -add_delay -clock_fall -clock [get_clocks {SPI_SCK}] 1.000 [get_ports {SPI_DO}]
set_output_delay -add_delay -clock_fall -clock [get_clocks {Clock_inst|altpll_component|auto_generated|pll1|clk[0]}] 1.000 [get_ports {AUDIO_L}]
set_output_delay -add_delay -clock_fall -clock [get_clocks {Clock_inst|altpll_component|auto_generated|pll1|clk[0]}] 1.000 [get_ports {AUDIO_R}]
set_output_delay -add_delay -clock_fall -clock [get_clocks {Clock_inst|altpll_component|auto_generated|pll1|clk[1]}] 1.000 [get_ports {LED}]
set_output_delay -add_delay -clock_fall -clock [get_clocks {Clock_inst|altpll_component|auto_generated|pll1|clk[2]}] 1.000 [get_ports {VGA_*}]
#**************************************************************
# Set Clock Groups
#**************************************************************
set_clock_groups -asynchronous -group [get_clocks {SPI_SCK}] -group [get_clocks {Clock_inst|altpll_component|auto_generated|pll1|clk[*]}]
#**************************************************************
# Set False Path
#**************************************************************
#**************************************************************
# Set Multicycle Path
#**************************************************************
set_multicycle_path -to {VGA_*[*]} -setup 2
set_multicycle_path -to {VGA_*[*]} -hold 1
#**************************************************************
# Set Maximum Delay
#**************************************************************
#**************************************************************
# Set Minimum Delay
#**************************************************************
#**************************************************************
# Set Input Transition
#**************************************************************

View File

@ -157,21 +157,21 @@ BEGIN
altpll_component : altpll
GENERIC MAP (
bandwidth_type => "AUTO",
clk0_divide_by => 603,
clk0_divide_by => 1350,
clk0_duty_cycle => 50,
clk0_multiply_by => 80,
clk0_multiply_by => 179,
clk0_phase_shift => "0",
clk1_divide_by => 18,
clk1_divide_by => 9,
clk1_duty_cycle => 50,
clk1_multiply_by => 5,
clk1_multiply_by => 2,
clk1_phase_shift => "0",
clk2_divide_by => 9,
clk2_duty_cycle => 50,
clk2_multiply_by => 10,
clk2_multiply_by => 8,
clk2_phase_shift => "0",
clk3_divide_by => 27,
clk3_divide_by => 208,
clk3_duty_cycle => 50,
clk3_multiply_by => 40,
clk3_multiply_by => 185,
clk3_phase_shift => "0",
compensate_clock => "CLK0",
inclk0_input_frequency => 37037,
@ -251,18 +251,18 @@ END SYN;
-- Retrieval info: PRIVATE: CUR_DEDICATED_CLK STRING "c0"
-- Retrieval info: PRIVATE: CUR_FBIN_CLK STRING "c0"
-- Retrieval info: PRIVATE: DEVICE_SPEED_GRADE STRING "8"
-- Retrieval info: PRIVATE: DIV_FACTOR0 NUMERIC "603"
-- Retrieval info: PRIVATE: DIV_FACTOR1 NUMERIC "18"
-- Retrieval info: PRIVATE: DIV_FACTOR2 NUMERIC "9"
-- Retrieval info: PRIVATE: DIV_FACTOR3 NUMERIC "27"
-- Retrieval info: PRIVATE: DIV_FACTOR0 NUMERIC "1396"
-- Retrieval info: PRIVATE: DIV_FACTOR1 NUMERIC "1"
-- Retrieval info: PRIVATE: DIV_FACTOR2 NUMERIC "20"
-- Retrieval info: PRIVATE: DIV_FACTOR3 NUMERIC "208"
-- Retrieval info: PRIVATE: DUTY_CYCLE0 STRING "50.00000000"
-- Retrieval info: PRIVATE: DUTY_CYCLE1 STRING "50.00000000"
-- Retrieval info: PRIVATE: DUTY_CYCLE2 STRING "50.00000000"
-- Retrieval info: PRIVATE: DUTY_CYCLE3 STRING "50.00000000"
-- Retrieval info: PRIVATE: EFF_OUTPUT_FREQ_VALUE0 STRING "3.582090"
-- Retrieval info: PRIVATE: EFF_OUTPUT_FREQ_VALUE1 STRING "7.500000"
-- Retrieval info: PRIVATE: EFF_OUTPUT_FREQ_VALUE2 STRING "30.000000"
-- Retrieval info: PRIVATE: EFF_OUTPUT_FREQ_VALUE3 STRING "40.000000"
-- Retrieval info: PRIVATE: EFF_OUTPUT_FREQ_VALUE0 STRING "3.580000"
-- Retrieval info: PRIVATE: EFF_OUTPUT_FREQ_VALUE1 STRING "6.000000"
-- Retrieval info: PRIVATE: EFF_OUTPUT_FREQ_VALUE2 STRING "24.000000"
-- Retrieval info: PRIVATE: EFF_OUTPUT_FREQ_VALUE3 STRING "24.014423"
-- Retrieval info: PRIVATE: EXPLICIT_SWITCHOVER_COUNTER STRING "0"
-- Retrieval info: PRIVATE: EXT_FEEDBACK_RADIO STRING "0"
-- Retrieval info: PRIVATE: GLOCKED_COUNTER_EDIT_CHANGED STRING "1"
@ -283,7 +283,7 @@ END SYN;
-- Retrieval info: PRIVATE: LVDS_MODE_DATA_RATE STRING "Not Available"
-- Retrieval info: PRIVATE: LVDS_MODE_DATA_RATE_DIRTY NUMERIC "0"
-- Retrieval info: PRIVATE: LVDS_PHASE_SHIFT_UNIT0 STRING "deg"
-- Retrieval info: PRIVATE: LVDS_PHASE_SHIFT_UNIT1 STRING "deg"
-- Retrieval info: PRIVATE: LVDS_PHASE_SHIFT_UNIT1 STRING "ps"
-- Retrieval info: PRIVATE: LVDS_PHASE_SHIFT_UNIT2 STRING "deg"
-- Retrieval info: PRIVATE: LVDS_PHASE_SHIFT_UNIT3 STRING "deg"
-- Retrieval info: PRIVATE: MIG_DEVICE_SPEED_GRADE STRING "Any"
@ -291,18 +291,18 @@ END SYN;
-- Retrieval info: PRIVATE: MIRROR_CLK1 STRING "0"
-- Retrieval info: PRIVATE: MIRROR_CLK2 STRING "0"
-- Retrieval info: PRIVATE: MIRROR_CLK3 STRING "0"
-- Retrieval info: PRIVATE: MULT_FACTOR0 NUMERIC "80"
-- Retrieval info: PRIVATE: MULT_FACTOR1 NUMERIC "5"
-- Retrieval info: PRIVATE: MULT_FACTOR2 NUMERIC "10"
-- Retrieval info: PRIVATE: MULT_FACTOR3 NUMERIC "40"
-- Retrieval info: PRIVATE: MULT_FACTOR0 NUMERIC "185"
-- Retrieval info: PRIVATE: MULT_FACTOR1 NUMERIC "1"
-- Retrieval info: PRIVATE: MULT_FACTOR2 NUMERIC "37"
-- Retrieval info: PRIVATE: MULT_FACTOR3 NUMERIC "185"
-- Retrieval info: PRIVATE: NORMAL_MODE_RADIO STRING "1"
-- Retrieval info: PRIVATE: OUTPUT_FREQ0 STRING "3.58000000"
-- Retrieval info: PRIVATE: OUTPUT_FREQ1 STRING "7.50000000"
-- Retrieval info: PRIVATE: OUTPUT_FREQ2 STRING "30.00000000"
-- Retrieval info: PRIVATE: OUTPUT_FREQ3 STRING "40.00000000"
-- Retrieval info: PRIVATE: OUTPUT_FREQ_MODE0 STRING "0"
-- Retrieval info: PRIVATE: OUTPUT_FREQ_MODE1 STRING "0"
-- Retrieval info: PRIVATE: OUTPUT_FREQ_MODE2 STRING "0"
-- Retrieval info: PRIVATE: OUTPUT_FREQ1 STRING "6.00000000"
-- Retrieval info: PRIVATE: OUTPUT_FREQ2 STRING "24.00000000"
-- Retrieval info: PRIVATE: OUTPUT_FREQ3 STRING "24.00000000"
-- Retrieval info: PRIVATE: OUTPUT_FREQ_MODE0 STRING "1"
-- Retrieval info: PRIVATE: OUTPUT_FREQ_MODE1 STRING "1"
-- Retrieval info: PRIVATE: OUTPUT_FREQ_MODE2 STRING "1"
-- Retrieval info: PRIVATE: OUTPUT_FREQ_MODE3 STRING "0"
-- Retrieval info: PRIVATE: OUTPUT_FREQ_UNIT0 STRING "MHz"
-- Retrieval info: PRIVATE: OUTPUT_FREQ_UNIT1 STRING "MHz"
@ -316,7 +316,7 @@ END SYN;
-- Retrieval info: PRIVATE: PHASE_SHIFT3 STRING "0.00000000"
-- Retrieval info: PRIVATE: PHASE_SHIFT_STEP_ENABLED_CHECK STRING "0"
-- Retrieval info: PRIVATE: PHASE_SHIFT_UNIT0 STRING "deg"
-- Retrieval info: PRIVATE: PHASE_SHIFT_UNIT1 STRING "deg"
-- Retrieval info: PRIVATE: PHASE_SHIFT_UNIT1 STRING "ps"
-- Retrieval info: PRIVATE: PHASE_SHIFT_UNIT2 STRING "deg"
-- Retrieval info: PRIVATE: PHASE_SHIFT_UNIT3 STRING "deg"
-- Retrieval info: PRIVATE: PLL_ADVANCED_PARAM_CHECK STRING "0"
@ -359,21 +359,21 @@ END SYN;
-- Retrieval info: PRIVATE: ZERO_DELAY_RADIO STRING "0"
-- Retrieval info: LIBRARY: altera_mf altera_mf.altera_mf_components.all
-- Retrieval info: CONSTANT: BANDWIDTH_TYPE STRING "AUTO"
-- Retrieval info: CONSTANT: CLK0_DIVIDE_BY NUMERIC "603"
-- Retrieval info: CONSTANT: CLK0_DIVIDE_BY NUMERIC "1350"
-- Retrieval info: CONSTANT: CLK0_DUTY_CYCLE NUMERIC "50"
-- Retrieval info: CONSTANT: CLK0_MULTIPLY_BY NUMERIC "80"
-- Retrieval info: CONSTANT: CLK0_MULTIPLY_BY NUMERIC "179"
-- Retrieval info: CONSTANT: CLK0_PHASE_SHIFT STRING "0"
-- Retrieval info: CONSTANT: CLK1_DIVIDE_BY NUMERIC "18"
-- Retrieval info: CONSTANT: CLK1_DIVIDE_BY NUMERIC "9"
-- Retrieval info: CONSTANT: CLK1_DUTY_CYCLE NUMERIC "50"
-- Retrieval info: CONSTANT: CLK1_MULTIPLY_BY NUMERIC "5"
-- Retrieval info: CONSTANT: CLK1_MULTIPLY_BY NUMERIC "2"
-- Retrieval info: CONSTANT: CLK1_PHASE_SHIFT STRING "0"
-- Retrieval info: CONSTANT: CLK2_DIVIDE_BY NUMERIC "9"
-- Retrieval info: CONSTANT: CLK2_DUTY_CYCLE NUMERIC "50"
-- Retrieval info: CONSTANT: CLK2_MULTIPLY_BY NUMERIC "10"
-- Retrieval info: CONSTANT: CLK2_MULTIPLY_BY NUMERIC "8"
-- Retrieval info: CONSTANT: CLK2_PHASE_SHIFT STRING "0"
-- Retrieval info: CONSTANT: CLK3_DIVIDE_BY NUMERIC "27"
-- Retrieval info: CONSTANT: CLK3_DIVIDE_BY NUMERIC "208"
-- Retrieval info: CONSTANT: CLK3_DUTY_CYCLE NUMERIC "50"
-- Retrieval info: CONSTANT: CLK3_MULTIPLY_BY NUMERIC "40"
-- Retrieval info: CONSTANT: CLK3_MULTIPLY_BY NUMERIC "185"
-- Retrieval info: CONSTANT: CLK3_PHASE_SHIFT STRING "0"
-- Retrieval info: CONSTANT: COMPENSATE_CLOCK STRING "CLK0"
-- Retrieval info: CONSTANT: INCLK0_INPUT_FREQUENCY NUMERIC "37037"

View File

@ -7,77 +7,100 @@ library work;
use work.pace_pkg.all;
use work.video_controller_pkg.all;
use work.sprite_pkg.all;
use work.project_pkg.all;
use work.platform_pkg.all;
entity Graphics is
port
(
bitmap_ctl_i : in to_BITMAP_CTL_a(1 to 3);
bitmap_ctl_o : out from_BITMAP_CTL_a(1 to 3);
tilemap_ctl_i : in to_TILEMAP_CTL_a(1 to 1);
tilemap_ctl_o : out from_TILEMAP_CTL_a(1 to 1);
sprite_reg_i : in to_SPRITE_REG_t;
sprite_ctl_i : in to_SPRITE_CTL_t;
sprite_ctl_o : out from_SPRITE_CTL_t;
spr0_hit : out std_logic;
graphics_i : in to_GRAPHICS_t;
graphics_o : out from_GRAPHICS_t;
video_i : in from_VIDEO_t;
video_o : out to_VIDEO_t
bitmap_ctl_i : in to_BITMAP_CTL_a(1 to PACE_VIDEO_NUM_BITMAPS);
bitmap_ctl_o : out from_BITMAP_CTL_a(1 to PACE_VIDEO_NUM_BITMAPS);
tilemap_ctl_i : in to_TILEMAP_CTL_a(1 to PACE_VIDEO_NUM_TILEMAPS);
tilemap_ctl_o : out from_TILEMAP_CTL_a(1 to PACE_VIDEO_NUM_TILEMAPS);
sprite_reg_i : in to_SPRITE_REG_t;
sprite_ctl_i : in to_SPRITE_CTL_t;
sprite_ctl_o : out from_SPRITE_CTL_t;
spr0_hit : out std_logic;
graphics_i : in to_GRAPHICS_t;
graphics_o : out from_GRAPHICS_t;
video_i : in from_VIDEO_t;
video_o : out to_VIDEO_t
);
end Graphics;
architecture SYN of Graphics is
alias clk : std_logic is video_i.clk;
signal from_video_ctl : from_VIDEO_CTL_t;
signal bitmap_ctl_o_s : from_BITMAP_CTL_a(1 to 3);
signal tilemap_ctl_o_s : from_TILEMAP_CTL_a(1 to 1);
signal sprite_ctl_o_s : from_SPRITE_CTL_t;
signal sprite_pri : std_logic;
signal rgb_data : RGB_t;
signal video_o_s : to_VIDEO_t;
alias clk : std_logic is video_i.clk;
signal from_video_ctl : from_VIDEO_CTL_t;
signal bitmap_ctl_o_s : from_BITMAP_CTL_a(1 to PACE_VIDEO_NUM_BITMAPS);
signal tilemap_ctl_o_s : from_TILEMAP_CTL_a(1 to PACE_VIDEO_NUM_TILEMAPS);
signal sprite_ctl_o_s : from_SPRITE_CTL_t;
signal sprite_pri : std_logic;
signal osd_active : std_logic;
signal osd_colour : std_logic_vector(7 downto 0);
signal rgb_data : RGB_t;
-- before OSD is mixed in
signal video_o_s : to_VIDEO_t;
begin
video_o.clk <= video_o_s.clk;
video_o.rgb.r <= video_o_s.rgb.r;
video_o.rgb.g <= video_o_s.rgb.g;
video_o.rgb.b <= video_o_s.rgb.b;
video_o.hsync <= video_o_s.hsync;
video_o.vsync <= video_o_s.vsync;
video_o.hblank <= video_o_s.hblank;
video_o.vblank <= video_o_s.vblank;
graphics_o.y <= from_video_ctl.y;
graphics_o.hblank <= video_o_s.hblank;
graphics_o.vblank <= video_o_s.vblank;
-- dodgy OSD transparency...
video_o.clk <= video_o_s.clk;
video_o.rgb.r <= video_o_s.rgb.r;
video_o.rgb.g <= video_o_s.rgb.g;
video_o.rgb.b <= video_o_s.rgb.b;
video_o.hsync <= video_o_s.hsync;
video_o.vsync <= video_o_s.vsync;
video_o.hblank <= video_o_s.hblank;
video_o.vblank <= video_o_s.vblank;
graphics_o.y <= from_video_ctl.y;
-- should this be the 'real' vblank or the 'active' vblank?
-- - use the real for now
graphics_o.hblank <= video_o_s.hblank;
graphics_o.vblank <= video_o_s.vblank;
--graphics_o.vblank <= from_video_ctl.vblank;
pace_video_controller_inst : entity work.pace_video_controller
generic map
(
CONFIG => PACE_VIDEO_VGA_800x600_60Hz,
DELAY => 7,
H_SIZE => 256,
V_SIZE => 256,
L_CROP => 0,--8
R_CROP => 0,--8
H_SCALE => 2,--2
V_SCALE => 2,--2
H_SYNC_POL => '1',--1
V_SYNC_POL => '1',--1
BORDER_RGB => RGB_BLACK
CONFIG => PACE_VIDEO_CONTROLLER_TYPE,
DELAY => PACE_VIDEO_PIPELINE_DELAY,
H_SIZE => PACE_VIDEO_H_SIZE,
V_SIZE => PACE_VIDEO_V_SIZE,
L_CROP => PACE_VIDEO_L_CROP,
R_CROP => PACE_VIDEO_R_CROP,
H_SCALE => PACE_VIDEO_H_SCALE,
V_SCALE => PACE_VIDEO_V_SCALE,
H_SYNC_POL => PACE_VIDEO_H_SYNC_POLARITY,
V_SYNC_POL => PACE_VIDEO_V_SYNC_POLARITY,
BORDER_RGB => PACE_VIDEO_BORDER_RGB
)
port map
(
video_i => video_i,
reg_i.h_scale => "000",
reg_i.v_scale => "000",
-- clocking etc
video_i => video_i,
-- register interface
reg_i.h_scale => "000",
reg_i.v_scale => "000",
-- video data signals (in)
rgb_i => rgb_data,
video_ctl_o => from_video_ctl,
-- video control signals (out)
video_ctl_o => from_video_ctl,
-- VGA signals (out)
video_o => video_o_s
);
pace_video_mixer_inst : entity work.pace_video_mixer
port map
(
@ -91,93 +114,161 @@ begin
graphics_i => graphics_i,
rgb_o => rgb_data
);
GEN_NO_BITMAPS : if PACE_VIDEO_NUM_BITMAPS = 0 generate
--bitmap_ctl_o_s <= ((others => '0'), (others => (others => '0')), '0');
end generate GEN_NO_BITMAPS;
forground_bitmapctl_inst1 : entity work.BITMAP_1
GEN_BITMAP_1 : if PACE_VIDEO_NUM_BITMAPS > 0 generate
forground_bitmapctl_inst : entity work.bitmapCtl(BITMAP_1)
generic map
(
DELAY => 7
DELAY => PACE_VIDEO_PIPELINE_DELAY
)
port map
(
reset => video_i.reset,
video_ctl => from_video_ctl,
ctl_i => bitmap_ctl_i(1),
ctl_o => bitmap_ctl_o_s(1),
graphics_i => graphics_i
reset => video_i.reset,
video_ctl => from_video_ctl,
ctl_i => bitmap_ctl_i(1),
ctl_o => bitmap_ctl_o_s(1),
graphics_i => graphics_i
);
end generate GEN_BITMAP_1;
forground_bitmapctl_inst2 : entity work.BITMAP_2
GEN_BITMAP_2 : if PACE_VIDEO_NUM_BITMAPS > 1 generate
forground_bitmapctl_inst : entity work.bitmapCtl(BITMAP_2)
generic map
(
DELAY => 7
DELAY => PACE_VIDEO_PIPELINE_DELAY
)
port map
(
reset => video_i.reset,
video_ctl => from_video_ctl,
ctl_i => bitmap_ctl_i(2),
ctl_o => bitmap_ctl_o_s(2),
graphics_i => graphics_i
);
reset => video_i.reset,
video_ctl => from_video_ctl,
ctl_i => bitmap_ctl_i(2),
ctl_o => bitmap_ctl_o_s(2),
forground_bitmapctl_inst3 : entity work.BITMAP_3
generic map
(
DELAY => 7
)
port map
(
reset => video_i.reset,
video_ctl => from_video_ctl,
ctl_i => bitmap_ctl_i(3),
ctl_o => bitmap_ctl_o_s(3),
graphics_i => graphics_i
graphics_i => graphics_i
);
bitmap_ctl_o <= bitmap_ctl_o_s;
end generate GEN_BITMAP_2;
foreground_mapctl_inst : entity work.TILEMAP_1
GEN_BITMAP_3 : if PACE_VIDEO_NUM_BITMAPS > 2 generate
forground_bitmapctl_inst : entity work.bitmapCtl(BITMAP_3)
generic map
(
DELAY => 7
DELAY => PACE_VIDEO_PIPELINE_DELAY
)
port map
(
reset => video_i.reset,
video_ctl => from_video_ctl,
ctl_i => tilemap_ctl_i(1),
ctl_o => tilemap_ctl_o_s(1),
graphics_i => graphics_i
reset => video_i.reset,
video_ctl => from_video_ctl,
ctl_i => bitmap_ctl_i(3),
ctl_o => bitmap_ctl_o_s(3),
graphics_i => graphics_i
);
end generate GEN_BITMAP_3;
bitmap_ctl_o <= bitmap_ctl_o_s;
GEN_NO_TILEMAPS : if PACE_VIDEO_NUM_TILEMAPS = 0 generate
--tilemap_ctl_o_s(1) <= ((others => '0'), (others => '0'), (others => '0'),
-- (others => (others => '0')), '0');
end generate GEN_NO_TILEMAPS;
GEN_TILEMAP_1 : if PACE_VIDEO_NUM_TILEMAPS > 0 generate
foreground_mapctl_inst : entity work.tilemapCtl(TILEMAP_1)
generic map
(
DELAY => PACE_VIDEO_PIPELINE_DELAY
)
port map
(
reset => video_i.reset,
video_ctl => from_video_ctl,
ctl_i => tilemap_ctl_i(1),
ctl_o => tilemap_ctl_o_s(1),
graphics_i => graphics_i
);
end generate GEN_TILEMAP_1;
GEN_TILEMAP_2 : if PACE_VIDEO_NUM_TILEMAPS > 1 generate
background_mapctl_inst : entity work.tilemapCtl(TILEMAP_2)
generic map
(
DELAY => PACE_VIDEO_PIPELINE_DELAY
)
port map
(
reset => video_i.reset,
video_ctl => from_video_ctl,
ctl_i => tilemap_ctl_i(2),
ctl_o => tilemap_ctl_o_s(2),
graphics_i => graphics_i
);
end generate GEN_TILEMAP_2;
tilemap_ctl_o <= tilemap_ctl_o_s;
GEN_NO_SPRITES : if PACE_VIDEO_NUM_SPRITES = 0 generate
sprite_ctl_o_s <= ((others => '0'), (others => (others => '0')), '0');
sprite_pri <= '0';
spr0_hit <= '0';
end generate GEN_NO_SPRITES;
GEN_SPRITES : if PACE_VIDEO_NUM_SPRITES > 0 generate
sprites_inst : sprite_array
generic map
generic map
(
N_SPRITES => 64,
DELAY => 7
N_SPRITES => PACE_VIDEO_NUM_SPRITES,
DELAY => PACE_VIDEO_PIPELINE_DELAY
)
port map
(
reset => video_i.reset,
reg_i => sprite_reg_i,
video_ctl => from_video_ctl,
graphics_i => graphics_i,
row_a => sprite_ctl_o_s.a,
row_d => sprite_ctl_i.d,
rgb => sprite_ctl_o_s.rgb,
set => sprite_ctl_o_s.set,
pri => sprite_pri,
spr0_set => spr0_hit
reset => video_i.reset,
-- register interface
reg_i => sprite_reg_i,
-- video control signals
video_ctl => from_video_ctl,
graphics_i => graphics_i,
row_a => sprite_ctl_o_s.a,
row_d => sprite_ctl_i.d,
rgb => sprite_ctl_o_s.rgb,
set => sprite_ctl_o_s.set,
pri => sprite_pri,
spr0_set => spr0_hit
);
end generate GEN_SPRITES;
sprite_ctl_o <= sprite_ctl_o_s;
end SYN;

View File

@ -1,34 +1,18 @@
library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.std_logic_unsigned.all;
use ieee.numeric_std.all;
library work;
use work.pace_pkg.all;
use work.platform_pkg.all;
use work.platform_variant_pkg.all;
use work.video_controller_pkg.all;
entity BITMAP_1 is
generic
(
DELAY : integer
);
port
(
reset : in std_logic;
--
-- Moon Patrol Cityscape Renderer
--
-- video control signals
video_ctl : in from_VIDEO_CTL_t;
-- bitmap controller signals
ctl_i : in to_BITMAP_CTL_t;
ctl_o : out from_BITMAP_CTL_t;
graphics_i : in to_GRAPHICS_t
);
end entity BITMAP_1;
architecture bit1 of BITMAP_1 is
architecture BITMAP_1 of bitmapCtl is
alias clk : std_logic is video_ctl.clk;
alias clk_en : std_logic is video_ctl.clk_ena;
@ -37,16 +21,22 @@ architecture bit1 of BITMAP_1 is
alias vblank : std_logic is video_ctl.vblank;
alias x : std_logic_vector(video_ctl.x'range) is video_ctl.x;
alias y : std_logic_vector(video_ctl.y'range) is video_ctl.y;
alias rgb : RGB_t is ctl_o.rgb;
alias rgb : RGB_t is ctl_o.rgb;
alias m52_bg1xpos : std_logic_vector(7 downto 0) is graphics_i.bit16(0)(15 downto 8);
alias m52_bg1ypos : std_logic_vector(7 downto 0) is graphics_i.bit16(0)(7 downto 0);
-- alias m52_bg2xpos : std_logic_vector(7 downto 0) is graphics_i.bit16(1)(15 downto 8);
-- alias m52_bg2ypos : std_logic_vector(7 downto 0) is graphics_i.bit16(1)(7 downto 0);
alias m52_bgcontrol : std_logic_vector(7 downto 0) is graphics_i.bit16(2)(7 downto 0);
begin
process (clk, reset)
variable y_r : std_logic_vector(y'range);
-- ensure bgy won't wrap on the screen
variable bgy : unsigned(7 downto 0);
-- must wrap at 256!!!
variable bgx : unsigned(7 downto 0);
variable bitmap_d_r : std_logic_vector(7 downto 0);
variable pel : std_logic_vector(1 downto 0);
@ -108,4 +98,4 @@ begin
-- unused
ctl_o.a(ctl_o.a'left downto 12) <= (others => '0');
end architecture bit1;
end architecture BITMAP_1;

View File

@ -1,34 +1,18 @@
library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.std_logic_unsigned.all;
use ieee.numeric_std.all;
library work;
use work.pace_pkg.all;
use work.platform_pkg.all;
use work.platform_variant_pkg.all;
use work.video_controller_pkg.all;
entity BITMAP_2 is
generic
(
DELAY : integer
);
port
(
reset : in std_logic;
--
-- Moon Patrol Hills Renderer
--
-- video control signals
video_ctl : in from_VIDEO_CTL_t;
-- bitmap controller signals
ctl_i : in to_BITMAP_CTL_t;
ctl_o : out from_BITMAP_CTL_t;
graphics_i : in to_GRAPHICS_t
);
end entity BITMAP_2;
architecture bit2 of BITMAP_2 is
architecture BITMAP_2 of bitmapCtl is
alias clk : std_logic is video_ctl.clk;
alias clk_en : std_logic is video_ctl.clk_ena;
@ -37,16 +21,22 @@ architecture bit2 of BITMAP_2 is
alias vblank : std_logic is video_ctl.vblank;
alias x : std_logic_vector(video_ctl.x'range) is video_ctl.x;
alias y : std_logic_vector(video_ctl.y'range) is video_ctl.y;
alias rgb : RGB_t is ctl_o.rgb;
alias rgb : RGB_t is ctl_o.rgb;
alias m52_bg1xpos : std_logic_vector(7 downto 0) is graphics_i.bit16(0)(15 downto 8);
alias m52_bg1ypos : std_logic_vector(7 downto 0) is graphics_i.bit16(0)(7 downto 0);
-- alias m52_bg2xpos : std_logic_vector(7 downto 0) is graphics_i.bit16(1)(15 downto 8);
-- alias m52_bg2ypos : std_logic_vector(7 downto 0) is graphics_i.bit16(1)(7 downto 0);
alias m52_bgcontrol : std_logic_vector(7 downto 0) is graphics_i.bit16(2)(7 downto 0);
begin
process (clk, reset)
variable y_r : std_logic_vector(y'range);
-- ensure bgy won't wrap on the screen
variable bgy : unsigned(7 downto 0);
-- must wrap at 256!!!
variable bgx : unsigned(7 downto 0);
variable bitmap_d_r : std_logic_vector(7 downto 0);
variable pel : std_logic_vector(1 downto 0);
@ -108,4 +98,4 @@ begin
-- unused
ctl_o.a(ctl_o.a'left downto 12) <= (others => '0');
end architecture bit2;
end architecture BITMAP_2;

View File

@ -1,34 +1,18 @@
library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.std_logic_unsigned.all;
use ieee.numeric_std.all;
library work;
use work.pace_pkg.all;
use work.platform_pkg.all;
use work.platform_variant_pkg.all;
use work.video_controller_pkg.all;
entity BITMAP_3 is
generic
(
DELAY : integer
);
port
(
reset : in std_logic;
--
-- Moon Patrol Mountains Renderer
--
-- video control signals
video_ctl : in from_VIDEO_CTL_t;
-- bitmap controller signals
ctl_i : in to_BITMAP_CTL_t;
ctl_o : out from_BITMAP_CTL_t;
graphics_i : in to_GRAPHICS_t
);
end entity BITMAP_3;
architecture bit3 of BITMAP_3 is
architecture BITMAP_3 of bitmapCtl is
alias clk : std_logic is video_ctl.clk;
alias clk_en : std_logic is video_ctl.clk_ena;
@ -37,7 +21,11 @@ architecture bit3 of BITMAP_3 is
alias vblank : std_logic is video_ctl.vblank;
alias x : std_logic_vector(video_ctl.x'range) is video_ctl.x;
alias y : std_logic_vector(video_ctl.y'range) is video_ctl.y;
alias rgb : RGB_t is ctl_o.rgb;
-- alias m52_bg1xpos : std_logic_vector(7 downto 0) is graphics_i.bit16(0)(15 downto 8);
-- alias m52_bg1ypos : std_logic_vector(7 downto 0) is graphics_i.bit16(0)(7 downto 0);
alias m52_bg2xpos : std_logic_vector(7 downto 0) is graphics_i.bit16(1)(15 downto 8);
alias m52_bg2ypos : std_logic_vector(7 downto 0) is graphics_i.bit16(1)(7 downto 0);
alias m52_bgcontrol : std_logic_vector(7 downto 0) is graphics_i.bit16(2)(7 downto 0);
@ -46,7 +34,9 @@ begin
process (clk, reset)
variable y_r : std_logic_vector(y'range);
-- ensure bgy won't wrap on the screen
variable bgy : unsigned(7 downto 0);
-- must wrap at 256!!!
variable bgx : unsigned(7 downto 0);
variable bitmap_d_r : std_logic_vector(7 downto 0);
variable pel : std_logic_vector(1 downto 0);
@ -108,4 +98,4 @@ begin
-- unused
ctl_o.a(ctl_o.a'left downto 12) <= (others => '0');
end architecture bit3;
end architecture BITMAP_3;

View File

@ -6,7 +6,8 @@ use ieee.numeric_std.all;
library work;
use work.pace_pkg.all;
use work.video_controller_pkg.all;
use work.platform_pkg.all;
use work.project_pkg.all;
entity bitmapCtl is
generic

View File

@ -1,2 +0,0 @@
`define BUILD_DATE "190305"
`define BUILD_TIME "212703"

View File

@ -1,454 +0,0 @@
//
//
// Copyright (c) 2012-2013 Ludvig Strigeus
// Copyright (c) 2017 Sorgelig
//
// This program is GPL Licensed. See COPYING for the full license.
//
//
////////////////////////////////////////////////////////////////////////////////////////////////////////
// synopsys translate_off
`timescale 1 ps / 1 ps
// synopsys translate_on
`define BITS_TO_FIT(N) ( \
N <= 2 ? 0 : \
N <= 4 ? 1 : \
N <= 8 ? 2 : \
N <= 16 ? 3 : \
N <= 32 ? 4 : \
N <= 64 ? 5 : \
N <= 128 ? 6 : \
N <= 256 ? 7 : \
N <= 512 ? 8 : \
N <=1024 ? 9 : 10 )
module hq2x_in #(parameter LENGTH, parameter DWIDTH)
(
input clk,
input [AWIDTH:0] rdaddr,
input rdbuf,
output[DWIDTH:0] q,
input [AWIDTH:0] wraddr,
input wrbuf,
input [DWIDTH:0] data,
input wren
);
localparam AWIDTH = `BITS_TO_FIT(LENGTH);
wire [DWIDTH:0] out[2];
assign q = out[rdbuf];
hq2x_buf #(.NUMWORDS(LENGTH), .AWIDTH(AWIDTH), .DWIDTH(DWIDTH)) buf0(clk,data,rdaddr,wraddr,wren && (wrbuf == 0),out[0]);
hq2x_buf #(.NUMWORDS(LENGTH), .AWIDTH(AWIDTH), .DWIDTH(DWIDTH)) buf1(clk,data,rdaddr,wraddr,wren && (wrbuf == 1),out[1]);
endmodule
module hq2x_out #(parameter LENGTH, parameter DWIDTH)
(
input clk,
input [AWIDTH:0] rdaddr,
input [1:0] rdbuf,
output[DWIDTH:0] q,
input [AWIDTH:0] wraddr,
input [1:0] wrbuf,
input [DWIDTH:0] data,
input wren
);
localparam AWIDTH = `BITS_TO_FIT(LENGTH*2);
wire [DWIDTH:0] out[4];
assign q = out[rdbuf];
hq2x_buf #(.NUMWORDS(LENGTH*2), .AWIDTH(AWIDTH), .DWIDTH(DWIDTH)) buf0(clk,data,rdaddr,wraddr,wren && (wrbuf == 0),out[0]);
hq2x_buf #(.NUMWORDS(LENGTH*2), .AWIDTH(AWIDTH), .DWIDTH(DWIDTH)) buf1(clk,data,rdaddr,wraddr,wren && (wrbuf == 1),out[1]);
hq2x_buf #(.NUMWORDS(LENGTH*2), .AWIDTH(AWIDTH), .DWIDTH(DWIDTH)) buf2(clk,data,rdaddr,wraddr,wren && (wrbuf == 2),out[2]);
hq2x_buf #(.NUMWORDS(LENGTH*2), .AWIDTH(AWIDTH), .DWIDTH(DWIDTH)) buf3(clk,data,rdaddr,wraddr,wren && (wrbuf == 3),out[3]);
endmodule
module hq2x_buf #(parameter NUMWORDS, parameter AWIDTH, parameter DWIDTH)
(
input clock,
input [DWIDTH:0] data,
input [AWIDTH:0] rdaddress,
input [AWIDTH:0] wraddress,
input wren,
output [DWIDTH:0] q
);
altsyncram altsyncram_component (
.address_a (wraddress),
.clock0 (clock),
.data_a (data),
.wren_a (wren),
.address_b (rdaddress),
.q_b(q),
.aclr0 (1'b0),
.aclr1 (1'b0),
.addressstall_a (1'b0),
.addressstall_b (1'b0),
.byteena_a (1'b1),
.byteena_b (1'b1),
.clock1 (1'b1),
.clocken0 (1'b1),
.clocken1 (1'b1),
.clocken2 (1'b1),
.clocken3 (1'b1),
.data_b ({(DWIDTH+1){1'b1}}),
.eccstatus (),
.q_a (),
.rden_a (1'b1),
.rden_b (1'b1),
.wren_b (1'b0));
defparam
altsyncram_component.address_aclr_b = "NONE",
altsyncram_component.address_reg_b = "CLOCK0",
altsyncram_component.clock_enable_input_a = "BYPASS",
altsyncram_component.clock_enable_input_b = "BYPASS",
altsyncram_component.clock_enable_output_b = "BYPASS",
altsyncram_component.intended_device_family = "Cyclone III",
altsyncram_component.lpm_type = "altsyncram",
altsyncram_component.numwords_a = NUMWORDS,
altsyncram_component.numwords_b = NUMWORDS,
altsyncram_component.operation_mode = "DUAL_PORT",
altsyncram_component.outdata_aclr_b = "NONE",
altsyncram_component.outdata_reg_b = "UNREGISTERED",
altsyncram_component.power_up_uninitialized = "FALSE",
altsyncram_component.read_during_write_mode_mixed_ports = "DONT_CARE",
altsyncram_component.widthad_a = AWIDTH+1,
altsyncram_component.widthad_b = AWIDTH+1,
altsyncram_component.width_a = DWIDTH+1,
altsyncram_component.width_b = DWIDTH+1,
altsyncram_component.width_byteena_a = 1;
endmodule
////////////////////////////////////////////////////////////////////////////////////////////////////////
module DiffCheck
(
input [17:0] rgb1,
input [17:0] rgb2,
output result
);
wire [5:0] r = rgb1[5:1] - rgb2[5:1];
wire [5:0] g = rgb1[11:7] - rgb2[11:7];
wire [5:0] b = rgb1[17:13] - rgb2[17:13];
wire [6:0] t = $signed(r) + $signed(b);
wire [6:0] gx = {g[5], g};
wire [7:0] y = $signed(t) + $signed(gx);
wire [6:0] u = $signed(r) - $signed(b);
wire [7:0] v = $signed({g, 1'b0}) - $signed(t);
// if y is inside (-24..24)
wire y_inside = (y < 8'h18 || y >= 8'he8);
// if u is inside (-4, 4)
wire u_inside = (u < 7'h4 || u >= 7'h7c);
// if v is inside (-6, 6)
wire v_inside = (v < 8'h6 || v >= 8'hfA);
assign result = !(y_inside && u_inside && v_inside);
endmodule
module InnerBlend
(
input [8:0] Op,
input [5:0] A,
input [5:0] B,
input [5:0] C,
output [5:0] O
);
function [8:0] mul6x3;
input [5:0] op1;
input [2:0] op2;
begin
mul6x3 = 9'd0;
if(op2[0]) mul6x3 = mul6x3 + op1;
if(op2[1]) mul6x3 = mul6x3 + {op1, 1'b0};
if(op2[2]) mul6x3 = mul6x3 + {op1, 2'b00};
end
endfunction
wire OpOnes = Op[4];
wire [8:0] Amul = mul6x3(A, Op[7:5]);
wire [8:0] Bmul = mul6x3(B, {Op[3:2], 1'b0});
wire [8:0] Cmul = mul6x3(C, {Op[1:0], 1'b0});
wire [8:0] At = Amul;
wire [8:0] Bt = (OpOnes == 0) ? Bmul : {3'b0, B};
wire [8:0] Ct = (OpOnes == 0) ? Cmul : {3'b0, C};
wire [9:0] Res = {At, 1'b0} + Bt + Ct;
assign O = Op[8] ? A : Res[9:4];
endmodule
module Blend
(
input [5:0] rule,
input disable_hq2x,
input [17:0] E,
input [17:0] A,
input [17:0] B,
input [17:0] D,
input [17:0] F,
input [17:0] H,
output [17:0] Result
);
reg [1:0] input_ctrl;
reg [8:0] op;
localparam BLEND0 = 9'b1_xxx_x_xx_xx; // 0: A
localparam BLEND1 = 9'b0_110_0_10_00; // 1: (A * 12 + B * 4) >> 4
localparam BLEND2 = 9'b0_100_0_10_10; // 2: (A * 8 + B * 4 + C * 4) >> 4
localparam BLEND3 = 9'b0_101_0_10_01; // 3: (A * 10 + B * 4 + C * 2) >> 4
localparam BLEND4 = 9'b0_110_0_01_01; // 4: (A * 12 + B * 2 + C * 2) >> 4
localparam BLEND5 = 9'b0_010_0_11_11; // 5: (A * 4 + (B + C) * 6) >> 4
localparam BLEND6 = 9'b0_111_1_xx_xx; // 6: (A * 14 + B + C) >> 4
localparam AB = 2'b00;
localparam AD = 2'b01;
localparam DB = 2'b10;
localparam BD = 2'b11;
wire is_diff;
DiffCheck diff_checker(rule[1] ? B : H, rule[0] ? D : F, is_diff);
always @* begin
case({!is_diff, rule[5:2]})
1,17: {op, input_ctrl} = {BLEND1, AB};
2,18: {op, input_ctrl} = {BLEND1, DB};
3,19: {op, input_ctrl} = {BLEND1, BD};
4,20: {op, input_ctrl} = {BLEND2, DB};
5,21: {op, input_ctrl} = {BLEND2, AB};
6,22: {op, input_ctrl} = {BLEND2, AD};
8: {op, input_ctrl} = {BLEND0, 2'bxx};
9: {op, input_ctrl} = {BLEND0, 2'bxx};
10: {op, input_ctrl} = {BLEND0, 2'bxx};
11: {op, input_ctrl} = {BLEND1, AB};
12: {op, input_ctrl} = {BLEND1, AB};
13: {op, input_ctrl} = {BLEND1, AB};
14: {op, input_ctrl} = {BLEND1, DB};
15: {op, input_ctrl} = {BLEND1, BD};
24: {op, input_ctrl} = {BLEND2, DB};
25: {op, input_ctrl} = {BLEND5, DB};
26: {op, input_ctrl} = {BLEND6, DB};
27: {op, input_ctrl} = {BLEND2, DB};
28: {op, input_ctrl} = {BLEND4, DB};
29: {op, input_ctrl} = {BLEND5, DB};
30: {op, input_ctrl} = {BLEND3, BD};
31: {op, input_ctrl} = {BLEND3, DB};
default: {op, input_ctrl} = 11'bx;
endcase
// Setting op[8] effectively disables HQ2X because blend will always return E.
if (disable_hq2x) op[8] = 1;
end
// Generate inputs to the inner blender. Valid combinations.
// 00: E A B
// 01: E A D
// 10: E D B
// 11: E B D
wire [17:0] Input1 = E;
wire [17:0] Input2 = !input_ctrl[1] ? A :
!input_ctrl[0] ? D : B;
wire [17:0] Input3 = !input_ctrl[0] ? B : D;
InnerBlend inner_blend1(op, Input1[5:0], Input2[5:0], Input3[5:0], Result[5:0]);
InnerBlend inner_blend2(op, Input1[11:6], Input2[11:6], Input3[11:6], Result[11:6]);
InnerBlend inner_blend3(op, Input1[17:12], Input2[17:12], Input3[17:12], Result[17:12]);
endmodule
////////////////////////////////////////////////////////////////////////////////////////////////////
module Hq2x #(parameter LENGTH, parameter HALF_DEPTH)
(
input clk,
input ce_x4,
input [DWIDTH:0] inputpixel,
input mono,
input disable_hq2x,
input reset_frame,
input reset_line,
input [1:0] read_y,
input [AWIDTH+1:0] read_x,
output [DWIDTH:0] outpixel
);
localparam AWIDTH = `BITS_TO_FIT(LENGTH);
localparam DWIDTH = HALF_DEPTH ? 8 : 17;
wire [5:0] hqTable[256] = '{
19, 19, 26, 11, 19, 19, 26, 11, 23, 15, 47, 35, 23, 15, 55, 39,
19, 19, 26, 58, 19, 19, 26, 58, 23, 15, 35, 35, 23, 15, 7, 35,
19, 19, 26, 11, 19, 19, 26, 11, 23, 15, 55, 39, 23, 15, 51, 43,
19, 19, 26, 58, 19, 19, 26, 58, 23, 15, 51, 35, 23, 15, 7, 43,
19, 19, 26, 11, 19, 19, 26, 11, 23, 61, 35, 35, 23, 61, 51, 35,
19, 19, 26, 11, 19, 19, 26, 11, 23, 15, 51, 35, 23, 15, 51, 35,
19, 19, 26, 11, 19, 19, 26, 11, 23, 61, 7, 35, 23, 61, 7, 43,
19, 19, 26, 11, 19, 19, 26, 58, 23, 15, 51, 35, 23, 61, 7, 43,
19, 19, 26, 11, 19, 19, 26, 11, 23, 15, 47, 35, 23, 15, 55, 39,
19, 19, 26, 11, 19, 19, 26, 11, 23, 15, 51, 35, 23, 15, 51, 35,
19, 19, 26, 11, 19, 19, 26, 11, 23, 15, 55, 39, 23, 15, 51, 43,
19, 19, 26, 11, 19, 19, 26, 11, 23, 15, 51, 39, 23, 15, 7, 43,
19, 19, 26, 11, 19, 19, 26, 11, 23, 15, 51, 35, 23, 15, 51, 39,
19, 19, 26, 11, 19, 19, 26, 11, 23, 15, 51, 35, 23, 15, 7, 35,
19, 19, 26, 11, 19, 19, 26, 11, 23, 15, 51, 35, 23, 15, 7, 43,
19, 19, 26, 11, 19, 19, 26, 11, 23, 15, 7, 35, 23, 15, 7, 43
};
reg [17:0] Prev0, Prev1, Prev2, Curr0, Curr1, Next0, Next1, Next2;
reg [17:0] A, B, D, F, G, H;
reg [7:0] pattern, nextpatt;
reg [1:0] i;
reg [7:0] y;
wire curbuf = y[0];
reg prevbuf = 0;
wire iobuf = !curbuf;
wire diff0, diff1;
DiffCheck diffcheck0(Curr1, (i == 0) ? Prev0 : (i == 1) ? Curr0 : (i == 2) ? Prev2 : Next1, diff0);
DiffCheck diffcheck1(Curr1, (i == 0) ? Prev1 : (i == 1) ? Next0 : (i == 2) ? Curr2 : Next2, diff1);
wire [7:0] new_pattern = {diff1, diff0, pattern[7:2]};
wire [17:0] X = (i == 0) ? A : (i == 1) ? Prev1 : (i == 2) ? Next1 : G;
wire [17:0] blend_result;
Blend blender(hqTable[nextpatt], disable_hq2x, Curr0, X, B, D, F, H, blend_result);
reg Curr2_addr1;
reg [AWIDTH:0] Curr2_addr2;
wire [17:0] Curr2 = HALF_DEPTH ? h2rgb(Curr2tmp) : Curr2tmp;
wire [DWIDTH:0] Curr2tmp;
reg [AWIDTH:0] wrin_addr2;
reg [DWIDTH:0] wrpix;
reg wrin_en;
function [17:0] h2rgb;
input [8:0] v;
begin
h2rgb = mono ? {v[5:3],v[2:0], v[5:3],v[2:0], v[5:3],v[2:0]} : {v[8:6],v[8:6],v[5:3],v[5:3],v[2:0],v[2:0]};
end
endfunction
function [8:0] rgb2h;
input [17:0] v;
begin
rgb2h = mono ? {3'b000, v[17:15], v[14:12]} : {v[17:15], v[11:9], v[5:3]};
end
endfunction
hq2x_in #(.LENGTH(LENGTH), .DWIDTH(DWIDTH)) hq2x_in
(
.clk(clk),
.rdaddr(Curr2_addr2),
.rdbuf(Curr2_addr1),
.q(Curr2tmp),
.wraddr(wrin_addr2),
.wrbuf(iobuf),
.data(wrpix),
.wren(wrin_en)
);
reg [1:0] wrout_addr1;
reg [AWIDTH+1:0] wrout_addr2;
reg wrout_en;
reg [DWIDTH:0] wrdata;
hq2x_out #(.LENGTH(LENGTH), .DWIDTH(DWIDTH)) hq2x_out
(
.clk(clk),
.rdaddr(read_x),
.rdbuf(read_y),
.q(outpixel),
.wraddr(wrout_addr2),
.wrbuf(wrout_addr1),
.data(wrdata),
.wren(wrout_en)
);
always @(posedge clk) begin
reg [AWIDTH:0] offs;
reg old_reset_line;
reg old_reset_frame;
wrout_en <= 0;
wrin_en <= 0;
if(ce_x4) begin
pattern <= new_pattern;
if(~&offs) begin
if (i == 0) begin
Curr2_addr1 <= prevbuf;
Curr2_addr2 <= offs;
end
if (i == 1) begin
Prev2 <= Curr2;
Curr2_addr1 <= curbuf;
Curr2_addr2 <= offs;
end
if (i == 2) begin
Next2 <= HALF_DEPTH ? h2rgb(inputpixel) : inputpixel;
wrpix <= inputpixel;
wrin_addr2 <= offs;
wrin_en <= 1;
end
if (i == 3) begin
offs <= offs + 1'd1;
end
if(HALF_DEPTH) wrdata <= rgb2h(blend_result);
else wrdata <= blend_result;
wrout_addr1 <= {curbuf, i[1]};
wrout_addr2 <= {offs, i[1]^i[0]};
wrout_en <= 1;
end
if(i==3) begin
nextpatt <= {new_pattern[7:6], new_pattern[3], new_pattern[5], new_pattern[2], new_pattern[4], new_pattern[1:0]};
{A, G} <= {Prev0, Next0};
{B, F, H, D} <= {Prev1, Curr2, Next1, Curr0};
{Prev0, Prev1} <= {Prev1, Prev2};
{Curr0, Curr1} <= {Curr1, Curr2};
{Next0, Next1} <= {Next1, Next2};
end else begin
nextpatt <= {nextpatt[5], nextpatt[3], nextpatt[0], nextpatt[6], nextpatt[1], nextpatt[7], nextpatt[4], nextpatt[2]};
{B, F, H, D} <= {F, H, D, B};
end
i <= i + 1'b1;
if(old_reset_line && ~reset_line) begin
old_reset_frame <= reset_frame;
offs <= 0;
i <= 0;
y <= y + 1'd1;
prevbuf <= curbuf;
if(old_reset_frame & ~reset_frame) begin
y <= 0;
prevbuf <= 0;
end
end
old_reset_line <= reset_line;
end
end
endmodule // Hq2x

View File

@ -96,7 +96,6 @@ module mist_io #(parameter PS2DIV=100)
localparam conf_str = {
"Moon Patr.;;",
// "O2,HQ2x,On,Off;",no effect
"O34,Scandoubler Fx,None,CRT 25%,CRT 50%,CRT 75%;",
"T5,Reset;",
"V,v1.11.",`BUILD_DATE

View File

@ -34,8 +34,8 @@ architecture SYN of mpatrol is
signal init : std_logic := '1';
signal clk_sys : std_logic;
signal clk_aud : std_logic;
signal clk_vid : std_logic;
signal clk_osd : std_logic;
signal clkrst_i : from_CLKRST_t;
signal buttons_i : from_BUTTONS_t;
signal switches_i : from_SWITCHES_t;
@ -53,18 +53,30 @@ architecture SYN of mpatrol is
signal buttons : std_logic_vector(1 downto 0);
signal ps2_kbd_clk : std_logic;
signal ps2_kbd_data : std_logic;
signal scan_disable : std_logic;
signal ypbpr : std_logic;
signal r : std_logic_vector(5 downto 0);
signal g : std_logic_vector(5 downto 0);
signal b : std_logic_vector(5 downto 0);
signal hs : std_logic;
signal vs : std_logic;
signal scandoubler_disable : std_logic;
signal ypbpr : std_logic;
signal reset : std_logic;
signal clock_3p58 : std_logic;
signal audio_out : std_logic_vector(11 downto 0);
signal sound_data : std_logic_vector(7 downto 0);
signal sd_r : std_logic_vector(5 downto 0);
signal sd_g : std_logic_vector(5 downto 0);
signal sd_b : std_logic_vector(5 downto 0);
signal sd_hs : std_logic;
signal sd_vs : std_logic;
signal osd_red_i : std_logic_vector(5 downto 0);
signal osd_green_i : std_logic_vector(5 downto 0);
signal osd_blue_i : std_logic_vector(5 downto 0);
signal osd_vs_i : std_logic;
signal osd_hs_i : std_logic;
signal osd_red_o : std_logic_vector(5 downto 0);
signal osd_green_o : std_logic_vector(5 downto 0);
signal osd_blue_o : std_logic_vector(5 downto 0);
signal vga_y_o : std_logic_vector(5 downto 0);
signal vga_pb_o : std_logic_vector(5 downto 0);
signal vga_pr_o : std_logic_vector(5 downto 0);
component keyboard
port (
clk :in STD_LOGIC;
@ -84,8 +96,8 @@ component mist_io
SPI_SS2 :in STD_LOGIC;
switches :out STD_LOGIC_VECTOR(1 downto 0);
buttons :out STD_LOGIC_VECTOR(1 downto 0);
scan_disable :out STD_LOGIC;
ypbpr :out STD_LOGIC;
scan_disable :out STD_LOGIC;
ypbpr :out STD_LOGIC;
joystick_1 :out STD_LOGIC_VECTOR(7 downto 0);
joystick_0 :out STD_LOGIC_VECTOR(7 downto 0);
status :out STD_LOGIC_VECTOR(31 downto 0);
@ -93,48 +105,75 @@ component mist_io
ps2_kbd_data :out STD_LOGIC);
end component;
component video_mist
port (
clk_sys :in STD_LOGIC;
ce_pix :in STD_LOGIC;
ce_pix_actual :in STD_LOGIC;
SPI_SCK :in STD_LOGIC;
SPI_SS3 :in STD_LOGIC;
SPI_DI :in STD_LOGIC;
R :in STD_LOGIC_VECTOR(5 downto 0);
G :in STD_LOGIC_VECTOR(5 downto 0);
B :in STD_LOGIC_VECTOR(5 downto 0);
HSync :in STD_LOGIC;
VSync :in STD_LOGIC;
VGA_R :out STD_LOGIC_VECTOR(5 downto 0);
VGA_G :out STD_LOGIC_VECTOR(5 downto 0);
VGA_B :out STD_LOGIC_VECTOR(5 downto 0);
VGA_HS :out STD_LOGIC;
VGA_VS :out STD_LOGIC;
scan_disable :in STD_LOGIC;
scanlines :in STD_LOGIC_VECTOR(1 downto 0);
hq2x :in STD_LOGIC;
ypbpr_full :in STD_LOGIC;
line_start :in STD_LOGIC;
mono :in STD_LOGIC);
end component;
component scandoubler
port (
clk_sys : in std_logic;
scanlines : in std_logic_vector(1 downto 0);
hs_in : in std_logic;
vs_in : in std_logic;
r_in : in std_logic_vector(5 downto 0);
g_in : in std_logic_vector(5 downto 0);
b_in : in std_logic_vector(5 downto 0);
hs_out : out std_logic;
vs_out : out std_logic;
r_out : out std_logic_vector(5 downto 0);
g_out : out std_logic_vector(5 downto 0);
b_out : out std_logic_vector(5 downto 0)
);
end component scandoubler;
component osd
generic ( OSD_COLOR : integer := 1 ); -- blue
port (
clk_sys : in std_logic;
R_in : in std_logic_vector(5 downto 0);
G_in : in std_logic_vector(5 downto 0);
B_in : in std_logic_vector(5 downto 0);
HSync : in std_logic;
VSync : in std_logic;
R_out : out std_logic_vector(5 downto 0);
G_out : out std_logic_vector(5 downto 0);
B_out : out std_logic_vector(5 downto 0);
SPI_SCK : in std_logic;
SPI_SS3 : in std_logic;
SPI_DI : in std_logic
);
end component osd;
COMPONENT rgb2ypbpr
PORT (
red : IN std_logic_vector(5 DOWNTO 0);
green : IN std_logic_vector(5 DOWNTO 0);
blue : IN std_logic_vector(5 DOWNTO 0);
y : OUT std_logic_vector(5 DOWNTO 0);
pb : OUT std_logic_vector(5 DOWNTO 0);
pr : OUT std_logic_vector(5 DOWNTO 0)
);
END COMPONENT;
begin
--CLOCK
Clock_inst : entity work.Clock
port map (
inclk0 => CLOCK_27,
c0 => clock_3p58,--3.58
c1 => clk_osd,--10
c2 => clk_sys,--30
c3 => clk_vid--40
);
inclk0 => CLOCK_27,
c0 => clk_aud, -- 3.58
c1 => clk_sys, -- 6
c2 => clk_vid -- 24
);
clkrst_i.clk(0) <= clk_sys;
clkrst_i.clk(1) <= clk_sys;
video_i.clk <= clk_sys;
video_i.clk_ena <= '1';
video_i.reset <= clkrst_i.rst(1);
clkrst_i.clk_ref <= CLOCK_27;
clkrst_i.clk(0) <= clk_sys;
clkrst_i.clk(1) <= clk_vid;
--RESET
process (clk_sys)
variable count : std_logic_vector (11 downto 0) := (others => '0');
@ -177,47 +216,15 @@ mist_io_inst : mist_io
SPI_SS2 => SPI_SS2,
switches => switches,
buttons => buttons,
scan_disable => scan_disable,
ypbpr => ypbpr,
scan_disable => scandoubler_disable,
ypbpr => ypbpr,
joystick_1 => joystick2,
joystick_0 => joystick1,
status => status,
ps2_kbd_clk => ps2_kbd_clk,
ps2_kbd_data => ps2_kbd_data
);
video_mist_inst : video_mist
port map (
clk_sys => clk_sys,
ce_pix => clk_osd,
ce_pix_actual => clk_osd,
SPI_SCK => SPI_SCK,
SPI_SS3 => SPI_SS3,
SPI_DI => SPI_DI,
R => video_o.rgb.r(9 downto 4),
G => video_o.rgb.g(9 downto 4),
B => video_o.rgb.b(9 downto 4),
HSync => video_o.hsync,
VSync => video_o.vsync,
VGA_R => VGA_R,
VGA_G => VGA_G,
VGA_B => VGA_B,
VGA_HS => VGA_HS,
VGA_VS => VGA_VS,
--ToDo
scan_disable => '1',--scan_disable,
scanlines => status(4 downto 3),
hq2x => status(2),
ypbpr_full => '1',
line_start => '0',
mono => '0'
);
video_i.clk <= clk_vid;
video_i.clk_ena <= '1';
video_i.reset <= clkrst_i.rst(1);
u_keyboard : keyboard
port map(
clk => clk_sys,
@ -258,7 +265,7 @@ u_keyboard : keyboard
moon_patrol_sound_board : entity work.moon_patrol_sound_board
port map(
clock_3p58 => clock_3p58,
clock_3p58 => clk_aud,
reset => clkrst_i.arst,
select_sound => sound_data,
audio_out => audio_out,
@ -266,21 +273,18 @@ moon_patrol_sound_board : entity work.moon_patrol_sound_board
);
dac : entity work.dac
port map (
clk_i => clk_sys,
res_n_i => '1',
dac_i => audio_out,
dac_o => audio
port map (
clk_i => clk_aud,
res_n_i => '1',
dac_i => audio_out,
dac_o => audio
);
AUDIO_R <= audio;
AUDIO_L <= audio;
AUDIO_R <= audio;
AUDIO_L <= audio;
pace_inst : entity work.pace
port map
(
pace_inst : entity work.pace
port map (
clkrst_i => clkrst_i,
buttons_i => buttons_i,
switches_i => switches_i,
@ -289,5 +293,66 @@ dac : entity work.dac
video_i => video_i,
video_o => video_o,
sound_data_o => sound_data
);
);
scandoubler_inst: scandoubler
port map (
clk_sys => clk_vid,
scanlines => status(4 downto 3),
hs_in => video_o.hsync,
vs_in => video_o.vsync,
r_in => video_o.rgb.r(9 downto 4),
g_in => video_o.rgb.g(9 downto 4),
b_in => video_o.rgb.b(9 downto 4),
hs_out => sd_hs,
vs_out => sd_vs,
r_out => sd_r,
g_out => sd_g,
b_out => sd_b
);
osd_inst: osd
port map (
clk_sys => clk_vid,
SPI_SCK => SPI_SCK,
SPI_SS3 => SPI_SS3,
SPI_DI => SPI_DI,
R_in => osd_red_i,
G_in => osd_green_i,
B_in => osd_blue_i,
HSync => osd_hs_i,
VSync => osd_vs_i,
R_out => osd_red_o,
G_out => osd_green_o,
B_out => osd_blue_o
);
rgb2component: component rgb2ypbpr
port map (
red => osd_red_o,
green => osd_green_o,
blue => osd_blue_o,
y => vga_y_o,
pb => vga_pb_o,
pr => vga_pr_o
);
osd_red_i <= video_o.rgb.r(9 downto 4) when scandoubler_disable = '1' else sd_r;
osd_green_i <= video_o.rgb.g(9 downto 4) when scandoubler_disable = '1' else sd_g;
osd_blue_i <= video_o.rgb.b(9 downto 4) when scandoubler_disable = '1' else sd_b;
osd_hs_i <= video_o.hsync when scandoubler_disable = '1' else sd_hs;
osd_vs_i <= video_o.vsync when scandoubler_disable = '1' else sd_vs;
-- If 15kHz Video - composite sync to VGA_HS and VGA_VS high for MiST RGB cable
VGA_HS <= not (video_o.hsync xor video_o.vsync) when scandoubler_disable='1' else not (sd_hs xor sd_vs) when ypbpr='1' else sd_hs;
VGA_VS <= '1' when scandoubler_disable='1' or ypbpr='1' else sd_vs;
VGA_R <= vga_pr_o when ypbpr='1' else osd_red_o;
VGA_G <= vga_y_o when ypbpr='1' else osd_green_o;
VGA_B <= vga_pb_o when ypbpr='1' else osd_blue_o;
--
end SYN;

View File

@ -6,8 +6,9 @@ library work;
use work.pace_pkg.all;
use work.video_controller_pkg.all;
use work.sprite_pkg.all;
--use work.platform_pkg.all;
--use work.project_pkg.all;
use work.target_pkg.all;
use work.platform_pkg.all;
use work.project_pkg.all;
entity PACE is
port
@ -39,8 +40,8 @@ end entity PACE;
architecture SYN of PACE is
constant CLK_1US_COUNTS : integer :=
integer(27 * 50 / 20);
constant CLK_1US_COUNTS : integer :=
integer(PACE_CLKIN0 * PACE_CLK0_MULTIPLY_BY / PACE_CLK0_DIVIDE_BY);
signal mapped_inputs : from_MAPPED_INPUTS_t(0 to 6-1);

View File

@ -150,6 +150,13 @@ package pace_pkg is
type from_MAPPED_INPUTS_t is array (natural range <>) of in8_t;
-- create a constant that automatically determines
-- whether this is simulation or synthesis
constant IN_SIMULATION : BOOLEAN := false
-- synthesis translate_off
or true
-- synthesis translate_on
;
constant IN_SYNTHESIS : boolean := not IN_SIMULATION;
end;

View File

@ -8,6 +8,7 @@ use work.pace_pkg.all;
use work.video_controller_pkg.all;
use work.sprite_pkg.all;
use work.platform_variant_pkg.all;
use work.platform_pkg.all;
entity platform is
generic
@ -267,7 +268,7 @@ begin
clk_en_inst : entity work.clk_div
generic map
(
DIVISOR => 16
DIVISOR => M52_CPU_CLK_ENA_DIVIDE_BY
)
port map
(

View File

@ -0,0 +1,47 @@
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
library work;
use work.target_pkg.all;
use work.project_pkg.all;
package platform_pkg is
constant PACE_VIDEO_NUM_BITMAPS : natural := 3;
constant PACE_VIDEO_NUM_TILEMAPS : natural := 1;
constant PACE_VIDEO_NUM_SPRITES : natural := 64;
constant PACE_VIDEO_H_SIZE : integer := 256;
constant PACE_VIDEO_V_SIZE : integer := 256;
constant PACE_VIDEO_L_CROP : integer := 6;
constant PACE_VIDEO_R_CROP : integer := 8;
constant PACE_VIDEO_PIPELINE_DELAY : integer := 7;
constant PACE_INPUTS_NUM_BYTES : integer := 6;
--
-- Platform-specific constants (optional)
--
constant PLATFORM : string := "m52";
constant PLATFORM_SRC_DIR : string := "";
constant CLK0_FREQ_MHz : natural :=
PACE_CLKIN0 * PACE_CLK0_MULTIPLY_BY / PACE_CLK0_DIVIDE_BY;
constant CPU_FREQ_MHz : natural := 3;
constant M52_CPU_CLK_ENA_DIVIDE_BY : natural := CLK0_FREQ_MHz / CPU_FREQ_MHz;
type pal_rgb_t is array (0 to 2) of std_logic_vector(7 downto 0);
type pal_a is array (natural range <>) of pal_rgb_t;
type from_PLATFORM_IO_t is record
not_used : std_logic;
end record;
type to_PLATFORM_IO_t is record
not_used : std_logic;
end record;
end;

View File

@ -3,9 +3,9 @@ use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
library work;
--use work.target_pkg.all;
--use work.project_pkg.all;
--use work.platform_pkg.all;
use work.target_pkg.all;
use work.project_pkg.all;
use work.platform_pkg.all;
package platform_variant_pkg is
@ -19,8 +19,6 @@ package platform_variant_pkg is
constant PLATFORM_VARIANT : string := "mpatrol";
constant PLATFORM_VARIANT_SRC_DIR : string := "";
type pal_rgb_t is array (0 to 2) of std_logic_vector(7 downto 0);
type pal_a is array (natural range <>) of pal_rgb_t;
type rom_a is array (natural range <>) of string;
constant M52_ROM : rom_a(0 to 3) :=
(

View File

@ -0,0 +1,75 @@
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
library work;
use work.pace_pkg.all;
use work.target_pkg.all;
use work.video_controller_pkg.all;
package project_pkg is
--
-- PACE constants which *MUST* be defined
--
-- Reference clock is 24MHz
constant PACE_HAS_PLL : boolean := true;
--constant PACE_HAS_FLASH : boolean := false;
--constant PACE_HAS_SRAM : boolean := false;
constant PACE_HAS_SDRAM : boolean := false;
constant PACE_HAS_SERIAL : boolean := false;
constant PACE_JAMMA : PACEJamma_t := PACE_JAMMA_NONE;
---- * defined in platform_pkg
--constant PACE_VIDEO_H_SIZE : integer := 224;
--constant PACE_VIDEO_V_SIZE : integer := 256; -- why not 240?
constant PACE_VIDEO_CONTROLLER_TYPE : PACEVideoController_t := PACE_VIDEO_PAL_320x288_50Hz; -- PACE_VIDEO_VGA_800x600_60Hz;
constant PACE_CLK0_DIVIDE_BY : natural := 27;
constant PACE_CLK0_MULTIPLY_BY : natural := 6; -- 27/27*6 = 6MHz
constant PACE_CLK1_DIVIDE_BY : natural := 27;
constant PACE_CLK1_MULTIPLY_BY : natural := 6; -- 27/27*6 = 6MHz
constant PACE_VIDEO_H_SCALE : integer := 1;
constant PACE_VIDEO_V_SCALE : integer := 1;
constant PACE_VIDEO_H_SYNC_POLARITY : std_logic := '1';
constant PACE_VIDEO_V_SYNC_POLARITY : std_logic := '1';
constant PACE_VIDEO_BORDER_RGB : RGB_t := RGB_BLACK;
constant PACE_HAS_OSD : boolean := false;
constant PACE_OSD_XPOS : natural := 0;
constant PACE_OSD_YPOS : natural := 0;
-- NAVICO-ROCKY-specific constants
constant ROCKY_EMULATED_SRAM_WIDTH_AD : natural := 16;
constant ROCKY_EMULATED_SRAM_WIDTH : natural := 8;
constant ROCKY_EMULATED_FLASH_INIT_FILE : string := "";
constant ROCKY_EMULATED_FLASH_WIDTH_AD : natural := 10;
constant ROCKY_EMULATED_FLASH_WIDTH : natural := 8;
-- Moon Patrol-specific constants
constant M52_USE_INTERNAL_WRAM : boolean := true;
-- derived - do not edit
constant ROCKY_EMULATE_SRAM : boolean := false;
constant ROCKY_EMULATE_FLASH : boolean := false;
constant PACE_HAS_FLASH : boolean := false;
constant PACE_HAS_SRAM : boolean := false;
type from_PROJECT_IO_t is record
not_used : std_logic;
end record;
type to_PROJECT_IO_t is record
not_used : std_logic;
end record;
end;

View File

@ -0,0 +1,55 @@
module rgb2ypbpr (
input [5:0] red,
input [5:0] green,
input [5:0] blue,
output [5:0] y,
output [5:0] pb,
output [5:0] pr
);
wire [5:0] yuv_full[225] = '{
6'd0, 6'd0, 6'd0, 6'd0, 6'd1, 6'd1, 6'd1, 6'd1,
6'd2, 6'd2, 6'd2, 6'd3, 6'd3, 6'd3, 6'd3, 6'd4,
6'd4, 6'd4, 6'd5, 6'd5, 6'd5, 6'd5, 6'd6, 6'd6,
6'd6, 6'd7, 6'd7, 6'd7, 6'd7, 6'd8, 6'd8, 6'd8,
6'd9, 6'd9, 6'd9, 6'd9, 6'd10, 6'd10, 6'd10, 6'd11,
6'd11, 6'd11, 6'd11, 6'd12, 6'd12, 6'd12, 6'd13, 6'd13,
6'd13, 6'd13, 6'd14, 6'd14, 6'd14, 6'd15, 6'd15, 6'd15,
6'd15, 6'd16, 6'd16, 6'd16, 6'd17, 6'd17, 6'd17, 6'd17,
6'd18, 6'd18, 6'd18, 6'd19, 6'd19, 6'd19, 6'd19, 6'd20,
6'd20, 6'd20, 6'd21, 6'd21, 6'd21, 6'd21, 6'd22, 6'd22,
6'd22, 6'd23, 6'd23, 6'd23, 6'd23, 6'd24, 6'd24, 6'd24,
6'd25, 6'd25, 6'd25, 6'd25, 6'd26, 6'd26, 6'd26, 6'd27,
6'd27, 6'd27, 6'd27, 6'd28, 6'd28, 6'd28, 6'd29, 6'd29,
6'd29, 6'd29, 6'd30, 6'd30, 6'd30, 6'd31, 6'd31, 6'd31,
6'd31, 6'd32, 6'd32, 6'd32, 6'd33, 6'd33, 6'd33, 6'd33,
6'd34, 6'd34, 6'd34, 6'd35, 6'd35, 6'd35, 6'd35, 6'd36,
6'd36, 6'd36, 6'd36, 6'd37, 6'd37, 6'd37, 6'd38, 6'd38,
6'd38, 6'd38, 6'd39, 6'd39, 6'd39, 6'd40, 6'd40, 6'd40,
6'd40, 6'd41, 6'd41, 6'd41, 6'd42, 6'd42, 6'd42, 6'd42,
6'd43, 6'd43, 6'd43, 6'd44, 6'd44, 6'd44, 6'd44, 6'd45,
6'd45, 6'd45, 6'd46, 6'd46, 6'd46, 6'd46, 6'd47, 6'd47,
6'd47, 6'd48, 6'd48, 6'd48, 6'd48, 6'd49, 6'd49, 6'd49,
6'd50, 6'd50, 6'd50, 6'd50, 6'd51, 6'd51, 6'd51, 6'd52,
6'd52, 6'd52, 6'd52, 6'd53, 6'd53, 6'd53, 6'd54, 6'd54,
6'd54, 6'd54, 6'd55, 6'd55, 6'd55, 6'd56, 6'd56, 6'd56,
6'd56, 6'd57, 6'd57, 6'd57, 6'd58, 6'd58, 6'd58, 6'd58,
6'd59, 6'd59, 6'd59, 6'd60, 6'd60, 6'd60, 6'd60, 6'd61,
6'd61, 6'd61, 6'd62, 6'd62, 6'd62, 6'd62, 6'd63, 6'd63,
6'd63
};
wire [18:0] y_8 = 19'd04096 + ({red, 8'd0} + {red, 3'd0}) + ({green, 9'd0} + {green, 2'd0}) + ({blue, 6'd0} + {blue, 5'd0} + {blue, 2'd0});
wire [18:0] pb_8 = 19'd32768 - ({red, 7'd0} + {red, 4'd0} + {red, 3'd0}) - ({green, 8'd0} + {green, 5'd0} + {green, 3'd0}) + ({blue, 8'd0} + {blue, 7'd0} + {blue, 6'd0});
wire [18:0] pr_8 = 19'd32768 + ({red, 8'd0} + {red, 7'd0} + {red, 6'd0}) - ({green, 8'd0} + {green, 6'd0} + {green, 5'd0} + {green, 4'd0} + {green, 3'd0}) - ({blue, 6'd0} + {blue , 3'd0});
wire [7:0] y_i = ( y_8[17:8] < 16) ? 8'd16 : ( y_8[17:8] > 235) ? 8'd235 : y_8[15:8];
wire [7:0] pb_i = (pb_8[17:8] < 16) ? 8'd16 : (pb_8[17:8] > 240) ? 8'd240 : pb_8[15:8];
wire [7:0] pr_i = (pr_8[17:8] < 16) ? 8'd16 : (pr_8[17:8] > 240) ? 8'd240 : pr_8[15:8];
assign pr = yuv_full[pr_i - 8'd16];
assign y = yuv_full[y_i - 8'd16];
assign pb = yuv_full[pb_i - 8'd16];
endmodule

View File

@ -2,7 +2,6 @@
// scandoubler.v
//
// Copyright (c) 2015 Till Harbaum <till@harbaum.org>
// Copyright (c) 2017 Sorgelig
//
// This source file is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published
@ -19,164 +18,160 @@
// TODO: Delay vsync one line
module scandoubler #(parameter LENGTH, parameter HALF_DEPTH)
module scandoubler
(
// system interface
input clk_sys,
input ce_pix,
input ce_pix_actual,
input clk_sys,
input hq2x,
// scanlines (00-none 01-25% 10-50% 11-75%)
input [1:0] scanlines,
// shifter video interface
input hs_in,
input vs_in,
input line_start,
input [DWIDTH:0] r_in,
input [DWIDTH:0] g_in,
input [DWIDTH:0] b_in,
input mono,
input hs_in,
input vs_in,
input [5:0] r_in,
input [5:0] g_in,
input [5:0] b_in,
// output interface
output reg hs_out,
output vs_out,
output [DWIDTH:0] r_out,
output [DWIDTH:0] g_out,
output [DWIDTH:0] b_out
output reg hs_out,
output reg vs_out,
output reg [5:0] r_out,
output reg [5:0] g_out,
output reg [5:0] b_out
);
// try to detect changes in input signal and lock input clock gate
// it
localparam DWIDTH = HALF_DEPTH ? 2 : 5;
reg [1:0] i_div;
wire ce_x1 = (i_div == 2'b01);
wire ce_x2 = i_div[0];
assign vs_out = vs_in;
reg [2:0] phase;
reg [2:0] ce_div;
reg [7:0] pix_len = 0;
wire [7:0] pl = pix_len + 1'b1;
reg ce_x1, ce_x4;
reg req_line_reset;
wire ls_in = hs_in | line_start;
always @(negedge clk_sys) begin
reg old_ce;
reg [2:0] ce_cnt;
reg [7:0] pixsz2, pixsz4 = 0;
old_ce <= ce_pix;
if(~&pix_len) pix_len <= pix_len + 1'd1;
ce_x4 <= 0;
ce_x1 <= 0;
// use such odd comparison to place c_x4 evenly if master clock isn't multiple 4.
if((pl == pixsz4) || (pl == pixsz2) || (pl == (pixsz2+pixsz4))) begin
phase <= phase + 1'd1;
ce_x4 <= 1;
end
if(~old_ce & ce_pix) begin
pixsz2 <= {1'b0, pl[7:1]};
pixsz4 <= {2'b00, pl[7:2]};
ce_x1 <= 1;
ce_x4 <= 1;
pix_len <= 0;
phase <= phase + 1'd1;
ce_cnt <= ce_cnt + 1'd1;
if(ce_pix_actual) begin
phase <= 0;
ce_div <= ce_cnt + 1'd1;
ce_cnt <= 0;
req_line_reset <= 0;
end
if(ls_in) req_line_reset <= 1;
end
end
reg ce_sd;
always @(*) begin
case(ce_div)
2: ce_sd = !phase[0];
4: ce_sd = !phase[1:0];
default: ce_sd <= 1;
endcase
end
localparam AWIDTH = `BITS_TO_FIT(LENGTH);
Hq2x #(.LENGTH(LENGTH), .HALF_DEPTH(HALF_DEPTH)) Hq2x
(
.clk(clk_sys),
.ce_x4(ce_x4 & ce_sd),
.inputpixel({b_in,g_in,r_in}),
.mono(mono),
.disable_hq2x(~hq2x),
.reset_frame(vs_in),
.reset_line(req_line_reset),
.read_y(sd_line),
.read_x(sd_h_actual),
.outpixel({b_out,g_out,r_out})
);
reg [10:0] sd_h_actual;
always @(*) begin
case(ce_div)
2: sd_h_actual = sd_h[10:1];
4: sd_h_actual = sd_h[10:2];
default: sd_h_actual = sd_h;
endcase
end
reg [10:0] sd_h;
reg [1:0] sd_line;
always @(posedge clk_sys) begin
reg last_hs_in;
last_hs_in <= hs_in;
if(last_hs_in & !hs_in) begin
i_div <= 2'b00;
end else begin
i_div <= i_div + 2'd1;
end
end
reg [11:0] hs_max,hs_rise,hs_ls;
reg [10:0] hcnt;
reg [11:0] sd_hcnt;
reg hs, hs2, vs, ls;
// --------------------- create output signals -----------------
// latch everything once more to make it glitch free and apply scanline effect
reg scanline;
always @(posedge clk_sys) begin
if(ce_x2) begin
hs_out <= hs_sd;
vs_out <= vs_in;
// reset scanlines at every new screen
if(vs_out != vs_in) scanline <= 0;
// toggle scanlines at begin of every hsync
if(hs_out && !hs_sd) scanline <= !scanline;
// if no scanlines or not a scanline
if(!scanline || !scanlines) begin
r_out <= sd_out[17:12];
g_out <= sd_out[11:6];
b_out <= sd_out[5:0];
end else begin
case(scanlines)
1: begin // reduce 25% = 1/2 + 1/4
r_out <= {1'b0, sd_out[17:14], 1'b0} + {2'b00, sd_out[17:14]};
g_out <= {1'b0, sd_out[11:8], 1'b0} + {2'b00, sd_out[11:8] };
b_out <= {1'b0, sd_out[5:2], 1'b0} + {2'b00, sd_out[5:2] };
end
2: begin // reduce 50% = 1/2
r_out <= {1'b0, sd_out[17:14], 1'b0};
g_out <= {1'b0, sd_out[11:8], 1'b0};
b_out <= {1'b0, sd_out[5:2], 1'b0};
end
3: begin // reduce 75% = 1/4
r_out <= {2'b00, sd_out[17:14]};
g_out <= {2'b00, sd_out[11:8]};
b_out <= {2'b00, sd_out[5:2]};
end
endcase
end
end
end
// scan doubler output register
reg [17:0] sd_out;
// ==================================================================
// ======================== the line buffers ========================
// ==================================================================
// 2 lines of 512 pixels 3*6 bit RGB
(* ramstyle = "no_rw_check" *) reg [17:0] sd_buffer[2048];
// use alternating sd_buffers when storing/reading data
reg line_toggle;
// total hsync time (in 16MHz cycles), hs_total reaches 1024
reg [9:0] hs_max;
reg [9:0] hs_rise;
reg [9:0] hcnt;
always @(posedge clk_sys) begin
reg hsD, vsD;
if(ce_x1) begin
hs <= hs_in;
ls <= ls_in;
if(ls && !ls_in) hs_ls <= {hcnt,1'b1};
hsD <= hs_in;
// falling edge of hsync indicates start of line
if(hs && !hs_in) begin
hs_max <= {hcnt,1'b1};
if(hsD && !hs_in) begin
hs_max <= hcnt;
hcnt <= 0;
if(ls && !ls_in) hs_ls <= {10'd0,1'b1};
end else begin
hcnt <= hcnt + 1'd1;
end
// save position of rising edge
if(!hs && hs_in) hs_rise <= {hcnt,1'b1};
if(!hsD && hs_in) hs_rise <= hcnt;
vs <= vs_in;
if(vs && ~vs_in) sd_line <= 0;
vsD <= vs_in;
if(vsD != vs_in) line_toggle <= 0;
// begin of incoming hsync
if(hsD && !hs_in) line_toggle <= !line_toggle;
sd_buffer[{line_toggle, hcnt}] <= {r_in, g_in, b_in};
end
end
if(ce_x4) begin
hs2 <= hs_in;
// ==================================================================
// ==================== output timing generation ====================
// ==================================================================
reg [9:0] sd_hcnt;
reg hs_sd;
// timing generation runs 32 MHz (twice the input signal analysis speed)
always @(posedge clk_sys) begin
reg hsD;
if(ce_x2) begin
hsD <= hs_in;
// output counter synchronous to input and at twice the rate
sd_hcnt <= sd_hcnt + 1'd1;
sd_h <= sd_h + 1'd1;
if(hs2 && !hs_in) sd_hcnt <= hs_max;
if(hsD && !hs_in) sd_hcnt <= hs_max;
if(sd_hcnt == hs_max) sd_hcnt <= 0;
// replicate horizontal sync at twice the speed
if(sd_hcnt == hs_max) hs_out <= 0;
if(sd_hcnt == hs_rise) hs_out <= 1;
if(sd_hcnt == hs_max) hs_sd <= 0;
if(sd_hcnt == hs_rise) hs_sd <= 1;
if(sd_hcnt == hs_ls) sd_h <= 0;
if(sd_hcnt == hs_ls) sd_line <= sd_line + 1'd1;
// read data from line sd_buffer
sd_out <= sd_buffer[{~line_toggle, sd_hcnt}];
end
end

View File

@ -8,7 +8,7 @@ library work;
use work.pace_pkg.all;
use work.video_controller_pkg.all;
use work.sprite_pkg.all;
--use work.platform_pkg.all;
use work.platform_pkg.all;
entity sprite_array is
generic

View File

@ -5,7 +5,9 @@ use ieee.numeric_std.all;
library work;
use work.pace_pkg.all;
use work.video_controller_pkg.all;
use work.sprite_pkg.all;
use work.sprite_pkg.all;
use work.project_pkg.all;
use work.platform_pkg.all;
use work.platform_variant_pkg.all;
entity spritectl is
@ -56,7 +58,7 @@ begin
-- the width of rowCount determines the scanline multipler
-- - eg. (4 downto 0) is 1:1
-- (5 downto 0) is 2:1 (scan-doubling)
variable rowCount : unsigned(3+2 downto 0);
variable rowCount : unsigned(3+PACE_VIDEO_V_SCALE downto 0);
alias row : unsigned(4 downto 0) is
rowCount(rowCount'left downto rowCount'left-4);
@ -69,7 +71,7 @@ begin
if rising_edge(clk) then
if clk_ena = '1' then
x := unsigned(reg_i.x) + 7 - 3;
x := unsigned(reg_i.x) + PACE_VIDEO_PIPELINE_DELAY - 3;
y := 254 - unsigned(reg_i.y) - 16;
if video_ctl.hblank = '1' then

View File

@ -0,0 +1,206 @@
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
use ieee.numeric_std.all;
library work;
use work.pace_pkg.all;
use work.sdram_pkg.all;
use work.video_controller_pkg.all;
use work.project_pkg.all;
use work.platform_pkg.all;
use work.target_pkg.all;
entity target_top is
port
(
clock_30 : in std_logic;
clock_v : in std_logic;
clock_3p58 : in std_logic;
reset : in std_logic;
dn_addr : in std_logic_vector(15 downto 0);
dn_data : in std_logic_vector(7 downto 0);
dn_wr : in std_logic;
AUDIO : out signed(12 downto 0);
JOY : in std_logic_vector(7 downto 0);
JOY2 : in std_logic_vector(7 downto 0);
VGA_VBLANK : out std_logic;
VGA_HBLANK : out std_logic;
VGA_VS : out std_logic;
VGA_HS : out std_logic;
VGA_R : out std_logic_vector(3 downto 0);
VGA_G : out std_logic_vector(3 downto 0);
VGA_B : out std_logic_vector(3 downto 0)
);
end target_top;
architecture SYN of target_top is
signal clkrst_i : from_CLKRST_t;
signal buttons_i : from_BUTTONS_t;
signal switches_i : from_SWITCHES_t;
signal leds_o : to_LEDS_t;
signal inputs_i : from_INPUTS_t;
signal flash_i : from_FLASH_t;
signal flash_o : to_FLASH_t;
signal sram_i : from_SRAM_t;
signal sram_o : to_SRAM_t;
signal sdram_i : from_SDRAM_t;
signal sdram_o : to_SDRAM_t;
signal video_i : from_VIDEO_t;
signal video_o : to_VIDEO_t;
signal audio_i : from_AUDIO_t;
signal audio_o : to_AUDIO_t;
signal ser_i : from_SERIAL_t;
signal ser_o : to_SERIAL_t;
signal project_i : from_PROJECT_IO_t;
signal project_o : to_PROJECT_IO_t;
signal platform_i : from_PLATFORM_IO_t;
signal platform_o : to_PLATFORM_IO_t;
signal target_i : from_TARGET_IO_t;
signal target_o : to_TARGET_IO_t;
signal sound_data : std_logic_vector(7 downto 0);
begin
clkrst_i.clk(0)<=clock_30;
clkrst_i.clk(1)<=clock_v;
clkrst_i.arst <= reset;
clkrst_i.arst_n <= not clkrst_i.arst;
GEN_RESETS : for i in 0 to 3 generate
process (clkrst_i.clk(i), clkrst_i.arst)
variable rst_r : std_logic_vector(2 downto 0) := (others => '0');
begin
if clkrst_i.arst = '1' then
rst_r := (others => '1');
elsif rising_edge(clkrst_i.clk(i)) then
rst_r := rst_r(rst_r'left-1 downto 0) & '0';
end if;
clkrst_i.rst(i) <= rst_r(rst_r'left);
end process;
end generate GEN_RESETS;
inputs_i.jamma_n.coin(1) <= JOY(7);
inputs_i.jamma_n.p(1).start <= JOY(6);
inputs_i.jamma_n.coin(2) <= JOY2(7);
inputs_i.jamma_n.p(2).start <= JOY2(6);
inputs_i.jamma_n.p(1).up <= not JOY(3);
inputs_i.jamma_n.p(1).down <= not JOY(2);
inputs_i.jamma_n.p(1).left <= not JOY(1);
inputs_i.jamma_n.p(1).right <= not JOY(0);
inputs_i.jamma_n.p(1).button(1) <= not JOY(4);
inputs_i.jamma_n.p(1).button(2) <= not JOY(5);
inputs_i.jamma_n.p(1).button(3) <= '1';
inputs_i.jamma_n.p(1).button(4) <= '1';
inputs_i.jamma_n.p(1).button(5) <= '1';
inputs_i.jamma_n.p(2).up <= not JOY2(3);
inputs_i.jamma_n.p(2).down <= not JOY2(2);
inputs_i.jamma_n.p(2).left <= not JOY2(1);
inputs_i.jamma_n.p(2).right <= not JOY2(0);
inputs_i.jamma_n.p(2).button(1) <= not JOY2(4);
inputs_i.jamma_n.p(2).button(2) <= not JOY2(5);
inputs_i.jamma_n.p(2).button(3) <= '1';
inputs_i.jamma_n.p(2).button(4) <= '1';
inputs_i.jamma_n.p(2).button(5) <= '1';
-- not currently wired to any inputs
inputs_i.jamma_n.coin_cnt <= (others => '1');
--inputs_i.jamma_n.coin(2) <= '1';
inputs_i.jamma_n.service <= '1';
inputs_i.jamma_n.tilt <= '1';
inputs_i.jamma_n.test <= '1';
video_i.clk <= clkrst_i.clk(1); -- by convention
video_i.clk_ena <= '1';
video_i.reset <= clkrst_i.rst(1);
VGA_R <= video_o.rgb.r(9 downto 6);
VGA_G <= video_o.rgb.g(9 downto 6);
VGA_B <= video_o.rgb.b(9 downto 6);
VGA_HS <= video_o.hsync;
VGA_VS <= video_o.vsync;
VGA_HBLANK <= video_o.hblank;
VGA_VBLANK <= video_o.vblank;
pace_inst : entity work.pace
port map
(
-- clocks and resets
clkrst_i => clkrst_i,
-- misc inputs and outputs
buttons_i => buttons_i,
switches_i => switches_i,
leds_o => open,
-- controller inputs
inputs_i => inputs_i,
-- external ROM/RAM
flash_i => flash_i,
flash_o => flash_o,
sram_i => sram_i,
sram_o => sram_o,
sdram_i => sdram_i,
sdram_o => sdram_o,
-- VGA video
video_i => video_i,
video_o => video_o,
-- sound
audio_i => audio_i,
audio_o => audio_o,
-- SPI (flash)
spi_i.din => '0',
spi_o => open,
-- serial
ser_i => ser_i,
ser_o => ser_o,
sound_data_o => sound_data,
dn_addr => dn_addr,
dn_data => dn_data,
dn_wr => dn_wr,
-- custom i/o
project_i => project_i,
project_o => project_o,
platform_i => platform_i,
platform_o => platform_o,
target_i => target_i,
target_o => target_o
);
moon_patrol_sound_board : entity work.moon_patrol_sound_board
port map(
clock_3p58 => clock_3p58,
reset => reset,
clock_30 => clock_30,
dn_addr => dn_addr,
dn_data => dn_data,
dn_wr => dn_wr,
select_sound => sound_data,
audio_out => AUDIO
);
end SYN;

View File

@ -4,6 +4,8 @@ use ieee.numeric_std.all;
library work;
use work.pace_pkg.all;
use work.project_pkg.all;
use work.platform_pkg.all;
use work.platform_variant_pkg.all;
use work.video_controller_pkg.all;
@ -13,27 +15,7 @@ use work.video_controller_pkg.all;
-- Tile data is 2 BPP.
--
entity TILEMAP_1 is
generic
(
DELAY : integer
);
port
(
reset : in std_logic;
-- video control signals
video_ctl : in from_VIDEO_CTL_t;
-- tilemap controller signals
ctl_i : in to_TILEMAP_CTL_t;
ctl_o : out from_TILEMAP_CTL_t;
graphics_i : in to_GRAPHICS_t
);
end entity TILEMAP_1;
architecture tile1 of TILEMAP_1 is
architecture TILEMAP_1 of tilemapCtl is
alias clk : std_logic is video_ctl.clk;
alias clk_ena : std_logic is video_ctl.clk_ena;
@ -128,4 +110,4 @@ begin
end process;
end architecture tile1;
end architecture TILEMAP_1;

View File

@ -0,0 +1,29 @@
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
library work;
use work.pace_pkg.all;
use work.project_pkg.all;
use work.platform_pkg.all;
use work.video_controller_pkg.all;
entity tilemapCtl is
generic
(
DELAY : integer
);
port
(
reset : in std_logic;
-- video control signals
video_ctl : in from_VIDEO_CTL_t;
-- tilemap controller signals
ctl_i : in to_TILEMAP_CTL_t;
ctl_o : out from_TILEMAP_CTL_t;
graphics_i : in to_GRAPHICS_t
);
end entity tilemapCtl;

View File

@ -1,8 +1,7 @@
library ieee;
library IEEE;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
library work;
use work.video_controller_pkg.all;
@ -259,6 +258,16 @@ begin
v_back_porch_r <= 13;
v_border_r <= (240-VIDEO_V_SIZE)/2;
when PACE_VIDEO_PAL_320x288_50Hz =>
h_front_porch_r <= 6;
h_sync_r <= 28;
h_back_porch_r <= 30;
h_border_r <= (320-VIDEO_H_SIZE)/2;
v_front_porch_r <= 8;
v_sync_r <= 3;
v_back_porch_r <= 13;
v_border_r <= (288-VIDEO_V_SIZE)/2;
when others =>
null;
end case;
@ -439,8 +448,8 @@ begin
end if;
video_o.hsync <= hsync_v after SIM_DELAY;
video_o.vsync <= vsync_v after SIM_DELAY;
video_o.hblank <= hblank_v after SIM_DELAY;
video_o.vblank <= vblank_v after SIM_DELAY;
video_o.hblank <= not hactive_v; -- hblank_v after SIM_DELAY;
video_o.vblank <= not vactive_v; -- vblank_v after SIM_DELAY;
-- pipelined signals
hsync_v_r := hsync_v_r(hsync_v_r'left-1 downto 0) & hsync_s;
vsync_v_r := vsync_v_r(vsync_v_r'left-1 downto 0) & vsync_s;

View File

@ -21,7 +21,8 @@ package video_controller_pkg is
PACE_VIDEO_ARCADE_STD_336x240_60Hz, -- arcade std resolution (7.16MHz)
PACE_VIDEO_ARCADE_STD_336x240_60Hz_28M64, -- arcade std resolution (28.64MHz)
PACE_VIDEO_CVBS_720x288p_50Hz, -- generic composite
PACE_VIDEO_LCM_320x240_60Hz -- DE2 LCD
PACE_VIDEO_LCM_320x240_60Hz, -- DE2 LCD
PACE_VIDEO_PAL_320x288_50Hz
);
type PACEVideoDisplay_t is

View File

@ -1,233 +0,0 @@
//
//
// Copyright (c) 2017 Sorgelig
//
// This program is GPL Licensed. See COPYING for the full license.
//
//
////////////////////////////////////////////////////////////////////////////////////////////////////////
`timescale 1ns / 1ps
//
// LINE_LENGTH: Length of display line in pixels
// Usually it's length from HSync to HSync.
// May be less if line_start is used.
//
// HALF_DEPTH: If =1 then color dept is 3 bits per component
// For half depth 6 bits monochrome is available with
// mono signal enabled and color = {G, R}
module video_mist
/*#(
parameter LINE_LENGTH = 256,
parameter HALF_DEPTH = 0,
parameter OSD_COLOR = 3'd4,
parameter OSD_X_OFFSET = 10'd0,
parameter OSD_Y_OFFSET = 10'd0
)*/
(
// master clock
// it should be multiple by (ce_pix*4).
input clk_sys,
// Pixel clock or clock_enable (both are accepted).
input ce_pix,
// Some systems have multiple resolutions.
// ce_pix_actual should match ce_pix where every second or fourth pulse is enabled,
// thus half or qurter resolutions can be used without brake video sync while switching resolutions.
// For fixed single resolution (or when video sync stability isn't required) ce_pix_actual = ce_pix.
input ce_pix_actual,
// OSD SPI interface
input SPI_SCK,
input SPI_SS3,
input SPI_DI,
// scanlines (00-none 01-25% 10-50% 11-75%)
input [1:0] scanlines,
// 0 = HVSync 31KHz, 1 = CSync 15KHz
input scan_disable,
// High quality 2x scaling
input hq2x,
// YPbPr always uses composite sync
input ypbpr,
// 0 = 16-240 range. 1 = 0-255 range. (only for YPbPr color space)
input ypbpr_full,
// color
input [5:0] R,
input [5:0] G,
input [5:0] B,
// Monochrome mode (for HALF_DEPTH only)
input mono,
// interlace sync. Positive pulses.
input HSync,
input VSync,
// Falling of this signal means start of informative part of line.
// It can be horizontal blank signal.
// This signal can be used to reduce amount of required FPGA RAM for HQ2x scan doubler
// If FPGA RAM is not an issue, then simply set it to 0 for whole line processing.
// Keep in mind: due to algo first and last pixels of line should be black to avoid side artefacts.
// Thus, if blank signal is used to reduce the line, make sure to feed at least one black (or paper) pixel
// before first informative pixel.
input line_start,
// MiST video output signals
output [5:0] VGA_R,
output [5:0] VGA_G,
output [5:0] VGA_B,
output VGA_VS,
output VGA_HS
);
wire [5:0] R_sd;
wire [5:0] G_sd;
wire [5:0] B_sd;
wire hs_sd, vs_sd;
scandoubler #(.LENGTH(800), .HALF_DEPTH(0)) scandoubler
(
.*,
.hs_in(HSync),
.vs_in(VSync),
.r_in(R),
.g_in(G),
.b_in(B),
.hs_out(hs_sd),
.vs_out(vs_sd),
.r_out(R_sd),
.g_out(G_sd),
.b_out(B_sd)
);
wire [5:0] rt = (scan_disable ? R : R_sd);
wire [5:0] gt = (scan_disable ? G : G_sd);
wire [5:0] bt = (scan_disable ? B : B_sd);
wire [5:0] r = rt;
wire [5:0] g = gt;
wire [5:0] b = bt;
wire hs = (scan_disable ? HSync : hs_sd);
wire vs = (scan_disable ? VSync : vs_sd);
reg scanline = 0;
always @(posedge clk_sys) begin
reg old_hs, old_vs;
old_hs <= hs;
old_vs <= vs;
if(old_hs && ~hs) scanline <= ~scanline;
if(old_vs && ~vs) scanline <= 0;
end
wire [5:0] r_out, g_out, b_out;
always @(*) begin
case(scanlines & {scanline, scanline})
1: begin // reduce 25% = 1/2 + 1/4
r_out = {1'b0, r[5:1]} + {2'b00, r[5:2]};
g_out = {1'b0, g[5:1]} + {2'b00, g[5:2]};
b_out = {1'b0, b[5:1]} + {2'b00, b[5:2]};
end
2: begin // reduce 50% = 1/2
r_out = {1'b0, r[5:1]};
g_out = {1'b0, g[5:1]};
b_out = {1'b0, b[5:1]};
end
3: begin // reduce 75% = 1/4
r_out = {2'b00, r[5:2]};
g_out = {2'b00, g[5:2]};
b_out = {2'b00, b[5:2]};
end
default: begin
r_out = r;
g_out = g;
b_out = b;
end
endcase
end
wire [5:0] red, green, blue;
osd #(10'd0, 10'd0, 3'd4) osd
(
.*,
.R_in(r_out),
.G_in(g_out),
.B_in(b_out),
.HSync(hs),
.VSync(vs),
.R_out(red),
.G_out(green),
.B_out(blue)
);
wire [5:0] yuv_full[225] = '{
6'd0, 6'd0, 6'd0, 6'd0, 6'd1, 6'd1, 6'd1, 6'd1,
6'd2, 6'd2, 6'd2, 6'd3, 6'd3, 6'd3, 6'd3, 6'd4,
6'd4, 6'd4, 6'd5, 6'd5, 6'd5, 6'd5, 6'd6, 6'd6,
6'd6, 6'd7, 6'd7, 6'd7, 6'd7, 6'd8, 6'd8, 6'd8,
6'd9, 6'd9, 6'd9, 6'd9, 6'd10, 6'd10, 6'd10, 6'd11,
6'd11, 6'd11, 6'd11, 6'd12, 6'd12, 6'd12, 6'd13, 6'd13,
6'd13, 6'd13, 6'd14, 6'd14, 6'd14, 6'd15, 6'd15, 6'd15,
6'd15, 6'd16, 6'd16, 6'd16, 6'd17, 6'd17, 6'd17, 6'd17,
6'd18, 6'd18, 6'd18, 6'd19, 6'd19, 6'd19, 6'd19, 6'd20,
6'd20, 6'd20, 6'd21, 6'd21, 6'd21, 6'd21, 6'd22, 6'd22,
6'd22, 6'd23, 6'd23, 6'd23, 6'd23, 6'd24, 6'd24, 6'd24,
6'd25, 6'd25, 6'd25, 6'd25, 6'd26, 6'd26, 6'd26, 6'd27,
6'd27, 6'd27, 6'd27, 6'd28, 6'd28, 6'd28, 6'd29, 6'd29,
6'd29, 6'd29, 6'd30, 6'd30, 6'd30, 6'd31, 6'd31, 6'd31,
6'd31, 6'd32, 6'd32, 6'd32, 6'd33, 6'd33, 6'd33, 6'd33,
6'd34, 6'd34, 6'd34, 6'd35, 6'd35, 6'd35, 6'd35, 6'd36,
6'd36, 6'd36, 6'd36, 6'd37, 6'd37, 6'd37, 6'd38, 6'd38,
6'd38, 6'd38, 6'd39, 6'd39, 6'd39, 6'd40, 6'd40, 6'd40,
6'd40, 6'd41, 6'd41, 6'd41, 6'd42, 6'd42, 6'd42, 6'd42,
6'd43, 6'd43, 6'd43, 6'd44, 6'd44, 6'd44, 6'd44, 6'd45,
6'd45, 6'd45, 6'd46, 6'd46, 6'd46, 6'd46, 6'd47, 6'd47,
6'd47, 6'd48, 6'd48, 6'd48, 6'd48, 6'd49, 6'd49, 6'd49,
6'd50, 6'd50, 6'd50, 6'd50, 6'd51, 6'd51, 6'd51, 6'd52,
6'd52, 6'd52, 6'd52, 6'd53, 6'd53, 6'd53, 6'd54, 6'd54,
6'd54, 6'd54, 6'd55, 6'd55, 6'd55, 6'd56, 6'd56, 6'd56,
6'd56, 6'd57, 6'd57, 6'd57, 6'd58, 6'd58, 6'd58, 6'd58,
6'd59, 6'd59, 6'd59, 6'd60, 6'd60, 6'd60, 6'd60, 6'd61,
6'd61, 6'd61, 6'd62, 6'd62, 6'd62, 6'd62, 6'd63, 6'd63,
6'd63
};
// http://marsee101.blog19.fc2.com/blog-entry-2311.html
// Y = 16 + 0.257*R + 0.504*G + 0.098*B (Y = 0.299*R + 0.587*G + 0.114*B)
// Pb = 128 - 0.148*R - 0.291*G + 0.439*B (Pb = -0.169*R - 0.331*G + 0.500*B)
// Pr = 128 + 0.439*R - 0.368*G - 0.071*B (Pr = 0.500*R - 0.419*G - 0.081*B)
wire [18:0] y_8 = 19'd04096 + ({red, 8'd0} + {red, 3'd0}) + ({green, 9'd0} + {green, 2'd0}) + ({blue, 6'd0} + {blue, 5'd0} + {blue, 2'd0});
wire [18:0] pb_8 = 19'd32768 - ({red, 7'd0} + {red, 4'd0} + {red, 3'd0}) - ({green, 8'd0} + {green, 5'd0} + {green, 3'd0}) + ({blue, 8'd0} + {blue, 7'd0} + {blue, 6'd0});
wire [18:0] pr_8 = 19'd32768 + ({red, 8'd0} + {red, 7'd0} + {red, 6'd0}) - ({green, 8'd0} + {green, 6'd0} + {green, 5'd0} + {green, 4'd0} + {green, 3'd0}) - ({blue, 6'd0} + {blue , 3'd0});
wire [7:0] y = ( y_8[17:8] < 16) ? 8'd16 : ( y_8[17:8] > 235) ? 8'd235 : y_8[15:8];
wire [7:0] pb = (pb_8[17:8] < 16) ? 8'd16 : (pb_8[17:8] > 240) ? 8'd240 : pb_8[15:8];
wire [7:0] pr = (pr_8[17:8] < 16) ? 8'd16 : (pr_8[17:8] > 240) ? 8'd240 : pr_8[15:8];
assign VGA_R = ypbpr ? (ypbpr_full ? yuv_full[pr-8'd16] : pr[7:2]) : red;
assign VGA_G = ypbpr ? (ypbpr_full ? yuv_full[y -8'd16] : y[7:2]) : green;
assign VGA_B = ypbpr ? (ypbpr_full ? yuv_full[pb-8'd16] : pb[7:2]) : blue;
assign VGA_VS = (scan_disable | ypbpr) ? 1'b1 : ~vs_sd;
assign VGA_HS = scan_disable ? ~(HSync ^ VSync) : ypbpr ? ~(hs_sd ^ vs_sd) : ~hs_sd;
endmodule

View File

@ -7,15 +7,15 @@ library work;
use work.pace_pkg.all;
use work.video_controller_pkg.all;
use work.sprite_pkg.all;
--use work.platform_pkg.all;
use work.platform_pkg.all;
entity pace_video_mixer is
port
(
--bitmap_rgb : in RGB_t;
--bitmap_set : in std_logic;
bitmap_ctl_o : in from_BITMAP_CTL_a(1 to 3);
tilemap_ctl_o : in from_TILEMAP_CTL_a(1 to 1);
bitmap_ctl_o : in from_BITMAP_CTL_a(1 to PACE_VIDEO_NUM_BITMAPS);
tilemap_ctl_o : in from_TILEMAP_CTL_a(1 to PACE_VIDEO_NUM_TILEMAPS);
sprite_rgb : in RGB_t;
sprite_set : in std_logic;
sprite_pri : in std_logic;
@ -30,15 +30,37 @@ architecture SYN of pace_video_mixer is
signal bg_rgb : RGB_t;
begin
GEN_BITMAPS :
if PACE_VIDEO_NUM_BITMAPS = 1 generate
bg_rgb <= bitmap_ctl_o(1).rgb;
elsif PACE_VIDEO_NUM_BITMAPS = 2 generate
bg_rgb <= bitmap_ctl_o(1).rgb when bitmap_ctl_o(1).set = '1' else
bitmap_ctl_o(2).rgb;
elsif PACE_VIDEO_NUM_BITMAPS = 3 generate
bg_rgb <= bitmap_ctl_o(1).rgb when bitmap_ctl_o(1).set = '1' else
bitmap_ctl_o(2).rgb when bitmap_ctl_o(2).set = '1' else
bitmap_ctl_o(3).rgb when bitmap_ctl_o(3).set = '1' else
(others => (others => '0'));
else generate
bg_rgb <= (others => (others => '0'));
end generate GEN_BITMAPS;
GEN_TILEMAPS :
if PACE_VIDEO_NUM_TILEMAPS = 1 generate
rgb_o <= sprite_rgb when sprite_set = '1' and sprite_pri = '1' else
tilemap_ctl_o(1).rgb when tilemap_ctl_o(1).set = '1' else
sprite_rgb when sprite_set = '1' else
bg_rgb;
elsif PACE_VIDEO_NUM_TILEMAPS = 2 generate
rgb_o <= sprite_rgb when sprite_set = '1' and sprite_pri = '1' else
tilemap_ctl_o(1).rgb when tilemap_ctl_o(1).set = '1' else
tilemap_ctl_o(2).rgb when tilemap_ctl_o(2).set = '1' else
sprite_rgb when sprite_set = '1' else
bg_rgb;
else generate
rgb_o <= sprite_rgb when sprite_set = '1' and sprite_pri = '1' else
sprite_rgb when sprite_set = '1' else
bg_rgb;
end generate GEN_TILEMAPS;
end architecture SYN;