[Xiaoyue Electronics] Anlu domestic FPGA development board system learning tutorial-LESSON7 serial communication

Serial communication routine explanation

To view the video tutorial accompanying this blog, click this link

Insert image description here
Based on many years of work experience, the FPGA design process has been summarized in a total of the above 12 steps, some of which can be omitted depending on the difficulty of the project. For example, for very simple projects, we can omit the steps in the dotted box, but our introductory course, no matter how simple it is, will be explained according to these 12 steps.

1. Interpretation of requirements

1.1 Requirements

Control 8 LED lights through the serial port with a baud rate of 9600. For example, if 8'h55 is sent through the serial port, 4 LED lights will be on and 4 LED lights will be off on the development board. At the same time, the serial port assistant will receive 8'h55

1.2 Knowledge background

    Serial port is the abbreviation of "serial interface", that is, an interface that uses serial communication. Serial communication divides data bytes into bits and transmits them one by one on a data line. It is characterized by simple communication lines but slow transmission speed. Therefore, serial ports are widely used in embedded, industrial control and other fields where data transmission speed is not required.
    Serial communication is divided into two methods: synchronous serial communication and asynchronous serial communication. Synchronous serial communication requires both communicating parties to transmit data synchronously under the control of the same clock; asynchronous serial communication means that both communicating parties use their own clocks to control the sending and receiving process of data.
    UART is a universal asynchronous receiver-transmitter that uses asynchronous serial communication. When sending data, it converts parallel data into serial data for transmission, and when receiving data, it converts the received serial data into serial data. Data is converted into parallel data.
    UART serial port communication requires two signal lines, one for serial port transmission and the other for serial port reception. A frame of data during UART transmission or reception consists of 4 parts, start bit, data bit, parity bit and stop bit. The specific timing is shown in Figure 1. Among them, the start bit marks the beginning of a frame of data, the stop bit marks the end of a frame of data, and the data bit is the valid data in a frame of data. The parity bits are divided into odd parity and even parity, which are used to check whether there are errors in the data during transmission. In odd parity, the sender should make the sum of the number of 1s in the data bits and the number of 1s in the check bits an odd number; when the receiver receives the data, it should check the number of 1s. If it is not an odd number, It means that there is an error in the data transmission process. Similarly, even parity checks whether the number of 1's is even.
    The data format and transmission rate during UART communication can be set. For correct communication, both the sending and receiving parties should agree on and follow the same settings. The data bits can be selected as 5, 6, 7 or 8 bits, among which 8 data bits are the most commonly used. In practical applications, 8 data bits are generally selected; the parity bit can be odd parity, even parity or none. Check bit; stop bit can be selected from 1 bit (default), 1.5 or 2 bits. The rate of serial communication is represented by the baud rate, which represents the number of binary data transmitted per second, and the unit is bps (bits/second). Commonly used baud rates are 9600, 19200, 38400, 57600, and 115200.
    After setting the data format and transmission rate, the UART is responsible for completing the serial-to-parallel conversion of the data, while the signal transmission is implemented by an external drive circuit. The transmission process of electrical signals has different level standards and interface specifications. The interface standards for asynchronous serial communication include RS232, RS422, RS485, etc., which define different electrical characteristics of the interface. For example, RS-232 is a single-ended input and output. RS-422/485 is differential input and output, etc.
    The RS232 interface standard appeared earlier and can realize full-duplex working mode, that is, data sending and receiving can be carried out at the same time. When the transmission distance is short (no more than 15m), RS232 is the most commonly used interface standard for serial communication. This chapter mainly introduces UART serial communication for the RS-232 standard.
    The most common interface type of the RS-232 standard serial port is DB9, as shown in Figure 2. Industrial computers used in the field of industrial control are generally equipped with multiple serial ports, and many old-fashioned desktop computers are also equipped with serial ports. However, laptops and newer desktop computers do not have serial ports. They generally use USB-to-serial cables (Figure 3) to achieve serial communication with external devices.
Insert image description here

Figure 1. Asynchronous serial port timing diagram

Insert image description here

Figure 2. DB9 connector

Insert image description here

Figure 3. USB serial cable

The DB9 interface definition and the function description of each pin are shown in Figure 16.1.4. We generally only use pins 2 (RXD), 3 (TXD), and 5 (GND). The other pins are generally used in normal serial port mode. Do not use.
Insert image description here

Figure 4. DB9 interface definition
Baud rate 9600bps: 9600 bits transmitted per second. The time to transmit 1 bit is: 1/9600 (second) = 104167ns, which is 5208 clock cycles. It needs to be collected more than once. This is just to introduce the knowledge related to the serial port. Our XLOGIC development board has a USB to TTL chip (CH340) onboard. Serial communication with the computer can be carried out using a USB cable.

1.3 Hardware design

Insert image description here

Figure 5. Active crystal oscillator

Insert image description here

Figure 6. Serial port chip circuit

Insert image description here

Figure 7. Corresponding FPGA pins

1.4 Interface description

Signal name direction FPGA pin number illustrate
CLK50M enter B10 Clock signal, 50MHZ
FPGA_RX enter H14 Serial signal input
FPGA_TX output F14 Serial signal output

    Summary: Through the above description, the requirement can be interpreted as: the serial port assistant sends a number at a baud rate of 9600, and sends it to the FPGA through the serial port sending port. The FPGA parses the number according to the serial port timing, and then assigns this number to 8 LED will do. At the same time, the FPGA sends this number through the serial port sending port, so that the sent data can be displayed on the serial port assistant.

2. Draw theoretical waveform diagram

Insert image description here

Block diagram

Insert image description here

Serial port receiving theoretical waveform diagram

Insert image description here

Serial port transmission theoretical waveform diagram

3. New TD project

In order to make the project look tidy and facilitate project transplantation. We create 4 new folders, namely Project, Source, Sim, and Doc.
Project — the project folder, which contains the TD project
Source — the source code folder, which contains the project source code (.v file or .vhd file)
Sim — the simulation folder, which contains the simulation-related files
Doc — stores relevant information , such as data manuals, requirements documents, etc.

4. Write code

4.1 Serial port receiving module code

///
//QQ:3181961725
//TEL/WX:13540738439
//作者:Mr Wang
//模块介绍:实现异步串口接收功能
///
module async_uart_rev(
	input				rst_n	,//复位信号,低电平有效
	input				clk		,//时钟信号,50MHZ
	input				rxd		,//串行接收数据
	output	reg	[7:0]	rev_data,//并行数据
	output	reg			rev_dvld //并行数据有效标志
	);
	parameter	baud_num=5207;//1/9600*1000000000/20
	parameter	IDLE		=4'd0;
	parameter	START_ST    =4'd1;
	parameter	STOP_ST     =4'd2;
	reg	[12:0]	baud_cnt;
	reg			baud_cnt_en;
	wire		sample_en;
	reg	[3:0]	sample_num;
	reg			rxd_ff1;
	reg			rxd_ff2;
	reg	[3:0]	curr_st;
	//打两拍操作
	always@(posedge clk)rxd_ff2<=rxd_ff1;
	always@(posedge clk)rxd_ff1<=rxd;
	assign	sample_en=(baud_cnt==baud_num[12:1])?1'b1:1'b0;
	//状态机跳转程序
	always@(posedge clk or negedge rst_n)begin
		if(!rst_n)
			curr_st<=IDLE;
		else case(curr_st)
			IDLE:begin
				if(rxd_ff2==0)
					curr_st<=START_ST;
				else;
			end
			START_ST:begin
				if(sample_num==8&&sample_en)
					curr_st<=STOP_ST;
				else;
			end
			STOP_ST:begin
				if(rxd_ff2==1&&sample_en)
					curr_st<=IDLE;
				else;
			end
			default:;
		endcase
	end
	always@(posedge clk or negedge rst_n)begin
		if(!rst_n)
			baud_cnt<=0;
		else if(curr_st==START_ST||curr_st==STOP_ST)begin
			if(baud_cnt==baud_num)
				baud_cnt<=0;
			else 
				baud_cnt<=baud_cnt+1;
		end else
			baud_cnt<=0;
	end
	always@(posedge clk or negedge rst_n)begin
		if(!rst_n)	
			sample_num<=0;
		else if(sample_en&&sample_num==9)
			sample_num<=0;
		else if(sample_en)
			sample_num<=sample_num+1;
		else;
	end
	always@(posedge clk or negedge rst_n)begin
		if(!rst_n)
			rev_data<=0;
		else if(sample_en)
			case(sample_num)
			1:rev_data[0]<=rxd_ff2;
			2:rev_data[1]<=rxd_ff2;
			3:rev_data[2]<=rxd_ff2;
			4:rev_data[3]<=rxd_ff2;
			5:rev_data[4]<=rxd_ff2;
			6:rev_data[5]<=rxd_ff2;
			7:rev_data[6]<=rxd_ff2;
			8:rev_data[7]<=rxd_ff2;
			default:;
		endcase
	end
	always@(posedge clk or negedge rst_n)begin
		if(!rst_n)	
			rev_dvld<=0;
		else if(sample_num==9&&sample_en)
			rev_dvld<=1;
		else
			rev_dvld<=0;
	end
endmodule

4.2 Serial port sending module code

///
//QQ:3181961725
//TEL/WX:13540738439
//作者:Mr Wang
//模块介绍:实现异步串口发送功能
///
module async_uart_tran(
	input			rst_n		,//复位信号,低电平有效
	input			clk			,//时钟,50MHZ
	input	[7:0]	tran_data	,//输入的并行数据
	input			tran_dvld	,//输入的并行数据有效标志
	output	reg		txd          //串行输出数据
	);
	parameter	baud_num=5207;//1/9600*1000000000/20
	parameter	IDLE		=4'd0;
	parameter	DATA_ST    =4'd1;
	parameter	START_ST    =4'd2;
	parameter	STOP_ST     =4'd3;
	reg	[12:0]	baud_cnt;
	reg			baud_cnt_en;
	wire		sample_en;
	reg	[3:0]	sample_num;
	reg	[3:0]	curr_st;

	assign	sample_en=(baud_cnt==baud_num)?1'b1:1'b0;
	always@(posedge clk or negedge rst_n)begin
		if(!rst_n)
			curr_st<=IDLE;
		else case(curr_st)
			IDLE:begin
				if(tran_dvld==1)
					curr_st<=START_ST;
				else;
			end
			START_ST:begin
				if(sample_en==1)
					curr_st<=DATA_ST;
			end
			DATA_ST:begin
				if(sample_en&&sample_num==8)
					curr_st<=STOP_ST;
				else;
			end
			STOP_ST:begin
				if(sample_en==1)
					curr_st<=IDLE;
				else;
			end
			default:;
		endcase
	end
	always@(posedge clk or negedge rst_n)begin
		if(!rst_n)
			baud_cnt<=0;
		else if(curr_st==START_ST||curr_st==DATA_ST||curr_st==STOP_ST)begin
			if(baud_cnt==baud_num)
				baud_cnt<=0;
			else 
				baud_cnt<=baud_cnt+1;
		end else
			baud_cnt<=0;
	end
	always@(posedge clk or negedge rst_n)begin
		if(!rst_n)	
			sample_num<=0;
		else if(curr_st==IDLE)
			sample_num<=0;
		else if(sample_en)
			sample_num<=sample_num+1;
		else;
	end
	always@(posedge clk or negedge rst_n)begin
		if(!rst_n)
			txd<=1;
		else if(sample_en)
			case(sample_num)
			0:txd<=1'b0;
			1:txd<=tran_data[0];
			2:txd<=tran_data[1];
			3:txd<=tran_data[2];
			4:txd<=tran_data[3];
			5:txd<=tran_data[4];
			6:txd<=tran_data[5];
			7:txd<=tran_data[6];
			8:txd<=tran_data[7];
			9:txd<=1'b1;
			default:txd<=1;
		endcase
	end
endmodule

4.3 Top-level module code

///
//QQ:3181961725
//TEL/WX:13540738439
//作者:Mr Wang
//模块介绍:顶层模块,例化接收和发送模块
///
module async_uart_top(
	input	clk			,//时钟,50MHZ
	input	rst_n		,//复位信号,低电平有效
	input	rxd			,//串行接收数据
	output	txd			,//串行发送数据
	output	[7:0] led
	);
	wire	[7:0]	rev_data;
	wire			rev_dvld;
	assign	led=rev_data;
	async_uart_rev Uasync_uart_rev(
	.rst_n		(rst_n),
	.clk		(clk),
	.rxd		(rxd),
	.rev_data	(rev_data),
	.rev_dvld   (rev_dvld)
	);
	async_uart_tran async_uart_tran(
	.rst_n		(rst_n),
	.clk		(clk),
	.tran_data	(rev_data),
	.tran_dvld	(rev_dvld),
	.txd        (txd)
	);
endmodule

5. Write simulation test stimulus file

Insert image description here

Simulation block diagram

Simulation test stimulus file (TB file)

`timescale 1ns/1ns
module async_uart_top_tb;
	reg					clk		;
	reg					rst_n	;
	wire				rxd		;
	wire				tran_dvld;
	reg	[17:0]	cnt=0;
initial
begin
	clk = 0;
	rst_n=0;
	#1000
	rst_n=1;
end
always #10 clk=~clk;
always@(posedge clk)cnt<=cnt+1;
assign	tran_dvld=(cnt==100)?1'b1:1'b0;
async_uart_tran Uasync_uart_tran(
	.rst_n		(rst_n),
	.clk		(clk),
	.tran_data	(8'h55),
	.tran_dvld	(tran_dvld),
	.txd        (rxd)
	);
async_uart_top async_uart_top(
	.clk	(clk),
	.rst_n	(rst_n),
	.rxd	(rxd),
	.txd	(),
	.led    ()
	);
endmodule

6.Modelsim simulation

There are generally two methods for Modelsim simulation:

  1. Graphical interface simulation means that all operations are completed on the Modelsim software interface. The advantage of this method is that it is easy to learn and suitable for simple projects. The disadvantage is that the operation steps are cumbersome.

  2. Batch simulation , this method requires writing corresponding script files before simulation. The advantage of this method is that the simulation can be completed with one click, saving time and effort. The disadvantage is that script files need to be written in the early stage. The first two lectures use graphical interface simulation; in order to be closer to engineering reality, starting from the third lecture, we use batch processing simulation. For specific operation steps, please refer to our video tutorial.
    The simulated waveform is shown below:
    Insert image description here

7. Compare waveforms

Compare the theoretical waveform diagram drawn in the second step with the waveform diagram simulated by Modelsim in the sixth step. The results are consistent, indicating that our logic design is correct. If the comparison results are found to be inconsistent, you need to find the reason for the inconsistency, and ultimately ensure that the comparison results are consistent. By comparison, the theoretical waveform is consistent with the simulated waveform, indicating that the function meets the design requirements.

8 Add .v file

Insert image description here

9 Bind the pins and save the constraint file (.adc)

Insert image description here
Insert image description here

10 Compile and synthesize the BIT file

Insert image description here

11. Download BIT file

Insert image description here
Insert image description here

After the download is successful, you can observe the experimental phenomena on the development board. If the experimental phenomena match the design requirements, it means that there is no problem with our design, and we can proceed to the next step of solidifying the configuration file.

12 solidification configuration file

FPGA has a characteristic that the configuration information will be lost after power failure, so we need to store the configuration information in the configuration chip (FLASH). After the development board is powered on, the FPGA will read the configuration information in the configuration chip, so the development The board can still work normally after powering off and on again.
Insert image description here

After the curing is successful, power off the development board and then power it on again. It can be observed that the development board can still perform the functions just now.

Guess you like

Origin blog.csdn.net/Moon_3181961725/article/details/126819160