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模块进行计算出想要的速率。


本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!

相关文章

立即
投稿

微信公众账号

微信扫一扫加关注

返回
顶部