Last active
August 20, 2020 15:59
-
-
Save hinzundcode/3162d6bfbcf0d5842d82d9e3e037055f to your computer and use it in GitHub Desktop.
This file contains 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
// user_1 is R, G and B (VGA pins 1, 2 and 3) | |
// user_2 is Ground | |
// user_3 is HSYNC (VGA pin 13) | |
// user_4 is VSYNC (VGA pin 15) | |
// from https://8bitworkshop.com/v3.6.0/?file=hvsync_generator.v&platform=verilog-vga | |
module hvsync_generator(clk, reset, hsync, vsync, display_on, hpos, vpos); | |
input clk; | |
input reset; | |
output reg hsync, vsync; | |
output display_on; | |
output reg [9:0] hpos; | |
output reg [9:0] vpos; | |
// declarations for TV-simulator sync parameters | |
// horizontal constants | |
parameter H_DISPLAY = 640; // horizontal display width | |
parameter H_BACK = 48; // horizontal left border (back porch) | |
parameter H_FRONT = 16; // horizontal right border (front porch) | |
parameter H_SYNC = 96; // horizontal sync width | |
// vertical constants | |
parameter V_DISPLAY = 480; // vertical display height | |
parameter V_TOP = 33; // vertical top border | |
parameter V_BOTTOM = 10; // vertical bottom border | |
parameter V_SYNC = 2; // vertical sync # lines | |
// derived constants | |
parameter H_SYNC_START = H_DISPLAY + H_FRONT; | |
parameter H_SYNC_END = H_DISPLAY + H_FRONT + H_SYNC - 1; | |
parameter H_MAX = H_DISPLAY + H_BACK + H_FRONT + H_SYNC - 1; | |
parameter V_SYNC_START = V_DISPLAY + V_BOTTOM; | |
parameter V_SYNC_END = V_DISPLAY + V_BOTTOM + V_SYNC - 1; | |
parameter V_MAX = V_DISPLAY + V_TOP + V_BOTTOM + V_SYNC - 1; | |
wire hmaxxed = (hpos == H_MAX) || reset; // set when hpos is maximum | |
wire vmaxxed = (vpos == V_MAX) || reset; // set when vpos is maximum | |
// horizontal position counter | |
always @(posedge clk) | |
begin | |
hsync <= (hpos>=H_SYNC_START && hpos<=H_SYNC_END); | |
if(hmaxxed) | |
hpos <= 0; | |
else | |
hpos <= hpos + 1; | |
end | |
// vertical position counter | |
always @(posedge clk) | |
begin | |
vsync <= (vpos>=V_SYNC_START && vpos<=V_SYNC_END); | |
if(hmaxxed) | |
if (vmaxxed) | |
vpos <= 0; | |
else | |
vpos <= vpos + 1; | |
end | |
// display_on is set when beam is in "safe" visible frame | |
assign display_on = (hpos<H_DISPLAY) && (vpos<V_DISPLAY); | |
endmodule | |
module gpu(clk, hsync, vsync, color); | |
input clk; | |
output hsync, vsync; | |
output color; | |
wire pclk; | |
wire display_on; | |
wire [9:0] hpos; | |
wire [9:0] vpos; | |
// generates pixelclock, 640x480 @60Hz | |
// from 48MHz to 25.125MHz (icepll -i 48 -o 25.175) | |
SB_PLL40_CORE #(.FEEDBACK_PATH("SIMPLE"), | |
.PLLOUT_SELECT("GENCLK"), | |
.DIVR(4'b0011), // R = 3 | |
.DIVF(7'b1000010), // F = 66 | |
.DIVQ(3'b101), // Q = 5 | |
.FILTER_RANGE(3'b001), | |
) uut ( | |
.REFERENCECLK(clk), | |
.PLLOUTCORE(pclk), | |
//.LOCK(D5), | |
.RESETB(1'b1), | |
.BYPASS(1'b0) | |
); | |
hvsync_generator hvsync_gen ( | |
.clk(pclk), | |
.reset(0), | |
.hsync(hsync), | |
.vsync(vsync), | |
.display_on(display_on), | |
.hpos(hpos), | |
.vpos(vpos), | |
); | |
// static square | |
wire inbox = hpos >= 100 && hpos < 200 && vpos >= 100 && vpos < 200; | |
assign color = display_on && inbox; | |
// moving square | |
/*reg [31:0] counter = 0; | |
reg signed [15:0] x0 = 0; | |
always @(posedge clk) begin | |
counter <= counter + 1; | |
// every second | |
if (counter >= 48000000) begin | |
counter <= 0; | |
x0 <= x0 + 10; | |
end | |
end | |
wire inbox = hpos >= x0 && hpos < 200 && vpos >= 100 && vpos < 200; | |
assign color = display_on && inbox;*/ | |
endmodule | |
module top ( | |
// 48MHz Clock input | |
// -------- | |
input clki, | |
// LED outputs | |
// -------- | |
output user_1, | |
output user_2, | |
output user_3, | |
output user_4, | |
// USB Pins (which should be statically driven if not being used). | |
// -------- | |
output usb_dp, | |
output usb_dn, | |
output usb_dp_pu | |
); | |
// Assign USB pins to "0" so as to disconnect Fomu from | |
// the host system. Otherwise it would try to talk to | |
// us over USB, which wouldn't work since we have no stack. | |
assign usb_dp = 1'b0; | |
assign usb_dn = 1'b0; | |
assign usb_dp_pu = 1'b0; | |
// Connect to system clock (with buffering) | |
wire clk; | |
SB_GB clk_gb ( | |
.USER_SIGNAL_TO_GLOBAL_BUFFER(clki), | |
.GLOBAL_BUFFER_OUTPUT(clk) | |
); | |
gpu g ( | |
.clk(clk), | |
.hsync(user_3), | |
.vsync(user_4), | |
.color(user_1), | |
); | |
assign user_2 = 'b0; | |
endmodule |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment