Created
November 11, 2018 16:05
-
-
Save peterzhu2118/4967adf8f197a2b9104fdce607f08f35 to your computer and use it in GitHub Desktop.
CSC258 Lab 7 Part 3
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
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