Untitled
unknown
verilog
2 years ago
3.3 kB
10
Indexable
`timescale 1ps/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 = 2'b00; parameter Escape = 2'b01; parameter Shining = 2'b10; wire clk_used, clk_div_24, clk_div_26; reg [3:0] cnt, nxt_cnt; reg [2:0] state, nxt_state; reg [15:0] nxt_led; reg [3:0] reg_tmp; //directly use two clock in our mudule clock_divider #(24) div1(.clk(clk), .clk_div(clk_div_24)); clock_divider #(26) div2(.clk(clk), .clk_div(clk_div_26)); //change speed by switch assign clk_used = (!speed) ? clk_div_26 : clk_div_24; // Use a counter to deal with the light; always @(posedge clk_used, posedge rst) begin if(rst) cnt <= 0; else if(en) cnt <= nxt_cnt; else cnt <= cnt; end always @(*) begin if(nxt_state != state) nxt_cnt = 0; else nxt_cnt = cnt + 1; end // State transition always @(posedge clk_used, posedge rst) begin if(rst) state <= Regular; else state <= nxt_state; end always @(*) begin case (state) Regular: begin if(cnt == 4'b1110) nxt_state = Escape; else nxt_state = Regular; end Escape: begin if(led == 16'b0000000000000000 && dir == 0) nxt_state = Shining; else if(led == 16'b1111111111111111 && dir == 1) nxt_state = Regular; else nxt_state = Escape; end Shining: begin if(cnt == 4'b1001) nxt_state = Regular; else nxt_state = Shining; end default: nxt_state = state; endcase end // Deal with the output always @(posedge clk_used, posedge rst) begin if(rst) begin led <= 16'b0000000000000000; end else if(en) begin if(state == Regular) begin reg_tmp = cnt % 5; case(reg_tmp) 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'b1111111111111111; endcase end else led <= nxt_led; end else led <= led; end reg [15:0] led_tmp; always @(*) begin case(state) Escape: begin if(dir == 0) begin nxt_led = led >> 2; end else begin led_tmp = led; nxt_led = (led << 2) | led_tmp; end end Shining: begin if(led == 16'b1111111111111111) nxt_led = 16'b0000000000000000; else nxt_led = 16'b1111111111111111; end default: nxt_led = led; endcase end endmodule
Editor is loading...