`define N_LED 4 `define LEDS_OFF {`N_LED{1'b1}} `define LEDS_ON {`N_LED{1'b0}} `define RIGHT_ON {{`N_LED-1{1'b1}}, 1'b0} `define LEFT_ON { 1'b0, {`N_LED-1{1'b1}}} module LedFsm ( input clk, input rst_n, output [`N_LED-1:0] leds); //0:on, 1:off parameter N_MODE = 4; parameter N_TICK = 50_000_0; //50Mhz, tick on 100ms // led change: // all on, off // left to right // right to left // arrive from both side /* Tick counter*/ reg[15:0] cnt; wire tick; assign tick = cnt == N_TICK ? 1: 0; always @(posedge clk or negedge rst_n) begin //tick counter cnt <= !rst_n || tick ? 0 : cnt + 1; end /* Mode fsm */ reg [7:0] mode_fsm; //sequence fsm wire [2:0] mode_enable; //0: flash 1: walk 2: backward walk wire [2:0] step_last; //last step of each mode always @(posedge tick, negedge rst_n) //1, shift left, 0(stop) mode_fsm <= !rst_n ? 1: //reset !mode_enable && step_last ? 0 : // end if hit 0 step_last ? mode_fsm + 1 : mode_fsm; /* Program your mode sequence here */ assign mode_enable = !rst_n ? 0 : mode_fsm == 1 ? 'b001 : //flash mode_fsm == 2 ? 'b010 : //walk mode_fsm == 3 ? 'b100 : //walk back mode_fsm == 4 ? 'b110 : //walk bi-direction mode_fsm == 5 ? 'b001 : //flash 0; //end wire [`N_LED-1:0] flash_leds; FlashLeds flash(tick, rst_n, mode_enable[0], step_last[0], flash_leds); wire [`N_LED-1:0] walk_leds; WalkLeds #(1) walk(tick, rst_n, mode_enable[1], step_last[1], walk_leds); wire [`N_LED-1:0] walk_back_leds; WalkLeds #(0) walk_back(tick, rst_n, mode_enable[2], step_last[2], walk_back_leds); assign leds = flash_leds & walk_leds & walk_back_leds; endmodule /* Flash Mode*/ module FlashLeds( input tick, rst_n, enable, output last, output [`N_LED-1:0] leds); reg[0:0] fsm; //0:on, 1:0ff, 2: end always @(posedge tick, negedge rst_n) fsm <= !rst_n || !enable ? 0 : //reset, default to on fsm == 0 ? 1 : 0; //toggle assign last = !rst_n || !enable ? 0 : fsm == 1; //last step assign leds = !rst_n || !enable ? `LEDS_OFF : //default off fsm[0] ? `LEDS_OFF : `LEDS_ON; endmodule /* Walk */ module WalkLeds( input tick, rst_n, enable, output last, output [`N_LED-1:0] leds); parameter R_TO_L = 1; //walk from right to left localparam INIT_LEDS = R_TO_L ? `RIGHT_ON : `LEFT_ON ; localparam LAST_LEDS = R_TO_L ? `LEFT_ON : `RIGHT_ON ; reg[`N_LED-1:0] fsm; //n bits, shift left or right always @(posedge tick, negedge rst_n) fsm <= (!rst_n || !enable) ? INIT_LEDS : //reset last ? INIT_LEDS : //end? R_TO_L ? ~(~fsm << 1) : ~(~fsm >> 1); //walk assign last = !rst_n || !enable ? 0 : fsm == LAST_LEDS; //last step assign leds = !rst_n || !enable ? `LEDS_OFF : fsm; endmodule module TestLedFsm; reg clk, rst_n; wire [3:0] leds; initial clk = 0; initial rst_n = 0; always #10 clk = ~clk; initial #25 rst_n = 1; LedFsm #(.N_MODE(4), .N_TICK(4)) fsm(clk, rst_n, leds); initial $display("\t\t\t\ttime, leds, fsm.mode_fsm"); initial $monitor("%d\t%b\t%b", $time, leds, fsm.mode_fsm); endmodule
复杂一点的灯光控制verilog fsm
猜你喜欢
转载自steeven.iteye.com/blog/2364852
今日推荐
周排行