基于VerilogHDL的RS-232串口通信在CPLD上的实现综述
verilog 逻辑函数 串口发送

verilog 逻辑函数串口发送摘要:1.Verilog 逻辑函数概述2.串口发送原理3.Verilog 实现串口发送的逻辑函数4.应用实例正文:【1.Verilog 逻辑函数概述】Verilog 是一种硬件描述语言,主要用于数字电路和模拟混合信号电路的描述。
它的语法简洁,易于理解和使用。
在数字电路设计中,逻辑函数是基本的构建模块,通过组合这些模块可以实现复杂的数字电路。
【2.串口发送原理】串口(Serial Port)是一种计算机硬件接口,可以通过串行通信传输数据。
发送数据时,数据被逐个比特按顺序传送,这样可以减少线路的传输次数,提高通信效率。
在电子设备中,如单片机、FPGA 等,通常会使用串口进行数据通信。
【3.Verilog 实现串口发送的逻辑函数】要实现串口发送功能,首先需要设计一个状态机,控制数据的发送过程。
下面是一个简单的Verilog 代码示例,实现一个8 位串口发送器:```verilogmodule serial_port_sender(input wire clk, // 时钟信号input wire rst_n, // 低电平复位信号input wire start, // 开始发送信号input wire [7:0] data, // 发送数据output wire busy // 忙碌信号);// 定义状态机typedef enum logic [1:0] {IDLE, SENDING} state_t; state_t current_state, next_state;always_ff @(posedge clk or negedge rst_n) begin if (!rst_n) begincurrent_state <= IDLE;end else begincurrent_state <= next_state;endendalways_comb begincase (current_state)IDLE: beginif (start &&!busy) beginnext_state = SENDING;endendSENDING: beginif (data == 8"b0000_0001) begin // 发送结束标志next_state = IDLE;end else begin// 发送数据busy = 1;next_state = SENDING;endendendcaseendendmodule```【4.应用实例】上述代码实现了一个简单的8 位串口发送器。
基于FPGA Verilog RS232串口回环测试例程,附源程序仿真源码及测试图片

FPGA Verilog RS232串口回环测试基于FPGA Verilog RS232串口回环测试例程,支持多byte数据传输,附源程序仿真源码及测试图片。
测试基于SSCOM/友善之臂上位机软件测试,测试结果如下图一图二所示。
图一SSCOM图二图三连续发送仿真截图图四连续接收仿真截图后附verilog源程序代码及testbech仿真例程,注释欠。
重点:多byte回环测试要点,上位机串口多位数据连续发送停止位和起始位之间无间隔,回环程序在接收和发送都需要具备在停止位后能立马跳转到下一个起始位的能力。
重点关注cnt_bit的处理方式。
附录1 顶层例化uart_txd uart_txd(.clk_50m(sys_clk_50m),.reset_n(sys_rst_n),.tx_data(rx_data),.baud_set(3'd4),.send_en(rx_done),.send_done(),.send_busy(send_busy),.uart_tx(uart_tx));uart_rxd uart_rxd(.clk_50m(sys_clk_50m),.reset_n(sys_rst_n),.rx_data(rx_data),.baud_set(3'd4),.rx_done(rx_done),.rx_busy(rx_busy),.uart_rx(uart_rx));附录2 串口发送源程序`timescale1ns/1ps///////////////////////////////////////////////////////////////////// /////////////// Company:// Engineer://// Create Date: 2020/06/21 09:45:23// Design Name:// Module Name: uart_txd// Project Name:// Target Devices:// Tool Versions:// Description://// Dependencies:// Revision:// Revision 0.01 - File Created// Additional Comments://///////////////////////////////////////////////////////////////////// /////////////module uart_txd(clk_50m,reset_n,tx_data,baud_set,send_en,send_done,send_busy,uart_tx);input clk_50m;input reset_n;input[7:0] tx_data;input[2:0] baud_set;input send_en;output reg send_done;output reg send_busy;output reg uart_tx;reg[12:0] cnt;reg[12:0] baud_rate_cnt_max;reg[3:0] cnt_bit;reg[7:0] tx_data_r;localparam baud_rate_9600 =13'd5207;localparam baud_rate_19200 =13'd2603;localparam baud_rate_38400 =13'd1301;localparam baud_rate_57600 =13'd867;localparam baud_rate_115200 =13'd433;always@(posedge clk_50m or negedge reset_n)if(!reset_n)baud_rate_cnt_max <= baud_rate_115200;elsecase(baud_set)3'd0:baud_rate_cnt_max = baud_rate_9600;3'd1:baud_rate_cnt_max = baud_rate_19200;3'd2:baud_rate_cnt_max = baud_rate_38400;3'd3:baud_rate_cnt_max = baud_rate_57600;3'd4:baud_rate_cnt_max = baud_rate_115200;default:baud_rate_cnt_max = baud_rate_115200;endcasealways@(posedge clk_50m or negedge reset_n)if(!reset_n)tx_data_r <=8'd0;else if(send_en)tx_data_r <= tx_data;elsetx_data_r <= tx_data_r;always@(posedge clk_50m or negedge reset_n)if(!reset_n)send_busy <=1'b0;else if(send_en)send_busy <=1'b1;else if(cnt == baud_rate_cnt_max)beginif(cnt_bit ==4'd10)send_busy <=1'b0;elsesend_busy <= send_busy;endelsesend_busy <= send_busy;always@(posedge clk_50m or negedge reset_n)if(!reset_n)send_done <=1'b0;else if(cnt == baud_rate_cnt_max)beginif(cnt_bit ==4'd10)send_done <=1'b1;elsesend_done <=1'b0;endelsesend_done <=1'b0;always@(posedge clk_50m or negedge reset_n)if(!reset_n)cnt <=13'd0;else if(send_busy)beginif(cnt == baud_rate_cnt_max)cnt <=13'd0;elsecnt <= cnt +1'b1;endelsecnt <= cnt;/****************************************always@(posedge clk_50m or negedge reset_n)if(!reset_n)cnt_bit <= 4'd0;else if(send_en) //send_en needs to be 1 clock high pulse cnt_bit <= 4'd1;else if(cnt == baud_rate_cnt_max)beginif(cnt_bit == 4'd10)cnt_bit <= 4'd0;elsecnt_bit <= cnt_bit + 1'b1;endelsecnt_bit <= cnt_bit;******************************************/always@(posedge clk_50m or negedge reset_n)if(!reset_n)cnt_bit <=4'd0;else if(send_busy &&(cnt_bit ==4'd11))cnt_bit <=4'd1;else if(cnt ==1)cnt_bit <= cnt_bit +1'b1;elsecnt_bit <= cnt_bit;always@(posedge clk_50m or negedge reset_n)if(!reset_n)beginuart_tx <=1'b1;endelsecase(cnt_bit)4'd0:;4'd1: uart_tx <=1'b0;//start4'd2: uart_tx <= tx_data_r[0];//bit 04'd3: uart_tx <= tx_data_r[1];4'd4: uart_tx <= tx_data_r[2];4'd5: uart_tx <= tx_data_r[3];4'd6: uart_tx <= tx_data_r[4];4'd7: uart_tx <= tx_data_r[5];4'd8: uart_tx <= tx_data_r[6];4'd9: uart_tx <= tx_data_r[7];//bit 84'd10: uart_tx <=1'b1;//stopdefault:;endcaseendmodule附录3 串口发送testbench`timescale1ns/1ps///////////////////////////////////////////////////////////////////// /////////////// Company:// Engineer://// Create Date: 2020/06/21 11:38:04// Design Name:// Module Name: uart_txd_tb// Project Name:// Target Devices:// Tool Versions:// Description://// Dependencies://// Revision:// Revision 0.01 - File Created// Additional Comments://///////////////////////////////////////////////////////////////////// /////////////module uart_txd_tb();reg clk_50m;reg reset_n;reg[7:0] tx_data;reg[2:0] baud_set;reg send_en;wire send_done;wire send_busy;wire uart_tx;parameter CLK_PERIOD =20;initial clk_50m =0;always#(CLK_PERIOD /2) clk_50m =~clk_50m;initial begintx_data =8'h55;baud_set =4;reset_n =0;send_en =0;#(CLK_PERIOD *100);reset_n =1;# CLK_PERIOD;send_en =1;#(CLK_PERIOD );send_en =0;#(CLK_PERIOD *4340);send_en =1;#(CLK_PERIOD );send_en =0;#(CLK_PERIOD *4340);#(CLK_PERIOD *100);$stop;enduart_txd uart_txd(.clk_50m(clk_50m),.reset_n(reset_n),.tx_data(tx_data),.baud_set(baud_set),.send_en(send_en),.send_done(send_done),.send_busy(send_busy),.uart_tx(uart_tx));endmodule附录4 串口接收源程序`timescale1ns/1ps///////////////////////////////////////////////////////////////////// /////////////// Company:// Engineer://// Create Date: 2020/06/21 15:30:30// Design Name:// Module Name: uart_rxd// Project Name:// Target Devices:// Tool Versions:// Description://// Dependencies://// Revision:// Revision 0.01 - File Created// Additional Comments://///////////////////////////////////////////////////////////////////// /////////////module uart_rxd(clk_50m,reset_n,rx_data,baud_set,rx_done,rx_busy,uart_rx);input clk_50m;input reset_n;output reg[7:0] rx_data;input[2:0] baud_set;output reg rx_done;output reg rx_busy;input uart_rx;reg[12:0] cnt;reg[12:0] baud_rate_cnt_max;reg[3:0] cnt_bit;reg uart_rx_r1;reg uart_rx_r2;wire nedge;localparam baud_rate_9600 =13'd5207;localparam baud_rate_19200 =13'd2603;localparam baud_rate_38400 =13'd1301;localparam baud_rate_57600 =13'd867;localparam baud_rate_115200 =13'd433;always@(posedge clk_50m or negedge reset_n)if(!reset_n)baud_rate_cnt_max <= baud_rate_115200;elsecase(baud_set)3'd0:baud_rate_cnt_max = baud_rate_9600;3'd1:baud_rate_cnt_max = baud_rate_19200;3'd2:baud_rate_cnt_max = baud_rate_38400;3'd3:baud_rate_cnt_max = baud_rate_57600;3'd4:baud_rate_cnt_max = baud_rate_115200;default:baud_rate_cnt_max = baud_rate_115200;endcasealways@(posedge clk_50m or negedge reset_n)if(!reset_n)beginuart_rx_r1 <=8'd0;uart_rx_r2 <=8'd0;endelse beginuart_rx_r1 <= uart_rx;uart_rx_r2 <= uart_rx_r1;endassign nedge = uart_rx_r2 &(!uart_rx_r1);always@(posedge clk_50m or negedge reset_n) if(!reset_n)rx_busy <=1'b0;else if(nedge)rx_busy <=1'b1;else if(cnt == baud_rate_cnt_max)begin if(cnt_bit ==4'd10)rx_busy <=1'b0;elserx_busy <= rx_busy;endelserx_busy <= rx_busy;always@(posedge clk_50m or negedge reset_n) if(!reset_n)rx_done <=1'b0;else if(cnt == baud_rate_cnt_max)begin if(cnt_bit ==4'd10)rx_done <=1'b1;elserx_done <=1'b0;endelserx_done <=1'b0;always@(posedge clk_50m or negedge reset_n) if(!reset_n)cnt <=13'd0;else if(rx_busy)beginif(cnt == baud_rate_cnt_max)cnt <=13'd0;elsecnt <= cnt +1'b1;endelsecnt <= cnt;always@(posedge clk_50m or negedge reset_n) if(!reset_n)cnt_bit <=4'd1;else if(cnt == baud_rate_cnt_max )begin if(cnt_bit ==4'd10)cnt_bit <=4'd1;elsecnt_bit <= cnt_bit +1'b1;endelsecnt_bit <= cnt_bit;always@(posedge clk_50m or negedge reset_n)if(!reset_n)beginrx_data <=8'd0;endelse if(cnt == baud_rate_cnt_max /2)case(cnt_bit)4'd1:;//start4'd2: rx_data[0]<= uart_rx_r2;//bit 04'd3: rx_data[1]<= uart_rx_r2;4'd4: rx_data[2]<= uart_rx_r2;4'd5: rx_data[3]<= uart_rx_r2;4'd6: rx_data[4]<= uart_rx_r2;4'd7: rx_data[5]<= uart_rx_r2;4'd8: rx_data[6]<= uart_rx_r2;4'd9: rx_data[7]<= uart_rx_r2;//bit 74'd10:;//stopdefault:;endcaseelserx_data <= rx_data;endmodule附录5串口接收testbench`timescale1ns/1ps///////////////////////////////////////////////////////////////////// /////////////// Company:// Engineer://// Create Date: 2020/06/21 19:44:29// Design Name:// Module Name: uart_rxd_tb// Project Name:// Target Devices:// Tool Versions:// Description://// Dependencies://// Revision:// Revision 0.01 - File Created// Additional Comments://///////////////////////////////////////////////////////////////////// /////////////module uart_rxd_tb();reg clk_50m;reg reset_n;wire[7:0] rx_data;wire rx_done;wire rx_busy;reg uart_rx;parameter CLK_PERIOD =20;initial clk_50m =0;always#(CLK_PERIOD /2) clk_50m =~clk_50m;initial beginreset_n =0;uart_rx =1;//idle#(CLK_PERIOD *100);reset_n =1;# CLK_PERIOD;uart_rx =0;//start#(CLK_PERIOD *434);uart_rx =1;//bit0#(CLK_PERIOD *434);uart_rx =0;//bit1#(CLK_PERIOD *434);uart_rx =1;//bit2#(CLK_PERIOD *434);uart_rx =0;//bit3#(CLK_PERIOD *434);uart_rx =1;//bit4#(CLK_PERIOD *434);uart_rx =0;//bit5#(CLK_PERIOD *434);uart_rx =1;//bit6#(CLK_PERIOD *434);uart_rx =0;//bit7#(CLK_PERIOD *434);uart_rx =1;//stop#(CLK_PERIOD *434);uart_rx =1;//idle#(CLK_PERIOD *434);#(CLK_PERIOD *434);#(CLK_PERIOD *434);uart_rx =0;//start #(CLK_PERIOD *434);uart_rx =0;//bit0#(CLK_PERIOD *434);uart_rx =1;//bit1#(CLK_PERIOD *434);uart_rx =0;//bit2#(CLK_PERIOD *434);uart_rx =1;//bit3#(CLK_PERIOD *434);uart_rx =0;//bit4#(CLK_PERIOD *434);uart_rx =1;//bit5#(CLK_PERIOD *434);uart_rx =0;//bit6#(CLK_PERIOD *434);uart_rx =1;//bit7#(CLK_PERIOD *434);uart_rx =1;//stop#(CLK_PERIOD *434);uart_rx =1;//idle#(CLK_PERIOD *434);#(CLK_PERIOD *434);#(CLK_PERIOD *434);$stop;enduart_rxd uart_rxd(.clk_50m(clk_50m),.reset_n(reset_n),.rx_data(rx_data),.baud_set(3'd4),.rx_done(rx_done),.rx_busy(rx_busy),.uart_rx(uart_rx));endmodule。
基于FPGA的串口通信设计与实现

置和输人数据计算出响应
的奇偶校验位,它是通过
纯组合逻辑来实现的。
2.6总线选择模块
总线选择模块用于
选择奇偶校验器的输入是
数据发送总线还是数据接
收总线。
2.7计数器模块
计数器模块的功能
是记录串行数据发送或者
接收的数日,在计数到某
数值时通知UART内核模
块。 3 UART程序设计 UART完整的工作流程可以分为接收过程
关键词:FPGA:UART:RS232
引言 串行接口的应用非常广泛,为实现串口通 信功能一般使用专用串行接口芯片,但是这种 接口芯片存在体积较大、接口复杂以及成本较 高的缺点,使得硬件设计更加复杂,并且结构与 功能相对固定,无法根据设计的需要对其逻辑 控制进行灵活的修改。介绍了一种采用FPGA 实现串口通信的方法。 1串口通信协议 对一个设备的处理器来说,要接收和发送 串行通信的数据,需要一个器件将串行的数据 转换为并行的数据以便于处理器进行处理,这 种器件就是UART(Universal Asynchronous Re— ceiver/Transmitter)通用异步收发器。作为接iSl的 一部分,UART提供以下功能: 1.1将由计算机内部传送过来的并行数据 转换为输出的串行数据流; 1.2将计算机外部来的串行数据转换为字 节,供计算机内部使用并行数据的器件使用; 1.3在输出的串行数据流中加入奇偶校验 位,并对从外部接收的数据流进行奇偶校验: 1.4在输出数据流中加入启停标记,并从 接收数据流中删除启停标记。 2 UART模块设计 UART主要由UART内核、信号检测器、移 位寄存器、波特率发生器、计数器、总线选择器 和奇偶校验器7个模块组成。(见图1) 2.1 UART内核模块 UART内核模块是整个设计的核心。在数 据接收时,UART内核模块负责控制波特率发 生器和移位寄存器同步的接收并且保存 RS一232接收端口上的串行数据。在数据发送 时,UART内核模块首先产生完整的发送序列, 之后控制移位寄存器将序列加载到移位寄存器 的内部寄存器里,最后再控制波特率发生器驱 动移位寄存器将数据串行输出。 2_2信号检测模块 信号检测器用于对RS一232的输入信号进 行实时检测,一旦发现新的数据则立即通知 UART内核。需要注意的是,这里所说的 RS一232输入输出信号都指经过电平转换后的 逻辑信号,而不是RS一232总线上的电平信号。 2_3移位寄存器模块 移位寄存器的作用是存储输入或者输出 的数据。 2.4波特率发生器模块 由于RS一232传输必定是工作在某种波特 率下,比如9600,为了便于和RS一232总线进行 同步,需要产生符合RS一232传输波特率的时 钟。 2.5奇偶校验器模块 奇偶校验器的功能是根据奇偶校验的设
基于Verilog HDL设计的UART模块

1 UART原理串行通信是指外部设备和计算机间使用一根数据线(另外需要地线,可能还需要控制线)进行数据传输的方式。
数据在一根数据线上一位一位传输,每一位数据都占据一个固定的时间长度。
与并行通信方式相比,串行通信方式的传输速度较慢,但这种通信方式使用的数据线少,在远距离通信中可以节约通信成本,因此得到了广泛的应用。
基本的UART只需要发送和接收两条数据线就可以完成数据的全双工通信,其基本功能是在发送端将控制器通过总线传过来的并行数据,以设定的格式,设定的频率串行地传输出去,并同时在接收端将串行接收到的数据,转换成相应的并行数据发送出去。
UART的基本帧格式如图1所示。
其中,起始位总是逻辑O状态,停止位总是逻辑l状态,其持续时间可选为1位、1.5位或2位,其数据位可为5、6、7、8位,校验位可根据需要选择奇校验位,偶校验位或无校验位。
2 UART的设计现今复杂的数字系统的设计往往采用自顶向下的设计方案,利用层次化结构化的方法,将一个设计方案划分为若干模块,在不同层次的模块都可以进行仿真,可以很方便地查看某一层次的代码以改正仿真时发现错误。
在本设计中UART主要由波特率发生器、接收模块、发送模块3部分组成,并具有l位停止位和无校验位。
波特率发生器实现波特率的变换,利用外部时钟信号产生一个所需波特率16倍的波特率时钟,用来控制UART的接收与发送。
接收模块是用于接收串行信号,并将其转化为并行数据;而发送模块则将准备输出的并行数据按照UART的帧格式转化为串行数据输出。
图2为UART结构图。
2.1 波特率发生器波特率表示的是每秒钟传送的二进制数据的位数,即单位时间内传送的信息量。
在串行异步传送中,常用到的波特率为1 200、2 400、4 800、9 600、19 200等。
波特率发生器实际上是一个分频器,主要是产生和。
RS-232通信所采用的波特率同步的时钟。
由于串行数据帧与接收数据时钟是异步的,所以存UA RT的接收端在什么时刻将数据移入寄存器,怎样选择可靠的采样点是非常关键的。
用vhdl语言在cpld上实现串行通信

用vhdl语言在cpld上实现串行通信一、概述串行通信是现代通信领域中最为常见的一种通信方式。
通过串行通信,现代社会中的各种设备可以以最高效的方式进行数据传输,实现快速、准确的信息交换。
而vhdl语言则是数字电路设计领域中最为常用的一种描述语言,因为vhdl 语言可以描述数字电路的不同行为,对于数字电路的模拟和仿真非常方便。
在本文中,我们将介绍如何使用vhdl语言在cpld 上实现串行通信。
二、串行通信的基本原理串行通信是指在数据传输过程中,数据位是按照顺序一个一个相继传输的。
串行通信的传输速率相对较慢,但是传输距离远,主要是通过数据信号占用两个或者三个核心线来完成的。
串行通信的数据信号一般由三个部分构成:开始位、数据位和停止位。
开始位一般用于启动数据传输,而停止位则用于结束数据传输。
三、vhdl语言概述VHDL(VHSIC Hardware Description Language)是美国国防工业联合会(VHSIC)在80年代末期为了解决数字电路设计中的复杂性而开发的一种硬件描述语言,是一种基于文本的语言。
VHDL语言主要用来描述数字逻辑和数字电路。
VHDL语言本身就是一种结构化的、层次化的语言,可以很好地体现出数字电路的层次关系。
四、使用vhdl语言在cpld上实现串行通信的步骤1、确定串行通信的传输速率和数据格式。
在确定串行通信的传输速率和数据格式之前,需要确定串行通信的基本参数,包括其传输速率、在接收端进行判定数据是否有效的时间程度、以及在发送端和接收端之间互相传输数据的位数。
这些参数对于后续的设计极为重要。
2、编写串行通信的vhdl模块。
在vhdl模块中,需要包括发送和接收两个部分,分别对应于硬件接口中的发送和接收部分。
发送部分主要是将数据按照规定的格式进行串行传输,而接收部分则主要是将串行传输的数据再转换为并行数据。
3、完成vhdl模块的仿真测试。
在完成vhdl模块的设计之后,需要进行仿真测试,以验证vhdl模块的正确性和稳定性。
基于FPGA技术的HDLC帧收发器的设计与实现的开题报告

基于FPGA技术的HDLC帧收发器的设计与实现的开题报告一、研究背景与意义在现代通信系统中, HDLC(High Level Data Link Control)协议是一种广泛应用的数据链路层协议,在数据传输领域具有重要的意义。
HDLC协议能够实现可靠的数据传输、错误检测和纠错等功能,被广泛应用于各种通信系统中,如计算机网络、通信卫星、传感器网络等。
而在HDLC协议中,帧的生成和解析是其最基本的部分,因此设计一种高效、可靠的HDLC帧收发器技术,对实现基于HDLC协议的数据通信具有重要的意义。
而FPGA(Field-Programmable Gate Array)技术是一种高性能、高灵活性的可编程逻辑器件,具有并行处理能力强、延迟低、功耗小、可扩展性高等特点,被广泛应用于数字电路设计领域。
基于FPGA技术设计和实现HDLC帧收发器,能够实现高速、高效的帧传输和处理,提高通信系统的可靠性和稳定性。
二、研究内容与目标本次研究的主要内容是基于FPGA技术设计和实现一种高效、可靠的HDLC帧收发器,实现对于HDLC帧的收发和解析。
具体包括以下内容:1. HDLC协议的理论分析和研究,了解HDLC帧格式和协议流程,确定设计方案和实现策略;2. FPGA器件的选型和系统设计,包括硬件电路设计和信号处理等方面的内容;3. 基于Verilog HDL进行设计和实现,包括模块化设计、状态机设计、时序控制等;4. 通过仿真和实际硬件测试验证设计的正确性和可行性;本研究的目标是实现一种高效、可靠、具有扩展性的HDLC帧收发器,满足各种通信系统对于数据传输和处理的需求,并且与现有通信系统的兼容性良好。
三、研究方法1. 理论分析法:对HDLC协议进行深入研究和理论分析,确定设计方案和实现策略,为后续的FPGA设计提供理论基础和指导;2. 硬件电路设计法:选用适合的FPGA器件进行系统设计,包括电路设计和信号处理等方面的内容,确定硬件电路结构和信号流程;3. Verilog HDL设计法:基于Verilog HDL进行设计和实现,包括模块化设计、状态机设计、时序控制等,实现HDLC协议的帧收发和解析功能;4. 仿真和测试法:采用Modelsim等仿真工具进行软件仿真,通过实际硬件测试验证设计的正确性和可行性。
ST-BUS总线接口模块的Verilog HDL设计

ST-BUS总线接口模块的Verilog HDL设计关键字:总线转换卡驱动控制电路输入输出模块印刷电路板滤波电路整流电路引言随着数字技术的迅速发展,现代通信系统已成为一个庞大的综合化数字网络。
电信核心网络除了提供传统电话服务外,还为其它专用通信(比如警用集群通信等)提供中继服务。
电信系统一般从交换机引出E1信号线路以供其它专用通信系统接入。
为了满足电信网的接入规范,E1终端设备内部常采用一种被称为ST-BUS的总线来对需要接入通信网的各路用户数据进行排队,以便统一与E1信号进行转换,充分利用E1线路资源。
由于批量生产的接口芯片都是针对某些特定标准接口而设计,无法满足E1通信的特殊需要。
为满足多种特殊接口与电信线路间进行数据交换的需要,增加系统可重配置的灵活性,本文在所涉及项目中的E1接口转换板的设计中采用了可编程器件实现了多种特殊接口的混合接入。
为了简化问题,文中主要介绍ST-BUS总线接口收发模块的Verilog HDL设计。
ST-BUS基本原理ST-BUS(Serial Telecom BUS,串行通信总线)是卓联半导体公司根据电信应用的需要而定义的一种重要的通信设备内部总线通信协议,它可以将多路信息(包括音频、视频、控制信息以及其它数据等)进行复接或解复接,以便统一进行信号转换,实现本地设备与电信E1线路间的数据交换。
随着通信系统越来越复杂,电信设备常有局部部件的淘汰或者更新换代。
为了提高设备兼容性也便于系统升级,电信设备广泛采取了模块化设计方法,而ST -BUS就是将各功能模块连接起来协同工作的一种总线标准。
所以,不论模块的功能和外部接口怎样,只要具备ST-BUS总线接口,都可以方便地嵌入到特定的通信系统中。
根据卓联对ST-BUS的信号及时序规范所作的定义,ST-BUS是一种传输数字信息的高速同步串行通信总线,总线接口所需信号有帧同步信号、位时钟信号和串行数据信号。
帧同步信号主要有类型0和类型1两种:类型0的同步脉冲仅出现在帧的开头,如图1所示,总线上各部件将之作为重要参考信号并由此决定何时开始接收或发送数据流;类型1的同步脉冲需要维持一个完整的时隙周期(即8个位时钟周期),在此期间部件也要接收或发送信息数据,这种同步方式较少应用。
基于FPGA的高速串行数据收发接口设计

基于FPGA的高速串行数据收发接口设计随着信息技术的不断发展,高速串行数据收发接口已经成为许多应用领域中的关键技术。
而基于FPGA的高速串行数据收发接口设计,可以充分发挥FPGA的并行计算和可编程性优势,实现高速数据传输和处理。
本文将介绍基于FPGA的高速串行数据收发接口的设计原理、关键技术和应用。
一、设计原理在高速串行数据收发接口中,主要涉及到以下几个方面的技术:物理接口、时钟同步、帧同步、数据编码和解码、差分信号传输等。
1.物理接口物理接口是指FPGA与外部设备之间进行数据传输的接口。
常见的物理接口包括LVDS、USB、PCIe等。
在设计中,需要选择合适的物理接口,并实现与FPGA之间的连接。
2.时钟同步时钟同步是指接收端与发送端的时钟信号保持同步,以确保数据的准确传输。
常见的时钟同步技术包括PLL锁相环、FIFO缓存等。
在设计中,需要使用适当的时钟同步技术,保证数据的稳定传输。
3.帧同步帧同步是指接收端能够正确识别数据帧的起始和结束标志,以及数据帧中的各个字段。
在设计中,通过使用标志位或者特定的编码格式,可以实现帧同步,保证数据的正确接收和解析。
4.数据编码和解码数据编码和解码是指将要传输的数据进行编码,以提高传输速率和抗干扰能力。
常见的数据编码和解码算法包括差分编码、曼彻斯特编码、8b/10b编码等。
在设计中,需要根据具体的应用需求,选择合适的数据编码和解码算法。
5.差分信号传输差分信号传输是指将发送端的信号分为正负两路进行传输,以提高传输速率和抗干扰能力。
差分信号传输可以有效抑制共模干扰和噪声,提高信号的可靠传输。
二、关键技术在基于FPGA的高速串行数据收发接口设计中,需要关注以下几个关键技术。
1.时钟和数据恢复由于传输中的时钟和数据可能存在相位偏移和抖动等问题,因此需要使用时钟和数据恢复技术来保持时钟的稳定,并将数据恢复到正确的状态。
2.信号完整性由于传输线上会存在反射、串扰等问题,需要采取合适的电路设计和布线策略,以提高信号的抗干扰能力和抗噪声能力,保证数据的可靠传输。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
基于Verilog的RS-232串口通信在CPLD上的实现
CPLD(Complex Programable Logic Device)是一种复杂的用户可编程逻辑器件。
采用连续连接结构,延时可预测,从而使电路仿真更加准确。
CPLD 是标准的大规模集成电路产品,可用于各种数字逻辑系统的设计。
开发工具Quartus II、ISE等功能强大,编程语言灵活多样,使设计开发缩短了周期。
随着嵌入式的发展,对数据的传输和人机交互通信的要求越来越高。
而串口通信因其资源消耗少、技术成熟而被广泛应用。
系统中上位机与嵌入式芯片之间的交互通信可以通过专用集成芯片作为外设RS-232异步串行接口,如TI、EXAR、EPIC公司的550、452等系列UAWT集成电路,或在拥有Nios系统的FPGA上可以方便地嵌入UART模块。
但是在设计中用户会提出自己的要求,如:数据加密或只使用UART部分功能等,即要求更灵活的UART。
而且有时CPLD资源剩余,出于成本考虑也会要求设计一种模拟的UART。
对于上述的两种情况,就可以在CPLD其丰富的资源上制作一款UART,实现PC机与嵌入式系统之间的数据交换。
1 串口通信协议
1.1 UART简介
通用异步收发器(Universal Asynchronous Receiver Transmitter,UART)。
异步通信的特点:不要求收发双方时钟的严格一致,实现容易,设备开销较小。
具有相关工业标准提供的标准的接口电平规范等优点,在工业控制领域被广泛采用。
异步通信一帧字符信息由4部分组成:起始位、数据位、奇偶校验位和停止位。
本设计基于RS-232的数据帧结构,设置数据帧结构如图1所示:1 bit起始位,8 bit数据位,1 bit停止位,无校验位。
每帧实质上传送1 Byte数据。
1.2 自定义数据包格式
多个上文所描述的帧就可以组成一个数据包。
串口通信是在RS-232数据帧结构的基础上定义的,传输以数据包为单位进行。
包结构如图2所示。
本文采用和校验的结构,一个数据包包含15 Byte。
其中第1个字节是数据包头即握手字符。
第2字节为控制字符,EE代表写命令,DD代表读命
令。
第3至第14为可利用数据。
第15字节作为校验字符,理论上应等于这个数据包中数据字符串之和的后8bit。
2 设计方案
2.1 UART的设计结构
笔者设计采用模块化设计,方案的UART主要由逻辑控制模块、波特率发生模块、发送模块和接收模块等组成。
波特率发生模块可以建立精确的时钟,确保数据采样准确、工作时序顺畅。
逻辑控制模块、波特率发生模块、发送模块和接收模块完成工作有:确定数据起始位、数据收发,串并转换、建立握手连接、判断命令、数据校验等功能。
2.2 状态图
利用串口通信在数据交互过程中涉及到了多种工作状态,情况比较多样,而利用程序设计中的有限状态机(FSM)理论进行编程设计,这个问题可以迎刃而解。
有限状态机是由寄存器组和组合逻辑构成的硬件时序电路,有限状态机的状态(即由寄存器组各位的1和0的组合状态所构成的有限个状态)只能在同一时钟跳变沿的情况下才能从一个状态转向另一个状态。
本设计的有限个状态编码使用独热码形式,即寄存器组每一个bit位代表一种状态(如“0100”,“1000”为四态机中的两种状态),这种状态码的好处是避免了状态混乱。
状态机采用Mealy型有限状态机,这种状态机的下一个状态不但取决于各个输入值,还取决于当前所在状态,符合UART的工作原理。
逻辑控制模块、数据接收模块和发送模块的设计都使用到了状态机,其中以逻辑状态机为主状态机,其余两个为从状态机。
确定各种工作状态和工作流程后便可构建出状态图,方便直观地进行后续设计。
通过状态图可以方便、准确地得到程序设计框图如图4所示。
3 各模块设计
3.1 波特率发生器
串口通信必须要设定波特率,本设计采用的波特率为9 600 bit/s。
产生波特率的时钟频率是越高越好,这样才可产生较高且精确的波特率。
设计选用50M主频率要产生9600bit/s波特率,每传送一位数据需要5 208.33个时钟周期。
取一个最接近的数是5 208,则波特率为9 600.61,其误差约为0.006%,误码率很低可以确保通信正常。
波特率发生器要解决的另一个关键性问题是确保准确地捕获起始位“0”。
即时准确地捕获起始位不仅决定通信是否顺畅开始,而且还影响后续的数据采样过程可靠地进行。
方案采取了16分频的波特率发生器,即通过对50 M 总时钟源分频,得到一个9 600x16 Hz的时钟进行数据传输,这样每16个时钟信号采样1 bit数据。
在Rxd数据接收端口接收到从空闲高电平“1”跳变为起始位低电平“0”信号后,连续8个分频周期确认是否是起始位。
若是连续的低电平则捕获起始位,自此之后每16个时钟周期读取1 bit数据。
这种方法不仅确保了起始位的准确捕获,而且使数据采样点处于了数据的正中央保证了数据的准确。
3.2 接收器
在波特率发生器捕获起始位并启动后,接收器将开始工作。
其主要工作是
接收每一位数据,将串行数据移位存入缓冲寄存器,并在接收完一字节数据后将数据存入锁存器完成串并转换,同时发出char_ok信号通知逻辑控制模块一个字节的数据已经接收完毕。
接收器的部分程序如下所示:
3.3 逻辑处理模块
逻辑处理模块是模拟UART的决策模块。
它主要完成PC机与CPLD的握手、数据处理和数据校验、状态分析与给收发模块提供决策。
PC机要向CPLD发数据时,先向串口发送FF,FF表示PC机要与CPLD建立联系。
CPLD收到这个信息后,由逻辑模块的talk信号通知发射模块握手情况,发送器通过串口给PC机反馈信息,DD表示CPLD收到了PC机的要求并同意建立联系,CC表示握手不成功PC机可以再次发出请求。
握手成功后,PC机要向CPLD发出命令字符,E1表示写,E2表示读。
随后进入数据接收或发送状态,每个数据包接收完毕后逻辑处理模块进入下一状态——数据校验状态。
根据上文提到的本设计的数据校验采用和校验,数据校验完后逻辑处理模块会根据校验结果给出信号check,通知发
送模块Txd发送反馈信息给PC机。
逻辑控制模块的部分程序如下所示:
在逻辑接收模块中的重点是握手环节,它体现了PC机与CPLD相互对话的关键,后面两者的互相通信都是基于此而建立的。
应用上述思路设计的握手环节时序仿真如图5所示。
如图所示当char接收寄存器通过Rxd接收到一个字符信息后发出char_ok 信号,经逻辑控制模块得知是握手信息FF后,触发握手成功talk信号,并在下一时钟上升沿Txd从空闲状态的高电平“1”变为起始位“0”准备发送反馈信息给PC机。
3.4 发送器
发送器在接收逻辑处理模块给出的命令后发送相应的数据给PC机。
发送内容主要包括:数据正确或握手成功信息DD,示意PC机继续下一步操作;数据重发或握手失败CC,示意PC机重新发送数据;以及PC机欲从嵌入式系统中读出的数据。
4 实验验证
工程设计的某嵌入式系统要求PC机向CPLD发送数据。
CPLD选用ATREL 公司的MAX7000系列芯片EPM7128SLC84-15。
芯片拥有2 500个可使用门阵列、128个宏单元、8个逻辑阵列块、84个用户I/O接口。
CPLD的IO操作电平是TTL电平,通过MAX232电平转换芯片将PC机串口电平转换为TTL电平,就建立起了串口通信的电气基础。
PC机上拥有VC++编写的数据下载程序,波特率为9600 bit/s,每个数据帧含1位起始位,8位数据位,无校验位,1位停止位。
通信数据格式用上文提到的和校验数据格式,以数据包为单位发送,如图6所示。
从实验结果可看到PC机每发送一个完整的15 Byte数据包,CPLD回复握手成功和数据校验正确,表明设计可行。
5 结束语
本文从工程设计实际出发,没有选取通用的UART芯片,通过分析异步通信中UART的结构特点,运用CPLD的丰富资源和一些工程技术制作了自定义通信数据包格式的串口通信模块。
通过与PC机上数据传输程序联试,实现了信息的传输和人机互动,证明设计方案的正确。
如今嵌入式技术应用十分广泛而且市场需求很广阔,PC机与嵌入式系统的通信实现了人机互动使系统功能更加强大。
研究对增强嵌入式系统操作性有重要意义。