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

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

文章摘要:beginif (clr_n==0)off<=0;elseif (counter>=pulse_width)off <= 1;elseif (counter==0)off<=0;elseoff<=off;endassign period_en = cs & !write_n & !addr;assign pulse_width_en = cs & !write_n & addr;//PWM输出assign pwm_out=!off;endmodule首先是端口说明,接着是内部信号说明。构成PWM软件控制接口的存储器映射型寄存器被声明为reg。该代码行只允许以32位

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

  begin

  if (clr_n==0)

  off<=0;

  else

  if (counter>=pulse_width)

  off <= 1;

  else

  if (counter==0)

  off<=0;

  else

  off<=off;

  end

  assign period_en = cs & !write_n & !addr;

  assign pulse_width_en = cs & !write_n & addr;

  //PWM输出

  assign pwm_out=!off;

  endmodule

  首先是端口说明,接着是内部信号说明。构成PWM软件控制接口的存储器映射型寄存器被声明为reg。该代码行只允许以32位的方式访问这些存储器映射型寄存器。如果需要8位或16位访问,就必须将寄存器分割成4个8位寄存器,并增加字节使能信号逻辑。用Verilog代码实现这一功能是非常简单的。 always块中已赋过值的所有信号都被声明为reg类型。声明为wire类型的信号是period和pulse_width寄存器写入使能信号。这些信号使用连续赋值语句进行赋值。

  清单的余下部分即是实际的代码,共有4个always块,最后还有几个赋值语句。每个always块描述一个信号或一组有相同基本行为(换句话说,使用相同的控制逻辑)的信号的行为。这是使代码具有可读性并能减少错误的Verilog代码编写风格。所有的always块都有复位逻辑,当clr_n信号被证实(设为0)时,复位逻辑将信号置为0。虽然这样做并不是严格必需的,但这是一种良好的设计习惯,能使每个信号在复位时都有确定的值。

  第一个always块描述了寄存器映射中的寄存器行为。当正确的使能信号被证实时,write_data寄存器值就被写入period或 pulse_width寄存器中。这是改变任一寄存器值的唯一途径。该文件底部的连续赋值语句定义了写入使能信号。当主写入使能信号和芯片选择信号同时被证实时,period和pulse_width寄存器的写入使能信号就被证实,此时period和pulse_width的地址位应分别被置为0和1。

  第二个always块定义了寄存器映射图中读寄存器。Period寄存器位于外围电路的基本地址处,pulse_width寄存器在后面32位字地址处。

  第三和第四个always块一起来决定PWM的输出。第三个always块实现计数器功能,它连续计数到period寄存器设置的值时复位到0,然后重新开始计数。第四个always块对该计数器值与pulse_width寄存器值进行比较,当计数器值小于pulse_width值时,PWM输出保持高电平,否则设为低电平。

  需要牢记的是不管在何种条件下每个信号都必须有明确的值。回顾一下硬件的基本行为特征——“始终在运行”。例如在最后一个always块(描述off信号的那个块)中,代码的最后行将off赋于它本身。最初看来好象比较奇怪,但如果没有这一行的话,off值将是不确定的。对这一情况保持跟踪的最方便途径是确保每次信号会在if语句中赋值,在相应的else语句中也赋值。

  软件访问

  现在硬件完成了,可以利用寄存器映射图中的寄存器通过软件对PWM实施控制。读者可以用一个简单的带指针的数据结构连接PWM中的寄存器。

  typedef volatile struct

  {

  uint32_t period;

  uint32_t pulse_width;

  } PWM;

  例如,可以将PWM连接到LED。先初始化一个名为pLED、类型为PWM*的变量,将其指向PWM基地址。这样做实际上是将硬件抽象进了一个数据结构。向pLED->period写入数据会设置或改变period值,向pLED->pulse_width写入数据将改变占空比,并导致LED 的亮度增加或减少。如果使用的是闪烁型LED,只需把周期变长,让肉眼清晰辨别开和关的周期即可。

  清单3所示的Verilog PWM实现在本例中是作为Altera的Nios处理器系统的外围电路进行测试的,可以利用前文所述的C结构通过软件对它访问。Altera的SOPC Builder创建了宏,可以使ModelSim(明导资讯公司的一个硬件仿真器)中的协同仿真。在系统执行C代码时可以利用ModelSim仿真器观察到PWM信号以及其它系统信号的行为。

  清单4给出了用于产生图1所示PWM波形的C代码。C代码向PWM寄存器写入数据,创建出周期为5个时钟周期、脉宽为4个时钟周期的PWM输出信号。请注意在波形的开始处,由于period和pulse_width寄存器都被写入了数据,cs和wr_n信号被证实了二次(在写period寄存器时地址信号为低电平,在写pulse_width寄存器时地址信号变成了高电平)。

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


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

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

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