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

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

文章摘要:always块内的第一条语句判断clr_n信号的上升沿有没有发生。如果有,下一行代码把out置为0。这些代码行实现了寄存器的异步复位功能。如果条件语句是:if(negedge clr_n and clk==1),那么该语句实现的就是基于时钟的异步复位。读者可能已经注意到,always块中的赋值运算符与以关键字assign开头的连续赋值语句中用到的运算符不一样。"<="运算符用于非阻塞性(nonblocking)赋值,而"="运算符用于阻塞性(blocking)赋值。在一组阻塞性赋值语句中,在下一个阻塞性赋值语句执行前需要计算并赋值第一个赋值语句。这

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

  always块内的第一条语句判断clr_n信号的上升沿有没有发生。如果有,下一行代码把out置为0。这些代码行实现了寄存器的异步复位功能。如果条件语句是:if(negedge clr_n and clk==1),那么该语句实现的就是基于时钟的异步复位。

  读者可能已经注意到,always块中的赋值运算符与以关键字assign开头的连续赋值语句中用到的运算符不一样。"<="运算符用于非阻塞性(nonblocking)赋值,而"="运算符用于阻塞性(blocking)赋值。

  在一组阻塞性赋值语句中,在下一个阻塞性赋值语句执行前需要计算并赋值第一个赋值语句。这一过程就象C语言中语句的顺序执行。而非阻塞语句在执行时,所有赋值语句的右边被同时计算和赋值。连续赋值语句必须使用阻塞赋值语句(否则编译器会报错)。

  为了减少代码出错的概率,建议在顺序逻辑(例如希望以寄存器方式实现的逻辑)always块中的所有赋值语句使用非阻塞性赋值语句。大多数always块应该使用非阻塞性赋值语句。如果always块都是组合逻辑,那么就需要使用阻塞性赋值语句。

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

  PWM硬件

  编写存储器映射硬件模块的首要任务是以软件方式决定寄存器映射图。在PWM案例中,一般设计师希望能用软件设置周期和脉宽。在硬件设计中用计数器统计系统时钟周期数是非常容易的。因此要用到两个寄存器,分别命名为pulse_width和period,并且都在时钟周期内度量。表1给出了PWM的寄存器映射图。

  为了确定输出信号,硬件可简单地通过将period和pulse_width寄存器内容作为运行中的计数器保持的输出。

  接下来要为PWM选择端口,大多数端口可以依据总线架构而定。表2提供了通用存储器映射PWM的信号描述概要。通常为低电平有效的信号命名做法是在信号名上加“_n”,对于控制信号更是如此。表2中的write_n和clr_n信号就是低电平有效的信号(下降沿触发)。

  至此我们已经定义好了硬件模块的接口,接下来就可以开始编写Verilog代码了。清单3给出了一个实现例子。

  清单3:用Verilog实现的PWM硬件。

  module pwm (clk, write_data, cs, write_n, addr, clr_n, read_data, pwm_out);

  input

  input [31:0]

  input

  input

  input

  input

  output [31:0]

  output

  clk;

  write_data;

  cs;

  write_n;

  addr;

  clr_n;

  read_data;

  pwm_out;

  reg [31:0]

  reg [31:0]

  reg [31:0]

  reg

  reg [31:0]

  wire

  period;

  pulse_width;

  counter;

  off;

  read_data;

  period_en, pulse_width_en; //写使能

  // 定义period和pulse_width寄存器的内容

  always @(posedge clk or negedge clr_n)

  begin

  if (clr_n==0)

  begin

  period<=32''h 00000000;

  pulse_width<=32''h 00000000;

  end

  else

  begin

  if (period_en)

  period<=write_data[31:0];

  else

  period<=period;

  if (pulse_width_en)

  pulse_width<=write_data[31:0];

  else

  pulse_width<=pulse_width;

  end

  end

  // period和pulse_width寄存器的读访问

  always @(addr or period or pulse_width)

  if (addr == 0)

  read_data=period;

  else

  read_data=pulse_width;

  always @(posedge clk or negedge clr_n)

  begin

  if (clr_n==0)

  counter<=0;

  else

  if (counter>=period-1)

  counter<=0;

  else

  counter<=counter+1;

  end

  always @(posedge clk or negedge clr_n)

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


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

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

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