zoukankan      html  css  js  c++  java
  • Uart的Verilog建模

    开发工具:Quartus II 9.1;

    仿真软件:Questa Sim 10.0c;

    硬件平台:Terasic DE2-115(EP2C35F672C6);

    外设:MAX3232;

    3个工程文件:"uart_baud.v" + "uart_rx.v" + "uart_tx.v";

    2个仿真文件::"uart_rx_tsb.v" + "uart_tx_tsb.v"

    设计思路:略

    注意事项:波特率模块采样脉冲式分频;

         接收模块仅在一个时刻采样,若需要考虑误码率可在状态机里插入0-1计数器;

    partI:uart_baud.v

     1 `timescale 1 ns / 1 ps
     2 `define SYS_CLK    50000000
     3 `define BAUD    115200
     4 `define DIV    `SYS_CLK/`BAUD/16
     5 module uart_baud(
     6                             sys_clk,
     7                             sys_rst_n,
     8                             sys_baud16_o,
     9                             sys_baud_o
    10                             );
    11 input sys_clk;
    12 input sys_rst_n;
    13 output sys_baud16_o;
    14 output sys_baud_o;
    15 
    16 reg [4:0] baud16_cnt =0;
    17 
    18 always @ (posedge sys_clk) begin
    19 if(1'b0 == sys_rst_n) baud16_cnt <= 0;
    20 else if(baud16_cnt == `DIV-1) baud16_cnt <= 0;
    21 else baud16_cnt <= baud16_cnt + 1'd1;
    22 end
    23 
    24 reg [3:0] baud_cnt = 0;
    25 always @ (posedge sys_clk) begin
    26 if(1'b0 == sys_rst_n)    baud_cnt <= 0;
    27 else if(sys_baud16_o == 1'b1)    baud_cnt <= baud_cnt + 1'd1;
    28 else baud_cnt <= baud_cnt;
    29 end
    30 
    31 assign sys_baud16_o = (baud16_cnt == `DIV-1)?1'b1:1'b0;
    32 assign sys_baud_o = ((baud_cnt == 4'd15) && (sys_baud16_o == 1'b1))?1'b1:1'b0;
    33 
    34 endmodule

    partII:uart_tx.v

      1 `timescale 1 ns / 1 ps
      2 `define SIM
      3 module uart_tx(
      4                         sys_clk,
      5                         sys_rst_n,
      6                         sys_baud_i,
      7                         sys_wreq_i,
      8                         sys_data_i,
      9                         uart_tx,
     10                         uart_tx_idle_o,
     11                         uart_tx_ack_o
     12                         );
     13 input sys_clk;
     14 input sys_rst_n;
     15 input sys_baud_i;
     16 input sys_wreq_i;
     17 input [7:0] sys_data_i;
     18 output uart_tx;
     19 output uart_tx_idle_o;
     20 output uart_tx_ack_o;
     21 `ifdef    SIM
     22     parameter ST_WIDTH = 40;
     23     parameter IDLE = "IDLE.",
     24                     START = "START",
     25                     SHIFT = "SHIFT",
     26                     CHECK = "CHECK",
     27                     END = "END..";
     28 `else
     29 parameter ST_WIDTH = 5;
     30 parameter IDLE = 5'b0_0001,
     31                 START = 5'b0_0010,
     32                 SHIFT = 5'b0_0100,
     33                 CHECK = 5'b0_1000,
     34                 END = 5'b1_0000;
     35 `endif
     36 parameter EVEN = 1'd0;
     37 
     38                 
     39 reg [ST_WIDTH-1:0] c_st = IDLE;
     40 reg [ST_WIDTH-1:0] n_st = IDLE;
     41 reg check_bit = 0;                //奇偶检验位
     42 reg [2:0] bit_cnt = 0;            //计数8个比特
     43 reg uart_tx=1;
     44 
     45 always @ (posedge sys_clk) begin
     46 if(sys_rst_n == 1'b0)    c_st <= IDLE;
     47 else c_st <= n_st;
     48 end
     49 
     50 always @ (*) begin
     51         n_st = IDLE;
     52         case(c_st)
     53         IDLE:begin
     54                     n_st = (1'b1 == sys_wreq_i)?START:IDLE;end
     55         START:begin
     56                     n_st = (sys_baud_i == 1'b1)?SHIFT:START;end
     57         SHIFT:begin
     58                     n_st = ((bit_cnt == 3'd7) && (sys_baud_i == 1'b1))?CHECK:SHIFT;end
     59         CHECK:begin
     60                         n_st = (sys_baud_i == 1'b1)?END:CHECK;end
     61         END:begin
     62                         n_st = (sys_baud_i == 1'b1)?IDLE:END;end
     63         default:begin
     64                         n_st = IDLE;end
     65         endcase
     66 end
     67 
     68 always @ (posedge sys_clk) begin
     69 if(1'b0 == sys_rst_n) begin
     70                                 bit_cnt <= 3'd7;
     71                                 uart_tx <= 1;
     72                                 check_bit <= EVEN;
     73                                 end
     74 else begin
     75         case(n_st)
     76         IDLE:begin
     77                     bit_cnt <= 3'd7;
     78                     uart_tx <= 1;
     79                     check_bit <= EVEN;end
     80         START:begin
     81                         bit_cnt <= 3'd7;
     82                         uart_tx <= 0;
     83                         check_bit <= EVEN;end
     84         SHIFT:begin
     85                         uart_tx <= sys_data_i[bit_cnt];
     86                         check_bit <= (sys_baud_i == 1'b1)?check_bit^sys_data_i[bit_cnt]:check_bit;
     87                         bit_cnt <= (sys_baud_i == 1'b1)?bit_cnt + 1'd1:bit_cnt;end
     88         CHECK:begin
     89                         uart_tx <= check_bit;
     90                         check_bit <= check_bit;
     91                         bit_cnt <= 3'd7;end
     92         END:begin
     93                         bit_cnt <= 3'd7;
     94                         check_bit <= check_bit;
     95                         uart_tx <= 1;end
     96         default:begin
     97                         bit_cnt <= bit_cnt;
     98                         check_bit <= check_bit;
     99                         uart_tx <= uart_tx;end
    100         endcase
    101         end
    102 end
    103 
    104 //assign
    105 assign uart_tx_idle_o = (c_st == IDLE)?1'b1:1'b0;
    106 assign uart_tx_ack_o = ((c_st == END) && (sys_baud_i == 1'b1))?1'b1:1'b0;
    107 
    108 endmodule

    partIII:uart_rx.v

      1 `timescale 1 ns / 1 ps
      2 `define SIM
      3 module uart_rx(
      4                         sys_clk,
      5                         sys_rst_n,
      6                         uart_rx,
      7                         sys_baud16_i,
      8                         uart_rx_idle_o,
      9                         uart_rx_ack_o,
     10                         uart_rx_error_o,
     11                         sys_data_o
     12                         );
     13 input sys_clk;
     14 input sys_rst_n;
     15 input uart_rx;
     16 input sys_baud16_i;
     17 output uart_rx_idle_o;
     18 output uart_rx_ack_o;
     19 output uart_rx_error_o;
     20 output [7:0] sys_data_o;
     21 parameter EVEN = 1'd0;
     22 `ifdef SIM
     23     parameter ST_WIDTH = 40;
     24     parameter IDLE = "IDLE.",
     25                     START = "START",
     26                     SHIFT = "SHIFT",
     27                     CHECK = "CHECK",
     28                     END = "END..";
     29 `else
     30     parameter ST_WIDTH = 5;
     31     parameter IDLE = 5'b0_0001,
     32                 START = 5'b0_0010,
     33                 SHIFT = 5'b0_0100,
     34                 CHECK = 5'b0_1000,
     35                 END = 5'b1_0000;
     36 `endif
     37 
     38 //capture the negedge of rx
     39 reg rx_r0=1;
     40 wire rx_trigger;
     41 
     42 always @ (posedge sys_clk) begin
     43 if(1'b0 == sys_rst_n)    rx_r0 <= 1;
     44 else if(1'b1 == sys_baud16_i)    rx_r0 <= uart_rx;
     45 else    rx_r0 <= rx_r0;
     46 end
     47 
     48 assign rx_trigger = ~uart_rx & rx_r0;
     49 
     50 //fsm
     51 reg [ST_WIDTH-1:0] c_st = IDLE;
     52 reg [ST_WIDTH-1:0] n_st = IDLE;
     53 reg [3:0] bit_cnt = 4'd0;
     54 reg [3:0] clk_cnt = 4'd0;
     55 reg [7:0] sys_data = 8'd0;
     56 reg check_bit = EVEN;
     57 reg error = 0;
     58 //fsm-1
     59 always @ (posedge sys_clk) begin
     60 if(sys_rst_n == 1'b0)    c_st <= IDLE;
     61 else c_st <= n_st;
     62 end
     63 //fsm-2
     64 always @ (*) begin
     65     n_st = IDLE;
     66     case(c_st)
     67     IDLE:begin
     68             n_st = (rx_trigger == 1'b1)?START:IDLE;end
     69     START:begin
     70                 n_st = (clk_cnt == 4'd15 && sys_baud16_i == 1'b1)?SHIFT:START;end
     71     SHIFT:begin
     72                 n_st = ((clk_cnt == 4'd15)&&(bit_cnt == 4'd8))?CHECK:SHIFT;end
     73     CHECK:begin
     74                 n_st = (clk_cnt == 4'd15 && bit_cnt == 4'd9)?END:CHECK;end
     75     END:begin
     76                 n_st = (clk_cnt == 4'd15 && bit_cnt == 4'd10)?IDLE:END;end
     77     default:begin
     78                     n_st = IDLE;end
     79     endcase
     80 end
     81 //fsm-3
     82 always @ (posedge sys_clk) begin
     83 if(sys_rst_n == 1'b0) begin
     84                                 sys_data <= 8'd0;
     85                                 error <= 0;
     86                                 clk_cnt <= 4'd0;
     87                                 bit_cnt <= 4'd0;
     88                                 check_bit <= EVEN;end
     89 else begin
     90         case(n_st)
     91         IDLE:begin
     92                     sys_data <= sys_data;
     93                     error <= 0;
     94                     clk_cnt <= 4'd0;
     95                     bit_cnt <= 4'd0;
     96                     check_bit <= EVEN;end
     97         START:begin
     98                     sys_data <= sys_data;
     99                     error <= 0;
    100                     clk_cnt <= (sys_baud16_i == 1'b1)?(clk_cnt+1'd1):clk_cnt;
    101                     bit_cnt <= 4'd0;
    102                     check_bit <= EVEN;end
    103         SHIFT:begin
    104                     sys_data <= ((sys_baud16_i == 1'b1)&&(clk_cnt == 4'd15))?{uart_rx,sys_data[7:1]}:sys_data;
    105                     error <= 0;
    106                     clk_cnt <= (sys_baud16_i)?clk_cnt+1'd1:clk_cnt;
    107                     bit_cnt <= ((sys_baud16_i)&&(clk_cnt == 4'd15))?bit_cnt+1'd1:bit_cnt;
    108                     check_bit <= ((sys_baud16_i)&&(clk_cnt == 4'd15))?check_bit^sys_data[bit_cnt]:check_bit;end
    109         CHECK:begin
    110                     sys_data <= sys_data;
    111                     error <= ((sys_baud16_i)&&(clk_cnt == 4'd15)&&(uart_rx!=check_bit))?1'b1:error;
    112                     clk_cnt <= (sys_baud16_i)?clk_cnt+1'd1:clk_cnt;
    113                     bit_cnt <= ((sys_baud16_i)&&(clk_cnt == 4'd15))?bit_cnt+1'd1:bit_cnt;
    114                     check_bit <=check_bit;end
    115         END:begin
    116                     sys_data <= sys_data;
    117                     error <= error;
    118                     clk_cnt <= (sys_baud16_i)?clk_cnt+1'd1:clk_cnt;
    119                     bit_cnt <= ((sys_baud16_i)&&(clk_cnt == 4'd15))?bit_cnt+1'd1:bit_cnt;
    120                     check_bit <= check_bit;end
    121         default:begin
    122                     sys_data <= sys_data;
    123                     error <= 0;
    124                     clk_cnt <= 4'd0;
    125                     bit_cnt <= 4'd0;
    126                     check_bit <= EVEN;end
    127         endcase
    128         end
    129 end
    130 
    131 //assign
    132 assign uart_rx_error_o = error;
    133 assign sys_data_o = sys_data;
    134 assign uart_rx_idle_o = (c_st == IDLE)?1'b1:1'b0;
    135 assign uart_rx_ack_o = ((c_st == END) && (sys_baud16_i == 1'b1) && (clk_cnt == 4'd15))?1'b1:1'b0;
    136 
    137 endmodule

    partIV:uart_tx_tsb.v

     1 `timescale 1 ns / 1 ps
     2 module uart_tx_tsb();
     3 reg sys_clk;
     4 reg sys_rst_n;
     5 
     6 reg [7:0] sys_data_i;
     7 reg sys_wreq_i;
     8 initial begin
     9 sys_clk=1;
    10 sys_data_i=0;
    11 sys_wreq_i=0;
    12 sys_rst_n=0;
    13 #100 sys_rst_n=1;
    14 end
    15 
    16 always begin
    17 #10 sys_clk=~sys_clk;end
    18 
    19 
    20 
    21 wire sys_baud16_o;
    22 wire sys_baud_o;
    23 
    24 uart_baud            u0(
    25                             .sys_clk( sys_clk ),
    26                             .sys_rst_n( sys_rst_n ),
    27                             .sys_baud16_o( sys_baud16_o ),
    28                             .sys_baud_o( sys_baud_o )
    29                             );
    30                             
    31 wire uart_tx;
    32 wire uart_idle_o;
    33 wire uart_ack_o;                            
    34 uart_tx                u1(
    35                         .sys_clk( sys_clk ),
    36                         .sys_rst_n( sys_rst_n ),
    37                         .sys_baud_i( sys_baud_o ),
    38                         .sys_wreq_i( sys_wreq_i ),
    39                         .sys_data_i( sys_data_i ),
    40                         .uart_tx( uart_tx ),
    41                         .uart_idle_o( uart_idle_o ),
    42                         .uart_ack_o( uart_ack_o )
    43                         );
    44                         
    45 always @ (posedge sys_clk) begin
    46 if(sys_rst_n == 1'b0) begin
    47                                 sys_wreq_i <= 1;
    48                                 sys_data_i <= 0;end
    49 else if(uart_ack_o) begin
    50                             sys_wreq_i <= 1;
    51                                 sys_data_i <= sys_data_i + 1'd1;end
    52 else begin
    53                             sys_wreq_i <= 0;
    54                                 sys_data_i <= sys_data_i;end
    55 end
    56 
    57 endmodule

    partV:uart_rx_tsb.v

     1 `timescale 1 ns / 1 ps
     2 module uart_rx_tsb();
     3 reg sys_clk;
     4 reg sys_rst_n;
     5 
     6 reg [7:0] sys_data_i;
     7 reg sys_wreq_i;
     8 initial begin
     9 sys_clk=1;
    10 sys_data_i=0;
    11 sys_wreq_i=0;
    12 sys_rst_n=0;
    13 #100000 sys_rst_n=1;
    14 end
    15 
    16 always begin
    17 #10 sys_clk=~sys_clk;end
    18 
    19 
    20 
    21 wire sys_baud16_o;
    22 wire sys_baud_o;
    23 
    24 uart_baud            u0(
    25                             .sys_clk( sys_clk ),
    26                             .sys_rst_n( sys_rst_n ),
    27                             .sys_baud16_o( sys_baud16_o ),
    28                             .sys_baud_o( sys_baud_o )
    29                             );
    30                             
    31 wire uart_tx;
    32 wire uart_tx_idle_o;
    33 wire uart_tx_ack_o;                            
    34 uart_tx                u1(
    35                         .sys_clk( sys_clk ),
    36                         .sys_rst_n( sys_rst_n ),
    37                         .sys_baud_i( sys_baud_o ),
    38                         .sys_wreq_i( sys_wreq_i ),
    39                         .sys_data_i( sys_data_i ),
    40                         .uart_tx( uart_tx ),
    41                         .uart_tx_idle_o( uart_tx_idle_o ),
    42                         .uart_tx_ack_o( uart_tx_ack_o )
    43                         );
    44                         
    45 always @ (posedge sys_clk) begin
    46 if(sys_rst_n == 1'b0) begin
    47                                 sys_wreq_i <= 1;
    48                                 sys_data_i <= 0;end
    49 else if(uart_tx_ack_o) begin
    50                             sys_wreq_i <= 1;
    51                                 sys_data_i <= sys_data_i + 1'd1;end
    52 else begin
    53                             sys_wreq_i <= 0;
    54                                 sys_data_i <= sys_data_i;end
    55 end
    56 
    57 
    58 wire uart_rx_idle_o;
    59 wire uart_rx_ack_o;
    60 wire uart_rx_error_o;
    61 wire [7:0] sys_data_o;
    62 uart_rx                u2(
    63                         .sys_clk( sys_clk ),
    64                         .sys_rst_n( sys_rst_n ),
    65                         .uart_rx( uart_tx ),
    66                         .sys_baud16_i( sys_baud16_o ),
    67                         .uart_rx_idle_o( uart_rx_idle_o ),
    68                         .uart_rx_ack_o( uart_rx_ack_o ),
    69                         .uart_rx_error_o( uart_rx_error_o ),
    70                         .sys_data_o( sys_data_o )
    71                         );
    72 endmodule
  • 相关阅读:
    iOS汇编系列-汇编入门
    C开发系列-指针
    iOS开发系列-LLVM、Clang
    java开发系列-Http协议
    iOS开发系列-SQLite
    iOS逆向系列-theos
    <Java><类加载机制><反射>
    <Java><!!!><面试题>
    <Java><修饰符>
    <Java><类与对象><OOP>
  • 原文地址:https://www.cnblogs.com/loadomain/p/3237923.html
Copyright © 2011-2022 走看看