There is some example code available from Numato Labs which shows the FPGA is working and places a message on the screen. That code is available from their github repository here:
Numato Labs VGA Sample Code
In order to get something working as quickly as possible I forked that code. The easiest thing to do is to load up Xilinx WebISE and start a new project for the Mimas V2 with the correct parameters. I have gone through this process in other blog posts before so I'm not going to repeat myself. Give the project a suitable name - I called mine Mimas2_VGA but anything sensible will do.
Next add a new source file - a VHDL Module and give it a suitable name I called mine VGA_display - don't worry about providing any inputs or outputs. This will be added when the code is written.
Next add another new source file, again a VHDL Module and call this file VGA_Synch - No inputs or outputs are needed as the code will be supplied as required.
Add another source file - a VHDL Module and call it clocking_Instant - don't add any inputs or outputs as the code will be supplied.
Add another source file - a VHDL Module - call it VGA_top_module - don't add any inputs or outputs as the code will be supplied.
Add yet another source file - An Implementation Constraints file - call it something sensible - I called mine VGA_sync.ucf
The hierachy window should look something like this:
Next ensure the VGA_top_module file is open in the text editor in Xilinx WebISE and copy and paste the code below into the text editor:
--------------------------------------------------------------------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;
entity VGA_top_module is
GENERIC (
BoardDescription : STRING := "NUMATO LAB Mimas V2";
DeviceDescripition : STRING := "SPARTAN6 LX9";
ClockFrequency : INTEGER := 100_000_000;
VGAResolution : STRING := "640x480 @ 60Hz";
NumberOfVGAColor : INTEGER := 3
);
PORT (
-- Inputs
-- Mimas V2 has a 100MHz input clock and an active Low reset.
CLK : IN STD_LOGIC;
RST_n : IN STD_LOGIC;
-- Outputs
-- VGA Display
HSync : OUT STD_LOGIC;
VSync : OUT STD_LOGIC;
Red : OUT STD_LOGIC_VECTOR(NumberOfVGAColor-1 downto 0);
Green : OUT STD_LOGIC_VECTOR(NumberOfVGAColor-1 downto 0);
Blue : OUT STD_LOGIC_VECTOR(NumberOfVGAColor-1 downto 1)
);
end VGA_top_module;
architecture Behavioral of VGA_top_module is
component clocking
port (
--Input clock 100 MHz
CLK_IN : in std_logic;
--Output
CLK_100MHz : out std_logic;
CLK_50MHz : out std_logic);
end component;
component VGA_Synch
generic (
VGAResolution : STRING ;
NumberOfVGAColor : INTEGER);
port (
-- Input clock 100 MHz
CLK : in std_logic;
RST_n : in std_logic;
-- Output
HSync : out std_logic;
VSync : out std_logic;
Red : out std_logic_vector(NumberOfVGAColor-1 downto 0);
Green : out std_logic_vector(NumberOfVGAColor-1 downto 0);
Blue : out std_logic_vector(NumberOfVGAColor-1 downto 1));
end component;
signal CLK_100MHz : std_logic := '0';
signal CLK_50MHz : std_logic := '0';
begin
clocking_Instant : clocking
port map (
CLK_IN => CLK,
CLK_100MHz => CLK_100MHz,
CLK_50MHz => CLK_50MHz);
VGA_instant : VGA_Synch
generic map(
VGAResolution => VGAResolution,
NumberOfVGAColor => NumberOfVGAColor)
port map (
CLK => CLK_50MHz,
RST_n => RST_n,
hsync => hsync,
vsync => vsync,
Red => Red,
Green => Green,
Blue => Blue);
end Behavioral;
--------------------------------------------------------------------------------------------------------------------------
Save the file - Always a good idea!!! I wasn't going to explain the code function line by line - Basically it defines the FPGA development board, sets the value for the source clock to 100 MHz, sets the video output resolution to be 640 by 480 with a refresh rate of 60 Hz and the number of colours available to be three (Red, Green and Blue).
Next the inputs and outputs are set. The inputs are the 100 MHz clock and the reset pin and the output is the VGA connector.
Then the code calls for some components:
- clocking (Call some external code clock generator code which takes the 100 MHz source clock and creates a 100 MHz clock and a 50 MHz clock)
- VGA_Synch (Call some external code which drives the VGA port on the FPGA development board)
Next some internal signals are created for the two new clock signals
Next the components are instantiated and the signals are mapped between the files.
I hope that was clear!!!
Next open the file clocking.vhd into the text editor in Xilinx WebISE and copy and paste the code below into it:
-----------------------------------------------------------------
-- file: clocking.vhd
--
-- (c) Copyright 2008 - 2011 Xilinx, Inc. All rights reserved.
--
-- This file contains confidential and proprietary information
-- of Xilinx, Inc. and is protected under U.S. and
-- international copyright and other intellectual property
-- laws.
--
-- DISCLAIMER
-- This disclaimer is not a license and does not grant any
-- rights to the materials distributed herewith. Except as
-- otherwise provided in a valid license issued to you by
-- Xilinx, and to the maximum extent permitted by applicable
-- law: (1) THESE MATERIALS ARE MADE AVAILABLE "AS IS" AND
-- WITH ALL FAULTS, AND XILINX HEREBY DISCLAIMS ALL WARRANTIES
-- AND CONDITIONS, EXPRESS, IMPLIED, OR STATUTORY, INCLUDING
-- BUT NOT LIMITED TO WARRANTIES OF MERCHANTABILITY, NON-
-- INFRINGEMENT, OR FITNESS FOR ANY PARTICULAR PURPOSE; and
-- (2) Xilinx shall not be liable (whether in contract or tort,
-- including negligence, or under any other theory of
-- liability) for any loss or damage of any kind or nature
-- related to, arising under or in connection with these
-- materials, including for any direct, or any indirect,
-- special, incidental, or consequential loss or damage
-- (including loss of data, profits, goodwill, or any type of
-- loss or damage suffered as a result of any action brought
-- by a third party) even if such damage or loss was
-- reasonably foreseeable or Xilinx had been advised of the
-- possibility of the same.
--
-- CRITICAL APPLICATIONS
-- Xilinx products are not designed or intended to be fail-
-- safe, or for use in any application requiring fail-safe
-- performance, such as life-support or safety devices or
-- systems, Class III medical devices, nuclear facilities,
-- applications related to the deployment of airbags, or any
-- other applications that could lead to death, personal
-- injury, or severe property or environmental damage
-- (individually and collectively, "Critical
-- Applications"). Customer assumes the sole risk and
-- liability of any use of Xilinx products in Critical
-- Applications, subject only to applicable laws and
-- regulations governing limitations on product liability.
--
-- THIS COPYRIGHT NOTICE AND DISCLAIMER MUST BE RETAINED AS
-- PART OF THIS FILE AT ALL TIMES.
--
------------------------------------------------------------------------------
-- User entered comments
------------------------------------------------------------------------------
-- None
--
------------------------------------------------------------------------------
-- "Output Output Phase Duty Pk-to-Pk Phase"
-- "Clock Freq (MHz) (degrees) Cycle (%) Jitter (ps) Error (ps)"
------------------------------------------------------------------------------
-- CLK_OUT1___100.000______0.000______50.0______200.000____150.000
-- CLK_OUT2____50.000______0.000______50.0______300.000____150.000
--
------------------------------------------------------------------------------
-- "Input Clock Freq (MHz) Input Jitter (UI)"
------------------------------------------------------------------------------
-- __primary_________100.000____________0.010
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
use ieee.std_logic_arith.all;
use ieee.numeric_std.all;
library unisim;
use unisim.vcomponents.all;
entity clocking is
port
(-- Clock in ports
CLK_IN : in std_logic;
-- Clock out ports
CLK_100MHz : out std_logic;
CLK_50MHz : out std_logic
);
end clocking;
architecture xilinx of clocking is
attribute CORE_GENERATION_INFO : string;
attribute CORE_GENERATION_INFO of xilinx : architecture is "clocking,clk_wiz_v3_6,{component_name=clocking,use_phase_alignment=true,use_min_o_jitter=false,use_max_i_jitter=false,use_dyn_phase_shift=false,use_inclk_switchover=false,use_dyn_reconfig=false,feedback_source=FDBK_AUTO,primtype_sel=DCM_SP,num_out_clk=2,clkin1_period=10.0,clkin2_period=10.0,use_power_down=false,use_reset=false,use_locked=false,use_inclk_stopped=false,use_status=false,use_freeze=false,use_clk_valid=false,feedback_type=SINGLE,clock_mgr_type=AUTO,manual_override=false}";
-- Input clock buffering / unused connectors
signal clkin1 : std_logic;
-- Output clock buffering
signal clk_out1_internal : std_logic;
signal clkfb : std_logic;
signal clk0 : std_logic;
signal clkdv : std_logic;
signal clkfbout : std_logic;
signal locked_internal : std_logic;
signal status_internal : std_logic_vector(7 downto 0);
begin
-- Input buffering
--------------------------------------
clkin1_buf : IBUFG
port map
(O => clkin1,
I => CLK_IN);
-- Clocking primitive
--------------------------------------
-- Instantiation of the DCM primitive
-- * Unused inputs are tied off
-- * Unused outputs are labeled unused
dcm_sp_inst: DCM_SP
generic map
(CLKDV_DIVIDE => 2.000,
CLKFX_DIVIDE => 1,
CLKFX_MULTIPLY => 4,
CLKIN_DIVIDE_BY_2 => FALSE,
CLKIN_PERIOD => 10.0,
CLKOUT_PHASE_SHIFT => "NONE",
CLK_FEEDBACK => "1X",
DESKEW_ADJUST => "SYSTEM_SYNCHRONOUS",
PHASE_SHIFT => 0,
STARTUP_WAIT => FALSE)
port map
-- Input clock
(CLKIN => clkin1,
CLKFB => clkfb,
-- Output clocks
CLK0 => clk0,
CLK90 => open,
CLK180 => open,
CLK270 => open,
CLK2X => open,
CLK2X180 => open,
CLKFX => open,
CLKFX180 => open,
CLKDV => clkdv,
-- Ports for dynamic phase shift
PSCLK => '0',
PSEN => '0',
PSINCDEC => '0',
PSDONE => open,
-- Other control and status signals
LOCKED => locked_internal,
STATUS => status_internal,
RST => '0',
-- Unused pin, tie low
DSSEN => '0');
-- Output buffering
-------------------------------------
clkfb <= clk_out1_internal;
clkout1_buf : BUFG
port map
(O => clk_out1_internal,
I => clk0);
CLK_100MHz <= clk_out1_internal;
clkout2_buf : BUFG
port map
(O => CLK_50MHz,
I => clkdv);
end xilinx;
--------------------------------------------------------------------------------------------------------------------------
Please don't ask me what this does as I don't know exactly! I believe it takes in the 100 MHz external clock and creates two new clock signals - a 100 MHz clock and a 50 MHz clock. It looks like the output from the DCM_clocking generator that was available for the Spartan 3A device used on the Elbert V2 board. The same IP code generator is not available for the Spartan 6 which is why I suspect Numato have just provided code as is...
Now open the file VGA_Synch.vhd into the text editor and copy and paste in the code below:
--------------------------------------------------------------------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;
library work;
entity VGA_Synch is
generic ( VGAResolution : STRING := "640x480 @ 60Hz";
NumberOfVGAColor : INTEGER := 3);
Port ( CLK : in STD_LOGIC;
RST_n : in STD_LOGIC;
HSync : out STD_LOGIC;
VSync : out STD_LOGIC;
Red : out STD_LOGIC_VECTOR (NumberOfVGAColor-1 downto 0);
Green : out STD_LOGIC_VECTOR (NumberOfVGAColor-1 downto 0);
Blue : out STD_LOGIC_VECTOR (NumberOfVGAColor-1 downto 1));
end VGA_Synch;
architecture Behavioral of VGA_Synch is
-- Intermediate register used internally
signal rgb : std_logic_vector(7 downto 0);
-- Set the resolution of screen
signal hCount : integer range 0 to 1023 := 640;
signal vCount : integer range 0 to 1023 := 480;
-- Set the count from where it should start
signal nextHCount : integer range 0 to 1023 := 641;
signal nextVCount : integer range 0 to 1023 := 480;
begin
-- Instantiate the file which contain the things to be displayed.
-- The clock which should be given here is 50MHz,so that the data is properly
-- obtained has the output is latched to VGA pins at 25MHz.
output : entity work.VGA_display
port map(clock => CLK,
hcounter => nextHCount,
vcounter => nextVCount,
pixels => rgb);
-- The process is carried out for every positive edge of the clock i.e, 50 MHz
-- clock(clock).
vgasignal: process(CLK,RST_n)
variable divide_by_2 : std_logic := '0';
begin
if (RST_n = '0') then
hCount <= 640;
vCount <= 480;
elsif rising_edge(CLK) then
-- Scale down the 50 MHz to 25 MHz so that the signal is
-- latched properly.
if divide_by_2 = '1' then
-- Maximum Horizontal count is limited to 799 for 640 x 480
-- display so that it fit's the screen.
if(hCount = 799) then
hCount <= 0;
-- Maximum Vertical count is limited to 524 for 640 x 480
-- display so that it fit's the screen.
if(vCount = 524) then
vCount <= 0;
else
vCount <= vCount + 1;
end if;
else
hCount <= hCount + 1;
end if;
-- Make sure we got the roll over covered
if (nextHCount = 799) then
nextHCount <= 0;
-- Make sure we got the roll over covered
if (nextVCount = 524) then
nextVCount <= 0;
else
nextVCount <= vCount + 1;
end if;
else
nextHCount <= hCount + 1;
end if;
-- Check if the count is within the minimum and maximum value for
-- proper generation of the vertical sync signal
if (vCount >= 490 and vCount < 492) then
VSync <= '0';
else
VSync <= '1';
end if;
-- Check if the count is within the minimum and maximum value for
-- proper generation of the horizontal sync signal
if (hCount >= 656 and hCount < 752) then
HSync <= '0';
else
HSync <= '1';
end if;
-- If in display range then display the pixel.
if (hCount < 640 and vCount < 480) then
Red <= rgb (7 downto 5);
Green <= rgb (4 downto 2);
Blue <= rgb (1 downto 0);
end if;
end if;
divide_by_2 := not divide_by_2;
end if;
end process;
end Behavioral;
--------------------------------------------------------------------------------------------------------------------------
The first lines above the entity statment ensure the required library files are included, then the entity statement is written. In VHDL an entity statement define the pins that interact with the actual FPGA device. In this case we are defining pins which control the clock and the VGA control pins.
Next comes the architecture begin statement. The next lines of code basically tell the system that there will be another text file which contains the code for actually placing what the designer would like on the display. The parameters which will be passed to the new file which will be called VGA_display are clock, nextHCount and nextVCount and finally rgb.
Immediately below that is a process (kind of like a function) which divides the 100 MHz clock to
50 MHz. It does this by inverting the Clk signal when that signal is positive. It then copies the state of the Clk to the clock variable which halves the frequency of the clock.
Immediately below that is a process (kind of like a function) which divides the 100 MHz clock to
50 MHz. It does this by inverting the Clk signal when that signal is positive. It then copies the state of the Clk to the clock variable which halves the frequency of the clock.
The next lines of code check if an entire scanline has been drawn and resets the hCount to zero if this is the case. The same check is performed on the vCount to see if an entire frame has been drawn. If it has then the vCount is reset. If neither hCount or vCount has reached it's limit they are incremented and the process continues.
The next lines of code check if the hCount variable has reached the limit for the display resolution.
If it has the count is restarted. The same check is performed on the vCount and if so then the vCount
is restarted.
Finally the next lines of code invert the clock divider and then close off the open if statements and end the process.
Lets open the file VGA_display.vhd and copy and paste the code below into it:
---------------------------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;
entity VGA_display is
-- Define the width and the height of the displayed text.
generic(
OutputWidth : integer := 10;
OutputHeight : integer := 40
);
port (
-- Assuming 50MHz clock.
clock: in std_logic;
-- The counter tells whether the correct position on the screen is reached
hcounter: in integer range 0 to 1023;
vcounter: in integer range 0 to 1023;
-- Output the colour that should appear on the screen.
pixels : out std_logic_vector(7 downto 0) );
end VGA_display;
architecture Behavioral of VGA_display is
-- Intermediate register telling the exact position on display on screen.
signal x : integer range 0 to 1023 := 100;
signal y : integer range 0 to 1023 := 80;
begin
-- On every positive edge of the clock counter condition is checked,
output1: process(clock)
begin
if rising_edge (clock) then
--change the if statements below to draw shapes
--change the pixels <= FF to change colours
-- FF = White
-- 00 = Black
-- F0 = Orange
-- Draw a single pixel in the
-- centre of the screen
if (hcounter = 320) and (vcounter = 240)
then pixels <= x"FF"; else
pixels <= x"00";
end if;
end if;
end process;
end Behavioral;
--------------------------------------------------------------------------------------------------------------------------
Save the file....in fact save everything! The code above is the VHDL code which actually defines what will be displayed on the screen. It connects its outputs to the inputs in the other files and selects which parts of the display with have colours present and which parts will be black.
Next open the file VGA_Sync.ucf into the text editor in WebISE and copy and paste the code below:
#+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++#
# This file is a .ucf for Mimas V2 #
# To use it in your project : #
# * Remove or comment the lines corresponding to unused pins in the project #
# * Rename the used signals according to the your project #
#+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++#
CONFIG VCCAUX = "3.3" ;
NET "CLK" LOC = V10 | IOSTANDARD = LVCMOS33 | PERIOD = 100MHz;
NET "RST_n" IOSTANDARD = LVCMOS33 | PULLUP;
#################################################################################
# VGA #
#################################################################################
NET "HSync" LOC = B12 | IOSTANDARD = LVCMOS33 | DRIVE = 8 | SLEW = FAST ;
NET "VSync" LOC = A12 | IOSTANDARD = LVCMOS33 | DRIVE = 8 | SLEW = FAST ;
NET "Red[2]" LOC = C9 | IOSTANDARD = LVCMOS33 | DRIVE = 8 | SLEW = FAST ;
NET "Red[1]" LOC = B9 | IOSTANDARD = LVCMOS33 | DRIVE = 8 | SLEW = FAST ;
NET "Red[0]" LOC = A9 | IOSTANDARD = LVCMOS33 | DRIVE = 8 | SLEW = FAST ;
NET "Green[2]" LOC = C11 | IOSTANDARD = LVCMOS33 | DRIVE = 8 | SLEW = FAST ;
NET "Green[1]" LOC = A10 | IOSTANDARD = LVCMOS33 | DRIVE = 8 | SLEW = FAST ;
NET "Green[0]" LOC = C10 | IOSTANDARD = LVCMOS33 | DRIVE = 8 | SLEW = FAST ;
NET "Blue[2]" LOC = A11 | IOSTANDARD = LVCMOS33 | DRIVE = 8 | SLEW = FAST ;
NET "Blue[1]" LOC = B11 | IOSTANDARD = LVCMOS33 | DRIVE = 8 | SLEW = FAST ;
--------------------------------------------------------------------------------------------------------------------------
Here is what the screen should look like if everything has gone according to plan:
Go back to the file VGA_display.vhd and load that into the text editor.
Shapes are drawn on the screen by changing or expanding the following If statement:
if (hcounter = 320) and (vcounter = 240)
then pixels <= x"FF";
At the moment a single white dot will be displayed in the centre of the monitor. If a white square in the centre of the monitor was required then the following statement might be suitable:
if (hcounter >= 310) and (hcounter <= 330) and (vcounter >= 230) and (vcounter <= 250) then pixels <= x"FF";
This will create a twenty by twenty pixel white square in the centre of the display. The rest of the display will be black. The colour could be changed by changing the value for pixels from FF to something else.
If it has the count is restarted. The same check is performed on the vCount and if so then the vCount
is restarted.
Finally the next lines of code invert the clock divider and then close off the open if statements and end the process.
Lets open the file VGA_display.vhd and copy and paste the code below into it:
---------------------------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;
entity VGA_display is
-- Define the width and the height of the displayed text.
generic(
OutputWidth : integer := 10;
OutputHeight : integer := 40
);
port (
-- Assuming 50MHz clock.
clock: in std_logic;
-- The counter tells whether the correct position on the screen is reached
hcounter: in integer range 0 to 1023;
vcounter: in integer range 0 to 1023;
-- Output the colour that should appear on the screen.
pixels : out std_logic_vector(7 downto 0) );
end VGA_display;
architecture Behavioral of VGA_display is
-- Intermediate register telling the exact position on display on screen.
signal x : integer range 0 to 1023 := 100;
signal y : integer range 0 to 1023 := 80;
begin
-- On every positive edge of the clock counter condition is checked,
output1: process(clock)
begin
if rising_edge (clock) then
--change the if statements below to draw shapes
--change the pixels <= FF to change colours
-- FF = White
-- 00 = Black
-- F0 = Orange
-- Draw a single pixel in the
-- centre of the screen
if (hcounter = 320) and (vcounter = 240)
then pixels <= x"FF"; else
pixels <= x"00";
end if;
end if;
end process;
end Behavioral;
--------------------------------------------------------------------------------------------------------------------------
Save the file....in fact save everything! The code above is the VHDL code which actually defines what will be displayed on the screen. It connects its outputs to the inputs in the other files and selects which parts of the display with have colours present and which parts will be black.
Next open the file VGA_Sync.ucf into the text editor in WebISE and copy and paste the code below:
#+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++#
# This file is a .ucf for Mimas V2 #
# To use it in your project : #
# * Remove or comment the lines corresponding to unused pins in the project #
# * Rename the used signals according to the your project #
#+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++#
CONFIG VCCAUX = "3.3" ;
NET "CLK" LOC = V10 | IOSTANDARD = LVCMOS33 | PERIOD = 100MHz;
NET "RST_n" IOSTANDARD = LVCMOS33 | PULLUP;
#################################################################################
# VGA #
#################################################################################
NET "HSync" LOC = B12 | IOSTANDARD = LVCMOS33 | DRIVE = 8 | SLEW = FAST ;
NET "VSync" LOC = A12 | IOSTANDARD = LVCMOS33 | DRIVE = 8 | SLEW = FAST ;
NET "Red[2]" LOC = C9 | IOSTANDARD = LVCMOS33 | DRIVE = 8 | SLEW = FAST ;
NET "Red[1]" LOC = B9 | IOSTANDARD = LVCMOS33 | DRIVE = 8 | SLEW = FAST ;
NET "Red[0]" LOC = A9 | IOSTANDARD = LVCMOS33 | DRIVE = 8 | SLEW = FAST ;
NET "Green[2]" LOC = C11 | IOSTANDARD = LVCMOS33 | DRIVE = 8 | SLEW = FAST ;
NET "Green[1]" LOC = A10 | IOSTANDARD = LVCMOS33 | DRIVE = 8 | SLEW = FAST ;
NET "Green[0]" LOC = C10 | IOSTANDARD = LVCMOS33 | DRIVE = 8 | SLEW = FAST ;
NET "Blue[2]" LOC = A11 | IOSTANDARD = LVCMOS33 | DRIVE = 8 | SLEW = FAST ;
NET "Blue[1]" LOC = B11 | IOSTANDARD = LVCMOS33 | DRIVE = 8 | SLEW = FAST ;
--------------------------------------------------------------------------------------------------------------------------
Here is what the screen should look like if everything has gone according to plan:
Go back to the file VGA_display.vhd and load that into the text editor.
Shapes are drawn on the screen by changing or expanding the following If statement:
if (hcounter = 320) and (vcounter = 240)
then pixels <= x"FF";
At the moment a single white dot will be displayed in the centre of the monitor. If a white square in the centre of the monitor was required then the following statement might be suitable:
if (hcounter >= 310) and (hcounter <= 330) and (vcounter >= 230) and (vcounter <= 250) then pixels <= x"FF";
This will create a twenty by twenty pixel white square in the centre of the display. The rest of the display will be black. The colour could be changed by changing the value for pixels from FF to something else.
By writing some clever code or loops it should be more than possible to create complex shapes and frames as needed.
Save everything one more time just to be sure all is well and then click on the green arrow to implement the top module - wait for the processes to complete...some time later!
Then create a bit file and upload it to the Mimas V2:
If all went according to plan you should see something like the image below:
If anyone needs the project code it is available here:
That's all for now - take care people!
You are a legend bro, the first freaking useful post about FPGAs and how to work with its VGA module
ReplyDelete