HDLbits:Serial系列

一、前言

菜鸟总结刷hblbits的心得体会,有错误还请指正!

二、Serial receiver

1、原题目

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.

2、设计思路

题目分析:比特流中如出现 0(数据位)1 为一个有效数据,done=1;出现 0(数据位)0...01 为无效数据,done=0。

状态机设计:我注意到有些设计者将DATA状态拆分为8个状态,简单粗暴,也容易分析,但这种拓展性不好,若数据位不只是8位,而是很多位,那么状态数就会变多,需要重新画状态机,代码也很冗长。我只使用了4个状态,分别为IDLE、DATA、STOP、WAIT(一开始我并没有设置WAIT,导致不好写输出逻辑表达式,出现很多次错误)。其中DATA 可以表示多位数据位,只需要增加一个计数器判断何时会从DATA状态向下一个状态转变。

3、我的代码

module top_module(
    input clk,
    input in,
    input reset,    // Synchronous reset
    output done
); 
    parameter IDLE=4'b0001;
    parameter DATA = 4'b0010;
    parameter STOP = 4'b0100; 
    parameter WAIT = 4'b1000;
    reg [4:0] state, next_state;
    reg [3:0] cnt;
   
//state transition logic
    always @(*) begin 
        case(state)
            IDLE: next_state = in ? IDLE:DATA;
            DATA: next_state = (cnt==9) ? (in ? STOP : WAIT) : DATA; 
            STOP: next_state = in ? IDLE : DATA;
            WAIT: next_state = in ? IDLE : WAIT;
            default: next_state = IDLE;
        endcase
    end
    
// state flip-flops
    always @(posedge clk) begin
        if(reset)
            state <= IDLE;
        else
            state <= next_state;
    end
    
//Output logic       
    assign done = (state==STOP);
    
//counter    
    always@(posedge clk)begin
        if(reset)
            cnt<=0;
        else if(next_state==DATA) /*next_state跟输入in是同步的,
                                   state相比于输入in则会延迟一个时钟*/
            cnt <= cnt + 1'b1;
        else 
            cnt <= 0;
    end
endmodule

三、Serial recevier and datapath

1、原题目

Now that you have a finite state machine that can identify when bytes are correctly received in a serial bitstream, add a datapath that will output the correctly-received data byte. out_byte needs to be valid when done is 1, and is don't-care otherwise.

Note that the serial protocol sends the least significant bit first.

2、设计思路 

只需要增加一个8bits的右移移位寄存器,再在done=1时输出寄存器的储存的数据即可。

3、我的代码

module top_module(
    input clk,
    input in,
    input reset,    // Synchronous reset
    output done,
    output reg [7:0] out_byte
); 
    parameter IDLE=4'b0001;
    parameter DATA = 4'b0010;
    parameter STOP = 4'b0100; 
    parameter WAIT = 4'b1000;
    reg [4:0] state, next_state;
    reg [3:0] cnt;
    reg [7:0] q;
   
//state transition logic
    always @(*) begin 
        case(state)
            IDLE: next_state = in ? IDLE:DATA;
            DATA: next_state = (cnt==9) ? (in ? STOP : WAIT) : DATA; 
            STOP: next_state = in ? IDLE : DATA;
            WAIT: next_state = in ? IDLE : WAIT;
            default: next_state = IDLE;
        endcase
    end
    
// state flip-flops
    always @(posedge clk) begin
        if(reset)
            state <= IDLE;
        else
            state <= next_state;
    end
    
//counter    
    always@(posedge clk)begin
        if(reset)
            cnt<=0;
        else if(next_state==DATA) /*next_state跟输入in是同步的,
                                   state相比于输入in则会延迟一个时钟*/
            cnt <= cnt + 1'b1;
        else 
            cnt <= 0;
    end

// New: Datapath to latch input bits.
    always @(posedge clk) begin //增加一个8bits的register
        if(next_state==DATA)
            q <= {in,q[7:1]};
    end

//Output logic       
    assign done = (state==STOP);
    assign out_byte = done ? q : 8'bx;
endmodule

四、Serial recevier with parity checking 

1、原题目

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.

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.

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.

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

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

endmodule

Note that the serial protocol sends the least significant bit first, and the parity bit after the 8 data bits.

2、设计思路

这道题增加了一位奇偶校验位,判断数据在传输过程中是否出现错误。

状态机不需要更改,这时DATA状态包括data和parity ,增加了1 bit 的parity,共9 bits,因此只需将状态转换逻辑中的cnt==9改为cnt==10即可。

done=1需要同时满足一个字节被正确接收和奇偶校验通过,即state=STOP和odd=0(关于odd=0的原因代码中有注释)。

必须正确设置Parity模块中的复位信号,否则done会输出错误。需要在上一个DATA状态结束之后进入下一个DATA状态前复位,或者top_module中的reset复位信号来到时复位。

由于DATA共有9比特,而只需输出8比特的data,因此在datapath中需要增加cnt<9的判断条件,防止奇偶校验位输出。

3、我的代码

module top_module(
    input clk,
    input in,
    input reset,    // Synchronous reset
    output [7:0] out_byte,
    output done
); 
	parameter IDLE = 4'b0001;
    parameter DATA = 4'b0010;
    parameter STOP = 4'b0100; 
    parameter WAIT = 4'b1000;
    reg [4:0] state, next_state;
    reg [3:0] cnt;
    reg [7:0] q;
    reg odd;
    
//state transition logic
    always @(*) begin 
        case(state)
            IDLE: next_state = in ? IDLE : DATA;
            DATA: next_state = (cnt==10) ? (in ? STOP : WAIT) : DATA; 
            STOP: next_state = in ? IDLE : DATA;
            WAIT: next_state = in ? IDLE : WAIT;
            default: next_state = IDLE;
        endcase
    end
    
// state flip-flops
    always @(posedge clk) begin
        if(reset)
            state <= IDLE;
        else
            state <= next_state;
    end
    
// New: Add parity checking.
	reg reset_p;
    assign reset_p = (state==STOP) || reset || (state==IDLE);
    parity U1 (.clk(clk), .reset(reset_p), .in(in), .odd(odd));
    
//Output logic       
    assign done = (state==STOP) && ~odd; //使用~odd是因为把停止位的1也算进去了,因此只有odd=0时,done=1;
    assign out_byte = done ? q : 8'bx;
    
//counter    
    always@(posedge clk)begin
        if(reset)
            cnt<=0;
        else if(next_state==DATA) //next_state跟输入in是同步的,state相比于输入in则会延迟一个时钟
            cnt <= cnt + 1'b1; 
        else 
            cnt <= 0;
    end
    
// New: Datapath to latch input bits.
    always @(posedge clk) begin //增加一个8bits的register
        if(next_state==DATA && cnt<9) 
            q <= {in,q[7:1]};         /*由于是非阻塞赋值,先计算右边的值再更新左侧表达式的值,因此是cnt<9;
                                      若为cnt<10,则数据位的第一位会被右移移位出去,奇偶校验位占据数据位最高位,导致错误*/
    end

endmodule

相关推荐

  1. 【Framework系列】Framework系列介绍

    2023-12-10 17:34:02       15 阅读
  2. 设计模式系列文章

    2023-12-10 17:34:02       47 阅读

最近更新

  1. TCP协议是安全的吗?

    2023-12-10 17:34:02       16 阅读
  2. 阿里云服务器执行yum,一直下载docker-ce-stable失败

    2023-12-10 17:34:02       16 阅读
  3. 【Python教程】压缩PDF文件大小

    2023-12-10 17:34:02       15 阅读
  4. 通过文章id递归查询所有评论(xml)

    2023-12-10 17:34:02       18 阅读

热门阅读

  1. Python3 基本数据类型 ----20231209

    2023-12-10 17:34:02       31 阅读
  2. mysql中information_schema.tables字段说明

    2023-12-10 17:34:02       38 阅读
  3. GO设计模式——1、简单工厂模式(创建型)

    2023-12-10 17:34:02       36 阅读
  4. 开源软件:JumpServer、DataEase、MeterSphere

    2023-12-10 17:34:02       44 阅读
  5. 【周报2023.12.09】

    2023-12-10 17:34:02       42 阅读
  6. c++ 类和对象-封装意义一

    2023-12-10 17:34:02       38 阅读
  7. 用格里高利公式求给定精度的PI值

    2023-12-10 17:34:02       40 阅读
  8. Vue笔记(一)基础

    2023-12-10 17:34:02       42 阅读
  9. ReactNative如何调用自定义的原生模块

    2023-12-10 17:34:02       44 阅读
  10. python的列表list

    2023-12-10 17:34:02       40 阅读