[Perf-V Review] Flowing Light & Verilog Basic Syntax
[Copy link]
This post was last edited by donatello1996 on 2021-2-19 20:21
During the Spring Festival holiday, I learned the basic usage of the VIVADO development environment and the basic syntax of the Verilog language. I used the knowledge I learned to write a simple running light, which was quite rewarding. Let me first talk about the VIVADO environment. To write the running light code in this environment, you need to do:
- Source code writing
- Run synthesis -
Run implementation -
Implementation design specifies hardware pins
- Generate bit files
- Burn bit files into DDR or FLASH
There are five steps, among which run implementation depends on the run synthesis step, generating bit files depends on the run implementation step, and binding the hardware pins of the FPGA chip and the source code is completed in the implementation design function of the run implementation step, because all the input and output variables in the source code are not bound to any pins. If the input and output variables in the source code change (variable name/number of variables changes), you need to re-run all the above steps; if you just want to re-specify some hardware pins and the input and output variables do not change, you do not need to re-run the run synthesis step. Let's take a look at the source code writing part first:
module led(
input sw1,
input sw2,
input sw3,
input sw4,
input clk,
output D0,
output D1,
output D2,
output D3,
output reg[8:0] D456
);
assign D0 = sw1;
assign D1 = sw2;
assign D2 = sw3;
assign D3 = sw4;
parameter T = 10000000;
reg [31:0] cnt;
reg [31:0] state;
reg [8:0] led_bits [8:0];
integer flag = 1;
always @ (posedge clk)
begin
if(flag == 1)
begin
flag <= 0;
state <= 0;
led_bits[0] <= 9'b111111110;
led_bits[1] <= 9'b111111101;
led_bits[2] <= 9'b111111011;
led_bits[3] <= 9'b111110111;
led_bits[4] <= 9'b111101111;
led_bits[5] <= 9'b111011111;
led_bits[6] <= 9'b110111111;
led_bits[7] <= 9'b101111111;
led_bits[8] <= 9'b011111111;
end
cnt <= cnt + 1;
if(cnt == T)
begin
cnt <= 0;
D456 <= led_bits[state];
state <= state + 1;
if(state == 10)
begin
state <= 0;
end
end
end
endmodule
Interpret line by line, for fear of overlooking the details:
-begin/end is similar to the curly brackets {} in C language, which is a section of inclusive code;
-module led(...); The writing method is similar to the main function of C language. It is the main execution part of Verilog language. The declaration of input and output variables is in the parentheses. A semicolon should be added after the parentheses. After writing module, it should end with endmodule, which is similar to the end of C language function. The right curly bracket
module usually contains input input variables and output output variables. If there is no reg or bracket [8:0] keyword, it defaults to bool type variable, and the variable value is 1 or 0. For example, input sw1 is a one-bit wide input variable sw1, output D0 is a one-bit wide output variable D0, and output reg[8:0] D456 is a 9-bit wide output variable D456;
-assign D0 = sw1; This statement fully demonstrates that Verilog is a descriptive language rather than a procedural language. This statement shows that the value of the output variable D0 must be completely equal to the value of the input variable sw1. As long as the FPGA starts to power on and run the code, the state of D0 must follow the state of sw1, regardless of the execution time and is not affected by other procedural factors and other variables.
-parameter T = 10000000; T is a constant with a value of 10000000 and cannot be modified elsewhere in the source code, similar to C language const;
-reg [31:0] cnt; cnt is a variable with a bit width of 32 bits, similar to int cnt in C language. The bit width of reg variable can be freely specified;
-reg [8:0] led_bits [8:0]; led_bits is a one-dimensional array with 9 members and a bit width of 9. The number of members is after the reg keyword, and the bit width is after the variable name. The bit width of the reg array can be freely specified;
-integer flag = 1; The usage is exactly the same as int flag = 1 in C language;
-always @ (posedge clk) is a loop syntax, similar to while(), where the variable posedge clk means the rising edge of the clk input variable/input signal. The whole sentence means that every time the clk input signal generates a rising edge, the statement inside the always is executed once. From this, we can see that the loop syntax of Verilg can be completely controlled by hardware signals, while statements such as while(1)/while(i++) in C language are controlled by CPU machine cycles. Although machine cycles and hardware signals have a specific algebraic relationship, there is still an essential difference. Here is another point to note, FPGA chips can be connected to one or more clock sources, at least one, and different always statements can be controlled by clock sources of different frequencies. The clock source is divided by counter overflow inside the always statement. The code is very simple and crude. Seeing this reminds me of the TIMER timer that comes with the STM32 microcontroller, but the Verilog statement is obviously more direct than the TIMER;
- if(flag == 1)
begin
flag <= 0;
...
end
This statement is executed once after power-on, because Verilg syntax stipulates that all variable assignment statements must be executed in the entity module, and the always statement is the most commonly used entity module;
-After power-on, assign values to each member of the led_bits array, from 111111110 to 011111111, which is the effect of running lights;
-D456 <= led_bits[state]; Assign the value of the array to the D456 output variable. D456 is exactly a 9-bit variable, corresponding to the three RGBLED lights on the board.
After the code is written, check for syntax errors and start run synthesis and run implementation. Use the shortcut key F11:
Then specify the hardware pins. Here, specify the pins of the D456 output variable as the actual RGBLED lamp pins of the development board. There are nine pins in total, which are configured in sequence. In addition, there are four red LED lights and four switches corresponding to D0~D3, sw1~sw4:
After the configuration is complete, generate the bit file by clicking the button in the upper toolbar. Note that there is a chance of error when generating the bit file, prompting Error(s) found during DRC. Bitgen not run. For the solution, refer to:
https://blog.csdn.net/weixin_43065256/article/details/86557378, that is, write a name.tcl script file with the following content:
set_property SEVERITY {Warning} [get_drc_checks NSTD-1]
set_property SEVERITY {Warning} [get_drc_checks RTSTAT-1]
set_property SEVERITY {Warning} [get_drc_checks UCIO-1]
Assign the script to the right-click menu Settings of the Generate Bitstram function, and fill in the name.tcl file just specified in the tcl.pre column:
Then there will be no problem in regenerating the bit file.
This should be considered a bug of XILINX. Later, the official forum also responded to it:
https://forums.xilinx.com/t5/Vivado-TCL-Community/Error-during-Bitgen-Vivado-12-1345-Error-s-found-during-DRC/td-p/333171
After the bit file is generated, you need to download the file to the DDR of the board and use the Hardware Manager function directly.
When you get onto the board, the RGBLED on the board will have a running light effect:
Toggle the switch and the corresponding red light will turn on and off:
If you want to download to SPI FLASH, you will encounter a second problem: ERROR: [Writecfgmem 68-20] SPI_BUSWIDTH property is set to "1" on bitfile
This method is also easy to solve. Enter in the terminal below
set_property BITSTREAM.CONFIG.SPI_BUSWIDTH 4 [current_design]
Instructions, regenerate the bit file and burn the MCS file.
In addition, the VIVADO environment also has an RTL function for developers to refer to, to verify whether the code is written and the device is built correctly:
Finally, during the operation of VIVADO2020, there may be incompatibility with the 2018 version of the driver. You can use the driver in the data\xicom\cable_drivers\nt64\digilent path under the VIVADO path:
|