这里会显示出您选择的修订版和当前版本之间的差别。
后一修订版 | 前一修订版 | ||
icore4tx_fpga_5 [2020/05/09 09:49] fmj 创建 |
icore4tx_fpga_5 [2022/04/01 11:36] (当前版本) sean |
||
---|---|---|---|
行 2: | 行 2: | ||
|技术支持电话|**0379-69926675-801**||| | |技术支持电话|**0379-69926675-801**||| | ||
|技术支持邮件|Gingko@vip.163.com||| | |技术支持邮件|Gingko@vip.163.com||| | ||
- | |技术论坛|http://www.eeschool.org||| | ||
^ 版本 ^ 日期 ^ 作者 ^ 修改内容 ^ | ^ 版本 ^ 日期 ^ 作者 ^ 修改内容 ^ | ||
| V1.0 | 2020-05-09 | gingko | 初次建立 | | | V1.0 | 2020-05-09 | gingko | 初次建立 | | ||
行 26: | 行 25: | ||
* 运算符是用来执行程序代码运算的,是一段代码的重要组成部分。在Verilog HDL中按照功能划分,运算符可分为算术运算符、逻辑运算符、关系运算符、条件运算符、按位运算符、拼接运算符、移位运算符、等式运算符、赋值运算符等类型。按照运算符所带的操作数的个数划分可分为3类,即: | * 运算符是用来执行程序代码运算的,是一段代码的重要组成部分。在Verilog HDL中按照功能划分,运算符可分为算术运算符、逻辑运算符、关系运算符、条件运算符、按位运算符、拼接运算符、移位运算符、等式运算符、赋值运算符等类型。按照运算符所带的操作数的个数划分可分为3类,即: | ||
- | - 单目操作符,运算符可带一个操作数; | + | * 1、单目操作符,运算符可带一个操作数; |
- | - 双目操作符,运算符可带两个操作数; | + | * 2、 双目操作符,运算符可带两个操作数; |
- | - 三目操作符,运算符可带三个操作数。 | + | * 3、 三目操作符,运算符可带三个操作数。 |
- | * 1、算术运算符 | + | **1、算术运算符** |
* 在Verilog HDL中的算术运算符有多种,其中最常用的有4种,如表5-1所示。 | * 在Verilog HDL中的算术运算符有多种,其中最常用的有4种,如表5-1所示。 | ||
- | | 操作符 |执行的操作|操作数个数|表达式| | + | {{ :icore4tx:icore4tx_fpga_5_1.png?direct |表5-1}} |
- | |+|加法运算|2|rega + 10| | + | |
- | |-|减法运算|2|rega - 10| | + | |
- | |*|乘法运算|2|rega * 10| | + | |
- | |/|除法运算|2|23 / 10,运行结果为2| | + | |
* 在基本算术运算符应用过程中需要注意: | * 在基本算术运算符应用过程中需要注意: | ||
- | - 在进行整数除法运算时,省略所有小数部分,只保留整数部分; | + | * 1、在进行整数除法运算时,省略所有小数部分,只保留整数部分; |
- | - 在进行算术运算操作时,如果操作符的某个操作数出现x或z时,则整个操作的运算结果为x。 | + | * 2、在进行算术运算操作时,如果操作符的某个操作数出现x或z时,则整个操作的运算结果为x。 |
- | * 1、逻辑运算符 | + | **2、逻辑运算符** |
* 在Verilog HDL中有三种逻辑运算符,如表5-2所示。逻辑运算的结果只有两种:0(假)和1(真),其逻辑真值如表5-3所示。 | * 在Verilog HDL中有三种逻辑运算符,如表5-2所示。逻辑运算的结果只有两种:0(假)和1(真),其逻辑真值如表5-3所示。 | ||
- | | 操作符 |执行的操作|操作数个数|表达式| | ||
- | |!|逻辑求反|1|!a| | ||
- | |&&|逻辑与|2|a && b| | ||
- | ||||逻辑或|2|a || b| | ||
+ | {{ :icore4tx:icore4tx_fpga_5_2.png?direct |表5-2}} | ||
- | |a|b|!a|!b|a && b|a || b| | + | {{ :icore4tx:icore4tx_fpga_5_3.png?direct |表5-3}} |
- | |1|1|0|0|1|1| | + | |
- | |1|0|0|1|0|1| | + | |
- | |0|1|1|0|0|1| | + | |
- | |0|0|1|0|0|0| | + | |
- | ==== 四、引脚分配 ==== | + | **3、关系运算符** |
- | **1、 手动分配引脚** | + | * 关系运算符主要表征两者之间的关系,常用于两个操作数的比较,常用的有四种符号类型,如表5-4所示。 |
- | * 1、以实验二led工程为例,打开工程,如图3.1所示。 | + | {{ :icore4tx:icore4tx_fpga_5_4.png?direct |表5-4}} |
- | {{ :icore4tx:icore4tx_fpga_3_1.png?direct |图3.1}} | + | * 在进行关系运算时,如果表达式的两个操作数之间的关系时正确的,则运行结果为1(真),否则,运行结果为0(假);如果表达式中的某个操作数为不定值(x和z),则运行结果为x。 |
- | * 2、点击工具栏Tools,下拉才当中选中PlanAhead I/O Pin Planning(PlanAhead) – Pre – Synthesis…。 | + | |
- | {{ :icore4tx:icore4tx_fpga_3_2.png?direct |图3.2}} | + | **4、条件运算符** |
- | * 3、如果有提示点击Yes,稍等片刻后可能会弹出欢迎界面,关闭欢迎界面,然后视图如下: | + | * 条件运算是根据条件表达式的运行结果来选择执行表达式的,有3个操作数,其符号为“?:”,使用方式如下:\\ **con_expression ? true_expression : false_expression;** |
- | {{ :icore4tx:icore4tx_fpga_3_3.png?direct |图3.3}} | + | * 在运行条件运算符时,若条件表达式(con_expression)为真,则运行真表达式(true_expression),否则,运行假表达式(false_expression)。 |
- | * 4、在I/O Ports栏下面,点击Scalar ports 前面的“+”,展开引脚列表;然后在对应引脚的Site栏选定引脚标号,完成引脚的绑定。如下图所示。 | + | * 例如:wire data_out = sel_en ? a : b; |
- | {{ :icore4tx:icore4tx_fpga_3_4.png?direct |图3.4}} | + | * 其运行结果为:若sel_en为真,data_out的值取a;否则,data_out的值取b。 |
- | * 5、分配好以后关闭该对话框,重新进行编译;如果编译无报错,则引脚分配完成。 | + | |
+ | **5、按位运算符** | ||
+ | * 按位运算是两个操作数按照对应位进行“与”、“或”、“非”等逻辑操作,常用的按位运算符有5种,如表5-5所示。 | ||
+ | {{ :icore4tx:icore4tx_fpga_5_5.png?direct |表5.5}} | ||
+ | * 在按位运算中,若两个操作数的位宽不一致,则会自动将两个操作数右对齐,高位补0后进行运算。 | ||
+ | |||
+ | **6、拼接运算符** | ||
+ | * 拼接运算是将两个或多个操作数的某些位拼接起来得到一个新数据的表达式,其运算符号为“{}”,被拼接的操作数用“,”隔开,其表达式如下:**{signal1,signal2}** | ||
+ | |||
+ | **7、移位运算符** | ||
+ | * 在Verilog HDL中有两种移位运算符,如表5-6所示。 | ||
+ | {{ :icore4tx:icore4tx_fpga_5_6.png?direct |表5.6}} | ||
+ | |||
+ | **8、等式运算符** | ||
+ | * 在Verilog HDL中有四种等式运算符,如表5-7所示。 | ||
+ | |||
+ | {{ :icore4tx:icore4tx_fpga_5_7.png?direct |表5.7}} | ||
+ | |||
+ | * 在进行等式运算中,“==”和“!=”又被称作是逻辑等式运算符,由于等式运算中的两个操作数有可能是x和z,因此其运算结果可能是不定值x。但是,“===”和“!==”对比时要求两个操作数必须完全一致,因此其运行结果只有0和1两种。 | ||
+ | |||
+ | **9、赋值运算符** | ||
+ | * 赋值运算就是Verilog HDL的赋值语句,根据赋值操作后变量改变方式的不同,赋值语句又分为连续赋值和过程赋值两种,如表5-8所示。 | ||
+ | {{ :icore4tx:icore4tx_fpga_5_8.png?direct |表5.8}} | ||
+ | * 通常,连续赋值运算用于“assign”语句中,用于对wire型变量进行赋值,“=”两侧的操作数是随时变化的。例如:assign a = b,当b信号发生变化时,a也随之变化。 | ||
+ | * 在过程赋值中,按照操作数改变时刻的不同,分为阻塞赋值(=)和非阻塞赋值(<=)两种。 | ||
+ | * 1、阻塞赋值方式 | ||
+ | * 1) 赋值语句执行完成后,才结束块的运行; | ||
+ | * 2) 操作数在赋值语句执行后立刻改变变量值; | ||
+ | * 2、非阻塞赋值方式 | ||
+ | * 1)在语句块中,赋值语句执行完成后,在块结束前,赋值语句中操作数的值保持不变; | ||
+ | * 2)块结束后,对操作数进行赋值操作,且所赋值为上一次赋值得到的; | ||
+ | * 3)非阻塞赋值方式常用于编写可综合的时序逻辑模块中。 | ||
+ | |||
+ | ==== 四、代码讲解 ==== | ||
+ | **1、 算术运算符表达式** | ||
+ | * 其代码如下: | ||
+ | <code verilog> | ||
+ | /*************************************************/ | ||
+ | //算数运算符:"+"、"-"、"*"、“/” | ||
+ | assign out_a = x1 + y1;//加法运算符表达式 | ||
+ | assign out_b = y1 - x1;//减法运算符表法式 | ||
+ | assign out_c = 2 * x1;//乘法运算符 | ||
+ | assign out_d = y1 / 5;//除法运算符 | ||
+ | </code> | ||
+ | |||
+ | **2、逻辑运算符表达式** | ||
+ | * 其代码如下: | ||
+ | <code verilog> | ||
+ | /*************************************************/ | ||
+ | //逻辑运算符:“!”、“&&”、“||”,逻辑运算符的结果只能是“1”或者“0” | ||
+ | assign out_e = !x2;//逻辑求反表达式 | ||
+ | assign out_f = x2 && y2;//逻辑与表达式 | ||
+ | assign out_g = x2 || y2;//逻辑或表达式 | ||
+ | |||
+ | </code> | ||
+ | **3、关系运算符表达式** | ||
+ | * 其代码如下: | ||
+ | <code verilog> | ||
+ | /*************************************************/ | ||
+ | //关系运算符:“<”、“>”、“<=”、“>=” | ||
+ | //条件运算符表达式:con_expression ? true_expression ? false_expression; | ||
+ | assign out_h = (x3 < y3) ? (y3 - x3) : 4'd0;//小于号表达式 | ||
+ | assign out_i = (x3 > y3) ? 4'd0 : (y3 + x3);//大于号表达式 | ||
+ | assign out_j = (y3 <= z3) ? (y3 - x3) : 4'd0;//小于等于号表达式 | ||
+ | assign out_k = (y3 >= z3) ? (y3 - x3) : 4'd0;//大于等于号表达式 | ||
+ | |||
+ | </code> | ||
+ | **4、按位运算符表达式** | ||
+ | * 其代码如下: | ||
+ | <code verilog> | ||
+ | /*************************************************/ | ||
+ | //按位运算符:“~”、“&”、“|”、“^”、“~^” | ||
+ | //在按位运算中,若两个操作数的位宽不一致,则会自动将两个操作数右对齐,高位补0后进行运算 | ||
+ | assign out_l = ~x4;//按位求反表达式 | ||
+ | assign out_m = x4 & y4;//按位与表达式 | ||
+ | assign out_n = x4 | y4;//按位或表达式 | ||
+ | assign out_o = x4 ^ y4;//按位异或表达式 | ||
+ | assign out_p = x4 ~^ y4;//按位同或表达式 | ||
+ | |||
+ | </code> | ||
+ | **5、拼接运算符** | ||
+ | * 其代码如下: | ||
+ | <code verilog> | ||
+ | /*************************************************/ | ||
+ | //拼接运算符 | ||
+ | assign q = {x5,y5};//拼接运算符表达式 | ||
+ | |||
+ | </code> | ||
+ | **6、移位运算符表达式** | ||
+ | * 其代码如下: | ||
+ | <code verilog> | ||
+ | /*************************************************/ | ||
+ | //移位运算符:“<<”、“>>” | ||
+ | assign r = x6 << 3;//左移表达式 | ||
+ | assign s = x6 >>3;//右移表达式 | ||
+ | |||
+ | </code> | ||
- | **2、TCL文件分配引脚** | ||
- | * 1、还是以实验二LED实验为例,选中工程,右键点击New Source …。 | ||
- | {{ :icore4tx:icore4tx_fpga_3_5.png?direct |图3.5}} | ||
- | * 2、新建文件类型为Implementation Constraints File,File name栏输入文件名,如下图所示,然后点击Next。 | ||
- | {{ :icore4tx:icore4tx_fpga_3_6.png?direct |图3.6}} | ||
- | * 3、点击Finish。 | ||
- | {{ :icore4tx:icore4tx_fpga_3_7.png?direct |图3.7}} | ||
- | * 4、可以在左侧边栏看到工程目录下多了一个.ucf格式的文件,在右边编辑区输入下图中的引脚约束信息,如图所示;引脚约束信息的语法定义如下: | ||
- | * **NET “端口名称” LOC = 引脚编号 | IOSTANDARD = “电压”** | ||
- | {{ :icore4tx:icore4tx_fpga_3_8.png?direct |图3.8}} | ||
- | * 5、点击保存,并编译工程;如果信息输入正确,编译通过,则Implement Design 前面会出现绿色“√”;则引脚分配完成。 | ||
- | {{ :icore4tx:icore4tx_fpga_3_9.png?direct |图3.9}} | ||
==== 五、实验步骤 ==== | ==== 五、实验步骤 ==== | ||
- | - 将iCore4TX连接下载器和USB供电线; | + | * 1、将硬件正确连接,如图5.1所示。 |
- | - 分别按照手动分配引脚方式和.ucf文件分配引脚方式分配引脚并编译整个工程。 | + | {{ :icore4tx:icore4tx_fpga_5_9.png?direct |图5.1}} |
- | - 分别将编译后的工程下载至iCore4TX,并观察现象。 | + | * 2、将编写好的代码进行编译,并将要观察的所有输出信号添加到ChipScope Pro中。 |
+ | * 3、通过ChipScopePro工具对运算结果进行采集,波形如图5.2所示。 | ||
+ | {{ :icore4tx:icore4tx_fpga_5_10.png?direct |图5.2}} | ||
+ | * 4、观察ChipScopePro采集到的运算结果与逻辑运算的实验结果,并进行对比验证。 | ||
+ | * 5、还可以通过RTL视图查看逻辑运算综合后的门逻辑。通过点击ToolsSchematic ViewerRTL…打开RTL视图。 | ||
+ | {{ :icore4tx:icore4tx_fpga_5_11.png?direct |图5.3}} | ||
+ | * 6、RTL级示图如下。 | ||
+ | {{ :icore4tx:icore4tx_fpga_5_12.png?direct |图5.4}} | ||
+ | |||
+ | ==== 六、 拓展实验==== | ||
+ | *1、更改实验代码中的变量的初始值,看看运算结果有何不同; | ||
+ | *2、编写代码观察阻塞赋值与非阻塞赋值有何不同。 | ||
- | ==== 六、实验结果 ==== | ||
- | * 可以观察到iCore4TX 的FPGA_LED 闪烁。 |