Skip to content
This repository was archived by the owner on Mar 13, 2024. It is now read-only.

Commit 33ad4e9

Browse files
committed
create basic FPGA-based VGA display
1 parent 7a4aa2b commit 33ad4e9

File tree

8 files changed

+6038179
-0
lines changed

8 files changed

+6038179
-0
lines changed
Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
BOARD = tangnano9k
2+
FAMILY = GW1N-9C
3+
DEVICE = GW1NR-LV9QN88PC6/I5
4+
5+
SRC_DIR = .
6+
TB_DIR = testbench
7+
WAVE_DIR = waveform
8+
9+
SRCS = $(wildcard $(SRC_DIR)/*.v)
10+
TESTS = $(wildcard $(TB_DIR)/*_tb.v)
11+
TEST_OBJS = $(TESTS:$(TB_DIR)/%_tb.v=%_tb.o)
12+
WAVES = $(TESTS:$(TB_DIR)/%_tb.v=$(WAVE_DIR)/%.vcd)
13+
14+
15+
all : make_clean toplevel.fs
16+
17+
# Synthesis
18+
toplevel.json : $(SRCS)
19+
@yosys -p "read_verilog $(SRCS); synth_gowin -top toplevel -json toplevel.json"
20+
21+
# Place and Route
22+
toplevel_pnr.json : toplevel.json
23+
@nextpnr-gowin --json toplevel.json --freq 27 --write \
24+
toplevel_pnr.json --device ${DEVICE} --family ${FAMILY} \
25+
--cst ${BOARD}.cst
26+
27+
# Generate Bitstream
28+
toplevel.fs : toplevel_pnr.json
29+
@gowin_pack -d ${FAMILY} -o toplevel.fs toplevel_pnr.json
30+
31+
# Programming Board
32+
program : toplevel.fs
33+
@openFPGALoader -b ${BOARD} toplevel.fs -f
34+
35+
36+
# Testing
37+
%_tb.o : $(TB_DIR)/%_tb.v $(SRCS)
38+
@iverilog -o $@ -s test $(SRCS) $<
39+
40+
$(WAVE_DIR)/%.vcd : %_tb.o
41+
@vvp $< -o $@
42+
43+
test : $(WAVES)
44+
45+
46+
# Cleanup build artifacts
47+
clean :
48+
rm -f ./*.fs
49+
rm -f ./*.o
50+
rm -f ./*.json
51+
rm -f ./*.vcd
52+
rm -f waveform/*
53+
54+
make_clean :
55+
@rm -f ./*.fs
56+
@rm -f ./*.o
57+
@rm -f ./*.json
58+
59+
.PHONY: clean program test make_clean
60+
.INTERMEDIATE: toplevel.json toplevel_pnr.json $(TEST_OBJS)
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
// generates signal timing for VGA 640x480 60Hz standard (25.175MHz clock)
2+
// also puts red/green/blue/luminence in high impedance state
3+
4+
module signalgen (
5+
input clk,
6+
7+
output vsync,
8+
output hsync
9+
);
10+
11+
reg [9:0] vertical_count = 0;
12+
reg [9:0] horizontal_count = 0;
13+
14+
assign hsync = (horizontal_count < 656 || horizontal_count >= 752);
15+
assign vsync = (vertical_count < 490 || vertical_count >= 492);
16+
17+
always @(posedge clk) begin
18+
if (horizontal_count == 799) begin
19+
horizontal_count <= 0;
20+
if (vertical_count == 524) vertical_count <= 0;
21+
else vertical_count <= vertical_count + 1;
22+
end else horizontal_count <= horizontal_count + 1;
23+
end
24+
25+
endmodule
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
IO_LOC "clk" 33;
2+
3+
IO_LOC "vsync" 25;
4+
IO_LOC "hsync" 26;
5+
6+
IO_LOC "red" 27;
7+
IO_LOC "green" 28;
8+
IO_LOC "blue" 29;
9+
IO_LOC "lum" 30;
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
`timescale 1 ns / 1 ns
2+
3+
module test ();
4+
reg clk = 0;
5+
wire hsync;
6+
wire vsync;
7+
8+
signalgen #() signal_generator (
9+
.clk (clk),
10+
.vsync(vsync),
11+
.hsync(hsync)
12+
);
13+
14+
always begin
15+
#1 clk = ~clk;
16+
end
17+
18+
initial begin
19+
$dumpfile("waveform/signalgen.vcd");
20+
$dumpvars(0, test);
21+
end
22+
23+
initial begin
24+
#1000000 $finish;
25+
end
26+
27+
endmodule
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
`timescale 1 ns / 1 ns
2+
3+
module test ();
4+
reg clk = 0;
5+
wire hsync;
6+
wire vsync;
7+
wire red;
8+
wire green;
9+
wire blue;
10+
wire lum;
11+
12+
toplevel #() t (
13+
.clk (clk),
14+
.vsync(vsync),
15+
.hsync(hsync),
16+
.red (red),
17+
.green(green),
18+
.blue (blue),
19+
.lum (lum)
20+
);
21+
22+
always begin
23+
#1 clk = ~clk;
24+
end
25+
26+
initial begin
27+
$dumpfile("waveform/toplevel.vcd");
28+
$dumpvars(0, test);
29+
end
30+
31+
initial begin
32+
#1000000 $finish;
33+
end
34+
35+
endmodule
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
module toplevel (
2+
input clk,
3+
4+
output vsync,
5+
output hsync,
6+
output red,
7+
output green,
8+
output blue,
9+
output lum
10+
);
11+
12+
reg [9:0] hori_counter = 0;
13+
reg [5:0] quart_counter = 0;
14+
reg [3:0] counter = 0;
15+
16+
always @(posedge clk) begin
17+
if (hori_counter == 799) begin
18+
hori_counter <= 0;
19+
quart_counter <= 0;
20+
counter <= 0;
21+
end else begin
22+
hori_counter <= hori_counter + 1;
23+
if (quart_counter == 39) begin
24+
quart_counter <= 0;
25+
counter <= counter + 1;
26+
end else quart_counter <= quart_counter + 1;
27+
end
28+
end
29+
30+
assign red = counter[0] ? counter[0] : 1'bZ;
31+
assign green = counter[1] ? counter[1] : 1'bZ;
32+
assign blue = counter[2] ? counter[2] : 1'bZ;
33+
assign lum = counter[3] ? counter[3] : 1'bZ;
34+
35+
signalgen #() signal_generator (
36+
.clk (clk),
37+
.vsync(vsync),
38+
.hsync(hsync)
39+
);
40+
41+
endmodule

0 commit comments

Comments
 (0)