首页
学习
活动
专区
圈层
工具
发布
社区首页 >专栏 >verilog 实现PWM DAC

verilog 实现PWM DAC

作者头像
FPGA开源工作室
发布2021-07-09 17:04:36
发布2021-07-09 17:04:36
1.7K0
举报
文章被收录于专栏:FPGA开源工作室FPGA开源工作室

PWM 采用任意宽度的输入值,并创建只有一位宽度的输出。使用自由运行计数器的 PWM,这是能做的最简单的 PWM。

代码语言:javascript
复制
module PWM(
    input clk,
  input rst_n,
    input [3:0] PWM_in,
    output PWM_out
);


reg [3:0] cnt;
always @(posedge clk or negedge rst_n) 
  if(!rst_n)
    cnt<=0;
  else
   cnt <= cnt + 1'b1;  // free-running counter


assign PWM_out = (PWM_in > cnt)?1'b1:1'b0;  // comparator
endmodule

选择了一个4位的 PWM 这里,所以 PWM 周期是16。输入可以从0到15,因此 PWM 输出比从0% 到15/16 = 93% 。如果需要能够达到100% ,输入需要有一个额外的bit位。

这段代码工作得很好,尽管当前形式的代码有点幼稚,因为输入必须是固定的(或者只有当计数器溢出 = 返回到0时才会更改)。否则输出将出现故障。因此,很可能需要一些额外的逻辑(通常是在正确的时间捕获输入的闩锁)

使用可加载的上下计数器的 PWM,这是一个稍微复杂一点的设计。

代码语言:javascript
复制
module PWM2(
    input clk,
  input rst_n,
    input [3:0] PWM_in,
    output PWM_out
);


reg [3:0] cnt;
reg cnt_dir;  // 0 to count up, 1 to count down
wire [3:0] cnt_next = cnt_dir ? cnt-1'b1 : cnt+1'b1;
wire cnt_end = cnt_dir ? cnt==4'b0000 : cnt==4'b1111;


always @(posedge clk or negedge rst_n ) 
  if(!rst_n)
    cnt <= 0;
  else
    cnt <= cnt_end ? PWM_in : cnt_next;
always @(posedge clk or negedge rst_n)
  if(!rst_n)
    cnt_dir<=1'b0;
  else
    cnt_dir <= cnt_dir ^ cnt_end;
assign PWM_out = cnt_dir;
endmodule

它使用一个可加载的上下计数器,不需要输出比较器。有趣的是,它并不完全等同于第一个设计,因为输出周期有17个状态而不是16个(输出从1/17 = 6% 到16/17 = 94%)。

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2021-07-01,如有侵权请联系 [email protected] 删除

本文分享自 FPGA开源工作室 微信公众号,前往查看

如有侵权,请联系 [email protected] 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档