Skip to content

Instantly share code, notes, and snippets.

@ejrh
Created June 30, 2013 11:17
Show Gist options
  • Save ejrh/5894801 to your computer and use it in GitHub Desktop.
Save ejrh/5894801 to your computer and use it in GitHub Desktop.
module fpgafrac(
input wire mclk,
/*input wire [7:0] sw,
input wire [3:0] btn,
output wire [7:0] led,
output wire [3:0] an,
output wire dp,
output wire [6:0] seg,*/
output reg vs,
output reg hs,
output reg [2:0] red,
output reg [2:0] green,
output reg [2:0] blue
);
/*
Active Video Front Porch Sync Pulse Back Porch Active Video Front Porch Sync Pulse Back Porch
800x600, 72Hz 50.000 800 56 120 64 600 37 6 23
*/
parameter CLK = 50000000;
parameter PAL = 640;
parameter HFP = 16;
parameter HPW = 96;
parameter HBP = 48;
parameter LAF = 480;
parameter VFP = 11;
parameter VPW = 2;
parameter VBP = 31;
/*parameter PAL = 800;
parameter HFP = 56;
parameter HPW = 120;
parameter HBP = 64;
parameter LAF = 600;
parameter VFP = 37;
parameter VPW = 6;
parameter VBP = 23;*/
parameter PLD = PAL+HFP+HPW+HBP;
parameter LFD = LAF+VFP+VPW+VBP;
reg vga_clk;
reg [15:0] vga_x;
reg [15:0] vga_y;
wire red_colour;
defparam red_ball.VEL_X = 5;
defparam red_ball.VEL_Y = 3;
ball red_ball(mclk, PAL, LAF, 32, vga_x, vga_y, red_colour);
wire green_colour;
defparam green_ball.VEL_X = 4;
defparam green_ball.VEL_Y = 4;
ball green_ball(mclk, PAL, LAF, 32, vga_x, vga_y, green_colour);
wire blue_colour;
defparam blue_ball.VEL_X = 3;
defparam blue_ball.VEL_Y = 6;
ball blue_ball(mclk, PAL, LAF, 32, vga_x, vga_y, blue_colour);
wire on_screen;
assign on_screen = (vga_x < PAL) && (vga_y < LAF);
wire [1:0] tile_colour;
assign tile_colour = vga_x[7:6] ^ vga_y[7:6];
always @(posedge mclk) begin
vga_clk <= !vga_clk;
if (vga_clk) begin
/* Update Pixel and Line positions. */
if (vga_x == PLD-1) begin
vga_x <= 0;
if (vga_y == LFD-1) begin
vga_y <= 0;
end else begin
vga_y <= vga_y + 1;
end
end else begin
vga_x <= vga_x + 1;
end
/* Horizontal sync. */
if (vga_x == PAL-1+HFP) begin
hs <= 0;
end else if (vga_x == PAL-1+HFP+HPW) begin
hs <= 1;
end
/* Vertical sync. */
if (vga_y == LAF-1+VFP) begin
vs <= 0;
end else if (vga_y == LAF-1+VFP+VPW) begin
vs <= 1;
end
if (on_screen) begin
red <= { red_colour, tile_colour };
green <= { green_colour, tile_colour };
blue <= { blue_colour, tile_colour };
end else begin
red <= 0;
green <= 0;
blue <= 0;
end
end
end
endmodule
module ball(
input wire mclk,
input wire [15:0] max_x,
input wire [15:0] max_y,
input wire [15:0] radius,
input wire [15:0] scan_x,
input wire [15:0] scan_y,
output wire in_circle
);
parameter POS_X = 0;
parameter POS_Y = 0;
parameter VEL_X = 1;
parameter VEL_Y = 2;
reg [31:0] pos_x = POS_X;
reg [31:0] pos_y = POS_Y;
reg signed [31:0] vel_x = VEL_X;
reg signed [31:0] vel_y = VEL_Y;
wire [15:0] circle_x;
assign circle_x = pos_x[31:21];
wire [15:0] circle_y;
assign circle_y = pos_y[31:21];
wire [15:0] xdiff, ydiff;
absdiff absdiff1(scan_x, circle_x, xdiff);
absdiff absdiff2(scan_y, circle_y, ydiff);
assign in_circle = xdiff*xdiff + ydiff*ydiff < radius*radius;
always @(posedge mclk) begin
pos_x <= pos_x + vel_x;
pos_y <= pos_y + vel_y;
if (circle_x >= max_x - radius && vel_x > 0) begin
vel_x <= -vel_x;
end else if (circle_x < radius && vel_x < 0) begin
vel_x <= -vel_x;
end
if (circle_y >= max_y - radius && vel_y > 0) begin
vel_y <= -vel_y;
end else if (circle_y < radius && vel_y < 0) begin
vel_y <= -vel_y;
end
end
endmodule
module absdiff(
input wire [15:0] in1,
input wire [15:0] in2,
output wire [15:0] out
);
assign out = (in1 > in2) ? in1 - in2 : in2 - in1;
endmodule
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment