网站建设推进计划庆阳市建设局海绵城市网站

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

网站建设推进计划,庆阳市建设局海绵城市网站,wordpress怎么调用api,类似中企动力的做网站的实例#xff1a;点灯学习 一、Verilog语法学习

  1. 参考文章 刚接触Verilog#xff0c;作为一个硬件小白#xff0c;只能尝试着去理解#xff0c;文章未完…持续更新。 参考博客文章#xff1a; Verilog语言入门学习#xff08;1#xff09;Verilog语法【Verilog】一文… 实例点灯学习 一、Verilog语法学习
  2. 参考文章 刚接触Verilog作为一个硬件小白只能尝试着去理解文章未完…持续更新。 参考博客文章 Verilog语言入门学习1Verilog语法【Verilog】一文带你了解Verilog基础语法 - 子墨祭的文章 - 知乎关于Verilog中的几种赋值语句 这里抄点那里扣点整理了一下感谢以上各位作者。具体的实例项目是同事给的他让我学着编出个流水灯这不要我的命嘛慢慢学吧。 你还可以在哪里看到这篇文章 知乎 2. Verilog模块 Verilog的基本设计单元是“模块”。一个模块是由两部分组成的一部分描述接口另一部分描述逻辑功能即定义输入是如何影响输出的。下面举例说明 可以看到模块由关键字module….endmodule 确定。 module 模块名(接口信号); ​ //信号声明 ​ //功能描述 endmodule 要求 1. 模块名具有意义2. 一个.v文件只有一个模块。
  3. Verilog语法 Verilog是一种硬件描述语言以文本形式来描述数字系统硬件的结构和行为的语言用它可以表示逻辑电路图、逻辑表达式还可以表示数字逻辑系统所完成的逻辑功能。 Verilog和C的区别 Verilog是硬件描述语言编译下载到FPGA之后会生成电路所以Verilog全部是并行处理与运行的C语言是软件语言编译下载到单片机CPU之后还是软件指令而不会根据代码生成相应的硬件电路而单片机CPU处理软件指令需要取址、译码、执行是串行执行的。 可综合描述综合tool能够Verilog描述转化complie成基本的数字电路底层cell与或非gate寄存器等的描述。 assign y a b 不可综合描述综合tool不能把Verilog描述转换为基本的数字电路底层cell的描述。 $display(hello word.\n) Verilog设计仿真与实现通过EDA TOOL可以在计算机上对Verilog设计的功能进行仿真。 数字电路设计方法学 Bottom-Up从底层cell开始逐渐往上加功能top-Down从底层结构协议算法开始向下逐步划分功能模块再细分各功能模块与IO。 目前基于Verilog的数字电路通常使用TOP-Down的设计方法。因为数字IP/IC的规模很大需要先抽象思维再细化 Verilog给数字电路的设计的抽象思维提供了一种设计语言但是数字设计和软件设计不同的需要Think in Hardware写代码前先设计电路结构。Verilog的功能描述 Top-Dowan描述数字电路功能通过模块module的层次化设计实现一个复杂的数字逻辑功能 Verilog逻辑值 逻辑电路中有四种值即四种状态 逻辑0表示低电平对应电路的GND逻辑1表示高电平对应电路的VCC逻辑X表示未知有可能是高电平也有可能是低电平逻辑Z表示高组态外部没有激励信号是一个悬空状态 Verilog的数字进制 Verilog数字进制格式包括二进制、八进制、十进制和十六进制一般常用的为二进制、十进制和十六进制。 二进制表示如下4b0101表示4位二进制数字0101十进制表示如下4d2表示4位十进制数字2十六进制表示如下4ha表示4位十六进制数字a 当没有指定数字的位宽与进制时默认为32位的十进制比如100实际上表示的值为32d100 4. Verilog语法详细介绍 1标识符 用于定义code中的各种名字比如信号moduledefineparameter 标识符由字符数字下划线组成首字母必须是字母或者下划线标识符是区分大小写的信号名字与信号功能相对应 不建议大小写混合使用普通内部信号建议全部小写参数定义建议大写 用有意义的有效的名字如sum、cpu_addr等用下划线区分词语组合如cpu_addr采用一些前缀或后缀 比如时钟采用clk前缀clk_50m,clk_cpu;低电平采用_n后缀enable_n 统一缩写如全局复位信号rst同一信号在不同层次保持一致如同一时钟信号必须在各模块保持一致。自定义的标识符不能与保留字关键字同名参数统一采用大写如定义参数使用SIZE 2关键字 优先记录常用关键字 关键字含义module模块开始定义input输入端口定义output输出端口定义inout双向端口定义parameter信号的参数定义wirewire信号定义regreg信号定义always产生reg信号语句的关键字assign产生wire信号语句的关键字begin语句的起始标志end语句的结束标志posedge、negedge时序电路的标志caseCase语句起始标记defaultCase语句的默认分支标志endcaseCase语句结束标志ifif/else语句标志elseif/else语句标记forfor语句标记endmodule模块结束定义 3注释 注释一行以//开始到行末 注释多行以/开始到/为止的所有内容
    4数据类型 主要有三大类数据类型 寄存器类型线网类型参数类型 线性数据用于连续赋值语句assign描述组合逻辑或者module间的信号连接线 1 寄存器类型 寄存器类型表示一个抽象的数据存储单元它只能在always语句和initial语句中被赋值并且它的值从一个赋值到另一个赋值过程中被保存下来。 如果语句描述的是时序逻辑即always语句带有时钟信号则该寄存器变量对应为寄存器如果该过程语句描述的是组合逻辑即always语句不带有时钟信号则该寄存器变量对应为硬件连线 寄存器类型的缺省值是x未知状态。 寄存器数据类型有很多种如reg、integer、real等其中最常用的就是reg类型 reg [31:0] delay_cnt; // 延时计数器 reg key_flag; // 按键标志wire [3:0] din; reg [3:0] d0; //4bit reg d1;//1bit initial begin //过程赋值语句d1 0;#10;d1 1; end always(posedge clk)begin //clk端一般就是寄存器if(d1) d0 din; end2线网类型 线网表示Verilog结构化元件间的物理连线。 值由驱动元件的值决定例如连续赋值或门的输出。 如果没有驱动元件连接到线网线网的缺省值为z高阻态。 线网类型如tri和wire等其中最常用的就是wire类型它的使用方法如下 wire data_en; //数据使能信号 wire [7:0] data;//数据wire a//1bit位宽 wire [3:0] b; //4bit wire [7:0] c;//8bit assign a 1b0;//连续赋值语句 assign c 8h5a;//8bit的十六进制数 //tri0、tri1带下拉、上拉电阻的特性没有驱动时会由默认的值为0/1一般综合代码不用 tri0 s0 tri1 [20:0] s1;3参数类型 参数其实就是一个常量常被用于定义状态机的状态、数据位宽和延迟大小等 可以在编译时修改参数的值因此又常被用于一些参数可调的模块中使用户在实例化模块时可以根据需要配置参数。 在定义参数时可以一次定义多个参数参数与参数之间需要用逗号隔开。 要注意的是参数的定义是局部的只在当前模块中有效。 parameter DATA_WIDTH 8;//数据位宽为85Verilog运算符 1算术运算符 - * / %Verilog实现乘除比较浪费组合逻辑资源尤其是除法。一般2的指数次幂的乘除法使用移位运算来完成运算. 非2的指数次幂的乘除法一般是调用现成的IPQUARTUS/ISE等工具软件会有提供不过这些工具软件提供的IP也是由最底层的组合逻辑(与或非门等)搭建而成的。 2关系运算符 !用来进行条件判断在进行关系运算符时如果声明的关系是假的则返回值是0如果声明的关系是真的则返回值是1 所有的关系运算符有着相同的优先级别关系运算符的优先级别低于算术运算符的优先级别。 3逻辑运算符 !||连接多个关系表达式可实现更加复杂的判断一般不单独使用都需要配合具体语句来实现完整意思。 4条件运算符 ? :从两个输入中选择一个作为输出的条件选择结构功能等同于always中的if-else语句。 5位运算符 ~| ^直接对应数字逻辑中的与、或、非门等逻辑门 位运算符一般用在信号赋值上。 6移位运算符 移位运算符包括左移位运算符和右移位运算符这两种移位运算符都用0来填补移出的空位。 一般使用左移位运算代替乘法右移位运算代替除法但是只能表示2的指数次幂的乘除法。 7拼接运算符 {a,b}可以把两个或多个信号的某些位拼接起来进行运算操作 5. 阻塞赋值Blocking和非阻塞赋值Non-Blocking 1阻塞赋值 在一个always块中后面的语句会受到前语句的影响具体来说在同一个always中一条阻塞赋值语句如果没有执行结束那么该语句后面的语句就不能被执行即被“阻塞”。 也就是说always块内的语句是一种顺序关系 符号“”用于阻塞的赋值如ba,阻塞赋值“”在begin和end之间的语句是顺序执行属于串行语句。其后面的赋值语句从概念上来讲是在前面一条语句赋值完成之后才执行的。 2非阻塞赋值 符号用于非阻塞赋值如ba;非阻塞赋值是由时钟节拍决定在时钟上升到来时执行赋值语句右边然后将begin-end之间的所有赋值语句同时赋值到赋值语句的左边。 begin-end之间的所有语句一起执行且是个时钟只执行一次属于并行执行语句。 非阻塞赋值的操作过程可以看作两个步骤 赋值开始的时候计算RHS等号右边的表达式赋值结束的时候更新LHS等号左边的表达式。 非阻塞的概念是指在计算非阻塞赋值的RHS以及LHS期间允许其他的非阻塞赋值语句同时计算RHS和更新LHS。
  4. assign和always的区别 assign语句使用时不能带时钟always语句可以带时钟也可以不带时钟在always不带时钟是逻辑功能和assign完全一致都是只产生组合逻辑。比较简单的组合逻辑推荐使用assign语句比较复杂的组合逻辑推荐使用always语句。 1带时钟和不带时钟的always always语句可以带时钟也可以不带时钟。 在always不带时钟时逻辑功能和assign完全一致虽然产生的信号定义为reg类型但是该语句产生的还是组合逻辑在always带时钟信号时这个逻辑语句才能产生真正的寄存器。 2latch latch指锁存器是一种对脉冲点平敏感的存储单元电路 锁存器和寄存器都是基本存储单元锁存器是电平触发的存储器寄存器是边沿触发的存储器。 两者的基本功能是一样的都可以存储数据。 锁存器是组合逻辑产生的而寄存器是在时序电路中使用由时钟触发产生的。 latch的主要危害是产生毛刺glitch这种毛刺对一级电路是很危险的。并且其隐蔽性很强不易查出。 在设计中应尽量避免latch的使用。 代码里出现latch的两个原因是在组合逻辑中if或者case语句不完整的描述比如if缺少else分支case缺少default分支导致代码在综合过程中出现了latch。解决办法就是if必须带else分支case必须带default分支。 只有不带时钟的always语句if语句或者case语句不完整才会产生latch带时钟的语句if或者case语句不完整描述不会产生latch。
  5. 状态机 Verilog是硬件描述语言硬件电路是并行执行的当需要按照流程或者步骤来完成某个功能是代码中通常会使用很多个if嵌套语句来实现这样就增加了代码的复杂度以及降低了代码的可读性这个时候就可以使用状态机来编写代码。 状态机相当于一个控制器它将一项功能的完成分解为若干步每一步对应二进制的一个状态通过预先设计的顺序在各状态之间进行转换状态转换的过程就是实现逻辑功能的过程。 状态机全程是有限状态机Finite State Machine缩写为FSM,是一种在有限状态之间按一定规律转换的时序电路可以认为是组合逻辑和时序逻辑的一种组合。状态机通过控制各个状态的跳转来控制流程使得整个代码看上去更加清晰易懂在控制复杂流程的时候状态机优势明显因此基本上都会用到状态机如SDRAM控制器等。 根据状态机的输出是否与输入条件相关可将状态机分为两大类即摩尔Moore状态机和米勒Mealy型状态机 Mealy状态机组合逻辑的输出不仅取决于当前状态还取决于输入状态 Moore状态机组合逻辑的输出只取决于当前状态 1三段式状态机 根据状态机的实际写法状态机还可以分为一段式、和二段式和三段式状态机。 一段式整个状态机写到一个always模块里面在该模块中即描述状态转移又描述状态的输入和输出。 不推荐一般都会要求把组合逻辑和时序逻辑分开组合逻辑和时序逻辑混合在一起不利于代码维护和修改 二段式用两个always模块来描述状态机其中一个always模块采用同步时序描述状态转移另一个模块采用组合逻辑判断状态转移条件描述状态转移规律以及输出需要定义两个状态现态和次态然后通过现态和次态的转换来实现时序逻辑。三段式在两个always模块描述方法基础上使用三个always模块一个always模块采用同步时序描述状态转移一个always采用组合逻辑判断状态转移条件描述状态转移规律另一个always模块描述状态输出可以用组合电路输出也可以时序电路输出。 三段式状态机的基本格式是 第一个always语句实现同步状态跳转第二个always语句采用组合逻辑判断状态转移条件第三个always语句描述状态输出可以用组合电路输出也可以时序电路输出。
  6. 模块化设计 划分模块的基本原则是子模块功能相对独立、模块内部联系尽量紧密、模块间的连接尽量简单。 在进行模块化设计中对于复杂的数字系统我们一般采用自顶向下的设计方式。可以把系统划分成几个功能模块每个功能模块再划分成下一层的子模块每个模块的设计对应一个module一个module设计成一个Verilog程序文件。因此对一个系统的顶层模块我们采用结构化的设计即顶层模块分别调用了各个功能模块。 FPGA逻辑设计中通常是一个大的模块中包含了一个或多个功能子模块Verilog通过模块调用或称为模块实例化的方式来实现这些子模块与高层模块的连接有利于简化每一个模块的代码易于维护和修改。 如果子模块内部使用parameter定义了一些参数Verilog也支持对参数的例化也叫参数的传递)即顶层模块可以通过例化参数来修改子模块内定义的参数。 子模块名是指被例化模块的模块名而例化模块名相当于标识当例化多个相同模块时可以通过例化名来识别哪一个例化一般命名为“u_”“子模块名” 参数的例化参数的例化是在模块例化的基础上增加了对参数的信号定义 // 例子 time_count #(.MAX_NUM (TIME_SHOW) // 参数例化 )u_time_count(.clk (sys_clk),.rst_n (sys_rst_n), // 信号例化.flag (add_flag) );9. Verilog的编程规范 工程的组织形式一般包括如下几个部分分别是doc、par、rtl和sim四个部分 doc一般存放工程相关的文档包括该项目用到的datasheet数据手册、设计方案等。par主要存放工程文件和使用到的一些IP文件rtl主要存放工程的rtl代码是工程的核心文件名与module名称应当一致建议按照模块的层次分开存放sim主要存放工程的仿真代码复杂的工程里面仿真也是不可或缺的部分可以极大减少调试的工作量。 1文件头声明 每一个Verilog文件的开头都必须有一段声明的文字。包含文件的版权、作者、创建日期以及内容简介等等 //**********************************Copyright©*************// // FileName: // Last modified Date: // Last Version: // Descriptions: //****************************************************************//2输入输出定义 module led(input sys_clk, // 系统时钟input sys_rst_n , // 系统复位output reg [3:0] led // 4位LED灯 );一行只定义一个信号信号全部对齐同一组的信号放在一起 3parameter定义 module中的parameter声明不建议随处乱放,将parameter定义放在紧跟着module的输入输出定义之后parameter等常量命名全部使用大写 4wire/reg定义 一个module中的wire/reg变量声明需要集中放在一起不建议随处乱放 将reg与wire的定义放在紧跟着parameter之后建议具有相同功能的信号集中放在一起信号需要对齐reg和位宽需要空2格位宽和信号名字至少空四格位宽使用降序描述[6:0]时钟使用前缀clk复位使用后缀rst一行只定义一个信号 5信号命名 内部信号不要使用大写也不要使用大小写混合建议全部使用小写模块名字使用小写异步信号使用_a作为信号后缀 6always块 一个always需要配一个begin和endalways前面需要有注释一个always和下一个always空一行即可不要空多行时序逻辑使用非阻塞赋值 7assign块 assign的逻辑不能太复杂否则易读性不好assign前面需要有注释组合逻辑使用阻塞赋值 8空格 和 TAB 由于不同的解释器对于TAB翻译不一致所以建议不使用TAB全部使用空格 二、环境Lattice Dimond环境的搭建 从Lattice的官网下载Dimond下一步下一步安装 获取电脑的MAC地址注意是有线网卡的MAC地址不能是无线的 在官网申请免费的证书这里有问题官网不会跳出来所以是请同事帮忙生成的 打开软件添加证书文件即可。 Lattice官网链接 证书申请网址
    有的会跳出来什么联系管理员我这里是把IP改为马来西亚打开网址的 填写物理网卡MAC地址质料 新建工程项目 选择芯片我的板子上的芯片是 生成项目文件夹 添加Verilog文件 这样就可以编写Verilog代码了。 三、点灯实例分析 同事给出的一段实例能够点亮两个灯 实例环境硬件如下 电脑可调电源 module clk_div ( in_clk, clk_8hz, clk_1hz, pg_rstn );input in_clk; output clk_8hz; output clk_1hz; input pg_rstn; reg [4:0] count0_r; reg [8:0] count1_r; reg [9:0] count2_r;reg div0_clk; reg div1_clk; reg div2_clk;wire clk_1hz; wire clk_8hz;assign clk_1hz count2_r[9]; assign clk_8hz count2_r[6];always (posedge in_clk or negedge pg_rstn) //25M–1M beginif (!pg_rstn)begindiv0_clk 1b1;count0_r 5b0; endelse if (count0_r5b11001)begindiv0_clk1b1; count0_r5b0;end elsebegincount0_rcount0_r1b1;div0_clk 1b0; end endalways (posedge div0_clk or negedge pg_rstn) //1M–1k beginif (!pg_rstn)begincount1_r 9b0;div1_clk 1b0;endelse if (count1_r9h1ff)begindiv1_clk~div1_clk; count1_r9h0;endelsecount1_rcount1_r1b1; endalways (posedge div1_clk or negedge pg_rstn) //1k–1Hz beginif (!pg_rstn)begincount2_r 10b0;endelse if (count2_r10h3ff)begin count2_r 10b0; endelsebegincount2_r count2_r1b1;end endOSCH #(10.23) osc_int (.STDBY(1b0),.OSC(clk_i),.SEDSTDBY());endmodule1. 实例代码分析 module clk_div ( in_clk, clk_8hz, clk_1hz, pg_rstn ); input in_clk; output clk_8hz; output clk_1hz; input pg_rstn;
    …. endmodule这一段是接口定义定义了两个输出信号clk_8hz、clk_1hz,代表两个灯不同的频率。两个输入信号in_clk、pg_rstn指芯片的时钟和复位。 模块由关键字module….endmodule 确定。 clk_div模块名 reg [4:0] count0_r;//5bit reg [8:0] count1_r;//9bit reg [9:0] count2_r;//10bitreg定义寄存器寄存器数据类型有很多种如reg、integer、real等其中最常用的就是reg类型。 reg div0_clk; reg div1_clk; reg div2_clk;默认位宽是1。 wire clk_1hz; wire clk_8hz;wire定义的是线网线网指的是Verilog结构化元件间的物理连线 assign clk_1hz count2_r[9]; assign clk_8hz count2_r[6];assign产生wire信号语句的关键字,连续赋值语句assign 比较简单的组合逻辑推荐使用assign语句比较复杂的组合逻辑推荐使用always语句。 reg与wire的区别详细
    always (posedge in_clk or negedge pg_rstn) //25M–1M beginif (!pg_rstn)begindiv0_clk 1b1;//一位二进制数1count0_r 5b0;//五位二进制数0endelse if (count0_r5b11001)//五位二进制数11001begindiv0_clk1b1;count0_r5b0;end 时序逻辑 带异步复位 ; posedge是上升沿电平从低到高跳变 negedge是下降沿电平从高到低跳变 参考文章 文章持续更新由于刚接触所以很多东西也分析不错来之后慢慢补充。 2. 编译运行 编译代码 生成JED文件 引脚设置 找到项目中的.jed文件 设备上电插上烧录器插上电脑。点击烧录 等待 完成 四、总结 这东西对于像我这样跨专业的初学者来说真难慢慢学吧之后会找有关书或者视频更新Verilog语言的基础学习笔记。