Skip to content

Instantly share code, notes, and snippets.

@peterzhu2118
Created November 11, 2018 16:05
Show Gist options
  • Save peterzhu2118/4967adf8f197a2b9104fdce607f08f35 to your computer and use it in GitHub Desktop.
Save peterzhu2118/4967adf8f197a2b9104fdce607f08f35 to your computer and use it in GitHub Desktop.
CSC258 Lab 7 Part 3
module animation(
SW,
KEY,
CLOCK_50,
VGA_CLK, // VGA Clock
VGA_HS, // VGA H_SYNC
VGA_VS, // VGA V_SYNC
VGA_BLANK_N, // VGA BLANK
VGA_SYNC_N, // VGA SYNC
VGA_R, // VGA Red[9:0]
VGA_G, // VGA Green[9:0]
VGA_B // VGA Blue[9:0]
);
input CLOCK_50; // 50 MHz
input [9:0] SW;
input [3:0] KEY;
// Declare your inputs and outputs here
// Do not change the following outputs
output VGA_CLK; // VGA Clock
output VGA_HS; // VGA H_SYNC
output VGA_VS; // VGA V_SYNC
output VGA_BLANK_N; // VGA BLANK
output VGA_SYNC_N; // VGA SYNC
output [9:0] VGA_R; // VGA Red[9:0]
output [9:0] VGA_G; // VGA Green[9:0]
output [9:0] VGA_B; // VGA Blue[9:0]
wire resetn;
assign resetn = KEY[0];
wire [2:0] colour;
wire [7:0] x;
wire [6:0] y;
wire writeEn;
vga_adapter VGA(
.resetn(resetn),
.clock(CLOCK_50),
.colour(colour),
.x(x),
.y(y),
.plot(writeEn),
/* Signals for the DAC to drive the monitor. */
.VGA_R(VGA_R),
.VGA_G(VGA_G),
.VGA_B(VGA_B),
.VGA_HS(VGA_HS),
.VGA_VS(VGA_VS),
.VGA_BLANK(VGA_BLANK_N),
.VGA_SYNC(VGA_SYNC_N),
.VGA_CLK(VGA_CLK));
defparam VGA.RESOLUTION = "160x120";
defparam VGA.MONOCHROME = "FALSE";
defparam VGA.BITS_PER_COLOUR_CHANNEL = 1;
defparam VGA.BACKGROUND_IMAGE = "black.mif";
wire ld_new, draw_blk;
wire clk_4;
four_herz_clock k0(
.enable(enable),
.resetn(resetn),
.clk_50(CLOCK_50),
.clk_4(clk_4)
);
datapath d0(
.SW(SW),
.clk_50(CLOCK_50),
.clk_4(clk_4),
.resetn(resetn),
.ld_new(ld_new),
.draw_blk(draw_blk),
.plot(writeEn),
.x(x),
.y(y),
.color(colour)
);
control c0(
.enable(~KEY[3]),
.resetn(resetn),
.clk_50(CLOCK_50),
.ld_new(ld_new),
.draw_blk(draw_blk),
.plot(writeEn)
);
endmodule
module datapath(SW, enable, clk_50, clk_4, resetn, ld_new, draw_blk, plot, x, y, color);
input [9:0] SW;
input enable;
input clk_50;
input clk_4;
input resetn;
input ld_new, draw_blk, plot;
output [7:0] x;
output [6:0] y;
output [2:0] color;
reg [7:0] x;
reg [6:0] y;
reg [2:0] color;
reg [3:0] counter;
wire [7:0] new_x;
wire [6:0] new_y;
reg [7:0] orig_x;
reg [6:0] orig_y;
pos_counter p0(
.enable(enable),
.resetn(resetn),
.clk(clk_4),
.x_pos(new_x),
.y_pos(new_y)
);
always @(posedge clk_50) begin
if (!resetn) begin
x <= 8'd0;
y <= 7'd60;
orig_x <= 8'd0;
orig_y <= 7'd60;
counter <= 4'd0;
end
else begin
if (ld_new) begin
orig_x <= new_x;
orig_y <= new_y;
end
if (plot) begin
x <= orig_x + (counter / 4'd4);
y <= orig_y + (counter % 4'd4);
if (draw_blk)
color <= 3'b0;
else
color <= SW[9:7];
counter <= counter + 1;
end
end
end
endmodule
module control(enable, resetn, clk_50, clk_4, ld_new, draw_blk, plot);
input clk_50;
input clk_4;
input resetn;
input enable;
output ld_new;
output draw_blk;
output plot;
reg ld_new;
reg draw_blk;
reg plot;
localparam S_WAIT = 6'd0,
S_PLOT_BLK_0 = 6'd3,
S_PLOT_BLK_1 = 6'd4,
S_PLOT_BLK_2 = 6'd5,
S_PLOT_BLK_3 = 6'd6,
S_PLOT_BLK_4 = 6'd7,
S_PLOT_BLK_5 = 6'd8,
S_PLOT_BLK_6 = 6'd9,
S_PLOT_BLK_7 = 6'd10,
S_PLOT_BLK_8 = 6'd11,
S_PLOT_BLK_9 = 6'd12,
S_PLOT_BLK_10 = 6'd13,
S_PLOT_BLK_11 = 6'd14,
S_PLOT_BLK_12 = 6'd15,
S_PLOT_BLK_13 = 6'd16,
S_PLOT_BLK_14 = 6'd17,
S_PLOT_BLK_15 = 6'd18,
//S_PLOT_BLK_16 = 6'd19,
S_LOAD_NEW = 6'd1,
S_PLOT_0 = 6'd20,
S_PLOT_1 = 6'd21,
S_PLOT_2 = 6'd22,
S_PLOT_3 = 6'd23,
S_PLOT_4 = 6'd24,
S_PLOT_5 = 6'd25,
S_PLOT_6 = 6'd26,
S_PLOT_7 = 6'd27,
S_PLOT_8 = 6'd28,
S_PLOT_9 = 6'd29,
S_PLOT_10 = 6'd30,
S_PLOT_11 = 6'd31,
S_PLOT_12 = 6'd32,
S_PLOT_13 = 6'd33,
S_PLOT_14 = 6'd34,
S_PLOT_15 = 6'd35,
S_PLOT_16 = 6'd36;
reg [5:0] next_state;
reg [5:0] current_state;
always @(*)
begin: state_table
case (current_state)
S_WAIT: next_state = clk_4 ? S_PLOT_BLK_0 : S_WAIT;
S_PLOT_BLK_0: next_state = S_PLOT_BLK_1;
S_PLOT_BLK_1: next_state = S_PLOT_BLK_2;
S_PLOT_BLK_2: next_state = S_PLOT_BLK_3;
S_PLOT_BLK_3: next_state = S_PLOT_BLK_4;
S_PLOT_BLK_4: next_state = S_PLOT_BLK_5;
S_PLOT_BLK_5: next_state = S_PLOT_BLK_6;
S_PLOT_BLK_6: next_state = S_PLOT_BLK_7;
S_PLOT_BLK_7: next_state = S_PLOT_BLK_8;
S_PLOT_BLK_8: next_state = S_PLOT_BLK_9;
S_PLOT_BLK_9: next_state = S_PLOT_BLK_10;
S_PLOT_BLK_10: next_state = S_PLOT_BLK_11;
S_PLOT_BLK_11: next_state = S_PLOT_BLK_12;
S_PLOT_BLK_12: next_state = S_PLOT_BLK_13;
S_PLOT_BLK_13: next_state = S_PLOT_BLK_14;
S_PLOT_BLK_14: next_state = S_PLOT_BLK_15;
S_PLOT_BLK_15: next_state = S_LOAD_NEW;
S_LOAD_NEW: next_state = S_PLOT_0;
S_PLOT_0: next_state = S_PLOT_1;
S_PLOT_1: next_state = S_PLOT_2;
S_PLOT_2: next_state = S_PLOT_3;
S_PLOT_3: next_state = S_PLOT_4;
S_PLOT_4: next_state = S_PLOT_5;
S_PLOT_5: next_state = S_PLOT_6;
S_PLOT_6: next_state = S_PLOT_7;
S_PLOT_7: next_state = S_PLOT_8;
S_PLOT_8: next_state = S_PLOT_9;
S_PLOT_9: next_state = S_PLOT_10;
S_PLOT_10: next_state = S_PLOT_11;
S_PLOT_11: next_state = S_PLOT_12;
S_PLOT_12: next_state = S_PLOT_13;
S_PLOT_13: next_state = S_PLOT_14;
S_PLOT_14: next_state = S_PLOT_15;
S_PLOT_15: next_state = S_PLOT_16;
S_PLOT_16: next_state = S_WAIT;
default: next_state = S_WAIT;
endcase
end
always @(*)
begin: enable_signals
ld_new = 0;
plot = 0;
draw_blk = 0;
case (current_state)
S_PLOT_BLK_0: begin
plot = 1;
draw_blk = 1;
end
S_PLOT_BLK_1: begin
plot = 1;
draw_blk = 1;
end
S_PLOT_BLK_2: begin
plot = 1;
draw_blk = 1;
end
S_PLOT_BLK_3: begin
plot = 1;
draw_blk = 1;
end
S_PLOT_BLK_4: begin
plot = 1;
draw_blk = 1;
end
S_PLOT_BLK_5: begin
plot = 1;
draw_blk = 1;
end
S_PLOT_BLK_6: begin
plot = 1;
draw_blk = 1;
end
S_PLOT_BLK_7: begin
plot = 1;
draw_blk = 1;
end
S_PLOT_BLK_8: begin
plot = 1;
draw_blk = 1;
end
S_PLOT_BLK_9: begin
plot = 1;
draw_blk = 1;
end
S_PLOT_BLK_10: begin
plot = 1;
draw_blk = 1;
end
S_PLOT_BLK_11: begin
plot = 1;
draw_blk = 1;
end
S_PLOT_BLK_12: begin
plot = 1;
draw_blk = 1;
end
S_PLOT_BLK_13: begin
plot = 1;
draw_blk = 1;
end
S_PLOT_BLK_14: begin
plot = 1;
draw_blk = 1;
end
S_PLOT_BLK_15: begin
plot = 1;
draw_blk = 1;
end
S_LOAD_NEW: ld_new = 1;
S_PLOT_0: plot = 1;
S_PLOT_1: plot = 1;
S_PLOT_2: plot = 1;
S_PLOT_3: plot = 1;
S_PLOT_4: plot = 1;
S_PLOT_5: plot = 1;
S_PLOT_6: plot = 1;
S_PLOT_7: plot = 1;
S_PLOT_8: plot = 1;
S_PLOT_9: plot = 1;
S_PLOT_10: plot = 1;
S_PLOT_11: plot = 1;
S_PLOT_12: plot = 1;
S_PLOT_13: plot = 1;
S_PLOT_14: plot = 1;
S_PLOT_15: plot = 1;
S_PLOT_16: plot = 1;
endcase
end
always @(posedge clk_50)
begin: state_FFs
if (!resetn)
current_state <= S_WAIT;
else
current_state <= next_state;
end
endmodule
module four_herz_clock(enable, resetn, clk_50, clk_4);
input enable, resetn, clk_50;
output clk_4;
reg clk_4;
reg [23:0] counter;
// Count to 12,499,999
localparam COUNT_TO = 24'b101111101011110000011111;
always @(posedge clk_50)
begin
if (!resetn) begin
counter <= 0;
clk_4 <= 0;
end
else if (enable) begin
if (counter == 0) begin
clk_4 <= 0;
counter <= counter + 1;
end
else if (counter == COUNT_TO) begin
clk_4 <= 1;
counter <= 0;
end
else
counter <= counter + 1;
end
end
endmodule
module pos_counter(enable, resetn, clk, x_pos, y_pos);
input enable, resetn, clk;
output [7:0] x_pos;
output [6:0] y_pos;
reg [7:0] x_pos;
reg [6:0] y_pos;
reg [1:0] direction;
localparam UP_RIGHT = 2'd0,
DOWN_RIGHT = 2'd1,
DOWN_LEFT = 2'd2,
UP_LEFT = 2'd3;
localparam MAX_X_VAL = 8'd160,
MAX_Y_VAL = 7'd120;
always @(posedge clk)
begin
if (!resetn) begin
x_pos <= 8'd0;
y_pos <= 7'd60;
direction <= UP_RIGHT;
end
else if (enable) begin
// If moving up right
if (direction == UP_RIGHT) begin
// If next move is to the top right corner
if (x_pos + 5 >= MAX_X_VAL & y_pos - 1 <= 0)
direction <= DOWN_LEFT;
// If next move is to the right edge
else if (x_pos + 5 >= MAX_X_VAL)
direction <= UP_LEFT;
// If next move is to the top edge
else if (y_pos - 1 <= 0)
direction <= DOWN_RIGHT;
x_pos <= x_pos + 1;
y_pos <= y_pos - 1;
end
// If moving down right
else if (direction == DOWN_RIGHT) begin
// If next move is to the bottom right corner
if (x_pos + 5 >= MAX_X_VAL & y_pos + 5 >= MAX_Y_VAL)
direction <= UP_LEFT;
// If next move is to the right edge
else if (x_pos + 5 >= MAX_X_VAL)
direction <= DOWN_LEFT;
// If next move is to the bottom edge
else if (y_pos + 5 >= MAX_Y_VAL)
direction <= UP_RIGHT;
x_pos <= x_pos + 1;
y_pos <= y_pos + 1;
end
// If moving down left
else if (direction == DOWN_LEFT) begin
// If next move is to the bottom left corner
if (x_pos - 1 <= 0 & y_pos + 5 >= MAX_Y_VAL)
direction <= UP_RIGHT;
// If next move is to the left edge
else if (x_pos - 1 <= 0)
direction <= DOWN_RIGHT;
// If next move is to the bottom edge
else if (y_pos + 5 >= MAX_Y_VAL)
direction <= UP_LEFT;
x_pos <= x_pos - 1;
y_pos <= y_pos + 1;
end
// Otherwise moving up left
else begin
// If next move is to the top left corner
if (x_pos - 1 <= 0 & y_pos - 1 <= 0)
direction <= DOWN_RIGHT;
// If next move is to the left edge
else if (x_pos - 1 <= 0)
direction <= UP_RIGHT;
// If next move is to the top edge
else if (y_pos - 1 <= 0)
direction <= DOWN_LEFT;
x_pos <= x_pos - 1;
y_pos <= y_pos - 1;
end
end
end
endmodule
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment