打印
[Verilog HDL]

VERILOG实现串口传输UART

[复制链接]
4509|32
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
gaochy1126|  楼主 | 2023-5-29 14:41 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
1.接收模块



//****************uart receive module******************//
//********************************************************//
`define SIM
module uart_rx#(
        parameter DATAWIDTH                 = 8,
        parameter BAUD_CNT_WIDTH         = 12,
        parameter BIT_CNT_WIDTH         = 4
)
(
        input                                                                 CLK,
        input                                                                 RSTn,
        input                                                                 rs232_rx,//input data
        output reg         [ DATAWIDTH - 1 : 0 ]         rx_data,//receive data
        output reg                                                         po_flag //finish sig
);
`ifndef SIM
localparam BAUD_END = 5207;//simulate time too long,change to 56(560)
`else
localparam BAUD_END = 56;
`endif
localparam BAUD_M         = BAUD_END / 2 - 1;
localparam BIT_END         = 8;

reg                                                         rx_r1;
reg                                                         rx_r2;
reg                                                         rx_r3;
reg                                                         rx_flag;
reg [ BAUD_CNT_WIDTH - 1 : 0 ]         baud_cnt;
reg                                                         bit_flag;
reg [ BIT_CNT_WIDTH - 1 : 0 ]         bit_cnt;
wire                                                         rx_neg;//rx negedge

assign rx_neg = ~rx_r2 & rx_r3;

always @(posedge CLK or negedge RSTn) begin
        rx_r1 <= 0;
        rx_r2 <= 0;
        rx_r3 <= 0;
end

always @(posedge CLK) begin
        rx_r1 <= rs232_rx;
        rx_r2 <= rx_r1;
        rx_r3 <= rx_r2;
end

//rx_flag
always @(posedge CLK or negedge RSTn) begin
        if (!RSTn) begin
                // reset
                rx_flag <= 0;
        end
        else if (rx_neg) begin
                rx_flag <= 1;
        end
        else if (bit_cnt == 0 && baud_cnt == BAUD_END) begin
                rx_flag <= 0;
        end
end

//baud_cnt
always @(posedge CLK or  negedge RSTn) begin
        if (!RSTn) begin
                // reset
                baud_cnt <= 0;
        end
        else if (baud_cnt == BAUD_END) begin
                baud_cnt <= 0;
        end
        else if (rx_flag) begin
                baud_cnt <= baud_cnt + 1;
        end
        else begin
                baud_cnt <= 0;
        end
end

//bit_flag
always @(posedge CLK or negedge RSTn) begin
        if (!RSTn) begin
                // reset
                bit_flag <= 0;
        end
        else if (baud_cnt == BAUD_M ) begin
                bit_flag <= 1;
        end
        else begin
                bit_flag <= 0;
        end
end

//bit_cnt
always @(posedge CLK or negedge RSTn) begin
        if (!RSTn) begin
                // reset
                bit_cnt <= 0;
        end
        else if (bit_flag == 1 && bit_cnt == BIT_END) begin
                bit_cnt <= 0;
        end
        else if (bit_flag) begin
                bit_cnt <= bit_cnt + 1;
        end
end

//rx_data
always @(posedge CLK or negedge RSTn) begin
        if (!RSTn) begin
                // reset
                rx_data <= 0;
        end
        else if (bit_flag == 1 && bit_cnt >= 1) begin
                rx_data <= { rx_r2, rx_data [ DATAWIDTH - 1 : 1 ] };
        end
end

//po_flag
always @(posedge CLK or negedge RSTn) begin
        if (!RSTn) begin
                // reset
                po_flag <= 0;
        end
        else if (bit_cnt == BIT_END && bit_flag == 1) begin
                po_flag <= 1;
        end
        else begin
                po_flag <= 0;
        end
end
endmodule


使用特权

评论回复

相关帖子

沙发
gaochy1126|  楼主 | 2023-5-29 14:42 | 只看该作者
testbench:
module uart_rx_tb;
        reg                         CLK;
        reg                         RSTn;
        reg                         rs232_tx;

        wire                         po_flag;
        wire [7:0]                 rx_data;

        reg  [7:0]                 mem [4:0];

initial $readmemh ("D:/Project/verilog_pro/project_module/sdram_controller/src/tx_data.txt",mem);

initial
        begin
                CLK = 1;
                forever #5 CLK = ~CLK;
        end

initial
        begin
                RSTn = 0;
                rs232_tx <= 1;
                #100
                RSTn = 1;
                #100
                tx_byte();
        end

task tx_byte();
        integer i;
        for (i = 0; i < 5;i=i+1 )
                begin
                        tx_bit(mem[i]);
                end
endtask

task tx_bit(
        input [7:0] data
);
        integer i;
        for (i = 0; i < 10;i=i+1 )
                begin
                        case(i)
                                0:        rs232_tx <= 1'b0;
                                1:        rs232_tx <= data [0];
                                2:        rs232_tx <= data [1];
                                3:        rs232_tx <= data [2];
                                4:        rs232_tx <= data [3];
                                5:        rs232_tx <= data [4];
                                6:        rs232_tx <= data [5];
                                7:        rs232_tx <= data [6];
                                8:        rs232_tx <= data [7];
                                9:        rs232_tx <= 1'b1;
                        endcase
                        #560;
                end

endtask

uart_rx uart_rx_inst(.CLK                (CLK                ),
                                         .RSTn                (RSTn                ),
                                         .rs232_rx        (rs232_tx        ),
                                         .rx_data        (rx_data        ),
                                         .po_flag        (po_flag        ));

endmodule


使用特权

评论回复
评论
gaochy1126 2023-5-29 16:59 回复TA
赞一个 
板凳
gaochy1126|  楼主 | 2023-5-29 14:42 | 只看该作者
txt文件:


使用特权

评论回复
评论
gaochy1126 2023-5-29 16:59 回复TA
赞一个 
地板
gaochy1126|  楼主 | 2023-5-29 14:43 | 只看该作者
2.发送模块

代码:
//******************uart transfer module******************//
//***********************************************************//
`define SIM
module uart_tx#(
        parameter DATAWIDTH                 = 8,
        parameter BAUD_CNT_WIDTH         = 32,
        parameter BIT_CNT_WIDTH         = 4

)
(
        input                                                                 CLK,
        input                                                                 RSTn,
        input                 [ DATAWIDTH - 1 : 0 ]         tx_data,//data
        input                                                                 tx_trig,//transfer sig
        output  reg                                                        rs232_tx//transfer data
);
`ifndef SIM
localparam BAUD_END = 5207;//simulate time too long,change to 56(560)
`else
localparam BAUD_END = 56;
`endif
localparam BAUD_M         = BAUD_END / 2 - 1;
localparam BIT_END         = 8;

reg [ DATAWIDTH - 1 : 0          ]         tx_data_r;
reg                                                         tx_flag;
reg [ BAUD_CNT_WIDTH - 1 : 0 ]         baud_cnt;
reg                                                         bit_flag;
reg [ BIT_CNT_WIDTH - 1 : 0  ]         bit_cnt;
//reg                             rs232_tx_t;

//tx_data_r
always @(posedge CLK or  negedge RSTn) begin
        if (!RSTn) begin
                // reset
                tx_data_r <= 0;
        end
        else if (tx_trig == 1 && tx_flag == 0) begin
                tx_data_r <= tx_data;
        end
end


//tx_flag
always @(posedge CLK or negedge RSTn) begin
        if (!RSTn) begin
                // reset
                tx_flag <= 0;
        end
        else if (tx_trig == 1 && tx_flag == 0) begin
                tx_flag <= 1;
        end
        else if (bit_cnt == BIT_END && bit_flag == 1) begin
                tx_flag <= 0;
        end
end
//baud_cnt
always @(posedge CLK or  negedge RSTn) begin
        if (!RSTn) begin
                // reset
                baud_cnt <= 0;
        end
        else if (baud_cnt == BAUD_END) begin
                baud_cnt <= 0;
        end
        else if (tx_flag) begin
                baud_cnt <= baud_cnt + 1;
        end
        else begin
                baud_cnt <= 0;
        end

end
//bit_flag
always @(posedge CLK or  negedge RSTn) begin
        if (!RSTn) begin
                // reset
                bit_flag <= 0;
        end
        else if (baud_cnt == BAUD_END) begin
                bit_flag <= 1;
        end
        else begin
                bit_flag <= 0;
        end
end
//bit_cnt
always @(posedge CLK or negedge RSTn) begin
        if (!RSTn) begin
                // reset
                bit_cnt <= 0;
        end
        else if (bit_flag == 1 && bit_cnt == BIT_END) begin
                bit_cnt <= 0;
        end
        else if (bit_flag) begin
                bit_cnt <= bit_cnt + 1;
        end
end
//rs232_tx
always @(posedge CLK or negedge RSTn) begin
        if (!RSTn) begin
                // reset
                rs232_tx <= 1;
        end
        else if (tx_flag) begin
                case(bit_cnt)
                0:                rs232_tx <= 0;
                1:                rs232_tx <= tx_data_r[0];
                2:                rs232_tx <= tx_data_r[1];
                3:                rs232_tx <= tx_data_r[2];
                4:                rs232_tx <= tx_data_r[3];
                5:                rs232_tx <= tx_data_r[4];
                6:                rs232_tx <= tx_data_r[5];
                7:                rs232_tx <= tx_data_r[6];
                8:                rs232_tx <= tx_data_r[7];
                default:rs232_tx <= 1;

                endcase
        end
        else begin
                rs232_tx <= 1;
        end
end

//assign rs232_tx = rs232_tx_t;
endmodule


使用特权

评论回复
评论
gaochy1126 2023-5-29 17:00 回复TA
赞一个 
5
gaochy1126|  楼主 | 2023-5-29 14:44 | 只看该作者
testbench:、
module uart_tx_tb;
        reg CLK;
        reg RSTn;
        reg tx_trig;
        reg [7:0] tx_data;

        wire rs232_tx;

initial
        begin
                CLK = 1;
                forever #5 CLK = ~CLK;
        end

initial
        begin
                RSTn = 0;
                #100
                RSTn = 1;
        end

initial
        begin
                tx_data <= 0;
                tx_trig <= 0;
                #200
                tx_trig <= 1;
                tx_data <= 8'h55;
                #10
                tx_trig <= 0;
        end
uart_tx uart_tx_inst(.CLK(CLK),
                                         .RSTn(RSTn),
                                         .tx_data(tx_data),
                                         .tx_trig(tx_trig),
                                         .rs232_tx(rs232_tx)
        );
endmodule

使用特权

评论回复
评论
gaochy1126 2023-5-29 17:00 回复TA
赞一个 
6
gaochy1126|  楼主 | 2023-5-29 14:45 | 只看该作者
3.顶层
module uart_top(
        input                 CLK,
        input                 RSTn,
        input                 rs232_rx,
        output            rs232_tx
);

//***************Main Code*************//
wire [7:0] rx_data;
wire tx_trig;
//reg  rs232_tx_t;

uart_rx uart_rx_inst(.CLK                (CLK                ),
                                         .RSTn                (RSTn                ),
                                         .rs232_rx        (rs232_rx        ),
                                         .rx_data        (rx_data        ),
                                         .po_flag        (tx_trig        ));

uart_tx uart_tx_inst(.CLK                (CLK                ),
                                         .RSTn                (RSTn                ),
                                         .tx_data        (rx_data        ),
                                         .tx_trig        (tx_trig        ),
                                         .rs232_tx        (rs232_tx         ));

endmodule
testbench:
module uart_tb;
        reg CLK;
        reg RSTn;
        reg rs232_rx;
        wire rs232_tx;

        reg  [7:0]                 mem [4:0];

initial $readmemh ("D:/Project/verilog_pro/project_module/sdram_controller/src/tx_data.txt",mem);

initial
        begin
                RSTn = 0;
                //rs232_tx = 1;
                #100
                RSTn = 1;
                #100
                tx_byte();
        end


initial
        begin
                CLK = 0;
                forever #5 CLK = ~CLK;
        end
task tx_byte();
        integer i;
        for (i = 0; i < 5;i=i+1 )
                begin
                        tx_bit(mem[i]);
                end
endtask

task tx_bit(
        input [7:0] data
);
        integer i;
        for (i = 0; i < 10;i=i+1 )
                begin
                        case(i)
                                0:        rs232_rx <= 1'b0;
                                1:        rs232_rx <= data [0];
                                2:        rs232_rx <= data [1];
                                3:        rs232_rx <= data [2];
                                4:        rs232_rx <= data [3];
                                5:        rs232_rx <= data [4];
                                6:        rs232_rx <= data [5];
                                7:        rs232_rx <= data [6];
                                8:        rs232_rx <= data [7];
                                9:        rs232_rx <= 1'b1;
                        endcase
                        #560;
                end

endtask

uart_top uart_inst(.CLK                        (CLK),
                                        .RSTn                (RSTn),
                                        .rs232_rx        (rs232_rx),
                                        .rs232_tx        (rs232_tx));
endmodule


使用特权

评论回复
评论
gaochy1126 2023-5-29 17:00 回复TA
赞一个 
7
hilahope| | 2023-5-29 16:48 | 只看该作者
资料很实用,谢谢楼主!                                 

使用特权

评论回复
评论
gaochy1126 2023-5-29 17:00 回复TA
赞一个 
8
qiufengsd| | 2023-5-29 16:49 | 只看该作者
资料的确是很全面                                 

使用特权

评论回复
评论
gaochy1126 2023-5-29 17:00 回复TA
赞一个 
9
claretttt| | 2023-5-29 16:49 | 只看该作者
相当全的资料,很适合初学者                                 

使用特权

评论回复
评论
gaochy1126 2023-5-29 17:00 回复TA
赞一个 
10
earlmax| | 2023-5-29 16:49 | 只看该作者
资料很实用,谢谢楼主!                                 

使用特权

评论回复
评论
gaochy1126 2023-5-29 17:01 回复TA
赞一个 
11
maudlu| | 2023-5-29 16:49 | 只看该作者
谢谢lz分享,很有用                                 

使用特权

评论回复
评论
gaochy1126 2023-5-29 17:01 回复TA
赞一个 
12
adolphcocker| | 2023-5-29 16:50 | 只看该作者
很详细的资料                                 

使用特权

评论回复
评论
gaochy1126 2023-5-29 17:01 回复TA
赞一个 
13
tabmone| | 2023-5-29 16:50 | 只看该作者
资料 好好收藏一下                                 

使用特权

评论回复
评论
gaochy1126 2023-5-29 17:01 回复TA
赞一个 
14
louliana| | 2023-5-29 16:51 | 只看该作者
这些资料太全了!!!                 

使用特权

评论回复
评论
gaochy1126 2023-5-29 17:01 回复TA
赞一个 
15
jonas222| | 2023-5-29 16:51 | 只看该作者
很详细的资料                                 

使用特权

评论回复
评论
gaochy1126 2023-5-29 17:01 回复TA
赞一个 
16
everyrobin| | 2023-5-29 16:51 | 只看该作者
谢谢lz分享,很有用                                 

使用特权

评论回复
评论
gaochy1126 2023-5-29 17:02 回复TA
赞一个 
17
wilhelmina2| | 2023-5-29 16:51 | 只看该作者
谢谢lz分享,很有用                                 

使用特权

评论回复
评论
gaochy1126 2023-5-29 17:02 回复TA
赞一个 
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

个人签名:这个社会混好的两种人:一是有权有势,二是没脸没皮的。

1025

主题

11271

帖子

25

粉丝