串口发送端verilog代码分析

串口发送端verilog代码分析

  1 `timescale 1ns / 1ps
  2 //////////////////////////////////////////////////////////////////////////////////
  3 // Company: 
  4 // Engineer: chensimin
  5 // 
  6 // Create Date: 2018/05/23 13:59:45
  7 // Design Name: 
  8 // Module Name: uart_tx
  9 // Project Name: 
 10 // Target Devices: 
 11 // Tool Versions: 
 12 // Description: 
 13 // 
 14 // Dependencies: 
 15 // 
 16 // Revision:
 17 // Revision 0.01 - File Created
 18 // Additional Comments:
 19 // 
 20 //////////////////////////////////////////////////////////////////////////////////
 21 
 22 
 23 module uart_tx(
 24 
 25     input  wire clk,
 26     input  wire receive_ack,
 27     input  wire [7:0]data_o,
 28     output reg  txd
 29    
 30     );
 31 
 32     localparam  IDLE = 0,
 33                 SEND_START = 1,
 34                 SEND_DATA = 2,
 35                 SEND_END = 3;
 36 
 37     reg txd = 0;
 38 
 39     reg [3:0]cur_st = 0;
 40     reg [3:0]nxt_st = 0;
 41     always @(posedge clk)
 42     begin
 43         cur_st <= nxt_st;
 44     end
 45 
 46     always @(*)
 47     begin
 48         nxt_st = cur_st;
 49 
 50         case(cur_st)
 51 
 52             IDLE:
 53             begin
 54                 if(receive_ack)
 55                     nxt_st = SEND_START;
 56             end
 57 
 58             SEND_START:
 59             begin
 60                 nxt_st = SEND_DATA;
 61             end
 62 
 63             //每次发送是8bit
 64             SEND_DATA:
 65             begin
 66                 if(count == 7)
 67                     nxt_st = SEND_END;
 68             end
 69 
 70             SEND_END:
 71             begin
 72                 if(receive_ack)
 73                     nxt_st = SEND_START;
 74             end
 75 
 76             default:
 77             begin
 78                 nxt_st = IDLE;
 79             end
 80 
 81         endcase
 82     end
 83 
 84     reg [4:0]count = 0;
 85     always @(posedge clk)
 86     begin
 87         if(cur_st == SEND_DATA)
 88             count <= count + 1'b1;
 89 
 90         else if(cur_st == IDLE || cur_st == SEND_END)
 91             count <= 0;
 92     end
 93 
 94     reg [7:0]data_o_tmp = 0; 
 95     always @(posedge clk)
 96     begin
 97         if(cur_st == SEND_START)
 98             data_o_tmp <= data_o;  // 在开始状态,采集数据
 99 
100         else if(cur_st == SEND_DATA) //在发送状态,对暂存数据进行右移操作
101             data_o_tmp[6:0] <= data_o_tmp[7:1]; 
102     end
103 
104     always @(posedge clk)
105     begin
106         if(cur_st == SEND_START)
107             txd <= 0;
108 
109         else if(cur_st == SEND_DATA)
110             txd <= data_o_tmp[0];   //在发送状态,发送最低位
111 
112         else if(cur_st == SEND_END)
113             txd <= 1;
114     end
115 
116 endmodule
117 
118 
119 
120 /*
121 
122 add_force {/uart_tx/clk} -radix hex {1 0ns} {0 50000ps} -repeat_every 100000ps
123 add_force {/uart_tx/data_o} -radix hex {ab 0ns}
124 add_force {/uart_tx/receive_ack} -radix hex {1 0ns}
125 
126 
127 */

仿真结果:

原文地址:https://www.cnblogs.com/chensimin1990/p/9077417.html