FPGA设计基础第3章FPGA设计入门课件.ppt
第三章 FPGA设计入门,有效的建模风格是控制综合结果的最有力手段。绝大多数系统设计都是使用HDL来实现。利用Verilog HDL进行FPGA设计规则、方法和技巧。,Page 1,组合逻辑电路,是指数字电路在任何时刻的输出仅仅取决于该时刻数字电路的输入,而与电路原来的状态 无关。组合逻辑电路分类:门电路 编码器、译码器和选择器 数据缓冲器,时序逻辑电路,时序逻辑电路就是指数字电路在任何时刻的输出不仅 仅取决于该时刻数字电路的输入,还取决于电路原来 的状态。时钟:进程敏感信号同步与异步复位 同步复位:复位语句是在以时钟为进程中执行 异步复位:进程敏感信号包括时钟和复位信号 分类:触发器 计数器:同步:在时钟下,各触发器状态同时变化 异步:上一位数据是下个触发器的时钟信号,3.1 系统的抽象层次与Verilog,一个系统可以在不同的抽象层次上进行描述,也可以从不同的描述域(行为结构物理)进行描述。1、系统描述的三个“域”行为域说明一个特定的系统完成什么功能 结构域说明不同的实体之间是如何连接的 物理域则说明如何构造出一个实际的器件,Page 3,3.1 系统的抽象层次与Verilog,Verilog可以在三个域、五个抽象层次上描述一个系统。行为模型-着重于描述系统的功能,忽略系统的实现(系统级或体系结构级,也可能是算法级)。结构模型-较为详细地至少描述到寄存器数据流的方式,大体的描述到了系统的结构和实现(RTL/门级/开关级)。,Page 4,3.1 系统的抽象层次与Verilog,2、系统描述的五个层次 工程师可以在系统级、算法级、RTL(Register Transfer Level 寄存器传输)级、逻辑级和电路级五个层次上描述一个系统,其中系统级的抽象层次最高,而电路级的抽象层次最低。抽象层次越高,所包含的细节信息就越少,抽象层次越低,所包含的细节就越多。,Page 5,Page 6,3.1 系统的抽象层次与Verilog,module adder(a,b,c0,c,sum);input 3:0 a,b;input c0;output 3:0 sum;output c;wire 4:0 mid_res;assign mid_res=a+b+c0;assign sum=mid_res3:0;assign c=mid_res4;endmodule,例如:行为级建模4bit全加器。因为在系统设计初期,人们更关心所设计系统的逻辑功能,还未关心系统的性能。行为级功能确认后,可进一步细化得到结构模型。,Page 7,3.1 系统的抽象层次与Verilog,行为级综合有时也称为高层次综合(highlevel synthesis),高层次综合工具对行为级描述电路的综合效果没有用RTL级描述的电路综合的效果好,故大部分的电路是在RTL级进行描述的。我们通常用 Verilog 在RTL级描述一个设计,借助于自动综合工具,设计人员可以将RTL级代码快速且便捷地变换成逻辑级描述。,Page 8,3.1 系统的抽象层次与Verilog,RTL级描述的典型模型,Page 9,3.1 系统的抽象层次与Verilog,对于有些特殊的电路,我们有时也采用“门级描述”来描述结构模型-即通过逻辑门及其互连线描述电路。在Verilog中可以通过三种实例化语句描述结构模型。Verilog內建的基本逻辑门 用户定义原语UPD Module实例语句(Book P86/87分别有RTL描述和门级描述例子),Page 10,3.2 用Verilog建立数字电路模型,设计的最终目标是将设计电路映射到具体的物理器件上。Verilog功能强大,用途范围广泛,语句丰富,但其中只有部分子集描述的设计可以通过EDA工具综合成具体的电路-Verilog可综合子集。良好的建模风格是控制综合结果的最有力的手段。,Page 11,3.2.1 代码的书写风格,编写代码的目的是对系统进行精确的描述,进行人-机(人-人)交流1、完备清晰的版本信息2、简洁扼要的功能说明,端口说明、变量说明,注释信息3、规范的端口定义,端口、变量命名规则4、模块互连时采用“显式关联方式”,Page 12,3.2.2 可综合代码的编码风格,always(posedge clk)begin begin begin q1=d;q3=q2;q1=d;q2=q1;q2=q1;q2=q1;q3=q2;q1=d;q3=q2;end end end/A 1/B/C,1、正确地理解和使用“阻塞/非阻塞”赋值,备注:综合结果见 P91、P92 图示。例3.2 见 ModelSim 例集,例3.1 三级移位寄存器的设计。,B、C:三移位寄存器,A:D触发器,Page 13,Page 14,3.2.2 可综合代码的编码风格,建议:在用always过程建立组合电路时,使用阻塞赋值(=),在用always过程描述时序电路时,使用非阻塞赋值语句(=)。小技巧:在用always过程建立组合电路时,所有的RHS变量都要加入到敏感变量表中。备注:理解 Book P94,例3.3,Page 15,3.2.2 可综合代码的编码风格,2、组合电路设计,注意:在使用 always 过程描述组合电路时,要对每一种输入的组合,都必须有一个值与之对应,否则会导致锁存器产生(组合电路不建议使用锁存器)。,结构原语连续赋值语句always 语句,a可综合组合电路的三种描述形式,Page 16,3.2.2 可综合代码的编码风格,b 简单组合电路设计方法,1、定义入/出逻辑变量2、列真值表,写表达式,化简3、电路图设计4、实验验证,手工设计步骤,HDL设计步骤,1、定义入/出逻辑变量2、列真值表,写表达式3、Verilog 编码4、仿真验证5、综合(优化、电路实现),Page 17,例3.7 半加器,3.2.2 可综合代码的编码风格,module HA(a,b,c,s);input a,b;output c,s;wire c,s;wire 1:0 adder;assign adder=a+b;assign s=adder0;assign c=adder1;endmodule,备注:多种描述方法描述同样功能。,Page 18,3.2.2 可综合代码的编码风格,例3.8 全加器,/实例化半加器,结构描述“全加器”module FA(a,b,c_i,s,c_o)input a,b,c_i;output s,c_o;wire c,s,c1;HA HA_1(.a(a),.b(b),.c(c),.s(s);HA HA_2(.a(s),.b(c),.c(c1),.s(s);assign c_o=c|c1;endmodule,Page 19,3.2.2 可综合代码的编码风格,/根据功能描述“全加器”module FA(a,b,c_i,s,c_o);input a,b,c_i;output s,c_o;wire 1:0 full_adder;/2比特变量,高位为进位,低位为和。assign full_adder=a+b+c_i;assign s=full_adder0;assign c_o=full_adder1;endmodule,3.2.2 可综合代码的编码风格,可以利用多个“1位全加器”构成多位的二进制加法器,即所谓的“行波加法器”。,Page 20,Page 21,3.2.2 可综合代码的编码风格,module adder_3(a,b,c0,s,cy);input 2:0 a,b;input c0;output 2:0 s;output cy;wire c1,c2;FA_1 FA1(.a(a0),.b(b0),.c_i(c0),.s(s0),.c_o(c1);FA_1 FA2(.a(a1),.b(b1),.c_i(c1),.s(s1),.c_o(c2);FA_1 FA3(.a(a2),.b(b2),.c_i(c2),.s(s2),.c_o(cy);endmodule,实例化1位全加器,设计“3位全加器”,Page 22,3.2.2 可综合代码的编码风格,例3.10 多路选择器可以通过CASE结构与IF-THEN-ELSE结构实现。要注意的是:case 结构无优先级特征if else 结构隐含着优先级电路综合的结果有些差别。,module single_if(a,b,c,d,sel,z);input a,b,c,d;input 3:0 sel;output z;reg z;always(a or b or c or d or sel)begin if(sel3)z=d;else if(sel2)z=c;else if(sel1)z=b;else if(sel0)z=a;else z=0;endendmodule,选择控制端sel3:0高位有高优先级,Page 23,module case1(a,b,c,d,sel,z);input a,b,c,d;input 1:0 sel;output z;reg z;always(a or b or c or d or sel)begin casex(sel)2b00:z=d;2b01:z=c;2b10:z=b;2b11:z=a;default:z=1b0;endcase endendmodule,选择控制端sel1:0无优先级,Page 24,Page 25,c 组合电路设计中应注意的问题,3.2.2 可综合代码的编码风格,不要有逻辑反馈(不能产生组合环)在敏感变量表中列全所有的敏感信号(RHS中以及“条件”中的信号都要进入敏感信号表)避免设计中无意间产生锁存器(case 语句有 default,if 语句 else 末分支,EXP 3.13),Page 26,有组合环,Page 27,3.2.2 可综合代码的编码风格,3、三态总线接口电路的设计,三态总线接口电路主要应用于微机接口(使能时传送,禁能时高阻)。三态总线接口电路设计使用“连续赋值”(assign)语句,其中一个分支被赋值成高阻z状态。,Page 28,3.2.2 可综合代码的编码风格,单向三态总线,assign data_to_bus=(bus_enable)?(core_log_to_bus):8hz;,Page 29,3.2.2 可综合代码的编码风格,双向三态总线,Page 30,module bi_dir_bus(rst_n,wr_clk,wr_en,rd_en,addr,data_to_from_bus);input rst_n;/复位信号;input wr_clk;/写数据时钟;input wr_en;/写使能;input rd_en;/读使能;input 1:0 addr;/地址;inout 7:0 data_to_from_bus;/双向数据总线;,reg 7:0 reg1,reg2,reg3,reg4;wire 7:0 core_logic;assign data_to_from_bus=(rd_en)?core_logic:8hz;always(negedge rst_n or posedge wr_clk)if(!rst_n)reg1=8h 00;else if(wr_en,Page 31,./reg2,reg3 同样的处理.always(negedge rst_n or posedge wr_clk)if(!rst_n)reg4=8h 00;else if(wr_en endmodule,3.2.2 可综合代码的编码风格-双向三态总线,3.2.3 时序电路的设计,1、时序电路的基本概念,时序电路的模型(通常)时序电路的输出不仅与当前的输入有关,而且与电路过去的状态也有关系。时序电路由存储元件(记忆功能,FF实现)和组合电路(用于完成运算)组成。FPGA中,一般使用D触发器作为存储元件。,备注:触发器-时钟沿工作,锁存器-时钟电平工作。,Page 32,Page 33,3.2.3 时序电路的设计,触发器的建立时间(tsu)、保持时间(th)tsu-触发器的时钟信号有效沿到来前,数据稳定 不变的时间。th-触发器的时钟信号有效沿到来以后,数据保持稳定不变的时间。,Page 34,3.2.3 时序电路的设计,同步电路/异步电路,如果时序电路中的所有D触发器的时钟端(锁存器除外)都与同一个时钟相连接,则称为同步时序电路,否则就称为是异步时序电路。本课程只研究同步电路设计。同步电路设计相对简单,设计出的电路可靠性高。,Page 35,3.2.3 时序电路的设计,时钟树,在同步设计中,要求时钟信号必须在同一时间到达电路中每个寄存器的时钟输入端,而且时钟信号经过输入管脚到达触发器的路径延时很小。在FPGA中,给专用的I/O模块配置了速度非常快的时钟驱动缓存器,这些缓冲器驱动输入时钟信号到芯片内部的时钟树上。时钟树的结构像一个树,它的每个分支都驱动固定数目的触发器,每个分支都有相同的长度。时钟驱动能快速驱动整个时钟树,时钟信号延时最小,一致性最好。,Page 36,3.2.3 时序电路的设计,时钟类型(四种类型),全局时钟-有专用的全局时钟管脚,直接连接到器件中的每个寄存器的时钟端,以提供最小的时钟信号延迟和时钟歪斜(skew)。门控时钟-由逻辑门和时钟进行逻辑操作后产生的时钟。设计不当的门控时钟往往容易产生毛刺,从而影响电路的可靠性。,Page 37,3.2.3 时序电路的设计,行波时钟-用一个D触发器的输出作另一个触发器的时钟输入。在数字电路设计中经常用到此种设计方案。要特别关注电路的时序,也是时序仿真的特别关照点。多级逻辑时钟-当产生门控时钟的组合逻辑超过一级门电路时,电路的可靠性变得很难控制,系统中避免采用。,Page 38,3.2.3 时序电路的设计,时钟策略,若电路要用到门控时钟/行波时钟,那么设计时要在顶层建立时钟模块,完成时钟的分频、反相或产生门控时钟。使用FPGA中的PLL资源倍频时钟,时钟元件的实例化要在顶层的时钟模块中进行。不要使用多级逻辑时钟。一般情况FPGA有专用的全局时钟引脚。对于内部信号如何处理,FPGA布局/线工具会自动优化使用系统时钟资源,但有时也需要设计者进行指定。,是指在数字系统中时钟的使用方法和策略。对于FPGA设计,合理的时钟策略是设计成功的基础。,3.2.3 时序电路的设计,时钟模块,Page 39,Page 40,2、时序电路的建模,3.2.3 时序电路的设计,D触发器,带使能端的D触发器,D 触发器,Page 41,3.2.3 时序电路的设计,/可异步复位D触发器module dflip(rst_n,clk,din,dout);input rst_n,clk;input din;output dout;reg dout;always(negedge rst_n or posedge clk)if(!rst_n)dout=1b0;else dout=din;endmodule,/带使能端的可同步复位D触发器module dflip(rst_n,clk,din_en,din,dout)input rst_n,clk,din,din_en;output dout;reg dout;always(posedge clk)if(!rst_n)dout=1b0;else if(din_en)dout=din;endmodule,3.2.3 时序电路的设计,状态机建模,有限状态机是建立系统模型最为有效的手段,有着广泛的应用。综合工具可以非常有效地将HDL语言描述的状态机行为优化成门级电路。,(状态机)时序电路按输出信号之特点分为两种:Moore型电路,Z=F(Q),输出只取决于上一状态。Mealy型电路,Z=F(Q,X),输出取决于上一状态以及当时的输入。,Page 42,Page 43,3.2.3 时序电路的设计,Moore机,Mealy 机,Page 44,3.2.3 时序电路的设计,根据功能要求,确定电路的状态数目;定义状态转移表;选择状态赋值;编码次状态和输出表;状态化简和输出;根据状态转移图完成电路的实现。,有限状态机的传统设计方法,Page 45,3.2.3 时序电路的设计,一个进程用电平敏感的组合逻辑,描述次态和输出;一个进程用边沿敏感的行为描述同步更新的时序逻辑(状态)。,用Verilog语言描述有限状态机,在用Verilog描述状态机时,将状态机的描述划分成两个进程:,3.2.3 时序电路的设计,例3.15 串行输入/输出的“BCD码”到“余3码”的转换电路设计。,根据编码的特点,可描述出状态图。,Page 46,module bcd_to_Excess_3(clk,rst_n,b_in,b_out);input clk,rst_n,b_in;output b_out;parameter s_0=3b 000,s_1=3b 001,s_2=3b 010,s_3=3b 011,s_4=3b 100,s_5=3b 101,s_6=3b 110;reg 2:0 curr_st,next_st;reg b_out;,/Part_I:组合逻辑;always(curr_st or b_in)begin b_out=0;case(curr_st)s_0:if(b_in)begin next_st=s_1;b_out=1b1;end else next_st=s_4;s_1:if(b_in)begin next_st=s_2;b_out=1b1;end else next_st=s_5;,Page 47,.s_6:begin next_st=s_0;b_out=1;enddefault:begin next_st=s_0;b_out=0;endendcaseend,/Part-II-updated new state;always(negedge rst_n or posedge clk)if(!rst_n)curr_st=s_0;else curr_st=next_st;endmodule,Page 48,3.2.3 时序电路的设计,用Verilog建立一个状态机模型的注意事项:,用parameter说明符号状态名;case语句中对所有的状态进行编码;时序部分只用组合电路计算出的新状态更新当前状态;要求一组D触发器表示一组状态,表示系统状态的D触发器数目与表示状态的编码有关;状态机的状态数目不宜过多。,Page 49,3.2.3 时序电路的设计,隐含状态机的 verilog 语言描述,有些时序电路并不是通过显式的状态机来描述,而是其状态被隐含地定义在行为的描述中。与显式状态机不同的是,隐含状态机中的每个状态只能从一个状态进入,状态机的状态是由每个周期行为所决定的。例如D触发器、移位寄存器、二进制计数器等(P122),Page 50,3.2.3 时序电路的设计,时序电路设计应该注意的问题:,避免使用门控时钟和多级时钟,应把这些时钟转换成使能端使用。,clk_p1=clk/(门控时钟)always(posedge clk_p1)begin end,always(posedge clk)begin if(p1_gate=1b1)begin end else begin end end,Page 51,3.2.3 时序电路的设计,不要随意使用行波时钟,FPGA的全局时钟资源有限,因此不要随意使用分频时钟,在布局布线时,它们不能被布线到全局时钟资源线上,因此会对电路的时序造成影响,可以用同步预制的方式实现行波时钟的功能。例:欲使用独热码三分频作计数器时钟。,always(posedge clk)case(count)begin 3b 000:count=3b 001;3b 001:count=3b 010;/one-hot code;endalways(posedge count 1)cnt_4=cnt_4+1;,应改为:always(posedge clk)If(count 1)cnt_4=cnt_4+1;,Page 52,3.2.3 时序电路的设计,关于敏感变量:时序逻辑模块设计中,敏感变量表只包含时钟和异步复位信号(若需要)。异步复位信号的产生:如果异步复位信号是由多个信号产生的,那么应该在always语句外,用assign语句产生。,.wire rst_n;/异步复位线assign rst_n=a,Page 53,3.2.3 时序电路的设计,对于较长的计数器,可以用多个进位链较短的计数器实现(资源换性能)。,/16b计数器一般设计module cnt_24(rst_n,clk,cnt_val);input rst_n,clk;output 15:0 cnt_val;reg 15:0 cnt_val;always(negedge rst_n or posedge clk)if(rst_n)cnt_val=16d0;else cnt_val=cnt_val+1;endmodule,例子说明如何用两个8位的计算器实现一个16位的计数器。,Page 54,Module cnt_16(rst_n,clk,cnt_val);input rst_n,clk;output 15:0 cnt_val;reg 7:0 cnt_1;reg 7:0 cnt_2;reg carry;always(negedge rst_n or posedge clk)if(rst_n)cnt_1=8d0;else cnt_1=cnt_1+1;,always(negedge rst_n or posedge clk)if(rst_n)carry=1b0;else carry=(cnt_1=8d254;)always(negedge rst_n or posedge clk)if(rst_n)cnt_2=8d0;else if(carry)cnt_2=cnt_2+1;assign cnt_val=cnt_2,cnt_1;endmodule,低8位进位位,低8位进位处理,Page 55,3.2.3 时序电路的设计,3、亚稳态及解决方法,所谓的“亚稳态”就是介于低电平0和高电平1之间不稳定的状态,或是经过振荡到达1或0的稳态。在异步电路中(FF 的Tsu、Th不能保证)很容易出现亚稳态,造成电路状态错误,在电路设计时要特别处理。,Page 56,3.2.3 时序电路的设计,可能出现亚稳态的异步电路,Page 57,3.2.3 时序电路的设计,尽量设计成同步时序电路无法避免时,将具有多个时钟的模块独立出来,在时钟的模块中,用一个时钟同步另外一个时钟域中的信号(进行时钟同步)。,data,Page 58,同步“异步信号”的两种电路,3.2.3 时序电路的设计,如果一个被同步信号的宽度大于同步时钟的周期,可以采用下图所示的同步电路。,Page 59,同步异步信号的两种电路,3.2.3 时序电路的设计,如果被同步的信号脉冲宽度小于用于同步的时钟时,可采用三个触发器的同步电路。,Page 60,3.2.3 时序电路的设计,4、存储器的建模,大部分的FPGA中提供了内嵌式存储器(RAM),因此,存储器的设计与目标器件密切相关。在使用存储器之前,首先应该清楚你所使用的存储器的类型(双端口/单端口)、深度、宽度、速度等。在综合前,可以先用Verilog语言描述一个存储器的功能模型供前仿真使用,电路设计验证正确后,再用FPGA中嵌入存储器替换语言的描述的存储器。,Page 61,3.2.3 时序电路的设计,例:设计1288的双端口的RAM。,module ram_128X8(wr_clk,wr_en,wr_addr,wr_dat8,rd_clk,rd_en,rd_addr,rd_dat8);input wr_clk,wr_en,rd_clk,rd_en;input 7:0 wr_dat8;input 6:0 wr_addr,rd_addr;output 7:0 rd_dat8;reg 7:0 rd_dat8;reg 7:0 ram127:0;,always(posedge wr_clk)if(wr_en)ramwr_addr=wr_dat8;always(posedge rd_clk)if(rd_en)rd_dat8=ramrd_addr;endmodule,Page 62,3.3 系统设计描述的一般方法,设计描述阶段包括顶层设计和详细设计两个阶段。根据系统规范的要求,将系统划分成若干个模块,形成顶层模块图,顶层模块完成系统定义的全部功能。顶层设计完成之后,定义各个模块的功能和接口并以原理图的形式划出各个子模块之间的连接关系。(原理图、自然语言、算法语言、时序波形图等)递归这个过程,直到便于Verilog描述实现。,Page 63,3.3 系统设计描述的一般方法,模块划分多大、如何划分取决于设计人员对所设计系统的理解和设计经验,没有严格的规则。工程师常遵循一些基本原则,使用这些规则可以清晰地划分电路,形成较为合理电路结构,帮助设计形成良好的习惯。我们简单地列举一些模块划分的原则:,模块划分的一般规则:,Page 64,3.3 系统设计描述的一般方法,分离特殊逻辑和核心逻辑,复位模块 I/O模块 时钟模块 存储器模块,Page 65,3.3 系统设计描述的一般方法,模块之间 无 粘合逻辑,只在层次结构中的最底层模块中包含门电路的实例。,模块间存在粘合逻辑,模块间存无粘合逻辑,Page 66,3.3 系统设计描述的一般方法,一个模块内只使用一个时钟,如果一个设计中包含了多个时钟,按时钟管辖的范围划分模块。,相邻的组合逻辑放到同一模块,Page 67,3.3 系统设计描述的一般方法,寄存器方式输出,每个模块经过D触发器锁存后再输出。亦即寄存器和输出端口之间不要含有组合逻辑。,时序逻辑使用D触发器,而不是锁存器,独立异步逻辑,在FPGA的设计中,应尽量避免异步逻辑设计。若必须使用异步逻辑,应将异步逻辑放在一个独立的模块中(这样可以更方便地检查代码,功能和时序)。,Page 68,3.4 系统规范,制定系统规范-定义系统的各项技术参数。模块设计-系统的模块组成、接口方式、功能实现等。设计输入-编码各模块输入计算机中。功能仿真(前仿真)-仿真系统的逻辑功能正确否。综合、布局布线-变换成网表和编成数据。时序仿真(后仿真)-仿真布局布线后的网表文件,检查电路的逻辑功能和时序特性。配置下载-用编程数据对 FPGA 编程。,FPGA的设计流程:,Page 69,3.4 系统规范-SPEC,系统规范的主要内容:,详细描述设计目标所完成的功能和拟达到的性能指标,功能规范要清晰、准确、完备。I/O管脚的特性描述(引脚的定义、时序、阈值、驱动能力等)简述系统的各模块构成,各模块信号形式(在各模块SPEC再递归,直到模块可直接设计实现)。可能选用的第三方IP核。,Page 70,3.4 系统规范,目标功耗、封装形式、FPGA器件选择、典型应用。设计的验证和测试:在规范文集中还应明确如何验证和测试电路的功能正确性(包括FPGA设计的仿真方案、测试程序方案和环境工具等-通常要形成单独文档)。详细的项目规划文档,包括项目的进度、资源的需求、各个阶段所使用的工具、技术和方法等。,Page 71,3.4 系统规范,在制定规范阶段,全体项目人员参与系统规范的制定与评估。XXX项目技术规范非常重要,是整个芯片设计的基础。目的:集思广意保证系统规范的正确,深刻地理解系统目标、系统结构和业务流程。系统规范完成后,可以进入第二阶段。,Page 72,目标 FPGA 的选择,3.4 系统规范,FPGA 的资源情况(LE数量、结构特点、嵌入式硬核);FPGA的工作速度、工作温度;I/O管脚的数量和类型;FPGA器件的编程方式;FPGA的开发工具支持情况;,Page 73,