【FPGA】基于SMIMS开发板的FDE-Lab
demo:
https://www.bilibili.com/video/BV1tx4y1A7wZ/?vd_source=3d19a3d894313e266a040f306849e552
Contents
1.1 The purpose of the experiment 3
1.2 Experimental Procedure of FDE Lab 3
Chapter 2. Name Display Experiment 5
2.1 The Text Display of Name 5
2.1.2 Experimental Principle 6
2.2 The Image Display of Name 10
2.1.2 Experimental Principle 10
Chapter 3. Aerial Combat Game 20
Chapter 4. Experiment Summary 31
Chapter 1 Introduction
1.1 The purpose of the experiment
Through various experiments in FDE Lab, I gradually master the specific steps of digital circuit design, be familiar with the use of SMIMS and Wonton software, and understand the workflow of Yosys and DC, such as compiling, packing, placing, routing and generating bit files. By writing Verilog files, I am familiar with top-down design methods, test document writing and waveform viewing. The mastery of these knowledge will be of great help to the later embedded experiments.
1.2 Experimental Procedure of FDE Lab
Firstly, the design source file is written by Vivado software developed by AMD Xilinx Company. By writing testbench files, we can verify the functions of source files through behavior level simulation. In order to ensure the reliability of the design source file, we can also conduct post synthesis simulation again after synthesis steps to verify the correctness of timing and functions.
Secondly, we can compile the design source file through Yosys or DC. After the compilation is complete, we can use the FDE2019 software to complete a work flow, such as packing, placing, routing, and generating bit files. It is worth noting that the SMIMS HDLAutoAssign tool should be used to generate pin constraint files in advance during the placing and routing process.
Finally, Wonton interactive software is used to control each input and output component. When creating a new project, it is necessary to add the previously generated pin constraint file, connect the FDE development board after adding the bitstream file, and set the clock frequency after programming. After setting this up, the output component can perform a series of operations by controlling the input component.
Next, I will introduce some specific process of digital circuit design:
- Packing
The packing step in digital circuit design is the process of grouping logical components and interconnect wires into physical entities called modules or cells.
The following are the typical steps involved in the packing step of digital circuit design:
- Module generation: The first step is to group related components into modules. This is done based on the functionality of the components and the design hierarchy. The modules can be pre-designed blocks or they can be created during the packing step.
- Cell generation: In this step, the modules are transformed into physical cells. Each cell contains one or more modules and associated interconnect wires. The cells are generated using a cell generation tool, which takes into account the placement of the components and the design rules specified by the manufacturer.
- Cell placement: Once the cells are generated, they are placed on the chip or PCB. The placement takes into account the location of the input/output pins and the interconnect wires between the cells.
Overall, the packing step in digital circuit design is a critical part of the design process, as it determines the physical grouping of components and interconnect wires into cells or modules. This can have a significant impact on the performance and reliability of the circuit
- Placing
The placement step in digital circuit design is the process of determining the physical location of each logic gate, flip-flop, and other components on a chip or printed circuit board (PCB). The goal of the placement step is to minimize the length of interconnect wires and optimize the performance of the circuit.
The following are the typical steps involved in the placement step of digital circuit design:
- Netlist generation: The first step is to generate a netlist, which is a list of all the components in the design and their connections. This is typically done using a computer-aided design (CAD) tool.
- Floorplanning: In this step, the designer allocates space for each component on the chip or PCB. This involves deciding on the overall size of the chip, the location of the input/output pins, and the placement of other components.
- Placement: Once the floorplan is complete, the designer uses a placement tool to place the components on the chip or PCB. The placement tool takes into account the location of the input/output pins, the size and shape of the components, and any design rules specified by the manufacturer.
To summarize, the placement step in digital circuit design determines the physical layout of the circuit and can have a significant impact on its performance.
- Routing
The routing step in digital circuit design is the process of determining the physical paths for interconnect wires that connect the various cells or modules of a circuit. The goal of the routing step is to minimize the total length of interconnect wires while meeting the timing, area, and power constraints of the design.
The following are the typical steps involved in the routing step of digital circuit design:
- Routing grid generation: In this step, a routing grid is created over the cells or modules of the circuit. The routing grid is a matrix of cells that represent the physical space available for routing wires between the cells.
- Global routing: In this step, a global router is used to determine the approximate paths for the interconnect wires between the cells. The global router takes into account the placement of the cells, the routing grid, and the design constraints.
- Detailed routing: Once the approximate paths for the interconnect wires have been determined, a detailed router is used to refine the paths and to optimize the routing. The detailed router takes into account the specific physical characteristics of the interconnect wires, such as their width and spacing, and the design constraints.
All in all, the routing step determines the physical paths for interconnect wires that connect the various cells or modules of a circuit. This can have a significant impact on the performance, area, and power consumption of the circuit.
Chapter 2. Name Display Experiment
The experiment of name display is mainly divided into two parts, respectively LED text display and LED image display. Compared to LED text display, LED image display is more complex, it needs to use more complex state machine and dynamic scanning knowledge.
2.1 The Text Display of Name
2.1.1 Document Directory
The table below shows the file directories in the Lab1 text folder.
Table.1 Related Files of the Text Display in Lab1 Text Folder
Name |
Specific content |
---|---|
ZTY_name_display2_FDE |
1. Source files 2. Generated bit files 3. Yosys compiled files 4. Packed, placed, and routed files 5. Pin constraint files. |
demo |
1. Demo videos 2. Demo pictures 3. Waveform pictures |
tb_wave | 1. Testbench file 2. Waveform file |
vivado_zty_word_display | 1. Vivado project file 2. Vivado source files 3. Vivado simulation files |
ZTY_name_display2_Wonton | Wonton project files |
2.1.2 Experimental Principle
The name display takes advantage of the LED text display module in Wonton. The LCD module has its display starting at the top left corner, where the first character is shown. As each character is displayed, the display address automatically moves to the next position. Once all 32 addresses (2 rows of 16 characters) are written, the character data in the initial position is overwritten in a cyclic manner. Additionally, the user manual provides the corresponding hexadecimal codes for letters, symbols, and numbers.
The component picture and the functions of the various I/O ports are shown below.
Table.2 Different Port Functions
Port | Function |
---|---|
DB0~DB7 | Input data |
RS |
Register select When it is 0, the instruction register is selected
|
RW |
Read/Write When it is 0, a write operation is performed When it is 1, no operation is performed |
EN | Data is transferred on the falling edge of EN |
RST |
RESET When it is 1, all display data is cleared and the cursor is moved to the initial position (top left corner). |
Figure.2 The Time Sequence Working Mode
Each character in the LED text display adopts the encoding rule of ASCII code, and each character corresponds to a hexadecimal code.
2.1.3 Source Code Design
Part of the sequential logic code is shown here, which is the key to led text display.
Code.1 Partial Text Display of Sequential Logic Code
1 |
|
The code consists of a series of always blocks and assign statements. The first always block is triggered on the positive edge of the input clock signal (iClk). It includes an if-else statement that checks the state of the oLcdRst signal, which is used to reset the LED display. If the oLcdRst signal is high, then the countlcd variable is set to 0. If the countlimit condition is met, then the countlcd variable is not updated. Otherwise, the countlcd variable is incremented by 1.
The second always block is also triggered on the positive edge of the input clock signal (iClk). It updates the oLcdRw signal, which is used to control the read/write operations of the LED display. If the oLcdRst signal is high, then the oLcdRw signal is set to 0 (write operation). If the countlimit condition is met, then the oLcdRw signal is set to 1 (no operation).
The assign statements are used to assign values to various signals. The oLcdRst signal is assigned the logical OR of the iRst and iButton2 signals. The oLcdRs signal is always set to 1, indicating that the data being transferred is a character data. The countlimit signal is assigned based on the value of the countlcd variable. It is set to 1 when the countlcd variable is equal to 255. The oLcdEn signal is assigned the complement of the bit at position 2 in the countlcd variable.
The final always block is triggered by changes in the countlcd variable. It uses a case statement to assign values to the oLcdData signal based on the value of the countlcd variable. The oLcdData signal represents the data being transferred to the LED display.
2.2 The Image Display of Name
2.2.1 Document Directory
The table below shows the file directories in the Lab1 image folder.
Table.3 Related Files of the Text Display in Lab1 Image Folder
Name |
Specific content |
---|---|
ZTY_name_display_FDE |
1. Source files 2. Generated bit files 3. Yosys compiled files 4. Packed, placed, and routed files 5. Pin constraint files. |
demo |
1. Demo videos 2. Demo pictures 3. Waveform pictures |
tb_simulation | 1. Testbench file 2. Waveform file |
vivado_zty_image_display | 1.Vivado project file 2.Vivado source files 3.Vivado simulation files |
ZTY_name_display_Wonton | Wonton project files |
2.1.2 Experimental Principle
The LED image display uses LED image display in the Wonton software, as shown in the figure below.
Figure.5 LED Image Display
The port of this component is defined as shown in the following table.
Port | Function |
---|---|
DB0~DB7 | Data input |
DI |
Register selection port 0: Enter command mode (select command register) 1: Enter data mode (select data bits register) |
RW |
Read/Write 0: write data 1: No operation |
EN | Enable signal. Data incoming port on negedge |
CS1 | Left half screen |
CS2 | Right half screen |
RST | Clear the data in the display and mem |
Table.4 the Port of this Component
The device has an overall pixel resolution of 128x64, which is divided into two 64x64 screens. Each screen is made up of eight 64x8 small screens, with x and y-axis address coordinates shown in the provided figure. When data is written to the memory (MEM), the Y-coordinate automatically moves to the next position, and resets to 0 when Y=63.
For generating specific text pixels, the pctolcd2002 software is used. The displayed text and pixel generation for this experiment are shown in the figure.
To display a word, both the left and right screens are divided into 8-bit x 8 pixels on the x-axis and 64 pixels on the y-axis. An 8-bit x 64 MEM is built into the LED, so 8 pages need to be lit. Each page is illuminated for 68 clock cycles, with the start display address set in cycle 1, the page set in cycle 2, and the Y address set in cycle 3. Cycles 4 to 67 load data into MEM (with one row of data (1 x 8) loaded in each cycle), and cycle 68 illuminates that segment of the screen. Therefore, to display each word, 68 x 8 = 544 cycles are required.
2.2.3 Source Code Design
- Generate Current Display
Code.2 Generate Current Display
1 |
|
This code is describing the functionality of an always block that is triggered on the positive edge of a clock signal. It first checks whether an input reset signal is active, and if so, sets the “current_display” variable to 0. Otherwise, it proceeds with additional checks.
If the current state is 2, 5, or 8, “current_display” is set to 0. However, if the count_clock value matches one of the specified clock cycle values (68, 136, 204, 272, 340, 408, 476, or 544), “current_display” is incremented by 1.
Essentially, this code is responsible for updating the “current_display” variable based on certain conditions related to the current state and clock cycle count.
- Generate Count Clock
Code.3 Generate Count Clock
1 | always @(posedge clock) |
This code is describing the functionality of an always block that is triggered on the positive edge of a clock signal. It first checks whether an input reset signal is active, and if so, sets the “current_state” variable to 0. Otherwise, it proceeds with additional checks.
If the current state is 0 and the count_clock value is equal to 544, “current_state” is incremented by 1. This same logic is applied for each of the following states: 1, 2, 3, 4, 5, 6, and 7. However, if the current state is 8 and the count_clock value is equal to 500, “current_state” is set back to 0.
Essentially, this code is responsible for updating the “current_state” variable based on certain conditions related to the current state and clock cycle count. These conditions are used to control the timing and sequencing of the LED display in the overall system.
- Generate Current State
Code.4 Generate Current State
1 |
|
This code is describing the functionality of an always block that is triggered on the positive edge of a clock signal. It first checks whether an input reset signal is active, and if so, sets the “current_state” variable to 0. Otherwise, it proceeds with additional checks.
If the current state is 0 and the count_clock value is equal to 544, “current_state” is incremented by 1. This same logic is applied for each of the following states: 1, 2, 3, 4, 5, 6, and 7. However, if the current state is 8 and the count_clock value is equal to 500, “current_state” is set back to 0.
- Generate Current DI
Code.5 Generate Current DI
1 | always @(posedge clock) |
This code is describing an always block that is triggered on the positive edge of a clock signal. It first checks whether an input reset signal is active, and if so, sets the “current_di” variable to 0. Otherwise, it proceeds with additional checks.
If the “count_clock” value is equal to 0, 67, 135, 203, 271, 339, 407, 475, or 543, “current_di” is set to 0. If the “count_clock” value is equal to 3, 71, 139, 207, 275, 343, 411, or 479, “current_di” is set to 1.
- Generate r_cs
Code.6 Generate r_cs
1 |
|
This code uses a case statement to determine the appropriate chip select signal to activate for the current state. The signals r_cs1 and r_cs2 are assigned different values based on the current state. This code is used to control the display of specific text on the two-screen LCD display.
- Generate Data
Code.7 Generate Data
1 |
|
The code checks for a reset signal and sets the value of “r_db” accordingly. If the reset signal is not asserted, the code checks the value of “count_clock” and sets “r_db” to a specific value based on its value and the current state of the circuit.
The code uses a case statement to set the value of “r_db” based on the current state of the circuit and the value of “count_clock”. If “count_clock” is not equal to any of the specified values, the code falls through to the default case. The values assigned to “r_db” in each case are expressed in hexadecimal notation.
Chapter 3. Aerial Combat Game
Table.5 Related Files of the Text Display in Lab1 Image Folder
Name |
Specific content |
---|---|
aerial_combat_FDE_yosys |
1.Source files 2.Generated bit files 3.Yosys compiled files 4.Packed, placed, and routed files 5.Pin constraint files. |
demo | 1.Demo videos 2.Waveform pictures and files |
tb_simulation | 1.Testbench file 2.Waveform file |
vivado_project_plane |
1.Vivado project file 2.Vivado source files 3.Vivado simulation files |
aerial_combat_Wonton | Wonton project files |
The whole game is implemented through Wonton software. The game is mainly divided into the following parts, respectively is the control of the start of the game switch, the control of the aircraft movement and shooting button, the game interface display, the score of the seven sections of the digital tube display and LED display.
Here are the rules of the game:
1. Enemy plane is falling from the top of the screen, and our plane is at the bottom at first.
2. The up, down, left and right movements of the aircraft are controlled by the four buttons.
3. The button in the middle controls the aircraft to shoot upward. When the bullet hits the enemy aircraft, the bullet and the enemy aircraft disappear from the current position and the enemy aircraft refreshes from the top of the screen.
4. The initial score is 1 point. Bonus points are awarded after hitting an enemy plane, for a total of 8 points. The higher the score, the more leds are lit below.When all the LED lights are on, that is, after shooting down 8 enemy aircraft, the game is won.
5. If our plane collides with the enemy plane, the game fails.
The overall framework of the game, shown here, is designed from the top down.
First of all, the top layer of the entire game becomes the bridge between the various modules of data transmission. The input of the top module is the clock signal, reset signal and signal related to mobile shooting, and the output is the row selection signal and column selection signal of the LED16*16 array, as well as the signal of the control LED and seven segment tube.
The clock_divider module is used to divide the clock frequency. Since dynamic scanning of the LED matrix and game running require different clock frequencies, the clock_divier module generates a clk_out signal that is slower than the original clk signal and feeds it to the game_logic module, LED_score_display module and seven_segment module. The dynamically scanned display module still uses the clk signal with the original faster frequency.
The game control module controls the game. The game control module includes control of aircraft and bullet movement, collision determination and game_matrix update. game_matrix is equivalent to a RAM that is flushed every clock cycle. The game_matrix data will be fed to the dynamically scanned display module, which is used to generate row selection signals and column selection signals to control the LED matrix. In addition, the game control module also generates scores, which are fed to the LED_score_display module and the seven_segment module to generate the final score.
In general, the overall design framework adopts the MVC(Model-View-Controller) design pattern. The game_marix matrix stores information about aircraft and bullet models. Dynamic scanning of LED matrix, seven sections of digital tube and LED display game interface and score effect.Finally through game_logic module we can control the game.
- Clock_divider
Code.7 Clock_divider
1 |
|
This code describes a clock divider module. The module takes an input clock signal and produces an output clock signal that is divided by a factor of 10.
The code uses an “always” block that is triggered by a positive edge of the input clock signal or a negative edge of the reset signal. Inside the “always” block, the code checks the value of the reset signal. If the reset signal is asserted, the counter and output clock signals are reset to 0. If the reset signal is not asserted, the code increments the counter by 1 on each clock cycle. When the counter reaches a value of 10, the counter is reset to 0 and the output clock signal is toggled.
- Display
Code.8 Display module
1 |
|
This code defines a module for a display driver that generates output signals to drive a display based on an input game matrix. The module takes an input game matrix represented as a 256-bit signal, an input clock signal, and a reset signal. The module produces two 16-bit output signals, row_sel and col_sel, which are used to drive the row and column select lines of the display.
The row_sel output signal is generated by shifting a binary value to select one row of the display at a time. The row counter is used to keep track of which row is currently being selected. When the row counter reaches a value of 15, it is reset to 0 and the row_sel signal is set to its initial value.The col_sel output signal is generated by selecting the corresponding 16-bit value from the game matrix for the current row being displayed. The value is updated on each clock cycle.
- LED_score_display
Code.9 LED_score_display
1 |
|
endmodule
This code defines a module for a LED score display that takes an input score value and produces an 8-bit output signal that drives an eight-segment LED display. The output signal is updated on each positive edge of the input clock signal or negative edge of the reset signal.
If the reset signal is asserted, the output signal is set to 0. Otherwise, a case statement is used to set the output signal based on the input score value. The case statement checks the input score value and sets the output signal to a binary value that represents the corresponding LED display pattern. If the input score is not equal to any of the specified values, the output signal is set to 0.
- Seven_segment_display
Code.10 Seven_segment_display
1 | module **seven\_segment\_display**( |
endmodule
This code defines a module for a seven-segment LED display that takes an input score value and produces an 8-bit output signal that drives the display. The output signal is updated on each positive edge of the input clock signal or negative edge of the reset signal.
If the reset signal is asserted, the output signal is set to a binary value that turns off all the segments. Otherwise, a case statement is used to set the output signal based on the input score value. The case statement checks the input score value and sets the output signal to a binary value that represents the corresponding display pattern for the number. If the input score is not equal to any of the specified values, the output signal is set to a binary value that turns off all the segments.
- Game_logic
Code.11 Game_logic
1 |
|
This code defines a module for a game logic that takes several input signals representing the player’s movements and actions, and generates two output signals: a game matrix that represents the state of the game world, and a score value that represents the player’s score. The output signals are updated on each positive edge of the input clock signal or negative edge of the reset signal.
The module contains several registers that represent the positions of the player, enemy, and bullet, as well as several flags that represent the player’s actions and the game status. The logic of the module is implemented using several if-else statements and a case statement that update the position of the player, bullet, and enemy, and check for collisions and other game events.
The output game matrix is a 256-bit binary vector that represents the state of the game world, with each bit corresponding to a pixel on the game screen. The matrix is updated on each clock cycle to reflect the current position of the player, enemy, and bullet, as well as any collisions that occur.
The output score value is an 8-bit binary number that represents the player’s score, which is incremented each time the player shoots down an enemy.
Overall, this module implements the game logic for a simple shooting game that allows the player to move their character and shoot down enemy planes, while avoiding collisions and other obstacles.
Chapter 5. References
1.Principle of dynamic scanning
https://blog.csdn.net/qq_55203246/article/details/124155818
2. Electronic Design tutorial:16 *16 LED Matrix Driver
https://blog.csdn.net/geek_monkey/article/details/107622595
3.The Case statement in Verilog
https://blog.csdn.net/CLL_caicai/article/details/104395480
4.Verilog assigns a value to the array collective
https://blog.csdn.net/weixin\_34532284/article/details/112821125
5.The problem of std:bad_alloc
https://blog.csdn.net/WhereYouSink/article/details/103299432
Chapter 6. Appendices
Code.12 LED Text Display Testbench
1 |
|
Code.13 LED Image Display Testbench
1 |
|
Code.14 Aerial Combat Testbench
1 |
|