地址:HDLBits-Exams/review2015 fancytimer
介绍:花了好长时间写的,记录一下。将计数值量化为以1000为单位,开始时则有delay的1000需要计数。在couting过程中统计已经计了1000次的次数num_1k,将delay减去num_1k即count。
module top_module ( input clk, input reset, // Synchronous reset input data, output [3:0] count, output counting, output done, input ack ); parameter [2:0] IDLE=3'b000,DEC_1=3'b001,DEC_11=3'b010,DEC_110=3'b011,SHIFT=3'b100,COUNT=3'b101,WAIT=3'b110; reg [2:0] current_state,next_state; always @(posedge clk) begin if (reset) current_state <= IDLE; else current_state <= next_state; end always @(*) begin case (current_state) IDLE: next_state = data?DEC_1:IDLE; DEC_1: next_state = data?DEC_11:IDLE; DEC_11: next_state = data?DEC_11:DEC_110; DEC_110: next_state = data?SHIFT:IDLE; SHIFT: next_state = (shift_cnt==2'b11)?COUNT:SHIFT; COUNT: next_state = (counter==(delay+1)*1000-1)?WAIT:COUNT; WAIT: next_state = (done&&ack)?IDLE:WAIT; default: next_state = IDLE; endcase end reg [1:0] shift_cnt; reg [3:0] delay; always @(posedge clk) begin if (reset) shift_cnt <= 2'b0; else if (current_state==SHIFT&&shift_cnt!=2'b11) shift_cnt <= shift_cnt+1'b1; else shift_cnt <= 2'b0; end always @(posedge clk) begin if (reset) delay <= 4'b0; else if (current_state==SHIFT) delay <= {delay[2:0],data}; else delay <= delay; end reg [14:0] counter; always @(posedge clk) begin if (reset) counter <= 15'd0; else if (current_state==COUNT&&counter!=(delay+1)*1000-1) counter <= counter+1'b1; else counter <= 15'd0; end reg [10:0] cnt_1k; reg [3:0] num_1k; always @(posedge clk) begin if (reset) cnt_1k <= 11'd0; else if (current_state==COUNT&&cnt_1k!=11'd999) cnt_1k <= cnt_1k+1'b1; else cnt_1k <= 11'd0; end always @(posedge clk) begin if (reset) num_1k <= 4'b0; else if (cnt_1k==11'd999) num_1k <= num_1k+1'b1; else if (current_state==COUNT) num_1k <= num_1k; else num_1k <= 4'b0; end assign counting = (current_state==COUNT)?1'b1:1'b0; assign done = (current_state==WAIT)?1'b1:1'b0; assign count = (current_state==COUNT)?(delay-num_1k):4'b0; endmodule