lcytms 发表于 2016-11-24 17:40:56

Uart_rx模块

模块功能说明:Uart_rx模块为串口串行数据的接收模块,数据从端口rs232_rx输入,在采集控制信号sel_data和有效位计数器num的控制下,进行串并转换,从端口rx_d输出。tx_en为发送控制模块的使能信号,当Uart_rx模块接收数据完毕以后,置高信号tx_en启动数据发送,将采集到的数据rx_d发送到上位机。

lcytms 发表于 2016-11-24 17:42:20

bps_tx模块

模块功能说明:bps_tx模块为串口发送数据的速率控制模块,当使能信号tx_en为高电平时,bps_tx模块内部计数器开始计数,按照设定好的波特率,输出控制数据发送的尖峰脉冲信号sel_data和有效数据位的计数值num。


lcytms 发表于 2016-11-24 17:43:34

Uart_tx模块

模块功能说明:Uart_tx模块为串口串行数据的发送模块,并行数据从端口rx_d输入,在采集控制信号sel_data和有效位计数器num的控制下,进行并串转换,从端口rs232_tx输出。

lcytms 发表于 2016-11-24 17:45:01

我们将以上四个模块一起放到uart.v顶层模块中,并将接收模块接收到的数据直接通过发送模块发送出去。
uart.v顶层模块的总体架构图如下。

lcytms 发表于 2016-11-24 17:47:14

查看实际效果。
至芯科技ZX_1开发板外部连接上位PC机,PC机通过串口工具发送数据,并检查从开发板返回的数据是否与发送数据一致。
实现效果图如下。

lcytms 发表于 2016-11-24 17:48:25

新建工程文件夹uart。
打开Quartus II软件,打开新工程向导。
新建逻辑模块uart.v。
搭建逻辑框架。
module uart (clk, rst_n, rs232_rx, rs232_tx);

        input clk, rst_n;
        input rs232_rx;
       
        output rs232_tx;


endmodule

lcytms 发表于 2016-11-24 17:52:51

新建接收端口速率控制逻辑bps_rx.v模块。
编写bps_rx模块代码如下。
module bps_rx (clk, rst_n, rx_en, rx_sel_data, rx_num);

        input clk, rst_n;
        input rx_en;
       
        output reg rx_sel_data;
        output reg rx_num;

        parameter bps_div = 13'd5208;
        parameter bps_div_2 = 13'd2604;
       
        reg flag;
       
        always @ (posedge clk or negedge rst_n)
                begin
                        if (!rst_n)
                                begin
                                        flag <= 0;
                                end
                        else
                                begin
                                        if (rx_en)
                                                begin
                                                        flag <= 1;
                                                end
                                        else
                                                begin
                                                        if (rx_num == 4'd10)
                                                                flag <= 0;
                                                end
                                end
                end

               
        reg cnt;
               
        always @ (posedge clk or negedge rst_n)
                begin
                        if (!rst_n)
                                begin
                                        cnt <= 13'd0;
                                end
                        else
                                begin
                                        if (!flag)
                                                begin
                                                        cnt <= 13'd0;
                                                end
                                        else
                                                begin
                                                        if (cnt < bps_div - 1)
                                                                begin
                                                                        cnt <= cnt + 13'd1;
                                                                end
                                                        else
                                                                begin
                                                                        cnt <= 13'd0;
                                                                end
                                                end
                                end
                end
               
               
        always @ (posedge clk or negedge rst_n)
                begin
                        if (!rst_n)
                                begin
                                        rx_sel_data <= 1'b0;
                                end
                        else
                                begin
                                        if (cnt == bps_div_2)
                                                begin
                                                        rx_sel_data <= 1'b1;
                                                end
                                        else
                                                begin
                                                        rx_sel_data <= 1'b0;
                                                end
                                end
                end
               
        always @ (posedge clk or negedge rst_n)
                begin
                        if (!rst_n)
                                begin
                                        rx_num <= 4'd0;
                                end
                        else
                                begin
                                        if (!flag)
                                                begin
                                                        rx_num <= 4'd0;
                                                end
                                        else
                                                begin
                                                        if (rx_num == 4'd10)
                                                                begin
                                                                        rx_num <= 4'd0;
                                                                end
                                                        else
                                                                begin
                                                                        if (rx_sel_data)
                                                                                rx_num <= rx_num + 4'd1;
                                                                end
                                                end
                                end
                end

endmodule

lcytms 发表于 2016-11-24 17:57:09

新建接收逻辑uart_rx.v模块。
编写uart_rx模块代码如下。
module uart_rx (clk, rst_n, rs232_rx, rx_sel_data, rx_num, rx_en, tx_en, rx_d);

        input clk, rst_n;
        input rs232_rx;
        input rx_sel_data;
        input rx_num;
       
        output rx_en;
        output reg tx_en;
        output reg rx_d;

       
        reg d, dd;
       
        always @ (posedge clk or negedge rst_n)
                begin
                        if (!rst_n)
                                begin
                                        d <= 1'b1;
                                        dd <= 1'b1;
                                end
                        else
                                begin
                                        d <= rs232_rx;
                                        dd <= d;
                                end
                end
       
        assign rx_en = dd & (~d);

       
        reg rx_data;
       
        always @ (posedge clk or negedge rst_n)
                begin
                        if (!rst_n)
                                begin
                                        rx_data <= 8'd0;
                                        rx_d <= 8'd0;
                                end
                        else
                                begin
                                        if (rx_sel_data)
                                                begin
                                                        case (rx_num)
                                                        0        :        ;
                                                        1        :        rx_data <= rs232_rx;
                                                        2        :        rx_data <= rs232_rx;
                                                        3        :        rx_data <= rs232_rx;
                                                        4        :        rx_data <= rs232_rx;
                                                        5        :        rx_data <= rs232_rx;
                                                        6        :        rx_data <= rs232_rx;
                                                        7        :        rx_data <= rs232_rx;
                                                        8        :        rx_data <= rs232_rx;
                                                        9        :        rx_d <= rx_data;
                                                        default        :        ;
                                                        endcase
                                                end
                                end
                end

        always @ (posedge clk or negedge rst_n)
                begin
                        if (!rst_n)
                                begin
                                        tx_en <= 0;
                                end
                        else
                                begin
                                        if (rx_sel_data && (rx_num == 4'd9))
                                                tx_en <= 1;
                                        else
                                                tx_en <= 0;
                                end
                end
               
endmodule

lcytms 发表于 2016-11-24 18:01:21

新建发送端口速率控制逻辑bps_tx.v模块。
编写bps_tx模块代码如下。
module bps_tx (clk, rst_n, tx_en, tx_sel_data, tx_num);

        input clk, rst_n;
        input tx_en;
       
        output reg tx_sel_data;
        output reg tx_num;

        parameter bps_div = 13'd5208;
        parameter bps_div_2 = 13'd2604;
       
        reg flag;
       
        always @ (posedge clk or negedge rst_n)
                begin
                        if (!rst_n)
                                begin
                                        flag <= 0;
                                end
                        else
                                begin
                                        if (tx_en)
                                                begin
                                                        flag <= 1;
                                                end
                                        else
                                                begin
                                                        if (tx_num == 4'd10)
                                                                flag <= 0;
                                                end
                                end
                end

               
        reg cnt;
               
        always @ (posedge clk or negedge rst_n)
                begin
                        if (!rst_n)
                                begin
                                        cnt <= 13'd0;
                                end
                        else
                                begin
                                        if (!flag)
                                                begin
                                                        cnt <= 13'd0;
                                                end
                                        else
                                                begin
                                                        if (cnt < bps_div - 1)
                                                                begin
                                                                        cnt <= cnt + 13'd1;
                                                                end
                                                        else
                                                                begin
                                                                        cnt <= 13'd0;
                                                                end
                                                end
                                end
                end
               
               
        always @ (posedge clk or negedge rst_n)
                begin
                        if (!rst_n)
                                begin
                                        tx_sel_data <= 1'b0;
                                end
                        else
                                begin
                                        if (cnt == bps_div_2 - 1)
                                                begin
                                                        tx_sel_data <= 1'b1;
                                                end
                                        else
                                                begin
                                                        tx_sel_data <= 1'b0;
                                                end
                                end
                end
               
        always @ (posedge clk or negedge rst_n)
                begin
                        if (!rst_n)
                                begin
                                        tx_num <= 4'd0;
                                end
                        else
                                begin
                                        if (!flag)
                                                begin
                                                        tx_num <= 4'd0;
                                                end
                                        else
                                                begin
                                                        if (tx_num == 4'd10)
                                                                begin
                                                                        tx_num <= 4'd0;
                                                                end
                                                        else
                                                                begin
                                                                        if (tx_sel_data)
                                                                                tx_num <= tx_num + 4'd1;
                                                                end
                                                end
                                end
                end

endmodule

lcytms 发表于 2016-11-24 18:04:55

新建发送逻辑uart_tx.v模块。
编写uart_tx模块代码如下。
module uart_tx (clk, rst_n, tx_sel_data, tx_num, tx_d, rs232_tx);

        input clk, rst_n;
        input tx_sel_data;
        input tx_num;
        input tx_d;
       
        output reg rs232_tx;

        always @ (posedge clk or negedge rst_n)
                begin
                        if (!rst_n)
                                begin
                                        rs232_tx <= 1'b1;
                                end
                        else
                                begin
                                        if (tx_sel_data)
                                                begin
                                                        case (tx_num)
                                                        0        :        rs232_tx <= 1'b0;
                                                        1        :        rs232_tx <= tx_d;
                                                        2        :        rs232_tx <= tx_d;
                                                        3        :        rs232_tx <= tx_d;
                                                        4        :        rs232_tx <= tx_d;
                                                        5        :        rs232_tx <= tx_d;
                                                        6        :        rs232_tx <= tx_d;
                                                        7        :        rs232_tx <= tx_d;
                                                        8        :        rs232_tx <= tx_d;
                                                        9        :        rs232_tx <= 1'b1;
                                                        default        :        rs232_tx <= 1'b1;
                                                        endcase
                                                end
                                end
                end
       
endmodule
页: 1 [2] 3 4
查看完整版本: FPGA初级课程第二十讲 UART