uart串口代码verilog

uart串口代码verilog,第1张

  Verilog HDL是一种硬件描述语言(HDL:Hardware DescripTIon Language),以文本形式来描述数字系统硬件的结构和行为的语言,用它可以表示逻辑电路图、逻辑表达式,还可以表示数字逻辑系统所完成的逻辑功能。 Verilog HDL和VHDL是世界上最流行的两种硬件描述语言,都是在20世纪80年代中期开发出来的。前者由Gateway Design AutomaTIon公司(该公司于1989年被Cadence公司收购)开发。两种HDL均为IEEE标准。

  uart串口代码verilog,uart串口代码verilog,第2张

  串口通信是目前比较重要的一种通信方式,主要是用于计算机和外部的通信。首先简单的介绍一下串口通信的原理:

  串口用于ASCII码字符的传输。通信使用3根线完成:(1)地线(GND),(2)发送(TXD),(3)接收(RXD)。由于串口通信是异步的,端口能够在一根线上发送数据同时在另一根线上接收数据。其它线用于握手,但是不是必须的。串口通信最重要的参数是波特率、数据位、停止位和奇偶校验位。对于两个进行通信的端口,这些参数必须匹配: a,波特率:这是一个衡量通信速度的参数。它表示每秒钟传送的bit的个数。例如300波特表示每秒钟发送300个bit。当我们提到时钟周期时,我们就是指波特率例如如果协议需要4800波特率,那么时钟是4800Hz。这意味着串口通信在数据线上的采样率为4800Hz。通常电话线的波特率为14400,28800和36600。波特率可以远远大于这些值,但是波特率和距离成反比。高波特率常常用于放置的很近的仪器间的通信,典型的例子就是GPIB设备的通信。 b,数据位:这是衡量通信中实际数据位的参数。当计算机发送一个信息包,实际的数据不会是8位的,标准的值是5、7和8位。如何设置取决于你想传送的信息。比如,标准的ASCII码是0~127(7位)。扩展的ASCII码是0~255(8位)。如果数据使用简单的文本(标准 ASCII码),那么每个数据包使用7位数据。每个包是指一个字节,包括开始/停止位,数据位和奇偶校验位。由于实际数据位取决于通信协议的选取,术语“包”指任何通信的情况。 c,停止位:用于表示单个包的最后一位。典型的值为1,1.5和2位。由于数据是在传输线上定时的,并且每一个设备有其自己的时钟,很可能在通信中两台设备间出现了小小的不同步。因此停止位不仅仅是表示传输的结束,并且提供计算机校正时钟同步的机会。适用于停止位的位数越多,不同时钟同步的容忍程度越大,但是数据传输率同时也越慢。 d,奇偶校验位:在串口通信中一种简单的检错方式。有四种检错方式:偶、奇、高和低。当然没有校验位也是可以的。对于偶和奇校验的情况,串口会设置校验位(数据位后面的一位),用一个值确保传输的数据有偶个或者奇个逻辑高位。例如,如果数据是011,那么对于偶校验,校验位为0,保证逻辑高的位数是偶数个。如果是奇校验,校验位位1,这样就有3个逻辑高位。高位和低位不真正的检查数据,简单置位逻辑高或者逻辑低校验。这样使得接收设备能够知道一个位的状态,有机会判断是否有噪声干扰了通信或者是否传输和接收数据是否不同步

  以下是用Verilog编写的串口UART程序

  ==========================================================================

  //-----------------------------------------------------

  // Design Name : uart

  // File Name : uart.v

  // FuncTIon : Simple UART

  // Coder : Deepak Kumar Tala

  //-----------------------------------------------------

  module uart (

  reset ,

  txclk ,

  ld_tx_data ,

  tx_data ,

  tx_enable ,

  tx_out ,

  tx_empty ,

  rxclk ,

  uld_rx_data ,

  rx_data ,

  rx_enable ,

  rx_in ,

  rx_empty

  );

  // Port declaraTIons

  input reset ;

  input txclk ;

  input ld_tx_data ;

  input [7:0] tx_data ;

  input tx_enable ;

  output tx_out ;

  output tx_empty ;

  input rxclk ;

  input uld_rx_data ;

  output [7:0] rx_data ;

  input rx_enable ;

  input rx_in ;

  output rx_empty ;

  // Internal Variables

  reg [7:0] tx_reg ;

  reg tx_empty ;

  reg tx_over_run ;

  reg [3:0] tx_cnt ;

  reg tx_out ;

  reg [7:0] rx_reg ;

  reg [7:0] rx_data ;

  reg [3:0] rx_sample_cnt ;

  reg [3:0] rx_cnt ;

  reg rx_frame_err ;

  reg rx_over_run ;

  reg rx_empty ;

  reg rx_d1 ;

  reg rx_d2 ;

  reg rx_busy ;

  // UART RX Logic

  always @ (posedge rxclk or posedge reset)

  if (reset) begin

  rx_reg 《= 0;

  rx_data 《= 0;

  rx_sample_cnt 《= 0;

  rx_cnt 《= 0;

  rx_frame_err 《= 0;

  rx_over_run 《= 0;

  rx_empty 《= 1;

  rx_d1 《= 1;

  rx_d2 《= 1;

  rx_busy 《= 0;

  end else begin

  // Synchronize the asynch signal

  rx_d1 《= rx_in;

  rx_d2 《= rx_d1;

  // Uload the rx data

  if (uld_rx_data) begin

  rx_data 《= rx_reg;

  rx_empty 《= 1;

  end

  // Receive data only when rx is enabled

  if (rx_enable) begin

  // Check if just received start of frame

  if (!rx_busy && !rx_d2) begin

  rx_busy 《= 1;

  rx_sample_cnt 《= 1;

  rx_cnt 《= 0;

  end

  // Start of frame detected, Proceed with rest of data

  if (rx_busy) begin

  rx_sample_cnt 《= rx_sample_cnt + 1;

  // Logic to sample at middle of data

  if (rx_sample_cnt == 7) begin

  if ((rx_d2 == 1) && (rx_cnt == 0)) begin

  rx_busy 《= 0;

  end else begin

  rx_cnt 《= rx_cnt + 1;

  // Start storing the rx data

  if (rx_cnt 》 0 && rx_cnt 《 9) begin

  rx_reg[rx_cnt - 1] 《= rx_d2;

  end

  if (rx_cnt == 9) begin

  rx_busy 《= 0;

  // Check if End of frame received correctly

  if (rx_d2 == 0) begin

  rx_frame_err 《= 1;

  end else begin

  rx_empty 《= 0;

  rx_frame_err 《= 0;

  // Check if last rx data was not unloaded,

  rx_over_run 《= (rx_empty) ? 0 : 1;

  end

  end

  end

  end

  end

  end

  if (!rx_enable) begin

  rx_busy 《= 0;

  end

  end

  // UART TX Logic

  always @ (posedge txclk or posedge reset)

  if (reset) begin

  tx_reg 《= 0;

  tx_empty 《= 1;

  tx_over_run 《= 0;

  tx_out 《= 1;

  tx_cnt 《= 0;

  end else begin

  if (ld_tx_data) begin

  if (!tx_empty) begin

  tx_over_run 《= 0;

  end else begin

  tx_reg 《= tx_data;

  tx_empty 《= 0;

  end

  end

  if (tx_enable && !tx_empty) begin

  tx_cnt 《= tx_cnt + 1;

  if (tx_cnt == 0) begin

  tx_out 《= 0;

  end

  if (tx_cnt 》 0 && tx_cnt 《 9) begin

  tx_out 《= tx_reg[tx_cnt -1];

  end

  if (tx_cnt == 9) begin

  tx_out 《= 1;

  tx_cnt 《= 0;

  tx_empty 《= 1;

  end

  end

  if (!tx_enable) begin

  tx_cnt 《= 0;

  end

  end

  endmodule

欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/dianzi/2717138.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-08-17
下一篇 2022-08-17

发表评论

登录后才能评论

评论列表(0条)

保存