FPGA的一些基本概念
1、建模是建立模块的缩写。
2、建模之汤
FPGA亦是模块的生命之汤,里面充满着形形色色的资源。FPGA中一些常见的资源有寄存器资源、组合逻辑资源、内存资源、硬件资源、引脚资源。如下图所示:
在上述的FPGA资源中,硬件资源中最常用的资源有PLL和乘法器最常见。一般,我们可以经由IP程序生成它们。引脚资源是最为珍贵的建模资源,但是这些是硬件工程师的事情,不关描述语言的事。
3、解读模块一直是心中的痛,尤其是解读别人写的模块,那简直是生不如死。因为五花八门的内容,一瞬间就可以把活人变成死人。所以为了让别人能轻松看懂你写的代码,下面就做了一些代码规范。如下表所示:
信号类 | 说明 | 例子 | 顶层类 | 实际连接引脚的信号 | CLOCK,RESET | 基本类 | 模块依赖的基础信号 | Clock,Reset | 沟通类 | 沟通作用的信号 | Call,Done,En,Trig | 数据类 | 数据作用的信号 | Addr,Data | 标签类 | 标签作用的信号 | Tag | 下面对上述信号进行解释说明:
顶层信号:就是连接引脚的信号,一般用大写字母来表示。eg:input CLOCK,RESET;
output [3:0]LED;
基本类信号:就是模块依赖的信号。常与顶层类信号搞混。
沟通类信号:就是模块之间的沟通连线。沟通类信号可分为3种方式,亦即触发式沟通、使能式沟通、问答式沟通。如下图所示:
从上图中,可以看到:沟通使能信号相对控制模块是输出信号,所以对控制模块来说,定义的信号是oen;沟通使能信号相对功能模块是输入信号,所以对功能模块来说,定义的信号是ien;
下面对沟通类信号的3种信号进行简单介绍:
1、触发式沟通
触发的意义就像扣下扳机让子弹飞。模块在沟通时偶尔需要扣下扳机,例如中断请求。下图中的Trig信号就是触发沟通类信号。
2、使能式沟通
使能的意义就犹如扣下扳机就连射几发子弹。下图就是使能式沟通信号:
3、问答式沟通
问答式沟通犹如扣下扳机之后直至子弹射完为止。下图就是问答式沟通信号。
数据类信号:数据信号似乎只有地址数据Addr,和读写数据Data,所以定义的信号有oAddr/oData;iAddr/iData;
标签类信号:亦是标志信号也是反馈信号,例如FIFO的饱满标志。将某模块的输出信号反馈给其它模块。
4、模块的操作方法
顺序操作、并行操作、即时操作(描述语言的即时操作主要由组合逻辑引起的)。
5、理想时序
理想时序就是可以按照一个时钟一个时钟去处理。
物理时序就是时序存在物理延迟导致信号失去对齐性。
理想时序拥有对齐性的信号。
6、流水操作
流水操作是有步骤性的并行操作。下面举个流水线操作的例子。
module pipeline(
CLOCK,
iData,
oData
);
input CLOCK;
input [7:0]iData;
output [7:0]oData;
reg [7:0]D1,D2,D3,D4;
always @(posedge CLOCK)
begin
D1<=iData+1'b1;
D2<= D1+1'b1;
D3<= D2+1'b1;
D4<= D3+1'b1;
end
assign oData=D4;
endmodule
上图是数据的整个操作流程。在流水操作的时序特征很容易辨认出来,它有明显的潜伏期Latency。潜伏期就是输入距离输出之前的空档时间,潜伏期的长度则是根据流水操作的步骤而定的。在上面的例子中Latency=4.注意,流水操作只有在处理数据流的时候才能凸显其优势。
7、模块的布局
(1)模块声明
(2)端口声明
(3)实例化声明
(4)常量声明
(5)周边操作
(6)核心操作
(7)输出驱动声明
module led( //模块声明
CLOCK, //端口声明
RESET,
LED
);
input CLOCK;
input RESET;
output [3:0]LED;
//实例声明
parameter T100MS=10'd1000; //常量声明
reg [9:0]C1; //周边操作
always @(posedge CLOCK)
begin
if(C1==T100MS)
C1<=10'd0;
else C1<=C1+1'b1;
end
reg [3:0]i,D1; //核心操作
always @(posedge CLOCK)
begin
case(i)
0:
1:
endcase
end
//核心操作扩展
assign LED=D1; //输出驱动声明
endmodule
核心操作一般以“指令式仿顺序”进行书写,“指令式仿顺序”具体指什么,在后面的章节中,我会单独拿出一章详细讲解。一般,一个稍微复杂的模块还要进行核心操作的扩展。这种感觉就像一根链条可以无限扩展下去,如果看哪段操作不顺眼了,就可以直接删除掉或者换掉,而且不需要破坏其它内容,是很方面的。
module led(
output reg [3:0]LED
);
......
endmodule
在上面的代码中,是输出驱动声明,尽管这是一个事实。但在上面的代码中LED端口被名为LED的寄存器驱动,虽然这样写语**确,不过总有一种说不出的违和感,这种感觉就像屁股戴在头上一样奇怪,可又不能取笑它一样难受。一般,这样写:reg [3:0]LED_r; assign LED=LED_r;
由于篇幅有限,FPGA——概念篇(1)就写到这,下面关于建模的概念还会继续介绍。请继续查看FPGA——概念篇(2).
|