Skip to content

Instantly share code, notes, and snippets.

@peterzhu2118
Created November 11, 2018 15:08
Show Gist options
  • Save peterzhu2118/c234954bf974fbb731e8aabb6731e373 to your computer and use it in GitHub Desktop.
Save peterzhu2118/c234954bf974fbb731e8aabb6731e373 to your computer and use it in GitHub Desktop.
CSC258 Lab 7 Part 2
WIDTH=3;
DEPTH=19200;
ADDRESS_RADIX=UNS;
DATA_RADIX=UNS;
CONTENT BEGIN
[0..19199] : 0;
END;
// Part 2 skeleton
module part2
(
CLOCK_50, // On Board 50 MHz
// Your inputs and outputs here
KEY,
SW,
// The ports below are for the VGA output. Do not change.
VGA_CLK, // VGA Clock
VGA_HS, // VGA H_SYNC
VGA_VS, // VGA V_SYNC
VGA_BLANK_N, // VGA BLANK
VGA_SYNC_N, // VGA SYNC
VGA_R, // VGA Red[9:0]
VGA_G, // VGA Green[9:0]
VGA_B // VGA Blue[9:0]
);
input CLOCK_50; // 50 MHz
input [9:0] SW;
input [3:0] KEY;
// Declare your inputs and outputs here
// Do not change the following outputs
output VGA_CLK; // VGA Clock
output VGA_HS; // VGA H_SYNC
output VGA_VS; // VGA V_SYNC
output VGA_BLANK_N; // VGA BLANK
output VGA_SYNC_N; // VGA SYNC
output [9:0] VGA_R; // VGA Red[9:0]
output [9:0] VGA_G; // VGA Green[9:0]
output [9:0] VGA_B; // VGA Blue[9:0]
wire resetn;
assign resetn = KEY[0];
// Create the colour, x, y and writeEn wires that are inputs to the controller.
wire [2:0] colour;
wire [7:0] x;
wire [6:0] y;
wire writeEn;
// Create an Instance of a VGA controller - there can be only one!
// Define the number of colours as well as the initial background
// image file (.MIF) for the controller.
vga_adapter VGA(
.resetn(resetn),
.clock(CLOCK_50),
.colour(colour),
.x(x),
.y(y),
.plot(writeEn),
/* Signals for the DAC to drive the monitor. */
.VGA_R(VGA_R),
.VGA_G(VGA_G),
.VGA_B(VGA_B),
.VGA_HS(VGA_HS),
.VGA_VS(VGA_VS),
.VGA_BLANK(VGA_BLANK_N),
.VGA_SYNC(VGA_SYNC_N),
.VGA_CLK(VGA_CLK));
defparam VGA.RESOLUTION = "160x120";
defparam VGA.MONOCHROME = "FALSE";
defparam VGA.BITS_PER_COLOUR_CHANNEL = 1;
defparam VGA.BACKGROUND_IMAGE = "black.mif";
// Put your code here. Your code should produce signals x,y,colour and writeEn/plot
// for the VGA controller, in addition to any other functionality your design may require.
wire ld_x, ld_y;
control c0(
.go(~KEY[3]),
.plotkey(~KEY[1]),
.resetn(KEY[0]),
.clk(CLOCK_50),
.ld_x(ld_x),
.ld_y(ld_y),
.plot(writeEn)
);
datapath d0(
.SW(SW),
.clk(CLOCK_50),
.ld_x(ld_x),
.ld_y(ld_y),
.plot(writeEn),
.x(x),
.y(y),
.color(colour)
);
endmodule
module datapath(SW, clk, resetn, ld_x, ld_y, plot, x, y, color);
input [9:0] SW;
input clk;
input resetn;
input ld_x, ld_y, plot;
output [7:0] x;
output [6:0] y;
output [2:0] color;
reg [7:0] x;
reg [6:0] y;
reg [2:0] color;
reg [7:0] temp_x;
reg [6:0] temp_y;
reg [3:0] counter;
always @(posedge clk) begin
if (!resetn) begin
x <= 8'd0;
y <= 7'd0;
counter <= 4'd0;
end
else begin
if (ld_x)
counter <= 0;
temp_x <= {1'b0, SW[6:0]};
if (ld_y) begin
temp_y <= SW[6:0];
end
if (plot) begin
x <= temp_x + (counter / 4'd4);
y <= temp_y + (counter % 4'd4);
color <= SW[9:7];
counter <= counter + 1;
end
end
end
endmodule
module control(go, plotkey, clk, resetn, ld_x, ld_y, plot);
input go;
input plotkey;
input clk;
input resetn;
output ld_x;
output ld_y;
output plot;
reg ld_x;
reg ld_y;
reg plot;
localparam S_LOAD_X = 5'd0,
S_LOAD_X_WAIT = 5'd1,
S_LOAD_Y = 5'd2,
S_PLOT_0 = 5'd3,
S_PLOT_1 = 5'd4,
S_PLOT_2 = 5'd5,
S_PLOT_3 = 5'd6,
S_PLOT_4 = 5'd7,
S_PLOT_5 = 5'd8,
S_PLOT_6 = 5'd9,
S_PLOT_7 = 5'd10,
S_PLOT_8 = 5'd11,
S_PLOT_9 = 5'd12,
S_PLOT_10 = 5'd13,
S_PLOT_11 = 5'd14,
S_PLOT_12 = 5'd15,
S_PLOT_13 = 5'd16,
S_PLOT_14 = 5'd17,
S_PLOT_15 = 5'd18,
S_PLOT_16 = 5'd19;
reg [4:0] next_state;
reg [4:0] current_state;
always @(*)
begin: state_table
case (current_state)
S_LOAD_X: next_state = go ? S_LOAD_X_WAIT : S_LOAD_X;
S_LOAD_X_WAIT: next_state = go ? S_LOAD_X_WAIT : S_LOAD_Y;
S_LOAD_Y: next_state = plotkey ? S_PLOT_0 : S_LOAD_Y;
S_PLOT_0: next_state = S_PLOT_1;
S_PLOT_1: next_state = S_PLOT_2;
S_PLOT_2: next_state = S_PLOT_3;
S_PLOT_3: next_state = S_PLOT_4;
S_PLOT_4: next_state = S_PLOT_5;
S_PLOT_5: next_state = S_PLOT_6;
S_PLOT_6: next_state = S_PLOT_7;
S_PLOT_7: next_state = S_PLOT_8;
S_PLOT_8: next_state = S_PLOT_9;
S_PLOT_9: next_state = S_PLOT_10;
S_PLOT_10: next_state = S_PLOT_11;
S_PLOT_11: next_state = S_PLOT_12;
S_PLOT_12: next_state = S_PLOT_13;
S_PLOT_13: next_state = S_PLOT_14;
S_PLOT_14: next_state = S_PLOT_15;
S_PLOT_15: next_state = S_PLOT_16;
S_PLOT_16: next_state = S_LOAD_X;
default: next_state = S_LOAD_X;
endcase
end
always @(*)
begin: enable_signals
ld_x = 0;
ld_y = 0;
plot = 0;
case (current_state)
S_LOAD_X: ld_x = 1;
S_LOAD_Y: ld_y = 1;
S_PLOT_0: plot = 1;
S_PLOT_1: plot = 1;
S_PLOT_2: plot = 1;
S_PLOT_3: plot = 1;
S_PLOT_4: plot = 1;
S_PLOT_5: plot = 1;
S_PLOT_6: plot = 1;
S_PLOT_7: plot = 1;
S_PLOT_8: plot = 1;
S_PLOT_9: plot = 1;
S_PLOT_10: plot = 1;
S_PLOT_11: plot = 1;
S_PLOT_12: plot = 1;
S_PLOT_13: plot = 1;
S_PLOT_14: plot = 1;
S_PLOT_15: plot = 1;
S_PLOT_16: plot = 1;
endcase
end
always @(posedge clk)
begin: state_FFs
if (!resetn)
current_state <= S_LOAD_X;
else
current_state <= next_state;
end
endmodule
/*
WARNING: Do NOT edit the input and output ports in this file in a text
editor if you plan to continue editing the block that represents it in
the Block Editor! File corruption is VERY likely to occur.
*/
/*
Copyright (C) 1991-2007 Altera Corporation
Your use of Altera Corporation's design tools, logic functions
and other software and tools, and its AMPP partner logic
functions, and any output files from any of the foregoing
(including device programming or simulation files), and any
associated documentation or information are expressly subject
to the terms and conditions of the Altera Program License
Subscription Agreement, Altera MegaCore Function License
Agreement, or other applicable license agreement, including,
without limitation, that your use is for the sole purpose of
programming logic devices manufactured by Altera and sold by
Altera or its authorized distributors. Please refer to the
applicable agreement for further details.
*/
(header "symbol" (version "1.1"))
(symbol
(rect 64 64 552 256)
(text "vga_adapter" (rect 5 0 66 12)(font "Arial" ))
(text "inst" (rect 8 176 25 188)(font "Arial" ))
(port
(pt 0 32)
(input)
(text "resetn" (rect 0 0 30 12)(font "Arial" ))
(text "resetn" (rect 21 27 51 39)(font "Arial" ))
(line (pt 0 32)(pt 16 32)(line_width 1))
)
(port
(pt 0 48)
(input)
(text "clock" (rect 0 0 25 12)(font "Arial" ))
(text "clock" (rect 21 43 46 55)(font "Arial" ))
(line (pt 0 48)(pt 16 48)(line_width 1))
)
(port
(pt 0 112)
(input)
(text "plot" (rect 0 0 17 12)(font "Arial" ))
(text "plot" (rect 21 107 38 119)(font "Arial" ))
(line (pt 0 112)(pt 16 112)(line_width 1))
)
(port
(pt 0 80)
(input)
(text "x[(7-(RESOLUTION==\"320x240\"))..0]" (rect 0 0 180 12)(font "Arial" ))
(text "x[(7-(RESOLUTION==\"320x240\"))..0]" (rect 21 75 201 87)(font "Arial" ))
(line (pt 0 80)(pt 16 80)(line_width 3))
)
(port
(pt 0 96)
(input)
(text "y[(6-(RESOLUTION==\"320x240\"))..0]" (rect 0 0 181 12)(font "Arial" ))
(text "y[(6-(RESOLUTION==\"320x240\"))..0]" (rect 21 91 202 103)(font "Arial" ))
(line (pt 0 96)(pt 16 96)(line_width 3))
)
(port
(pt 0 64)
(input)
(text "colour[((3*BITS_PER_COLOUR_CHANNEL-1) & (MONOCHROME==\"FALSE\"))..0]" (rect 0 0 403 12)(font "Arial" ))
(text "colour[((3*BITS_PER_COLOUR_CHANNEL-1) & (MONOCHROME==\"FALSE\"))..0]" (rect 21 59 424 71)(font "Arial" ))
(line (pt 0 64)(pt 16 64)(line_width 3))
)
(port
(pt 488 32)
(output)
(text "VGA_R[9..0]" (rect 0 0 62 12)(font "Arial" ))
(text "VGA_R[9..0]" (rect 405 27 467 39)(font "Arial" ))
(line (pt 488 32)(pt 472 32)(line_width 3))
)
(port
(pt 488 48)
(output)
(text "VGA_G[9..0]" (rect 0 0 62 12)(font "Arial" ))
(text "VGA_G[9..0]" (rect 405 43 467 55)(font "Arial" ))
(line (pt 488 48)(pt 472 48)(line_width 3))
)
(port
(pt 488 64)
(output)
(text "VGA_B[9..0]" (rect 0 0 61 12)(font "Arial" ))
(text "VGA_B[9..0]" (rect 406 59 467 71)(font "Arial" ))
(line (pt 488 64)(pt 472 64)(line_width 3))
)
(port
(pt 488 80)
(output)
(text "VGA_HS" (rect 0 0 43 12)(font "Arial" ))
(text "VGA_HS" (rect 424 75 467 87)(font "Arial" ))
(line (pt 488 80)(pt 472 80)(line_width 1))
)
(port
(pt 488 96)
(output)
(text "VGA_VS" (rect 0 0 42 12)(font "Arial" ))
(text "VGA_VS" (rect 425 91 467 103)(font "Arial" ))
(line (pt 488 96)(pt 472 96)(line_width 1))
)
(port
(pt 488 112)
(output)
(text "VGA_BLANK" (rect 0 0 63 12)(font "Arial" ))
(text "VGA_BLANK" (rect 404 107 467 119)(font "Arial" ))
(line (pt 488 112)(pt 472 112)(line_width 1))
)
(port
(pt 488 128)
(output)
(text "VGA_SYNC" (rect 0 0 60 12)(font "Arial" ))
(text "VGA_SYNC" (rect 407 123 467 135)(font "Arial" ))
(line (pt 488 128)(pt 472 128)(line_width 1))
)
(port
(pt 488 144)
(output)
(text "VGA_CLK" (rect 0 0 49 12)(font "Arial" ))
(text "VGA_CLK" (rect 418 139 467 151)(font "Arial" ))
(line (pt 488 144)(pt 472 144)(line_width 1))
)
(parameter
"BITS_PER_COLOUR_CHANNEL"
"1"
""
)
(parameter
"MONOCHROME"
"\"FALSE\""
""
)
(parameter
"RESOLUTION"
"\"320x240\""
""
)
(parameter
"BACKGROUND_IMAGE"
"\"background.mif\""
""
)
(drawing
(rectangle (rect 16 16 472 176)(line_width 1))
)
(annotation_block (parameter)(rect 552 -8 800 64))
)
/* 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. */
/*****************************************************************************/
/* 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;
endmodule
/* 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
/* 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.
*/
//--- 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 = 10'd480;
parameter C_VERT_SYNC_START = 10'd493;
parameter C_VERT_SYNC_END = 10'd494; //(C_VERT_SYNC_START + 2 - 1);
parameter C_VERT_TOTAL_COUNT = 10'd525;
parameter C_HORZ_NUM_PIXELS = 10'd640;
parameter C_HORZ_SYNC_START = 10'd659;
parameter C_HORZ_SYNC_END = 10'd754; //(C_HORZ_SYNC_START + 96 - 1);
parameter C_HORZ_TOTAL_COUNT = 10'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)
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;
always @(pixel_colour)
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] <= pixel_colour[sub_index + BITS_PER_COLOUR_CHANNEL*2];
VGA_G[sub_index+index] <= pixel_colour[sub_index + BITS_PER_COLOUR_CHANNEL];
VGA_B[sub_index+index] <= pixel_colour[sub_index];
end
end
end
else
begin
for (index = 0; index < 10; index = index + 1)
begin
VGA_R[index] <= pixel_colour[0:0];
VGA_G[index] <= pixel_colour[0:0];
VGA_B[index] <= pixel_colour[0:0];
end
end
end
endmodule
// 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
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment