可编程逻辑设计原则

1.面积与速度互换原则

        面积指FPGA逻辑器件的逻辑资源。在逻辑器件资源有限,设计规模庞大的情况下,必须采用牺牲速度以减少资源消耗,节约面积。例如,减少实例化模块数量,分时复用模块。

        例如,用一个查找表ROM进行数制转换实验,对一组16进制数据转换为十进制数据时,可以分时复用一个查找表ROM:

module hex_doc0(
	
	input clk,
	input rst_n,
	input [7:0]hex0,//8位16进制数
	input [7:0]hex1,//8位16进制数
	input [7:0]hex2,//8位16进制数
	input [7:0]hex3,//8位16进制数

	output reg[7:0]dec0,//8位十进制数
	output reg[7:0]dec1,//8位十进制数
	output reg[7:0]dec2,//8位十进制数
	output reg[7:0]dec3 //8位十进制数
	
);
	
wire [7:0]hex;

wire [7:0]dec;//数据连线
reg  [2:0]cnt;//计数器


my_rom	my_rom_inst (
	.address ( hex ),
	.clock ( clk ),
	.q ( dec )
	);

always @(posedge clk,negedge rst_n)//计数器驱动
begin
	if(rst_n == 0)
		cnt <= 3'd0;
	else
		begin
			cnt <= cnt + 3'd1;
				if(cnt >= 3'd6)//这里只调用一个数制转换模块
	//输入4组16进制数据(同时),输出也需要控制使得同时输出
	//故在第三个时钟周期进行数据依次寄存输出
						cnt <= 3'd0;
		end
end

assign hex = ( cnt == 3'd0 ) ? 8'b0 :
		     ( cnt == 3'd1 ) ? hex0 ://选择输入接口
		     ( cnt == 3'd2 ) ? hex1 ://cnt = 3'd0时选择hex0......
			 ( cnt == 3'd3 ) ? hex2 : hex3;

always @(posedge clk)//寄存模块输出数据
begin
	if(cnt == 3'd2)
		begin
			dec0 <= dec;
		end
end

always @(posedge clk)//寄存模块输出数据
begin
	if(cnt == 3'd3)
		begin
			dec1 <= dec;
		end
end

always @(posedge clk)//寄存模块输出数据
begin
	if(cnt == 3'd4)
		begin
			dec2 <= dec;
		end
end

always @(posedge clk)//寄存模块输出数据
begin
	if(cnt == 3'd5)
		begin
			dec3 <= dec;
		end
end

endmodule

以上是用一个查找表ROM模块在7个周期内实现4组十六进制数转换为十进制数的程序,下面是在4个周期内实现4组十六进制数转换为十进制数的程序。

module hex_doc1(
	
	input clk,
	input rst_n,
	input [7:0]hex0,//8位16进制数
	input [7:0]hex1,//8位16进制数
	input [7:0]hex2,//8位16进制数
	input [7:0]hex3,//8位16进制数

	output reg[7:0]dec0,//8位十进制数
	output reg[7:0]dec1,//8位十进制数
	output reg[7:0]dec2,//8位十进制数
	output reg[7:0]dec3 //8位十进制数
	
);
	
wire [7:0]dec_0;//数据连线
wire [7:0]dec_1;//数据连线
wire [7:0]dec_2;//数据连线
wire [7:0]dec_3;//数据连线

reg  [2:0]cnt;//计数器


my_rom	my_rom_inst (
	.address ( hex0 ),
	.clock ( clk ),
	.q ( dec_0 )
	);

my_rom	my_rom_inst (
	.address ( hex1 ),
	.clock ( clk ),
	.q ( dec_1 )
	);
	
my_rom	my_rom_inst (
	.address ( hex2 ),
	.clock ( clk ),
	.q ( dec_2 )
	);
	
my_rom	my_rom_inst (
	.address ( hex3 ),
	.clock ( clk ),
	.q ( dec_3 )
	);
	
always @(posedge clk,negedge rst_n)//计数器驱动
begin
	if(rst_n == 0)
		cnt <= 3'd0;
	else
		begin
			cnt <= cnt + 3'd1;
				if(cnt >= 3'd2)//这里只调用一个数制转换模块
	//输入4组16进制数据(同时),输出也需要控制使得同时输出
	//故在第三个时钟周期进行数据依次寄存输出
						cnt <= 3'd0;
		end
end


always @(posedge clk)
begin
	if(cnt == 3'd2)
		begin
			dec0 <= dec_0;
		end
end

always @(posedge clk)
begin
	if(cnt == 3'd2)
		begin
			dec1 <= dec_1;
		end
end

always @(posedge clk)
begin
	if(cnt == 3'd2)
		begin
			dec2 <= dec_2;
		end
end

always @(posedge clk)
begin
	if(cnt == 3'd2)
		begin
			dec3 <= dec_3;
		end
end

endmodule

        对比上面两个程序可以看出,分时复用一个登找表ROM 模块,需要7个向期米元叹 4组数据转换,而同时实例化4个查找表ROM 模块来并行转换,只需要 4个周期来完成 4组数据转换,相当于速度提高了约40%,但是逻辑资源多耗费了3倍。在资源充足的情况下,可采用并行实例化的设计;如果资源紧张,就只能采取降低速度来换取面积的做法。

2.数字电路硬件原则

        可编程逻辑设计与软件的高级语言开发有着本质的区别。软件工程师进行高级语言开发时不必关心硬件的具体细节,只关心一段程序实现的结果,而且不在乎也不好把握每条语句执行的时间周期。数字电路硬件原则是指开发人员进行可编程逻辑设计时要保持硬件思维。首先,开发人员必须对数字电路有深刻的认识,特别是组合逻辑电路和时序逻辑电路。其次,开发人员必须了解数字电路的工作过程,如组合逻辑电路按电流速度工作,时序逻辑电路按时钟周期工作。下面以Verilog HDL编程与C语言编程为例说明两者的区别。

        1.语句执行顺序的区别

        在Verilog HDL编程中,对于时序逻辑要注意语句的执行顺序。例如:

always @ (posedge clk)
begin
    c<= l'h0;
    c<= c+ 1'h1;
    a <= Ci
    b<= ai
end

        如果c在上一周期的值是1,那么它在当前周期的值是2,而不是1,因为寄存器在同一周期内,Verilog HDL以always赋值语句的最后一条作为该周期的赋值语句,这条语句之前的语句都无效;而C语言程序是顺序执行的,先把0赋予c,再把c+1赋予c,最终结果就是1。

        2. 语句执行周期的区别

        对于上述程序中的变量a和b,在经过当前这个周期之后,它们的值等于上一周期的e和a的值,而不是c和a实时的值,这就是可编程逻辑的时序特性。开发人员从事可编程逻辑设计时,必须谨记时序的概念。

        3. 变量类型的区别

        可编程逻辑中主要有两种类型的变量:寄存器 reg和信号线 wire。其中,寄存器变量是按照时钟周期工作的,所以只能用非阻塞赋值方式赋值,即<=,而且寄存器变量只能在连续赋值语句中赋值,即always@0;信号线变量只能用阻塞赋值方式赋值,即=,而且不能同时用多个阻塞赋值语句赋值。

3.系统设计原则

        系统设计原则是指在充分了解器件资源之后,对模块功能进行正确划分。特别是在设计规模较大、器件资源复杂的情况下,如集成CPU的SoC FPGA芯片,要正确分配在FPGA和CPU中实现的算法。对于FPGA中资源的使用要注意以下几点。

        1.存储器资源的使用

        存储器资源的使用原则是根据设计中用到的RAM的宽度和深度,确定所选器件的入式RAM的容量。嵌入式RAM的具体配置由Quartus软件自动分配,用户只需要确保片上RAM资源大于设计中的RAM需求。

        2.软核的使用

        核是指用FPGA的逻辑资源生成的一个软IP核,它可以定制功能,同时要消耗大的逻辑资源。使用软核的好处是不需要外部CPU就能在FPGA中实现大量复杂的计算功能,而且能与FPGA内部逻辑无缝连接,传输速率和运行效率高。缺点是在资源有限的器件中,软核会占用其他逻辑功能模块的资源。所以在设计之前,必须确定计算量大的功能模块是使用软核、硬核还是外部协处理器。

        3. 串行收发器的使用

        由于目前高速通信的需要,高端FPGA器件都集成了高速串行收发器SERDES。其中,发送串口用于把数据和时钟调制到模拟差分信号线上,接收串口用于恢复数据和时钟。目前最快的SERDES 可以达到几Gbit/s到几十Gbit/s的传输速率。SERDES可用来实现千兆网传输,也可用来实现PCIe和SPI4.2等高速接口。采用串行收发器可以节约板级布线资源。

        4.其他结构的使用

        其他结构主要是指可编程PLL或者DLL时钟资源,通常采用片上自带的PLL来做时钟驱动,分频或者倍频有利于增强系统的稳定性和改善最高工作频率。

4.同步设计原则

时序电路通常分为同步时序电路和异步时序电路。

         1. 同步时序电路的特点

        (1)电路核心为各种触发器。

        (2)电路输入和输出信号都由时钟沿触发。

        (3)可避免电路信号产生毛刺现象。

        (4)有利于程序在器件间移植。

        (5)有利于静态时序分析。

        2. 异步时序电路的特点

        (1)电路核心为组合逻辑门电路。

        (2)电路输入和输出信号与时钟沿不同步。

        (3)电路信号容易产生毛刺现象。

        (4)不利于程序在器件间移植,或者移植后参数不一样导致结果不一样。

        (5)不利于静态时序分析。

在FPGA设计中,通常优先采用同步时序设计。在同步时序设计中,需要注意以下事项。

        (1)两个基本时序原则:setup time原则和hold time原则。setup time是指时钟沿到来前数据已经准备好的时间,hold time是指时钟沿离去后数据保持的时间。这两个时间都满足相应条件才能保证数据被正确采样保存。

        (2)异步时钟域数据传输。

        (3)组合逻辑常用设计方式。

        (4)同步时序逻辑的时钟设计。

        (5)同步时序电路信号的延迟,即需要把信号延迟一定时间再送往下一级寄存器,短时间延迟用寄存器级联,长时间延迟用计数器。

        (6)关于reg变量是否被综合成实际寄存器的问题。Verilog中定义了两种类型的变量:reg和wire,reg指寄存器,wire指组合逻辑的信号线。一般情况下,将reg变量放到always@0中会被综合成寄存器。但是,如果always@)的括号里面的敏感信号不是时钟沿,而是其他信号的高低电平,而且always@()中不采用非阻塞赋值,则会把该reg变量综合成组合逻辑的一个信号线变量,没有数据寄存功能。所以要想把reg变量综合成实际的寄存器,必须使always@()的敏感信号为时钟沿,而且always@()中要采用非阻塞赋值。

参考资料

FPGA进阶开发与实践

  • 13
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

张明阳.

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值