Verilog全新语法认识--Xilinx language template
文章目錄
- 0.背景
- 1、verilog語法篇
- 1.1、common constructs
- 1.2 、compiler directives(編譯指令)
- define
- include
- timescale
- 1.3 operator
- arithmetric
- bitwise
- logic
- replicate/concatenate 復制和拼接操作
- shift移位操作
- unary reduction
- function and task 用法
0.背景
本篇blog將圍繞官方提供的verilog模板以及仿真模板,來全新的認識verilog語法,這里面其實有很多你還不熟悉的語法,以及你沒見過的語法,要不然我就不會打算寫這么一篇文章了,當然,僅僅是逐步熟悉語法,以至于怎么將verilog和實際的數字電路對應起來,還需要更進一步的深刻認識,才能真正理解數字電路,這個在后續的日子中,我再好好理解理解,有空推出。另外關于VHDL和systemveriog這兩個語法其實也很好懂,以后再來學一下,然后再推出文章。
1、verilog語法篇
1.1、common constructs
/* */ 對于多行的注釋 // 對于單行的注釋1.2 、compiler directives(編譯指令)
define
`define <name> <string> `ifdef <define_name><statements>; `elsif <define_name><statements>; `else<statements>; `endif `ifndef <define_name><statements>; `endif例子:
// The `define, `ifdef, `elsif, `else, `ifndef and the `endif compiler directives // ============================================================================== // // `define is a compiler directive that defines a value to a variable. That variable // can then be called upon in the code by referencing the `name of the specified variable. // // `ifdef is a compiler directive that checks for the existence of a specified `define // and then conditionally includes a section of code during compilation if it exists. // // `ifndef is the opposite of `ifdef in that if a `define was not declared, it includes // a section of code. // // `elsif can be used in conjunction with a `ifdef to find the existence of another // `define and conditionally compile a different section of code if the previous // conditions were not met and this condition is met. // // `else also can be used in conjunction with a `ifdef where it will compile a section // of code if all previous `ifdef and `elsif conditions were not met. // // `endif is used at the end of a `ifdef or `ifndef statement to signify the end of // the included code. // // Example:`define DATA_WIDTH 16 `define DATA_WIDTH16reg [`DATA_WIDTH-1:0] data;`ifdef DATA_WIDTH8// If DATA_WIDTH8 was set, this would get compiled `elsif DATA_WIDTH16// Since DATA_WIDTH16 is set, this does get compiled `else// If DATA_WIDTH8 and DATA_WIDTH16 was not defined, this would be compiled `endif我的例子(以下例子是我個人在QUARTUS實驗編譯成功的模板結果):
`define datawidth 32 module CP_language_template_test( input clk, output [`datawidth:0] result );endmodule說明:宏定義可以在module的外面,也可以在module的里面,另外在引用宏定義的時候要記得前綴,在引用已定義的宏名時,必須在宏名的前面加上符號“`”,表示該名字是一個經過宏定義的名字。module CP_language_template_test `define datawidth 32 ( input clk, output [`datawidth:0] result); endmodule說明:以下是使用ifdef elsif else的例子`ifdef datawidth1`define datawidth1 3 `elsif datawidth2`define datawidth2 3 `else`define datawidth 32 `endifmodule CP_language_template_test( input clk, output [`datawidth-1:0] result); endmodule說明:以下是ifndef endif的使用 module CP_language_template_test `ifdef datawidth1`define datawidth1 3 `elsif datawidth2`define datawidth2 3 `else`ifndef datawidth3`define datawidth 32`endif`endif( input clk, output [`datawidth-1:0] result);endmoduleinclude
`include "<file_name>" // The `include complier directive // =============================== // // `include can be used to insert the contents of a separate file into a module. // This is often used to communicate common functions, compiler directives, parameters // and `defines to multiple files in a project. The file and path name must be // specified in quotes and can consist of just the file name (looks in the current // working directory for the file), a relative path to the file or an absolute path // to the file. This directive can be specified both before the module declaration // as well as within the module directive. // // Example:// Include the contents of the parameters.vh file located in the current working directory. // Many simulator and synthesis tools also offer a switch/option to allow specification // of a search directory other than the working directory for files specified in this manner. `include "parameters.vh" // Include the contents of the ram_data.vh file in the relative directory ../data `include "../data/ram_data.vh" // Include the contents of master.vh in the absolute directory /export/vol1/sim_data `include "/export/vol1/sim_data/master.vh"我的例子(以下例子是我個人在QUARTUS實驗編譯成功的模板結果):
`include "define.v" module CP_language_template_test `ifdef datawidth1`define datawidth 3 `elsif datawidth2`define datawidth 4 `else`ifndef datawidth`define datawidth 32`endif`endif( input clk, output [`datawidth-1:0] result);endmodule另外,我再生成一個文件define.v的文件 `define datawidth 18
經過上圖,完全符合我們的預期效果。
timescale
// The `timescale compile directive information // ============================================ // // `timescale is a compiler directive that indicates to the simulator the time units // and precision to be used during simulation. The format is the following: // // `timescale <units> / <precision> // // The units should be set to the base value in which time will be communicated to // the simulator for that module. // The precision is the minimum time units you wish the simulator to resolve. The // smallest resolution value in all files and models compiled for simulation dictates // the overall simulation resolution. In general for Xilinx FPGAs, a simulator // resolution of 1ps is recommended since some components like the DCM require this // resolution for proper operation and 1 ps is the resolution used for timing simulation. // // In general, this directive should appear at the top of the testbench, simulation models // and all design files for a Verilog project. // // Example:`timescale 1 ns / 1ps#1; // Delays for 1 ns #1.111; // Delays for 1111 ps #1.111111111; // Delays for 1111 ps since the resolution is more course than// what is specified, the delay amount is truncated1.3 operator
arithmetric
// The following are the arithmetic operators as defined by the Verilog language. // // + .... Addition // - .... Subtraction // * .... Multiplication // / .... Divide // % .... Modulus // ** ... Power Operator (i.e. 2**8 returns 256)除法,在一個周期內完成
求余
求指數算法
bitwise
// The following operators can be used on two single bits to produce a single bit // output or two equivalent sized bused signals where the operations are performed // on each bit of the bus. In the case of the Invert, only one signal or bus is // provided and the operation occurs on each bit of the signal. // // ~ .... Invert a single-bit signal or each bit in a bus // & .... AND two single bits or each bit between two buses // | .... OR two single bits or each bit between two buses // ^ .... XOR two single bits or each bit between two buses // ~^ ... XNOR two single bits or each bit between two buses
result_reg=a&b;如上圖所示
result_reg=a&&b;如上圖所示
可以看出&是按照位進行操作的
result_reg=a^b;如上圖所示
logic
// The following logical operators are used in conditional TRUE/FALSE statements // such as an if statement in order to specify the condition for the operation. // // ! .... Not True // && ... Both Inputs True // || ... Either Input True // == ... Inputs Equal // === .. Inputs Equal including X and Z (simulation only) // != ... Inputs Not Equal // !== .. Inputs Not Equal including X and Z (simulation only) // < .... Less-than // <= ... Less-than or Equal // > .... Greater-than // >= ... Greater-than or Equalreplicate/concatenate 復制和拼接操作
// The following operators either concatenates several bits into a bus or replicate // a bit or combination of bits multiple times. // // {a, b, c} .... Concatenate a, b and c into a bus // {3{a}} ....... Replicate a, 3 times // {{5{a}}, b} .. Replicate a, 5 times and concatenate to b //
shift移位操作
// The following operators will shift a bus right or left a number of bits. // // << .... Left shift (i.e. a << 2 shifts a two bits to the left) // <<< ... Left shift and fill with zeroes // >> .... Right shift (i.e. b >> 1 shifts b one bits to the right) // >>> ... Right shift and maintain sign bit
可以看出采用1來填充,并且保持符號位置不變
unary reduction
// The following operators can be used on a bussed signal where all bits in the bus // are used to perform the operation and a single bit output is resolved. // // & .... AND all bits together to make single bit output // ~& ... NAND all bits together to make single bit output // | .... OR all bits together to make single bit output // ~| ... NOR all bits together to make single bit output // ^ .... XOR all bits together to make single bit output // ~^ ... XNOR all bits together to make single bit outputfunction and task 用法
// User defined function and task information // ========================================== // // A user defined function is a set of Verilog statements that // can be called from elsewhere within the body of the code by // an assignment. A function can have multiple inputs however // can return only a single output. No timing information can // be specified within a function. // // A user defined task is a subroutine that can be executed by // a single call from elsewhere within the body of the code. // A task can have any number of inputs, outputs and inouts as // well as contain timing information. // // Example of a function declaration:function [9:0] gray_encode;input [9:0] binary_input;begingray_encode[9] = binary_input[9];for (k=8; k>=0; k=k-1) begingray_encode[k] = binary_input[k+1] ^ binary_input[k];endendendfunction// Example of calling a function:// write_count is the binary input being passed to the function gray_encode.// The output of the function gray_encode is then passed to the signal FIFO_ADDRFIFO_ADDR = gray_encode(write_count);// Example of a task declaration:task error_action;input read_write;input correct_value;input actual_value;input [8*11:0] output_string;beginif (ERROR_CHECK) beginif (read_write)$display("Error: %s value incorrect during write %d at time %t\nExpecting %b, got %b",output_string, write_attempt, $realtime, correct_value, actual_value);else$display("Error: %s value incorrect during read %d at time %t\nExpecting %b, got %b",output_string, read_attempt, $realtime, correct_value, actual_value);if (ON_ERROR=="FINISH")$finish;else if (ON_ERROR=="STOP")$stop;endendendtask// Example of calling a task:// The task error_action is called by name and passed the four input values// in the order they are declared in the taskerror_action(1'b1, wr_ready_value, WR_READY, "WR_READY"); function [<lower>:<upper>] <output_name> ;input <name>;begin<statements>endendfunction // A task is a subroutine with any number of input, output or inout// arguments and may contain timing controlstask <task_name>;input <input_name>;<more_inputs>output <output_name>;<more_outputs>begin<statements>;endendtask我的例子(以下例子是我個人在QUARTUS實驗編譯成功的模板結果):
function [<lower>:<upper>] <output_name> ;input <name>;begin<statements>endendfunction正如官方的語法說明所示,
function 語句標志著函數定義結構的開始; [:]參數代表了指定函數返回值的
位寬,是一個可選項,若沒有指定,默認缺省值為 1 比特的寄存器數據;<output_name> 為所定義函數的名稱,對函數的調用也是通過函數名完成的,并在函數結構體內部代表一個內部變
量,函數調用的返回值就是通過函數名變量傳遞給調用語句。
現在不用function函數
可以看出綜合出來的RTL代碼是一樣的,說明使用functon函數可以簡化我們的編程,而且是可綜合的。
當然,這一眼看上去貌似都正確,細心的人有沒有發現我們的RTL代碼輸出的result的數據表示呢?
其實,我發現,采用reg [高位:低位]和reg [低位:高位]兩種定義的方法是一樣的。
這里我的建議是【高位 低位】
此處例子參考:https://blog.csdn.net/qq_37147721/article/details/84889832
我的例子(以下例子是我個人在QUARTUS實驗編譯成功的模板結果):
下面我開始延時task的用法
總結
以上是生活随笔為你收集整理的Verilog全新语法认识--Xilinx language template的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 安装UPS电源
- 下一篇: STM32系列--初识寄存器1