├── README.md ├── uart.v ├── tb_uart.v ├── uart_transmitter.v └── uart_receiver.v /README.md: -------------------------------------------------------------------------------- 1 | 实现FPGA和PC的通信, 2 | uart协议层:1个bit起始位,8bit数据位,无校验位,1bit停止位,波特率115,200bit/s 3 | ![image](https://user-images.githubusercontent.com/103894715/199928299-68ffd18e-32a0-463e-8d1d-ae45fc176502.png) 4 | -------------------------------------------------------------------------------- /uart.v: -------------------------------------------------------------------------------- 1 | module uart( 2 | input clk, 3 | input rst_n, 4 | input uart_rxd, // receive data from PC 5 | output uart_txd // transmit data to PC 6 | ); 7 | 8 | // the definition of some important periods 9 | parameter SYS_PERIOD = 50_000_000; // my FPGA clock period 10 | parameter BPS = 115_200; // my defined BPS(bit/s) 11 | parameter HALF_BIT_PERIOD = SYS_PERIOD/BPS/2; // HALF_BIT_PERIOD = 217 , each half_bit time_cnt 12 | // 10bits data needs time_cnt = 217*20 = 4340 13 | wire receive_done; // 1:receive over 14 | wire [7:0] data_receive; // transfer received data to parallel data 15 | 16 | uart_receiver #( 17 | .SYS_PERIOD (SYS_PERIOD), 18 | .BPS (BPS), 19 | .HALF_BIT_PERIOD(HALF_BIT_PERIOD) 20 | )u_uart_receiver 21 | ( 22 | .clk (clk),//input 23 | .rst_n (rst_n), 24 | .uart_rxd (uart_rxd), 25 | .receive_done (receive_done),//output 26 | .data_receive (data_receive) 27 | ); 28 | 29 | uart_transmitter #( 30 | .SYS_PERIOD (SYS_PERIOD), 31 | .BPS (BPS), 32 | .HALF_BIT_PERIOD(HALF_BIT_PERIOD) 33 | )u_uart_transmitter( 34 | .clk (clk),//input 35 | .rst_n (rst_n), 36 | .receive_done (receive_done), 37 | .data_receive (data_receive), 38 | .uart_txd (uart_txd)//output 39 | ); 40 | 41 | endmodule -------------------------------------------------------------------------------- /tb_uart.v: -------------------------------------------------------------------------------- 1 | 2 | `timescale 1ns/10ps 3 | 4 | module tb_uart (); 5 | 6 | parameter T = 20; // a FPGA clock period 7 | parameter SYS_PERIOD = 50000000; // system clock frequency 8 | parameter BPS = 115200; // uart transmition velocity 9 | parameter HALF_BIT_PERIOD = SYS_PERIOD/BPS/2*T; // 接收一个1/2 bit所用时间 10 | 11 | reg clk; 12 | reg rst_n; 13 | reg uart_rxd; 14 | wire uart_txd; 15 | 16 | integer i; 17 | 18 | initial begin 19 | for(i=0; i<=60000; i=i+1) begin 20 | #10 clk = ~clk; 21 | end 22 | end 23 | 24 | initial begin 25 | clk = 1'b0; 26 | rst_n = 1'b0; 27 | #(T*3) rst_n = 1'b1; 28 | end 29 | 30 | initial begin 31 | uart_rxd = 1'b1; 32 | #(HALF_BIT_PERIOD*2) uart_rxd = 1'b1; 33 | 34 | #(HALF_BIT_PERIOD*2) uart_rxd = 1'b0; //start 35 | 36 | #(HALF_BIT_PERIOD*2) uart_rxd = 1'b1; //bit 0 37 | #(HALF_BIT_PERIOD*2) uart_rxd = 1'b0; //bit 1 38 | #(HALF_BIT_PERIOD*2) uart_rxd = 1'b0; //bit 2 39 | #(HALF_BIT_PERIOD*2) uart_rxd = 1'b0; //bit 3 40 | #(HALF_BIT_PERIOD*2) uart_rxd = 1'b0; //bit 4 41 | #(HALF_BIT_PERIOD*2) uart_rxd = 1'b0; //bit 5 42 | #(HALF_BIT_PERIOD*2) uart_rxd = 1'b1; //bit 6 43 | #(HALF_BIT_PERIOD*2) uart_rxd = 1'b0; //bit 7 44 | 45 | #(HALF_BIT_PERIOD*2) uart_rxd = 1'b1; //over 46 | 47 | 48 | #(HALF_BIT_PERIOD*2) uart_rxd = 1'b1; 49 | #(HALF_BIT_PERIOD*2) uart_rxd = 1'b1; 50 | #(HALF_BIT_PERIOD*2) uart_rxd = 1'b1; 51 | #(HALF_BIT_PERIOD*2) uart_rxd = 1'b1; 52 | #(HALF_BIT_PERIOD*2) uart_rxd = 1'b1; 53 | #(HALF_BIT_PERIOD*2) uart_rxd = 1'b1; 54 | 55 | 56 | #(HALF_BIT_PERIOD*2) uart_rxd = 1'b0; //start 57 | 58 | #(HALF_BIT_PERIOD*2) uart_rxd = 1'b1; //bit 0 59 | #(HALF_BIT_PERIOD*2) uart_rxd = 1'b1; //bit 1 60 | #(HALF_BIT_PERIOD*2) uart_rxd = 1'b1; //bit 2 61 | #(HALF_BIT_PERIOD*2) uart_rxd = 1'b1; //bit 3 62 | #(HALF_BIT_PERIOD*2) uart_rxd = 1'b0; //bit 4 63 | #(HALF_BIT_PERIOD*2) uart_rxd = 1'b0; //bit 5 64 | #(HALF_BIT_PERIOD*2) uart_rxd = 1'b0; //bit 6 65 | #(HALF_BIT_PERIOD*2) uart_rxd = 1'b0; //bit 7 66 | 67 | #(HALF_BIT_PERIOD*2) uart_rxd = 1'b1; //over 68 | 69 | #(HALF_BIT_PERIOD*2) uart_rxd = 1'b1; 70 | #(HALF_BIT_PERIOD*2) uart_rxd = 1'b1; 71 | 72 | end 73 | 74 | uart u_uart( 75 | .clk (clk),//input 76 | .rst_n (rst_n), 77 | .uart_rxd (uart_rxd), 78 | .uart_txd (uart_txd)//output 79 | ); 80 | 81 | /* 82 | initial 83 | $vcdpluson(); 84 | 85 | initial begin 86 | $fsdbDumpfile("top_uart.fsdb"); 87 | $fsdbDumpvars(0); 88 | end 89 | */ 90 | endmodule 91 | 92 | -------------------------------------------------------------------------------- /uart_transmitter.v: -------------------------------------------------------------------------------- 1 | module uart_transmitter( 2 | input clk, 3 | input rst_n, 4 | input receive_done, // 1:receive over 5 | input [7:0] data_receive, // transfer received data to parallel data 6 | output reg uart_txd 7 | ); 8 | 9 | // the definition of some important periods 10 | parameter SYS_PERIOD = 50_000_000; // my FPGA clock period 11 | parameter BPS = 115_200; // my defined BPS(bit/s) 12 | parameter HALF_BIT_PERIOD = SYS_PERIOD/BPS/2; // HALF_BIT_PERIOD = 217 , each half_bit transmit_time_cnt 13 | // 10bits data needs transmit_time_cnt = 217*20 = 4340 14 | 15 | reg [14:0] transmit_time_cnt; // counting for receiving data 16 | reg transmit_flag; // transmit_flag = 1 in the period of 10bits transmitting 17 | wire [7:0] data_temp; // save receiving data 18 | 19 | assign data_temp = receive_done ? data_receive : data_temp; // save data_receive to data_temp when finished receiving 20 | 21 | // transmit_time_cnt start counting when receive_done = 1, sending 10bits data needs 217*20 = 4340 counting 22 | always @(posedge clk, negedge rst_n) begin 23 | if (!rst_n ) 24 | transmit_time_cnt <= 15'd0; 25 | else if(transmit_flag) 26 | transmit_time_cnt <= (transmit_time_cnt == 20*HALF_BIT_PERIOD) ? 15'd0 : transmit_time_cnt + 1'b1; 27 | else 28 | transmit_time_cnt <= 15'd0; 29 | end 30 | 31 | // when uart_rxd's negedge is coming, transmit_time_cnt start counting. transmit_flag = 1 in the period of 10bits transmitting 32 | always @(posedge clk, negedge rst_n) begin 33 | if (!rst_n) 34 | transmit_flag <= 1'b0; 35 | else begin 36 | if (receive_done) 37 | transmit_flag <= 1'b1; 38 | else if (transmit_time_cnt == 20*HALF_BIT_PERIOD) 39 | transmit_flag <= 1'b0; 40 | else 41 | transmit_flag <= transmit_flag; 42 | end 43 | end 44 | 45 | // transmit data 46 | always @(posedge clk, negedge rst_n) begin 47 | if (!rst_n) 48 | uart_txd <= 1'b1; 49 | else if (transmit_flag) begin 50 | case (transmit_time_cnt) 51 | 0*HALF_BIT_PERIOD: 52 | uart_txd <= 0; // transmitting start bit = 0 53 | 2*HALF_BIT_PERIOD: 54 | uart_txd <= data_temp[0]; // transmitting 1st data 55 | 4*HALF_BIT_PERIOD: 56 | uart_txd <= data_temp[1]; // transmitting 2nd data 57 | 6*HALF_BIT_PERIOD: 58 | uart_txd <= data_temp[2]; // transmitting 3rd data 59 | 8*HALF_BIT_PERIOD: 60 | uart_txd <= data_temp[3]; // transmitting 4th data 61 | 10*HALF_BIT_PERIOD: 62 | uart_txd <= data_temp[4]; // transmitting 5th data 63 | 12*HALF_BIT_PERIOD: 64 | uart_txd <= data_temp[5]; // transmitting 6th data 65 | 14*HALF_BIT_PERIOD: 66 | uart_txd <= data_temp[6]; // transmitting 7th data 67 | 16*HALF_BIT_PERIOD: 68 | uart_txd <= data_temp[7]; // transmitting 8th data 69 | 18*HALF_BIT_PERIOD: 70 | uart_txd <= 1; // transmitting stop bit = 1 71 | default: 72 | uart_txd <= uart_txd; 73 | endcase 74 | end 75 | else 76 | uart_txd <= uart_txd; 77 | end 78 | endmodule 79 | -------------------------------------------------------------------------------- /uart_receiver.v: -------------------------------------------------------------------------------- 1 | module uart_receiver( 2 | input clk, 3 | input rst_n, 4 | input uart_rxd, // receive data from PC 5 | output receive_done, // 1:receive over 6 | output reg [7:0] data_receive // transfer received data to parallel data 7 | ); 8 | 9 | // the definition of some important periods 10 | parameter SYS_PERIOD = 50_000_000; // my FPGA clock period 11 | parameter BPS = 115_200; // my defined BPS(bit/s) 12 | parameter HALF_BIT_PERIOD = SYS_PERIOD/BPS/2; // HALF_BIT_PERIOD = 50000000/115200 = 217 , each half_bit receive_time_cnt 13 | // 10bits data needs receive_time_cnt = 217*20 = 4340 14 | 15 | reg [14:0] receive_time_cnt; // counting for receiving data 16 | reg uart_rxd_delay1, uart_rxd_delay2; // to find negedge of uart_rxd 17 | reg start_flag; // the flag to start 18 | reg receive_flag; // receive_flag = 1 in the period of receiving datas 19 | 20 | // when receive_receive_time_cnt = 20*HALF_BIT_PERIOD, it means data finished receiving, then receive_done = 1. 21 | assign receive_done = (receive_time_cnt == 20*HALF_BIT_PERIOD); 22 | 23 | // clk delay for 2 periods, to check the coming of uart_rxd's negedge(for starting receiving) 24 | always @(posedge clk, negedge rst_n) begin 25 | if (!rst_n) begin 26 | uart_rxd_delay1 <= 1'b0; 27 | uart_rxd_delay2 <= 1'b0; 28 | end 29 | else begin 30 | uart_rxd_delay1 <= uart_rxd; 31 | uart_rxd_delay2 <= uart_rxd_delay1; 32 | end 33 | start_flag <= (~uart_rxd) & uart_rxd_delay2; // start_flag = 1, when negedge's coming 34 | end 35 | 36 | // receive_time_cnt start counting when reveive_flag=1, receiving 10bits data needs 217*20 = 4340 counting 37 | always @(posedge clk, negedge rst_n) begin 38 | if (!rst_n ) 39 | receive_time_cnt <= 15'd0; 40 | else if(receive_flag) 41 | receive_time_cnt <= (receive_time_cnt == 20*HALF_BIT_PERIOD) ? 15'd0 : receive_time_cnt + 1'b1; 42 | else 43 | receive_time_cnt <= 15'd0; 44 | end 45 | 46 | // when uart_rxd's negedge is coming, receive_time_cnt start counting. receive_flag = 1 in the period of 10bits receiving 47 | always @(posedge clk, negedge rst_n) begin 48 | if (!rst_n) 49 | receive_flag <= 1'b0; 50 | else begin 51 | if (start_flag) 52 | receive_flag <= 1'b1; 53 | else if ((receive_time_cnt == 20*HALF_BIT_PERIOD) && (uart_rxd==1'b1)) 54 | receive_flag <= 1'b0; 55 | else 56 | receive_flag <= receive_flag; 57 | end 58 | end 59 | 60 | 61 | // data receiving 62 | always @(posedge clk, negedge rst_n) begin 63 | if (!rst_n) 64 | data_receive <= 8'b0; 65 | else if (receive_flag) begin 66 | case (receive_time_cnt) 67 | 3*HALF_BIT_PERIOD: 68 | data_receive[0] <= uart_rxd; // receiving 1st data 69 | 5*HALF_BIT_PERIOD: 70 | data_receive[1] <= uart_rxd; // receiving 2nd data 71 | 7*HALF_BIT_PERIOD: 72 | data_receive[2] <= uart_rxd; // receiving 3st data 73 | 9*HALF_BIT_PERIOD: 74 | data_receive[3] <= uart_rxd; // receiving 4st data 75 | 11*HALF_BIT_PERIOD: 76 | data_receive[4] <= uart_rxd; // receiving 5st data 77 | 13*HALF_BIT_PERIOD: 78 | data_receive[5] <= uart_rxd; // receiving 6st data 79 | 15*HALF_BIT_PERIOD: 80 | data_receive[6] <= uart_rxd; // receiving 7st data 81 | 17*HALF_BIT_PERIOD: 82 | data_receive[7] <= uart_rxd; // receiving 8st data 83 | default: 84 | data_receive <= data_receive; 85 | endcase 86 | end 87 | else 88 | data_receive <= data_receive; 89 | end 90 | 91 | endmodule --------------------------------------------------------------------------------