8 - 状态机代码设计与仿真

8 - 状态机代码设计与仿真

串口数据接收

image-20211122144750606

波特率 VS 比特率:

在信息传输通道中,携带数据信息的信号单元叫码元。

每秒钟通过信道传输的码元数称为码元传输速率,简称波特率。波特率是传输通道频宽的指标。

每秒钟通过信道传输的信息量称为位传输速率,简称比特率。比特率表示有效数据的传输速率。

比特率 = 波特率 * 单个调制状态对应的二进制位数。

image-20211122144808493

UART:串行接口是指数据在有限的几个 IO 上按照顺序,一位一位的进行传输。这类有很多:UART、IIC、SPI、CAN、USB 等等,只要是串行传输的接口,都是串口的一种。但是由于早期人们都习惯把 UART 口称为串口,导致很多人都习惯了说串口的时候特指 UART 口。

image-20211122144835386

image-20211122144856998

识别空闲:可以连续收到 12 个 1。

起始位:等下降沿——反向延时之后相与,有脉冲。

代码:

//2021.11.22 lyw
//Serial port data receiving
`timescale 1ns/10ps
module UART_RXer (
                clk,
                res,
                RX,
                data_out,
                en_data_out
);
input           clk;
input           res;
input           RX;
output[7:0]     data_out;   //Receive byte input
output          en_data_out;    //Output enable

reg [7:0]       state;      //Main state machine
reg [12:0]      con;        //count Bit width
//24000000/4800=5000; 1.5*5000=7500=0001_1101_0100_1100 need 13 bits
reg [3:0]       con_bits;   //count bits
reg             RX_delay;   //relay of RX
reg [7:0]       data_out;
reg             en_data_out;

always @(posedge clk or negedge res) begin
    if(~res) begin
        state<=0;
        con<=0;
        con_bits<=0;
        RX_delay<=0;
        data_out<=0;
        en_data_out<=0;
    end
    else begin
        RX_delay<=RX;
        case(state)
        0://wait free
        begin               
            if (con==5000-1) begin
                con<=0;
            end
            else begin
                con<=con+1;
            end
            
            if (con==0) begin
                if (RX) begin
                    con_bits<=con_bits+1;
                end
                else begin
                    con_bits<=0;
                end
            end
        
            if (con_bits==12) begin
                state<=1;
            end
        end

        1://wait start
        begin
            en_data_out<=0;
            if (~RX&RX_delay) begin
                state<=2;
            end
        end
        2://receive b0
        begin
            if (con==7500-1) begin//wait 1.5T
                con<=0;
                data_out[0]<=RX;
                state<=3;
            end
            else begin
                con<=con+1;
            end
        end
        3://receive b1
        begin
            if (con==5000-1) begin//wait 1T
                con<=0;
                data_out[1]<=RX;
                state<=4;
            end
            else begin
                con<=con+1;
            end
        end
        4://receive b2
        begin
            if (con==5000-1) begin//wait 1T
                con<=0;
                data_out[2]<=RX;
                state<=5;
            end
            else begin
                con<=con+1;
            end
        end
        5://receive b3
        begin
            if (con==5000-1) begin//wait 1T
                con<=0;
                data_out[3]<=RX;
                state<=6;
            end
            else begin
                con<=con+1;
            end
        end
        6://receive b4
        begin
            if (con==5000-1) begin//wait 1T
                con<=0;
                data_out[4]<=RX;
                state<=7;
            end
            else begin
                con<=con+1;
            end
        end
        7://receive b5
        begin
            if (con==5000-1) begin//wait 1T
                con<=0;
                data_out[5]<=RX;
                state<=8;
            end
            else begin
                con<=con+1;
            end
        end
        8://receive b6
        begin
            if (con==5000-1) begin//wait 1T
                con<=0;
                data_out[6]<=RX;
                state<=9;
            end
            else begin
                con<=con+1;
            end
        end
        9://receive b7
        begin
            if (con==5000-1) begin//wait 1T
                con<=0;
                data_out[7]<=RX;
                state<=10;
            end
            else begin
                con<=con+1;
            end
        end
        10://Generate enable pulse
        begin
            en_data_out<=1;
            state<=1;
        end

        default:
        begin
            state<=0;
            con<=0;
            con_bits<=0;
            RX_delay<=0;
            data_out<=0;
            en_data_out<=0;          
        end

        endcase
    end
end

endmodule

//-----testbench of UART_RXer-----
module UART_RXer_tb ;
//Same name instantiation
reg                 clk,res;
reg                 RX;
wire [7:0]          data_out;
wire                en_data_out;
    
reg [25:0]          RX_send;    //Equipped with serial byte to send data
reg [12:0]			    con;

always @* begin
   RX=RX_send[0];
end

//Connect RX
//assign              RX=RX_send[0];


UART_RXer UART_RXer (
                    clk,
                    res,
                    RX,
                    data_out,
                    en_data_out
);
initial begin
                    clk<=0;res<=0;con<=0;
                    RX_send<={1'b1,8'haa,1'b0,16'hffff};
        #17         res<=1;
        #4000000    $stop;   
end

always #5 clk=~clk;

always @(posedge clk) begin
    if(con==5000-1) begin
        con<=0;
    end
    else begin
        con<=con+1;
    end

    if (con==0) begin
        RX_send[24:0]<=RX_send[25:1];
        RX_send[25]<=RX_send[0];
    end
end


endmodule

tips:

一定义了寄存器就要想复位。

同名例化:名字必须相同,不用打点加括号,当例化很多个时需要用异名例化。

关键:

RX_delay<=RX; RX_delay 用上一个时钟的 RX 来表示,自带延时意义。

原因:在时钟沿赋值而不是直接 assign 赋值的,所以 RX_delay 就比 RX 晚了一个时钟周期。

产生使能信号就是冒个尖。

串口发送—>右移,循环右移的实现方式:RX_send[24:0]<=RX_send[25:1]; RX_send[25]<=RX_send[0];

RX_send[0] 不会被覆盖,因为非阻塞赋值语句是并行的

仿真波形:

image-20211122214313932

image-20211123164851702

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值