---
# System prepended metadata

title: Untitled
tags: [HDLBits, verilog]

---

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