《FPGA杂记之基础篇(FPGA设计重要知识点).docx》由会员分享,可在线阅读,更多相关《FPGA杂记之基础篇(FPGA设计重要知识点).docx(18页珍藏版)》请在优知文库上搜索。
1、Verilog基础语法组合逻辑1.1 可综合模块以module为单元,具体实现如下:11*声明模块:module模块名(输入输出);endmodule-*/1.1.1时序逻辑以异步触发的D触发器为例,时序逻辑在always块里实现。moduleex_seodule(IWUtwiresys-cllc,声明模块时.输入变量一定是类型InPUtWirrt-nrinputwire(:.Jd,OQtPntreg:二q输出变量可以是wra,也可以是工ag,rg变量只能在lxay3块中赋迫1.);always(POSedgCays-clkfnogedgeNSJn)敏S?列表既可以是边沿帆发,也可以是电平核发
2、if(rst_n=1bC)qib;elseq三d;沿烛发的逻辑里.一定采用的是非阻塞电冽endnodle主要注意点:1 .声明模块时,输入变量一定是Wire类型。2 .声明模块时,输出变量可以是Wire,也可以是reg,reg变量只能在always块中赋值。3 .敏感列表既可以是边沿触发,也可以是电平触发。4 .沿触发的逻辑里,一定采用的是非阻塞触发=。1.1.2组合逻辑以数据选择器为例,组合逻辑通常使用assign语句赋值。modulesei(inputwiresei,inputwirea,inputwirebroutputwirec);assignc=(SeI=1,b)?a:b;endmo
3、dule主要注意点:1.Sel=O时,c=a;SeI=I时,c=b,即二选一数据选择器。四选一则有两个选择端,四个输入端,八选一则是三个选择端,八个输入端。2 .wire变量一定要用连续赋值语句赋值,而且必须用阻塞赋值。3 .2仿真模块仿真模块和可综合模块的区别:可综合模块最终生成的bit文件会烧录进芯片运行,而仿真模块编译过后是在仿真软件(例如modelsim)上运行的。仿真模块是基于可综合模块进行例化,并通过仿真软件的模拟,可以初步验证我们写的可综合模块的实现现象。以计数器为例,可综合模块如下:mmoduleex_cnt(inputwiresys_clk,inputwirerst_nrou
4、tputwire9:0ent);reg?:cnt_r;由于要在always里面操作赋值,因此要定义一个reg变量always(posedgesys_clk,negedgerst_n)if(rst_n三三1,bC)cnt_r=10,b;elseIcnt_r=cnt_r+_bl;endmodle基于以上可综合模块的仿真模块如下:zincscle/时葬卫位是ns褶堂是IOoP3,BP100.1是有效效僚,为100.1ns,而】0。.】先是遍别为100.1-octaletb_ex_cns仿M的矮块声明不需委输入列表regtb-ays-clk;regZtTrstja:wire9:3zbjcnz:init
5、ial上电初始化,只在上电时执行一次!可以认为整个程序中只会执行一次begintb_sys_clk三0;/块只能对【寄存器】量进行赋值cbrscn0;2001*/200.1之后8_“jn-1:endalways一tb_ays_clk-tb_3y3_clk;宸55循环周期为20113.sys-clk(tbsys-clk),X9ZJJarcnc(tbent);例化模境时,如果朦始模块时输出交量则括号内必须是【wire变量】endmoduld1 .仿真的模块声明不需要输入列表。2 .initial块只能对【寄存器】量进行赋值。3 .例化模块时,如果原始模块是输出变量,则括号内必须【wire变量工HD
6、L常见例子2.1 译码器2.1.1 可综合模块(CaSe语句)此模块用case实现了一个数据选择的功能,先产生了一个8位计数器,通过判断计数器的值来输出不同的取值,当计数器计数到1时,o_data和。_dv分别输出5和1,当计数器为2时,输出7和1,其余均输出0。(Note:CaSe语句常常运用于状态机中状态的判断)*译码器11moduleex_case(inputwireSClk,inptwirersc_n,outputrego_dv,outputreg7:0o_data,);reg2:0ent;always6(posedgesclk,negedgerst_n)if(rst_n=L,b)11
7、beginent=3,b;endelseent=ent+-bl212223 B242526-27fi 8 9 0 2 2 3313233-34 A353637-38394041-42-43-always (posedge sclk, negedge rst_n) if(rst_n = .,b)begino_dv = .,b;o_data = 3 ,b;endelsebegincase(ent)3,dl:begino_data n 3,d5;o_dv = 1,bl; end3,d2:begino_data 3,d7;。二dv = l,bl; enddefault:begino_data = S,
8、d;o_dv 1,b; endendcaseendendmoduleCase语句注意点:必须有default语句,否则会形成锁存器。2.1.2仿真模块timescalelns100psmoduletb_ex_case;regtb_scllc;regtb_rst_n;wiretb_o_dv;wire:.tb_o_daca;|91011 1213141516-initialbegintb_sclk=1b;tb_rst_n=1,b;#200tb_rst_n=1bl;end1718192021222324252627always #10 tb SCIk 0.5outputregchange,outpu
9、tregcola);reg3:3scare;二进制编码e.g.IDLE-000:HALF-001;ONE-010;ONEHALr三011;TWO=100t占用的寄存器效量少,但是组合逻辑资源多.独热码编码如例程中使用的.占用的寄存器数量多,但是组合逻辑资源少.关于组合逻辑贡源占用,例如,使用语句,即比较器1(Stace-4b0001)经过优化会变成if(staee(0-lbl)即实际上,用到的是1比特的比较器,只用判断对应位是否为0:而二迸制编码,用到的是3比特比较器,三个位置都要判断是否为0,使用的速辑资源就明39404142434445464748495051525354555657585
10、96061626364656667686970717273747576-n787980818283848586878889909192939495969798parameter Parameter Parameter parcuneter ParameterIDLE=4,b0000;HALF=4,b0001;ONE=三4,b0010;ONEHALF=4,b0100;TWO=4,blOOC;always(posedgeSClk,negedgerst_n)if(!rst_n)state=IDLE;elsebegincase(state)IDLE:if(money=0)state=HALF;else
11、state=ONE;HALF:|if(money=0)state=ONE;elsestate=ONEHALF;ONE:if(money=0)state=ONEHALF;elsestate=TWO;ONEHALF:if(money=0)state=TWO;elsestate三IDLE;TWO:state三IDLE;default:state=IDLE;endcaseend-endalways(posedgesclk,negedgerst-n)beginif(!rsjn)change0;elseif(state=TWO&money=ltbl)change三-bl;elsechange=0;1.en
12、dalwaysQ(posedgesclktnegedgerst_n)Rbeginif(!rsjn)cola=0;elseif(state三三TWO)(state三三ONEHALF&money三三1,t-)cola=1,bl;elsecola三0;-endendmodule2.2.3仿真模块timescale/moduletb_fsm();4一regsclk;regrst_n;regmoney;wirechange;wirecola;1011121314151617181920212223242526272829initialbeginsclk=0;rst_n=0;money=0;#20rst_n=1;-endalways#sclk=sc1k;always#2.money=SrandomJ;Rjfsmfsminst(.sclk(sclk),.rst_n(rst_n),.money(money),.change(change),.cola(cola);endmodul