Untitled
unknown
plain_text
a year ago
5.1 kB
5
Indexable
Never
`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