In many (older) serial communications protocols, each data byte is sent along with a start bit and a stop bit, to help the receiver delimit bytes from the stream of bits. One common scheme is to use one start bit (0), 8 data bits, and 1 stop bit (1). The line is also at logic 1 when nothing is being transmitted (idle).
Design a finite state machine that will identify when bytes have been correctly received when given a stream of bits. It needs to identify the start bit, wait for all 8 data bits, then verify that the stop bit was correct. If the stop bit does not appear when expected, the FSM must wait until it finds a stop bit before attempting to receive the next byte.
module top_module(
input clk,
input in,
input reset, // Synchronous reset
output done
);
reg [3:0] cnt;
reg [1:0] state,next_state;
// integer cnt;
//定义状态空间
parameter idle = 2'b00; //等待数据起始位
parameter start = 2'b01; //开始接收数据
parameter wait0 = 2'b10; //数据截止位没有正常出现,进入等待状态
parameter stop = 2'b11; //数据截止位正常出现,进入停止状态
//计数器
always@(posedge clk)begin
if(reset)
cnt <= 4'd0;
else if (state == start)
cnt <= cnt+ 4'd1;
else if (state == wait0)
cnt <= cnt;
else
cnt<=4'd0;
end
//状态转移条件
always@(*)begin
case(state)
idle: next_state = in? idle: start;
start: begin
if(cnt== 4'd8) // cnt计数的范围应该是0-7,共计8个时钟周期,当cnt=4'd7的时候,已经接收到了8个数据位,所以我们用状态转移到的下一个数据位来检查是否到停止位,所以用cnt== 4'd8来进行下一状态的条件判断
next_state = in? stop: wait0;
else
next_state = start;
end
wait0: next_state = in? idle: wait0;
stop: next_state = in? idle:start;
default: next_state = idle;
endcase
end
//状态转移过程
always@(posedge clk)begin
if(reset)
state <= idle;
else
state <= next_state;
end
assign done = (state == stop);
endmodule
在上一道题目的基础上,添加以下内容:
always@(posedge clk)begin
if(reset)
out_byte <= 8'd0; 0 //复位时清零
else if(state == start && cnt < 4'd8)
out_byte[cnt] <= in; //cnt作为索引,将输入信号in的值存到out_byte相应的位置上
else
out_byte <= out_byte;
end