diff options
| author | github-classroom[bot] <66690702+github-classroom[bot]@users.noreply.github.com> | 2026-02-05 19:36:36 +0000 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2026-02-05 19:36:36 +0000 |
| commit | ead28dd6fed440ccf4667c459778012bb0d95733 (patch) | |
| tree | bbc326fa1b487efc0fe163ef733a76c8a241fbb0 /vga-core | |
Initial commit
Diffstat (limited to 'vga-core')
| -rw-r--r-- | vga-core/de1_vga_gui.tcl | 107 | ||||
| -rw-r--r-- | vga-core/vga_adapter.sv | 283 | ||||
| -rw-r--r-- | vga-core/vga_adapter.v | 263 | ||||
| -rw-r--r-- | vga-core/vga_address_translator.sv | 39 | ||||
| -rw-r--r-- | vga-core/vga_address_translator.v | 35 | ||||
| -rw-r--r-- | vga-core/vga_controller.sv | 216 | ||||
| -rw-r--r-- | vga-core/vga_controller.v | 212 | ||||
| -rw-r--r-- | vga-core/vga_pll.sv | 173 | ||||
| -rw-r--r-- | vga-core/vga_pll.v | 173 |
9 files changed, 1501 insertions, 0 deletions
diff --git a/vga-core/de1_vga_gui.tcl b/vga-core/de1_vga_gui.tcl new file mode 100644 index 0000000..a6a3a4a --- /dev/null +++ b/vga-core/de1_vga_gui.tcl @@ -0,0 +1,107 @@ +# vim: set sw=4 ai cin et: + +# NOTE: this must be sychronized with VGA adaptor module + + +if { [namespace exists ::de1vga] } { namespace delete ::de1vga } + +namespace eval ::de1vga { + namespace eval var { + set zoom 4 + set width 160 + set height 120 + set bg "#808080" + set count 0 + } + + + proc init {} { + if ({[winfo exists .de1vga]}) { destroy .de1vga } + + toplevel .de1vga -padx 5 -pady 5 + wm title .de1vga "fake VGA screen" + + frame .de1vga.draw + pack .de1vga.draw -expand 1 -fill both + + frame .de1vga.status + button .de1vga.status.reset -width 5 -relief ridge -text "CLEAR" -command [namespace code reset] + label .de1vga.status.count_legend -text " count:" + label .de1vga.status.count_val -relief groove -width 10 + + label .de1vga.status.drawn_legend -text "last:" + label .de1vga.status.drawn_pos -relief groove -width 7 + label .de1vga.status.click_legend -text " clicked:" + label .de1vga.status.click_pos -relief groove -width 7 + label .de1vga.status.mouse_legend -text " mouse:" + label .de1vga.status.mouse_pos -relief groove -width 7 + pack .de1vga.status.reset .de1vga.status.count_legend .de1vga.status.count_val -side left + pack .de1vga.status.mouse_pos .de1vga.status.mouse_legend .de1vga.status.click_pos .de1vga.status.click_legend \ + .de1vga.status.drawn_pos .de1vga.status.drawn_legend -side right + pack .de1vga.status -side bottom -fill x + .de1vga.status.drawn_pos configure -text "-,-" + .de1vga.status.mouse_pos configure -text "-,-" + .de1vga.status.click_pos configure -text "-,-" + + set w [expr $var::width * $var::zoom] + set h [expr {$var::height * $var::zoom}] + canvas .de1vga.draw.c -width $w -height $h -bg $var::bg + pack .de1vga.draw.c -expand 1 -fill both + bind .de1vga.draw.c <Motion> [namespace code { show_mouse %x %y }] + bind .de1vga.draw.c <ButtonPress> [namespace code { show_click %x %y }] + bind .de1vga.draw.c <Leave> [namespace code { .de1vga.status.mouse_pos configure -text "-,-" }] + } + + proc reset {} { + .de1vga.draw.c create rectangle 0 0 [expr $var::width * $var::zoom - 1] [expr $var::height * $var::zoom - 1] -outline $var::bg -fill $var::bg + set var::count 0 + .de1vga.status.count_val configure -text "$var::count" + .de1vga.status.drawn_pos configure -text "-,-" + } + + proc rgb_to_hex {c} { + set b [expr ($c & 1) * 255] + set g [expr (($c >> 1) & 1) * 255] + set r [expr (($c >> 2) & 1) * 255] + return [format "#%02x%02x%02x" $r $g $b] + } + + proc plot {x y c} { + if !({[winfo exists .de1vga]}) {init} + + set x [string tolower $x] + set y [string tolower $y] + set c [string tolower $c] + if { [string equal $x "x"] || [string equal $x "z" ]} { return } + if { [string equal $y "x"] || [string equal $y "z" ]} { return } + if { [string equal $c "x"] || [string equal $c "z" ]} { return } + if {[expr $x < 0]} { return } + if {[expr $x >= $var::width]} { return } + if {[expr $y < 0]} { return } + if {[expr $y >= $var::height]} { return } + if !({[winfo exists .de1vga]}) { init } + set x0 [expr $x * $var::zoom] + set y0 [expr $y * $var::zoom] + set x1 [expr ($x+1) * $var::zoom - 1] + set y1 [expr ($y+1) * $var::zoom - 1] + set clr [rgb_to_hex $c] + .de1vga.draw.c create rectangle $x0 $y0 $x1 $y1 -outline $clr -fill $clr + incr var::count + .de1vga.status.count_val configure -text "$var::count" + .de1vga.status.drawn_pos configure -text "$x,$y:$c" + } + + proc show_mouse {x0 y0} { + set x [expr $x0 / $var::zoom] + set y [expr $y0 / $var::zoom] + .de1vga.status.mouse_pos configure -text "$x,$y" + } + + proc show_click {x0 y0} { + set x [expr $x0 / $var::zoom] + set y [expr $y0 / $var::zoom] + .de1vga.status.click_pos configure -text "$x,$y" + } +} + +namespace inscope ::de1vga init diff --git a/vga-core/vga_adapter.sv b/vga-core/vga_adapter.sv new file mode 100644 index 0000000..3b9209c --- /dev/null +++ b/vga-core/vga_adapter.sv @@ -0,0 +1,283 @@ +// synopsys translate_off +`timescale 1 ps / 1 ps +// synopsys translate_on + +/* VGA Adapter + * ---------------- + * + * This is an implementation of a VGA Adapter. The adapter uses VGA mode signalling to initiate + * a 640x480 resolution mode on a computer monitor, with a refresh rate of approximately 60Hz. + * It is designed for easy use in an early digital logic design course to facilitate student + * projects on the Altera DE2 Educational board. + * + * This implementation of the VGA adapter can display images of varying colour depth at a resolution of + * 320x240 or 160x120 superpixels. The concept of superpixels is introduced to reduce the amount of on-chip + * memory used by the adapter. The following table shows the number of bits of on-chip memory used by + * the adapter in various resolutions and colour depths. + * + * ------------------------------------------------------------------------------------------------------------------------------- + * Resolution | Mono | 8 colours | 64 colours | 512 colours | 4096 colours | 32768 colours | 262144 colours | 2097152 colours | + * ------------------------------------------------------------------------------------------------------------------------------- + * 160x120 | 19200 | 57600 | 115200 | 172800 | 230400 | 288000 | 345600 | 403200 | + * 320x240 | 78600 | 230400 | ############## Does not fit ############################################################## | + * ------------------------------------------------------------------------------------------------------------------------------- + * + * By default the adapter works at the resolution of 320x240 with 8 colours. To set the adapter in any of + * the other modes, the adapter must be instantiated with specific parameters. These parameters are: + * - RESOLUTION - a string that should be either "320x240" or "160x120". + * - MONOCHROME - a string that should be "TRUE" if you only want black and white colours, and "FALSE" + * otherwise. + * - BITS_PER_COLOUR_CHANNEL - an integer specifying how many bits are available to describe each colour + * (R,G,B). A default value of 1 indicates that 1 bit will be used for red + * channel, 1 for green channel and 1 for blue channel. This allows 8 colours + * to be used. + * + * In addition to the above parameters, a BACKGROUND_IMAGE parameter can be specified. The parameter + * refers to a memory initilization file (MIF) which contains the initial contents of video memory. + * By specifying the initial contents of the memory we can force the adapter to initially display an + * image of our choice. Please note that the image described by the BACKGROUND_IMAGE file will only + * be valid right after your program the DE2 board. If your circuit draws a single pixel on the screen, + * the video memory will be altered and screen contents will be changed. In order to restore the background + * image your circuti will have to redraw the background image pixel by pixel, or you will have to + * reprogram the DE2 board, thus allowing the video memory to be rewritten. + * + * To use the module connect the vga_adapter to your circuit. Your circuit should produce a value for + * inputs X, Y and plot. When plot is high, at the next positive edge of the input clock the vga_adapter + * will change the contents of the video memory for the pixel at location (X,Y). At the next redraw + * cycle the VGA controller will update the contants of the screen by reading the video memory and copying + * it over to the screen. Since the monitor screen has no memory, the VGA controller has to copy the + * contents of the video memory to the screen once every 60th of a second to keep the image stable. Thus, + * the video memory should not be used for other purposes as it may interfere with the operation of the + * VGA Adapter. + * + * As a final note, ensure that the following conditions are met when using this module: + * 1. You are implementing the the VGA Adapter on the Altera DE2 board. Using another board may change + * the amount of memory you can use, the clock generation mechanism, as well as pin assignments required + * to properly drive the VGA digital-to-analog converter. + * 2. Outputs VGA_* should exist in your top level design. They should be assigned pin locations on the + * Altera DE2 board as specified by the DE2_pin_assignments.csv file. + * 3. The input clock must have a frequency of 50 MHz with a 50% duty cycle. On the Altera DE2 board + * PIN_N2 is the source for the 50MHz clock. + * + * During compilation with Quartus II you may receive the following warnings: + * - Warning: Variable or input pin "clocken1" is defined but never used + * - Warning: Pin "VGA_SYNC" stuck at VCC + * - Warning: Found xx output pins without output pin load capacitance assignment + * These warnings can be ignored. The first warning is generated, because the software generated + * memory module contains an input called "clocken1" and it does not drive logic. The second warning + * indicates that the VGA_SYNC signal is always high. This is intentional. The final warning is + * generated for the purposes of power analysis. It will persist unless the output pins are assigned + * output capacitance. Leaving the capacitance values at 0 pf did not affect the operation of the module. + * + * If you see any other warnings relating to the vga_adapter, be sure to examine them carefully. They may + * cause your circuit to malfunction. + * + * NOTES/REVISIONS: + * July 10, 2007 - Modified the original version of the VGA Adapter written by Sam Vafaee in 2006. The module + * now supports 2 different resolutions as well as uses half the memory compared to prior + * implementation. Also, all settings for the module can be specified from the point + * of instantiation, rather than by modifying the source code. (Tomasz S. Czajkowski) + */ + +module vga_adapter( + resetn, + clock, + colour, + x, y, plot, + /* Signals for the DAC to drive the monitor. */ + VGA_R, + VGA_G, + VGA_B, + VGA_HS, + VGA_VS, + VGA_BLANK, + VGA_SYNC, + VGA_CLK); + + parameter BITS_PER_COLOUR_CHANNEL = 1; + /* The number of bits per colour channel used to represent the colour of each pixel. A value + * of 1 means that Red, Green and Blue colour channels will use 1 bit each to represent the intensity + * of the respective colour channel. For BITS_PER_COLOUR_CHANNEL=1, the adapter can display 8 colours. + * In general, the adapter is able to use 2^(3*BITS_PER_COLOUR_CHANNEL ) colours. The number of colours is + * limited by the screen resolution and the amount of on-chip memory available on the target device. + */ + + parameter MONOCHROME = "FALSE"; + /* Set this parameter to "TRUE" if you only wish to use black and white colours. Doing so will reduce + * the amount of memory you will use by a factor of 3. */ + + parameter RESOLUTION = "320x240"; + /* Set this parameter to "160x120" or "320x240". It will cause the VGA adapter to draw each dot on + * the screen by using a block of 4x4 pixels ("160x120" resolution) or 2x2 pixels ("320x240" resolution). + * It effectively reduces the screen resolution to an integer fraction of 640x480. It was necessary + * to reduce the resolution for the Video Memory to fit within the on-chip memory limits. + */ + + parameter BACKGROUND_IMAGE = "background.mif"; + /* The initial screen displayed when the circuit is first programmed onto the DE2 board can be + * defined useing an MIF file. The file contains the initial colour for each pixel on the screen + * and is placed in the Video Memory (VideoMemory module) upon programming. Note that resetting the + * VGA Adapter will not cause the Video Memory to revert to the specified image. */ + + parameter USING_DE1 = "FALSE"; + /* If set to "TRUE" it adjust the offset of the drawing mechanism to account for the differences + * between the DE2 and DE1 VGA digital to analogue converters. Set to "TRUE" if and only if + * you are running your circuit on a DE1 board. */ + + /*****************************************************************************/ + /* Declare inputs and outputs. */ + /*****************************************************************************/ + input resetn; + input clock; + + /* The colour input can be either 1 bit or 3*BITS_PER_COLOUR_CHANNEL bits wide, depending on + * the setting of the MONOCHROME parameter. + */ + input [((MONOCHROME == "TRUE") ? (0) : (BITS_PER_COLOUR_CHANNEL*3-1)):0] colour; + + /* Specify the number of bits required to represent an (X,Y) coordinate on the screen for + * a given resolution. + */ + input [((RESOLUTION == "320x240") ? (8) : (7)):0] x; + input [((RESOLUTION == "320x240") ? (7) : (6)):0] y; + + /* When plot is high then at the next positive edge of the clock the pixel at (x,y) will change to + * a new colour, defined by the value of the colour input. + */ + input plot; + + /* These outputs drive the VGA display. The VGA_CLK is also used to clock the FSM responsible for + * controlling the data transferred to the DAC driving the monitor. */ + output [9:0] VGA_R; + output [9:0] VGA_G; + output [9:0] VGA_B; + output VGA_HS; + output VGA_VS; + output VGA_BLANK; + output VGA_SYNC; + output VGA_CLK; + + /*****************************************************************************/ + /* Declare local signals here. */ + /*****************************************************************************/ + + wire valid_160x120; + wire valid_320x240; + /* Set to 1 if the specified coordinates are in a valid range for a given resolution.*/ + + wire writeEn; + /* This is a local signal that allows the Video Memory contents to be changed. + * It depends on the screen resolution, the values of X and Y inputs, as well as + * the state of the plot signal. + */ + + wire [((MONOCHROME == "TRUE") ? (0) : (BITS_PER_COLOUR_CHANNEL*3-1)):0] to_ctrl_colour; + /* Pixel colour read by the VGA controller */ + + wire [((RESOLUTION == "320x240") ? (16) : (14)):0] user_to_video_memory_addr; + /* This bus specifies the address in memory the user must write + * data to in order for the pixel intended to appear at location (X,Y) to be displayed + * at the correct location on the screen. + */ + + wire [((RESOLUTION == "320x240") ? (16) : (14)):0] controller_to_video_memory_addr; + /* This bus specifies the address in memory the vga controller must read data from + * in order to determine the colour of a pixel located at coordinate (X,Y) of the screen. + */ + + wire clock_25; + /* 25MHz clock generated by dividing the input clock frequency by 2. */ + + wire vcc, gnd; + + /*****************************************************************************/ + /* Instances of modules for the VGA adapter. */ + /*****************************************************************************/ + assign vcc = 1'b1; + assign gnd = 1'b0; + + vga_address_translator user_input_translator( + .x(x), .y(y), .mem_address(user_to_video_memory_addr) ); + defparam user_input_translator.RESOLUTION = RESOLUTION; + /* Convert user coordinates into a memory address. */ + + assign valid_160x120 = (({1'b0, x} >= 0) & ({1'b0, x} < 160) & ({1'b0, y} >= 0) & ({1'b0, y} < 120)) & (RESOLUTION == "160x120"); + assign valid_320x240 = (({1'b0, x} >= 0) & ({1'b0, x} < 320) & ({1'b0, y} >= 0) & ({1'b0, y} < 240)) & (RESOLUTION == "320x240"); + assign writeEn = (plot) & (valid_160x120 | valid_320x240); + /* Allow the user to plot a pixel if and only if the (X,Y) coordinates supplied are in a valid range. */ + + /* Create video memory. */ + altsyncram VideoMemory ( + .wren_a (writeEn), + .wren_b (gnd), + .clock0 (clock), // write clock + .clock1 (clock_25), // read clock + .clocken0 (vcc), // write enable clock + .clocken1 (vcc), // read enable clock + .address_a (user_to_video_memory_addr), + .address_b (controller_to_video_memory_addr), + .data_a (colour), // data in + .q_b (to_ctrl_colour) // data out + ); + defparam + VideoMemory.width_a = ((MONOCHROME == "FALSE") ? (BITS_PER_COLOUR_CHANNEL*3) : 1), + VideoMemory.width_b = ((MONOCHROME == "FALSE") ? (BITS_PER_COLOUR_CHANNEL*3) : 1), + VideoMemory.intended_device_family = "Cyclone II", + VideoMemory.operation_mode = "DUAL_PORT", + VideoMemory.widthad_a = ((RESOLUTION == "320x240") ? (17) : (15)), + VideoMemory.numwords_a = ((RESOLUTION == "320x240") ? (76800) : (19200)), + VideoMemory.widthad_b = ((RESOLUTION == "320x240") ? (17) : (15)), + VideoMemory.numwords_b = ((RESOLUTION == "320x240") ? (76800) : (19200)), + VideoMemory.outdata_reg_b = "CLOCK1", + VideoMemory.address_reg_b = "CLOCK1", + VideoMemory.clock_enable_input_a = "BYPASS", + VideoMemory.clock_enable_input_b = "BYPASS", + VideoMemory.clock_enable_output_b = "BYPASS", + VideoMemory.power_up_uninitialized = "TRUE"; + + vga_pll mypll(clock, clock_25); + /* This module generates a clock with half the frequency of the input clock. + * For the VGA adapter to operate correctly the clock signal 'clock' must be + * a 50MHz clock. The derived clock, which will then operate at 25MHz, is + * required to set the monitor into the 640x480@60Hz display mode (also known as + * the VGA mode). + */ + + vga_controller controller( + .vga_clock(clock_25), + .resetn(resetn), + .pixel_colour(to_ctrl_colour), + .memory_address(controller_to_video_memory_addr), + .VGA_R(VGA_R), + .VGA_G(VGA_G), + .VGA_B(VGA_B), + .VGA_HS(VGA_HS), + .VGA_VS(VGA_VS), + .VGA_BLANK(VGA_BLANK), + .VGA_SYNC(VGA_SYNC), + .VGA_CLK(VGA_CLK) + ); + defparam controller.BITS_PER_COLOUR_CHANNEL = BITS_PER_COLOUR_CHANNEL ; + defparam controller.MONOCHROME = MONOCHROME; + defparam controller.RESOLUTION = RESOLUTION; + defparam controller.USING_DE1 = USING_DE1; + + // synthesis translate_off + always @(posedge clock, negedge resetn) begin + if (resetn === 1'b0) begin +`ifdef MODEL_TECH + mti_fli::mti_Command("if { [namespace exists ::de1vga] } { ::de1vga::reset } else { echo \"VGA RESET\" }"); +`else + $display("VGA RESET"); +`endif + end else if (plot === 1'b1) begin +`ifdef MODEL_TECH + mti_fli::mti_Command($sformatf("if { [namespace exists ::de1vga] } { ::de1vga::plot %0d %0d %0d } else { echo \"VGA PLOT %0d,%0d %0d\" }", x, y, colour, x, y, colour)); +`else + $display("VGA PLOT %0d,%0d %0d", x, y, colour); +`endif + end + end + // synthesis translate_on + +endmodule diff --git a/vga-core/vga_adapter.v b/vga-core/vga_adapter.v new file mode 100644 index 0000000..83e7413 --- /dev/null +++ b/vga-core/vga_adapter.v @@ -0,0 +1,263 @@ +/* VGA Adapter
+ * ----------------
+ *
+ * This is an implementation of a VGA Adapter. The adapter uses VGA mode signalling to initiate
+ * a 640x480 resolution mode on a computer monitor, with a refresh rate of approximately 60Hz.
+ * It is designed for easy use in an early digital logic design course to facilitate student
+ * projects on the Altera DE2 Educational board.
+ *
+ * This implementation of the VGA adapter can display images of varying colour depth at a resolution of
+ * 320x240 or 160x120 superpixels. The concept of superpixels is introduced to reduce the amount of on-chip
+ * memory used by the adapter. The following table shows the number of bits of on-chip memory used by
+ * the adapter in various resolutions and colour depths.
+ *
+ * -------------------------------------------------------------------------------------------------------------------------------
+ * Resolution | Mono | 8 colours | 64 colours | 512 colours | 4096 colours | 32768 colours | 262144 colours | 2097152 colours |
+ * -------------------------------------------------------------------------------------------------------------------------------
+ * 160x120 | 19200 | 57600 | 115200 | 172800 | 230400 | 288000 | 345600 | 403200 |
+ * 320x240 | 78600 | 230400 | ############## Does not fit ############################################################## |
+ * -------------------------------------------------------------------------------------------------------------------------------
+ *
+ * By default the adapter works at the resolution of 320x240 with 8 colours. To set the adapter in any of
+ * the other modes, the adapter must be instantiated with specific parameters. These parameters are:
+ * - RESOLUTION - a string that should be either "320x240" or "160x120".
+ * - MONOCHROME - a string that should be "TRUE" if you only want black and white colours, and "FALSE"
+ * otherwise.
+ * - BITS_PER_COLOUR_CHANNEL - an integer specifying how many bits are available to describe each colour
+ * (R,G,B). A default value of 1 indicates that 1 bit will be used for red
+ * channel, 1 for green channel and 1 for blue channel. This allows 8 colours
+ * to be used.
+ *
+ * In addition to the above parameters, a BACKGROUND_IMAGE parameter can be specified. The parameter
+ * refers to a memory initilization file (MIF) which contains the initial contents of video memory.
+ * By specifying the initial contents of the memory we can force the adapter to initially display an
+ * image of our choice. Please note that the image described by the BACKGROUND_IMAGE file will only
+ * be valid right after your program the DE2 board. If your circuit draws a single pixel on the screen,
+ * the video memory will be altered and screen contents will be changed. In order to restore the background
+ * image your circuti will have to redraw the background image pixel by pixel, or you will have to
+ * reprogram the DE2 board, thus allowing the video memory to be rewritten.
+ *
+ * To use the module connect the vga_adapter to your circuit. Your circuit should produce a value for
+ * inputs X, Y and plot. When plot is high, at the next positive edge of the input clock the vga_adapter
+ * will change the contents of the video memory for the pixel at location (X,Y). At the next redraw
+ * cycle the VGA controller will update the contants of the screen by reading the video memory and copying
+ * it over to the screen. Since the monitor screen has no memory, the VGA controller has to copy the
+ * contents of the video memory to the screen once every 60th of a second to keep the image stable. Thus,
+ * the video memory should not be used for other purposes as it may interfere with the operation of the
+ * VGA Adapter.
+ *
+ * As a final note, ensure that the following conditions are met when using this module:
+ * 1. You are implementing the the VGA Adapter on the Altera DE2 board. Using another board may change
+ * the amount of memory you can use, the clock generation mechanism, as well as pin assignments required
+ * to properly drive the VGA digital-to-analog converter.
+ * 2. Outputs VGA_* should exist in your top level design. They should be assigned pin locations on the
+ * Altera DE2 board as specified by the DE2_pin_assignments.csv file.
+ * 3. The input clock must have a frequency of 50 MHz with a 50% duty cycle. On the Altera DE2 board
+ * PIN_N2 is the source for the 50MHz clock.
+ *
+ * During compilation with Quartus II you may receive the following warnings:
+ * - Warning: Variable or input pin "clocken1" is defined but never used
+ * - Warning: Pin "VGA_SYNC" stuck at VCC
+ * - Warning: Found xx output pins without output pin load capacitance assignment
+ * These warnings can be ignored. The first warning is generated, because the software generated
+ * memory module contains an input called "clocken1" and it does not drive logic. The second warning
+ * indicates that the VGA_SYNC signal is always high. This is intentional. The final warning is
+ * generated for the purposes of power analysis. It will persist unless the output pins are assigned
+ * output capacitance. Leaving the capacitance values at 0 pf did not affect the operation of the module.
+ *
+ * If you see any other warnings relating to the vga_adapter, be sure to examine them carefully. They may
+ * cause your circuit to malfunction.
+ *
+ * NOTES/REVISIONS:
+ * July 10, 2007 - Modified the original version of the VGA Adapter written by Sam Vafaee in 2006. The module
+ * now supports 2 different resolutions as well as uses half the memory compared to prior
+ * implementation. Also, all settings for the module can be specified from the point
+ * of instantiation, rather than by modifying the source code. (Tomasz S. Czajkowski)
+ */
+
+module vga_adapter(
+ resetn,
+ clock,
+ colour,
+ x, y, plot,
+ /* Signals for the DAC to drive the monitor. */
+ VGA_R,
+ VGA_G,
+ VGA_B,
+ VGA_HS,
+ VGA_VS,
+ VGA_BLANK,
+ VGA_SYNC,
+ VGA_CLK);
+
+ parameter BITS_PER_COLOUR_CHANNEL = 1;
+ /* The number of bits per colour channel used to represent the colour of each pixel. A value
+ * of 1 means that Red, Green and Blue colour channels will use 1 bit each to represent the intensity
+ * of the respective colour channel. For BITS_PER_COLOUR_CHANNEL=1, the adapter can display 8 colours.
+ * In general, the adapter is able to use 2^(3*BITS_PER_COLOUR_CHANNEL ) colours. The number of colours is
+ * limited by the screen resolution and the amount of on-chip memory available on the target device.
+ */
+
+ parameter MONOCHROME = "FALSE";
+ /* Set this parameter to "TRUE" if you only wish to use black and white colours. Doing so will reduce
+ * the amount of memory you will use by a factor of 3. */
+
+ parameter RESOLUTION = "320x240";
+ /* Set this parameter to "160x120" or "320x240". It will cause the VGA adapter to draw each dot on
+ * the screen by using a block of 4x4 pixels ("160x120" resolution) or 2x2 pixels ("320x240" resolution).
+ * It effectively reduces the screen resolution to an integer fraction of 640x480. It was necessary
+ * to reduce the resolution for the Video Memory to fit within the on-chip memory limits.
+ */
+
+ parameter BACKGROUND_IMAGE = "background.mif";
+ /* The initial screen displayed when the circuit is first programmed onto the DE2 board can be
+ * defined useing an MIF file. The file contains the initial colour for each pixel on the screen
+ * and is placed in the Video Memory (VideoMemory module) upon programming. Note that resetting the
+ * VGA Adapter will not cause the Video Memory to revert to the specified image. */
+
+ parameter USING_DE1 = "FALSE";
+ /* If set to "TRUE" it adjust the offset of the drawing mechanism to account for the differences
+ * between the DE2 and DE1 VGA digital to analogue converters. Set to "TRUE" if and only if
+ * you are running your circuit on a DE1 board. */
+
+ /*****************************************************************************/
+ /* Declare inputs and outputs. */
+ /*****************************************************************************/
+ input resetn;
+ input clock;
+
+ /* The colour input can be either 1 bit or 3*BITS_PER_COLOUR_CHANNEL bits wide, depending on
+ * the setting of the MONOCHROME parameter.
+ */
+ input [((MONOCHROME == "TRUE") ? (0) : (BITS_PER_COLOUR_CHANNEL*3-1)):0] colour;
+
+ /* Specify the number of bits required to represent an (X,Y) coordinate on the screen for
+ * a given resolution.
+ */
+ input [((RESOLUTION == "320x240") ? (8) : (7)):0] x;
+ input [((RESOLUTION == "320x240") ? (7) : (6)):0] y;
+
+ /* When plot is high then at the next positive edge of the clock the pixel at (x,y) will change to
+ * a new colour, defined by the value of the colour input.
+ */
+ input plot;
+
+ /* These outputs drive the VGA display. The VGA_CLK is also used to clock the FSM responsible for
+ * controlling the data transferred to the DAC driving the monitor. */
+ output [9:0] VGA_R;
+ output [9:0] VGA_G;
+ output [9:0] VGA_B;
+ output VGA_HS;
+ output VGA_VS;
+ output VGA_BLANK;
+ output VGA_SYNC;
+ output VGA_CLK;
+
+ /*****************************************************************************/
+ /* Declare local signals here. */
+ /*****************************************************************************/
+
+ wire valid_160x120;
+ wire valid_320x240;
+ /* Set to 1 if the specified coordinates are in a valid range for a given resolution.*/
+
+ wire writeEn;
+ /* This is a local signal that allows the Video Memory contents to be changed.
+ * It depends on the screen resolution, the values of X and Y inputs, as well as
+ * the state of the plot signal.
+ */
+
+ wire [((MONOCHROME == "TRUE") ? (0) : (BITS_PER_COLOUR_CHANNEL*3-1)):0] to_ctrl_colour;
+ /* Pixel colour read by the VGA controller */
+
+ wire [((RESOLUTION == "320x240") ? (16) : (14)):0] user_to_video_memory_addr;
+ /* This bus specifies the address in memory the user must write
+ * data to in order for the pixel intended to appear at location (X,Y) to be displayed
+ * at the correct location on the screen.
+ */
+
+ wire [((RESOLUTION == "320x240") ? (16) : (14)):0] controller_to_video_memory_addr;
+ /* This bus specifies the address in memory the vga controller must read data from
+ * in order to determine the colour of a pixel located at coordinate (X,Y) of the screen.
+ */
+
+ wire clock_25;
+ /* 25MHz clock generated by dividing the input clock frequency by 2. */
+
+ wire vcc, gnd;
+
+ /*****************************************************************************/
+ /* Instances of modules for the VGA adapter. */
+ /*****************************************************************************/
+ assign vcc = 1'b1;
+ assign gnd = 1'b0;
+
+ vga_address_translator user_input_translator(
+ .x(x), .y(y), .mem_address(user_to_video_memory_addr) );
+ defparam user_input_translator.RESOLUTION = RESOLUTION;
+ /* Convert user coordinates into a memory address. */
+
+ assign valid_160x120 = (({1'b0, x} >= 0) & ({1'b0, x} < 160) & ({1'b0, y} >= 0) & ({1'b0, y} < 120)) & (RESOLUTION == "160x120");
+ assign valid_320x240 = (({1'b0, x} >= 0) & ({1'b0, x} < 320) & ({1'b0, y} >= 0) & ({1'b0, y} < 240)) & (RESOLUTION == "320x240");
+ assign writeEn = (plot) & (valid_160x120 | valid_320x240);
+ /* Allow the user to plot a pixel if and only if the (X,Y) coordinates supplied are in a valid range. */
+
+ /* Create video memory. */
+ altsyncram VideoMemory (
+ .wren_a (writeEn),
+ .wren_b (gnd),
+ .clock0 (clock), // write clock
+ .clock1 (clock_25), // read clock
+ .clocken0 (vcc), // write enable clock
+ .clocken1 (vcc), // read enable clock
+ .address_a (user_to_video_memory_addr),
+ .address_b (controller_to_video_memory_addr),
+ .data_a (colour), // data in
+ .q_b (to_ctrl_colour) // data out
+ );
+ defparam
+ VideoMemory.WIDTH_A = ((MONOCHROME == "FALSE") ? (BITS_PER_COLOUR_CHANNEL*3) : 1),
+ VideoMemory.WIDTH_B = ((MONOCHROME == "FALSE") ? (BITS_PER_COLOUR_CHANNEL*3) : 1),
+ VideoMemory.INTENDED_DEVICE_FAMILY = "Cyclone II",
+ VideoMemory.OPERATION_MODE = "DUAL_PORT",
+ VideoMemory.WIDTHAD_A = ((RESOLUTION == "320x240") ? (17) : (15)),
+ VideoMemory.NUMWORDS_A = ((RESOLUTION == "320x240") ? (76800) : (19200)),
+ VideoMemory.WIDTHAD_B = ((RESOLUTION == "320x240") ? (17) : (15)),
+ VideoMemory.NUMWORDS_B = ((RESOLUTION == "320x240") ? (76800) : (19200)),
+ VideoMemory.OUTDATA_REG_B = "CLOCK1",
+ VideoMemory.ADDRESS_REG_B = "CLOCK1",
+ VideoMemory.CLOCK_ENABLE_INPUT_A = "BYPASS",
+ VideoMemory.CLOCK_ENABLE_INPUT_B = "BYPASS",
+ VideoMemory.CLOCK_ENABLE_OUTPUT_B = "BYPASS",
+ VideoMemory.POWER_UP_UNINITIALIZED = "FALSE",
+ VideoMemory.INIT_FILE = BACKGROUND_IMAGE;
+
+ vga_pll mypll(clock, clock_25);
+ /* This module generates a clock with half the frequency of the input clock.
+ * For the VGA adapter to operate correctly the clock signal 'clock' must be
+ * a 50MHz clock. The derived clock, which will then operate at 25MHz, is
+ * required to set the monitor into the 640x480@60Hz display mode (also known as
+ * the VGA mode).
+ */
+
+ vga_controller controller(
+ .vga_clock(clock_25),
+ .resetn(resetn),
+ .pixel_colour(to_ctrl_colour),
+ .memory_address(controller_to_video_memory_addr),
+ .VGA_R(VGA_R),
+ .VGA_G(VGA_G),
+ .VGA_B(VGA_B),
+ .VGA_HS(VGA_HS),
+ .VGA_VS(VGA_VS),
+ .VGA_BLANK(VGA_BLANK),
+ .VGA_SYNC(VGA_SYNC),
+ .VGA_CLK(VGA_CLK)
+ );
+ defparam controller.BITS_PER_COLOUR_CHANNEL = BITS_PER_COLOUR_CHANNEL ;
+ defparam controller.MONOCHROME = MONOCHROME;
+ defparam controller.RESOLUTION = RESOLUTION;
+ defparam controller.USING_DE1 = USING_DE1;
+
+endmodule
+
\ No newline at end of file diff --git a/vga-core/vga_address_translator.sv b/vga-core/vga_address_translator.sv new file mode 100644 index 0000000..cc63fac --- /dev/null +++ b/vga-core/vga_address_translator.sv @@ -0,0 +1,39 @@ +// synopsys translate_off +`timescale 1 ps / 1 ps +// synopsys translate_on + +/* This module converts a user specified coordinates into a memory address. + * The output of the module depends on the resolution set by the user. + */ +module vga_address_translator(x, y, mem_address); + + parameter RESOLUTION = "320x240"; + /* Set this parameter to "160x120" or "320x240". It will cause the VGA adapter to draw each dot on + * the screen by using a block of 4x4 pixels ("160x120" resolution) or 2x2 pixels ("320x240" resolution). + * It effectively reduces the screen resolution to an integer fraction of 640x480. It was necessary + * to reduce the resolution for the Video Memory to fit within the on-chip memory limits. + */ + + input [((RESOLUTION == "320x240") ? (8) : (7)):0] x; + input [((RESOLUTION == "320x240") ? (7) : (6)):0] y; + output reg [((RESOLUTION == "320x240") ? (16) : (14)):0] mem_address; + + /* The basic formula is address = y*WIDTH + x; + * For 320x240 resolution we can write 320 as (256 + 64). Memory address becomes + * (y*256) + (y*64) + x; + * This simplifies multiplication a simple shift and add operation. + * A leading 0 bit is added to each operand to ensure that they are treated as unsigned + * inputs. By default the use a '+' operator will generate a signed adder. + * Similarly, for 160x120 resolution we write 160 as 128+32. + */ + wire [16:0] res_320x240 = ({1'b0, y, 8'd0} + {1'b0, y, 6'd0} + {1'b0, x}); + wire [15:0] res_160x120 = ({1'b0, y, 7'd0} + {1'b0, y, 5'd0} + {1'b0, x}); + + always @(*) + begin + if (RESOLUTION == "320x240") + mem_address = res_320x240; + else + mem_address = res_160x120[14:0]; + end +endmodule diff --git a/vga-core/vga_address_translator.v b/vga-core/vga_address_translator.v new file mode 100644 index 0000000..bf97e90 --- /dev/null +++ b/vga-core/vga_address_translator.v @@ -0,0 +1,35 @@ +/* This module converts a user specified coordinates into a memory address.
+ * The output of the module depends on the resolution set by the user.
+ */
+module vga_address_translator(x, y, mem_address);
+
+ parameter RESOLUTION = "320x240";
+ /* Set this parameter to "160x120" or "320x240". It will cause the VGA adapter to draw each dot on
+ * the screen by using a block of 4x4 pixels ("160x120" resolution) or 2x2 pixels ("320x240" resolution).
+ * It effectively reduces the screen resolution to an integer fraction of 640x480. It was necessary
+ * to reduce the resolution for the Video Memory to fit within the on-chip memory limits.
+ */
+
+ input [((RESOLUTION == "320x240") ? (8) : (7)):0] x;
+ input [((RESOLUTION == "320x240") ? (7) : (6)):0] y;
+ output reg [((RESOLUTION == "320x240") ? (16) : (14)):0] mem_address;
+
+ /* The basic formula is address = y*WIDTH + x;
+ * For 320x240 resolution we can write 320 as (256 + 64). Memory address becomes
+ * (y*256) + (y*64) + x;
+ * This simplifies multiplication a simple shift and add operation.
+ * A leading 0 bit is added to each operand to ensure that they are treated as unsigned
+ * inputs. By default the use a '+' operator will generate a signed adder.
+ * Similarly, for 160x120 resolution we write 160 as 128+32.
+ */
+ wire [16:0] res_320x240 = ({1'b0, y, 8'd0} + {1'b0, y, 6'd0} + {1'b0, x});
+ wire [15:0] res_160x120 = ({1'b0, y, 7'd0} + {1'b0, y, 5'd0} + {1'b0, x});
+
+ always @(*)
+ begin
+ if (RESOLUTION == "320x240")
+ mem_address = res_320x240;
+ else
+ mem_address = res_160x120[14:0];
+ end
+endmodule
diff --git a/vga-core/vga_controller.sv b/vga-core/vga_controller.sv new file mode 100644 index 0000000..4217c13 --- /dev/null +++ b/vga-core/vga_controller.sv @@ -0,0 +1,216 @@ +// synopsys translate_off +`timescale 1 ps / 1 ps +// synopsys translate_on + +/* This module implements the VGA controller. It assumes a 25MHz clock is supplied as input. + * + * General approach: + * Go through each line of the screen and read the colour each pixel on that line should have from + * the Video memory. To do that for each (x,y) pixel on the screen convert (x,y) coordinate to + * a memory_address at which the pixel colour is stored in Video memory. Once the pixel colour is + * read from video memory its brightness is first increased before it is forwarded to the VGA DAC. + */ +module vga_controller( vga_clock, resetn, pixel_colour, memory_address, + VGA_R, VGA_G, VGA_B, + VGA_HS, VGA_VS, VGA_BLANK, + VGA_SYNC, VGA_CLK); + + /* Screen resolution and colour depth parameters. */ + + parameter BITS_PER_COLOUR_CHANNEL = 1; + /* The number of bits per colour channel used to represent the colour of each pixel. A value + * of 1 means that Red, Green and Blue colour channels will use 1 bit each to represent the intensity + * of the respective colour channel. For BITS_PER_COLOUR_CHANNEL=1, the adapter can display 8 colours. + * In general, the adapter is able to use 2^(3*BITS_PER_COLOUR_CHANNEL) colours. The number of colours is + * limited by the screen resolution and the amount of on-chip memory available on the target device. + */ + + parameter MONOCHROME = "FALSE"; + /* Set this parameter to "TRUE" if you only wish to use black and white colours. Doing so will reduce + * the amount of memory you will use by a factor of 3. */ + + parameter RESOLUTION = "320x240"; + /* Set this parameter to "160x120" or "320x240". It will cause the VGA adapter to draw each dot on + * the screen by using a block of 4x4 pixels ("160x120" resolution) or 2x2 pixels ("320x240" resolution). + * It effectively reduces the screen resolution to an integer fraction of 640x480. It was necessary + * to reduce the resolution for the Video Memory to fit within the on-chip memory limits. + */ + + parameter USING_DE1 = "FALSE"; + /* If set to "TRUE" it adjust the offset of the drawing mechanism to account for the differences + * between the DE2 and DE1 VGA digital to analogue converters. Set to "TRUE" if and only if + * you are running your circuit on a DE1 board. */ + + //--- Timing parameters. + /* Recall that the VGA specification requires a few more rows and columns are drawn + * when refreshing the screen than are actually present on the screen. This is necessary to + * generate the vertical and the horizontal syncronization signals. If you wish to use a + * display mode other than 640x480 you will need to modify the parameters below as well + * as change the frequency of the clock driving the monitor (VGA_CLK). + */ + parameter C_VERT_NUM_PIXELS = 11'd480; + parameter C_VERT_SYNC_START = 11'd493; + parameter C_VERT_SYNC_END = 11'd494; //(C_VERT_SYNC_START + 2 - 1); + parameter C_VERT_TOTAL_COUNT = 11'd525; + + parameter C_HORZ_NUM_PIXELS = 11'd640; + parameter C_HORZ_SYNC_START = 11'd659; + parameter C_HORZ_SYNC_END = 11'd754; //(C_HORZ_SYNC_START + 96 - 1); + parameter C_HORZ_TOTAL_COUNT = 11'd800; + + /*****************************************************************************/ + /* Declare inputs and outputs. */ + /*****************************************************************************/ + + input vga_clock, resetn; + input [((MONOCHROME == "TRUE") ? (0) : (BITS_PER_COLOUR_CHANNEL*3-1)):0] pixel_colour; + output [((RESOLUTION == "320x240") ? (16) : (14)):0] memory_address; + output reg [9:0] VGA_R; + output reg [9:0] VGA_G; + output reg [9:0] VGA_B; + output reg VGA_HS; + output reg VGA_VS; + output reg VGA_BLANK; + output VGA_SYNC, VGA_CLK; + + /*****************************************************************************/ + /* Local Signals. */ + /*****************************************************************************/ + + reg VGA_HS1; + reg VGA_VS1; + reg VGA_BLANK1; + reg [9:0] xCounter, yCounter; + wire xCounter_clear; + wire yCounter_clear; + wire vcc; + + reg [((RESOLUTION == "320x240") ? (8) : (7)):0] x; + reg [((RESOLUTION == "320x240") ? (7) : (6)):0] y; + /* Inputs to the converter. */ + + /*****************************************************************************/ + /* Controller implementation. */ + /*****************************************************************************/ + + assign vcc =1'b1; + + /* A counter to scan through a horizontal line. */ + always @(posedge vga_clock or negedge resetn) + begin + if (!resetn) + xCounter <= 10'd0; + else if (xCounter_clear) + xCounter <= 10'd0; + else + begin + xCounter <= xCounter + 1'b1; + end + end + assign xCounter_clear = (xCounter == (C_HORZ_TOTAL_COUNT-1)); + + /* A counter to scan vertically, indicating the row currently being drawn. */ + always @(posedge vga_clock or negedge resetn) + begin + if (!resetn) + yCounter <= 10'd0; + else if (xCounter_clear && yCounter_clear) + yCounter <= 10'd0; + else if (xCounter_clear) //Increment when x counter resets + yCounter <= yCounter + 1'b1; + end + assign yCounter_clear = (yCounter == (C_VERT_TOTAL_COUNT-1)); + + /* Convert the xCounter/yCounter location from screen pixels (640x480) to our + * local dots (320x240 or 160x120). Here we effectively divide x/y coordinate by 2 or 4, + * depending on the resolution. */ + always @(*) + begin + if (RESOLUTION == "320x240") + begin + x = xCounter[9:1]; + y = yCounter[8:1]; + end + else + begin + x = xCounter[9:2]; + y = yCounter[8:2]; + end + end + + /* Change the (x,y) coordinate into a memory address. */ + vga_address_translator controller_translator( + .x(x), .y(y), .mem_address(memory_address) ); + defparam controller_translator.RESOLUTION = RESOLUTION; + + + /* Generate the vertical and horizontal synchronization pulses. */ + always @(posedge vga_clock) + begin + //- Sync Generator (ACTIVE LOW) + if (USING_DE1 == "TRUE") + VGA_HS1 <= ~((xCounter >= C_HORZ_SYNC_START-2) && (xCounter <= C_HORZ_SYNC_END-2)); + else + VGA_HS1 <= ~((xCounter >= C_HORZ_SYNC_START) && (xCounter <= C_HORZ_SYNC_END)); + VGA_VS1 <= ~((yCounter >= C_VERT_SYNC_START) && (yCounter <= C_VERT_SYNC_END)); + + //- Current X and Y is valid pixel range + VGA_BLANK1 <= ((xCounter < C_HORZ_NUM_PIXELS) && (yCounter < C_VERT_NUM_PIXELS)); + + //- Add 1 cycle delay + VGA_HS <= VGA_HS1; + VGA_VS <= VGA_VS1; + VGA_BLANK <= VGA_BLANK1; + end + + /* VGA sync should be 1 at all times. */ + assign VGA_SYNC = vcc; + + /* Generate the VGA clock signal. */ + assign VGA_CLK = vga_clock; + + /* Brighten the colour output. */ + // The colour input is first processed to brighten the image a little. Setting the top + // bits to correspond to the R,G,B colour makes the image a bit dull. To brighten the image, + // each bit of the colour is replicated through the 10 DAC colour input bits. For example, + // when BITS_PER_COLOUR_CHANNEL is 2 and the red component is set to 2'b10, then the + // VGA_R input to the DAC will be set to 10'b1010101010. + + integer index; + integer sub_index; + + wire on_screen; + + assign on_screen = (USING_DE1 == "TRUE") ? + (({1'b0, xCounter} >= 2) & ({1'b0, xCounter} < C_HORZ_NUM_PIXELS+2) & ({1'b0, yCounter} < C_VERT_NUM_PIXELS)) : + (({1'b0, xCounter} >= 0) & ({1'b0, xCounter} < C_HORZ_NUM_PIXELS+2) & ({1'b0, yCounter} < C_VERT_NUM_PIXELS)); + + always @(pixel_colour or on_screen) + begin + VGA_R <= 'b0; + VGA_G <= 'b0; + VGA_B <= 'b0; + if (MONOCHROME == "FALSE") + begin + for (index = 10-BITS_PER_COLOUR_CHANNEL; index >= 0; index = index - BITS_PER_COLOUR_CHANNEL) + begin + for (sub_index = BITS_PER_COLOUR_CHANNEL - 1; sub_index >= 0; sub_index = sub_index - 1) + begin + VGA_R[sub_index+index] <= on_screen & pixel_colour[sub_index + BITS_PER_COLOUR_CHANNEL*2]; + VGA_G[sub_index+index] <= on_screen & pixel_colour[sub_index + BITS_PER_COLOUR_CHANNEL]; + VGA_B[sub_index+index] <= on_screen & pixel_colour[sub_index]; + end + end + end + else + begin + for (index = 0; index < 10; index = index + 1) + begin + VGA_R[index] <= on_screen & pixel_colour[0:0]; + VGA_G[index] <= on_screen & pixel_colour[0:0]; + VGA_B[index] <= on_screen & pixel_colour[0:0]; + end + end + end + +endmodule diff --git a/vga-core/vga_controller.v b/vga-core/vga_controller.v new file mode 100644 index 0000000..0e4cfba --- /dev/null +++ b/vga-core/vga_controller.v @@ -0,0 +1,212 @@ +/* This module implements the VGA controller. It assumes a 25MHz clock is supplied as input.
+ *
+ * General approach:
+ * Go through each line of the screen and read the colour each pixel on that line should have from
+ * the Video memory. To do that for each (x,y) pixel on the screen convert (x,y) coordinate to
+ * a memory_address at which the pixel colour is stored in Video memory. Once the pixel colour is
+ * read from video memory its brightness is first increased before it is forwarded to the VGA DAC.
+ */
+module vga_controller( vga_clock, resetn, pixel_colour, memory_address,
+ VGA_R, VGA_G, VGA_B,
+ VGA_HS, VGA_VS, VGA_BLANK,
+ VGA_SYNC, VGA_CLK);
+
+ /* Screen resolution and colour depth parameters. */
+
+ parameter BITS_PER_COLOUR_CHANNEL = 1;
+ /* The number of bits per colour channel used to represent the colour of each pixel. A value
+ * of 1 means that Red, Green and Blue colour channels will use 1 bit each to represent the intensity
+ * of the respective colour channel. For BITS_PER_COLOUR_CHANNEL=1, the adapter can display 8 colours.
+ * In general, the adapter is able to use 2^(3*BITS_PER_COLOUR_CHANNEL) colours. The number of colours is
+ * limited by the screen resolution and the amount of on-chip memory available on the target device.
+ */
+
+ parameter MONOCHROME = "FALSE";
+ /* Set this parameter to "TRUE" if you only wish to use black and white colours. Doing so will reduce
+ * the amount of memory you will use by a factor of 3. */
+
+ parameter RESOLUTION = "320x240";
+ /* Set this parameter to "160x120" or "320x240". It will cause the VGA adapter to draw each dot on
+ * the screen by using a block of 4x4 pixels ("160x120" resolution) or 2x2 pixels ("320x240" resolution).
+ * It effectively reduces the screen resolution to an integer fraction of 640x480. It was necessary
+ * to reduce the resolution for the Video Memory to fit within the on-chip memory limits.
+ */
+
+ parameter USING_DE1 = "FALSE";
+ /* If set to "TRUE" it adjust the offset of the drawing mechanism to account for the differences
+ * between the DE2 and DE1 VGA digital to analogue converters. Set to "TRUE" if and only if
+ * you are running your circuit on a DE1 board. */
+
+ //--- Timing parameters.
+ /* Recall that the VGA specification requires a few more rows and columns are drawn
+ * when refreshing the screen than are actually present on the screen. This is necessary to
+ * generate the vertical and the horizontal syncronization signals. If you wish to use a
+ * display mode other than 640x480 you will need to modify the parameters below as well
+ * as change the frequency of the clock driving the monitor (VGA_CLK).
+ */
+ parameter C_VERT_NUM_PIXELS = 11'd480;
+ parameter C_VERT_SYNC_START = 11'd493;
+ parameter C_VERT_SYNC_END = 11'd494; //(C_VERT_SYNC_START + 2 - 1);
+ parameter C_VERT_TOTAL_COUNT = 11'd525;
+
+ parameter C_HORZ_NUM_PIXELS = 11'd640;
+ parameter C_HORZ_SYNC_START = 11'd659;
+ parameter C_HORZ_SYNC_END = 11'd754; //(C_HORZ_SYNC_START + 96 - 1);
+ parameter C_HORZ_TOTAL_COUNT = 11'd800;
+
+ /*****************************************************************************/
+ /* Declare inputs and outputs. */
+ /*****************************************************************************/
+
+ input vga_clock, resetn;
+ input [((MONOCHROME == "TRUE") ? (0) : (BITS_PER_COLOUR_CHANNEL*3-1)):0] pixel_colour;
+ output [((RESOLUTION == "320x240") ? (16) : (14)):0] memory_address;
+ output reg [9:0] VGA_R;
+ output reg [9:0] VGA_G;
+ output reg [9:0] VGA_B;
+ output reg VGA_HS;
+ output reg VGA_VS;
+ output reg VGA_BLANK;
+ output VGA_SYNC, VGA_CLK;
+
+ /*****************************************************************************/
+ /* Local Signals. */
+ /*****************************************************************************/
+
+ reg VGA_HS1;
+ reg VGA_VS1;
+ reg VGA_BLANK1;
+ reg [9:0] xCounter, yCounter;
+ wire xCounter_clear;
+ wire yCounter_clear;
+ wire vcc;
+
+ reg [((RESOLUTION == "320x240") ? (8) : (7)):0] x;
+ reg [((RESOLUTION == "320x240") ? (7) : (6)):0] y;
+ /* Inputs to the converter. */
+
+ /*****************************************************************************/
+ /* Controller implementation. */
+ /*****************************************************************************/
+
+ assign vcc =1'b1;
+
+ /* A counter to scan through a horizontal line. */
+ always @(posedge vga_clock or negedge resetn)
+ begin
+ if (!resetn)
+ xCounter <= 10'd0;
+ else if (xCounter_clear)
+ xCounter <= 10'd0;
+ else
+ begin
+ xCounter <= xCounter + 1'b1;
+ end
+ end
+ assign xCounter_clear = (xCounter == (C_HORZ_TOTAL_COUNT-1));
+
+ /* A counter to scan vertically, indicating the row currently being drawn. */
+ always @(posedge vga_clock or negedge resetn)
+ begin
+ if (!resetn)
+ yCounter <= 10'd0;
+ else if (xCounter_clear && yCounter_clear)
+ yCounter <= 10'd0;
+ else if (xCounter_clear) //Increment when x counter resets
+ yCounter <= yCounter + 1'b1;
+ end
+ assign yCounter_clear = (yCounter == (C_VERT_TOTAL_COUNT-1));
+
+ /* Convert the xCounter/yCounter location from screen pixels (640x480) to our
+ * local dots (320x240 or 160x120). Here we effectively divide x/y coordinate by 2 or 4,
+ * depending on the resolution. */
+ always @(*)
+ begin
+ if (RESOLUTION == "320x240")
+ begin
+ x = xCounter[9:1];
+ y = yCounter[8:1];
+ end
+ else
+ begin
+ x = xCounter[9:2];
+ y = yCounter[8:2];
+ end
+ end
+
+ /* Change the (x,y) coordinate into a memory address. */
+ vga_address_translator controller_translator(
+ .x(x), .y(y), .mem_address(memory_address) );
+ defparam controller_translator.RESOLUTION = RESOLUTION;
+
+
+ /* Generate the vertical and horizontal synchronization pulses. */
+ always @(posedge vga_clock)
+ begin
+ //- Sync Generator (ACTIVE LOW)
+ if (USING_DE1 == "TRUE")
+ VGA_HS1 <= ~((xCounter >= C_HORZ_SYNC_START-2) && (xCounter <= C_HORZ_SYNC_END-2));
+ else
+ VGA_HS1 <= ~((xCounter >= C_HORZ_SYNC_START) && (xCounter <= C_HORZ_SYNC_END));
+ VGA_VS1 <= ~((yCounter >= C_VERT_SYNC_START) && (yCounter <= C_VERT_SYNC_END));
+
+ //- Current X and Y is valid pixel range
+ VGA_BLANK1 <= ((xCounter < C_HORZ_NUM_PIXELS) && (yCounter < C_VERT_NUM_PIXELS));
+
+ //- Add 1 cycle delay
+ VGA_HS <= VGA_HS1;
+ VGA_VS <= VGA_VS1;
+ VGA_BLANK <= VGA_BLANK1;
+ end
+
+ /* VGA sync should be 1 at all times. */
+ assign VGA_SYNC = vcc;
+
+ /* Generate the VGA clock signal. */
+ assign VGA_CLK = vga_clock;
+
+ /* Brighten the colour output. */
+ // The colour input is first processed to brighten the image a little. Setting the top
+ // bits to correspond to the R,G,B colour makes the image a bit dull. To brighten the image,
+ // each bit of the colour is replicated through the 10 DAC colour input bits. For example,
+ // when BITS_PER_COLOUR_CHANNEL is 2 and the red component is set to 2'b10, then the
+ // VGA_R input to the DAC will be set to 10'b1010101010.
+
+ integer index;
+ integer sub_index;
+
+ wire on_screen;
+
+ assign on_screen = (USING_DE1 == "TRUE") ?
+ (({1'b0, xCounter} >= 2) & ({1'b0, xCounter} < C_HORZ_NUM_PIXELS+2) & ({1'b0, yCounter} < C_VERT_NUM_PIXELS)) :
+ (({1'b0, xCounter} >= 0) & ({1'b0, xCounter} < C_HORZ_NUM_PIXELS+2) & ({1'b0, yCounter} < C_VERT_NUM_PIXELS));
+
+ always @(pixel_colour or on_screen)
+ begin
+ VGA_R <= 'b0;
+ VGA_G <= 'b0;
+ VGA_B <= 'b0;
+ if (MONOCHROME == "FALSE")
+ begin
+ for (index = 10-BITS_PER_COLOUR_CHANNEL; index >= 0; index = index - BITS_PER_COLOUR_CHANNEL)
+ begin
+ for (sub_index = BITS_PER_COLOUR_CHANNEL - 1; sub_index >= 0; sub_index = sub_index - 1)
+ begin
+ VGA_R[sub_index+index] <= on_screen & pixel_colour[sub_index + BITS_PER_COLOUR_CHANNEL*2];
+ VGA_G[sub_index+index] <= on_screen & pixel_colour[sub_index + BITS_PER_COLOUR_CHANNEL];
+ VGA_B[sub_index+index] <= on_screen & pixel_colour[sub_index];
+ end
+ end
+ end
+ else
+ begin
+ for (index = 0; index < 10; index = index + 1)
+ begin
+ VGA_R[index] <= on_screen & pixel_colour[0:0];
+ VGA_G[index] <= on_screen & pixel_colour[0:0];
+ VGA_B[index] <= on_screen & pixel_colour[0:0];
+ end
+ end
+ end
+
+endmodule
diff --git a/vga-core/vga_pll.sv b/vga-core/vga_pll.sv new file mode 100644 index 0000000..d433ef5 --- /dev/null +++ b/vga-core/vga_pll.sv @@ -0,0 +1,173 @@ +// megafunction wizard: %ALTPLL% +// GENERATION: STANDARD +// VERSION: WM1.0 +// MODULE: altpll + +// ============================================================ +// File Name: VgaPll.v +// Megafunction Name(s): +// altpll +// ============================================================ +// ************************************************************ +// THIS IS A WIZARD-GENERATED FILE. DO NOT EDIT THIS FILE! +// +// 5.0 Build 168 06/22/2005 SP 1 SJ Full Version +// ************************************************************ + + +//Copyright (C) 1991-2005 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 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. + + +// synopsys translate_off +`timescale 1 ps / 1 ps +// synopsys translate_on +module vga_pll ( + clock_in, + clock_out); + + input clock_in; + output clock_out; + + wire [5:0] clock_output_bus; + wire [1:0] clock_input_bus; + wire gnd; + + assign gnd = 1'b0; + assign clock_input_bus = { gnd, clock_in }; + + altpll altpll_component ( + .inclk (clock_input_bus), + .clk (clock_output_bus) + ); + defparam + altpll_component.operation_mode = "NORMAL", + altpll_component.intended_device_family = "Cyclone II", + altpll_component.lpm_type = "altpll", + altpll_component.pll_type = "FAST", + /* Specify the input clock to be a 50MHz clock. A 50 MHz clock is present + * on PIN_N2 on the DE2 board. We need to specify the input clock frequency + * in order to set up the PLL correctly. To do this we must put the input clock + * period measured in picoseconds in the inclk0_input_frequency parameter. + * 1/(20000 ps) = 0.5 * 10^(5) Hz = 50 * 10^(6) Hz = 50 MHz. */ + altpll_component.inclk0_input_frequency = 20000, + altpll_component.primary_clock = "INCLK0", + /* Specify output clock parameters. The output clock should have a + * frequency of 25 MHz, with 50% duty cycle. */ + altpll_component.compensate_clock = "CLK0", + altpll_component.clk0_phase_shift = "0", + altpll_component.clk0_divide_by = 2, + altpll_component.clk0_multiply_by = 1, + altpll_component.clk0_duty_cycle = 50; + + assign clock_out = clock_output_bus[0]; + +endmodule + +// ============================================================ +// CNX file retrieval info +// ============================================================ +// Retrieval info: PRIVATE: MIRROR_CLK0 STRING "0" +// Retrieval info: PRIVATE: PHASE_SHIFT_UNIT0 STRING "deg" +// Retrieval info: PRIVATE: OUTPUT_FREQ_UNIT0 STRING "MHz" +// Retrieval info: PRIVATE: INCLK1_FREQ_UNIT_COMBO STRING "MHz" +// Retrieval info: PRIVATE: SPREAD_USE STRING "0" +// Retrieval info: PRIVATE: SPREAD_FEATURE_ENABLED STRING "0" +// Retrieval info: PRIVATE: GLOCKED_COUNTER_EDIT_CHANGED STRING "1" +// Retrieval info: PRIVATE: GLOCK_COUNTER_EDIT NUMERIC "1048575" +// Retrieval info: PRIVATE: SRC_SYNCH_COMP_RADIO STRING "0" +// Retrieval info: PRIVATE: DUTY_CYCLE0 STRING "50.00000000" +// Retrieval info: PRIVATE: PHASE_SHIFT0 STRING "0.00000000" +// Retrieval info: PRIVATE: MULT_FACTOR0 NUMERIC "1" +// Retrieval info: PRIVATE: OUTPUT_FREQ_MODE0 STRING "1" +// Retrieval info: PRIVATE: SPREAD_PERCENT STRING "0.500" +// Retrieval info: PRIVATE: LOCKED_OUTPUT_CHECK STRING "0" +// Retrieval info: PRIVATE: PLL_ARESET_CHECK STRING "0" +// Retrieval info: PRIVATE: STICKY_CLK0 STRING "1" +// Retrieval info: PRIVATE: BANDWIDTH STRING "1.000" +// Retrieval info: PRIVATE: BANDWIDTH_USE_CUSTOM STRING "0" +// Retrieval info: PRIVATE: DEVICE_SPEED_GRADE STRING "Any" +// Retrieval info: PRIVATE: SPREAD_FREQ STRING "50.000" +// Retrieval info: PRIVATE: BANDWIDTH_FEATURE_ENABLED STRING "0" +// Retrieval info: PRIVATE: LONG_SCAN_RADIO STRING "1" +// Retrieval info: PRIVATE: PLL_ENHPLL_CHECK NUMERIC "0" +// Retrieval info: PRIVATE: LVDS_MODE_DATA_RATE_DIRTY NUMERIC "0" +// Retrieval info: PRIVATE: USE_CLK0 STRING "1" +// Retrieval info: PRIVATE: INCLK1_FREQ_EDIT_CHANGED STRING "1" +// Retrieval info: PRIVATE: SCAN_FEATURE_ENABLED STRING "0" +// Retrieval info: PRIVATE: ZERO_DELAY_RADIO STRING "0" +// Retrieval info: PRIVATE: PLL_PFDENA_CHECK STRING "0" +// Retrieval info: PRIVATE: CREATE_CLKBAD_CHECK STRING "0" +// Retrieval info: PRIVATE: INCLK1_FREQ_EDIT STRING "50.000" +// Retrieval info: PRIVATE: CUR_DEDICATED_CLK STRING "c0" +// Retrieval info: PRIVATE: PLL_FASTPLL_CHECK NUMERIC "0" +// Retrieval info: PRIVATE: ACTIVECLK_CHECK STRING "0" +// Retrieval info: PRIVATE: BANDWIDTH_FREQ_UNIT STRING "MHz" +// Retrieval info: PRIVATE: INCLK0_FREQ_UNIT_COMBO STRING "MHz" +// Retrieval info: PRIVATE: GLOCKED_MODE_CHECK STRING "0" +// Retrieval info: PRIVATE: NORMAL_MODE_RADIO STRING "1" +// Retrieval info: PRIVATE: CUR_FBIN_CLK STRING "e0" +// Retrieval info: PRIVATE: DIV_FACTOR0 NUMERIC "1" +// Retrieval info: PRIVATE: INCLK1_FREQ_UNIT_CHANGED STRING "1" +// Retrieval info: PRIVATE: HAS_MANUAL_SWITCHOVER STRING "1" +// Retrieval info: PRIVATE: EXT_FEEDBACK_RADIO STRING "0" +// Retrieval info: PRIVATE: PLL_AUTOPLL_CHECK NUMERIC "1" +// Retrieval info: PRIVATE: CLKLOSS_CHECK STRING "0" +// Retrieval info: PRIVATE: BANDWIDTH_USE_AUTO STRING "1" +// Retrieval info: PRIVATE: SHORT_SCAN_RADIO STRING "0" +// Retrieval info: PRIVATE: LVDS_MODE_DATA_RATE STRING "Not Available" +// Retrieval info: PRIVATE: CLKSWITCH_CHECK STRING "1" +// Retrieval info: PRIVATE: SPREAD_FREQ_UNIT STRING "KHz" +// Retrieval info: PRIVATE: PLL_ENA_CHECK STRING "0" +// Retrieval info: PRIVATE: INCLK0_FREQ_EDIT STRING "50.000" +// Retrieval info: PRIVATE: CNX_NO_COMPENSATE_RADIO STRING "0" +// Retrieval info: PRIVATE: INT_FEEDBACK__MODE_RADIO STRING "1" +// Retrieval info: PRIVATE: OUTPUT_FREQ0 STRING "25.000" +// Retrieval info: PRIVATE: PRIMARY_CLK_COMBO STRING "inclk0" +// Retrieval info: PRIVATE: CREATE_INCLK1_CHECK STRING "0" +// Retrieval info: PRIVATE: SACN_INPUTS_CHECK STRING "0" +// Retrieval info: PRIVATE: DEV_FAMILY STRING "Cyclone II" +// Retrieval info: PRIVATE: SWITCHOVER_COUNT_EDIT NUMERIC "1" +// Retrieval info: PRIVATE: SWITCHOVER_FEATURE_ENABLED STRING "1" +// Retrieval info: PRIVATE: BANDWIDTH_PRESET STRING "Low" +// Retrieval info: PRIVATE: GLOCKED_FEATURE_ENABLED STRING "1" +// Retrieval info: PRIVATE: USE_CLKENA0 STRING "0" +// Retrieval info: PRIVATE: LVDS_PHASE_SHIFT_UNIT0 STRING "deg" +// Retrieval info: PRIVATE: CLKBAD_SWITCHOVER_CHECK STRING "0" +// Retrieval info: PRIVATE: BANDWIDTH_USE_PRESET STRING "0" +// Retrieval info: PRIVATE: PLL_LVDS_PLL_CHECK NUMERIC "0" +// Retrieval info: LIBRARY: altera_mf altera_mf.altera_mf_components.all +// Retrieval info: CONSTANT: CLK0_DUTY_CYCLE NUMERIC "50" +// Retrieval info: CONSTANT: LPM_TYPE STRING "altpll" +// Retrieval info: CONSTANT: CLK0_MULTIPLY_BY NUMERIC "1" +// Retrieval info: CONSTANT: INCLK0_INPUT_FREQUENCY NUMERIC "20000" +// Retrieval info: CONSTANT: CLK0_DIVIDE_BY NUMERIC "2" +// Retrieval info: CONSTANT: PLL_TYPE STRING "FAST" +// Retrieval info: CONSTANT: INTENDED_DEVICE_FAMILY STRING "Cyclone II" +// Retrieval info: CONSTANT: OPERATION_MODE STRING "NORMAL" +// Retrieval info: CONSTANT: COMPENSATE_CLOCK STRING "CLK0" +// Retrieval info: CONSTANT: CLK0_PHASE_SHIFT STRING "0" +// Retrieval info: USED_PORT: c0 0 0 0 0 OUTPUT VCC "c0" +// Retrieval info: USED_PORT: @clk 0 0 6 0 OUTPUT VCC "@clk[5..0]" +// Retrieval info: USED_PORT: inclk0 0 0 0 0 INPUT GND "inclk0" +// Retrieval info: USED_PORT: @extclk 0 0 4 0 OUTPUT VCC "@extclk[3..0]" +// Retrieval info: CONNECT: @inclk 0 0 1 0 inclk0 0 0 0 0 +// Retrieval info: CONNECT: c0 0 0 0 0 @clk 0 0 1 0 +// Retrieval info: CONNECT: @inclk 0 0 1 1 GND 0 0 0 0 +// Retrieval info: GEN_FILE: TYPE_NORMAL VgaPll.v TRUE FALSE +// Retrieval info: GEN_FILE: TYPE_NORMAL VgaPll.inc FALSE FALSE +// Retrieval info: GEN_FILE: TYPE_NORMAL VgaPll.cmp FALSE FALSE +// Retrieval info: GEN_FILE: TYPE_NORMAL VgaPll.bsf FALSE FALSE +// Retrieval info: GEN_FILE: TYPE_NORMAL VgaPll_inst.v FALSE FALSE +// Retrieval info: GEN_FILE: TYPE_NORMAL VgaPll_bb.v FALSE FALSE diff --git a/vga-core/vga_pll.v b/vga-core/vga_pll.v new file mode 100644 index 0000000..bbf375f --- /dev/null +++ b/vga-core/vga_pll.v @@ -0,0 +1,173 @@ +// megafunction wizard: %ALTPLL%
+// GENERATION: STANDARD
+// VERSION: WM1.0
+// MODULE: altpll
+
+// ============================================================
+// File Name: VgaPll.v
+// Megafunction Name(s):
+// altpll
+// ============================================================
+// ************************************************************
+// THIS IS A WIZARD-GENERATED FILE. DO NOT EDIT THIS FILE!
+//
+// 5.0 Build 168 06/22/2005 SP 1 SJ Full Version
+// ************************************************************
+
+
+//Copyright (C) 1991-2005 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 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.
+
+
+// synopsys translate_off
+`timescale 1 ps / 1 ps
+// synopsys translate_on
+module vga_pll (
+ clock_in,
+ clock_out);
+
+ input clock_in;
+ output clock_out;
+
+ wire [5:0] clock_output_bus;
+ wire [1:0] clock_input_bus;
+ wire gnd;
+
+ assign gnd = 1'b0;
+ assign clock_input_bus = { gnd, clock_in };
+
+ altpll altpll_component (
+ .inclk (clock_input_bus),
+ .clk (clock_output_bus)
+ );
+ defparam
+ altpll_component.operation_mode = "NORMAL",
+ altpll_component.intended_device_family = "Cyclone II",
+ altpll_component.lpm_type = "altpll",
+ altpll_component.pll_type = "FAST",
+ /* Specify the input clock to be a 50MHz clock. A 50 MHz clock is present
+ * on PIN_N2 on the DE2 board. We need to specify the input clock frequency
+ * in order to set up the PLL correctly. To do this we must put the input clock
+ * period measured in picoseconds in the inclk0_input_frequency parameter.
+ * 1/(20000 ps) = 0.5 * 10^(5) Hz = 50 * 10^(6) Hz = 50 MHz. */
+ altpll_component.inclk0_input_frequency = 20000,
+ altpll_component.primary_clock = "INCLK0",
+ /* Specify output clock parameters. The output clock should have a
+ * frequency of 25 MHz, with 50% duty cycle. */
+ altpll_component.compensate_clock = "CLK0",
+ altpll_component.clk0_phase_shift = "0",
+ altpll_component.clk0_divide_by = 2,
+ altpll_component.clk0_multiply_by = 1,
+ altpll_component.clk0_duty_cycle = 50;
+
+ assign clock_out = clock_output_bus[0];
+
+endmodule
+
+// ============================================================
+// CNX file retrieval info
+// ============================================================
+// Retrieval info: PRIVATE: MIRROR_CLK0 STRING "0"
+// Retrieval info: PRIVATE: PHASE_SHIFT_UNIT0 STRING "deg"
+// Retrieval info: PRIVATE: OUTPUT_FREQ_UNIT0 STRING "MHz"
+// Retrieval info: PRIVATE: INCLK1_FREQ_UNIT_COMBO STRING "MHz"
+// Retrieval info: PRIVATE: SPREAD_USE STRING "0"
+// Retrieval info: PRIVATE: SPREAD_FEATURE_ENABLED STRING "0"
+// Retrieval info: PRIVATE: GLOCKED_COUNTER_EDIT_CHANGED STRING "1"
+// Retrieval info: PRIVATE: GLOCK_COUNTER_EDIT NUMERIC "1048575"
+// Retrieval info: PRIVATE: SRC_SYNCH_COMP_RADIO STRING "0"
+// Retrieval info: PRIVATE: DUTY_CYCLE0 STRING "50.00000000"
+// Retrieval info: PRIVATE: PHASE_SHIFT0 STRING "0.00000000"
+// Retrieval info: PRIVATE: MULT_FACTOR0 NUMERIC "1"
+// Retrieval info: PRIVATE: OUTPUT_FREQ_MODE0 STRING "1"
+// Retrieval info: PRIVATE: SPREAD_PERCENT STRING "0.500"
+// Retrieval info: PRIVATE: LOCKED_OUTPUT_CHECK STRING "0"
+// Retrieval info: PRIVATE: PLL_ARESET_CHECK STRING "0"
+// Retrieval info: PRIVATE: STICKY_CLK0 STRING "1"
+// Retrieval info: PRIVATE: BANDWIDTH STRING "1.000"
+// Retrieval info: PRIVATE: BANDWIDTH_USE_CUSTOM STRING "0"
+// Retrieval info: PRIVATE: DEVICE_SPEED_GRADE STRING "Any"
+// Retrieval info: PRIVATE: SPREAD_FREQ STRING "50.000"
+// Retrieval info: PRIVATE: BANDWIDTH_FEATURE_ENABLED STRING "0"
+// Retrieval info: PRIVATE: LONG_SCAN_RADIO STRING "1"
+// Retrieval info: PRIVATE: PLL_ENHPLL_CHECK NUMERIC "0"
+// Retrieval info: PRIVATE: LVDS_MODE_DATA_RATE_DIRTY NUMERIC "0"
+// Retrieval info: PRIVATE: USE_CLK0 STRING "1"
+// Retrieval info: PRIVATE: INCLK1_FREQ_EDIT_CHANGED STRING "1"
+// Retrieval info: PRIVATE: SCAN_FEATURE_ENABLED STRING "0"
+// Retrieval info: PRIVATE: ZERO_DELAY_RADIO STRING "0"
+// Retrieval info: PRIVATE: PLL_PFDENA_CHECK STRING "0"
+// Retrieval info: PRIVATE: CREATE_CLKBAD_CHECK STRING "0"
+// Retrieval info: PRIVATE: INCLK1_FREQ_EDIT STRING "50.000"
+// Retrieval info: PRIVATE: CUR_DEDICATED_CLK STRING "c0"
+// Retrieval info: PRIVATE: PLL_FASTPLL_CHECK NUMERIC "0"
+// Retrieval info: PRIVATE: ACTIVECLK_CHECK STRING "0"
+// Retrieval info: PRIVATE: BANDWIDTH_FREQ_UNIT STRING "MHz"
+// Retrieval info: PRIVATE: INCLK0_FREQ_UNIT_COMBO STRING "MHz"
+// Retrieval info: PRIVATE: GLOCKED_MODE_CHECK STRING "0"
+// Retrieval info: PRIVATE: NORMAL_MODE_RADIO STRING "1"
+// Retrieval info: PRIVATE: CUR_FBIN_CLK STRING "e0"
+// Retrieval info: PRIVATE: DIV_FACTOR0 NUMERIC "1"
+// Retrieval info: PRIVATE: INCLK1_FREQ_UNIT_CHANGED STRING "1"
+// Retrieval info: PRIVATE: HAS_MANUAL_SWITCHOVER STRING "1"
+// Retrieval info: PRIVATE: EXT_FEEDBACK_RADIO STRING "0"
+// Retrieval info: PRIVATE: PLL_AUTOPLL_CHECK NUMERIC "1"
+// Retrieval info: PRIVATE: CLKLOSS_CHECK STRING "0"
+// Retrieval info: PRIVATE: BANDWIDTH_USE_AUTO STRING "1"
+// Retrieval info: PRIVATE: SHORT_SCAN_RADIO STRING "0"
+// Retrieval info: PRIVATE: LVDS_MODE_DATA_RATE STRING "Not Available"
+// Retrieval info: PRIVATE: CLKSWITCH_CHECK STRING "1"
+// Retrieval info: PRIVATE: SPREAD_FREQ_UNIT STRING "KHz"
+// Retrieval info: PRIVATE: PLL_ENA_CHECK STRING "0"
+// Retrieval info: PRIVATE: INCLK0_FREQ_EDIT STRING "50.000"
+// Retrieval info: PRIVATE: CNX_NO_COMPENSATE_RADIO STRING "0"
+// Retrieval info: PRIVATE: INT_FEEDBACK__MODE_RADIO STRING "1"
+// Retrieval info: PRIVATE: OUTPUT_FREQ0 STRING "25.000"
+// Retrieval info: PRIVATE: PRIMARY_CLK_COMBO STRING "inclk0"
+// Retrieval info: PRIVATE: CREATE_INCLK1_CHECK STRING "0"
+// Retrieval info: PRIVATE: SACN_INPUTS_CHECK STRING "0"
+// Retrieval info: PRIVATE: DEV_FAMILY STRING "Cyclone II"
+// Retrieval info: PRIVATE: SWITCHOVER_COUNT_EDIT NUMERIC "1"
+// Retrieval info: PRIVATE: SWITCHOVER_FEATURE_ENABLED STRING "1"
+// Retrieval info: PRIVATE: BANDWIDTH_PRESET STRING "Low"
+// Retrieval info: PRIVATE: GLOCKED_FEATURE_ENABLED STRING "1"
+// Retrieval info: PRIVATE: USE_CLKENA0 STRING "0"
+// Retrieval info: PRIVATE: LVDS_PHASE_SHIFT_UNIT0 STRING "deg"
+// Retrieval info: PRIVATE: CLKBAD_SWITCHOVER_CHECK STRING "0"
+// Retrieval info: PRIVATE: BANDWIDTH_USE_PRESET STRING "0"
+// Retrieval info: PRIVATE: PLL_LVDS_PLL_CHECK NUMERIC "0"
+// Retrieval info: LIBRARY: altera_mf altera_mf.altera_mf_components.all
+// Retrieval info: CONSTANT: CLK0_DUTY_CYCLE NUMERIC "50"
+// Retrieval info: CONSTANT: LPM_TYPE STRING "altpll"
+// Retrieval info: CONSTANT: CLK0_MULTIPLY_BY NUMERIC "1"
+// Retrieval info: CONSTANT: INCLK0_INPUT_FREQUENCY NUMERIC "20000"
+// Retrieval info: CONSTANT: CLK0_DIVIDE_BY NUMERIC "2"
+// Retrieval info: CONSTANT: PLL_TYPE STRING "FAST"
+// Retrieval info: CONSTANT: INTENDED_DEVICE_FAMILY STRING "Cyclone II"
+// Retrieval info: CONSTANT: OPERATION_MODE STRING "NORMAL"
+// Retrieval info: CONSTANT: COMPENSATE_CLOCK STRING "CLK0"
+// Retrieval info: CONSTANT: CLK0_PHASE_SHIFT STRING "0"
+// Retrieval info: USED_PORT: c0 0 0 0 0 OUTPUT VCC "c0"
+// Retrieval info: USED_PORT: @clk 0 0 6 0 OUTPUT VCC "@clk[5..0]"
+// Retrieval info: USED_PORT: inclk0 0 0 0 0 INPUT GND "inclk0"
+// Retrieval info: USED_PORT: @extclk 0 0 4 0 OUTPUT VCC "@extclk[3..0]"
+// Retrieval info: CONNECT: @inclk 0 0 1 0 inclk0 0 0 0 0
+// Retrieval info: CONNECT: c0 0 0 0 0 @clk 0 0 1 0
+// Retrieval info: CONNECT: @inclk 0 0 1 1 GND 0 0 0 0
+// Retrieval info: GEN_FILE: TYPE_NORMAL VgaPll.v TRUE FALSE
+// Retrieval info: GEN_FILE: TYPE_NORMAL VgaPll.inc FALSE FALSE
+// Retrieval info: GEN_FILE: TYPE_NORMAL VgaPll.cmp FALSE FALSE
+// Retrieval info: GEN_FILE: TYPE_NORMAL VgaPll.bsf FALSE FALSE
+// Retrieval info: GEN_FILE: TYPE_NORMAL VgaPll_inst.v FALSE FALSE
+// Retrieval info: GEN_FILE: TYPE_NORMAL VgaPll_bb.v FALSE FALSE
|