] Fsm serial ###### tags: `HDLBits` `verilog` main code ```=verilog module top_module( input clk, input reset, input in, output reg done); //parameter parameter idle=3'd0, start=3'd1, data=3'd2, stop=3'd3, error=3'd4; //fsm ////regs reg [2:0]state,nextstate; reg [3:0]count; ////state transition always@(posedge clk) begin if (reset) state<=1'd0; else state <=nextstate; end ////next_state logic always@(*) begin case (state) idle: if (in) nextstate=idle; else nextstate=start; start: nextstate=data; data: if (count!=4'd7) nextstate=data; else if (in) nextstate=stop; else nextstate=error; stop:if (in) nextstate=idle; else nextstate=start; error:if (in) nextstate=idle; else nextstate=error; default:nextstate=idle; endcase end ////state output logic always@(*) begin case(state) stop:done<=1'd1; default:done<=1'd0; endcase end //cnt always@(posedge clk) begin if (count==4'd7) count<=4'd0; else case (state) data:count<=count+4'd1; default:count<=4'd0; endcase end endmodule ``` tb ```=verilog //設定timescale `timescale 1ns/100ps //設定testbench名 module top_module_test; //input用reg output用wire reg reset,clk,in; wire done; //引用待測模組 top_module t1(.reset(reset), .clk(clk), .in(in), .done(done)); //clk signal initial #0 clk=1'b1; always #5 clk =~clk; //也可以用initial forever #5 clk=~clk //rst input initial begin: in_set_blk //名字? #0 reset =1'b1; in =1'b1; #10 reset =1'b0; in =1'b0; #92 in =1'b1; #10 in =1'b0; #90 in =1'b1; #10 in =1'b0; end //signals initial begin: signals_blks integer i; for (i=0;i<30;i=i+1) begin #10 $display ($time, " in=%d \n",in); $display ($time, " state=%d nextstate=%d\n", t1.state,t1.nextstate); $display ($time, " count=%d \n",t1.count); $display ($time, " done=%d\n",done); end #10 $stop; #10 $finish; end endmodule ```