commit 8dfbc7e78bb5be8b310a34597b7f30aafc662946 Author: Zack Buhman Date: Wed Aug 14 15:45:04 2024 -0500 initial diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..9d1d87f --- /dev/null +++ b/.gitignore @@ -0,0 +1,17 @@ +*.cdf +*.cfg +*.cfg.bit +*.id +*.log +*.net +*.pathes +*.pin +*.place +*.pos +*.prn +*.refcomp +*.refparam +*.refwire +*.sdf +*.txt +*.used diff --git a/bin/.keep b/bin/.keep new file mode 100644 index 0000000..e69de29 diff --git a/build.sh b/build.sh new file mode 100644 index 0000000..15da558 --- /dev/null +++ b/build.sh @@ -0,0 +1,13 @@ +set -eux + +yosys <" Loc = "" | ; +# +# Backward compatible legacy syntax: +# "" Loc = "" | ; +# +# Additional constraints can be appended using the pipe symbol. +# Files are read line by line. Text after the hash symbol is ignored. +# +# Available legacy pin directions: +# +# Pin_in +# defines an input pin +# Pin_out +# defines an output pin +# Pin_triout +# defines a tristate output pin +# Pin_inout +# defines a bidirectional pin +# +# Available pin constraints: +# +# SCHMITT_TRIGGER={true,false} +# enables or disables schmitt trigger (hysteresis) option +# PULLUP={true,false} +# enables or disables I/O pullup resistor of nominal 50kOhm +# PULLDOWN={true,false} +# enables or disables I/O pulldown resistor of nominal 50kOhm +# KEEPER={true,false} +# enables or disables I/O keeper option +# SLEW={slow,fast} +# sets slew rate to slow or fast +# DRIVE={3,6,9,12} +# sets output drive strength to 3mA..12mA +# DELAY_OBF={0..15} +# adds an additional delay of n * nominal 50ps to output signal +# DELAY_IBF={0..15} +# adds an additional delay of n * nominal 50ps to input signal +# FF_IBF={true,false} +# enables or disables placing of FF in input buffer, if possible +# FF_OBF={true,false} +# enables or disables placing of FF in output buffer, if possible +# LVDS_BOOST={true,false} +# enables increased LVDS output current of 6.4mA (default: 3.2mA) +# LVDS_RTERM={true,false} +# enables on-chip LVDS termination resistor of nominal 100Ohm, in input mode only +# +# Global IO constraints can be set with the default_GPIO statement. It can be +# overwritten by individual settings for specific GPIOs, e.g.: +# default_GPIO | DRIVE=3; # sets all output strengths to 3mA, unless overwritten +# + +Net "clk" Loc = "IO_SB_A8" | SCHMITT_TRIGGER=true; +Net "rst" Loc = "IO_SB_B7"; # SW3 +Net "led" Loc = "IO_SB_B6"; # D1 +Net "h_sync" Loc = "IO_WB_A1"; +Net "v_sync" Loc = "IO_WB_B1"; +Net "red[3]" Loc = "IO_WB_A2"; +Net "red[2]" Loc = "IO_WB_B2"; +Net "red[1]" Loc = "IO_WB_A3"; +Net "red[0]" Loc = "IO_WB_B3"; +Net "green[3]" Loc = "IO_WB_A4"; +Net "green[2]" Loc = "IO_WB_B4"; +Net "green[1]" Loc = "IO_WB_A5"; +Net "green[0]" Loc = "IO_WB_B5"; +Net "blue[3]" Loc = "IO_WB_A6"; +Net "blue[2]" Loc = "IO_WB_B6"; +Net "blue[1]" Loc = "IO_WB_A7"; +Net "blue[0]" Loc = "IO_WB_B7"; diff --git a/vga_spg.v b/vga_spg.v new file mode 100644 index 0000000..b02069f --- /dev/null +++ b/vga_spg.v @@ -0,0 +1,79 @@ +module vga_spg + (input wire clk, + input wire rst, + output reg [9:0] h_count, + output reg [9:0] v_count, + output reg h_sync, + output reg v_sync, + output wire display + ); + + localparam h_visible = 640; + localparam h_frontporch = 16; + localparam h_syncpulse = 96; + localparam h_backporch = 48; + localparam h_period = h_visible + + h_frontporch + + h_syncpulse + + h_backporch; + + localparam v_visible = 480; + localparam v_frontporch = 10; + localparam v_syncpulse = 2; + localparam v_backporch = 33; + localparam v_period = v_visible + + v_backporch + + v_syncpulse + + v_frontporch; + + wire h_count_h_period; + assign h_count_h_period = h_count == h_period - 1; + + // h_count + always @(posedge clk) begin + if (rst) begin + h_count <= 10'd0; + end else if (h_count_h_period) begin + h_count <= 10'd0; + end else begin + h_count <= h_count + 1; + end + end + + // h_sync + always @(posedge clk) begin + if (h_count == h_visible + h_frontporch - 1) begin + h_sync <= 1; + end else if (h_count == h_visible + h_frontporch + h_syncpulse - 1) begin + h_sync <= 0; + end + end + + // v_count + always @(posedge clk) begin + if (rst) begin + v_count <= 10'd0; + end else if (h_count_h_period) begin + if (v_count == v_period - 1) begin + v_count <= 10'd0; + end else begin + v_count <= v_count + 1; + end + end + end + + // v_sync + always @(posedge clk) begin + if (h_count_h_period) begin + if (v_count == v_visible + v_frontporch - 1) begin + v_sync <= 1; + end else if (v_count == v_visible + v_frontporch + v_syncpulse - 1) begin + v_sync <= 0; + end + end + end + + // display + assign display = h_count < h_visible && v_count < v_visible; + +endmodule diff --git a/vga_tb.v b/vga_tb.v new file mode 100644 index 0000000..76d1c89 --- /dev/null +++ b/vga_tb.v @@ -0,0 +1,31 @@ +module vga_tb; + + reg rst = 0; + + initial begin + $dumpfile("test.vcd"); + $dumpvars; + + # 10 rst = 1; + # 2 rst = 0; + # 2800000 $finish; + end + + reg clk = 0; + always #1 clk = !clk; + + wire [9:0] h_count; + wire [9:0] v_count; + wire h_sync; + wire v_sync; + wire display; + + vga_spg spg(clk, + rst, + h_count, + v_count, + h_sync, + v_sync, + display); + +endmodule diff --git a/vga_top.v b/vga_top.v new file mode 100644 index 0000000..5b2e55d --- /dev/null +++ b/vga_top.v @@ -0,0 +1,88 @@ +`timescale 1ns / 1ps + +module vga_top + (input wire clk, + input wire rst, + output wire led, + output reg [3:0] red, + output reg [3:0] green, + output reg [3:0] blue, + output wire h_sync, + output wire v_sync + ); + + reg [26:0] counter; + + wire clk270, clk180, clk90, clk0, usr_ref_out; + wire usr_pll_lock_stdy, usr_pll_lock; + + CC_PLL #( + .REF_CLK(10.0), // reference input in MHz + .OUT_CLK(25.175), // pll output frequency in MHz + .PERF_MD("ECONOMY"), // LOWPOWER, ECONOMY, SPEED + .LOW_JITTER(1), // 0: disable, 1: enable low jitter mode + .CI_FILTER_CONST(2), // optional CI filter constant + .CP_FILTER_CONST(4) // optional CP filter constant + ) pll_inst ( + .CLK_REF(clk), .CLK_FEEDBACK(1'b0), .USR_CLK_REF(1'b0), + .USR_LOCKED_STDY_RST(1'b0), .USR_PLL_LOCKED_STDY(usr_pll_lock_stdy), .USR_PLL_LOCKED(usr_pll_lock), + .CLK270(clk270), .CLK180(clk180), .CLK90(clk90), .CLK0(clk0), .CLK_REF_OUT(usr_ref_out) + ); + + assign led = counter[26]; + + always @(posedge clk0) + begin + if (!rst) begin + counter <= 0; + end else begin + counter <= counter + 1'b1; + end + end + + wire [9:0] h_count; + wire [9:0] v_count; + wire display; + + wire h_sync1; + wire v_sync1; + + wire rst0 = 0; + + + vga_spg spg(.clk(clk0), + .rst(rst0), + .h_count(h_count), + .v_count(v_count), + .h_sync(h_sync1), + .v_sync(v_sync1), + .display(display)); + + reg h_sync2; + reg v_sync2; + + assign h_sync = h_sync2; + assign v_sync = v_sync2; + + always @(posedge clk0) begin + h_sync2 <= h_sync1; + v_sync2 <= v_sync1; + + if (display) begin + if (v_count[3]) begin + red <= 4'd15; + green <= 4'd15; + blue <= 4'd0; + end else begin + red <= 4'd15; + green <= 4'd0; + blue <= 4'd0; + end + end else begin + red <= 4'd0; + green <= 4'd0; + blue <= 4'd0; + end + end + +endmodule