Bug fixes and tweaks

This commit is contained in:
Philip Smart
2020-11-10 22:39:10 +00:00
parent 52d0700aca
commit 6a8da13e6f
4 changed files with 92 additions and 23 deletions

View File

@@ -70,6 +70,7 @@ entity VideoController is
VIDCLK_65MHZ : in std_logic; -- 65MHz base clock for video timing and gate clocking.
VIDCLK_25_175MHZ : in std_logic; -- 25.175MHz base clock for video timing and gate clocking.
VIDCLK_40MHZ : in std_logic; -- 40MHz base clock for video timing and gate clocking.
VIDCLK_PSEUDO : in std_logic; -- Clock to create pixel slicing to generate pseudo monochrome.
-- V[name] = Voltage translated signals which mirror the mainboard signals but at a lower voltage.
-- Address Bus
@@ -377,6 +378,8 @@ architecture rtl of VideoController is
signal V_I_SYNC_END : unsigned(15 downto 0);
signal V_I_LINE_END : unsigned(15 downto 0);
signal DISABLE_INT_DISPLAY : std_logic;
signal PSEUDOGREY_VIDEO : std_logic; -- Pseudo grey video stream.
signal PSEUDOGREY_CTR : integer range 0 to 7; -- Counter to create video signal sub divisions.
--
-- CG-ROM
--
@@ -747,7 +750,7 @@ begin
-- Every time we reach the end of the visible display area we enable copying of the VRAM and GRAM into the
-- display framebuffer, ready for the next frame display. This starts to occur a fixed set of rows after
-- they have been displayed, initially only during the hblank period of a row, but the during the full row
-- they have been displayed, initially only during the hblank period of a row, but during the full row
-- in the vblank period.
--
if V_COUNT = 0 then
@@ -2392,7 +2395,7 @@ begin
else
GRAM_DO_GII when VZ80_RDn = '0' and CS_GRAMn = '0' and GRAM_OPT_WRITE = '1' -- For MZ80B GRAM II memory read - lower 8K of blue framebuffer.
else
V_BLANKi & H_BLANKi & VIDEO_MODE_REG(5 downto 0)when VZ80_RDn = '0' and CS_FB_VMn = '0'
VIDEO_MODE_REG(7 downto 0) when VZ80_RDn = '0' and CS_FB_VMn = '0'
else
GRAM_MODE_REG when VZ80_RDn = '0' and CS_FB_CTLn = '0'
else
@@ -2402,7 +2405,7 @@ begin
else
GRAM_B_FILTER when VZ80_RDn = '0' and CS_FB_BLUEn = '0'
else
PAGE_MODE_REG when VZ80_RDn = '0' and CS_FB_PAGEn = '0'
PAGE_MODE_REG(7) & V_BLANKi & H_BLANKi & PAGE_MODE_REG(4 downto 0) when VZ80_RDn = '0' and CS_FB_PAGEn = '0'
else
CGROM_DO when VZ80_RDn = '0' and CS_DXXXn = '0' and CGROM_PAGE = '1'
else
@@ -2697,6 +2700,55 @@ begin
-- end if;
-- end process;
-- Pseudo greyscale monochrome generator.
-- The internal monitor only supports on/off pixels so representing colour or grey scale cannot be done. This process, based on the colour attribute, pulses the pixels, skipping some pulses depending on colour
-- to give the effect of grey scaling.
process(VIDCLK_PSEUDO, VRESETn)
begin
-- Ensure default values at reset.
if VRESETn='0' then
PSEUDOGREY_CTR <= 0;
PSEUDOGREY_VIDEO <= '0';
elsif rising_edge(VIDCLK_PSEUDO) then
-- Always reset the pulse every clock tick, so 1 pulse = 1/VIDCLK_PSEUDO wide.
--
PSEUDOGREY_VIDEO <= '0';
-- Rotate the counter, the value determines when a pulse is output according to the colour pixel being displayed.
PSEUDOGREY_CTR <= PSEUDOGREY_CTR + 1;
if SR_R_DATA(7) = '1' and SR_G_DATA(7) = '1' and SR_B_DATA(7) = '1' then
PSEUDOGREY_VIDEO <= '1';
elsif SR_R_DATA(7) = '1' and SR_G_DATA(7) = '1' and SR_B_DATA(7) = '0' and (PSEUDOGREY_CTR = 1 or PSEUDOGREY_CTR = 2 or PSEUDOGREY_CTR = 4 or PSEUDOGREY_CTR = 5 or PSEUDOGREY_CTR = 6 or PSEUDOGREY_CTR = 7) then
PSEUDOGREY_VIDEO <= '1';
elsif SR_R_DATA(7) = '1' and SR_G_DATA(7) = '0' and SR_B_DATA(7) = '1' and (PSEUDOGREY_CTR = 2 or PSEUDOGREY_CTR = 4 or PSEUDOGREY_CTR = 5 or PSEUDOGREY_CTR = 6 or PSEUDOGREY_CTR = 7) then
PSEUDOGREY_VIDEO <= '1';
elsif SR_R_DATA(7) = '1' and SR_G_DATA(7) = '0' and SR_B_DATA(7) = '0' and (PSEUDOGREY_CTR = 1 or PSEUDOGREY_CTR = 4 or PSEUDOGREY_CTR = 5 or PSEUDOGREY_CTR = 7) then
PSEUDOGREY_VIDEO <= '1';
elsif SR_R_DATA(7) = '0' and SR_G_DATA(7) = '1' and SR_B_DATA(7) = '1' and (PSEUDOGREY_CTR = 2 or PSEUDOGREY_CTR = 4 or PSEUDOGREY_CTR = 6 ) then
PSEUDOGREY_VIDEO <= '1';
elsif SR_R_DATA(7) = '0' and SR_G_DATA(7) = '1' and SR_B_DATA(7) = '0' and (PSEUDOGREY_CTR = 4 or PSEUDOGREY_CTR = 5) then
PSEUDOGREY_VIDEO <= '1';
elsif SR_R_DATA(7) = '0' and SR_G_DATA(7) = '0' and SR_B_DATA(7) = '1' and (PSEUDOGREY_CTR = 4) then
PSEUDOGREY_VIDEO <= '1';
end if;
-- During blanking periods. clear the video stream and reset counter ready for next line to keep things consistent.
if H_BLANKi = '1' or V_BLANKi = '1' then
PSEUDOGREY_VIDEO <= '0';
PSEUDOGREY_CTR <= 0;
end if;
end if;
end process;
-- Set the mainboard video state, 0 = enabled, 1 = disabled.
MODE_CPLD_MB_VIDEOn <= CPLD_CFG_DATA(3);
@@ -2734,19 +2786,21 @@ begin
-- Mainboard Video output circuitry. This is the emulation of the MB14298/MB14299 gate arrays. We inject the video (serialised data) and the sync/blanking signals into the MB14298 socket
-- and these are combined on the mainboard to generate the internal monitor signals.
--
VSRVIDEO_OUT <= (SR_R_DATA(7) xor SR_B_DATA(7)) or (SR_R_DATA(7) xor SR_G_DATA(7)) or (SR_B_DATA(7) xor SR_G_DATA(7)) when DISABLE_INT_DISPLAY = '0' -- Video out from 74LS165 on mainboard, pre-GATE.
VSRVIDEO_OUT <= SR_G_DATA(7) when DISABLE_INT_DISPLAY = '0' and (MODE_VIDEO_MONO = '1' or MODE_VIDEO_MONO80 = '1')
else
PSEUDOGREY_VIDEO when DISABLE_INT_DISPLAY = '0' -- Video out from 74LS165 on mainboard, pre-GATE.
else '0';
VHBLNK_OUTn <= not H_BLANKi when DISABLE_INT_DISPLAY = '0' -- Horizontal blanking.
VHBLNK_OUTn <= not H_BLANKi when DISABLE_INT_DISPLAY = '0' -- Horizontal blanking.
else H_I_BLANKi;
VHSY_OUT <= not H_SYNCni when DISABLE_INT_DISPLAY = '0' -- Horizontal Sync.
VHSY_OUT <= not H_SYNCni when DISABLE_INT_DISPLAY = '0' -- Horizontal Sync.
else H_I_SYNCni;
VSYNCH_OUT <= not V_SYNCni when DISABLE_INT_DISPLAY = '0' -- Veritcal Sync.
VSYNCH_OUT <= not V_SYNCni when DISABLE_INT_DISPLAY = '0' -- Veritcal Sync.
else V_I_SYNCni;
VVBLNK_OUTn <= not V_BLANKi when DISABLE_INT_DISPLAY = '0' -- Vertical blanking.
VVBLNK_OUTn <= not V_BLANKi when DISABLE_INT_DISPLAY = '0' -- Vertical blanking.
else V_I_BLANKi;
-- Composite video signal output. Composite video is formed in hardware by the combination of VGA R/G/B signals.
CSYNCn <= not (H_SYNCni or V_SYNCni);
CSYNC <= H_SYNCni or V_SYNCni;
CSYNCn <= not (H_SYNCni xor V_SYNCni);
CSYNC <= H_SYNCni xor V_SYNCni;
end architecture rtl;

View File

@@ -85,10 +85,12 @@ architecture rtl of VideoControllerFPGA is
signal VIDCLK_25_175MHZ : std_logic;
signal VIDCLK_40MHZ : std_logic;
signal VIDCLK_65MHZ : std_logic;
signal VIDCLK_PSEUDO : std_logic;
signal PLL_LOCKED : std_logic;
signal PLL_LOCKED2 : std_logic;
signal PLL_LOCKED3 : std_logic;
signal RESETn : std_logic;
signal RESET_COUNTER : unsigned(1 downto 0);
signal RESET_COUNTER : unsigned(5 downto 0);
begin
-- Instantiate a PLL to generate the system clock and base video clocks.
@@ -97,7 +99,7 @@ begin
port map
(
inclk0 => CLOCK_50,
areset => not VRESETn,
areset => '0',
c0 => SYS_CLK,
c1 => IF_CLK,
c2 => VIDCLK_8MHZ,
@@ -117,6 +119,16 @@ begin
locked => PLL_LOCKED2
);
-- Instantiate a 3rd PLL to generate clock for pseudo monochrome generation on internal monitor.
VCPLL3 : entity work.Video_Clock_III
port map
(
inclk0 => CLOCK_50,
areset => not VRESETn,
c0 => VIDCLK_PSEUDO,
locked => PLL_LOCKED3
);
-- Add the Serial Flash Loader megafunction to enable in-situ programming of the EPCS16 configuration memory.
--
SFL : entity work.sfl
@@ -139,6 +151,7 @@ begin
VIDCLK_65MHZ => VIDCLK_65MHZ, -- 65MHz base clock for video timing and gate clocking.
VIDCLK_25_175MHZ => VIDCLK_25_175MHZ, -- 25.175MHz base clock for video timing and gate clocking.
VIDCLK_40MHZ => VIDCLK_40MHZ, -- 40MHz base clock for video timing and gate clocking.
VIDCLK_PSEUDO => VIDCLK_PSEUDO, -- Clock to create pixel slicing to generate pseudo monochrome.
-- V[name] = Voltage translated signals which mirror the mainboard signals but at a lower voltage.
-- Addres Bus
@@ -179,12 +192,12 @@ begin
-- Process to reset the FPGA based on the external RESET trigger, PLL's being locked
-- and a counter to set minimum width.
--
FPGARESET: process(VRESETn, CLOCK_50, PLL_LOCKED, PLL_LOCKED2)
FPGARESET: process(VRESETn, CLOCK_50, PLL_LOCKED, PLL_LOCKED2, PLL_LOCKED3)
begin
if VRESETn = '0' then
RESET_COUNTER <= (others => '1');
RESETn <= '0';
elsif PLL_LOCKED = '1' and PLL_LOCKED2 = '1' then
elsif PLL_LOCKED = '1' and PLL_LOCKED2 = '1' and PLL_LOCKED3 = '1' then
if rising_edge(CLOCK_50) then
if RESET_COUNTER /= 0 then
RESET_COUNTER <= RESET_COUNTER - 1;

View File

@@ -264,6 +264,7 @@ set_global_assignment -name VHDL_FILE ../VideoController_Toplevel.vhd
set_global_assignment -name QIP_FILE SFL.qip
set_global_assignment -name QIP_FILE Video_Clock.qip
set_global_assignment -name QIP_FILE Video_Clock_II.qip
set_global_assignment -name QIP_FILE Video_Clock_III.qip
set_global_assignment -name QIP_FILE vbuffer.qip
set_global_assignment -name VHDL_FILE ../VideoController_pkg.vhd
set_global_assignment -name VHDL_FILE ../VideoController.vhd
@@ -280,4 +281,5 @@ set_global_assignment -name SDC_FILE VideoController_constraints.sdc
set_instance_assignment -name PARTITION_HIERARCHY root_partition -to | -section_id Top

View File

@@ -140,12 +140,12 @@ BEGIN
altpll_component : altpll
GENERIC MAP (
bandwidth_type => "LOW",
clk0_divide_by => 4800,
clk0_divide_by => 25,
clk0_duty_cycle => 50,
clk0_multiply_by => 1007,
clk0_multiply_by => 64,
clk0_phase_shift => "0",
compensate_clock => "CLK0",
inclk0_input_frequency => 8333,
inclk0_input_frequency => 20000,
intended_device_family => "Cyclone III",
lpm_hint => "CBX_MODULE_PREFIX=Video_Clock_III",
lpm_type => "altpll",
@@ -227,7 +227,7 @@ END SYN;
-- Retrieval info: PRIVATE: DEVICE_SPEED_GRADE STRING "8"
-- Retrieval info: PRIVATE: DIV_FACTOR0 NUMERIC "1"
-- Retrieval info: PRIVATE: DUTY_CYCLE0 STRING "50.00000000"
-- Retrieval info: PRIVATE: EFF_OUTPUT_FREQ_VALUE0 STRING "25.174999"
-- Retrieval info: PRIVATE: EFF_OUTPUT_FREQ_VALUE0 STRING "128.000000"
-- 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"
@@ -235,7 +235,7 @@ END SYN;
-- Retrieval info: PRIVATE: GLOCKED_MODE_CHECK STRING "0"
-- Retrieval info: PRIVATE: GLOCK_COUNTER_EDIT NUMERIC "1048575"
-- Retrieval info: PRIVATE: HAS_MANUAL_SWITCHOVER STRING "1"
-- Retrieval info: PRIVATE: INCLK0_FREQ_EDIT STRING "120.000"
-- Retrieval info: PRIVATE: INCLK0_FREQ_EDIT STRING "50.000"
-- Retrieval info: PRIVATE: INCLK0_FREQ_UNIT_COMBO STRING "MHz"
-- Retrieval info: PRIVATE: INCLK1_FREQ_EDIT STRING "100.000"
-- Retrieval info: PRIVATE: INCLK1_FREQ_EDIT_CHANGED STRING "1"
@@ -252,7 +252,7 @@ END SYN;
-- Retrieval info: PRIVATE: MIRROR_CLK0 STRING "0"
-- Retrieval info: PRIVATE: MULT_FACTOR0 NUMERIC "1"
-- Retrieval info: PRIVATE: NORMAL_MODE_RADIO STRING "1"
-- Retrieval info: PRIVATE: OUTPUT_FREQ0 STRING "25.17500000"
-- Retrieval info: PRIVATE: OUTPUT_FREQ0 STRING "128.00000000"
-- Retrieval info: PRIVATE: OUTPUT_FREQ_MODE0 STRING "1"
-- Retrieval info: PRIVATE: OUTPUT_FREQ_UNIT0 STRING "MHz"
-- Retrieval info: PRIVATE: PHASE_RECONFIG_FEATURE_ENABLED STRING "1"
@@ -291,12 +291,12 @@ 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 "LOW"
-- Retrieval info: CONSTANT: CLK0_DIVIDE_BY NUMERIC "4800"
-- Retrieval info: CONSTANT: CLK0_DIVIDE_BY NUMERIC "25"
-- Retrieval info: CONSTANT: CLK0_DUTY_CYCLE NUMERIC "50"
-- Retrieval info: CONSTANT: CLK0_MULTIPLY_BY NUMERIC "1007"
-- Retrieval info: CONSTANT: CLK0_MULTIPLY_BY NUMERIC "64"
-- Retrieval info: CONSTANT: CLK0_PHASE_SHIFT STRING "0"
-- Retrieval info: CONSTANT: COMPENSATE_CLOCK STRING "CLK0"
-- Retrieval info: CONSTANT: INCLK0_INPUT_FREQUENCY NUMERIC "8333"
-- Retrieval info: CONSTANT: INCLK0_INPUT_FREQUENCY NUMERIC "20000"
-- Retrieval info: CONSTANT: INTENDED_DEVICE_FAMILY STRING "Cyclone III"
-- Retrieval info: CONSTANT: LPM_TYPE STRING "altpll"
-- Retrieval info: CONSTANT: OPERATION_MODE STRING "NORMAL"