• 首页 首页 icon
  • 工具库 工具库 icon
    • IP查询 IP查询 icon
  • 内容库 内容库 icon
    • 快讯库 快讯库 icon
    • 精品库 精品库 icon
    • 问答库 问答库 icon
  • 更多 更多 icon
    • 服务条款 服务条款 icon

FPGA-串口通信

武飞扬头像
学习云玩家
帮助1

串口通信概念

学新通
学新通
学新通
学新通

UART通信原理

UART (universal asynchronous receiver-transmitter)是一种采用异步串行通信方式的通用异步收发传输器;它在发送数据时将并行数据转换成串行数据来传输,在接收数据时将接收到的串行数据转换成并行数据。UART串口通信需要两根信号线来实现,一根用于发送,另外一根接收(表明是异步全双工通信)。

①协议层:通信协议(包括数据格式、传输速率等)。

②物理层:接口类型、电平标准等。

协议层:数据格式,一帧数据由4部分组成(用代码设计串口用到的就是协议层):

·起始位( 1bit)

·数据位(6/7/8bit)

·奇偶校验位(1bit)

·停止位(1bit/1.5bit/2bit)

起始位,数据位,停止位是必要的。

数据位的数据高位在后,低位在前,从左只有从低到高,即bit[0]至bit[n].

学新通

协议层:传输速率

串口通信的速率用波特率表示,它表示每秒传输二进制数据的位数,

单位是bit/s (位/秒),简称bps;

常用的波特率有9600、19200、 38400、 57606以 及115200等。

物理层:接口类型、电平标准串口电平标准:

.TTL电平的串口(3.3V)

·RS232电平的串口( 5~ 12V为低电平,-12~-5V为高电平)

串口按电气标准分包括:

·RS-232-C:TXD/RXD/GND、15米/9600bps

·RS-422:TX /TX-/RX /RX-/GND

.RS485:A/B/G 、1200米/9600bps

学新通

数据传输(串口回环)整体框架:

数据传输时,串行数据经过接收端进行串转并的处理变为并行数据,再经过发送端并转串处理传输串行数据。

学新通

起始位检测

学新通

首先找到起始位才能开始数据接收(检测下降沿,进行同步打拍;检测下降沿时为r0低电平,r1高电平)

ps:为什么要做同步?因为传输过程中是没有时钟信号的,首先需要将其与时钟边沿同步,然后打拍检测边沿

起始位传输占据1bit,求波特率为9600传输1bit需要的时钟周期,即起始位所占用的时间,计算方法为:链接(https://blog.csdn.net/weixin_45388202/article/details/116465712),需要计数大约5208次。

学新通

数据位传输

传输一帧数据的数据位如图所示:

学新通

从低位到高位传输,所以数据位数据为11111001.

接收端RX

rx_data接收数据进行中间采样(中间信号稳定),如果接收的时候检测到了下降沿但采样的起始位为1(接收数据包含了起始位),说明rxd可能产生了抖动过后又回到高电平,因此需要进行判断其是否为起始位,采样到1说明产生了抖动,此时将bit计数器清零,rx_data不是有效数据不能作为输出。

输入串行数据rxd,进入FPGA后,一帧数据里包含停止位和起始位,但只有数据位这8位是需要的有效数据。

接收端设计文件:

  1. 输入串行数据rxd,输出8位数据rx_data,加入标志信号rx_data_vld判断输出的rx_data是否为8位数据位,是则有效。

  1. 对rxd进行同步打拍,边沿检测下降沿(起始位为一帧数据的开始)

  1. 定义参数及信号,flag为接收一帧数据的标志信号,作为开启bps计数器的标志,即在一帧数据到来时,起始位检测下降沿bps计数器开启计数flag拉高,记完1bit后end_cnt_bps拉高结束这一比特计时,此处flag则拉低。除开end_cnt_bps的其他时刻均保持flag拉高,知道最后1bit数据传输完毕。

  1. 对于end_cnt_bit = add_cnt_bit && (cnt_bit == 9 || data_in[0]),它必须满足计数完第十个bit或者起始位data_in[0]为1,此时才是bit结束计数标志,两钟情况满足任一即可。

  1. 进行数据采样时最好是选择之间的稳定信号,为什么加入data_in信号?我的理解是此信号是经过串行信号通过FPGA进行并行处理,但我们只需要数据位的8位有效信号,因此需要对有效信号进行提取做准备

  1. 将有效数据位数据赋予rx_data,并进行是否是有效数据的判断,判断条件结束bit计数和存在起始位必须同时满足,这样才能有一帧完整的10bit数据,然后去除的data_in[8:1]中间的8位数据才是数据位信息。

  1.  
    module uart_rx (
  2.  
    input clk ,
  3.  
    input rst_n ,
  4.  
    input rxd ,//输入串行数据
  5.  
     
  6.  
    output reg [7:0] rx_data ,
  7.  
    output reg rx_data_vld//判断标志信号,判断rx_data的数据是否有效
  8.  
    );
  9.  
    //参数定义
  10.  
    parameter BPS_9600 = 5208 ;
  11.  
     
  12.  
    //信号定义
  13.  
    reg rx_r0 ;
  14.  
    reg rx_r1 ;
  15.  
     
  16.  
    wire nedge ;//检测起始位
  17.  
     
  18.  
    reg [12:0] cnt_bps ;//计数1bit时钟周期
  19.  
    wire add_cnt_bps ;
  20.  
    wire end_cnt_bps ;
  21.  
    reg flag ;//接收标志
  22.  
     
  23.  
    reg [3:0] cnt_bit ;//计数bit数
  24.  
    wire add_cnt_bit ;
  25.  
    wire end_cnt_bit ;
  26.  
     
  27.  
    reg [9:0] data_in ;//一帧数据,起始位(1bit),数据位(8bit),停止位(1bit)
  28.  
    //进行串并转换
  29.  
     
  30.  
    //同步,打拍,边沿检测
  31.  
    always @(posedge clk or negedge rst_n) begin
  32.  
    if (!rst_n) begin
  33.  
    rx_r0 <= 1'b1 ;
  34.  
    rx_r1 <= 1'b1 ;
  35.  
    end
  36.  
    else begin
  37.  
    rx_r0 <= rxd ;//同步数据
  38.  
    rx_r1 <= rx_r0 ;//打拍
  39.  
    end
  40.  
    end
  41.  
     
  42.  
    assign nedge = rx_r1 & ~rx_r0 ;//下降沿检测
  43.  
     
  44.  
    //flag
  45.  
    always @(posedge clk or negedge rst_n) begin
  46.  
    if (!rst_n) begin
  47.  
    flag <= 1'b0 ;
  48.  
    end
  49.  
    else if(nedge) begin
  50.  
    flag <= 1'b1 ;
  51.  
    end
  52.  
    else if(end_cnt_bit) begin
  53.  
    flag <= 1'b0;
  54.  
    end
  55.  
    end
  56.  
     
  57.  
    //cnt_bps
  58.  
    always @(posedge clk or negedge rst_n) begin
  59.  
    if (!rst_n) begin
  60.  
    cnt_bps <= 'd0;
  61.  
    end
  62.  
    else if (add_cnt_bps) begin
  63.  
    if (end_cnt_bps) begin
  64.  
    cnt_bps <= 'd0 ;
  65.  
    end
  66.  
    else begin
  67.  
    cnt_bps <= cnt_bps 1'b1 ;
  68.  
    end
  69.  
    end
  70.  
    end
  71.  
     
  72.  
    assign add_cnt_bps = flag ;
  73.  
    assign end_cnt_bps = add_cnt_bps && (cnt_bps == BPS_9600 - 1) ;
  74.  
     
  75.  
     
  76.  
     
  77.  
    //cnt_bit
  78.  
    always @(posedge clk or negedge rst_n) begin
  79.  
    if (!rst_n) begin
  80.  
    cnt_bit <= 'd0;
  81.  
    end
  82.  
    else if (add_cnt_bit) begin
  83.  
    if (end_cnt_bit) begin
  84.  
    cnt_bit <= 'd0 ;
  85.  
    end
  86.  
    else begin
  87.  
    cnt_bit <= cnt_bit 1'b1 ;
  88.  
    end
  89.  
    end
  90.  
    end
  91.  
     
  92.  
    assign add_cnt_bit = end_cnt_bps ;
  93.  
    assign end_cnt_bit = add_cnt_bit && (cnt_bit == 9 || data_in[0]) ;//data_in[0]是存的起始位
  94.  
     
  95.  
    //data_in采样数据(包含起始位和停止位)
  96.  
    always @(posedge clk or negedge rst_n) begin
  97.  
    if (!rst_n) begin
  98.  
    data_in <= 0;
  99.  
    end
  100.  
    else if (cnt_bps == BPS_9600 >> 1) begin//为了稳定采样中间的值
  101.  
    data_in[cnt_bit] <= rx_r1 ;
  102.  
    end
  103.  
    end
  104.  
     
  105.  
    //取数据位rx_data
  106.  
    always @(posedge clk or negedge rst_n) begin
  107.  
    if (!rst_n) begin
  108.  
    rx_data <= 0 ;
  109.  
    end
  110.  
    else if (end_cnt_bit) begin
  111.  
    rx_data <= data_in[8:1] ;//只需要给数据位
  112.  
    end
  113.  
    else begin
  114.  
    rx_data <= 0 ;
  115.  
    end
  116.  
    end
  117.  
     
  118.  
    //判断rx_data是否有效
  119.  
    always @(posedge clk or negedge rst_n) begin
  120.  
    if (!rst_n) begin
  121.  
    rx_data_vld <= 0 ;
  122.  
    end
  123.  
    else begin
  124.  
    rx_data_vld <= end_cnt_bit && (data_in[0] == 0);
  125.  
    end
  126.  
    end
  127.  
     
  128.  
     
  129.  
    endmodule
学新通

接收端测试文件:

定义系统时钟周期,例化模块,产生时钟,上电复位并赋予初值,然后分配起始位,数据位,停止位并进行延时处理。

  1.  
    `timescale 1ns/1ps
  2.  
    module tb_uart_rx ();
  3.  
    reg clk ;
  4.  
    reg rst_n ;
  5.  
    reg rxd ;
  6.  
     
  7.  
    wire [7:0] rx_data ;
  8.  
    wire rx_data_vld ;
  9.  
     
  10.  
    //参数定义
  11.  
    parameter CYCLE = 20 ;
  12.  
     
  13.  
    //例化
  14.  
    uart_rx u_uart_rx(
  15.  
    .clk (clk ),
  16.  
    .rst_n (rst_n ),
  17.  
    .rxd (rxd ),
  18.  
    .rx_data (rx_data ),
  19.  
    .rx_data_vld (rx_data_vld)
  20.  
    );
  21.  
     
  22.  
    //时钟
  23.  
    initial begin
  24.  
    clk = 1'b1 ;
  25.  
    forever begin
  26.  
    #(CYCLE/2);
  27.  
    clk = ~clk ;
  28.  
    end
  29.  
    end
  30.  
     
  31.  
    integer i;//数据个数
  32.  
     
  33.  
    initial begin
  34.  
    rst_n = 1'b1 ;
  35.  
    #(CYCLE);
  36.  
    rst_n = 1'b0 ;
  37.  
    rxd = 1'b1 ;
  38.  
    #22;
  39.  
    rst_n = 1'b1 ;
  40.  
     
  41.  
    #(CYCLE*200);
  42.  
     
  43.  
    //模拟一帧数据的格式
  44.  
    rxd = 1'b0 ;//起始位
  45.  
    #(CYCLE*5208);
  46.  
     
  47.  
    //数据位
  48.  
    for (i=0;i<8;i=i 1) begin
  49.  
    case (i)//赋值rxd = 1111_1001
  50.  
    1: rxd = 1'b0 ;
  51.  
    2: rxd = 1'b0 ;
  52.  
    default: rxd = 1'b1 ;//只有第一位和第二位为0
  53.  
    endcase
  54.  
    #(CYCLE*5208);
  55.  
    end
  56.  
     
  57.  
    rxd = 1'b1 ;//停止位
  58.  
    #(CYCLE*5208);
  59.  
     
  60.  
    #(CYCLE*200);
  61.  
    $stop;
  62.  
    end
  63.  
    endmodule
学新通

仿真

test.do文件:

  1.  
    vlib work
  2.  
    vmap work work
  3.  
     
  4.  
    #编译testbench文件
  5.  
    vlog tb_uart_rx.v
  6.  
    #编译 设计文件
  7.  
    vlog ../rtl/uart_rx.v
  8.  
     
  9.  
     
  10.  
    #vlog altera_mf.v
  11.  
     
  12.  
     
  13.  
    #指定仿真顶层
  14.  
    vsim -novopt work.tb_uart_rx
  15.  
    #添加信号到波形窗
  16.  
    add wave -position insertpoint sim:/tb_uart_rx//*
  17.  
     
  18.  
    run -all
学新通
学新通
学新通
学新通
学新通
学新通

观测到最后8位数据位为1111_1001符合要求。

疑问

此处没有理解透彻5802为啥右移一位就变成中间部分的数据了?将打拍的数据赋予data_in内部为什么应bit计数器表示?

答:右移一个一个地位相当于除以2,符合在中间值采样原则

学新通

发送端TX

学新通

发送端设计文件:

和发送端类似,由上设计框图

  1. 输入并行信号tx_data,将rx_data的数据传输给它,tx_data_vld为传输8位数据位有效信号标志,输出串行数据txd

  1. 必须保持波特率一致,定义参数

  1. flag在这里作为发送数据标志,同时也是计时器bps的开启条件,其在数据有效时拉高进行发送,所有bit的数据发送完后拉低

  1. 同样用data_out寄存一帧10bit的数据(并行数据),通过发送端转化为串行数据,在数据发送有效时,添加起始位和停止位赋值于它进行寄存

  1. 输出串行数据txd,仅在发送数据标志flag拉高时发送数据,数据来自于寄存于data_out的10bit并行数据。

  1.  
    module uart_tx (
  2.  
    input clk ,
  3.  
    input rst_n ,
  4.  
    input [7:0] tx_data ,
  5.  
    input tx_data_vld ,//发送有效信号标志
  6.  
     
  7.  
    output reg txd
  8.  
    );
  9.  
    //参数定义
  10.  
    parameter BPS_9600 = 5208 ;
  11.  
     
  12.  
    //信号定义
  13.  
     
  14.  
    reg [12:0] cnt_bps ;//计数1bit时钟周期
  15.  
    wire add_cnt_bps ;
  16.  
    wire end_cnt_bps ;
  17.  
    reg flag ;//发送数据标志,同时也是bps计数的开启条件
  18.  
     
  19.  
    reg [3:0] cnt_bit ;//计数bit数
  20.  
    wire add_cnt_bit ;
  21.  
    wire end_cnt_bit ;
  22.  
     
  23.  
    reg [9:0] data_out ;
  24.  
     
  25.  
    //flag
  26.  
    always @(posedge clk or negedge rst_n) begin
  27.  
    if (!rst_n) begin
  28.  
    flag <= 1'b0 ;
  29.  
    end
  30.  
    else if(tx_data_vld) begin //在发送有效信号时,flag作为标志拉高
  31.  
    flag <= 1'b1 ;
  32.  
    end
  33.  
    else if(end_cnt_bit) begin//bit计数结束时,flag拉低
  34.  
    flag <= 1'b0;
  35.  
    end
  36.  
    end
  37.  
     
  38.  
    //cnt_bps
  39.  
    always @(posedge clk or negedge rst_n) begin
  40.  
    if (!rst_n) begin
  41.  
    cnt_bps <= 'd0;
  42.  
    end
  43.  
    else if (add_cnt_bps) begin
  44.  
    if (end_cnt_bps) begin
  45.  
    cnt_bps <= 'd0 ;
  46.  
    end
  47.  
    else begin
  48.  
    cnt_bps <= cnt_bps 1'b1 ;
  49.  
    end
  50.  
    end
  51.  
    end
  52.  
     
  53.  
    assign add_cnt_bps = flag ;
  54.  
    assign end_cnt_bps = add_cnt_bps && (cnt_bps == BPS_9600 - 1) ;
  55.  
     
  56.  
     
  57.  
     
  58.  
    //cnt_bit
  59.  
    always @(posedge clk or negedge rst_n) begin
  60.  
    if (!rst_n) begin
  61.  
    cnt_bit <= 'd0;
  62.  
    end
  63.  
    else if (add_cnt_bit) begin
  64.  
    if (end_cnt_bit) begin
  65.  
    cnt_bit <= 'd0 ;
  66.  
    end
  67.  
    else begin
  68.  
    cnt_bit <= cnt_bit 1'b1 ;
  69.  
    end
  70.  
    end
  71.  
    end
  72.  
     
  73.  
    assign add_cnt_bit = end_cnt_bps ;
  74.  
    assign end_cnt_bit = add_cnt_bit && (cnt_bit == 9) ;
  75.  
     
  76.  
    //寄存数据至data_out(包含起始位和停止位)
  77.  
    always @(posedge clk or negedge rst_n) begin
  78.  
    if (!rst_n) begin
  79.  
    data_out <= 0;
  80.  
    end
  81.  
    else if (tx_data_vld) begin
  82.  
    data_out <= {1'b1,tx_data,1'b0} ;
  83.  
    end
  84.  
    end
  85.  
     
  86.  
    //输出txd
  87.  
    always @(posedge clk or negedge rst_n) begin
  88.  
    if (!rst_n) begin
  89.  
    txd <= 1'b1 ;
  90.  
    end
  91.  
    else if (flag) begin
  92.  
    txd <= data_out[cnt_bit] ;
  93.  
    end
  94.  
    end
  95.  
     
  96.  
    endmodule
学新通

发送端测试文件:

只需要加上接收端的例化模块即可,中间信号端口互通,在最后再增加10bit的周期延迟。

学新通
学新通
  1.  
    `timescale 1ns/1ps
  2.  
    module tb_uart_rx ();
  3.  
    reg clk ;
  4.  
    reg rst_n ;
  5.  
    reg rxd ;
  6.  
     
  7.  
    wire [7:0] rx_data ;
  8.  
    wire rx_data_vld ;
  9.  
     
  10.  
    //参数定义
  11.  
    parameter CYCLE = 20 ;
  12.  
     
  13.  
    //例化
  14.  
    uart_rx u_uart_rx(
  15.  
    .clk (clk ),
  16.  
    .rst_n (rst_n ),
  17.  
    .rxd (rxd ),
  18.  
    .rx_data (rx_data ),
  19.  
    .rx_data_vld (rx_data_vld)
  20.  
    );
  21.  
     
  22.  
    uart_tx u_uart_tx(
  23.  
    .clk (clk ) ,
  24.  
    .rst_n (rst_n ) ,
  25.  
    .tx_data (rx_data ) ,
  26.  
    .tx_data_vld (rx_data_vld) ,
  27.  
     
  28.  
    .txd (txd )
  29.  
    );
  30.  
     
  31.  
    //时钟
  32.  
    initial begin
  33.  
    clk = 1'b1 ;
  34.  
    forever begin
  35.  
    #(CYCLE/2);
  36.  
    clk = ~clk ;
  37.  
    end
  38.  
    end
  39.  
     
  40.  
    integer i;//数据个数
  41.  
     
  42.  
    initial begin
  43.  
    rst_n = 1'b1 ;
  44.  
    #(CYCLE);
  45.  
    rst_n = 1'b0 ;
  46.  
    rxd = 1'b1 ;
  47.  
    #22;
  48.  
    rst_n = 1'b1 ;
  49.  
     
  50.  
    #(CYCLE*200);//增加间隔
  51.  
     
  52.  
    //模拟一帧数据的格式
  53.  
    rxd = 1'b0 ;//起始位
  54.  
    #(CYCLE*5208);
  55.  
     
  56.  
    //数据位
  57.  
    for (i=0;i<8;i=i 1) begin
  58.  
    case (i)//赋值rxd = 1111_1001
  59.  
    1: rxd = 1'b0 ;
  60.  
    2: rxd = 1'b0 ;
  61.  
    default: rxd = 1'b1 ;//只有第一位和第二位为0
  62.  
    endcase
  63.  
    #(CYCLE*5208);
  64.  
    end
  65.  
     
  66.  
    rxd = 1'b1 ;//停止位
  67.  
    #(CYCLE*5208);
  68.  
     
  69.  
    #(CYCLE*200);//增加间隔
  70.  
     
  71.  
    #(CYCLE*10*5208);//10bit时钟周期延迟
  72.  
     
  73.  
     
  74.  
    $stop;
  75.  
    end
  76.  
    endmodule
学新通

仿真

test.do文件

  1.  
    vlib work
  2.  
    vmap work work
  3.  
     
  4.  
    #编译testbench文件
  5.  
    vlog tb_uart_rx.v
  6.  
    #编译 设计文件
  7.  
    vlog ../rtl/uart_rx.v
  8.  
    vlog ../rtl/uart_tx.v
  9.  
     
  10.  
     
  11.  
    #vlog altera_mf.v
  12.  
     
  13.  
     
  14.  
    #指定仿真顶层
  15.  
    vsim -novopt work.tb_uart_rx
  16.  
    #添加信号到波形窗
  17.  
    add wave -position insertpoint sim:/tb_uart_rx//*
  18.  
     
  19.  
    run -all
学新通
学新通
学新通
学新通

顶层仿真

只需要改动例化模块即可

  1.  
    `timescale 1ns/1ps
  2.  
    module tb_uart ();
  3.  
    reg clk ;
  4.  
    reg rst_n ;
  5.  
    reg rxd ;
  6.  
     
  7.  
    wire txd ;
  8.  
     
  9.  
    //参数定义
  10.  
    parameter CYCLE = 20 ;
  11.  
     
  12.  
    //例化
  13.  
    uart u_uart(
  14.  
    .clk (clk ),
  15.  
    .rst_n (rst_n),
  16.  
    .rxd (rxd ),
  17.  
     
  18.  
    .txd (txd )
  19.  
    );
  20.  
     
  21.  
    //时钟
  22.  
    initial begin
  23.  
    clk = 1'b1 ;
  24.  
    forever begin
  25.  
    #(CYCLE/2);
  26.  
    clk = ~clk ;
  27.  
    end
  28.  
    end
  29.  
     
  30.  
    integer i;//数据个数
  31.  
     
  32.  
    initial begin
  33.  
    rst_n = 1'b1 ;
  34.  
    #(CYCLE);
  35.  
    rst_n = 1'b0 ;
  36.  
    rxd = 1'b1 ;
  37.  
    #22;
  38.  
    rst_n = 1'b1 ;
  39.  
     
  40.  
    #(CYCLE*200);//增加间隔
  41.  
     
  42.  
    //模拟一帧数据的格式
  43.  
    rxd = 1'b0 ;//起始位
  44.  
    #(CYCLE*5208);
  45.  
     
  46.  
    //数据位
  47.  
    for (i=0;i<8;i=i 1) begin
  48.  
    case (i)//赋值rxd = 1111_1001
  49.  
    1: rxd = 1'b0 ;
  50.  
    2: rxd = 1'b0 ;
  51.  
    default: rxd = 1'b1 ;//只有第一位和第二位为0
  52.  
    endcase
  53.  
    #(CYCLE*5208);
  54.  
    end
  55.  
     
  56.  
    rxd = 1'b1 ;//停止位
  57.  
    #(CYCLE*5208);
  58.  
     
  59.  
    #(CYCLE*200);//增加间隔
  60.  
     
  61.  
    #(CYCLE*10*5208);//10bit时钟周期延迟
  62.  
     
  63.  
     
  64.  
    $stop;
  65.  
    end
  66.  
    endmodule
学新通

仿真图

学新通
学新通

另外一种测试方法:

用FPGA的tx端去模拟PC端的tx端发送数据,然后FPGA接收端rx进行接收

学新通

代码:

直接建立task发送三个数据

学新通
学新通
  1.  
    `timescale 1ns/1ps
  2.  
    module tb_uart1 ();
  3.  
    reg clk ;
  4.  
    reg rst_n ;
  5.  
    reg [7:0] data ;
  6.  
    reg data_vld ;
  7.  
     
  8.  
    wire dout ; //中间连线
  9.  
    wire txd ;//tx输出
  10.  
     
  11.  
    //参数定义
  12.  
    parameter CYCLE = 20 ;
  13.  
     
  14.  
    //例化
  15.  
    uart_tx u_uart_tx(
  16.  
    .clk (clk ) ,
  17.  
    .rst_n (rst_n ) ,
  18.  
    .tx_data (data ) ,
  19.  
    .tx_data_vld (data_vld) ,
  20.  
     
  21.  
    .txd (dout )
  22.  
    );
  23.  
     
  24.  
    uart u_uart(
  25.  
    .clk (clk ),
  26.  
    .rst_n (rst_n ),
  27.  
    .rxd (dout ),
  28.  
     
  29.  
    .txd (txd )
  30.  
    );
  31.  
     
  32.  
    //时钟
  33.  
    initial begin
  34.  
    clk = 1'b1 ;
  35.  
    forever begin
  36.  
    #(CYCLE/2);
  37.  
    clk = ~clk ;
  38.  
    end
  39.  
    end
  40.  
     
  41.  
     
  42.  
    initial begin
  43.  
    rst_n = 1'b1 ;
  44.  
    #(CYCLE);
  45.  
    rst_n = 1'b0 ;
  46.  
    data = 0 ;
  47.  
    data_vld = 1'b0 ;
  48.  
    #22;
  49.  
    rst_n = 1'b1 ;
  50.  
    #(CYCLE*200);//增加间隔
  51.  
     
  52.  
    //发送几个数据
  53.  
    Send(8'hf9);
  54.  
    Send(8'ha0);
  55.  
    Send(8'hff);
  56.  
     
  57.  
    #(CYCLE*10*5208);//10bit时钟周期延迟
  58.  
    #(CYCLE*200);
  59.  
    $stop;
  60.  
    end
  61.  
     
  62.  
    task Send;
  63.  
    input [7:0] send_data ;
  64.  
    begin
  65.  
    data = send_data ;
  66.  
    data_vld = 1'b1 ;
  67.  
    #(CYCLE);
  68.  
    data_vld = 1'b0 ;
  69.  
    #(10*5208*CYCLE);
  70.  
    end
  71.  
    endtask
  72.  
     
  73.  
     
  74.  
     
  75.  
    endmodule
学新通
学新通
学新通

上板验证

能够在波特率为9600时进行发送和接收

学新通

这篇好文章是转载于:学新通技术网

  • 版权申明: 本站部分内容来自互联网,仅供学习及演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,请提供相关证据及您的身份证明,我们将在收到邮件后48小时内删除。
  • 本站站名: 学新通技术网
  • 本文地址: /boutique/detail/tanhgfahie
系列文章
更多 icon
同类精品
更多 icon
继续加载