Untitled
unknown
verilog
a year ago
4.1 kB
4
Indexable
`timescale 1ns / 1ps module clock_divider #(parameter n = 25)( input clk, output clk_div ); 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 ); parameter REGULAR_MODE = 0; parameter ESCAPE_MODE = 1; parameter SHINING_MODE = 2; wire clk_div0, clk_div1, clk_div25, clk_div27; reg [3:0] cnt; reg [3:0] next_cnt; reg [1:0] mode; reg [1:0] next_mode; reg [3:0] round; clock_divider #(25) div1(.clk(clk), .clk_div(clk_div25)); clock_divider #(27) div2(.clk(clk), .clk_div(clk_div27)); assign clk_div0 = (speed)? clk_div25 : clk_div27; //change speed by switch // led display according to mode always @(posedge clk_div0 or posedge rst) begin if(rst) begin led <= 0; end else begin if (en) begin if(mode == REGULAR_MODE) begin case (cnt) 4'b0000: led <= 16'b0000000000000000; 4'b0001: led <= 16'b1000100010001000; 4'b0010: led <= 16'b1110111011101110; 4'b0011: led <= 16'b1111111111111111; default: led <= 16'b0000000000000000; endcase end else if(mode == ESCAPE_MODE) begin case (cnt) 4'b0000: led <= 16'b1111111111111111; 4'b0001: led <= 16'b0011111111111111; 4'b0010: led <= 16'b0000111111111111; 4'b0011: led <= 16'b0000001111111111; 4'b0100: led <= 16'b0000000011111111; 4'b0101: led <= 16'b0000000000111111; 4'b0110: led <= 16'b0000000000001111; 4'b0111: led <= 16'b0000000000000011; 4'b1000: led <= 16'b0000000000000000; default: led <= 16'b0000000000000000; endcase end else begin case (cnt) 4'b0000: led <= 16'b1111111111111111; 4'b0001: led <= 16'b0000000000000000; default: led <= 16'b0000000000000000; endcase end end else led <= led; end end // update current cnt and mode always @(posedge clk_div0 or posedge rst) begin if(rst) begin cnt <= 0; mode <= 0; end else begin cnt <= next_cnt; mode <= next_mode; end end // update the value of next_cnt and round always @(*) begin case(mode) REGULAR_MODE: begin if(cnt == 4'b0101) begin next_cnt = 0; round = round + 1; end else next_cnt = cnt + 1; end ESCAPE_MODE: begin if(cnt == 4'b1000 && dir == 1) begin next_cnt = 0; round = round + 1; end else if(cnt == 4'b000 && dir == 0) begin next_cnt = 4'b1000; round = round + 1; end else next_cnt = cnt + 1; end SHINING_MODE: begin if(cnt == 4'b0010) begin next_cnt = 0; round = round + 1; end else next_cnt = cnt + 1; end endcase end // mode transtion always @(*) begin case(mode) REGULAR_MODE: begin if(round == 2) next_mode = ESCAPE_MODE; else next_mode = REGULAR_MODE; end ESCAPE_MODE: begin if(round == 3 && dir == 1) next_mode = SHINING_MODE; else if(round == 3 && dir == 0) next_mode = REGULAR_MODE; else next_mode = ESCAPE_MODE; end SHINING_MODE: begin if(round == 8) next_mode = REGULAR_MODE; else next_mode = SHINING_MODE; end endcase end endmodule
Editor is loading...