当前位置: 首页 > news >正文

网站专门做冻品的有什么推广网站

网站专门做冻品的,有什么推广网站,上传网站代码,贵州省建设厅网站官网来源#xff1a;CSDN文章使用逻辑门和连续赋值对电路建模#xff0c;是相对详细的描述硬件的方法。使用过程块可以从更高层次的角度描述一个系统#xff0c;称作行为级建模(behavirol modeling)。1. 过程赋值阻塞赋值和非阻塞赋值的区别都很熟悉了。这里记录两个特性。1.1 特… 来源CSDN文章使用逻辑门和连续赋值对电路建模是相对详细的描述硬件的方法。使用过程块可以从更高层次的角度描述一个系统称作行为级建模(behavirol modeling)。1. 过程赋值阻塞赋值和非阻塞赋值的区别都很熟悉了。这里记录两个特性。1.1 特性1绝大多数情况下非阻塞赋值都是一个时间点处最后执行的赋值语句。看下面的示例代码module test( input clk, output reg a, b);always (posedge clk) begin a 0; b 1; a b; b a;endendmodule非阻塞赋值可以认为包括两步(1)求值和调度(evaluate and schedule)先得到非阻塞赋值等式右侧的值并将这次赋值安排在当前时间点的结束时刻。(2)当前时间点结束时更新左侧的值。因此这段代码的结果是 a 1b 0。1.2 特性2如果过程块内有针对同一个变量的多个非阻塞赋值那么这些非阻塞赋值会按顺序执行(但我认为不能简单地说过程块内是“顺序执行的”容易造成误导应该说具有一定的“顺序性”特点)。看下面的示例代码module test( input clk, output reg a, b);always (posedge clk) begin a 0; a 1;endendmodulealways块内有两条对于变量a的赋值语句但由于顺序性特点a的赋值结果应该是1。利用这个特性会经常见到下面这种代码写法always (posedge clk) begin a 0; if (flag 1) a 1;end只有当flag1时a才为1。2. 过程连续赋值这种赋值方式允许在过程块中连续地驱动网络或变量。但这种建模方法不可综合因此这里只简单记录一下两种过程连续赋值方式的作用。assign和deassignassign连续赋值会优先占用一个变量让其它对这个变量进行赋值的过程块无效。deassign连续赋值会解除占用关系。看下面的示例代码timescale 1ns / 1psmodule sim();reg clk 0, rst_n 0, d 1;reg q;//test i1//(// .clk (clk),// .rst_n(rst),// .q(q),// .d(d)//);always (rst_n) if (!rst_n) assign q 0; else deassign q;always (posedge clk) q d;always #5 clk ~clk;initial begin #50 rst_n 1;endendmodule当rst_n0时asssign连续赋值占用了qq的值恒为0当rst_n1时deassign解除了占用q的值由其它过程赋值决定在clk上升沿随d变化而变化。force和release功能和assign、deassign相同只是赋值对象可以是变量也可以是网络。force过程赋值的对象为网络时会使其它所有对该网络的驱动无效。3. case语句case语句的default分支不是必须的只要设计者清楚设计意图即可。记录一下case两个比较少见但有时候特别有用的用法。3.1 do-not-cares包括两种  •  casez表示不关心高阻状态(z)  •  casex表示不关心高祖状态(z)和未知状态(x)。在不关心的bit位上使用“?”表示要更加方便。casex和casez完全是可以综合的例如下面的代码可以实现优先编码器module test( input clk, input [3:0] d, output reg [15:0] q);always (posedge clk) casez (d) 4b1??? : q 1; 4b01?? : q 2; 4b001? : q 3; 4b0001 : q 4; endcaseendmodule如果想使用casex和casez还是要从“设计上”能否综合的角度考虑一下并且做好综合后的仿真。比如上面的代码使用case语句16条分支可以实现同样的效果这个设计完全是可以综合实现的。使用casez更多还是起到简化代码设计的作用。3.2 常数casecase语句中可以使用常数表达式这个常数会和每个分支中的表达式进行比较。如下面的代码module test( input clk, input [3:0] d, output reg [15:0] q);always (posedge clk) casez (1) d[0] : q 1; d[1] : q 2; d[2] : q 3; d[3] : q 4; endcaseendmodule可以实现根据d中的哪个bit为1执行相应的代码。如果d中多个bit同时为1此时多条分支同时满足会执行顺序最前面的一条。总之还是要清楚设计意图做好仿真工作。4. 循环语句forever 和 repeat 是完全不可综合的只用于仿真文件的设计。循环语句 for 和 while 并不是完全不能综合的但因为Verilog是对硬件进行建模for和while的使用肯定不像在软件编程语言中使用一样灵活。还是上面的老话要从“设计上”能否综合的角度进行考虑。如果循环语句的使用出现问题综合工具会给出提示如Vivado的提示信息如下[Synth 8-3380] loop condition does not converge after 2000 iterations用好循环可以简化代码设计。一个寄存器链的示例如下(使用for也能达到同样的效果)module test( input clk, rst_n, input [15:0] d, output reg [15:0] q);integer i;(* keep true *)reg [15:0] mem [7:0];always (posedge clk or negedge rst_n) begin if (!rst_n) begin i 0; while(i 8) begin mem[i] 0; i i 1b1; end end else begin i 0; mem[0] d; while(i 7) begin mem[i1] mem[i]; i i 1b1; end end q mem[7];endendmodule相应的RTL原理图如下 按软件编程思维考虑循环语句是一条一条执行的一个过程。而从上面的设计结果来说显然while循环中的所有语句是“同时”执行的代码只是将很多具有重复性特点的赋值语句改用 while/for 的形式来编写。5. 过程块过程块(procedure)包括四种initial结构、always结构、任务(task)、函数(function)。这里只记录两个不太熟悉的特性。5.1 零延迟无限循环always块在仿真文件中都要与一些时序控制配合使用。如果always块中没有任何推动仿真时间的控制仿真会卡在一个时间点。比如经常用如下语句创建时钟信号always #10 clk ~clk;如果写成了如下的形式always clk ~clk;相当于形成了一个零延迟的无限循环仿真时间会卡在0s无法前进。如果运行这个代码轻则程序卡死重则系统奔溃只能重启。5.2 initial用于初始化initial块是可以综合的只不过不能添加时序控制语句因此作用有限一般用于变量的初始化。如下面代码reg [15:0] mem [7:0];integer i;initial begin for (i 0; i 8; ii1) mem[i] i;end6. 过程块时序控制此特性主要用于仿真文件中部分在硬件设计中也会涉及。Verilog有两种明确的时序控制类型延时控制和事件表达式。仿真时间正是靠过程块中的延时控制、事件控制以及wait语句来推动的。6.1 延时控制用于控制语句的执行时间比如描述激励的波形。延迟值可以是表达式比如“#d rega regb;”这条赋值语句会在延迟d个时间单位后执行。(1)如果d的计算结果是高阻(z)或未知(x)则当作0处理(2)如果d的计算结果为负数也会将其视作无符号数来看待如下面的代码parameter [7:0] delay -50;initial begin rst_n 0; #(-delay) rst_n 1; #delay rst_n 0;endrst_n先延迟50个时钟后变为1由于8bit -50的二进制补码当作无符号数看时值为206因此在延时206个时钟后rst_n值又变为0。6.2 事件表达式直到某些仿真事件发生时语句才会只执行。网络或变量的值发生变化称作隐式事件(implict event)设计者设置一些命名事件可能会由其它过程块触发称作显式事件(explicit event)。值的变化、或变化的方向(上升沿posedge或下降沿negedge)都是隐式事件。虽然在硬件设计中经常和always配合使用(比如 always (posedge clk) )但在仿真文件中有更多灵活的使用方法。看下面的代码示例// example1clk上升沿语句执行reg [7:0] delay 0;initial begin forever (posedge clk) delay delay 1b1;end// example2clk的值发生变化语句执行reg [7:0] delay 0;always begin (clk) delay delay 1b1;end如果 posedge 和 negedge 检测的对象是一个表达式或多位宽的数据则只会检测LSB上的边沿变化。如下// example3reg [2:0] cnt 0;always (posedge clk) cnt cnt 1b1;reg [7:0] delay 0;always begin (posedge cnt) delay delay 1b1;end检测3bit变量cnt的上升沿相当于检测cnt[0]的边沿事件。事件(event) 是除了变量和网络外Verilog中的另一种数据类型如果一个标识符被申明为事件类型则称作“命名事件”需要显示地触发。虽然事件是一种数据类型但它本身又没有任何“数据”。如下面的示例event trig; // 命名事件申明reg [2:0] cnt 0;always (posedge clk) begin cnt cnt 1b1; if (cnt 7) - trig; // 事件显示触发endreg [7:0] delay 0;always begin (trig) delay delay 1b1; // 事件捕获end使用命名事件可以有效的实现多个过程块之间的通信和同步。如果过程块语句的执行同时对多个事件敏感可以使用事件的逻辑或特性。在事件敏感列表中使用 “or” 或 “,”(这两个符号含义等价)如“always (posedge clka or posedge clkb, trig)”。还有一个特性称作隐式事件表达式符号为“*”会把过程时序控制语句中所有读取的变量和网络添加到事件表达式中6.3 wait语句上面的事件控制方法都是边沿敏感型的。还可以使用wait语句控制过程块的时序直到某项条件为true时才执行相应语句这种方法称作电平敏感型。如果wait中的条件为false则过程块会一直阻塞直到条件变为真时才会执行后面的语句。比如下面的代码reg [7:0] cnta 0, cntb 0;initial begin wait(en) #10 cnta 60; #10 cntb 70;end对于begin…end(顺序块) 而言wait会阻止顺序块的执行直到en为1时cnta和cntb的两条赋值语句才会执行。如果使用fork…join(并行块)则上述代码中的wait只会对cnta的赋值语句有效此时最好也为wait语句加上块声明(begin…end或fork…join)。6.4 赋值间(Intra-assignment)时序控制赋值间延迟和事件控制是另一种时序控制方法如 a #5 b;与“ #5 a b; ”不同赋值语句右边的表达式会马上求值延迟和事件只是控制这个值赋值给赋值语句左边的时间。比如上面的代码等效于begin temp b; #5 a temp;end 利用赋值间时序控制的特性可以巧妙地完成一些行为建模。比如下面的代码可以避免赋值语句间的“竞争”达到数据交换的效果fork // 并行块存在竞争 #5 a b; #5 b a;joinfork // 数据交换 a #5 b; b #5 a;join赋值间延迟之前会先求等式右边的值延迟后才会把这个值赋到左边因此上面代码相当于交换了a和b的值。很多工具在实现Verilog的赋值间时序控制这个特性时都会使用临时存储来存放右边表达式的值。也可以用事件控制a (posedge clk) b;//等效于begin temp b; (posedge clk) a temp;end赋值间时序控制还有一个特点是可以用repeat来控制延迟或事件执行的次数如a repeat(3) (posedge clk) b;//等效于begin temp b; (posedge clk); (posedge clk); (posedge clk); a temp;end要注意如果采用变量的形式 “ repeat (num) ”  •   若num是无符号数当num为负数时相当于二进制补码对应的无符号数。比如num -1repeat(num) 相当于 repeat(7) 。  •   若num是带符号数当num为0或负数时这条语句将永远不会被执行。7. 块(block)块(block)是一些赋值语句的组合包括  •   顺序块begin-end块中语句按照给定的顺序执行因此块中的延迟、事件控制相当于起到了隔断的作用。顺序块的开始时间是第一条语句开始执行的时刻结束时间是最后一条语句执行完的时刻。  •   并行块fork-join块中语句同时执行即所有语句的开始时间相同。并行块的结束时间是所有语句都执行完的时刻。7.1 嵌套块通常要使用多个块的嵌套实现更复杂的控制逻辑因此最好要理解各个块的开始时间和结束时间。下面给出几个例子// Example1begin fork Aevent; Bevent; join areg breg;end由于fork-join的并行性A和B两个事件可以以任意的顺序出现fork-join块结束后执行赋值语句 areg breg。// Example2begin begin Aevent; Bevent; end areg breg;end如果换成begin-end事件的触发必须按照给定的顺序。如果B事件先出现再出现A那么内部嵌套的begin-end还要再等待B事件的发生。// Example3fork Aevent; begin #ta wa 0; #ta wa 1; end Bevent; begin #tb wb 1; #tb wb 0; endjoinfork-join中的两个顺序块的执行分别受到两个事件的控制。由于fork-join的并行性两个begin-end的触发和执行同样也是并行的。7.2 命名块每个块都可以在begin和fork后面为其附加名字称为命名块。其它语句可以通过这个名字来引用命名块最常见的是“命名块disable”的用法。disable语句可以终止命名块的运行一般用于处理异常情况比如下面的代码begin : block_name ... if (a 0) disable block_name; ...end当满足a 0时begin-end块会终止运行。disable会终止整个命名块的运行包括命名块中的其它所有块和已调用的任务。利用这个特性可以实现两个功能  •   中止一个循环语句(相当于C语言中的break)  •   跳过循环中的某些状态(相当于C语言中的continue)虽然Verilog没有直接提供类似于C语言中break和continue的关键词但可以使用“命名块disable”来实现此特性。看下面的示例代码reg [7:0] cnt 0;always (posedge clk) cnt cnt 1b1;reg [7:0] data;integer i;initial begin : break for (i 0; i 100; i i 1) begin : continue (posedge clk) if (cnt 5) disable break; data cnt; endendfor循环中当满足一定条件时 disable break; 会终止initial之后的begin-end块的执行整个循环也就终止了。如果改成 disable continue; 当满足条件时会终止for之后的begin-end块的执行这样只会终止当前的循环状态而不会影响循环的下一次迭代。原文链接https://bestfpga.blog.csdn.net/article/details/102784167‧‧‧‧‧‧‧‧‧‧‧‧‧‧‧‧  END  ‧‧‧‧‧‧‧‧‧‧‧‧‧‧‧‧
http://www.yutouwan.com/news/291081/

相关文章:

  • 网站的数据库怎么做当阳建设中学网站
  • 网站顶部轮播怎么做微信小商店和小程序商城的区别
  • 阜康市建设银行网站铜仁市网站建设
  • 网站设计两边为什么要留白吉林省白山市建设厅网站首页
  • 网站教学视频phpcms律师网站源码
  • 做的asp网站手机号码东莞互联网企业
  • 帮做试卷的网站建凡网站
  • 苏州响应式网站建设特效比漂亮的网站
  • 如何制作一个公司网站抖音代运营怎么解绑
  • 评析网站建设报价单wordpress下载主题错误
  • 江门阿里巴巴网站建设如何登录百度站长平台
  • 网站建设基本流程ppt基于php技术的小型企业网站开发
  • 自建网站的优缺点中国建设银行青岛网站
  • 网站模板制作工具wordpress如何关闭标签功能
  • 北京兼职网站建设网站的优化方法
  • 会员管理系统多少钱温州网站优化定制
  • 网站优化升级网页设计与制作项目
  • 网站默认极速模式电脑平面设计软件
  • 免费建站还用学做网站吗网站建设培训基地
  • 专业制作网站 地摊陕西省建设工程施工许可证查询网站
  • 织梦做双语网站wordpress提高浏览量
  • 免费crm网站下载的软件wordpress公共聊天室
  • 餐饮网站开发性能需求买外链
  • 商城网站建设高端产品网络推广的方法有哪些
  • 贵州省住房和城乡建设厅网站(广州网站优化排名
  • 扁平化高端网站模板长沙网站建设
  • 西安工程建设信息网站直播视频软件哪个好
  • 广州市民政局网站建设公众号开发难吗
  • 网站的作用wordpress 倡萌 相册
  • 小说网站开发环境那个号企业网站建设费用账务处理