verilog基础---uart_tx代码
1、功能概述
功能是发送串口,波特率是115200,时钟是148.5Mhz。
控制的参数:
顶层接口:
| clk | 148.5M |
| Rst_n | 低电平复位 |
| Tx_data | 串口要传输的数据 |
| Rx232_tx | 串口的tx引脚线 |
| busy | 1表示串口正在发送数据。0表示空闲,可以接收数据 |
| Tx_int | 1表示有数据等待要发送,0表示无数据状态 |
转摘:https://blog.csdn.net/weixin_36590806/article/details/118441535
思路:
设计两个模块,一个模块是根据时钟控制读写的时间点。
另一个模块是发送串口的模块。
顶层代码:
module my_uart_tx_top
(
clk ,
rst_n ,
tx_int ,
tx_data ,
rs232_tx ,
busy
);
input clk ; // 148.5MHz主时钟
input rst_n ; //低电平复位信号
input [7:0]tx_data ; //接收数据寄存器,保存直至下一个数据来到
input tx_int ;
output rs232_tx ; //RS232发送数据信号
output busy ;
wire clk_bps ; // clk_bps_r高电平为接收数据位的中间采样点,同时也作为发送数据的数据改变点
//----------------------------------------------------
speed_select speed_tx
(
.clk (clk ), //波特率选择模块
.rst_n (rst_n ),
.bps_start(busy ),
.clk_bps (clk_bps )
);
my_uart_tx my_uart_tx
(
.clk (clk ), //发送数据模块
.rst_n (rst_n ),
.tx_data (tx_data ),
.tx_int (tx_int ),
.rs232_tx (rs232_tx ),
.clk_bps (clk_bps ),
.busy (busy )
);
endmodule
speed_select模块代码:
module speed_select
(
clk ,
rst_n ,
bps_start,
clk_bps
);
input clk ; // 148.5MHz主时钟
input rst_n ; //低电平复位信号
input bps_start; //接收到数据后,波特率时钟启动信号置位
output clk_bps ; // clk_bps的高电平为接收或者发送数据位的中间采样点
parameter bps115200 = 1288 ; //148.5MHZ 波特率为115200bps
parameter bps115200_2 = 644 ;
reg[13:0] cnt ; //分频计数
reg clk_bps_r; //波特率时钟寄存器
//----------------------------------------------------------
always @ (posedge clk or negedge rst_n)
if(!rst_n)
cnt <= 14'd0;
else if((cnt >= bps115200) || !bps_start)
cnt <= 14'd0; //波特率计数清零
else
cnt <= cnt+1'b1;//波特率时钟计数启动
always @ (posedge clk or negedge rst_n)
if(!rst_n)
clk_bps_r <= 1'b0;
else if(cnt == bps115200_2)
clk_bps_r <= 1'b1;
else
clk_bps_r <= 1'b0;
assign clk_bps = clk_bps_r;
endmodule
my_uart_tx模块代码:
module my_uart_tx
(
clk ,
rst_n ,
tx_data ,
tx_int ,
rs232_tx ,
clk_bps ,
busy
);
input clk ; // 148.5MHz主时钟
input rst_n ; //低电平复位信号
input clk_bps ; // clk_bps_r高电平为接收数据位的中间采样点,同时也作为发送数据的数据改变点
input[7:0] tx_data ; //接收数据寄存器
input tx_int ; //接收数据中断信号,接收到数据期间始终为高电平,在该模块中利用它的下降沿来启动串口发送数据
output rs232_tx ; // RS232发送数据信号
//output bps_start; //接收或者要发送数据,波特率时钟启动信号置位
output busy ;
//---------------------------------------------------------
reg[7:0] tx_data_temp ; //待发送数据的寄存器
//---------------------------------------------------------
//reg bps_start_r;
reg tx_en ; //发送数据使能信号,高有效
reg[3:0] num ;
always @ (posedge clk or negedge rst_n) begin
if(!rst_n) begin
//bps_start_r <= 1'bz;
tx_en <= 1'b0;
tx_data_temp <= 8'd0;
end
else if(tx_int) begin //接收数据完毕,准备把接收到的数据发回去
//bps_start_r <= 1'b1;
tx_data_temp <= tx_data; //把接收到的数据存入发送数据寄存器
tx_en <= 1'b1; //进入发送数据状态中
end
else if(num==4'd11) begin //数据发送完成,复位
//bps_start_r <= 1'b0;
tx_en <= 1'b0;
end
end
assign busy = tx_en ;
//---------------------------------------------------------
reg rs232_tx_r ;
always @ (posedge clk or negedge rst_n) begin
if(!rst_n) begin
num <= 4'd0 ;
rs232_tx_r <= 1'b1 ;
end
else if(tx_en) begin
if(clk_bps) begin
num <= num+1'b1 ;
case( num )
4'd0: rs232_tx_r <= 1'b0 ; //发送起始位
4'd1: rs232_tx_r <= tx_data_temp[0] ; //发送bit0
4'd2: rs232_tx_r <= tx_data_temp[1] ; //发送bit1
4'd3: rs232_tx_r <= tx_data_temp[2] ; //发送bit2
4'd4: rs232_tx_r <= tx_data_temp[3] ; //发送bit3
4'd5: rs232_tx_r <= tx_data_temp[4] ; //发送bit4
4'd6: rs232_tx_r <= tx_data_temp[5] ; //发送bit5
4'd7: rs232_tx_r <= tx_data_temp[6] ; //发送bit6
4'd8: rs232_tx_r <= tx_data_temp[7] ; //发送bit7
4'd9: rs232_tx_r <= 1'b1 ; //发送结束位
default: rs232_tx_r <= 1'b1 ;
endcase
end
else if(num==4'd11) num <= 4'd0; //复位
end
end
assign rs232_tx = rs232_tx_r;
endmodule
如果想要不同的速率,可以根据speed_select模块进行计算出想要的速率。
本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!
