FPGAPrototypingByVerilogExamples第六章状态机FSMD设计解析.docx
《FPGAPrototypingByVerilogExamples第六章状态机FSMD设计解析.docx》由会员分享,可在线阅读,更多相关《FPGAPrototypingByVerilogExamples第六章状态机FSMD设计解析.docx(23页珍藏版)》请在冰豆网上搜索。
FPGAPrototypingByVerilogExamples第六章状态机第六章状态机FSMD设计解析设计解析FSMD(带数据通道的有限状态机)是FSM和常规时序电路的结合。
基于RTmethodology的消抖电路设计本设计中主要的数据通道是一个用户自定制的21位递减计数器,其作用为:
1:
可初始化为一个指定的值;2:
具有递减计数和暂停计数的功能;3:
当计数器计数为0的时候,输出一个状态信号。
moduledebounce_explicit(inputwireclk,reset,inputwiresw,outputregdb_level,db_tick);/symbolicstatedeclarationlocalparam1:
0zero=2b00,wait0=2b01,one=2b10,wait1=2b11;/numberofcounterbits(2N*20ns=40ms)localparamN=21;/signaldeclarationreg1:
0state_reg,state_next;regN-1:
0q_reg;wireN-1:
0q_next;wireq_zero;regq_load,q_dec;/q_load:
loadtheinitialvalue;q_dec:
enablethecounter/body/fsmdstate&dataregistersalways(posedgeclk,posedgereset)if(reset)beginstate_reg=zero;q_reg=0;endelsebeginstate_reg=state_next;q_reg=q_next;end/FSMDdatapath(counter)next-statelogicassignq_next=(q_load)?
N1b1:
/load1.1(q_dec)?
q_reg-1:
/decrementq_reg;/statussignalassignq_zero=(q_next=0);/FSMDcontrolpathnext-statelogicalways*beginstate_next=state_reg;/defaultstate:
thesameq_load=1b0;/defaultoutput:
0q_dec=1b0;/defaultoutput:
0db_tick=1b0;/defaultoutput:
0case(state_reg)zero:
begindb_level=1b0;if(sw)beginstate_next=wait1;q_load=1b1;endendwait1:
begindb_level=1b0;if(sw)beginq_dec=1b1;if(q_zero)beginstate_next=one;db_tick=1b1;endendelse/sw=0state_next=zero;endone:
begindb_level=1b1;if(sw)beginstate_next=wait0;q_load=1b1;endendwait0:
begindb_level=1b1;if(sw)beginq_dec=1b1;if(q_zero)state_next=zero;endelse/sw=1state_next=one;enddefault:
state_next=zero;endcaseendendmodule另一种可替代的代码风格:
将RT(寄存器传输)的操作嵌入到FSM控制通路中,我们不需要明确的指定数据通路的元素,只需要在相应的FSM状态中列出RT操作即可。
/Listing6.2moduledebounce(inputwireclk,reset,inputwiresw,outputregdb_level,db_tick);/symbolicstatedeclarationlocalparam1:
0zero=2b00,wait0=2b01,one=2b10,wait1=2b11;/numberofcounterbits(2N*20ns=40ms)localparamN=21;/signaldeclarationregN-1:
0q_reg,q_next;reg1:
0state_reg,state_next;/body/fsmdstate&dataregistersalways(posedgeclk,posedgereset)if(reset)beginstate_reg=zero;q_reg=0;endelsebeginstate_reg=state_next;q_reg=q_next;end/next-statelogic&datapathfunctionalunits/routingalways*beginstate_next=state_reg;/defaultstate:
thesameq_next=q_reg;/defaultq:
unchnageddb_tick=1b0;/defaultoutput:
0case(state_reg)zero:
begindb_level=1b0;if(sw)beginstate_next=wait1;q_next=N1b1;/load1.1endendwait1:
begindb_level=1b0;if(sw)beginq_next=q_reg-1;if(q_next=0)beginstate_next=one;db_tick=1b1;endendelse/sw=0state_next=zero;endone:
begindb_level=1b1;if(sw)beginstate_next=wait0;q_next=N1b1;/load1.1endendwait0:
begindb_level=1b1;if(sw)beginq_next=q_reg-1;if(q_next=0)state_next=zero;endelse/sw=1state_next=one;enddefault:
state_next=zero;endcaseendendmodule第二种描述方式(隐数据通道)基本上跟ASMD描述顺序一样,我们仅仅是把ASMD图转换成了HDL语言。
虽然这种方法简单而且描述性强,但是数据通道的综合主要依赖于软件,不容易控制。
为了代码的可读性、明晰化和高效性,我们常常把复杂的数据通道提取出来单独描述。
Fibonaccinumbercircuit(数列)1234567891011121314151617181920212223242526272829/Listing6.4modulefib(inputwireclk,reset,inputwirestart,inputwire4:
0i,outputregready,done_tick,outputwire19:
0f);/symbolicstatedeclarationlocalparam1:
0idle=2b00,op=2b01,done=2b10;/signaldeclarationreg1:
0state_reg,state_next;reg19:
0t0_reg,t0_next,t1_reg,t1_next;reg4:
0n_reg,n_next;/body/FSMDstate&dataregistersalways(posedgeclk,posedgereset)if(reset)beginstate_reg=idle;t0_reg=0;t1_reg=0;3031323334353637383940414243444546474849505152535455565758n_reg=0;endelsebeginstate_reg=state_next;t0_reg=t0_next;t1_reg=t1_next;n_reg=n_next;end/FSMDnext-statelogicalways*beginstate_next=state_reg;ready=1b0;done_tick=1b0;t0_next=t0_reg;t1_next=t1_reg;n_next=n_reg;case(state_reg)idle:
beginready=1b1;if(start)begint0_next=0;t1_next=20d1;n_next=i;state_next=op;end596061626364656667686970717273747576777879808182838485endop:
if(n_reg=0)begint1_next=0;state_next=done;endelseif(n_reg=1)state_next=done;elsebegint1_next=t1_reg+t0_reg;t0_next=t1_reg;n_next=n_reg-1;enddone:
begindone_tick=1b1;state_next=idle;enddefault:
state_next=idle;endcaseend/outputassignf=t1_reg;endmodule除法器12345678910111213141516171819/Listing6.5modulediv#(parameterW=8,CBIT=4/CBIT=log2(W)+1)(inputwireclk,reset,inputwirestart,inputwireW-1:
0dvsr,dvnd,outputregready,done_tick,outputwireW-1:
0quo,rmd);/symbolicstatedeclarationlocalparam1:
0idle=2b00,op=2b01,last=2b10,2021222324252627282930313233343536373839404142434445464748done=2b11;/signaldeclarationreg1:
0state_reg,state_next;regW-1:
0rh_reg,rh_next,rl_reg,rl_next,rh_tmp;regW-1:
0d_reg,d_next;regCBIT-1:
0n_reg,n_next;regq_bit;/body/FSMDstate&dataregistersalways(posedgeclk,posedgereset)if(reset)beginstate_reg=idle;rh_reg=0;rl_reg=0;d_reg=0;n_reg=0;endelsebeginstate_reg=state_next;rh_reg=rh_next;rl_reg=rl_next;d_reg=d_next;n_reg=d_reg)beginrh_tmp=rh_reg-d_reg;q_bit=1b1;endelsebeginrh_tmp=rh_reg;1071081091101