查看: 266|回复: 1

[原创] 从零开始学FPGA我的第八个实验(上2.0)(记录一下)

[复制链接]

19

主题

2

好友

370

积分

秀才

Rank: 3Rank: 3

  • TA的每日心情
    开心
    2016-9-21 20:33
  • 签到天数: 29 天

    [LV.4]偶尔看看III

    发表于 2016-7-28 21:38:12 |显示全部楼层
    从零开始学FPGA我的第八个实验(上2.0)(记录一下)
    UART_TX模块
    1. module uart_tx(Clk,Rst_n,data,bps_set,send_en,TX,done);
    2.                
    3.                 input Clk;//系统时钟
    4.                 input Rst_n;//复位
    5.                 input [7:0]data;//要发送的数据
    6.                
    7.                 input [2:0]bps_set;//波特率设置
    8.            input send_en;//发送使能
    9.                
    10.                 output reg  TX;//UART_TX
    11. reg uart_state;//TX口的状态
    12. reg done;
    13.                
    14.                 reg bps_clk;//波特率时钟
    15.                 reg [15:0]bps_DR;//分频计数的最大值
    16.            reg [3:0]bps_cnt;        //波特率时钟计数器
    17.                
    18.                 localparam Start = 1'b0;//开始发送数据的标志
    19.                 localparam Stop = 1'b1;//发送结束的标志
    20.                 reg [7:0] data_r;//缓存要发送的数据 以防止在发送过程中数据被修改
    21.                
    22.                
    23. //波特率设置模块通过bps_set[0:3]来选择波特率 bps_DR 其实是一个查找表
    24.       always @(posedge Clk or negedge Rst_n )
    25.       if(!Rst_n)
    26.          bps_DR  <= 16'd5207;//默认的波特率是9600
    27.            else begin
    28.                    case (bps_set)
    29.                         0: bps_DR <= 16'd5207;//9600
    30.                         1: bps_DR <= 16'd2603;//19200
    31.                         2: bps_DR <= 16'd1301;//38400
    32.                         3: bps_DR <= 16'd807;//57000
    33.                         4: bps_DR <= 16'd433;//115200
    34.                         default : bps_DR  <= 16'd5207;//其他情况的波特率是9600
    35.          endcase
    36.       end                
    37. //分频计数器 根据上面选择的波特率 也就是分频计数的最大值来实现计数的范围达到分频
    38.       reg[15:0] div_cnt;
    39.                 always@(posedge Clk or negedge Rst_n)
    40.                 if(!Rst_n)
    41.                       div_cnt <= 16'd0;
    42.                 else if(uart_state)begin //如果有发送使能则开始计数
    43.                     if(div_cnt == bps_DR)
    44.                         div_cnt <= 16'd0;
    45.                     else
    46.                    div_cnt <= div_cnt + 1'b1;
    47.                     end
    48.                 else
    49.                                 div_cnt <= 16'b0;
    50. //产生bps时钟        由bps_cnt 计数实现不同波特率bps_clk 就是最终实现的波特率的时钟信号                       
    51.       always@(posedge Clk or negedge Rst_n)
    52.                 if(!Rst_n)
    53.                    bps_clk <= 1'b0;
    54.                 else if(div_cnt == 16'd1)//防止滞后的情况
    55.                    bps_clk <= 1'b1;
    56.                 else
    57.                         bps_clk <= 1'b0;
    58. //11MUX 模块
    59.       always @(posedge Clk or negedge Rst_n)
    60.                    if(!Rst_n)
    61.                            bps_cnt <= 4'd0;
    62.                         else if(bps_cnt == 4'd11)//一个字节的数据发送完成
    63.                            bps_cnt <= 4'd0;
    64.                         else if(bps_clk)//一个bps_clk的高电平
    65.                            bps_cnt  <= bps_cnt + 1'b1;
    66.                                 else
    67.                         bps_cnt <= bps_cnt;
    68.                                   
    69.         always @(posedge Clk or negedge Rst_n)
    70.                 if(!Rst_n)
    71.                   uart_state <= 1'b0;//复位的时候uart的状态为0
    72.                 else if (send_en)
    73.               uart_state <= 1'b1;
    74.            else if(bps_cnt == 4'd11)//当发送了11位数据的时候uart的状态是0
    75.          uart_state <= 1'b0;
    76.            else
    77.          uart_state <= uart_state;
    78.                        
    79. always@(posedge Clk or negedge Rst_n)
    80.         if(!Rst_n)
    81.                 Tx_Done <= 1'b0;
    82.         else if(bps_cnt == 4'd11)
    83.                 Tx_Done <= 1'b1;
    84.         else
    85.                 Tx_Done <= 1'b0;                       
    86.                                   
    87.                                   
    88.                                   
    89. //先缓存要发送的数据 防止数据在发送过程中被修改了
    90.                         always @(posedge Clk or negedge Rst_n)
    91.          if(!Rst_n)
    92.                          data_r <= 8'd0;
    93.                          else if(send_en )
    94.                             data_r <= data;
    95.                     else
    96.                            data_r <= data_r;
    97.         //最终数据发送的模块                       
    98.       always@(posedge Clk or negedge Rst_n)               
    99.                  if(!Rst_n)
    100.                   TX <= 1'b1;
    101.                   else begin
    102.                        case(bps_cnt)
    103.                                 0:TX <= 1'b1;
    104.                                 1:TX <= Start;
    105.                                 2:TX <= data[0];
    106.                                 3:TX <= data[1];
    107.                                 4:TX <= data[2];
    108.                                 5:TX <= data[3];
    109.                                 6:TX <= data[4];
    110.                                 7:TX <= data[5];
    111.                                 8:TX <= data[6];
    112.                                 9:TX <= data[7];
    113.                                 10:TX <=Stop;
    114.                                 default: TX <= 1'b1;
    115.                              endcase
    116.                         end               
    117. endmodule
    复制代码
    testbeach 代码:
    1. `timescale 1ns/1ns
    2. `define clk_period 20

    3. module uart_tx_tb;
    4.    reg Clk;
    5.         reg Rst_n;
    6.         reg [7:0]data;
    7.         reg [2:0]bps_set;
    8.         reg send_en;
    9.        
    10.         wire TX;
    11.         wire done;
    12. //例化
    13.   uart_tx uart_tx0(
    14.           .Clk(Clk),
    15.           .Rst_n(Rst_n),
    16.           .data(data),
    17.           .bps_set(bps_set),
    18.           .send_en(send_en),
    19.           .TX(TX),
    20.           .done(done)
    21.   );
    22.   
    23.                 initial Clk = 1;
    24.                 always # (`clk_period/2)Clk =~ Clk;//产生50MHZ的时钟
    25.                
    26.                 initial begin
    27.                     Rst_n = 1'b0;
    28.                          data = 8'd0;
    29.                          send_en = 1'd0;
    30.                          bps_set = 3'd2;
    31.                          #(`clk_period*20 +1)//+1便于仿真的时候看波形
    32.                          Rst_n = 1'b1;
    33.                          #(`clk_period*50);
    34.                          data = 8'h2b;
    35.                          send_en =1'd1;
    36.                          #`clk_period;
    37.                          send_en =1'd0;
    38.                         @( posedge done)
    39.                          #(`clk_period*2000);
    40.                          data = 8'h99;
    41.                          send_en = 1'd1;
    42.                          # `clk_period ;
    43.                          send_en = 1'd0;
    44.                          #10000;
    45.                          $stop;       
    46.      end
    47. endmodule
    复制代码
    RTL仿真:

    20160728213736.png



    回复

    使用道具 举报

    5

    主题

    1

    好友

    205

    积分

    秀才

    Rank: 3Rank: 3

    该用户从未签到

    发表于 2016-7-29 14:38:38 |显示全部楼层
    态度非常好,对自己的要求就应该高些,有规划有计划
    回复

    使用道具 举报

    您需要登录后才可以回帖 登录 | 立即注册

    关闭

    站长推荐上一条 /6 下一条


    手机版|爱板网 |网站地图  

    GMT+8, 2016-12-8 06:18 , Processed in 0.188656 second(s), 11 queries , Memcache On.

    苏公网安备 32059002001056号

    Powered by Discuz!

    回顶部