下载本文档
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
1、第四章、 Verilog HDL设计技巧本章通过一些简单的实例演示一下如何在verilog hdl中实现看似不可能实现的技巧,主要包括1双向端口的使用2.PWM波形的产生3常见几种分频器的设计4巧用存储器定义语句实现存储器设计5基于存储器的DDS设计6有限状态机本章讲述一些常用的 verilog设计方法和技巧,可以加速实际的工程应用,提高效率。双向端口双向端口在应用过程中常常用到,如在进行和存储器的接口设计时。由于存储器的数据线是双向信号,故FPGA的端口也必须用双向端口才能够连接。Verilog HDL中的双向端口关键字为 in out,女口 in out dat,则表示dat为一个双向(既
2、可以输 入也可以输出)的端口。在硬件中为了更好的处理端口,大多数情况下都是使用单向端口,即in put或者output。这样更容易对电路的逻辑进行描述。双向端口也往往转换成两个单向的端口进行操作。仔细分析一下,当一个端口作为双向端口时,实际上是分时的输入和输出,也就是说,当内部逻辑 需要双向端口作为输入时,这时候是用双向的输入功能,反之,用输出功能。假设”内部需要”为一个变量,暂且命名为 dir,则,双向端口转化为两个单向端口的电路就可以如下图所 示。图中,实线框是整个的逻辑设计电路模块,io为此模块的双向端口。 虚线框为将双向端口转化为两个单向端口的子模块,两个三角形的电路为三态门,上面的三
3、态门低电平使能,下面的三态门高电平使能。当需要将io端作为输入时候,即 dir为高(假设为高电平时使用io端的输入功能),上面的三态门被关闭,下面的三态门打开,于是信号的流向从io 口经过下面的三态门由a端输出,那么这个时候其他逻辑部分就可以使用a端的信号进行运算处理;反之,当内部的其他逻辑需要输出信号至io双向端口时,可以置dir为低电平,上面的三态门被打开,下面的三态门被关闭,这样b端口的信号经由上面的三态门输出至io端。这样,虚线框中的子模块就完成了双向端口转化为两个独立的单向端口(a和b)的功能。代码如下:代码注释:声明io端口为双向端口,一般情况下双向端口的类型声明为wire型,这里
4、省略,默认为wire 型。(2)当dir为高电平时,io端口赋值给a端口,否则,a端为高阻态,也可以写成assign a =(dir)?io:1 bz;。当dir为低电平时,b端口赋值给io端口,否则,io端赋值成高阻态,也可以写成assignio =(!dir) ? b:1 z;。上面电路中用到了三态门,通常来说,三态门在fpga和cpld内部不推荐使用,而且一般仅限于fpga或者是cpld的引脚端才有,内部没有三态门。如果在设计过程中大量采用三态门 的话,会使芯片的功耗大幅增加,资源浪费严重。仔细研究发现,可以在这里省略一个三态门。新电路如下:因为io的双向特性是分时使用的,所以在内部其他
5、逻辑使用a端和b端的时候也是分时使用的,换句话说,当内其他逻辑部向b写的时候,无论a端是什么值对内部的其他电路时没 有影响的,因为这个时候内部其他的逻辑不读取a端口;反过来,当内部需要读取a端的值的时候,a端的值必须来自于io端的值,故必须把 b端和io端断开,即三态门呈现 3态即 可。新的代码如下:module bidir2(io, a, b );in out io;output a;in put b;assig n a = io;/assign io = ( dir = 0 ) ? b:1 bz;en dmodule代码注释:(1)直接赋值即可。PWM波形的产生脉冲宽度调制(PWM),是英
6、文“ Pulse Width Modulation的缩写,简称脉宽调制,是利用 微处理器的数字输出来对模拟电路进行控制的一种非常有效的技术,广泛应用在从测量、信到功率控制与变换的许多领域中。PWM波形本质上是宽度可以变化的脉冲。见下图图中,从A到C为一个脉冲的周期,AB之间电平为高电平,称作这个脉冲周期的宽度, PWM是指AB之间的高电平宽度可以调节。若想用数字电路来实现 pwm,不妨借鉴一下模拟电路中的pwm是如和生成的。9先产生锯齿波,然后利用锯齿波的电压和另一个门限电压做比较,当门限电压变化的时候, 比较器输出的脉冲宽度就变化了。示意图如下:ab由上图比较得知,当门限电平电压升高时, 比
7、较器的输出的占空比宽度在减少, 即达到了脉 冲宽度调制的目的。那么,在数字领域里,门限电平可以由一个任意的常量或者用端口输入来实现, 怎么样去实 现锯齿波呢?仔细研究锯齿波,电压随着时间按照一定的比例上升(也就是增加) ,有点类 似计数器的味道。而实际上,如果将计数器的输出的数字量进行 DA转换的话,看到的输出就是锯齿波。这里以8位的计数器和门限宽度为例,设计一个宽度可调的脉冲输出。module pwm(thres, elk, pwm );in put elk;output pwm;in put 7:0 thres;reg 7:0 cntr; /(1)always(posedge elk) /
8、(2)cntr = thres)?1:0; /(3)en dmodule代码注释:(1) 设置计数用的变量,位宽为8位。和门限宽度一样。(2) 计数器计数,相当于模拟波形中的锯齿波(3) 比较器电路,当锯齿波值大于或等于门限时,pwm输出高电平,否则,输出低电平。可想,当门限输入的值发生变化时,pwm输出的脉冲宽度一定随着变化。使用Quartus II仿真如下图:thres为240时候,pwm的输出脉冲宽度很窄。实现了pwm输出脉冲宽度受thres门限值的调制。PWM在很多场合有重要的应用,例如,直流电机驱动,步进电机驱动、呼吸灯等。分频器计数器和分频器是 Verilog HDL设计中最基础的
9、时序电路的组成部分。分频器指的是一个系统能够将输入的系统时钟信号转变成较低频率信号的输出。例如:4分频电路就是指输出的时钟频率是输入时钟频率的四分之一。那么,如何实现呢?仔细分析输出和输入的关系就可以得到答案。先看下图:输入波形输出波形f;!a?F*012$3孑0:1;23;10 i 1 !H_hLKK_rLrLHK_hu1I1I+fT_bdt911:t3丨 11111-1a194I-4I:!:!:i-aIa;I:E:tiF-$这里有2个方波,上面的波形每个周期被虚竖线隔开,可以看出下面波形的周期为上面的 波形的4倍。如果说上面的波形为输入的时钟信号,下面的波形为分频器输出的信号,那 么说这个
10、输出就是输入的 4分频。仔细研究上图,可以看出,如果要输出4分频信号的话,可以对输入的信号进行模4计数(即03),当计数值为0和1时,将输出信号的电平置为低电平;当计数值为2和3的时候将输出信号的电平置为高电平。由于计数是模4的,所以计数值就会在 03之间不停的计数,而输出信号也会不停的输出低电平、高电平、低电平,这样4分频的输出信号就实现了!module freqdiv4(clki,clko); in put clki;output clko;reg1:0 cntr; always(posedge clki) if(cntr = 3)cntr = 0;elsecntr =c ntr + 1b
11、1;assig n clko=(c ntr=1)?0:1;en dmodule为了能更加清楚地了解Verilog语言的特点,请把上面代码作如下修改,然后体会一下assign和always的区别。module freqdiv4(clki,clko);in put clki;output reg clko; /将输出设计成 reg 型reg1:0 cntr;always(posedge clki)beginif(c ntr = 3) cntr = 0;elsecntr =c ntr + 1b1;if (cntr=1) 在这个always中直接判断计数值,然后给出clko的电平值clko = 0;e
12、lseclko = 1;enden dmodule在刚才的4分频中,输出信号时方波,如果说输出信号不是方波的话,但只要频率是输入的1/4,就称之为4分频。如下图,波形 2和波形3都是输入信号的4分频。module freqdiv4(clki,clko);in put clki;output clko;reg1:0 cntr;always(posedge clki) if(cntr = 3)cntr = 0;elsecntr =c ntr + 1b1;assig n clko=(c ntr=O)?O:1;只需要修改这里en dmodule同理也可以完成占空比为 25%的4分频输出,代码请读者自己
13、完成。2分频2分频和4分频一样,首先要构建一个模 2计数器,当计数器值为 0时,输出低电平;当计 数器值为1时,输出高电平。这样计数器每计2个数就可以得到一个周期的输出,故是2分频。2分频的另外一种思想:如果说输入信号每个信号上升沿到来的时候,都将输出端进行电平翻转一下(原来是低电平,现在变高电平;原来是高电平,现在变成低电平。)这样,输出端若要得到一个周期就需要翻转 2次,也就是2个输入时钟的上升沿, 也就是输入2个周期 得到一个周期,也即:2分频。代码如下:module freqdiv2(clki,clko);in put clki;output reg clko;always(posed
14、ge clki)clko = !clko;en dmodule通过波形仿真可以验证2分频的正确性。这种二分频的方式用的比较频繁,也推荐大家在以后的应用中使用。 接下来进行三分频的学习。根据前面的学习,可以得出,三分频可能有2中波形输出,见下图:波形1波形2在上面的波形中,2中输出的占空比分别是 33%和67%,没有50%的占空比输出波形了。如波形3为50%的方波,看图中虚线处,方波输出在输入时钟的下降沿和上升沿均有变化。所以,这里要想到,如果使用下降沿做分频,效果如何呢?为了便于比较,下图以33%占空比为例,分别用下降沿和上升沿进行分频。图中,点虚线为一个周期,这个周期输出下降沿的分频信号,线
15、虚线为上升沿分频的一个周期。大家会发现,两个输出“错位” 了半个输入时钟周期,按照50%的计算,输出脉冲宽度为1.5个输入时钟周期,如果说将两个33%的分频输出信号相“或”的话,输出不就是50%占空比了嘛!3分频50%输出占空比的代码如下:module freqdiv3(i nput clki,output clko);reg 1:0 cn t1;/(1)always(posedge clki)beginif(cn t1 = 2) cnt1 = 0;elsecn t1=c nt1+1;endreg o1/*sy nthesis keep */; /(2)always(*)/(3)if(cnt1
16、=0) o1 = 1;else o1 = 0;reg 1:0 cn t2;/(4)always (n egedge clki)beginif(c nt2 = 2) cnt2 =0;elsecn t2 = cn t2 + 1;endreg o2/*s yn thesis keep */;always(*)if(cnt2=0) o2 = 1;/(5)else o2 0) o1 = O;else o1 = 1;或者 always(*) if(cnt1=1)|(cnt1=2) o1 = 0; else o1 = 1;从逻辑角度上讲,只要有 1个时钟周期的高电平输出即可。(4) cnt2为下降沿分频用的
17、计数器值。不同的计数器要用不同的变量计数,因为在硬件描述语言中,变量对应着硬件,一个硬件只能有一个固定功能(逻辑上分时处理的除外)。(5) 同(3),可以有多种写法,读者可以进行尝试验证。刚才使用了 33%的占空比输出信号相或得到了50%的占空比输出,同理,使用67%的上升沿分频和下降沿分频也可以得到50%的输出,原理见下图:下降沿分频 上升沿分频使用两个输出信号的相“与”操作,可以得到50%的占空比输出。代码请读者自行完成。以上使用的是 3分频输出50%的占空比输出,其实,同样的原理适用于所有的奇数分频。因为奇数分频若想得到 50%的占空比输出,则必然有半个周期的宽度脉冲出现(例如,5分频,
18、50%占空比,则脉冲宽度为2.5个时钟周期),而上升沿和下降沿恰好就是半个周期的差别,因此,无论任何奇数,只要用此方法均可得到50%分频输出。只是要注意,上升沿计数和下降沿计数要同一个时钟周期开始,这可以通过设计一个异步的复位端来实现,读 者需细心揣摩。半整数分频所谓半整数分频指的是 N.5分频,N为整数。比如2.5分频。如果输入频率为 50Hz,则 输出为20Hz。在前面的整数分频中, 都是以上升(或下降)沿作为计数的,所以每计数一个则为一个周期, 不会出现.5的效果。这里采用反推导方式来进行。假设已经得到了分频后的结果。2.5分频的输出分频后的周期根据刚才的推导,直接使用输入时钟去计数不可
19、能得到半整数的分频效果。所以必须使用另外的时钟来计数。图中,由于没有明确指出分频后的占空比,图中仅给出半个周期的脉冲宽度,不过周期是固定的,就是2.5个输入时钟。为了明确分频后的周期,图中以分频后输出信号的2分频给出波形的。这里大胆进行一下尝试,如果说,用输出信号的2分频和输入时钟做“异或”操作,然后再用异或后的时钟作为分频时钟参与动作,会是什么样的结果呢?先给出“异或”后的波形。2.5分频的输出分频后的周期2个周期连接处发生了最后面一行是异或后的时钟信号。可以看出时钟的周期在分频后的 变化。这里用它,代替原输入时钟进行计数和分频尝试。module freqdiv2dot5(i nput cl
20、ki,output reg clko);reg clkodiv2;always(posedge clko)clkodiv2=!clkodiv2;wire n ewclk;assig n n ewclk= clkiAclkodiv2;reg 1:0 cn tr;always(posedge n ewclk) /(1)beginif(cntr = 2) cntr = 0; /(2)elsecn tr=c ntr+1;endalways(*)if(cntr=0) clko = 1;/(3)else clko = 0;en dmodule代码说明:(1) 这儿使用新的时钟信号作为计数时钟。(2) 因v
21、erilog不支持小数2.5,采用整数3作为计数的模,经验证可以发现,如果写成整数2,则进行的是1.5分频。这里可以修改 2.5 分频输出脉冲的宽度,如果改为if(cntr=1),贝U输出占空比为1.5/2.5。可以通过实践验证。仿真波形如下:通过查看计数器的技术过程,可以看出,在计数器的值由2变到0的时候,实际的newclk是没有脉冲上升沿的。因为这里采用了一个相互关联的连带性输出导致了该结果,可以看出,newclk 间接地产生了 clko ,而clko 又间接地影响了 newclk 的生成。此处无法直接推 导出。有的文献上把这种方式称作脉冲扣除电路,它有一套成型的公式,根据这个公式,任何半
22、整数分频都可以很容易设计出来。N.5分频电路构成。另一种形式的半整数分频思想:如果说能够在一个时钟周期内计数2个的话,半整数分频就可以转化成整数分频了。例如2.5分频,在2.5个周期内能计5个数,则,可以在计数1个的时候输出高电平,其余值时输出低电平。那么,怎么样才能在1个周期内计2个数呢?有的人立刻想至打always ( posedge elk, negedge elk) cntr=cntr + 1;这种方式,这是错误的。因为硬件描述语言是对硬件的描述,硬件上不存在的逻辑(即现实的触发器都只有1个输入时钟),即使语句语法没有错误,也是不能生成硬件的。这里给出 Quartus II对这种方式提
23、出的错误报告,供大家参考。Error (10239):VerilogHDL Always Co nstructerror atfreqdiv2dot5.v(23): event con trol cannot test for both positive and n egative edges of variable clk。那么怎样才能实现上升下降沿同时计数呢?试着想一下,当上升沿计数后,紧接着下降沿到来,那么下降沿计数必须是在上升沿计数值的基础上进行加1操作,同理,再出现上升沿又必须在之前的下降沿计数基础上进行+1 ;或者换种说法,不管哪个沿计数,都必须在最终计数器的值上进行加1计数。于是
24、,这里需要设计多个计数器,上升沿计数器posecntr ,下降沿计数器negcntr,和最终的计数器的值cntr。以模5计数为例,这三者之间的关系是这样的,cntr 在正常计数过程中应该是posecntr和negcntr中的最大值(谁大取谁);当计数值到达模值时候,再计数(无论是上升沿还是下降沿)应为0 (假设做的是加计数,减计数另论),而不是谁大就取谁了。然后在 0的基础上继续计数。双沿计数器的代码如下:module dot5_2(clki,cntr);in put clki;reg 2:0 posc ntr;reg 2:0 n egc ntr;always(posedge clki)if(
25、cn tr=4)begi n posc ntr = 0;e ndelsebegi n posc ntr = cntr + 1;e ndalways (n egedge clki)if(cn tr=4)begi n n egc ntr = 0;e ndelsebegi n n egc ntr = n egc ntr)?posc ntr: n egc ntr;en dmodule仿真波形如下:JclkiA ihlhl L_rL_rT_rT_rT_r尋1+j cntrU I可以看出,每个时钟的上升沿或者是下降沿cntr都进行了加1动作,是真正的双边沿计数器。在上面代码上稍加修改,就得到了半整数分频的
26、实现了。module dot5_2(clki,clko);/(1)in put clki;output reg clko;wire 2:0 cntr /*syn thesis keep*/; /(2)/always*/(4)if(cntr = 0)&(cntr =1) clko = 1;else clko 0dkLJl iTTTT.-LT-LT-LT-LT-L-L_T-L_r-L_T-L_TTEJ cntrV iidkcX_r_r l _r l _r l _r l田 negcntrU ii10F*1 pQ5CIltr可以看出输出信号clko的周期为2.5个输入时钟周期。小数分频:所谓小数分频,
27、就是输出频率和输入频率的比是小数,由于Verilog HDL的特点,这种情况下输出肯定不是均匀的,只是从统计学角度上平均是小数。例如:3.1分频,也就是说,假设输入了 3.1个脉冲个数,得到一个输出时钟周期。很显然,这种方法是不可能均 匀的,因为Verilog中所有的分频动作都是在上升沿或者是下降沿的时候进行的。只能从统计学角度考虑,则输入了31个脉冲的话,输出端得到10个脉冲,也就是,先做 2个10分频,再做一个11分频就可以了。这里可以套用这个公式,假设要做M.N小数分频,可以做M分频和M+1分频的组合。假设需要做 m个M分频,n个M+1分频,则:m +n = 10;m*(M) + n*(
28、M +1)=M *10 + N;以3.1分频为例:m +n = 10;m* (3) + 门气4) = 3*10+1;得出m=9, n=1 ,也就是做9次3分频,1次4分频。需要说明的是,这9次3分频和1次4分频是分时工作的, 也就是所,在进行3分频期间, 4分频模块不要工作,反之亦然。对于这类问题,最好的办法就是在一个always 中进行,因为多个 always 之间是并行执行的,相互控制必然带来不必要的硬件动作和资源浪费。由于是3分频和4分频是分时工作,可以采用一个计数器,另外,一共需要做10次分频,这个次数也需要存下来,这就是第二个计数器。分别命名为cnt4和cnt10 吧。详细内容见代码
29、:代码说明:(1)前面9次的3分频时间内做三分频,控制3分频的个数为9个(08)(2) 每个分频模块中都要分频输出,三分频最后输出高电平,也可以计数值为0时刻输出高电平,其余时刻输出低电平,这个地方和以前分频方式相同。(3) 每次分频之后要对分频的总个数进行加1,否则会一直停留在三分频里,4分频模块就不会工作了。 当三分频结束时,进入4分频模块。如果需要做多次的4分频,也要写成 cnt=?&cnt=?的形式。这里只需要做一次,故可以省略写。(5) 和三分频一样,公用cnt4,因为是分时工作。(6) 这里写成了通用形式,和 (4)原理一样。可以直接写成cnt10 =0;因为就做一次 4分频。仿真
30、波形如下:从波形的输出上看, 在cnt10 计数值9之前都是3分频,输出较密一些。当cnt10变为9 时候就是一个4分频的输出,稍稀疏些。在这种方式的分频, 可以推广到所有的有理小数方法,最好是化简成最简分数形式,节约硬件寄存器资源。如果是无理小数呢?比如 10/3,这个结果是 3.3333,无理小数是没有 办法套用之前的公式的。不过,只要能表示成分数形式的分频都可以采用下面这种方式。小数分频的另一种形式在之前的分频中,我门采用的计数器都是进行加1操作的,如果不是加 1呢,比如说加3会是什么效果呢?以下以模16的计数器演示一下module freqdivfloat_2(i nput clki,
31、output reg 3:0 cntr); always(posedge clki)cntr = cntr + 3;F面是仿真图en dmodule 1SS.76 di*315.36 “rLrLrLnArLrLrLrLrLrLrLrLrLrLrLrLrLrLrLArLrLrLrLrLJi i这里有两个光标,在光标中间的数据为一个大周期,之后便不停得循环。 且两个光标之间的数值由小到大的变化了 3次,也就是说如果做成分频的话,会输出 3个脉冲,而输入时钟 的个数为16个,也就是说,如果做分频的话,分频的频率应为16/3分频。也可以这样理解,当cntr计数器进行加1计数的时候,每计完一个周期输出一
32、个脉冲的话就是16分频,那么每次加3,就是16/3分频。那么,如何确定分频的输出呢?在之前的分频中都是靠计数值来决定输出信号电平的高低,而在这种每次加3的计数过程中,每次计数的值都是不同的,如何确定呢?第一种方式,从上面的仿真图上可以看出,当进入第二周的时候,开始的计数值一定比第一周值得最后的计数值小(如:图中的2比15小),可以在这个时候输出一个脉冲。实现代码如下:module freqdiv16_3(i nput clki, output clko);reg 3:0 cntr, cn tr_dly; /(1)always(posedge clki)cntr = cntr + 3;alway
33、s(posedge clki) /(2)cn tr_dly = cntr;assign clko=(cntr12)?1:0;(3)仿真波形如下:TLnnnnrnr.nnnr.nnnnnnnnnnn.n可以看出,输出的波形没变,只是提前了一个时钟周期,因为这里没有比较,不需要将之前的计数值暂存。cntr3,这个值可以理解第三种方式,也是最简单的方式,直接取计数器的最高位,即 成模16的中间值,且这种方式得到的输出近似的为方波。 代码如下:assign clko=cntr3;仿真波形如下:8 X11X1C I4 XT YiaX13Y0 Y3 Y8 Y9 Y12Y15Y2 Y5 Y8虽然波形的脉宽发
34、生了变化,但个数没变。因此,这个结果也是正确的。分频系数大于1小于1.5的另一种分频方法例如,4/3分频。这种分频结果只能是在多个脉冲之间任意消除一个,像4/3分频,每4个脉冲中小曲一个脉冲。当然,也可以采用前面的计数方式来实现,可以计4个数,前三个计数中,直接输出输入的时钟,最后计数的一个周期内不输出。这样就可以实现4个脉冲输出3个了,即4/3分频。下面是另一种方式的实现。先看代码:代码说明:(1) 和之前一样,设计一个暂存计数器最高位的变量(2) 将计数器的最高位延时一个时钟周期(3) 这个表达式的结果需要仔细分析cntr2的波形,请读者参照下面仿真图自行分析。下图为4/3分频仿真结果:从
35、上图上看,clko_n_n_nLrLTLTLTLnLTLn_rmLrnrLJirLnrLnj-LnLTL_n_rLTLn_rLTrnrLj每4个输入clki输出3个周期脉冲,达到了 4/3分频的效果。存储器的设计与使用寄存器与存储器的定义在Verilog HDL中,通常使用reg m-1:0 r来定义寄存器r。这个寄存器r的位宽为m位.可以用下图来说明。1丨丨 1 它占有m个位空间。Reg类型通常用来定义寄存器,但也有例外的情况,例如前面讲过的 与门电路可以使用reg定义输出端:module an dgate2(i nput a, in put b, output reg c);/(1)alw
36、ays(*)c= a & b;en dmodule这里将c定义成reg型,而实际上生成与门电路的时候并没有寄存器的存在。它只是从语 法角度上满足 always块的赋值特点而设计的,所以,寄存器类型的变量不一定生成寄存器。于是在新的语法标准中,将reg类型重新命名为 variable 类型,并且同时将 wire等连线型命名为net型。同为variable 类型的还有integer型,在32位的操作系统当中,它的作用相当于reg31:0 ,即32位的寄存器类型变量。例如:integer i;相当于reg31:0 i ;。对于多位的寄存器或者是连线型变量的定义,通常也称作向量的定义,它有高地位顺序的
37、。这里用msb_constant_expression:lsb_constant_expression表示向量的通用形式,msb_co nsta nt_expression为最高位常量表达式,代表范围的左侧值,lsb_co nsta nt_expression为最低位常量表达式,代表范围的右侧值。右侧表达式的值可以大于、等于、小于左侧表达式的值。在前面的学习之中,大家知道,可以将向量中的部分位取出进行单独操作。 例如:wire 3:0 bus;wire b;assig n b=bus1;这种操作称为位操作,如果取出多个位,称作域操作。例如:wire 3:0 bus;wire 1:0 b;ass
38、ign b=bus1:0; /取 bus 的低两位域。如果说,不允许在向量中进行位选择和域选择的话,可以使用scalared关键字来定义向量。例如:wire vectored 7:0 bus;那么,这个时候 bus就不可以进行位操作和域操作了。vectored 关键字为标量类矢量。例如上例bus就是标量类矢量。默认情况下 wire7:0 bus这个bus向量为矢量类 矢量,它相当于 wire scalared 7:0 bus; ,scalared 为矢量类矢量的关键字。在没有位宽的定义中,都称为标量。如reg a; ,a就是一位标量。总之,标量类矢量与矢量类标量按位或部分位(域)赋值的矢量称为
39、标量类矢量,这相当于多个一位标量的集合,标量类矢量进行类型说明时,需要关键字scalared 。不能按位或域赋值的矢量称为矢量类矢量,在进行类型说明时,需要关键字vectored 。标量类矢量的说明可以缺省,就是说没有关键字 scalared 或vectored的矢量均将被解释成标量类矢量,这是使用最多的一类矢量。由若干个位宽相同向量组合在一起,就可以构成存储器空间。例如:reg 7:0 mymem63:0;这里定义了一个存储器空间,能存储数据位宽为8位,由64个单元组成。空间表示如下图:位宽8位在对存储器空间进行操作的时候,只能对存储器空间单个单元进行操作。 如:mymen1=8 h80;表
40、示将第1个空间存入值 80 (十六进制)位宽8位对存储器空间赋值的方法是分别对存储器中的每个字赋值。例如:mymem1 = 8hAA; mymem2 = 8h88;mymem3 = 8hFF; mymem4 = 8h22;这样就可以实现对存储器中的任意单元进行赋值。完整的示例代码如下。module memory1(addr,data);in put 3:0 addr;output reg 7:0 data;reg7:0 mymem15:0;in teger i;in itial/(1)for(i=0;i16;i=i+1)/(2)mymemi = i;always(*) data1 1 1 1
41、1 1 1 1 1 1 1 1 1 11 1 1 1 1 1 1 1 1 1 1 1 1 1IIIIIIIIIIIII为存储器赋值的另一种方法是使用系统任务,所谓系统任务就是指Verilog 内置的一些函数,均已$开头,如$monitor,他们不能够生成硬件电路,通常用于仿真。但在存储器赋值中,可以使用。分别是:1) $readmemb(加载二进制值)2) $readmemh(加载十六进制值)这些系统任务从指定的文本文件中读取数据并加载到存储器。文本文件必须包含相应的二进制或者十六进制数。例如:$readmemb (ram.patt, mymem);mymem是存储器空间。文件“ ram.pa
42、tt ”必须包含二进制值。 文件也可以包含空白空间和注释。下面是文件中可能内容的实例。11011101111011011000011101111000000001111001001100110011系统任务$readmemb促使从索引63即mymem最左边的字索引,开始读取值。完整代码及仿真图如下,为了更能清楚的看到现象,示例中将mymem存储空间定义成了 16 个:memory.vmodule memory(addr,data);in put 3:0 addr;output reg 7:0 data;reg7:0 mymem15:0;in itial$readmemb(ram.patt, m
43、ymem); /(1)always(*) dataNew,在弹出的窗口中选择 Memory In itializatio n File,如下图,然后选择ok,在弹出的窗口中设定宽度为8,深度为16,然后点击 0K。Number of words:Word size:|eCancelOK JNumber of Words & Word Size这时候会弹出界面,在界面中写入相应的内容即可。这里随机的写入一些值,如下图: 巒 Mifl.mifAddr+3+4+6I+7000000000000000010000001Q0000001100000100OOQOOIOt00001111000101118
44、10101010100011101111001110101010010111101100001110111101 10011111将文件保存为Mif1.mif 。如果在存储器定义的时候使用syn thesis ramn it_file=”Mif1.mif”属性的话,则在编译时候就可以按照mif文件中定义的值给存储器赋初值了。例如:reg7:0 mymem15:0/*syn thesis ramn it_file=”Mif1.mif”*/;使用该属性时候,需要将mif文件盒verilog文件放在同一个文件夹卜面,否则的话,需要指明mif文件的相对路径或者绝对路径。并且注意,这个属性也是以注释的形式出现 的,它必须介于存储器定义语句和分号之间。也可以用下面的形
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 2025年广灵辅警招聘真题及答案
- 国家知识产权局专利局专利审查协作湖北中心2026年度专利审查员公开招聘40人备考题库含答案详解
- 厦门大学附属第一医院漳州招商局开发区分院2025年第四批公开招聘编外工作人员备考题库附答案详解
- 咸安区2026年面向教育部直属师范大学公费师范毕业生专项招聘备考题库完整参考答案详解
- 2025年西安市雁塔区第一小学教师招聘考试备考题库及答案解析
- 2025年12月云南玉溪市易门县华亿投资有限责任公司(第二次)招聘8人备考核心题库及答案解析
- 2025年卫生健康局招聘备考题库及1套参考答案详解
- 2025年第十师北屯市公安局面向社会公开招聘警务辅助人员备考题库及1套完整答案详解
- 构建区域教育评价改革模型:人工智能评价结果应用与效果评估教学研究课题报告
- 国家知识产权局专利局专利审查协作四川中心2026年度专利审查员公开招聘备考题库有答案详解
- 火灾自动报警系统故障应急预案
- 人货电梯施工方案
- 南大版一年级心理健康第7课《情绪小世界》课件
- 光大金瓯资产管理有限公司笔试
- 算力产业园项目计划书
- 塔式起重机安全管理培训课件
- 老年髋部骨折快速康复治疗
- 【初中地理】跨学科主题学习探 索外来食料作物的传播史课件-2024-2025学年七年级上学期(人教版2024)
- 四川省南充市2024-2025学年高一地理上学期期末考试试题含解析
- 化学品管理控制程序
- 探索·鄱阳湖智慧树知到期末考试答案2024年
评论
0/150
提交评论