当前位置:   article > 正文

通信协议:UART的Verilog实现(上)_uart数据发送接收状态机

uart数据发送接收状态机

相关阅读

通信协议icon-default.png?t=N7T8https://blog.csdn.net/weixin_45791458/category_12452508.html?spm=1001.2014.3001.5482


1、前言

        调制解调器是主机/设备与串行数据通路之间的接口,以串行单比特格式发送和接收数据。它也被称为通用异步收发器(UART, Universal Asynchronous Receiver/Transmitter),这表明该设备能够接收和发送数据,并且发送和接收单元不同步。

        本节中,UART以ASCII码的格式交换文本数据,在ASCII码格式中,每一帧包含1位起始位,5-8位数据位,1位可选的奇偶校验位和1位停止位。在本文的实现中,使用了了7位数据,因此数据格式如下所示。发送时从起始位(低位)开始,向高位逐位发送,每个位持续一个时钟周期(比特位时间),停止位的有效时间则可能会超过一个时钟周期,即两帧之间的间隔可以是多个时钟周期。

停止位校验位数据位6数据位5数据位4数据位3数据位2数据位1数据位0起始位

Uart传送的ASCII文本数据格式

2、UART的操作

        UART发送器通常是更大系统的一部分,其主机以并行格式取出数据并指定UART以串行格式发送。UART接收器需检测传输情况,以串行格式接收数据,去掉起始位和停止位后以并行格式存储数据。因为远程接收器无法得到数据发送时钟——数据异步到达,接收器会比发送器更复杂。接收器必须重新产生本地时钟而不是用发送时钟来同步数据采样。

        UART的简化结构如下图所示,图中给出了主机用于控制UART以及从数据总线接收或发送数据的信号,但没有给出主机的细节。

3、UART发送器

        下面的框图给出了发送器的输入/输出信号。输入信号由主机提供,包括(Load_XMT_datareg, Byte_ready, T_byte, Data_Bus)而输出信号包括串行数据流(Serial_out)。发送器由控制单元和数据通路构成,控制单元是一个FSM,用于给出控制信号给数据通路;而数据通路包含数据寄存器(XMT_datareg)、数据移位寄存器(XMT_shftreg)和用于计数已发送比特数的状态寄存器(bit_count)。状态寄存器包含在数据通路中。

        发送器的内部信号如下所列。注意,信号Load_XMT_datareg本可以直接送至数据通路,但这里将其送入控制器并在idle状态下根据该信号对Load_XMT_DR进行条件赋值。

        控制单元的输入信号及其作用:

        Load_XMT_datareg:idle状态下由其决定Load_XMT_DR信号的值(用于控制将Data_Bus的内容载入XMT_data_reg)。

        Byte_ready:由其决定Load_XMT_shftreg信号的值(用于控制将XMT_data_reg中的内容载入XMT_shftreg)。

        T_byte:用于决定一帧数据传输的开始(将串行输出拉低)。

        BC_lt_BCmax:用于指示数据移位还未完成(即Bit_count < word_size + 1)。

        控制单元的输出信号及其作用:

        Load_XMT_DR:控制Data_Bus的内容载入XMT_data_reg。

        Load_XMT_shftreg:控制将XMT_data_reg中的内容载入XMT_shftreg。

        Start:控制将XMT_shftreg[0]清零表示输出起始位,传输开始。

        Shift:控制将XMT_shftreg右移一位,并在高位补1(停止位)。

        Clear:控制将bit_count清零。

        发送器控制器的状态机ASMD图如下图所示。该状态机包括idle、waiting和sending三个状态。当低有效的同步复位信号rst_b有效时,状态机进入idle状态,同时bit_count被清零,XMT_shftreg被1填充。在idle状态下,主机在令Load_XMT_datareg有效后,控制器输出信号Load_XMT_DR将Data_bus上的内容载入XMT_data_reg。状态机保持idle状态直到主机使Load_XMT_datareg无效并使Byte_ready信号有效,这时会输出Load_XMT_shftreg并进入waiting状态。Load_XMT_shftreg会控制XMT_datareg中的内容载入XMT_shftreg的最左边的比特位,同时令LSB为1(停止位)。

        T_byte有效后输出start信号,下个时钟沿,状态机进入sending状态,同时XMT_shftreg的LSB清零。此时只要计数值未满,sending状态下会一直输出shift信号,这使得XMT_shftreg的数据右移并高位补1。当计数满时(BC_lt_BCmax==0)时,clear信号有效,表示所有有效数字已输出,此时正在输出最后一位停止位,在下一个时钟沿状态机返回idle状态。

        下面给出UART_XMTR的Verilog HDL描述:

  1. module UART_XMTR #(parameter word_size = 8)(
  2. output Serial_out, //Serial output ti data channel
  3. input [word_size - 1 : 0] Data_Bus, //Host data bus containing data word
  4. input Load_XMT_datareg, //Used by host to load the data register
  5. Byte_ready, //Used by host to signal ready
  6. T_byte, //Used by host to signal start of transmission
  7. Clock, //Bit clock of the transmitter
  8. rst_b //Resets internal registers, loads the
  9. //XMT_shftreg with ones
  10. );
  11. wire BC_lt_BCmax;
  12. wire Load_XMT_DR;
  13. wire Load_XMT_shftreg;
  14. wire start;
  15. wire shift;
  16. wire clear;
  17. Controller_Unit M0(
  18. Load_XMT_DR, Load_XMT_shftreg, start, shift, clear, Load_XMT_datareg,
  19. Byte_ready, T_byte, BC_lt_BCmax, Clock, rst_b);
  20. Datapath_Unit M1(
  21. Serial_out, BC_lt_BCmax, Data_bus, Load_XMT_DR, Load_XMT_shftreg,
  22. start, shift, clear, Clock, rst_b);
  23. endmodule
  24. module Control_Unit #(
  25. parameter one_hot_count = 3, //Numbers of one-hot states
  26. state_count = one_hot_count, //Number of bits in state register
  27. size_bit_count = 3 //Size of the bit counte
  28. )(
  29. output reg Load_XMT_DR, //Loads Data_Bus into XMT_datareg
  30. Load_XMT_shftreg, //Loads XMT_datareg into XMT_shftreg
  31. start, //Launches shifting of bits in XMT_shftreg
  32. shift, //Shift bits in XMT_shftreg
  33. clear, //Clears bit_count after last bit is sent
  34. input Load_XMT_datareg, //Asserts Load_XMT_DR in state idle
  35. Byte_ready, //Asserts Load_XMT_shftreg in state idle
  36. T_byte, //Asserts start signal in state waiting
  37. BC_lt_BCmax, //Indicates status of bit counter
  38. Clock,
  39. rst_b
  40. );
  41. localparam idle = 3'b001,
  42. waiting = 3'b010,
  43. sending = 3'b100,
  44. all_ones = 9'b1_1111_1111;
  45. reg [state_count - 1 : 0] state, next_state; // State machine controller
  46. always@(*)begin
  47. Load_XMT_DR = 0;
  48. Load_XMT_shftreg = 0;
  49. start = 0;
  50. clear = 0;
  51. shift = 0;
  52. next_state = idle;
  53. case(state)
  54. idle: if(Load_XMT_datareg == 1'b1)begin
  55. Load_XMT_DR = 1;
  56. next_state = idle;
  57. end
  58. else if(Byte_ready == 1'b1)begin
  59. Load_XMT_shftreg = 1;
  60. next_state = waiting;
  61. end
  62. waiting: if(T_byte == 1)begin
  63. start = 1;
  64. next_state = sending;
  65. end
  66. else next_state = waiting;
  67. sending: if(BC_lt_BCmax == 1)begin
  68. shift = 1;
  69. next_state = sending;
  70. end
  71. else begin
  72. clear = 1;
  73. next_state = idle;
  74. end
  75. default: next_state = idle;
  76. endcase
  77. end
  78. always@(posedge Clock, negedge rst_b)begin
  79. if(rst_b == 0)
  80. state <= idle;
  81. else
  82. state <= next_state;
  83. end
  84. endmodule
  85. module Datapath_Unit #(
  86. parameter word_size = 8,
  87. size_bit_count = 3
  88. )(
  89. output Serial_out,
  90. BC_lt_BCmax,
  91. input [word_size - 1 : 0] Data_bus,
  92. input Load_XMT_DR,
  93. Load_XMT_shftreg,
  94. start,
  95. shift,
  96. clear,
  97. Clock,
  98. rst_b
  99. );
  100. localparam all_ones = 9'b1_1111_1111;
  101. reg [word_size - 1 : 0] XMT_datareg; //Transmit Data Register
  102. reg [word_size : 0] XMT_shftreg; //Transmit Shift Register
  103. reg [size_bit_count : 0] bit_count; //Counts the bits that are transmitted
  104. assign Serial_out = XMT_shftreg[0];
  105. assign BC_lt_BCmax = (bit_count < word_size + 1);
  106. always@(posedge Clock, negedge rst_b)
  107. if(rst_b == 0)begin
  108. XMT_shftreg <= all_ones;
  109. bit_count <= 0;
  110. end
  111. else begin
  112. if(Load_XMT_DR == 1)
  113. XMT_datareg <= Data_bus; //Get the data bus
  114. if(Load_XMT_shftreg == 1)
  115. XMT_shftreg <= {XMT_datareg, 1'b1};//Load shift reg, insert stop
  116. //bit
  117. if(start == 1)XMT_shftreg[0] <= 0; //Signal start of transmission
  118. if(clear == 1)bit_count <= 0;
  119. if(shift == 1)begin
  120. XMT_shftreg <= {1'b1, XMT_shftreg[word_size : 1]};//Shift right,
  121. //fill with ones
  122. bit_count <= bit_count + 1;
  123. end
  124. end
  125. endmodule

以上内容来源于《Verilog HDL高级数字设计》,有删改

        

        

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/你好赵伟/article/detail/666074
推荐阅读
相关标签
  

闽ICP备14008679号