对C语言编程者的Verilog开发指南实例

[09-12 18:28:41]   来源:http://www.88dzw.com  EDA/PLD   阅读:8104

文章摘要:清单2:实现带异步复位功能8位宽寄存器的Verilog编写模块。module simple_register(in, out, clr_n, clk, a);//端口声明inputinputinput [7:0]inputoutput [7:0]clr_n;clk;in;a;out;//信号声明reg [7:0]wireout;a;//实现带异步清除的寄存器always @(posedge clk or negedge clr_n)beginif (clr_n==0) // could also be written if (!clr_n)out<=0;elseout<=in;en

对C语言编程者的Verilog开发指南实例,标签:eda技术,eda技术实用教程,http://www.88dzw.com

  清单2:实现带异步复位功能8位宽寄存器的Verilog编写模块。

  module simple_register(in, out, clr_n, clk, a);

  //端口声明

  input

  input

  input [7:0]

  input

  output [7:0]

  clr_n;

  clk;

  in;

  a;

  out;

  //信号声明

  reg [7:0]

  wire

  out;

  a;

  //实现带异步清除的寄存器

  always @(posedge clk or negedge clr_n)

  begin

  if (clr_n==0) // could also be written if (!clr_n)

  out<=0;

  else

  out<=in;

  end

  //连续赋值

  assign a=!out[0];

  endmodule

  粗略地看Verilog与C语言有许多相似之处。分号用于结束每个语句,注释符也是相同的(/* ... */和// 都是熟悉的),运算符“==”也用来测试相等性。Verilog的if..then..else语法与C语言的也非常相似,只是Verilog用关键字 begin和end代替了C的大括号。事实上,关键字begin和end对于单语句块来说是可有可无的,就与C中的大括号用法一样。Verilog和C都对大小写敏感。

  当然,硬件和软件的一个重要区别是它们的“运行”方式。硬件设计中用到的许多单元都是并行工作的。一旦设备电源开启,硬件的每个单元就会一直处于运行状态。虽然根据具体的控制逻辑和数据输入,设备的一些单元可能不会改变它们的输出信号,但它们还是一直在“运行”中。

  相反,在同一时刻整个软件设计中只有一小部分(即使是多软件任务也只有一个任务)在执行。如果只有一个处理器,同一时间点只能有一条指令在执行。软件的其它部分可以被认为处于休眠状态,这与硬件有很大的不同。变量可能以一个有效值而存在,但大多数时间里它们都不在使用状态。

  软硬件的不同行为会直接导致硬件和软件代码编程方式的不同。软件是串行执行的,每一行代码的执行都要等到前一行代码执行完毕后才能进行(中断的非线性或操作系统的命令除外)。

  //-------------------------------------------------------------------------------------------------------------

  一个Verilog模块的开头是关键字module,紧跟其后的是模块名称和端口列表,端口列表列出了该模块用到的所有输入输出名称。接下来是端口声明部分。注意:所有的输入输出既出现在模块第一行的端口列表中,也会出现在端口声明(declaration)部分中。

  在Verilog中有二种类型的内部信号用得比较多,它们是reg和wire。它们具有不同的功能。所有端口都有一个名称相同且声明为wire的信号。因此连线line被声明为wire不是必要的。reg会保持上次的赋值,因此不需要每次都进行驱动。wire型信号用于异步逻辑,有时也用来连接信号。因为 reg可以保持上次的值,因此输入不能被声明为reg类型。在Verilog模块中可以在任何时候异步地将输入改变为任何事件。reg和wire的主要区别是,reg类型的信号只能在过程块(后面会谈到)中赋值,而wire类型的信号只能在过程块外赋值。这两种信号类型都可以出现在过程块内部和外部的赋值运算符右边。

  使用关键字reg并不一定意味着编译器会创建一个寄存器,理解这一点是非常重要的。清单2的代码中有一个reg类型8位宽的内部信号out。该模块使用寄存器源于always模块(过程块的一种)的编程方式。值得注意的是,信号a是一个wire类型,因此只能在连续赋值(continuous assignment)语句中赋值,而reg类型的out信号只能在always块中赋值。

  always块是过程块的一种,仅在某种变化发生时用于更新信号。always语句圆括号里的表达式组被称为敏感列表,格式是:(表达式or表达式…)

  只要敏感列表中的任何一个表达式值为真,always块中的代码就会被执行。Verilog中用于上升沿和下降沿的关键字分别是posedge和 negedge。这二个关键字经常被用于敏感列表。在本例中,如果clk信号的上升沿或clr_n的下降沿信号发生时,always块内部的语句就会被执行。

  为了用好寄存器,输出必须在时钟的上升沿得到更新(下降沿也可以,但上升沿更常见些)。增加negedge clr_n会使寄存器在clr_n信号的下降沿复位。但并不是所有的敏感列表都会包含关键字posedge或negedge,因此在实际硬件中并不总是存在真实的寄存器。

上一页  [1] [2] [3] [4] [5]  下一页


Tag:EDA/PLDeda技术,eda技术实用教程EDA/PLD

《对C语言编程者的Verilog开发指南实例》相关文章

分类导航
最新更新
热门排行