loadomain

博客园 首页 新随笔 联系 订阅 管理

开发工具: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

 

 

posted on 2013-08-05 12:05  loadomain  阅读(2128)  评论(1编辑  收藏  举报