Serial communication routine explanation
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'h 55
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.
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.
1.3 Hardware design
1.4 Interface description
Signal name | direction | FPGA pin number | illustrate |
---|---|---|---|
CLK_50M | enter | E1 | System clock, 50Mhz |
KEY1 | enter | M1 | Independent button, press low level, used as reset signal |
CH340_RX | enter | B11 | Serial signal input |
CH340_TX | output | A11 | 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 receiving port, so that the sent data can be displayed on the serial port assistant.
2. Draw theoretical waveform diagram
3. Create a new QuartusII 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 — project folder, which contains the QuartusII project
Source — source code folder, which contains the project source code (.v file or .vhd file)
Sim — simulation folder, which contains simulation-related files
Doc — stores related 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
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:
-
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.
-
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:
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. Compilation and synthesis
9. Bind pins
When the project is compiled successfully, pin assignment can be made (you need to refer to the schematic diagram of the development board). The development boards and modules in our store are marked with signal names on the PCB, and you can directly refer to the physical connection relationships when binding pins.
The pin mapping relationship is as follows:
10. Compile and synthesize again
11 Download SOF file
After successful compilation and synthesis again, the generated SOF file can be downloaded to the development board.
After the download is successful, the experimental phenomena on the development board can be observed. If the experimental phenomena are consistent with the design requirements, it means that there is no problem with our design, that is, You can proceed to the next step of solidifying the JIC file.
12 Generate and solidify JIC files
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. To solidify the program to the configuration chip, you need to generate a JIC file first. The steps to convert SOF files into JIC files are as follows:
12.1 file–>Convert Programming File…
12.2 Select the JIC file and configure the chip model and FPGA model
Label 1 : Select the format of the generated file, we choose the JIC file
Label 2 : Select the model of the configuration chip, we choose EPCS16
Label 3 : Modify the name and storage path of the generated JIC file
Label 4 : Click the left mouse button on the Flash Loader
Label 5 : Select As for the FPGA model, our development board uses the EP4CE6F17C8 FPGA, so we should also choose this model, as shown in the figure below:
12.3 Select SOF file
Label 1 : Click the left mouse button on SOF Data
Label 2 : Add SOF file, select the SOF file generated by our project, as shown below:
12.3 Generate JIC file
At this point, the JIC file is generated and the curing operation can be performed.
12.4 Curing JIC files
After curing, the program will not be lost when the power is turned off!
Experimental phenomena
It matches the design requirements and the design is completed!