找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 2752|回复: 2
打印 上一主题 下一主题
收起左侧

Verilog语法学习(一)

[复制链接]
跳转到指定楼层
楼主
ID:51024 发表于 2014-7-30 14:39 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
Verilog并不难,只要有一点的C语言基础,你就可以开始学习它,进而不断深入的学习FPGA。和C语言以main函数一样,Verilog以模块为主体,看下面一个小小的例子:module my_first(
sys_clk,
rst_n,
data_ina,
data_inb,
data_out
);
// 端口说明
input sys_clk;
input rst_n;
input [7:0] data_ina;
input      [7:0] data_inb
output [8:0] data_out;
// 功能操作
assign data_out = data_ina + data_inb;

endmodule




整个模块就是以 module   模块名 和 endmodule组成,这样就算编写了一个简单的模块了。它主要包括:
  • 模块的输入(input)和输出(output)端口声明:简单的说就是这个模块对外部的相应输入做处理后输出处理后的结果.上面的例子就是对2个8位宽的数据做加法后在data_out端口输出结果。
  • 模块的功能:主要有3中方法可以用:a.数据流级操作,属于组合逻辑,例如例子中的 assigndata_out =data_ina + data_inb;只要模块执行,就不断地对数据data_ina和data_inb进行加法操作并赋给data_out输出;b.门级操作,属于组合逻辑如:c= a & b;它就是一个2输入的与门,对输入数据做与门计算后输出;c.行为级操作,这个用的最多,属于时序逻辑,如:always @(触发的条件) 执行操作,简单的说就是锁存器或者触发器的模型。当触发的条件是电平触发时,即锁存器模型,只要相应的电平改变了就会执行后面需要执行的操作一次;而当触发条件是边沿触发时,即触发器模型,只要用对应的边沿产生就执行后面的操作一次。这里有一个重要的概念需要弄明白,组合逻辑是,输入一旦改变,相应输出就改变;而时序逻辑是输入改变了,需等触发条件的到来才相应的改变一次。但是它们的执行是并行的,所有级都是同时执行,这和C语言是不同的,初学者一定要弄明白。
  • 功能的操作语法:不仅和C语言很相似,而且都是C语言里面常用的一些语法,常用的语法有:             if( ),if( )  else( ),if( ) elseif( ) else,case( ),至于它和C语言的用法有什么不同,下次将详细的讲解。


分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏 分享淘帖 顶 踩
回复

使用道具 举报

沙发
ID:51024 发表于 2014-7-30 14:40 | 只看该作者
Verilog的数据类型常用的是:reg和wire型。当我们对端口申明了时,此时默认的类型是wire型。
reg型是寄存器类型,也就是再用锁存器和触发器时必须声明为此类型才合法,否则就不合法,这也是我们经常对一个输出定义时大多需要定义为reg的原因。当然,当我们的输出由组合逻辑获得时,就不需声明了,因为默认就是wire型而不用再申明了。wire类型就是连线类型,一般作为输出级表达式右侧的参数适用。例
module  test(
sys_clk,
rst_n,
data_in,
data_outa,
data_outb
);
input    data_in;
output  data_outa;
output  reg  data_outb;

assign data_outa = data_in;

always @(posedge sys_clk)
begin
if(rst_n == 1'b0)
data_outb <= 1'b0;
else
data_outb <= data_outa;
end
endmodule

这个例子中的data_outa是默认的wire类型,它是对的,因为assign   data_outa = data_in;是组合逻辑语句,不需要用寄存器保存其值;而data_outa是时序逻辑,需要寄存器保存现在的值,只有当触发条件到来时才更新寄存器中的值,所以定义为reg型,同时它的值可有wire类型的data_outa来决定,也就是一个组合逻辑的输出作为时序的输入,这是合法的。下次将从硬件描述语言的角度来看看 if和case语句的理解和运用。
回复

使用道具 举报

板凳
ID:51024 发表于 2014-7-30 14:40 | 只看该作者
本帖最后由 wangyin 于 2014-7-30 14:42 编辑

顺序执行语句:if(条件语句)  执行的语句;即在程序执行过程中是顺序执行的,按上下顺序依次执行。当执行的语句是一句语句,则不需加 begin   end,否则就要加begin     end,这里的begin end相当于C语言里面的{ },同时注意:一般一个if需与一个else配对,如果没有的话则综合的时候会生成一个隐性的锁存器,当有多个条件需要判断时则用if(条件语句)  执行的语句;else if(条件语句)  执行的语句;.....else(条件语句)  执行的语句道理同上面一样,但if分支一般最多不超过3个,如果太多的话则采用case语句实现。
并行执行语句:case(条件语句)  满足的条件:执行的语句......; endcase 即在程序执行过程中是并行执行的,满足条件的语句同时执行。begin end的用法同上面的一样,也需注意:当有缺项没有作为条件使用时,同样需要加default项,否则也会生成隐性的锁存器,case语句主要用在状态机的编写中。看下面的2个例子:
用if语句实现的一个选择器:
module  mux(
a,
b,
sel,
out
);

input a;
input b;
input sel;
output out;
reg out;

always (sel)
begin
if(sel)
out <= a; // sel=1时,out=a
else
out <= b; // sel=0时,out=b
end
endmodule
用case语句实现的一个3-8译码器:
module yima(
data_in,
data_out,
);
input [2:0] data_in;
output [7:0] data_out;
reg [7:0] data_out;


always @(data_in)
begin
case(data_in)
3'd0: data_out <= 8'b0000_0001;
3'd1: data_out <= 8'b0000_0010;
3'd2: data_out <= 8'b0000_0100;
3'd3: data_out <= 8'b0000_1000;
3'd4: data_out <= 8'b0001_0000;
3'd5: data_out <= 8'b0010_0000;
3'd6: data_out <= 8'b0100_0000;
3'd7: data_out <= 8'b1000_0000;
endcase
end



endmodule
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表