Untitled
unknown
plain_text
2 years ago
5.1 kB
10
Indexable
`timescale 1ns / 1ps
module clock_divider(clk,clk_div);
input clk;
output clk_div;
parameter n = 25;
reg[n-1:0]num;
wire[n-1:0]next_num;
always@(posedge clk)begin
num <= next_num;
end
assign next_num = num + 1;
assign clk_div = num[n-1];
endmodule
module lab3_2(
input clk,
input rst,
input en,
input speed,
input dir,
output reg[15:0]led
);
// add your design here
wire clk_div,clk_div24,clk_div26;
reg [1:0] state,next_state;
reg [1:0] regular_repeat,next_regular_repeat;
reg[2:0]shining_repeat,next_shining_repeat;
reg [15:0] next_led;
reg change_state;
parameter regular_mode = 2'b00;
parameter esscape_mode_down = 2'b01;
parameter esscape_mode_up = 2'b10;
parameter shining_mode = 2'b11;
clock_divider #(24) div1(.clk(clk), .clk_div(clk_div24));
clock_divider #(26) div2(.clk(clk), .clk_div(clk_div26));
assign clk_div = (speed)?clk_div24 : clk_div26;
always@(posedge clk_div , posedge rst ,posedge change_state)begin
if(rst)begin
state <= regular_mode;
end
else if (change_state)begin
state <= next_state;
change_state <= 0;
end
else begin
state <= next_state;
end
end
always@(*)begin
if(!en)
next_state <= state;
else if(state == regular_mode & regular_repeat == 2'b11 & dir == 0 & led == 16'b1111111111111111)begin
next_state <= esscape_mode_down;
end
else if(state == regular_mode & regular_repeat == 2'b11 & dir == 1 & led == 16'b1111111111111111)begin
next_state <= esscape_mode_up;
end
else if(state == esscape_mode_down & dir == 1)begin
next_state <= esscape_mode_up;
change_state <= 1;
end
else if(state == esscape_mode_up & dir == 0)begin
next_state <= esscape_mode_down;
change_state <= 1;
end
else if(state == esscape_mode_down & led == 16'b0000000000000000)begin
next_state <= shining_mode;
end
else if(state == esscape_mode_up & led == 16'b1111111111111111)begin
next_state <= regular_mode;
end
else if(state == shining_mode & shining_repeat == 3'b100 & led == 16'b1111111111111111)begin
next_state <= regular_mode;
end
else
next_state <= state;
end
always@(posedge clk_div , posedge rst)begin
if(rst)begin
regular_repeat <= 2'b00;
end
else begin
regular_repeat <= next_regular_repeat;
end
end
always @(*) begin
if(!en)
next_regular_repeat <= regular_repeat;
else if(regular_repeat == 2'b11)
next_regular_repeat <= 2'b00;
else if(state == regular_mode & led == 16'b1110111011101110)
next_regular_repeat <= regular_repeat + 2'b01;
else
next_regular_repeat <= regular_repeat;
end
always@(posedge clk_div , posedge rst)begin
if(rst)begin
shining_repeat <= 3'b000;
end
else begin
shining_repeat <= next_shining_repeat;
end
end
always @(*) begin
if(!en)
next_shining_repeat <= shining_repeat;
else if(shining_repeat == 3'b101)
next_shining_repeat <= 3'b000;
else if(state == shining_mode & led == 16'b1111111111111111)
next_shining_repeat <= shining_repeat + 3'b001;
else
next_shining_repeat <= shining_repeat;
end
always@(posedge clk_div , posedge rst)begin
if(rst)begin
led <= 16'b0000000000000000;
end
else if (change_state)begin
led <= next_led;
change_state <= 0;
end
else begin
led <= next_led;
end
end
always @(*)begin
if(!en)
next_led <= led;
else if(state == regular_mode )begin
if(led == 16'b0000000000000000)
next_led <= 16'b1000100010001000;
else if(led == 16'b1000100010001000)
next_led <= 16'b1100110011001100;
else if(led == 16'b1100110011001100)
next_led <= 16'b1110111011101110;
else if(led == 16'b1110111011101110)
next_led <= 16'b1111111111111111;
else if(led == 16'b1111111111111111 & regular_repeat == 2'b11)
next_led <= 16'b1111111111111111;
else if(led == 16'b1111111111111111)
next_led <= 16'b0000000000000000;
end
else if(state == esscape_mode_down)begin
if(dir)
next_led <= led * 4 + 3;
else
next_led <= led >> 2;
end
else if(state == esscape_mode_up)begin
if(dir)
next_led <= led * 4 + 3;
else
next_led <= led >> 2;
end
else if(state == shining_mode)begin
if(led == 16'b1111111111111111)
next_led <= 16'b0000000000000000;
else if(led == 16'b0000000000000000 && shining_repeat == 3'b101)
next_led <= 16'b1000100010001000;
else if(led == 16'b0000000000000000)
next_led <= 16'b1111111111111111;
end
else
next_led <= led;
end
endmodule Editor is loading...