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