本题链接:
https://hdlbits.01xz.net/wiki/Fsm_serialdata
另请参阅:Serial receiver
现在你有了一个有限状态机,可以识别何时在串行比特流中正确接收到字节,添加一个数据路径来输出正确接收到的数据字节。 out_byte 需要在 done 为 1 时有效,否则无关紧要。
请注意,串行协议首先发送最低有效位。
一些时序图
无错误:


题目
module top_module(
input clk,
input in,
input reset, // Synchronous reset
output [7:0] out_byte,
output done
);
提示:
串行比特流需要一次只移一位,然后并行读出。

答案
module top_module(
input clk,
input in,
input reset, // Synchronous reset
output [7:0] out_byte,
output done
); //
reg [3:0] i;
parameter rc = 0, rd = 1, dn = 2, err = 3;
reg [2:0] state, next_state;
reg [7:0] date;
always @(*) begin
case (state)
rd: next_state <= in ? rd : rc;
rc: begin
if ((i == 8) & in) begin
next_state <= dn;
end
else if ((i == 8) & (~in)) begin
next_state <= err;
end
else begin
next_state <= rc;
date[i] <= in;
end
end
dn: begin
next_state <= in ? rd : rc;
out_byte <= date;
end
err: next_state <= in ? rd : err;
endcase
end
always @(posedge clk) begin
if (reset) begin
state <= rd;
i <= 0;
end
else begin
if ((state == rc) && (i != 8)) begin
i <= i + 1;
end
else if ((state == dn)) begin
i <= 0;
end
else if (state == err) begin
i <= 0;
end
state <= next_state;
end
end
// New: Datapath to latch input bits.
assign done = (state == dn);
endmodule

有限状态机(Finite-State Machine,FSM),简称状态机,是表示有限个状态以及在这些状态之间的转移和动作等行为的数学模型。状态机不仅是一种电路的描述工具,而且也是一种思想方法,在电路设计的系统级和 RTL 级有着广泛的应用。
Verilog 中状态机主要用于同步时序逻辑的设计,能够在有限个状态之间按一定要求和规律切换时序电路的状态。状态的切换方向不但取决于各个输入值,还取决于当前所在状态。状态机可分为 2 类:Moore 状态机和 Mealy 状态机。
在远程通信和计算机科学中,串行通信(英语:Serial communication)是指在计算机总线或其他数据通道上,每次传输一个比特数据,并连续进行以上单次过程的通信方式。与之对应的是并行通信,它在串行端口上通过一次同时传输若干比特数据的方式进行通信。

每个字符表示为一个帧,以逻辑低电平为开始比特,然后是数据比特,可选的奇偶校验比特,最后是一个或多个停止比特(逻辑高电平)。
接收器在每个时钟脉冲时测试接收到的信号状态是否为开始比特。如果开始比特的低电平持续传输1个比特所需时间的一半以上,则认为开始了一个数据帧的传输;否则,则认为是毛刺脉冲并忽略。到了下一个比特时间后,线路状态被采样并送入移位寄存器。
简化的UART在开始比特下降沿开始重新同步时间,然后在每个数据比特的中心时刻采样。
参考内容:
6.3 Verilog 状态机 | 菜鸟教程:
https://www.runoob.com/w3cnote/verilog-fsm.html
通用异步收发传输器 | 维基百科:
https://zh.wikipedia.org/wiki/UART
串行通信 | 维基百科:
https://zh.wikipedia.org/wiki/串行通信