赞
踩
本篇文章介绍了FPGA平台的使用语言的基本语法,并用一个3-8译码器模块的实例引导嵌入式工程师熟悉FPGA开发的一般流程。FPGA的嵌入式程序最终都会映射成数字逻辑电路,在开发的过程中要保持对实际生成电路的敏感,功能做对的基础上还要考虑时序优化,更别提纷繁复杂的接口协议实现。
本篇文章只是从语言的角度做了一些简单介绍,帮助基于其他平台开发的嵌入式工程师FPGA平台开发有一个大概的认识,能够跟FPGA工程师更顺畅的沟通。
Verilog HDL是一种硬件描述语言(HDL:Hardware Description Language),以文本形式来描述数字系统硬件的结构和行为的语言,用它可以表示逻辑电路图、逻辑表达式,还可以表示数字逻辑系统所完成的逻辑功能。
FPGA的开发以模块的为基础设计,模块的概念类似于C语言中的函数,提供输入,输出端口,能被其他模块实例调用,也可以调用其他模块实例。顶层模块常被称为“测试平台”(Testbench)。下面是语言的基本组成:
Verilog所用的所有变量都属于两个基本类型,线网类型和寄存器类型。线网只能通过连续赋值,由赋值符右侧连接的驱动源决定。寄存器的值可以保持当前的赋值。模块的输入端口可以与外界的线网或寄存器类型的变量连接,但是这个模块输出端口只能连接到外界的线网。下面是不同变量的表示形式。
寄存器变量在过程中赋值。在Verilog中,有两种赋值运算,一种叫做阻塞赋值,其运算符为=,另一种叫做非阻塞赋值,其运算符为<=。在顺序代码块中使用非阻塞赋值,则执行这这一句的同时。线网变量的连续赋值如下:assign #5 out = in1 & in2; //in1和in2逻辑与的结果在5个时间周期后才施加在out上。
事件时序控制的意思是,如果指定的事件发生,则代码被触发执行。他的关键字为@。
z = @(negedge clk) (x+y); //先立即计算表达式(x+y),然后在变量clk下降沿,将表达式的结果赋值给z。经典用法1:一旦某一变量发生变化,就执行某操作always @(a)begin x = x+1;end。
电平敏感时序控制:wait(a),当变量a为真,则执行后面的代码块。
FPGA的过程的时序控制可以通过三种方式实现:延迟时序控制、事件时序控制以及电平敏感时序控制。所有的系统任务名称前都带有美元符号$使之与用户定义的任务和函数相区分。常用的编译指令有文本宏预定义define、
include。
begin、end组合代表了这个代码块的各行代码是顺序执行的,这种代码块称为顺序代码块。逻辑综合的含义是将高抽象级别的Verilog代码转化为低抽象级别的逻辑门级电路。自动化逻辑综合工具的出现,硬件描述语言,所需器件工艺信息(工艺库)可以直接被逻辑综合工具读取,通过其内部的自动综合算法,输出符合设计约束的逻辑门级网表。
FPGA代码需要进行层次化管理。
综合的依据是逻辑设计的描述和各种约束条件,综合的结果则是一个硬件电路的实现方案。
选择芯片和设计的时候要预留一定的逻辑资源余量,以便加入测试部分等。而这也是硬件设计区别于软件设计的一个重要特性。
常见的FPGA芯片厂商有Xilinx(赛灵思);Altera公司(阿尔特拉)。开发步骤:
FPGA练手小实例:
下面是一个3-8译码器modul的实现代码,功能是根据a,b,c三个输入信号来获得一个8位状态寄存器:
module decoder_38(a,b,c,out); input a,b,c; //输入端口 output reg [7:0]out; //高位在前,低位在后,共8位 always@(a,b,c)begin //敏感列表,当a,b,c中的一个发生变化就执行begin后面的语句。 case({a,b,c}) //花括号将a,b,c拼接成一个信号 3'b000:out = 8'b0000_0001; //always中的赋值必须是reg形式 3'b001:out = 8'b0000_0010; 3'b010:out = 8'b0000_0100; 3'b011:out = 8'b0000_1000; 3'b100:out = 8'b0001_0000; 3'b101:out = 8'b0010_0000; 3'b110:out = 8'b0100_0000; //3'b111:out = 8'b1000_0000; default:out = 8'b1000_0000; endcase end endmodule
下面是针对这个模块的测试文件(testbench),模拟三个输入信号并获得out输出:
`timescale 1ns/1ps module decoder_38_tb(); reg signal_a, signal_b, signal_c; wire [7:0]out; decoder_38 decoder1( .a(signal_a), .b(signal_b), .c(signal_c), .out(out) ); initial begin signal_a = 0; signal_b = 0; signal_c = 0; #200; signal_a = 0; signal_b = 0; signal_c = 1; #200; signal_a = 0; signal_b = 1; signal_c = 0; #200; signal_a = 0; signal_b = 1; signal_c = 1; #200; signal_a = 1; signal_b = 0; signal_c = 0; #200; signal_a = 1; signal_b = 0; signal_c = 1; #200; signal_a = 1; signal_b = 1; signal_c = 0; #200; signal_a = 1; signal_b = 1; signal_c = 1; #200; $stop; end endmodule
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。