-
Notifications
You must be signed in to change notification settings - Fork 3
Add initial content to vga_timing.sv #38
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
JayR-360
wants to merge
6
commits into
main
Choose a base branch
from
Video/Audio
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from all commits
Commits
Show all changes
6 commits
Select commit
Hold shift + click to select a range
f5f490e
Add initial content to vga_timing.sv
JayR-360 ed48052
Add VGA_timing module for video synchronization
JayR-360 dbb83f5
Erase 'timescale' from VGA_timing module
Meowcaroni 93b651c
Merge branch 'main' into Video/Audio
JayR-360 ffff12e
Update VGA_timing module with new input and logic
JayR-360 7b8cad6
Document VGA timing module functionality
JayR-360 File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,60 @@ | ||
| The purpose of the VGA timing module is to generate the horizontal and vertical synchronization pulses and pixel coordinate signals required for standard VGA resolutions (e.g., 640×480 @ 60 Hz). It defines when each pixel should be drawn, when blanking intervals occur, and when sync pulses are active essentially acting as the heartbeat of the display pipeline. Other video blocks, such as the framebuffer controller or DAC driver, use these timing signals to know when to fetch and output video data. | ||
|
|
||
| Parameters | ||
|
|
||
| | Name | Default | Description | | ||
| | ----------| ------- | --------------------------------------------| | ||
| | H_RES | 640 | Active horizontal pixels per line | | ||
| | V_RES | 480 | Active vertical pixels per frame | | ||
| | H_FP | 16 | Horizontal front porch (pixels) | | ||
| | H_SYNC | 96 | Horizontal sync pulse width (pixels) | | ||
| | H_BP | 48 | Horizontal back porch (pixels) | | ||
| | V_FP | 10 | Vertical front porch (lines) | | ||
| | V_SYNC | 2 | Vertical sync pulse width (lines) | | ||
| | V_BP | 2 | Vertical back porch (lines) | | ||
| | PIXEL_CLK | 25*10^6 | Pixel clock frequency for 640 by 480 @ 60Hz | | ||
|
|
||
| Interfaces (Ports) | ||
|
|
||
| | Signal | Dir | Width | Description | | ||
| | ---- | ---- | ---- |-------------------------------------------------------------------------------------------------------------| | ||
| | clk | Input | 1 | Main pixel clock. Ensures timing logic and display pipeline stay synchronized | | ||
| | reset | Input | 1 | Active-low synchronous reset | | ||
| | hsync | Output | 1 | Horizontal sync pulse. Signals the end of a frame (start of new refresh) | | ||
| | vsync | Output | 1 | Vertical sync pulse. Signals the end of a frame (start of new fresh) | | ||
| | x | Output | 10 | Horizontal pixel counter (0-639 during active display) | | ||
| | y | Output | 10 | Vertical pixel counter (0-479 during active display) | | ||
| | active_video | Output | 1 | High during visible display time; low during blanking intervals (used to gate pixel output or blank screen) | | ||
|
|
||
| Reset/Initialization | ||
|
|
||
| - On reset (reset = 0), all internal counters (x,y) reset to zero and both sync outputs (hsync, vsync) are deserted | ||
| - The module begins normal operation as soon as reset is released and a valid clk is present | ||
| - No external configuration sequence is required timing parameters are static or parametrized at synthesis | ||
|
|
||
| Behavior and Timing | ||
|
|
||
| - The module implements two nested counters: | ||
| - The horizontal counter (x) increments every clock cycle | ||
| - When x reaches the total pixels per line, it resets to zero and increments the vertical counter (y) | ||
| - hsync is asserted low for H_SYNC cycles after the active + front porch interval | ||
| - vsync is asserted low for V_SYNC lines after the active + front porch period | ||
| - The signal active_video is high only when both x and y are within the active display area | ||
| - The structure guarantees a 60 Hz refresh at 640 \* 480 with a 25 MHz pixel clock | ||
|
|
||
| Errors / IRQs | ||
|
|
||
| - This module does not generate interrupts or error signals | ||
| - It operates continuously as long as a valid clock is provided | ||
| - Any display synchronization or VSYNC interrupt is usually handled by the framebuffer controller | ||
|
|
||
| Dependencies | ||
|
|
||
| - Clock: Requires a stable pixel clock (typically 25 MHz). | ||
| - Reset: Synchronous, active-low (reset). | ||
| - Upstream IP: Clock generation block (PLL or divider). | ||
| - Downstream IP: Framebuffer controller or video DAC/encoder that consumes timing signals. | ||
|
|
||
| Summary | ||
|
|
||
| - The VGA timing generator defines the temporal structure of a video frame by driving sync pulses, counters, and valid video windows. It forms the foundation for raster-scan display logic and provides synchronization for all downstream video pipeline modules |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,79 @@ | ||
| module VGA_timing( | ||
| input clk_i, //clock to control porject | ||
| input rst_ni, //active low reset | ||
| output hsync, //horizotal sync | ||
| output vsync, //vertical sync | ||
|
|
||
| /****/ | ||
| //not in ond pager added after fact | ||
| output reg [9:0] pos_in_row, //current position in row | ||
| output reg [9:0] pos_in_col, //current position in col | ||
| /****/ | ||
|
|
||
| output reg [9:0] x, //x coordinate to display pixel data | ||
| output reg [9:0] y, //y coordinate to display pixel data | ||
| output reg active_video //determines whether we have active video or not | ||
| ); | ||
|
|
||
| //parameters for VGA window | ||
| localparam H_RES = 640, | ||
| V_RES = 480, | ||
| H_FP = 16, | ||
| H_SYNC = 98, | ||
| H_BP = 48, | ||
| V_FP = 10, | ||
| V_SYNC = 2, | ||
| V_BP = 2, | ||
| H_ACTIVE_START = H_SYNC + H_BP, //this parameter list the start of the valid horizontal output | ||
| H_ACTIVE_END = H_ACTIVE_START + H_RES, //this parameter contains when to stop output data | ||
| V_ACTIVE_START = V_SYNC + V_BP, | ||
| V_ACTIVE_END = V_SYNC + 480; | ||
|
|
||
|
|
||
| /* STUFF TO CONTROL and MAKE VGA CLOCK */ | ||
| reg [2:0] counter; | ||
| reg pixel_clk; | ||
| initial begin | ||
| counter = 0; | ||
| end | ||
|
|
||
| always@ (posedge clk_i) begin | ||
| if (counter == 2'd2) begin | ||
| pixel_clk <= ~pixel_clk; | ||
| counter <= 0; | ||
| end | ||
| else begin | ||
| counter <= counter + 1; | ||
| end | ||
| end | ||
|
|
||
| /* clock end */ | ||
|
|
||
|
|
||
|
|
||
| /* STUFF TO CONTROL VGA DISPLAY */ | ||
| assign hsync = (x < H_SYNC) ? 1'b0 : 1'b1; //while this is less than the HSYNC value (98) it is going to not write valid data (black) | ||
| assign vsync = (y < V_SYNC) ? 1'b0 : 1'b1; //while this is less than the VSYNC value (2) it is going to not write valid data (black) | ||
|
|
||
|
|
||
| always@ (posedge pixel_clk) begin | ||
| if (rst_ni) begin | ||
| x <= 0; | ||
| y <= 0; | ||
| active_video <= 0; | ||
| end | ||
|
Comment on lines
+59
to
+64
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Functionality Issue: To match other subsystems, please treat rst_ni as an asynchronous (independent of clock) reset (see previous comment for example). |
||
|
|
||
| if (active_video == 1'b1) begin | ||
| if ((pos_in_row >= H_ACTIVE_START) && (pos_in_row < H_ACTIVE_END) && | ||
| (pos_in_col >= V_ACTIVE_START) && (pos_in_col < V_ACTIVE_END)) begin | ||
| x <= pos_in_row - H_ACTIVE_START; | ||
| y <= pos_in_col - V_ACTIVE_START; | ||
| end | ||
| end | ||
| else begin //not within valid data window | ||
| x <= 0; | ||
| y <= 0; | ||
| end | ||
| end | ||
| /* VGA STUFF */ | ||
| endmodule | ||
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Functionality Issue: For the counter, initial blocks usually are not synthesizable and reset signals are preferred. For the internal clock pixel_clk, you need to have an initial value or simulations won't have a definite signal (1 or 0) to show it as. Please use a reset signal instead as follows: