实质上说,FPGA的模块规划便是将输入转化成想要得到的输出成果。而除了某些简略模块,即在当拍内完结,行将输入进行逻辑操作后,再输出。(如简略加法器等)。其他大部分的规划需求经过时序逻辑和组合逻辑混合完成,时序逻辑带来便是推迟起效的问题,举例说,如完成某个信号(start)起效后,接下来五个周期需求别离进行五种操作,别离是op0,op1,op2,op3,op4 等等。怎么进行操控,这便是每个工程师要面临的问题。
关于简略操控,别离能够选用计数和移位存放器的办法来处理问题。而关于较为杂乱的操控,则需求规划状况机来处理。下面将别离介绍
计数器: 关于上述操作来说,start起效后,能够经过计数完成,设置存放器count[2:0],有用信号开端时计数自加。 计数的办法带来的问题便是,计数从零开端仍是从1开端,假定计数器初始化为0,则从0-4状况能够别离输出op0,op1,op2,op3,op4,可是在无有用信号时,计数会坚持0,然后形成op0的输出。 上述举例尽管简略,可是的确许多初学者或许工程师在仿真时会经常会犯的过错。从规划来说,计数需求考虑初始值关于输出的影响。相同计数带来的另一个问题便是,从零开端的计数会导致规划与实践不共同,例如,一个信号9拍后拉低,但从零计数到8时,现已到9拍了(0-8),这种规划会导致命名count==8 与9拍存在不共同的现象。当然也能够从1计数到9,这样状况在count==9时触发。这样就会初始化需求复位存放器为1。当然这个问题大端和小端的争斗相同,没有结尾。一个规划中假如多种计数来驱动计数的话,就需求特别当心这个问题计数。当然也可把问题交给仿真器,仿真时依据波形调整,计数的状况。
移位存放器:如选用移位存放器,依据上述比如,则start信号有用后,规划5bit的移位存放器flag[4:0]别离运用存放器的某BIT来操控输出,然后在每BIT有用时,别离输出op0,op1,op2,op3,op4。假定此种状况较少,FPGA存放器资源较为丰厚,因而运用移位存放器是一个不错的留意。
assign op4 = ( count == 3’b100) ;
assign op4 = flag[4] ;
比较上述两种输出,则能够看出,经过计数的办法占用输出资源较多,而移位存放器在此种运用下,占用逻辑就相对简略。(仅针对小规模的计数来说,关于超越16的计数,则运用计数器更优)。别的,经过移位存放器能够便利的进行时序操控,不必纠结从零开端仍是从1开端的问题,在某些简略的处理下能够到达更小的面积和更快的时序。
关于杂乱的操控,则状况机,便是有必要的。关于FPGA完成状况机,其实并不需求那么多的规划的办法。首要便是两个要害。(1)独热码。(2)三段式。
关于第一点来说,独热码,由于FPGA内部存放器资源较多,别的独热码将会带来额定的面积和时序优化的优点。则以上述比如为例,添加状况搬运的触发信号,状况搬运图如下所示:
状况独热码(也能够用define localparam)主张运用parameter或许localparam
parameter idle == 6’b000001,
op0_state == 6’b000010,
op1_state == 6’b000100,
op2_state == 6’b001000,
op3_state == 6’b010000,
op4_state == 6’b100000;
三段式结构如下
//(1)当时状况
always@(posedge sys_clk or negedge rst_n)
if(!rst_n)
cs_state <= idle;
else
cs_state <= ns_state;
//(2)下一状况的赋值
always@(*)
case(cs_state)
idle : if(start)
ns_state = op0_state;
else
ns_state = idle;
op0_state :
if(op0_over)
ns_state = op1_state;
else
ns_state = op0_state;
op1_state :
if(op1_over)
ns_state = op2_state;
else
ns_state = op1_state;
op2_state :
if(op2_over)
ns_state = op3_state;
else
ns_state = op2_state;
op3_state :
if(op3_over)
ns_state = op4_state;
else
ns_state = op3_state;
op4_state :
if(op4_over)
ns_state = op4_state;
else
ns_state = idle;
default ns_state = idle;
endcase
//(3)输出状况
assign out1 = (cs_state == op0_state);
always@(posedge sys_clk or negedge rst_n)
if(!rst_n)
out2_reg <= 1'b0;
else if (cs_state == op2_state)
out2_reg <= 1'b1;
else
out2_reg <= 1'b0;
上述比如,介绍独热码和三段式。三段式的优点不必说,便是逻辑清楚。能够看出out1输出为组合输出。out_2_reg为存放输出。那么独热码在FPGA内部的优势又有哪些?
(1)归纳后,逻辑简略
例如assign out1 = (cs_state == op0_state); 归纳后的电路等同于
assign out1= cs_state(0) ;//能够看出无逻辑耗费
而 out2_reg 的电路等同于 将cs_state(2)存放一拍,只需一个存放器的耗费
(2)时序优化。
从上述相同得出结论,假如是运用某状况cs_state(n)作为其他信号的输入来说,其本身为存放器信号,因而要害途径就会削减一级。或许运转较快的频率就会添加。如不是独**,比照这两条句子cs_state = 3 与cs_state(3) 一个是组合输出,一个存放器输出。其不同也便是上述计数与移位存放器的差异共同。
那么一般状况时机发生的过错会有哪些那?
首要;便是状况不全发生LATCH,前文已述,这是FPGA规划的大敌,处理这个问题的办法能够经过一切分支都设定确认状况,如上例中。有没有更简略的办法?
其此:状况机上述描绘,并不直观的闪现归纳后电路的描绘,有没有更直接的rtl的描绘,一眼就能看出独热码的特征和优点?
最终:状况机是一个较为老练技能,还会有哪些值得重视的当地?
这些问题,下节再述。