玩FPGA的人大多数都知道原语,但很多初学者并不是很了解但有调用过,会有一种疑问,它和IP有什么区别?下面就讲解一下区别,以及如何自定义一个原语
原语和IP是FPGA中的两个重要概念。
- 原语:原语是指FPGA中用于实现特定硬件操作的基本单元,通常由多个逻辑门和触发器组成。原语可以由硬件设计者根据特定应用需求进行设计和优化,以实现高性能、低功耗的硬件电路。在FPGA中,原语可以用来实现各种硬件操作,例如算术运算、逻辑运算、数据存储和传输等。
- IP:IP(Intellectual Property)是指FPGA中预先设计好的、可重复使用的硬件模块。这些模块通常由FPGA厂商提供,并经过优化和测试,以确保其性能和稳定性。IP可以包括各种不同的功能模块,例如串口通信、DDR内存控制器、PCIe接口控制器等。使用IP可以加速硬件设计的速度,减少开发和验证的时间和资源,并提高设计的可靠性和稳定性。
总的来说,原语和IP都是FPGA中的硬件模块,但它们的使用方式和目的略有不同。原语主要用于设计和优化特定的硬件电路,以满足特定应用的需求;而IP则主要用于加速硬件设计的速度和减少开发和验证的资源和时间。在实际应用中,硬件设计者可以根据需要选择使用原语或IP来实现特定的硬件功能。
UDP(User-Defined Primitive)
在这里的UDP就不是协议了,自定义原语的一种表达方式的缩写。嗯~,相信很多人会想这说我们为什么要去自定原语,直接调用不就好了吗!
确实这样省时又方便,但有的人面向的是设计,他们需要面对嵌入式等高性能数据开发必须要取了解并且编写更改,就相当于自带原语编写者的工作一样。
使用用户自定义原语与FPGA自带原语的利弊区别如下:
- 灵活性和效率:使用用户自定义原语(UDP)可以根据特定应用需求来设计和优化硬件电路,从而在灵活性和效率上具有优势。UDP允许用户在HDL代码中直接使用硬件操作,这使得硬件设计者可以更直接地控制硬件行为,并可以根据需要自由地优化和定制硬件电路。
- 易用性和可维护性:使用FPGA自带的原语(IP核)可以简化开发流程,因为IP核是经过优化和预先测试的,而且通常具有更高的可靠性和稳定性。此外,IP核的使用可以减少开发时间和错误,并且通常具有更好的可维护性。
- 成本和资源:使用UDP需要更多的时间和资源来设计和验证硬件电路,这可能导致更高的开发成本。相比之下,使用FPGA自带的IP核可能更快地完成设计和验证过程,并且通常需要更少的资源。
- 适用范围:UDP适用于需要定制和优化硬件电路的应用场景,例如高性能计算、信号处理和嵌入式系统等。而IP核则适用于需要快速开发和可靠运行的应用场景,例如通信、数据转换和接口控制等。
综上所述,用户自定义原语和FPGA自带原语各有其利弊,选择使用哪种方式取决于具体的应用需求和开发团队的偏好。在需要灵活性和效率的情况下,UDF可能更合适;而在需要快速可靠的开发和降低成本的情况下,使用IP核可能更有优势。
好了,废话不多说,开始实用。
首先了解一下UDP的基础组合部分有哪些
primitive project_name(output_name,input_name1,input_name2);//第一个必须是输出
input input_name1;//输入端口1,可以有多个输入端口,但只能是一位宽
input input_name2;//输入端口2,输入端口数量最好在10个以内,不然工作量就很大,因为真值表的结果是指数型增长的
output output_name;//输出端口,只能有一个输出端口并且只能是一位宽
table
//真值表,自己定义所想要的结果即可,下面只是一个小举例
//input_name1 input_name2 : output_name
1 1 : 0
endtable
endprimitive
注意几点:第一个必须是输出!
输入端口可以多,但只能是一位宽!
输出端口只能是一个,并且一位宽 !
建议输入端口在10个以内(最好5个以内),因为真值表的数据是指数型增长,会占用很大的运算和存储。
其次举个栗子
举一个“与(and)”逻辑的例子,组合逻辑的例子。
primitive AND(c,b,a);
input a,b;
output c;
table
// a b : c
0 0 : 0;
0 1 : 0;
1 0 : 0;
1 1 : 1;
endtable
endprimitive
仿真
后面的例子的仿真代码,自己写一下哈,我就偷个懒
module tb_2( );
reg a, b;
wire c;
initial begin
#5 a = 0;b = 0; $display("a = %b, b = %b", a, b);
#5 $display("c = %b", c);
#5 a = 1;b = 1; $display("a = %b, b = %b", a, b);
#5 $display("c = %b", c);
#5 a = 1;b = 0; $display("a = %b, b = %b", a, b);
#5 $display("c = %b", c);
#5 a = 1;b = 1; $display("a = %b, b = %b", a, b);
#5 $display("c = %b", c);
#5 a = 0;b = 1; $display("a = %b, b = %b", a, b);
#5 $display("c = %b", c);
end
AND and_inst(c, a, b);
endmodule
TCL显示
波形显示
举个时序逻辑的例子,电平敏感触发
primitive clk_latch(out,data,clk,rst_n);
output reg out;
input data;
input clk;
input rst_n;
initial out = 0; //赋个初值
table
//data clk rst_n: out : out+;
? ? 1 : ? : 0;//清零,out+新的输出值
//clk = 1时将data值锁存到q中
1 1 0 : ? :1;//将data的数值1所存到out中
0 1 0 : ? : 0;//将data的数值0所存到out中
? 0 0 : ? : -;//当clk=0时保持不变
endtable
endprimitive
?表示不会影响下一个状态的输出
举个时序逻辑的例子,边沿敏感触发。
带清零的时钟下降沿触发的D触发器
primitive clk_neged(out,data,clk,rst_n);
output reg out;
input data;
input clk;
input rst_n;
initial out = 0; //赋个初值
table
// data clk rst_n : out : out+;
? ? 1 : ? : 0 ;//清零
? ? (10) : ? : - ;//忽略 rst_n 的负跳变沿
1 (10) 0 : ? : 1 ;//在clk的下降沿锁存数据
0 (10) 0 : ? : 0 ;
? (1x) 0 : ? : - ;// clk变化到不定状态时,out保持不变
? (0?) 0 : ? : - ;//忽略 clk 的正跳变
? (x1) 0 : ? : - ;//忽略 clk 的正跳变
(??) ? 0 : ? : - ;//clk不变时,忽略data的变化
endtable
endprimitive
符号含义入下:
(10)表示从逻辑1到逻辑0的负跳变沿;
(1x) 表示从逻辑1到不确定状态x的跳变;
(0?)表示从逻辑0到0, 1或x的跳变,这里隐含正跳变沿;
(??)表示信号值从0. 1或x,到0, 1或x的任意跳变。
缩写 | 符义 | 解释 |
? | 0,1,x | 不能用于输出部分 |
b | 0,1 | 不能用于输出部分 |
- | 维持原值不变 | 只能用在时序 UDP 的輸出部分 |
r | (01) | 信号的上升沿 |
f | (10) | 信号的下降沿 |
p | (01), (0x)或(x1) | 可能是信号的上升沿 |
n | (10), (1x)或(x0) | 可能是信号的下降沿 |
* | (??) | 信号值的任意变化 |
建议
在设计功能模块时,决定使用module还是用户自定义原语(UDP)来建模是一个重要的决策。以下是一些指导原则,可以帮助你在两者之间进行选择:
- 复杂性和可重用性:如果功能模块比较复杂,或者需要多次在不同的项目中使用,那么使用module可能更合适。Module可以提供更好的封装和抽象,使得代码更易于理解和维护。此外,module还支持参数化,可以使用户更容易地复用代码。
- 性能优化:如果功能模块对性能要求很高,或者需要进行定制化的优化,那么使用UDP可能更合适。UDP允许用户直接控制硬件行为,可以根据特定应用的需求进行优化,从而提高性能。
- 硬件资源:如果硬件资源有限,或者需要尽可能减少资源占用,那么使用module可能更合适。Module通常比UDP更节省资源,因为它们是预先编译和优化过的。
- 开发时间和经验:如果开发时间紧迫,或者开发人员缺乏硬件设计经验,那么使用module可能更合适。Module可以提供更高级别的抽象和易用性,使得开发人员能够更快地开发和调试代码。
- 社区支持和维护:如果功能模块需要与开源社区共享或维护,或者需要获得更广泛的支持,那么使用module可能更合适。Module通常比UDP更容易被社区接受和维护。
综上所述,选择使用module还是UDP取决于特定应用的需求和约束。在决定使用哪种方式时,需要考虑功能模块的复杂性、可重用性、性能要求、硬件资源、开发时间、经验以及社区支持和维护等因素。
动动你的小手手一键三连,点个赞,收藏,关注。后续会发更多作品哦(有时间的话)。