] 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
```