Last active
December 16, 2018 13:49
-
-
Save quangIO/7397bb390a456f0b9f2683034b436d4d 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
`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