Skip to content

Instantly share code, notes, and snippets.

@quangIO
Last active December 16, 2018 13:49
Show Gist options
  • Save quangIO/7397bb390a456f0b9f2683034b436d4d to your computer and use it in GitHub Desktop.
Save quangIO/7397bb390a456f0b9f2683034b436d4d to your computer and use it in GitHub Desktop.
`timescale 1ns / 1ps
`define BRUSH_X(idx, size) (h_cnt <= (H_START + pos[idx][0] + size) * SCALE_X) && (h_cnt >= (H_START + pos[idx][0] - size) * SCALE_X)
`define BRUSH_Y(idx, size) (v_cnt <= (V_START + pos[idx][1] + size) * SCALE_Y) && (v_cnt >= (V_START + pos[idx][1] - size) * SCALE_Y)
`define BRUSH_C(idx, size, color) (((h_cnt - H_START - pos[idx][0]) * (h_cnt - H_START - pos[idx][0]) + (v_cnt - V_START - pos[idx][1]) * (v_cnt - V_START - pos[idx][1]) < size * size * SCALE_X * SCALE_Y) ? color : 3'd0)
`define BRUSH(idx, size_x, size_y) (`BRUSH_X(idx, size_x) && `BRUSH_Y(idx, size_y))
`define BRUSH_SCORE(idx) ((h_cnt <= (H_START + (score[idx] << 2)) * SCALE_X) * SCALE_X && v_cnt <= (V_START + (idx << 2) + 4) * SCALE_Y && v_cnt >= (V_START + (idx << 2)) * SCALE_Y)
module vga640x480(
input clk,
output vs,
output hs,
output[2: 0] r, g,
output[1: 0] b,
input[4: 0] keys
);
localparam NUM_OBJECT = 3;
localparam VIEWPORT_W = 640 * SCALE_X;
localparam VIEWPORT_H = 480 * SCALE_Y;
localparam MAX_V = 4;
parameter CLK_FACTOR_SIZE = 21;
parameter EOL = 800;
parameter EOS = 525;
parameter H_START = 144;
parameter H_END = 784;
parameter V_START = 35;
parameter V_END = 515;
parameter SCALE_X = 1;
parameter SCALE_Y = 1;
localparam SHAPE_SIZE = 20;
parameter[7: 0] COLOR[7: 0] = {8'hf9, 8'he7, 8'hbb, 8'ha7, 8'hfa, 8'hff, 8'hc0, 8'hcf};
reg[2:0] i = 0;
reg[2:0] j = 0;
reg[CLK_FACTOR_SIZE - 1: 0] p_cnt = 0;
reg[9: 0] h_cnt = 0;
reg[9: 0] v_cnt = 0;
assign hs = (h_cnt <= 10'd96);
assign vs = (v_cnt <= 10'd02);
reg signed[10: 0] pos [NUM_OBJECT - 1: 0][1: 0];
reg signed[10: 0] peak [NUM_OBJECT - 1: 0];
reg[9: 0] score [NUM_OBJECT - 1: 0];
reg[NUM_OBJECT - 1: 0] direction;
reg[NUM_OBJECT - 1: 0] last_keys;
reg[7: 0] current_color = 0;
reg[7: 0] background = 0;
wire a_display = (h_cnt >= H_START && h_cnt <= H_END) & (v_cnt >= V_START && v_cnt <= V_END);
assign {r, g, b} = a_display ? current_color : 8'h0;
always @(posedge clk) begin
p_cnt = p_cnt + 2'd1;
current_color = background;
// Pixel count stuff
if (!p_cnt[1:0]) begin
h_cnt = h_cnt + 10'd1;
if (h_cnt == EOL) begin
h_cnt = 0;
v_cnt = v_cnt + 10'd1;
end
if (v_cnt == EOS)
v_cnt = 10'b0;
end
// begin update
for (i = 0; i < NUM_OBJECT; i = i + 1) begin
for (j = 0; j < NUM_OBJECT; j = j + 1) begin
if (pos[j][1] - pos[i][1] == (SHAPE_SIZE << 1) && (pos[i][0] - pos[j][0]) * (pos[i][0] - pos[j][0]) <= (SHAPE_SIZE * SHAPE_SIZE << 2)) begin
pos[j][0] = 0;
pos[j][1] = 0;
peak[j] = 0;
direction[j] = 0;
score[i] = score[i] + 1'b1;
background = ((67 * p_cnt) + p_cnt << 1) + background;
end
end
if (`BRUSH(i, SHAPE_SIZE, SHAPE_SIZE)) current_color = COLOR[i];
else if (`BRUSH_SCORE(i)) current_color = COLOR[i];
// else current_color = background;
if (pos[i][1] <= peak[i]) peak[i] = VIEWPORT_H;
if (!p_cnt[19: 0] || (!p_cnt[18: 0] && pos[i][1] > peak[i])) begin
pos[i][0] = pos[i][0] + ((direction[i]) << 1) - 1'd1;
end
if (!p_cnt[17: 0]) begin
pos[i][1] = pos[i][1] + 1'd1 - ((pos[i][1] > peak[i]) << 1);
end
if (!last_keys[i] && keys[i]) begin
peak[i] = pos[i][1] - 8'd150;
end
last_keys[i] = keys[i];
// 8 lines below can be written as direction[i] = (pos[i][0] < 0 && pos[i][0] > VIEWPORT_W) ^ direction[i];
if (pos[i][0] < 0) begin
direction[i] = 1;
pos[i][0] = 0; // redundant
end
if (pos[i][0] > VIEWPORT_W) begin
direction[i] = 0;
pos[i][0] = VIEWPORT_W; // redundant
end
if (pos[i][1] < 0) pos[i][1] = 0;
if (peak[i] < 0) peak[i] = 0;
if (pos[i][1] > VIEWPORT_H) pos[i][1] = VIEWPORT_H;
end
end
endmodule
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment