基于fpga uart学习笔记

2018年7月24日

uart 接收 部分测试成功,多谢开源骚客 邓堪文老师 ,想学的同学可以微信公众号搜索开源骚客

好啦!言归正传。

 

1.先附上老师的时序图,自己有点懒不想画,rx_t、rx_tt、rx_ttt分别对应源码中的rx_r1、rx_r2、rx_r2。

认真理解时序图,代码具体怎么实现就好理解了。

2.需要说明的是baud_cnt这个计数器,他是波特率的计数器,计数原理了解这个公式

3.剩下的就自己结合一下源码

  1 `define SIM
  2 
  3 module  uart_rx(
  4           //system signale
  5           input                       sclk            ,            
  6           input                        s_rst_n            ,
  7           //uart interface
  8           input                        rs232_rx        ,
  9           //other
 10           output    reg        [7:0]    rx_data            ,
 11           output    reg                po_flag
 12 
 13 );
 14 
 15 //-----------------------------------------------------------------\
 16 //***********Difine Parameter and Internal signals*****************
 17 //-----------------------------------------------------------------/
 18 `ifndef SIM
 19 localparam        BAUD_END            =    5207        ;
 20 `else
 21 localparam        BAUD_END            =    55            ;
 22 `endif
 23 localparam        BAUD_M                =    BAUD_END/2-1    ;
 24 localparam        BIT_END                =    8            ;
 25 
 26 
 27 reg                                    rx_r1            ;
 28 reg                                    rx_r2            ;
 29 reg                                    rx_r3            ;
 30 reg                                    rx_flag            ;
 31 reg            [12:0]                    baud_cnt        ;
 32 reg                                    bit_flag        ;
 33 reg            [3:0]                    bit_cnt            ;
 34 
 35 //==================================================================\
 36 //****************Main   Code *********************************
 37 //==================================================================/
 38 
 39 //捕获起始位下降沿
 40 assign rx_neg   =        ~rx_r2    & rx_r3;
 41 
 42 always @(posedge sclk ) begin
 43         rx_r1    <=        rs232_rx;
 44         rx_r2    <=        rx_r1;
 45         rx_r3    <=        rx_r2;
 46 end 
 47 
 48 //接收数据标志
 49 always @(posedge sclk or negedge s_rst_n) begin
 50         if(s_rst_n == 1'b0)
 51                 rx_flag <=    1'b0;
 52         else if(rx_neg == 1'b1)
 53                 rx_flag    <=    1'b1;
 54         else if(bit_cnt == 4'd0 && baud_cnt    == BAUD_END)
 55                 rx_flag    <=  1'b0;
 56 end
 57 
 58 //波特率生成
 59 always @(posedge sclk or negedge s_rst_n ) begin
 60         if(s_rst_n == 1'b0)
 61                 baud_cnt <= 13'd0;
 62         else if(baud_cnt == BAUD_END)
 63                 baud_cnt <= 13'd0;
 64         else if(rx_flag == 1'b1)
 65                 baud_cnt <= baud_cnt + 1'b1;
 66         else
 67                 baud_cnt <= 13'd0;
 68 end
 69 
 70 //位接收有效
 71 always @(posedge sclk or negedge s_rst_n) begin
 72         if(s_rst_n == 1'b0)
 73                 bit_flag <= 1'b0;
 74         else if (baud_cnt == BAUD_M)
 75                 bit_flag <= 1'b1;
 76         else
 77                 bit_flag <= 1'b0;
 78 end
 79  
 80 //位计数
 81 always @(posedge sclk or negedge s_rst_n) begin
 82         if(s_rst_n == 1'b0)
 83                 bit_cnt <= 4'd0;
 84         else if(bit_flag == 1'b1 && bit_cnt == BIT_END )
 85                 bit_cnt <= 4'd0;
 86         else if(bit_flag == 1'b1)
 87                 bit_cnt <= bit_cnt + 1'b1;
 88         
 89 end
 90 
 91 //串转并
 92 always @(posedge sclk or s_rst_n) begin
 93         if(s_rst_n == 1'b0)
 94                 rx_data <= 8'd0;
 95         else if (bit_flag == 1'b1 && bit_cnt >= 4'd1)
 96                 rx_data <= {rx_r2, rx_data[7:1]};
 97 end 
 98 //一位接收完成
 99 always @(posedge sclk or s_rst_n) begin
100         if(s_rst_n == 1'b0)
101                 po_flag <= 1'b0;
102         else if(bit_cnt == BIT_END && bit_flag == 1'b1)
103                 po_flag <= 1'b1;
104         else
105                 po_flag <= 1'b0;
106 end
107 
108 endmodule

4.源码这儿需要理解一下 `ifndef ,`else,`endif。这个是预编译处理,详情可以看这位大佬

https://blog.csdn.net/hision_fpgaer/article/details/50909653

5.测试文件,这里需要理解tast使用,以及外部数据文件的的用法(第26行)以及将文件里的数据如何存入二维数组中,tx_data文件就是一般的文本文件,这里设计的技巧太多,可以自己去查询一下。

 

 

 1 `timescale            1ns/1ns
 2 module    tb_uart_rx;
 3 
 4 reg                sclk;
 5 reg                s_rst_n;
 6 reg                rs232_tx;
 7 
 8 wire            po_flag;
 9 wire    [7:0]    rx_data;
10 
11 reg [7:0] mem_a[4:0];
12 
13 initial begin
14         sclk     = 1;
15         s_rst_n     = 0;
16         rs232_tx = 1;
17         #100
18         s_rst_n     = 1;
19         #100
20         tx_tyte();
21 end
22 
23 always # 10 sclk = ~sclk;
24 
25 
26 initial  $readmemh("./tx_data.txt",mem_a);
27 
28 task  tx_tyte();
29         integer i ;
30         for(i = 0;i < 4; i = i +1)  begin
31            tx_bit(mem_a[i]);
32         end
33 
34 endtask
35 
36 
37 task    tx_bit(
38                 input        [7:0] data
39                 );
40         integer i;
41         for(i = 0; i < 10; i = i+1)begin
42             case(i)
43                 0:        rs232_tx <= 1'b0;
44                 1:        rs232_tx <= data[0];
45                 2:        rs232_tx <= data[1];
46                 3:        rs232_tx <= data[2];
47                 4:        rs232_tx <= data[3];
48                 5:        rs232_tx <= data[4];
49                 6:        rs232_tx <= data[5];
50                 7:        rs232_tx <= data[6];
51                 8:        rs232_tx <= data[7];
52                 9:        rs232_tx <= 1'b1;
53             endcase
54             #560;
55         end
56 endtask
57 
58 uart_rx        uart_rx_inst(
59           //system signale
60           .sclk                (sclk        ),            
61           .s_rst_n            (s_rst_n    ),
62           //uart interface
63           .rs232_rx            (rs232_tx    ),
64           //other
65           .rx_data            (rx_data    ),
66           .po_flag            (po_flag    )
67 
68 );
69 
70 
71 endmodule

 

 

总结一些自己,大一下学期期末左右接触到fpga,自己就爱好电子设计,大一一来就学了51单片机,下学期看着自己同学都报班32,学的都很好,而自己呢还在玩51,弄3D打印机,那个时候挺迷的。

后来不小心看到了fpga,自己仔细去查了,也与32做了比较,斟酌了很久,最后还是下决心学fpga,但是那个我是什么处境呢,同级的一起玩的32都会做很多东西了,自己有小小羞耻感,关键是学校没有人学fpga或者说没有人学的可以的,如果要学的话只能孤军奋战。

后来还是下决心买了板子,自学了一段时间,刚好暑假国赛,我也参加了,打击很大啊,最后还用51做,太丢人了。国赛完,我就自己瞎学fpga,一直因为对fpga的真正的喜爱,以及他那强大而又神秘能力支撑着我学到现在。

刚开始都是看着大佬们的博客一路学习过来,这学期终于翻身了开始自己写博客了,虽然技术含量有点低,哈哈哈,但是还是很开心。到现在差不多学fpga一年了,说实话fpga也让我害怕,不光是她太难驾驭还有的是没啥成就,看其他人啪啪啪的一下子做一堆东西,而自己控制个舵机都吃力。

现在这个暑假,马上又要大三了,趁着时间很多,好好重头在干一次,或许注定是孤独的,我爱你fpga,希望你也爱我,啦啦啦啦啦啦啦!!!!!!!!!!!!!!

完工回去睡觉,fpga等我明天再来宠幸你!

 

2018年7月26日

uart发送部分以及收发整合,其实是昨天就完事儿了,有事给耽搁了,今天再补来得及。

先说发送部分

1.还是先看时序图,信号都不用解释,直接看图。

2.仔细的同学发现bit_flag这个信号和接收的不一样,这次是baud_cnt波特率计数器记完再触发,而接收的是计数到一半触发,这两种方式作用相同,只是后者稳定一下,自己也可以改。

下面附上接收的源码

  1// `define SIM
  2 module uart_tx(
  3         //system signal
  4         input                sclk            ,
  5         input                s_rst_n            ,
  6         //uart interface
  7         output        reg        rs232_tx        ,
  8         //other
  9         input                tx_trig            ,
 10         input        [7:0]    tx_data
 11  );
 12 
 13 //-----------------------------------------------------------------\
 14 //***********Difine Parameter and Internal signals*****************
 15 //-----------------------------------------------------------------/
 16 
 17 `ifndef SIM
 18 localparam        BAUD_END            =    5207        ;
 19 `else
 20 localparam        BAUD_END            =    56            ;
 21 `endif
 22 
 23 localparam        BAUD_M                =    BAUD_END/2-1    ;
 24 localparam        BIT_END                =    8            ;
 25 
 26 reg             [7:0]            tx_data_r            ;
 27 reg                                tx_flag                ;
 28 reg                [12:0]            baud_cnt            ;
 29 reg                                bit_flag            ;
 30 reg                [3:0]            bit_cnt                ;
 31 
 32 
 33 //==================================================================\
 34 //****************Main   Code *********************************
 35 //==================================================================/
 36 //tx_data_r
 37 always @(posedge sclk or negedge s_rst_n) begin
 38         if(s_rst_n == 1'b0)
 39                 tx_data_r    <=    8'd0;
 40         else if (tx_trig == 1'b1 && tx_flag == 1'b0)
 41                 tx_data_r    <=    tx_data;
 42 end
 43 
 44 //tx_flag
 45 always @(posedge sclk or negedge s_rst_n) begin
 46         if(s_rst_n == 1'b0)
 47                 tx_flag        <=    1'b0;
 48         else if(tx_trig == 1'b1 )
 49                 tx_flag        <=    1'b1;
 50         else if (bit_cnt == BIT_END && bit_flag == 1'b1)
 51                 tx_flag        <= 1'b0;
 52 end
 53 
 54 //波特率计数器
 55 always @(posedge sclk or negedge s_rst_n) begin
 56         if(s_rst_n == 1'b0)
 57                 baud_cnt    <= 13'd0;
 58         else if (baud_cnt  == BAUD_END)
 59                 baud_cnt    <= 13'd0;
 60         else if(tx_flag == 1'b1)
 61                 baud_cnt    <= baud_cnt +1'b1;
 62         else    
 63                 baud_cnt     <= 13'd0;
 64 end
 65 
 66 //bit_flag
 67 always @(posedge sclk or negedge s_rst_n) begin
 68         if(s_rst_n == 1'b0)
 69                 bit_flag <= 1'b0;
 70         else if(baud_cnt == BAUD_END)
 71                 bit_flag <= 1'b1;
 72         else
 73                 bit_flag <= 1'b0;    
 74 end
 75 
 76 //bit_cnt
 77 always @(posedge sclk or negedge s_rst_n) begin
 78         if(s_rst_n == 1'b0)
 79                 bit_cnt  <= 4'd0;
 80         else if(bit_flag == 1'b1 && bit_cnt == BIT_END)
 81                 bit_cnt <= 4'd0;
 82         else if (bit_flag == 1'b1)
 83                 bit_cnt <= bit_cnt +1'b1;
 84                 
 85 end
 86 
 87 //rs232_tx
 88 always @(posedge sclk or negedge s_rst_n) begin
 89         if(s_rst_n == 1'b0)
 90                 rs232_tx <= 1'b1;
 91         else if(tx_flag == 1'b1)
 92                 case(bit_cnt)
 93                         0:        rs232_tx    <=    1'b0;
 94                         1:        rs232_tx    <=    tx_data_r[0];
 95                         2:        rs232_tx    <=    tx_data_r[1];
 96                         3:        rs232_tx    <=    tx_data_r[2];
 97                         4:        rs232_tx    <=    tx_data_r[3];
 98                         5:        rs232_tx    <=    tx_data_r[4];
 99                         6:        rs232_tx    <=    tx_data_r[5];
100                         7:        rs232_tx    <=    tx_data_r[6];
101                         8:        rs232_tx    <=    tx_data_r[7];
102                         default:rs232_tx    <=    1'b1;
103                 endcase
104         else
105                 rs232_tx    <=    1'b1;
106 end
107 
108 endmodule

3.下面附上接收部分的激励源码

 1 `timescale        1ns/1ns
 2 
 3 module tb_uart_tx;
 4 
 5 reg                sclk;
 6 reg                s_rst_n;
 7 reg                tx_trig;
 8 reg        [7:0]    tx_data;
 9 wire            rs232_tx;
10 //----------------------------------difine system signales-----------------
11 initial begin
12         sclk    =    1;
13         s_rst_n    =    0;
14         #100
15         s_rst_n    =    1;
16 end
17 
18 always #10    sclk    =    ~sclk;
19 
20 //-----------------------------------------------------------------------
21 initial begin
22         tx_data <= 8'd0;
23         tx_trig <= 0;
24         
25         #200
26         tx_trig <= 1'b1;
27         tx_data <= 8'h55;
28         #20
29         tx_trig <= 1'b0;
30         
31         #20000
32         tx_trig <= 1'b1;
33         tx_data <= 8'h78;
34         #20
35         tx_trig <= 1'b0;
36         
37         #20000
38         tx_trig <= 1'b1;
39         tx_data <= 8'h53;
40         #20
41         tx_trig <= 1'b0;
42 
43 end
44 
45 uart_tx        uart_tx_inst(
46         //system signal
47         .sclk                (sclk        ),
48         .s_rst_n            (s_rst_n    ),
49         //uart interface
50         .rs232_tx            (rs232_tx    ),
51         //other
52         .tx_trig            (tx_trig    ),
53         .tx_data            (tx_data    )
54  );
55 
56 endmodule

最后收发整合前面接收和发送部分都做好的话,这个就很简单了,但是这儿注意一个细节,把模块第一行的   ” `define SIM“给注释掉,这个是仿真用的,不然烧写到板卡不对

 1 module  uart_top(
 2     //system signals
 3     input            sclk        ,
 4     input            s_rst_n        ,
 5     //UART Interface
 6     input            rs232_rx    ,
 7     output  wire    rs232_tx
 8 );
 9 
10 //-----------------------------------------------------------------\
11 //***********Difine Parameter and Internal signals*****************
12 //-----------------------------------------------------------------/
13 wire    [7:0]        rx_data        ;
14 wire                tx_trig        ;
15 //==================================================================\
16 //****************Main   Code *********************************
17 //==================================================================/
18 
19 uart_rx        uart_rx_inst(
20           //system signale
21           .sclk                (sclk        ),            
22           .s_rst_n            (s_rst_n    ),
23           //uart interface
24           .rs232_rx            (rs232_rx    ),
25           //other
26           .rx_data            (rx_data    ),
27           .po_flag            (tx_trig    )
28 
29 );
30 
31 
32 uart_tx        uart_tx_inst(                                
33         //system signal                                  
34         .sclk                (sclk        ),               
35         .s_rst_n            (s_rst_n    ),               
36         //uart interface                                 
37         .rs232_tx            (rs232_tx    ),               
38         //other                                          
39         .tx_trig            (tx_trig    ),               
40         .tx_data            (rx_data    )
41  );
42  
43  
44 endmodule
uart_top

uart学习到此为止了,已完成

 

转载于:https://www.cnblogs.com/hqz68/p/9362964.html

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值