FPGA基础——串行数据接收(Fsm serialdp)

我们想在串行接收机中加入奇偶校验。奇偶校验检查在每个数据字节后添加一个额外的位。我们将使用奇奇偶校验,其中接收到的9位中的1必须是奇数。例如,101001011个满足奇偶校验(有5个1) ,但001001011个不满足。

只有在正确接收到一个字节并且它的奇偶校验通过时,才断言完成信号。与串行接收机一样,该有限状态机需要确定开始位,等待所有9位(数据和奇偶校验) ,然后验证停止位是正确的。如果停止位没有在预期的时候出现,FSM 必须等到找到停止位之后才能尝试接收下一个字节。

注意,串行协议先发送低有效位,奇偶校验位在8个数据位之后,然后是高有效停止位。

 

 

 1 module parity (
 2     input clk,
 3     input reset,
 4     input in,
 5     output reg odd);
 6 
 7     always @(posedge clk)
 8         if (reset) odd <= 0;
 9         else if (in) odd <= ~odd;
10 
11 endmodule

 

 1 module top_module(
 2     input clk,
 3     input in,
 4     input reset,    // Synchronous reset
 5     output [7:0] out_byte,
 6     output done
 7 ); //
 8     parameter IDLE = 4'd0, START = 4'd1, RXD = 4'd2,STOP = 4'd3,WAIT = 4'd4,PARITY = 4'd5;
 9       reg [7:0]     out_byte_reg;
10     reg [3:0]    current_state;
11     reg [3:0]    next_state;
12     wire odd;
13     wire re;
14     reg [3:0]cnt_byte;
15     
16     always@(posedge clk)begin
17         if(reset)begin
18             current_state <= IDLE;
19         end
20         else begin
21             current_state <= next_state;
22         end
23     end
24     
25     always@(*)begin
26         case(current_state)
27             IDLE:
28                 next_state = in ? IDLE : START;
29             START:
30                 next_state = RXD;
31             RXD:
32                 next_state = (cnt_byte==8)?PARITY:((cnt_byte>8)?WAIT:RXD);    //cnt_byte不会大于8(直接进入WAIT状态),可省略内层判断
33             PARITY:
34                 next_state = in ? STOP : WAIT;
35             WAIT:
36                 next_state = in ? IDLE : WAIT;
37             STOP:
38                 next_state = in ? IDLE : START;            
39             default:
40                 next_state = IDLE;
41         endcase
42     end
43     
44     always@(posedge clk)begin
45         if(reset || next_state == IDLE || next_state == START)
46             cnt_byte <= 0;
47         else if(next_state==RXD)begin                //数据data接受状态
48             out_byte_reg[cnt_byte] <= in;            //8bit数据寄存,利用计数器当位置索引        
49             cnt_byte <= cnt_byte+4'd1;
50         end
51     end
52     
53     assign re = reset || next_state == IDLE || next_state == START;    //IDLE或START为新一轮数据传输开始,奇偶校验清零信号
54     parity u_parity(
55                     .clk(clk),
56                     .reset(re),
57                     .in(in),
58                     .odd(odd)
59                     );
60  
61     assign done = (current_state==STOP)&&~odd;        //因为在STOP状态又进行奇校验反转了一次,odd取反    
62     assign out_byte = done?out_byte_reg:8'bz;
63     
64 endmodule

 

posted on 2021-04-21 17:06  一曲挽歌  阅读(1343)  评论(0编辑  收藏  举报

导航