赞
踩
1.uart接收模块:接收串行数据,输出并行数据和其有效标志。
- module uart_rx#(
- parameter UART_BPS='d9600 , //波特率:1s传输9600个bit
- parameter CLK_FREQ='d50_000_000 //时钟频率:50MHz
- )(
- input wire clk ,
- input wire rst_n ,
- input wire rx , //接收的串行数据
-
- output reg [7:0] po_data , //输出并行数据
- output reg po_flag //输出有效并行数据的标志信号
- );
首先对rx进行时钟同步,消除亚稳态,以及打拍处理提取下降沿;
- always@(posedge clk or negedge rst_n)
- if(!rst_n) begin
- rx_d1<=1'b1;
- rx_d2<=1'b1;
- rx_d3<=1'b1;
- end
- else begin
- rx_d1<=rx; //时钟同步,消除亚稳态
- rx_d2<=rx_d1; //时钟同步,消除亚稳态
- rx_d3<=rx_d2; //打拍处理
- end
-
- assign rx_fall = ~rx_d2 & rx_d3 ; //提取rx下降沿
然后需要数据帧的有效信号,以便知道什么时候计数;
- always@(posedge clk or negedge rst_n)
- if(!rst_n) frame_val<=1'b0;
- else if((bit_cnt==BIT_CNT_MAX-1'b1) && bit_flag) //接收完1帧数据
- frame_val<=1'b0;
- else if(rx_fall)
- frame_val<=1'b1;
- else
- frame_val<=frame_val;
1码元符号(1bit)所需的计数器;
- always@(posedge clk or negedge rst_n)
- if(!rst_n) baud_cnt<=16'd0;
- else if(frame_val==1'b0) //数据帧无效
- baud_cnt<=16'd0;
- else if(baud_cnt==BAUD_CNT_MAX-1'b1)
- baud_cnt<=16'd0;
- else
- baud_cnt<=baud_cnt+1'b1;
1bit稳定数据的采样标志信号;
- always@(posedge clk or negedge rst_n)
- if(!rst_n) bit_flag<=1'b0;
- else if(baud_cnt==BAUD_CNT_MAX_HALF-1'b1) //采样需要在中间数据才稳定
- bit_flag<=1'b1;
- else
- bit_flag<=1'b0;
对采样到的bit数据进行计数;
- always@(posedge clk or negedge rst_n)
- if(!rst_n) bit_cnt<=4'd0;
- else if((bit_cnt==BIT_CNT_MAX-1'b1) && bit_flag) //10bit数据采样完毕
- bit_cnt<=4'd0;
- else if(bit_flag) //采样到1bit数据
- bit_cnt<=bit_cnt+1'b1;
- else
- bit_cnt<=bit_cnt;
将接收到的串行数据rx转化为并行数据po_data_t;
- always@(posedge clk or negedge rst_n)
- if(!rst_n) po_data_t<=8'b0;
- else if((bit_cnt>=4'd1) && (bit_cnt<BIT_CNT_MAX-1'b1) && bit_flag) //8bit数据
- po_data_t<={rx_d3,po_data_t[7:1]}; //起始位后接的是低位
- else
- po_data_t<=po_data_t;
并行数据全部拼接完成的标志信号;
- always@(posedge clk or negedge rst_n)
- if(!rst_n) po_flag_t<=1'b0;
- else if((bit_cnt==BIT_CNT_MAX-1'b1) && bit_flag)
- po_flag_t<=1'b1;
- else
- po_flag_t<=1'b0;
输出并行数据和输出有效并行数据的标志信号。
- always@(posedge clk or negedge rst_n)
- if(!rst_n) po_data<=8'b0;
- else if(po_flag_t)
- po_data<=po_data_t;
- else
- po_data<=po_data;
-
- //po_flag_t延迟1拍与po_data同步
- always@(posedge clk or negedge rst_n)
- if(!rst_n) po_flag<=1'b0;
- else
- po_flag<=po_flag_t;
- module uart_tx#(
- parameter UART_BPS='d9600 , //波特率:1s传输9600个bit
- parameter CLK_FREQ='d50_000_000 //时钟频率:50MHz
- )(
- input wire clk ,
- input wire rst_n ,
- input wire pi_flag , //输入并行数据
- input wire [7:0] pi_data , //输入有效并行数据的标志信号
-
- output reg tx //输出串行数据
- );
首先同样是uart 1帧数据的有效信号;
- always@(posedge clk or negedge rst_n)
- if(!rst_n) frame_val<=1'b0;
- else if((bit_cnt==BIT_CNT_MAX-1'b1) && bit_flag) //发送完1帧数据
- frame_val<=1'b0;
- else if(pi_flag) //接收到有效的并行数据
- frame_val<=1'b1;
- else
- frame_val<=frame_val;
1码元符号(1bit)所需的计数器;
- always@(posedge clk or negedge rst_n)
- if(!rst_n) baud_cnt<=16'd0;
- else if(frame_val==1'b0) //数据帧无效
- baud_cnt<=16'd0;
- else if(baud_cnt==BAUD_CNT_MAX-1'b1)
- baud_cnt<=16'd0;
- else
- baud_cnt<=baud_cnt+1'b1;
1bit数据的发送标志信号;
- always@(posedge clk or negedge rst_n)
- if(!rst_n) bit_flag<=1'b0;
- else if(frame_val && !baud_cnt)
- bit_flag<=1'b1;
- else
- bit_flag<=1'b0;
对bit数据的发送进行计数;
- always@(posedge clk or negedge rst_n)
- if(!rst_n) bit_cnt<=4'd0;
- else if((bit_cnt==BIT_CNT_MAX-1'b1) && bit_flag) //10bit数据计数完毕
- bit_cnt<=4'd0;
- else if(bit_flag) //发送完1bit数据
- bit_cnt<=bit_cnt+1'b1;
- else
- bit_cnt<=bit_cnt;
输出串行数据。
- always@(posedge clk or negedge rst_n)
- if(rst_n==1'b0) tx<=1'b1; //空闲
- else if(bit_flag)
- case(bit_cnt)
- 4'd0: tx<=1'b0; //起始位
- 4'd1: tx<=pi_data[0]; //最低位数据
- 4'd2: tx<=pi_data[1];
- 4'd3: tx<=pi_data[2];
- 4'd4: tx<=pi_data[3];
- 4'd5: tx<=pi_data[4];
- 4'd6: tx<=pi_data[5];
- 4'd7: tx<=pi_data[6];
- 4'd8: tx<=pi_data[7]; //最高位数据
- 4'd9: tx<=1'b1; //结束位
- default:tx<=1'b1;
- endcase
- module uart_test#(
- parameter UART_BPS='d9600 , //波特率:1s传输9600个bit
- parameter CLK_FREQ='d50_000_000 //时钟频率:50MHz
- )(
- input wire clk ,
- input wire rst_n ,
- input wire rx , //接收的串行数据
-
- output wire tx //发送的串行数据
- );
-
- wire [7:0] data ;
- wire data_flag ;
-
- uart_rx#(
- .UART_BPS(UART_BPS),
- .CLK_FREQ(CLK_FREQ)
- )u_uart_rx(
- .clk (clk ),
- .rst_n (rst_n ),
- .rx (rx ),
-
- .po_data(data),
- .po_flag(data_flag)
- );
-
- uart_tx#(
- .UART_BPS(UART_BPS),
- .CLK_FREQ(CLK_FREQ)
- )u_uart_tx(
- .clk (clk ),
- .rst_n (rst_n ),
- .pi_data(data),
- .pi_flag(data_flag),
-
- .tx(tx)
- );
-
- endmodule
- `timescale 1ns/1ns
- module tb_uart_test();
-
- parameter UART_BPS='d9600 ; //波特率:1s传输9600个bit
- parameter CLK_FREQ='d50_000_000 ; //时钟频率:50MHz
-
- reg clk;
- reg rst_n;
- reg rx;
-
- wire tx;
-
- initial
- begin
- clk=1'b0;
- rst_n<=1'b0;
- rx<=1'b1;
- #20
- rst_n<=1'b1;
- end
-
- always #10 clk=~clk;
-
- initial
- begin
- #200 //空闲状态
- rx_test();
-
- #(5208*10*20*3)
- #200
- $stop;
- end
-
- //输出uart数据帧(10-13)
- task rx_test(); //任务函数,类似C语言
- integer j;
- for(j=10;j<13;j=j+1)
- rx_8bit(j);
- endtask
-
- //输入8bit并行数据,输出uart数据帧
- task rx_8bit(
- input [7:0] data
- );
- integer i;
-
- for(i=0;i<10;i=i+1)
- begin
- case(i)
- 0:rx<=1'b0; //1帧数据
- 1:rx<=data[0];
- 2:rx<=data[1];
- 3:rx<=data[2];
- 4:rx<=data[3];
- 5:rx<=data[4];
- 6:rx<=data[5];
- 7:rx<=data[6];
- 8:rx<=data[7];
- 9:rx<=1'b1;
- endcase
- #(5208*20); //9600波特率
- end
- endtask
-
- uart_test#(
- .UART_BPS(UART_BPS),
- .CLK_FREQ(CLK_FREQ)
- )u_uart_test(
- .clk (clk ),
- .rst_n (rst_n ),
- .rx (rx ),
-
- .tx(tx)
- );
-
- endmodule
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。