Fsm serialdp

We want to add parity checking to the serial receiver. Parity checking adds one extra bit after each data byte. We will use odd parity, where the number of 1s in the 9 bits received must be odd. For example, 101001011 satisfies odd parity (there are 5 1s), but 001001011 does not.

我们想向串行接收器添加奇偶校验检查,奇偶校验检查在每个数据字节之后在增加一个位.我们将使用奇数奇偶校验,其中接收到的9位中的1s的数量必须是奇数.例如,101001011,满足奇数奇偶检测,有5个1s,但是001001011没有.

Change your FSM and datapath to perform odd parity checking. Assert the done signal only if a byte is correctly received and its parity check passes. Like the serial receiver FSM, this FSM needs to identify the start bit, wait for all 9 (data and parity) 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.

更改FSM和数据路径以执行奇数奇偶检验.只有在正确接收到一个字节并且其奇偶校验通过的时候,才断言已完成的信号.像串行接收器FSM,这个FSM需要去识别开始位,等待所有9个(数据和奇偶校验)位,然后验证停止位是正确的.如果停止位没有在预期时出现,则FSM必须等待找到停止位后才能尝试接收下一个字节.

You are provided with the following module that can be used to calculate the parity of the input stream (It's a TFF with reset). The intended use is that it should be given the input bit stream, and reset at appropriate times so it counts the number of 1 bits in each byte.

你被提供了以下模块,可用于计算输入流的奇偶性,这是一个带有重置功能的TFF.预期的用途是应该给予输入位流,并在适当的时间重置,以便计算每个字节中1位的数量.

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

    // Modify FSM and datapath from Fsm_serialdata
    parameter [3:0] idle=4'd0;
    parameter [3:0] start=4'd1;
    parameter [3:0] bit1=4'd2;
    parameter [3:0] bit2=4'd3;
    parameter [3:0] bit3=4'd4;
    parameter [3:0] bit4=4'd5;
    parameter [3:0] bit5=4'd6;
    parameter [3:0] bit6=4'd7;
    parameter [3:0] bit7=4'd8;
    parameter [3:0] bit8=4'd9;
    parameter [3:0] odd=4'd10;
   // parameter [3:0] data=4'd11;
    parameter [3:0] stop=4'd11;
    parameter [3:0] error=4'd12;
    reg [3:0] state,next_state;
    reg [7:0] data_r;
    wire st,ODD;
    reg odd_1;
    // New: Add parity checking.
    always@(posedge clk)
        if(reset)begin
            state<=idle;
        end
            else begin
                state<=next_state;
        end
    
    always@(*)begin
        st=0;
        case(state)
            //idle:next_state=in?idle:start;
               idle:begin
                    next_state = (~in)?start:idle;
                	st=1; end
            start:next_state=bit1;
            bit1:next_state=bit2;
            bit2:next_state=bit3;
            bit3:next_state=bit4;
            bit4:next_state=bit5;
            bit5:next_state=bit6;
            bit6:next_state=bit7;
            bit7:next_state=bit8;
            bit8:next_state=odd;
            odd:next_state=in?stop:error;
            //stop:next_state=in?idle:start;
                            stop: begin
                    next_state = (in)?idle:start;
					st=1; end
            error:next_state=in?idle:error;
            default next_state = idle;
        endcase
    end
    
   /* always@(posedge clk)begin
        case(next_state)
            bit1:data_r<={in,data_r[7:1]};
            bit2: data_r <= {in,data_r[7:1]};
            bit3: data_r <= {in,data_r[7:1]};
            bit4: data_r <= {in,data_r[7:1]};
            bit5: data_r <= {in,data_r[7:1]};
            bit6: data_r <= {in,data_r[7:1]};
            bit7: data_r <= {in,data_r[7:1]};
            bit8: data_r <= {in,data_r[7:1]}; 
        endcase
    end*/
        always @ (posedge clk)
	 case (state)
       start:data_r[0] = in;
       bit1:data_r[1] = in;
       bit2:data_r[2] = in;
       bit3:data_r[3] = in;
	   bit4:data_r[4] = in;
       bit5:data_r[5] = in;
       bit6:data_r[6] = in;
       bit7:data_r[7] = in;
       default data_r = data_r;
	endcase
    

    parity U1(.clk(clk),
          .reset(reset|st),
          .in(in),
              .odd(ODD));
    
    always@(posedge clk)
        if(reset)begin
        	odd_1<=0;
        end
		else  
            begin
        	odd_1<=ODD;
        end

    assign done = (state==stop) & odd_1;
    assign out_byte=data_r;
    
endmodule



   /*parity  U1 ( .clk(clk), .reset(reset | st), .in(in), .odd(odd)); 
   always @(posedge clk)
        if(reset)
            check_1 <= 0;
        else
            check_1 <= odd;
    assign done = (state == stop) & check_1;
    assign out_byte = out_temp;
	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 top_module(
 input clk,
    input in,
    input reset,    // Synchronous reset
    output [7:0] out_byte,
    output done
);
     parameter idle = 0,start = 1,data1 = 2,data2 = 3,data3 = 4,data4 = 5,
    	data5 = 6,data6 = 7,data7 = 8,data8 = 9,stop = 10,error = 11, check = 12;
    reg [3:0] state,next_state;
    reg [7:0] out_temp;
    wire st,odd;
    reg check_1;

    always @ (*)
        begin
	        st = 0;
	        case (state)
                idle:begin
                    next_state = (~in)?start:idle;
                	st=1; end
                start: next_state = data1;
                data1: next_state = data2;              
                data2: next_state = data3;               
                data3: next_state = data4;               
                data4: next_state = data5;               
                data5: next_state = data6;              
                data6: next_state = data7;               
                data7: next_state = data8;                
                data8: next_state = check;               
                check: next_state = (in)?stop:error;                   
                stop: begin
                    next_state = (in)?idle:start;
					st=1; end
                error: next_state = (in)?idle:error;
	            default next_state = idle;
	        endcase
        end
	always @(posedge clk)
        if(reset)
            state <= idle;
    	else state <= next_state;
    always @ (posedge clk)
	 case (state)
       start:out_temp[0] = in;
       data1:out_temp[1] = in;
       data2:out_temp[2] = in;
       data3:out_temp[3] = in;
	   data4:out_temp[4] = in;
       data5:out_temp[5] = in;
       data6:out_temp[6] = in;
       data7:out_temp[7] = in;
       default out_temp = out_temp;
	endcase
   parity  U1 ( .clk(clk), .reset(reset | st), .in(in), .odd(odd)); 
   always @(posedge clk)
        if(reset)
            check_1 <= 0;
        else
            check_1 <= odd;
    assign done = (state == stop) & check_1;
    assign out_byte = out_temp;

endmodule*/

来一个简化后的coding:

来源于:FPGA基础——串行数据接收(Fsm serialdp) - 一曲挽歌 - 博客园 (cnblogs.com)

module top_module(
    input clk,
    input in,
    input reset,    // Synchronous reset
    output [7:0] out_byte,
    output done
); //
    parameter IDLE = 4'd0, START = 4'd1, RXD = 4'd2,STOP = 4'd3,WAIT = 4'd4,PARITY = 4'd5;
      reg [7:0]     out_byte_reg;
    reg [3:0]    current_state;
    reg [3:0]    next_state;
    wire odd;
    wire re;
    reg [3:0]cnt_byte;

    always@(posedge clk)begin
        if(reset)begin
            current_state <= IDLE;
        end
        else begin
            current_state <= next_state;
        end
    end

    always@(*)begin
        case(current_state)
            IDLE:
                next_state = in ? IDLE : START;
            START:
                next_state = RXD;
            RXD:
                next_state = (cnt_byte==8)?PARITY:((cnt_byte>8)?WAIT:RXD);    //cnt_byte不会大于8(直接进入WAIT状态),可省略内层判断
            PARITY:
                next_state = in ? STOP : WAIT;
            WAIT:
                next_state = in ? IDLE : WAIT;
            STOP:
                next_state = in ? IDLE : START;
            default:
                next_state = IDLE;
        endcase
    end

    always@(posedge clk)begin
        if(reset || next_state == IDLE || next_state == START)
            cnt_byte <= 0;
        else if(next_state==RXD)begin                //数据data接受状态
            out_byte_reg[cnt_byte] <= in;            //8bit数据寄存,利用计数器当位置索引
            cnt_byte <= cnt_byte+4'd1;
        end
    end

    assign re = reset || next_state == IDLE || next_state == START;    //IDLE或START为新一轮数据传输开始,奇偶校验清零信号
    parity u_parity(.clk(clk),
                    .reset(re),
                    .in(in),
                    .odd(odd)
                    );

    assign done = (current_state==STOP)&&~odd;        //因为在STOP状态又进行奇校验反转了一次,odd取反
    assign out_byte = done?out_byte_reg:8'bz;

endmodule

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值