对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.comalways块内的第一条语句判断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)
《对C语言编程者的Verilog开发指南实例》相关文章
- › 对C语言编程者的Verilog开发指南实例
- 在百度中搜索相关文章:对C语言编程者的Verilog开发指南实例
- 在谷歌中搜索相关文章:对C语言编程者的Verilog开发指南实例
- 在soso中搜索相关文章:对C语言编程者的Verilog开发指南实例
- 在搜狗中搜索相关文章:对C语言编程者的Verilog开发指南实例