Verilog硬件编程基础语法笔记

Verilog笔记

assign:

assign 相当于连线,一般是将一个变量的值不间断地赋值给另一个变量,就像把这两个变量连在一起,所以习惯性的当做连线用,比如把一个模块的输出给另一个模块当输入。

wire型变量赋值,wire 是线网,相当于实际的连接线,如果要用assign直接连接,就用wire型变量。wire型变量的值随时变化。

(1)在Verilog module中的所有过程块(如initial块和always块)、连续赋值语句(如assign语句)和实例引用都是并行的。在同一module中这三者出现的先后顺序没有关系

(2)只有连续赋值语句assign实例引用语句可以独立于过程块而存在于module的功能定义部分。

(3)连续赋值assign语句独立于过程块,所以不能在always过程块中使用assign语句。只有连续赋值语句assign实例引用语句可以独立于过程块而存在于模块的功能定义部分

通过连续赋值语句描述3位加法器

module  adder ( count,sum,a,b,cin );
input [2:0] a,b;
input   cin;
output  count;
output [2:0] sum;
      assign {count,sum} = a + b + cin;
endmodule

通过连续赋值语句描述一个比较器

module compare ( equal,a,b );
output  equal;    //声明输出信号equal
input [1:0] a,b;  //声明输入信号a,b
  assign  equal =(a = = b)?1:0;
/*如果a、b 两个输入信号相等,输出为1。否则为0*/
endmodule

//版本2
module compare_2 ( equal,a,b );
output  equal;    //声明输出信号equal
input [1:0] a,b;  //声明输入信号a,b
reg equal;//

  always @(a,b)
    if(a==b)
      equal=1;
    else
      equal=0;
/*如果a、b 两个输入信号相等,输出为1。否则为0*/
endmodule


//版本3
module compare_3 ( equal,a,b );
output  equal;    //声明输出信号equal
input [1:0] a,b;  //声明输入信号a,b
reg equal;//

  always @(a,b)
  begin   //
    if(a==b)
      equal=1;
    else
      equal=0;
  end     //
assign  equal =(a = = b)?1:0;
/*如果a、b 两个输入信号相等,输出为1。否则为0*/
endmodule




always:

always @(a)表示如果a有变化就执行下面的语句

always @(sl or a or b)表示只要slab,其中若有一个变化时就执行下面的语句

Verilog程序包括4个主要部分:

  • 端口定义
  • I/O说明
  • 内部信号声明
  • 功能定义

I/O说明的格式:

  • 输入口 input[范围];
  • 输出口 output [范围];
  • 输入/输出口 inout [范围];
  • I/O说明也可以写在端口声明里。

内部信号说明:

  • reg[范围] 变量1,变量2…;
  • wire[范围] 变量1,变量2…;

模块中实现逻辑功能的3种方法:

(1)assign: assign c=a&b;

(2)用实例元件 :and #2 u1(q,a,b);

(3)用always

  • assign语句是描述组合逻辑最常用的方法之一。
  • always块既可用于描述时序逻辑,又可用于组合逻辑。

D触发器:

module new_dff(q,clk,d);
    input clk,d;
    output q;
    reg q;

    always @(posedge clk)
        q<=d;
endmodule

D触发器(带异步清除端)

module new_dff2(q,clk,d,clr);
input clk,d,clr;
output q;
reg q;

  always @(posedge clk or  posedge clr)
  begin
    if(clr)
      q<=0;
    else
      q<=d;
  end
endmodule

D触发器(带异步清除端和使能端)

module new_dff3(q,clk,d,clr,en);
output q;
input clk,d,clr,en;
reg q;

  always @(posedge clk or  posedge clr)
  begin
    if(clr)
      q<=0;
    else if (en)
      q<=d;
  end
endmodule

数据类型及其常量和变量:

4种逻辑值 : 0 1 z(高阻) x (不定值)

常量:在程序运行过程中,其值不能被改变的量称为常量。


整数:

  • 二进制整数 bB
  • 十进制整数 dD
  • 八进制整数 oO
  • 十六进制整数 hH

数字表达方式: <位宽>'<进制><数字>,默认位宽是32bit

4'b1110   //4位二进制数
12'habc  //12位十六进制数
16'd255  //16位十进制数

负数: 一个数字可以被定义为负数,只需在位宽表达式前加一个减号,减号必须写在数字定义表达式的最前面。

-8'd5 //这个表达式代表5的补数(用八位二进制数表示)


参数(Parameter)型:

parameter来定义一个标识符 代表一个常量,称为符号常量,即标识符形式的常量,采用标识符代表一个常量可提高程序的可读性和可维护性。是一种常数型的数据,其说明格式如下:

parameter 参数名1=表达式,参数名2=表达式, …, 参数名n=表达式;

parameter是参数型数据的确认符,确认符后跟着一个用逗号分隔开的赋值语句表。在每一个赋值语句的右边必须是一个常数表达式。也就是说,该表达式只能包含数字或先前已定义过的参数。

parameter msb=7; //定义参数msb为常量7
parameter e=25, f=29; //定义二个常数参数
parameter r=5.7; //声明r为一个实型参数
parameter byte_size=8, byte_msb=byte_size-1; //用常数表达式赋值
parameter average_delay = (r+f)/2; //用常数表达式赋值

参数型常数经常用于定义延迟时间和变量宽度。在实例引用时可通过参数传递改变在被引用模块中已定义的参数

module two_delay(a,b,c,d);
output c,d;
input a,b;
reg c,d;
parameter delay1=2,delay2=2;

  always @(a)
    c<= #delay1 a;

  always @(b)
    d<=#delay2 b;

endmodule

//调用版本1
module top_delay(a1,b1,c1,d1);
input a1,b1;
output c1,d1;

  two_delay #(.delay1(5),.delay2(10)) u1(.a(a1),.b(b1),.c(c1),.d(d1));

endmodule

//调用版本2
module top_delay2(a1,b1,c1,d1);
input a1,b1;
output c1,d1;

  two_delay #(5,10) u1(.a(a1),.b(b1),.c(c1),.d(d1));

endmodule

//调用版本3
module top_delay3(a1,b1,c1,d1);
input a1,b1;
output c1,d1;

  two_delay #(.delay2(10)) u1(.a(a1),.b(b1),.c(c1),.d(d1));

endmodule

//调用版本4
module top_delay4(a1,b1,c1,d1);
input a1,b1;
output c1,d1;

  two_delay #(10) u1(.a(a1),.b(b1),.c(c1),.d(d1));  //参数被传给了delay1

endmodule

变量:


wire变量:

wire [n-1:0] 数据名1,数据名2,…数据名i;  //共有i条总线,每条总线内有n条线路
wire [n:1] 数据名1,数据名2,…数据名i;
wire a;     //定义了一个一位的wire型数据
wire [7:0] b;   //定义了一个八位的wire型数据
wire [4:1] c, d;    //定义了二个四位的wire型数据

///////////////////////////////////////////////////////

reg是最常用的寄存器型数据。默认初始值是x:

reg [n-1:0] 数据名1,数据名2,… 数据名i;
reg [n:1] 数据名1,数据名2,… 数据名i;
reg rega; //定义了一个一位的名为rega的reg型数据
reg [3:0] regb; //定义了一个四位的名为regb的reg型数据
reg [4:1] regc, regd; //定义了两个四位的名为regc和regd的reg型数据

运算符按其功能可分为以下几类:

1) 算术运算符(+,-,×,/,%)
2) 赋值运算符(=,<=)
3) 关系运算符(>,<,>=,<=)
4) 逻辑运算符(&&,||,!)
5) 条件运算符(?:)
6) 位运算符(~,|,^,&,^~)
7) 移位运算符(<<,>>)
8) 拼接运算符({ })
9) 其它

下面是Verilog HDL中使用的关键词:
always, and, assign,begin,buf,bufif0,bufif1,case,casex,casez,cmos,deassign,default,defparam,disable,edge,else,end,endcase,endmodule,endfunction,endprimitive,endspecify, endtable, endtask, event, for, force, forever, fork, function,highz0,highz1, if,initial, inout, input,integer,join,large,macromodule,medium,module,nand,negedge,nmos,nor,not,notif0,notifl, or, output, parameter, pmos, posedge,primitive, pull0, pull1, pullup, pulldown, rcmos, reg, releses, repeat, mmos, rpmos,rtran, rtranif0,rtranif1,scalared,small,specify,specparam,strength,strong0, strong1,supply0, supply1, table, task, time, tran, tranif0, tranif1, tri, tri0, tri1, triand,trior, trireg,vectored,wait,wand,weak0,weak1,while, wire,wor, xnor, xor

块语句:

begin_end语句 通常用来标识顺序执行的语句,用它来标识的块称为顺序块

顺序块有以下特点:

(1) 块内的语句是按顺序执行的,即只有上面一条语句执行后下面的语句才能执行。
(2) 每条语句的延迟时间是相对于前一条语句的仿真时间而言的。
(3) 直到最后一条语句执行完,程序流程控制才跳出该语句块。

块内声明语句可以是参数声明语句、reg型变量声明语句、integer型变量声明语句、real型变量声明语句。

module ex4_5;
parameter d=50;
reg[7:0] r;
reg[3:0] a;
event end_wave;

  always @(end_wave)
    a=4'hf;
    initial
       begin
         a=4'h2;
       end

    initial
      begin
        #d r='h35;
        #d r='hE2;
        #d r='h00;
        #d r='hF7;
        #d ->end_wave;
      end

endmodule

逻辑判断:

module counter10b(q,clk,clr);
output[3:0] q;
input clk,clr;
reg[3:0] q=4'b0000;//ModelSim仿真用,QuartusII不用初值
  always @(posedge clk or posedge clr)
  begin
    if(clr)
      q<=4'b0000;
    else
    begin
      if (q==4'b1001)
        q<=4'b0000;
      else
        q<=q+1'b1;
    end
  end
endmodule

case语句:

case语句是一种多分支选择语句,if语句只有两个分支可供选择,而实际问题中常常需要用到多分支选择,Verilog语言提供的case语句直接处理多分支选择。

case语句的所有表达式的值的位宽必须相等,只有这样控制表达式和分支表达式才能进行对应位的比较。一个经常犯的错误是用'bx, 'bz 来替代 n'bx, n'bz,这样写是不对的,因为信号x, z的缺省宽度是机器的字节宽度,通常是32位(此处 n 是case控制表达式的位宽)

module test_case;
reg[1:0] select;
  initial
  begin
    select=2'b01;
    case (select)
      2'b01:$display("second 2b01...");
      2'b01:$display("third 2b01...");
      2'b01,2'b00:$display("2b01");
      2'b11:$display("2b11");
      default:$display("default...");
    endcase
  end
endmodule

initialalways 说明语句在仿真的一开始即开始执行。

initial 语句只执行一次。相反,always 语句则是不断地重复执行,直到仿真过程结束。

always 语句后面跟着的过程块是否运行,则要看它的触发条件是否满足,如满足则运行过程块一次,再次满足再运行一次,直至仿真过程结束。

在一个模块中,使用initialalways 语句的次数是不受限制的。

taskfunction 语句可以在程序模块中的一处或多处调用。

@*@(*),它们都表示对其后面语句块中所有输入变量的变化时敏感的。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 200,302评论 5 470
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 84,232评论 2 377
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 147,337评论 0 332
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 53,977评论 1 272
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 62,920评论 5 360
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,194评论 1 277
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,638评论 3 390
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,319评论 0 254
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,455评论 1 294
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,379评论 2 317
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,426评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,106评论 3 315
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,696评论 3 303
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,786评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,996评论 1 255
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,467评论 2 346
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,043评论 2 341

推荐阅读更多精彩内容