要理解一段 RS232 的传输程序,需要首先搞清楚 RS232 发送和接收端各进行了哪些操作以及
发送和接收的数据是哪些?RTL 代码行为级结构划分示意图如下所示:
RS23 说明文档
(1)读版本寄存器(寄存器 0)
行为级结构划分示意图
此时的操作是先进行 Ubm_frame_deal.tx_frame({READ, 3’b0, addr}, tx_content);
此时,{READ, 3’b0, addr}=2’b10 + 3’b0 + 3’b0,tx_content=32’b0,任务 tx_frame 的具体操作
如下所示:
其 中 输 入 为 input [7:0] operation_code , input [31:0] content , SYN_WORD 为 8’h55 ,
FRAME_HEADER 为 8’hF1 , 则 [7:0] check_sum= 8’h55 + 8’hF1 +{2’b10 + 3’b0 +
3’b0}+content[31:24] +content[23:16]+…
Uharness.delay_n_clock(10000);
,
为
Uharness.Ubfm_uart.uart_tx(SYN_WORD)为发送 8’h55 的 8bit 数据,其中 uart_tx 的发送代码
如下:
10000
sysclk
延
迟
个
#duration 为 assign duration = `SEC/`BAUD_RATE=10 的 9 次方/115_200,然后每隔 10000 个
SYSCLK 依次发送 FRAME_HEADER(8’hf1)、operation_code({2’b10 + 3’b0 + 3’b0})、content[31:24]
( tx_content[31:24] ) …check_sum , 如 图 所 示 为 发 送 帧 格 式 , 对 应 的 task 为
Ubm_frame_deal.tx_frame({READ, 3’b0, addr}, tx_content):
然后进行的操作是 Ubm_frame_deal.rx_frame(rx_content),其中 rx_frame 的定义为:
如 上 图 所 示 , 主 要 的 功 能 实 现 是 由 Uharness.Ubfm_uart.uart_rx(rx_data) 实 现 的 ,
uart_rx(rx_data)的具体实现为:
其中,接收的时序是检测 rs232_dout 的低电平,然后延迟一个半 duration 开始检测,但是
在仿真过程中发现,rs232 模块的波特率并不等于 115_200,其波特率为 120_076,接收时
序为,对应的 task 为 Ubm_frame_deal.rx_frame(rx_content):
如 下 图 所 示 , 为 对 寄 存 器 1 操 作 的 步 骤 , 首 先 用
Ubm_frame_deal.tx_frame({WRITE,3’b0,addr},tx_content)对寄存器 1 进行写操作,写入数据
8’hFF,然后用 Ubm_frame_deal.tx_frame({WRITE,3’b0,addr},tx_content)对寄存器 1 发出读操
作 指 令 , 之 后 用 Ubm_frame_deal.rx_frame(rx_content) 读 出 当 前 寄 存 器 1 中 的 数 据 ,
compare_result(rx_content,tx_content)用于作比较,输出比较结果:
模块 1:rxvr 模块
端口
clk
方向
in
源/目的
pin
rst_n
rs232_16xclk_en
rs232_din
uart_rxdata
uart_d_ready
in
in
in
out
out
rxvr 仿真时序图如下图所示:
描述
系 统 时 钟 , 该 仿 真 周 期 是 24ns , 频 率 是
41.67MHZ
外部系统复位
pin
clken_gen 周期为 22 个 clk,高电平为 1 个 clk 宽度的
pin
脉冲信号,间隔时间为 528ns
外 部 输 入 rs232 信 号 , 每 个 间 隔 时 间 是
8681ns
rx_frame 输出 8bit 数据
rx_frame 输出接收 8bit 数据完成信号,在接收完 8 个
bit 之后,在第 9 个 bit 的中间输出 ready 信
号
rs232_16xclk_en 为 clk 时钟的 22 分频,通过对 rs232_din 在 rs232_16xclk_en 的延迟,得到
rs232_din_d1、rs232_din_d2 的高低电平,从而得到 rs232_din 的下降沿,从而确定接收的起
始位置,设置 clk1x_enable 为高电平,在 clk1x_enable 为高电平情况下,对 rs232_16xclk_en
进 行 循 环 计 数 0~f , 当计 数 值 rs232_1xclk_en_cnt 为 7 且 rs232_16xclk_en 有 效 时 , 置 高
rs232_1xclk_en,rcvr_cnt 根据 rs232_1xclk_en 计数,此计数值作为采样值的标志和输出标志。
输出值 uart_rxdata 的采样过程如下:
输出标志 uart_d_ready 的配置过程如下:
在本程序中,实际的采样间隔是 16 个 rs232_16xclk_en 即 16*22 个 clk 的时间间隔为 8448ns,
115_200 波特率下的时间间隔是 8681ns。
模块 2:rx_frame 模块
端口
clk
方向
in
源/目的
pin
描述
系统时钟,该仿真周期是 24ns,频率是
41.67MHZ
rst_n
rs232_1xclk_en
uart_d_ready
in
in
in
rxvr
pin
clken_gen
外部系统复位
周期为 347 个 clk,高电平为 1 个 clk 宽度
的脉冲信号,间隔时间为 8328ns
输入接收 8bit 数据完成信号,在接收完 8
个 bit 之后,在第 9 个 bit 的中间输出 ready
信号
rx_frame
输入 8bit 数据
tx_frame
读数据使能
config_registers 写数据使能
config_registers 写寄存器地址
config_registers 写寄存器数据
uart_rxdata
read_cmd
write_cmd
config_addr
config_din
如下图所示,为 rx_frame 接收的状态机:
in
out
out
out
out
IDLE 状态:接收同步字;CHECK_HEADER:接收帧头;LOAD_OPERATION:接收操作码;
LOAD_DATA:接收 4byte 数据;VERIFICAE_CHECKSUM:接收校验码;
对寄存器地址为 3’b1 的寄存器先写入 32’hff,在读出地址为 3’b1 寄存器的值,仿真时序图
如下所示:
如 图 所 示 , 1/2/3/4/5 为 写 地 址 为 3’b1 的 寄 存 器 数 据 为 32’hff , 帧 格 式 为
,6/7/8/9/10 为发送读地址为 3’b1 的寄存器数据的命令,读
命令的写入与写数据的帧结构相同,11 为 rs232_dout 根据在 3’b1 写入的数据 32’hff,执行
读 命 令 , 完 成 读 取 地 址 为 3’b1 寄 存 器 的 数 据 过 程 , 11 过 程 的 帧 格 式 为
,由时序图可知,在 5 过程处,即完成校验和之后,rx_frame
输出 write_cmd 写有效信号至 config_registers 模块,此时 config_addr 与 config_din 对应写寄
存器的地址和写入数据。同时,在 10 过程处,即完成校验和之后,rx_frame 输出 read_cmd
读有效信号至 tx_frame 模块。
模块 3:config_registers 模块
端口
clk
rst_n
write_cmd
config_din
config_addr
config_dout
方向
in
源/目的
pin
in
in
in
in
out
pin
rx_frame
rx_frame
rx_frame
tx_frame
描述
系统时钟,该仿真周期是 24ns,频率是
41.67MHZ
外部系统复位
写入寄存器数据使能信号
写入寄存器数据
写入寄存器地址
读出寄存器数据
写入过程如下所示:
读出过程如下所示:
模块 4:tx_frame 模块
端口
clk
方向
in
源/目的
pin
rst_n
rs232_1xclk_en
in
in
pin
clken_gen
read_cmd
config_dout[31:0]
uart_txdata_en
uart_txdata[7:0]
如下图所示,为 tx_frame 接收的状态机:
tx_frame
config_registers
txmit
txmit
in
in
out
out
描述
系统时钟,该仿真周期是 24ns,频率是
41.67MHZ
外部系统复位
周期为 347 个 clk,高电平为 1 个 clk 宽
度的脉冲信号,间隔时间为 8328ns
读使能信号
config_registers 输出的寄存器数据
1BYTE 数据输出使能信号
1BYTE 数据输出
IDLE:初始状态;SEND_SYN_CODE:发送同步字状态;SEND_HEADER:发送帧头状态;
SEND_DATA:发送数据状态;SEND_CHECKSUM:发送校验码状态;其中,uart_txdata_en 的
值如下所示:
rs232_cnt 为非 IDLE 状态下,对 rs232_1xclk_en 进行计数,0 -> f -> 0 -> f…,即在非 IDLE 状态
下每隔 16 个 rs232_1xclk_en 进入下一个状态,然后,需要对 uart_txdata[7:0]进行赋值:
时序图如下所示:
模块 5:txmit 模块
txmit 模块实现的功能较为简单,主要是将 uart_txdata_en 使能信号和 8bit 的数据信号
uart_txdata 变成单 bit 依次输出。如下所示,send_enable 为确定发送数据的时序范围,
send_cnt 为进行发送数据 bit 位的计数依据,每个 bit 之间间隔为一个 rs232_1xclk_en。