Untitled
unknown
verilog
2 years ago
6.1 kB
7
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; reg [3:0] next_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'b1100110011001100; 4'b0011: led <= 16'b1110111011101110; 4'b0100: 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 <= REGULAR_MODE; end else if(en == 0) begin cnt <= cnt; mode <= mode; end else begin cnt <= next_cnt; mode <= next_mode; end end // update round always @(posedge clk_div0 or posedge rst) begin if(rst) begin round <= 0; end else if(en == 0) begin round <= round; end else begin case(mode) REGULAR_MODE: begin if(cnt == 4'b0100) round <= next_round; end ESCAPE_MODE: begin if(cnt == 4'b0000 && dir == 1) round <= next_round; else if(cnt == 4'b1000 && dir == 0) round <= next_round; end SHINING_MODE: begin if(cnt == 4'b0001) round <= next_round; end endcase end end // update the value of next_cnt always @(*) begin if(rst) begin next_cnt = 0; end else begin case(mode) REGULAR_MODE: begin if(cnt == 4'b0100) begin next_cnt = 0; if(next_mode == ESCAPE_MODE) begin if(dir == 1) begin next_cnt = 4'b1000; end else next_cnt = 4'b0000; end end else next_cnt = cnt + 1; end ESCAPE_MODE: begin if(cnt == 4'b0000 && dir == 1) begin next_cnt = 0; end else if(cnt == 4'b1000 && dir == 0) begin next_cnt = 0; end else if(dir == 1) next_cnt = cnt - 1; else next_cnt = cnt + 1; end SHINING_MODE: begin if(cnt == 4'b0001) begin next_cnt = 0; end else next_cnt = cnt + 1; end endcase end end // mode transtion always @(*) begin if(rst) begin next_mode = REGULAR_MODE; end else begin case(mode) REGULAR_MODE: begin if(round == 2 && cnt == 4'b0100) begin if(dir == 0) next_mode = REGULAR_MODE; else next_mode = ESCAPE_MODE; next_round = 0; end else begin next_mode = REGULAR_MODE; next_round = round + 1; end end ESCAPE_MODE: begin if(cnt == 4'b0000 && dir == 1) begin next_mode = REGULAR_MODE; next_round = 0; end else if(cnt == 4'b1000 && dir == 0) begin next_mode = SHINING_MODE; next_round = 0; end else begin next_mode = ESCAPE_MODE; next_round = round + 1; end end SHINING_MODE: begin if(round == 4 && cnt == 4'b0001) begin next_mode = REGULAR_MODE; next_round = 0; end else begin next_mode = SHINING_MODE; next_round = round + 1; end end endcase end end endmodule
Editor is loading...