Skip to content
15 changes: 6 additions & 9 deletions LFSR.v
Original file line number Diff line number Diff line change
@@ -1,20 +1,17 @@
module LFSR (clk_i, en_i, out_o);
module LFSR #(parameter seed = 0) (clk_i, en_i, nextbit);
input clk_i, en_i;
output [7:0] out_o;
output reg nextbit;

reg [7:0] next_LFSR = 0;
reg nextbit;
reg [2:0] next_LFSR = seed;

always@(posedge clk_i) begin
if (en_i == 1'b1) begin
next_LFSR <= {next_LFSR[6:0], nextbit};
next_LFSR <= {next_LFSR[1:0], nextbit};
end
end // always

always@(*) begin
nextbit = next_LFSR[7] ^~ next_LFSR[5] ^~ next_LFSR[4] ^~ next_LFSR[3];
nextbit = next_LFSR[2] ^~ next_LFSR[1];
end // always

assign out_o = next_LFSR[7:0];


endmodule
252 changes: 252 additions & 0 deletions Nexys4DDR_Master_final.xdc

Large diffs are not rendered by default.

10 changes: 7 additions & 3 deletions Testbenches/LFSR_tb.v
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,14 @@ module LFSR_tb();
reg clk_i;
wire [7:0] out_o;

LFSR lfsr_inst(.clk_i(clk_i), .en_i(1'b1), .out_o(out_o));

LFSR lfsr_inst(.clk_i(clk_i), .en_i(1'b1), .nextbit(out_o));

initial begin
clk_i = 1'b0;
end

always@(*) begin
#10 clk_i <= ~clk_i;
end

endmodule
endmodule
1 change: 0 additions & 1 deletion Testbenches/line_generate_tb.v
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ odule line_generate_tb();

initial begin
clk_i = 0;
#10 reset_i = 0;
reset_i = 1;
end

Expand Down
26 changes: 26 additions & 0 deletions clock_divider.v
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
module clock_divider
#(parameter CLK_I_SPEED = 100000000, // 100mhz default
parameter CLK_O_SPEED = 100000000) (
// hz (must be less than input clock, 100mhz default)
input clk_i,
input rst_i,
output reg clk_o
);

localparam CLK_O_PERIOD = (CLK_I_SPEED / 2) / CLK_O_SPEED;
reg [31:0] clk_count_int;

always @ (posedge clk_i or negedge rst_i) begin
if (rst_i == 1'b0) begin
clk_count_int <= 32'h0;
clk_o <= 1'b0;
end else begin
clk_count_int <= clk_count_int + 1'b1;

if (clk_count_int == CLK_O_PERIOD) begin // 100mhz base clock
clk_o <= ~clk_o;
clk_count_int <= 32'h0;
end
end // else
end // always
endmodule
131 changes: 131 additions & 0 deletions draw_game.v
Original file line number Diff line number Diff line change
@@ -0,0 +1,131 @@
module draw_game(
input rst_i,
input clk_i,
input rst_cpu,
output wire VGA_HS_O, // horizontal sync output
output wire VGA_VS_O, // vertical sync output
output wire [3:0] VGA_R, // 4-bit VGA red output
output wire [3:0] VGA_G, // 4-bit VGA green output
output wire [3:0] VGA_B // 4-bit VGA blue output
);

wire clk_line;
wire clk_lfsr;
wire rst_rnd = ~rst_i; // flip reset (active low)
wire rst_display = ~rst_cpu; // flip vga reset for display (active low on artix board)
wire [639:0] line0_int, line1_int, line2_int, line3_int;
wire line0_region, line1_region, line2_region, line3_region;
reg all_lines_region;

wire [9:0] display_x; // current pixel x position: 10-bit value: 0-1023
wire [8:0] display_y; // current pixel y position: 9-bit value: 0-511
reg [15:0] cnt;
reg pix_stb;

localparam LINE_WIDTH = 18;
localparam LINE_INC = 142;
localparam LINE_0_LOC = LINE_WIDTH/2 - 1; // line midpoint location in pixels
localparam LINE_1_LOC = LINE_0_LOC + LINE_INC; // line midpoint location in pixels
localparam LINE_2_LOC = LINE_1_LOC + LINE_INC; // line midpoint location in pixels
localparam LINE_3_LOC = LINE_2_LOC + LINE_INC; // line midpoint location in pixels


// set line speed of 240 pix/s
clock_divider #(.CLK_O_SPEED(240)) clk_240hz(
.rst_i(rst_rnd),
.clk_i(clk_i),
.clk_o(clk_line)
);

clock_divider #(.CLK_O_SPEED(3)) clk_rand(
.rst_i(rst_rnd),
.clk_i(clk_i),
.clk_o(clk_lfsr)
);

// generate a 25 MHz pixel strobe
always @(posedge clk_i) begin
{pix_stb, cnt} <= cnt + 16'h4000; // divide by 4: (2^16)/4 = 0x4000
end

vga640x480 display(
.i_clk(clk_i),
.i_pix_stb(pix_stb),
.i_rst(rst_display),
.o_hs(VGA_HS_O),
.o_vs(VGA_VS_O),
.o_x(display_x),
.o_y(display_y)
);

line_generate #(.seed(0)) gen_line_0(
.clk_i(clk_line),
.clk_lfsr(clk_lfsr),
.en_i(1'b1),
.reset_i(rst_rnd),
.line_o(line0_int)
);

line_generate #(.seed(1)) gen_line_1(
.clk_i(clk_line),
.clk_lfsr(clk_lfsr),
.en_i(1'b1),
.reset_i(rst_rnd),
.line_o(line1_int)
);

line_generate #(.seed(2)) gen_line_2(
.clk_i(clk_line),
.clk_lfsr(clk_lfsr),
.en_i(1'b1),
.reset_i(rst_rnd),
.line_o(line2_int)
);

line_generate #(.seed(3)) gen_line_3(
.clk_i(clk_line),
.clk_lfsr(clk_lfsr),
.en_i(1'b1),
.reset_i(rst_rnd),
.line_o(line3_int)
);

draw_line #(.LineMidpointLoc(LINE_0_LOC),
.LineWidth(LINE_WIDTH)) draw_line_0(
.line_i(line0_int),
.x_i(display_x),
.y_i(display_y),
.region_o(line0_region)
);

draw_line #(.LineMidpointLoc(LINE_1_LOC),
.LineWidth(LINE_WIDTH)) draw_line_1(
.line_i(line1_int),
.x_i(display_x),
.y_i(display_y),
.region_o(line1_region)
);

draw_line #(.LineMidpointLoc(LINE_2_LOC),
.LineWidth(LINE_WIDTH)) draw_line_2(
.line_i(line2_int),
.x_i(display_x),
.y_i(display_y),
.region_o(line2_region)
);

draw_line #(.LineMidpointLoc(LINE_3_LOC),
.LineWidth(LINE_WIDTH)) draw_line_3(
.line_i(line3_int),
.x_i(display_x),
.y_i(display_y),
.region_o(line3_region)
);

always @(*) begin
all_lines_region = line0_region | line1_region | line2_region | line3_region; // add all lines here
end // always

// assign VGA outputs
assign VGA_R[3] = all_lines_region;
endmodule
12 changes: 12 additions & 0 deletions draw_line.v
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
module draw_line
# (parameter LineMidpointLoc = 0,
parameter LineWidth = 1) (
input [639:0] line_i,
input [9:0] x_i,
input [8:0] y_i,
output region_o
);
assign region_o = ((line_i[x_i] == 1) &
(y_i >= LineMidpointLoc - LineWidth/2) &
(y_i < LineMidpointLoc + LineWidth/2)) ? 1 : 0;
endmodule
48 changes: 19 additions & 29 deletions line_generate.v
Original file line number Diff line number Diff line change
@@ -1,33 +1,23 @@
module line_generate(reset_i, clk_i, en_i, line_o);
input reset_i, clk_i, en_i;
output [639:0] line_o;
wire [7:0] rand_num;
reg [639:0] cs = {640{1'b1}}, ns = {640{1'b1}};
reg [6:0] count = 0;
reg new_bit = 1;
module line_generate #(parameter seed = 0) (reset_i, clk_i, clk_lfsr, en_i, line_o, rand_num);
input clk_i, reset_i, en_i, clk_lfsr;
output reg [639:0] line_o;
output wire rand_num;

LFSR #(.seed(seed)) rn(.clk_i(clk_lfsr), .en_i(en_i), .nextbit(rand_num));

initial begin
line_o = {640{1'b1}};
end

LFSR rn(.clk_i(clk_i), .en_i(en_i), .out_o(rand_num));

always@(posedge clk_i or negedge reset_i) begin
if (reset_i==0) begin
cs = 0;
cs = cs - 1;
ns = 0;
ns = ns - 1;
count = 0;
new_bit = 1;
if (reset_i == 0) begin
line_o <= {640{1'b1}};
end else begin
if (line_o == {640{1'b0}})
line_o <= {640{1'b1}};
else begin
line_o <= {rand_num, line_o[639:1]};
end
end
cs <= ns;
count = count + 1;
end // always

always@(posedge clk_i) begin
if (count == 80) begin
new_bit = rand_num[0];
count = 0;
end
ns = {cs[638:0], new_bit};
end // always

assign line_o = cs;
end
endmodule
2 changes: 1 addition & 1 deletion move_player.v
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ module move_player(reset, clk, grav_dir, is_dead, lines, height);

always @ (posedge clk or negedge reset) begin
if (reset==0)
height = 180; //starts player at height of middle line
height <= 180; //starts player at height of middle line
else if (is_dead==0)
height <=next;
end
Expand Down
54 changes: 54 additions & 0 deletions vga640x480.v
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
module vga640x480(
input wire i_clk, // base clock
input wire i_pix_stb, // pixel clock strobe
input wire i_rst, // reset: restarts frame
output wire o_hs, // horizontal sync
output wire o_vs, // vertical sync
output wire [9:0] o_x, // current pixel x position
output wire [8:0] o_y // current pixel y position
);


localparam HS_STA = 16; // horizontal sync start
localparam HS_END = 16 + 96; // horizontal sync end
localparam HA_STA = 16 + 96 + 48; // horizontal active pixel start
localparam VS_STA = 480 + 10; // vertical sync start
localparam VS_END = 480 + 10 + 2; // vertical sync end
localparam VA_END = 480; // vertical active pixel end
localparam LINE = 800; // complete line (pixels)
localparam SCREEN = 525; // complete screen (lines)

reg [9:0] h_count; // line position
reg [9:0] v_count; // screen position

// generate sync signals (active low for 640x480)
assign o_hs = ~((h_count >= HS_STA) & (h_count < HS_END));
assign o_vs = ~((v_count >= VS_STA) & (v_count < VS_END));

// keep x and y bound within the active pixels
assign o_x = (h_count < HA_STA) ? 0 : (h_count - HA_STA);
assign o_y = (v_count >= VA_END) ? (VA_END - 1) : (v_count);


always @ (posedge i_clk)
begin
if (i_rst) // reset to start of frame
begin
h_count <= 0;
v_count <= 0;
end
if (i_pix_stb) // once per pixel
begin
if (h_count == LINE) // end of line
begin
h_count <= 0;
v_count <= v_count + 1;
end
else
h_count <= h_count + 1;

if (v_count == SCREEN) // end of screen
v_count <= 0;
end
end
endmodule