打印

FPGA设计思想与技巧

[复制链接]
2036|3
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
AutoESL|  楼主 | 2011-10-19 22:50 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
第一章 FPGA设计指导性原则
这一部分主要介绍FPGA/CPLD设计的指导性原则,如FPGA设计的基本原则、基本设计思想、基本操作技巧、常用模块等。FPGA/CPLD设计的基本原则、思想、技巧和常用模块是一个非常大的问题,在此不可能面面俱到,只能我们公司项目中常用的一些设计原则与方法提纲携领地加以介绍,希望引起同事们的注意,如果大家能有意识的用这些原则方法指导日后的工作,不断积累和充实自己,将取得事半功倍的效果!本章主要内容如下:
·基本原则之一:面积和速度的平衡与互换;
·基本原则之二:硬件原则;
·基本原则之三:系统原则;
·基本原则之四:同步设计原则;
·基本设计思想与技巧之一:乒乓操作;
·基本设计思想与技巧之二:串并转换;
·基本设计思想与技巧之三:流水线操作;
·基本设计思想与技巧之四:数据接口的同步方法;
·常用模块之一:RAM;
·常用模块之二:FIFO;
·常用模块之三:全局时钟资源与时钟锁相环;
·常用模块之四:全局复位、置位信号。

1.1基本原则之一:面积和速度的平衡与互换
       这里"面积"指一个设计消耗FPGA/CPLD的逻辑资源的数量,对于FPGA可以用所消耗的触发器(FF)和查找表(LUT)来衡量,更一般的衡量方式可以用设计所占用的等价逻辑门数。"速度"指设计在芯片上稳定运行,所能够达到的最高频率,这个频率由设计的时序状况决定,和设计满足的时钟周期,PADto PAD Time,Clock Setup Time,Clock Hold Time,Clock-to-Output Delay等众多时序特征量密切相关。面积(area)和速度(speed)这两个指标贯穿着FPGA/CPLD设计的始终,是设计质量的评价的终极标准。这里我们就讨论一下关于面积和速度的两个最基本的概念:面积与速度的平衡和面积与速度的互换。
     面积和速度是一对对立统一的矛盾体。要求一个同时具备设计面积最小,运行频率最高是不现实的。更科学的设计目标应该是在满足设计时序要求(包含对设计频率的要求)的前提下,占用最小的芯片面积。或者在所规定的面积下,使设计的时序余量更大,频率跑得更高。这两种目标充分体现了面积和速度的平衡的思想。关于面积和速度的要求,我们不应该简单的理解为工程师水平的提高和设计完美性的追求,而应该认识到它们是和我们产品的质量和成本直接相关的。如果设计的时序余量比较大,跑的频率比较高,意味着设计的健壮性更强,整个系统的质量更有保证;另一方面,设计所消耗的面积更小,则意味着在单位芯片上实现的功能模块更多,需要的芯片数量更少,整个系统的成本也随之大幅度削减。
     作为矛盾的两个组成部分,面积和速度的地位是不一样的。相比之下,满足时序、工作频率的要求更重要一些,当两者冲突时,采用速度优先的准则。
     面积和速度的互换是FPGA/CPLD设计的一个重要思想。从理论上讲,一个设计如果时序余量较大,所能跑的频率远远高于设计要求,那么就能通过功能模块复用减少整个设计消耗的芯片面积,这就是用速度的优势换面积的节约;反之,如果一个设计的时序要求很高,普通方法达不到设计频率,那么一般可以通过将数据流串并转换,并行复制多个操作模块,对整个设计采取"乒乓操作"和"串并转换"的思想进行运作,在芯片输出模块再对数据进行"并串转换",是从宏观上看整个芯片满足了处理速度的要求,这相当于用面积复制换速度提高。面积和速度的互换的具体操作有很多的技巧,比如模块复用,"乒乓操作","串并转换"等,需要大家在日后工作中积累掌握。下面举例说明如何使用"速度换面积"和"面积换速度"。
      例1:如何使用"速度的优势换取面积的节约"? 在 WCDMA预商用系统设计中,使用到了快速**码(FHT)运算,FHT 由四步相同的算法完成,如图1所示。FHT的单步算法如下:


                                              图 1-1 FHT


原设计由于考虑流水线式数据的要不同 4 FHT用将
4 模块,以完成数据流流水线 FHT 代码下:

//模块是 FHT 顶层 4 个不同 FHT 模块,完成整 FHT
modulefhtpart(Clk,Reset,FhtStarOne,FhtStarTwo,FhtStarThree,FhtStarFour,
I0,I1,I2,I3,I4,I5,I6,I7,I8,
I9,I10,I11,I12,I13,I14,I15,
Out0,Out1,Out2,Out3,Out4,Out5,Out6,Out7,Out8,
Out9,Out10,Out11,Out12,Out13,Out14,Out15);
input Clk; //
设计的主时钟
input Reset; //
步复位
input FhtStarOne,FhtStarTwo,FhtStarThree,FhtStarFour; //4
法的时序控制

信号
input [11:0] I0,I1,I2,I3,I4,I5,I6,I7,I8;
input [11:0] I9,I10,I11,I12,I13,I14,I15; //FHT
16 输入
output [15:0] Out0,Out1,Out2,Out3,Out4,Out5,Out6,Out7;
output [15:0] Out8,Out9,Out10,Out11,Out12,Out13,Out14,Out15; //FHT
16 输出
// 1 FHT 步运输出
wire [12:0] m0,m1,m2,m3,m4,m5,m6,m7,m8,m9;
wire [12:0] m10,m11,m12,m13,m14,m15;
//
2 FHT 步运输出
wire [13:0] mm0,mm1,mm2,mm3,mm4,mm5,mm6,mm7,mm8,mm9;
wire [13:0] mm10,mm11,mm12,mm13,mm14,mm15;
//
3 FHT 步运输出
wire [14:0] mmm0,mmm1,mmm2,mmm3,mmm4,mmm5,mmm6,mmm7,mmm8,mmm9;
wire [14:0] mmm10,mmm11,mmm12,mmm13,mmm14,mmm15;
//
4 FHT 步运输出
wire [15:0] Out0,Out1,Out2,Out3,Out4,Out5,Out6,Out7,Out8,Out9;
wire [15:0] Out10,Out11,Out12,Out13,Out14,Out15;
//
1 FHT 步运
fht_unit1 fht_unit1(Clk,Reset,FhtStarOne,
I0,I1,I2,I3,I4,I5,I6,I7,I8,
I9,I10,I11,I12,I13,I14,I15,
m0,m1,m2,m3,m4,m5,m6,m7,m8,
m9,m10,m11,m12,m13,m14,m15
);
//
2 FHT 步运
fht_unit2 fht_unit2(Clk,Reset,FhtStarTwo,
m0,m1,m2,m3,m4,m5,m6,m7,m8,
m9,m10,m11,m12,m13,m14,m15,
mm0,mm1,mm2,mm3,mm4,mm5,mm6,mm7,mm8,
mm9,mm10,mm11,mm12,mm13,mm14,mm15
);
//
3 FHT 步运
fht_unit3 fht_unit3(Clk,Reset,FhtStarThree,
mm0,mm1,mm2,mm3,mm4,mm5,mm6,mm7,mm8,
mm9,mm10,mm11,mm12,mm13,mm14,mm15,

mmm0,mmm1,mmm2,mmm3,mmm4,mmm5,mmm6,mmm7,mmm8,
mmm9,mmm10,mmm11,mmm12,mmm13,mmm14,mmm15
);
//
4 FHT 步运
fht_unit4 fht_unit4(Clk,Reset,FhtStarFour,
mmm0,mmm1,mmm2,mmm3,mmm4,mmm5,mmm6,mmm7,mmm8,
mmm9,mmm10,mmm11,mmm12,mmm13,mmm14,mmm15,
Out0,Out1,Out2,Out3,Out4,Out5,Out6,Out7,Out8,
Out9,Out10,Out11,Out12,Out13,Out14,Out15
);
endmodule


FHT 下(仅仅举例第 4 的模块):


module fht_unit4(Clk,Reset,FhtStar,
In0,In1,In2,In3,In4,In5,In6,In7,In8,
In9,In10,In11,In12,In13,In14,In15,
Out0,Out1,Out2,Out3,Out4,Out5,Out6,Out7,Out8,
Out9,Out10,Out11,Out12,Out13,Out14,Out15
);
input Clk; //
设计的主时钟
input Reset; //
步复位
input FhtStar; //
FHT 算控制信号
input [14:0] In0,In1,In2,In3,In4,In5,In6,In7,In8,In9;
input [14:0] In10,In11,In12,In13,In14,In15; //
FHT 算输入
output [15:0] Out0,Out1,Out2,Out3,Out4,Out5,Out6,Out7,Out8,Out9;
output [15:0] Out10,Out11,Out12,Out13,Out14,Out15; //
FHT 算输出
//Single FHT calculation
reg [15:0] Out0,Out1,Out2,Out3,Out4,Out5;
reg [15:0] Out6,Out7,Out8,Out9,Out10,Out11;
reg [15:0] Out12,Out13,Out14,Out15;
//
补码
wire [14:0] In8Co =~In8+1;
wire [14:0] In9Co =~In9+1;
wire [14:0] In10Co=~In10+1;
wire [14:0] In11Co=~In11+1;
wire [14:0] In12Co=~In12+1;
wire [14:0] In13Co=~In13+1;
wire [14:0] In14Co=~In14+1;
wire [14:0] In15Co=~In15+1;
always @(posedge Clk or negedge Reset)
begin
if(!Reset)
begin
Out0<=0;Out1<=0;Out2<=0;Out3<=0;
Out4<=0;Out5<=0;Out6<=0;Out7<=0;
Out8<=0;Out9<=0;Out10<=0;Out11<=0;
Out12<=0;Out13<=0;Out14<=0;Out15<=0;
end
else
begin
if(FhtStar)
begin
Out0<={In0[14],In0 }+{In8[14],In8 };
Out1<={In0[14],In0 }+{In8Co[14],In8Co };
Out2<={In1[14],In1 }+{In9[14],In9 };
Out3<={In1[14],In1 }+{In9Co[14],In9Co };
Out4<={In2[14],In2 }+{In10[14],In10 };
Out5<={In2[14],In2 }+{In10Co[14],In10Co };
Out6<={In3[14],In3 }+{In11[14],In11 };
Out7<={In3[14],In3 }+{In11Co[14],In11Co };
Out8<={In4[14],In4 }+{In12[14],In12 };

Out9<={In4[14],In4 }+{In12Co[14],In12Co };
Out10<={In5[14],In5 }+{In13[14],In13 };
Out11<={In5[14],In5 }+{In13Co[14],In13Co };
Out12<={In6[14],In6 }+{In14[14],In14 };
Out13<={In6[14],In6 }+{In14Co[14],In14Co };
Out14<={In7[14],In7 }+{In15[14],In15 };
Out15<={In7[14],In7 }+{In15Co[14],In15Co };
end
end
end
endmodule

相关帖子

沙发
AutoESL|  楼主 | 2011-10-19 22:51 | 只看该作者
当评估完系统的流水线时间余量后,发现整个流水线有 16 个时钟周期,而 FHT 模块的

频率很高,加法本身仅仅消耗 1 个时钟周期,加上数据的选择和分配所消耗时间,也能完全
满足频率要求,所以将单步 FHT 运算复用 4 次,就能大幅度节约所消耗的资源。这种复用单

步算法的 FHT 实现框图如图 1-2 所示,由输入选择寄存、单步 FHT 模块、输出选择寄存、计
数器构成。
   

代码如下:

//复用单步算法的 FHT 运算模块
module wch_fht(Clk,Reset,
PreFhtStar,
In0,In1,In2,In3,In4,In5,In6,In7,
In8,In9,In10,In11,In12,In13,In14,In15,
Out0,Out1,Out2,Out3,Out4,Out5,Out6,Out7,Out8,
Out9,Out10,Out11,Out12,Out13,Out14,Out15
);
input Clk; //设计的主时钟
input Reset; //异步复位信号
input PreFhtStar; //FHT 运算指示信号,和上级模块运算关联
input [11:0] In0,In1,In2,In3,In4,In5,In6,In7;
input [11:0] In8,In9,In10,In11,In12,In13,In14,In15; //FHT的 16 个输入
output [15:0] Out0,Out1,Out2,Out3,Out4,Out5,Out6,Out7;
output [15:0] Out8,Out9,Out10,Out11,Out12,Out13,Out14,Out15; //FHT的 16 个输出
//FHT 输出寄存信号
reg [15:0] Out0,Out1,Out2,Out3,Out4,Out5,Out6,Out7;
reg [15:0] Out8,Out9,Out10,Out11,Out12,Out13,Out14,Out15;
//FHT 的中间结果
wire [15:0] Temp0,Temp1,Temp2,Temp3,Temp4,Temp5,Temp6,Temp7;
wire [15:0] Temp8,Temp9,Temp10,Temp11,Temp12,Temp13,Temp14,Temp15;
//FHT 运算控制计数器,和前一级流水线模块配合
reg [2:0] Cnt3;//count from 0 to 4,when Reset Cnt3=7;
reg FhtEn;//Enable fht culculate
always @(posedge Clk or negedge Reset)
begin
if (!Reset)
Cnt3<= #1 3'b111;
else
begin

if(PreFhtStar)
Cnt3<= #1 3'b100;
else
Cnt3<= #1 Cnt3-1;
end
end
always @(posedge Clk or negedge Reset)
if (!Reset)
FhtEn<= #1 0;
else
begin
if (PreFhtStar)
FhtEn<= #1 1;
if (Cnt3==1)
FhtEn<= #1 0;
end
//补码运算,复制符号位
assign Temp0=(Cnt3==4)?{4{In0[11]},In0}:Out0;
assign Temp1=(Cnt3==4)?{4{In1[11]},In1}:Out1;
assign Temp2=(Cnt3==4)?{4{In2[11]},In2}:Out2;
assign Temp3=(Cnt3==4)?{4{In3[11]},In3}:Out3;
assign Temp4=(Cnt3==4)?{4{In4[11]},In4}:Out4;
assign Temp5=(Cnt3==4)?{4{In5[11]},In5}:Out5;
assign Temp6=(Cnt3==4)?{4{In6[11]},In6}:Out6;
assign Temp7=(Cnt3==4)?{4{In7[11]},In7}:Out7;
assign Temp8=(Cnt3==4)?{4{In8[11]},In8}:Out8;
assign Temp9=(Cnt3==4)?{4{In9[11]},In9}:Out9;
assign Temp10=(Cnt3==4)?{4{In10[11]},In10}:Out10;
assign Temp11=(Cnt3==4)?{4{In11[11]},In11}:Out11;
assign Temp12=(Cnt3==4)?{4{In12[11]},In12}:Out12;

assign Temp13=(Cnt3==4)?{4{In13[11]},In13}:Out13;
assign Temp14=(Cnt3==4)?{4{In14[11]},In14}:Out14;
assign Temp15=(Cnt3==4)?{4{In15[11]},In15}:Out15;
always @(posedge Clk or negedge Reset)
begin
if (!Reset)
begin
Out0<=0;Out1<=0;Out2<=0;Out3<=0;
Out4<=0;Out5<=0;Out6<=0;Out7<=0;
Out8<=0;Out9<=0;Out10<=0;Out11<=0;
Out12<=0;Out13<=0;Out14<=0;Out15<=0;
end
else
begin
if ((Cnt3<=4) && Cnt3>=0 && FhtEn)
begin
Out0[15:0]<= #1 Temp0[15:0]+Temp8[15:0];
Out1[15:0]<= #1 Temp0[15:0]-Temp8[15:0];
Out2[15:0]<= #1 Temp1[15:0]+Temp9[15:0];
Out3[15:0]<= #1 Temp1[15:0]-Temp9[15:0];
Out4[15:0]<= #1 Temp2[15:0]+Temp10[15:0];
Out5[15:0]<= #1 Temp2[15:0]-Temp10[15:0];
Out6[15:0]<= #1 Temp3[15:0]+Temp11[15:0];
Out7[15:0]<= #1 Temp3[15:0]-Temp11[15:0];
Out8[15:0]<= #1 Temp4[15:0]+Temp12[15:0];
Out9[15:0]<= #1 Temp4[15:0]-Temp12[15:0];
Out10[15:0]<= #1 Temp5[15:0]+Temp13[15:0];
Out11[15:0]<= #1 Temp5[15:0]-Temp13[15:0];
Out12[15:0]<= #1 Temp6[15:0]+Temp14[15:0];
Out13[15:0]<= #1 Temp6[15:0]-Temp14[15:0];

Out14[15:0]<= #1 Temp7[15:0]+Temp15[15:0];
Out15[15:0]<= #1 Temp7[15:0]-Temp15[15:0];
end
end
end
endmodule

为了便于对比两种实现方式的资源消耗,我在 Synplify Pro 对两种实现方法分别做了

综合。两次综合选用的参数都完全一致,器件类型为:Xilinx Virtex-E XCV100E -6 BG352,

出于仅仅考察设计所消耗的寄存器和逻辑资源,Enable“Disable I/O Insertion”选项,
不插入 IO,取 消 Synplify Pro中诸

使用特权

评论回复
板凳
AutoESL|  楼主 | 2011-10-19 22:51 | 只看该作者
地板
GoldSunMonkey| | 2011-10-19 22:51 | 只看该作者
。。。。太旧了。

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

个人签名:天使宝贝 博客IT人生 From C/C++/SystemC to Xilinx FPGA

0

主题

2517

帖子

3

粉丝