1 //1、底层代码源代码发送10位数据
  2 module uart_pr(
  3     clk,
  4     reset_n,
  5     send_go,
  6     data,
  7     baud_set,
  8     tx_done,
  9     uart_tx
 10     );
 11     input clk;
 12     input reset_n;
 13     input send_go;
 14     input [7:0]data;
 15     input [2:0]baud_set;
 16     output reg tx_done;
 17     output reg uart_tx;
 18     
 19     
 20     //再书写关于bps_DR的选择计算
 21     reg [17:0] bps_DR;
 22     always@(*)
 23         case(baud_set)
 24             0:bps_DR=50000000/9600;
 25             1:bps_DR=50000000/19200;
 26             2:bps_DR=50000000/38400;
 27             3:bps_DR=50000000/57600;
 28             4:bps_DR=50000000/115200;
 29             default:bps_DR=50000000/9600;
 30         endcase
 31     reg send_en;
 32     always@(posedge clk or negedge reset_n)
 33     if(!reset_n)
 34         send_en<=0;
 35     else if(send_go)//记住这边只能用顶层的计数counter,不能用底层的div_cnt以及bps_cnt;
 36         send_en<=1;
 37     else if(tx_done)
 38         send_en<=0;
 39         
 40     //存储数据
 41     reg [7:0]r_data;
 42     always@(posedge clk or negedge reset_n)//这里为什么不需要复位的下降沿
 43     if(!reset_n)
 44         r_data<=0;
 45     else if(send_go)
 46         r_data<=data;
 47     else
 48         r_data<=r_data;
 49     //首先书写对应波特率的计数,分频div_cnt
 50     //根据最低的波特率来确定div_cnt的宽度
 51     reg [17:0]div_cnt;
 52     always@(posedge clk or negedge reset_n)
 53     if(!reset_n)
 54         div_cnt<=0;
 55     else if(send_en)begin
 56         if(div_cnt==bps_DR-1)
 57             div_cnt<=0;
 58         else
 59             div_cnt<=div_cnt+1'b1;
 60     end
 61     else
 62         div_cnt<=0;
 63         
 64     wire bps_clk;
 65     assign bps_clk=(div_cnt==1);
 66     //开始书写下一个计数bps_cnt,来实现10为数据的发送
 67     reg [3:0] bps_cnt;
 68     always@(posedge clk or negedge reset_n)
 69     if(!reset_n)
 70         bps_cnt<=0;
 71     else if(send_en)begin
 72         if(bps_clk)begin
 73             if(bps_cnt==11)
 74                 bps_cnt<=0;
 75             else
 76                 bps_cnt<=bps_cnt+1'b1;
 77         end
 78     end
 79     else
 80         bps_cnt=0;
 81     //开始书写发送10位的数据
 82     always@(posedge clk or negedge reset_n)
 83     if(!reset_n)
 84         uart_tx<=1;
 85     else case(bps_cnt)
 86         1:uart_tx<=0;
 87         2:uart_tx<=r_data[0];
 88         3:uart_tx<=r_data[1];
 89         4:uart_tx<=r_data[2];
 90         5:uart_tx<=r_data[3];
 91         6:uart_tx<=r_data[4];
 92         7:uart_tx<=r_data[5];
 93         8:uart_tx<=r_data[6];
 94         9:uart_tx<=r_data[7];
 95         10:uart_tx<=1;
 96         11:uart_tx<=1;
 97         default:uart_tx<=1;
 98     endcase
 99 
100     always@(posedge clk or negedge reset_n)
101     if(!reset_n)
102         tx_done<=0;
103     else if((bps_cnt==10)&&(bps_clk==1))
104         tx_done<=1;
105     else
106         tx_done<=0;
107 endmodule
108 //2、底层代码仿真文件
109 `timescale 1ns / 1ps
110 module uart_pr_tb();
111     reg clk;
112     reg reset_n;
113     reg send_en;
114     reg [7:0]data;
115     reg [2:0]baud_set;
116     wire tx_done;
117     wire uart_tx;
118     uart_pr uart_pr_tb(
119         .clk(clk),
120         .reset_n(reset_n),
121         .send_en(send_en),
122         .data(data),
123         .baud_set(baud_set),
124         .tx_done(tx_done),
125         .uart_tx(uart_tx)
126         );
127     initial clk=1;
128     always#10 clk=!clk;
129     
130     initial begin
131         reset_n=0;
132         data=0;
133         send_en=0;
134         baud_set=4;
135         #201;
136         reset_n=1;
137         #20;
138         data=8'h57;
139         send_en=1;
140         @(posedge tx_done)
141             send_en=0;
142             #2000;
143             data=8'h75;
144             send_en=1;
145         @(posedge tx_done)
146             send_en=0;
147             #20000;
148             $stop;
149     end
150         
151 
152 endmodule
153 3、顶层代码源文件
154 //每10ms以115200的波特率发送一个数据,每次发送的
155 //数据比前一个数据大一(计数器)
156 //顶层设计模块
157 module uart_test1(
158     clk,
159     reset_n,
160     uart_tx
161     );
162     input clk;
163     input reset_n;
164     output uart_tx;
165     
166     reg send_go;//这是顶层的send_en放在下面会出错
167     reg [7:0] data;
168     //先将发送10位数据的uart进行例化
169     uart_pr uart_pr_inst0(
170         .clk(clk),
171         .reset_n(reset_n),
172         .send_go(send_go),
173         .data(data),
174         .baud_set(3'd4),
175         .tx_done(tx_done),
176         .uart_tx(uart_tx)
177     );
178     //先写出一个10ms的计数器
179     reg [18:0]counter;
180     always@(posedge clk or negedge reset_n)
181     if(!reset_n)
182         counter<=0;
183     else if(counter==499999)
184         counter<=0;
185     else
186         counter<=counter+1'b1;
187     //书写发送信号send_en
188     //底层不是控制过send_en了吗??怎么这里还写控制send_en
189     //因为底层控制send_en在testbench中控制的,最后不会在板级验证的时候起作用
190     //那只在testbench中也就是仿真波形中会出现。
191     always@(posedge clk or negedge reset_n)
192     if(!reset_n)
193         send_go<=0;
194     else if(counter==1)//记住这边只能用顶层的计数counter,不能用底层的div_cnt以及bps_cnt;
195         send_go<=1;
196     else    //设置send_go的时候一定要注意,什么时候开始,什么时候结束要形成闭环。
197         send_go<=0;//else还是要加,只不过不用带tx_done因为tx_done已经在顶层模块说明过了
198     //书写data的每次加1;
199     always@(posedge clk or negedge reset_n)
200     if(!reset_n)
201         data<=0;
202     else if(tx_done)
203         data<=data+1'b1;
204 endmodule
205 4、顶层代码仿真文件
206 `timescale 1ns / 1ps
207 module uart_test1_tb();
208     reg clk;
209     reg reset_n;
210     wire uart_tx;
211     uart_test1 uart_test1_inst0(
212     .clk(clk),
213     .reset_n(reset_n),
214     .uart_tx(uart_tx)
215     );
216     
217     initial clk=1;
218     always #10 clk=!clk;
219     
220     initial begin
221     reset_n=0;
222     #201;
223     reset_n=1;
224     
225     #50000000;
226     $stop;
227     
228     end 
229 endmodule

 

posted on 2023-03-03 11:22  无情的造轮子  阅读(118)  评论(0编辑  收藏  举报