当前位置: 代码迷 >> 综合 >> Verilog专题(三十)Serial receiver with parity checking(有奇偶校验的串口协议)
  详细解决方案

Verilog专题(三十)Serial receiver with parity checking(有奇偶校验的串口协议)

热度:39   发布时间:2024-02-04 22:33:59.0

HDLBits网址:https://hdlbits.01xz.net/wiki/Main_Page

 

题目

    我们要向串行接收器添加奇偶校验。奇偶校验在每个数据字节后增加一个额外的位。将使用奇数奇偶校验,其中接收到的9位中1的数量必须为奇数。例如,101001011满足奇偶校验(有5个1),而001001011不满足。

    更改上面的FSM和数据路径以执行奇偶校验。仅当正确接收到一个字节且其奇偶校验通过时,才声明完成信号。像串行接收器FSM一样,该FSM需要标识起始位,等待所有9位(数据和奇偶校验),然后验证终止位是否正确。如果在预期的情况下没有出现停止位,则FSM必须等待直到找到停止位,然后再尝试接收下一个字节。

    提供了以下模块,该模块可用于计算输入流的奇偶校验(这是带复位的TFF)。预期的用途是应该为它提供输入位流,并在适当的时间进行重置,以便它计算每个字节中1位的数目。

    请注意,串行协议首先发送最低有效位,然后在8个数据位之后发送奇偶校验位。

module parity (
input clk,
input reset,
input in,
output reg odd);

always @(posedge clk)
if (reset) odd <= 0;
else if (in) odd <= ~odd;

endmodule

 

    没有成帧错误。奇偶校验通过第一个字节,通过第二个字节失败,波形如下:

 

Module Declaration

module top_module(
input clk,
input in,
input reset,    // Synchronous reset
output [7:0] out_byte,
output done
);

 

我的设计

    原理之前的文章一样,本设计采用5个状态,其中IDLE状态是起始状态,当起始位为0的时候,才开始数据传输(即跳到DATA状态),否则保持IDLE状态;DATA状态用一个cnt计数,数到8(即接受到一个字节的数据和一个奇校验位)才跳到下一个状态CHECK;CHECK状态主要主要判断是连续发送(即STOP状态)还是停止位为0的错误等待(即ERROR状态)。数据的发送采用一个右移寄存器进行存放;奇偶校验功能直接调用题目所给的模块,需要注意的是,每次传输结束之后需要复位奇偶模块,因此有一个start寄存器充当复位信号;最后done信号在奇校验正确且数据正常接收结束(停止位为1)的情况下置1,否则置0,代码如下:

?module top_module(    input clk,    input in,    input reset,    // Synchronous reset    output [7:0] out_byte,    output done); //?    parameter IDLE = 0, DATA = 1, CHECK = 2, STOP = 3, ERROR = 4;        reg[2:0] state, next_state;    reg[3:0] cnt;    reg[7:0] out;    reg check;    wire odd, start;        parity parity_inst(        .clk(clk),        .reset(reset | start),        .in(in),        .odd(odd));            //transition    always@(*)begin        start = 0;        case(state)            IDLE:begin               next_state = in?IDLE:DATA;               start=1;             end            DATA:              next_state = (cnt==8)?CHECK:DATA;            CHECK:              next_state = in?STOP:ERROR;            STOP:begin               next_state=in?IDLE:DATA;               start=1;             end            ERROR:              next_state = in?IDLE:ERROR;        endcase    end        //state    always@(posedge clk)begin        if(reset)            state<=IDLE;        else            state<=next_state;    end        //cnt    always@(posedge clk)begin        if(reset)            cnt<=0;        else            case(state)                DATA:cnt<=cnt+1;                default:cnt<=0;            endcase    end        //out    always@(posedge clk)begin        if(reset)            out<=0;        else            case(next_state)                DATA:out<={in,out[7:1]};            endcase    end        //check    always@(posedge clk)begin        if(reset)            check<=0;        else            check<=odd;    end        assign out_byte=out;    assign done=check&(state==STOP);                endmodule

 

 

微信公众号

     建立了一个微信公众号“Andy的ICer之路”,此公众号主要分享数字IC相关的学习经验,做公众号的目的就是记录自己的学习过程,很多东西回过头来可能就忘记了,为了记住知识和分享知识,希望自己可以保持更新,有兴趣的朋友可以关注一下!

 

 

  相关解决方案