1 源代码
  2 module uart_byte_tx(
  3     clk,
  4     reset_n,
  5     data,
  6     send_en,
  7     baud_set,
  8     uart_tx,
  9     tx_done
 10 );
 11     input clk;
 12     input reset_n;
 13     input [7:0] data;
 14     input send_en;
 15     input [2:0] baud_set;
 16     output reg uart_tx;
 17     output reg tx_done;
 18     //设置可选择选择波特率的模式
 19     reg [17:0] bps_DR;
 20     always@(*)
 21     case(baud_set)
 22         0:bps_DR=1000000000/9600/20;
 23         1:bps_DR=1000000000/19200/20;
 24         2:bps_DR=1000000000/38400/20;
 25         3:bps_DR=1000000000/57600/20;
 26         4:bps_DR=1000000000/115200/20;
 27         default:bps_DR=1000000000/9600/20;
 28     endcase
 29     
 30     
 31     //设置分频计数器,满足最低的波特率的位数,18位。
 32     reg [17:0] div_cnt;
 33     always @(posedge clk or negedge reset_n)
 34     if(!reset_n)
 35         div_cnt<=0;
 36     else if(send_en)begin
 37         if(div_cnt==bps_DR-1)
 38             div_cnt<=0;
 39         else
 40             div_cnt<=div_cnt+1'b1;
 41     end
 42     else
 43         div_cnt<=0;
 44         
 45     wire bps_clk;
 46     assign bps_clk=(div_cnt==1);
 47     //开始讲每个时间段连接起来。
 48     reg [3:0] bps_cnt;
 49     always@(posedge clk or negedge reset_n)
 50     if(!reset_n)
 51         bps_cnt<=0;
 52     //1、这里的等于div_cnt==1是为了让计数器从0计数到1时时间比较段,二不产生太大延迟,
 53     //2、加入send_en是为了让计数完及时清零。
 54     else if(send_en)begin
 55 //每次计数到11清零,其他时间进行加一的操作。
 56         if(div_cnt==1) begin
 57             if(bps_cnt==11)
 58                 bps_cnt<=0;
 59             else
 60                 bps_cnt<=bps_cnt+1'b1;    
 61         end
 62     end
 63     else
 64         bps_cnt<=0;
 65     //开始发送数据
 66     always@(posedge clk or negedge reset_n)
 67     if(!reset_n)begin
 68         uart_tx<=1'b1;
 69         tx_done<=0;
 70     end
 71     else case(bps_cnt)
 72 //如果从0开始的话,会在中间间隔时间(空窗期),使得uart_tx=0;
 73 //因为发送初始位置时(0时刻),就让uart_tx<=0了.
 74           1:begin uart_tx<=0;tx_done<=0; end
 75           2:uart_tx<=data[0];
 76           3:uart_tx<=data[1];
 77           4:uart_tx<=data[2];
 78           5:uart_tx<=data[3];
 79           6:uart_tx<=data[4];
 80           7:uart_tx<=data[5];         
 81           8:uart_tx<=data[6];
 82           9:uart_tx<=data[7];
 83           10:uart_tx<=1;
 84           11:begin uart_tx<=1;tx_done<=1;end
 85           default uart_tx<=1;
 86     endcase
 87     
 88 endmodule
 89 
 90 仿真代码
 91 `timescale 1ns/1ns
 92 module uart_byte_tx_tb();
 93     reg clk;
 94     reg reset_n;
 95     reg [7:0] data;
 96     reg send_en;
 97     reg [2:0] baud_set;
 98     wire uart_tx;
 99     wire tx_done;
100     uart_byte_tx uart_byte_tx_inst0(
101     .clk(clk),
102     .reset_n(reset_n),
103     .data(data),
104     .send_en(send_en),
105     .baud_set(baud_set),
106     .uart_tx(uart_tx),
107     .tx_done(tx_done)
108     );
109     initial clk=1;
110     always #10 clk=!clk;
111     
112     initial begin
113         reset_n=0;
114         data=0;
115         baud_set=4;
116         send_en=0;
117         #201;
118         reset_n=1;
119         #20;
120         
121         data=8'h57;
122         send_en=1;
123         
124         @(posedge tx_done)
125         send_en=0;
126         #2000;
127         data=8'h75;
128         send_en=1;
129         #20;
130         @(posedge tx_done)
131         send_en=0;
132         #20000;
133         $stop; 
134     end
135     
136 
137 endmodule

 

posted on 2023-02-21 15:24  无情的造轮子  阅读(116)  评论(0编辑  收藏  举报