PWM generation(一)基于APB总线的32位寄存器

 (一)功能描述:

  产生最简单的PWM,且占空比可调。PWM周期p由INIT-MOD差值决定,高电平由MOD与MID差值h决定,占空比r=h/p。可产生中断。

(二)寄存器描述:

  包含寄存器名称,地址偏移量,位定义等。

Name STS  
Offset 0x00
Bit 31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16
Read  
Write
Reset 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
 
Bit 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0
Read   TOF
Write W1C
Reset 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0

TOF:计数器溢出标志,通过写1清零。

Name CTRL  
Offset 0x04
Bit 31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16
Read  
Write
Reset 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
 
Bit 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0
Read                             IE EN
Write                            
Reset 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0

IE:中断使能。

EN:PWM使能。

Name INIT  
Offset 0x08
Bit 31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16
Read  
Write
Reset 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
 
Bit 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0
Read INIT
Write
Reset 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0

INIT:计数器初始值。

Name MOD  
Offset 0x0C
Bit 31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16
Read  
Write
Reset 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
 
Bit 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0
Read MOD
Write
Reset 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0

MOD:计数器终值。

Name MID  
Offset 0x10
Bit 31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16
Read  
Write
Reset 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
 
Bit 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0
Read MID
Write
Reset 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0

 MID:计数器中间值。

 

(三)以下为基于APB总线实现寄存器配置的verilog代码,已编译成功,但是未添加周详的注释,后期再进行注释。

  1 //`default nettype none
  2 
  3 module pwm_config(
  4  
  5   output reg  [31:0] prdata ,  // APB read data
  6   output wire        pslverr,  // APB transfer error
  7   output wire        pready ,  // APB transfer ready
  8   output wire        int_req,
  9   output reg         ctrl_en,
 10   output reg  [15:0] init   ,
 11   output reg  [15:0] mod    ,
 12   output reg  [15:0] mid    ,
 13 
 14   input wire         pclk   ,  // Bus clock
 15   input wire         presetn,  // APB reset
 16   input wire  [11:0] paddr  ,  // APB address
 17   input wire         pwrite ,  // APB read-0/write-1 
 18   input wire         psel   ,  // APB select
 19   input wire         penable,  // APB enable
 20   input wire  [3:0]  pstrb  ,  // APB byte enable
 21   input wire  [31:0] pwdata ,  // APB write data
 22    
 23   input wire         tof_en
 24 );
 25   // local parameter for registers address offset
 26   localparam [11:2] PWM_STS_OFFSET  = 0;
 27   localparam [11:2] PWM_CTRL_OFFSET = 1;
 28   localparam [11:2] PWM_INIT_OFFSET = 2; 
 29   localparam [11:2] PWM_MOD_OFFSET  = 3; 
 30   localparam [11:2] PWM_MID_OFFSET  = 4;
 31   // reg or bits define
 32   wire wr_en  ;
 33   wire rd_en  ;
 34 
 35   wire wr_sts ;
 36   wire wr_ctrl;
 37   wire wr_init;
 38   wire wr_mod ;
 39   wire wr_mid ;
 40 
 41   reg  sts_tof;
 42   reg  ctrl_ie;
 43 
 44   wire reg_map;
 45   //reigisters write and read enable
 46   assign wr_en = psel & penable & pwrite; 
 47   assign rd_en = psel & penable & (-pwrite);
 48    
 49   assign wr_sts  = wr_en & (paddr[11:2] == PWM_STS_OFFSET );
 50   assign wr_ctrl = wr_en & (paddr[11:2] == PWM_CTRL_OFFSET);
 51   assign wr_init = wr_en & (paddr[11:2] == PWM_INIT_OFFSET);
 52   assign wr_mod  = wr_en & (paddr[11:2] == PWM_MOD_OFFSET );
 53   assign wr_mid  = wr_en & (paddr[11:2] == PWM_MID_OFFSET  ); 
 54    
 55   //PWM STS
 56   always @(posedge pclk or negedge presetn)begin 
 57     if(!presetn)begin
 58       sts_tof <= 1'b0;
 59     end
 60     else if(wr_sts & pstrb[0] & pwdata[0])begin
 61       sts_tof <= 1'b0;
 62     end
 63     else if(tof_en)begin
 64       sts_tof <= 1'b1;
 65     end
 66   end
 67 
 68   //PWM CTRL
 69   always @(posedge pclk or negedge presetn)begin
 70     if(!presetn)begin
 71       ctrl_ie <= 1'b0;
 72       ctrl_en <= 1'b0;
 73     end
 74     else if(wr_ctrl & pstrb[0])begin
 75       ctrl_ie <= pwdata[1]; 
 76       ctrl_en <= pwdata[0];
 77     end
 78   end
 79 
 80   //PWM INIT
 81   always @(posedge pclk or negedge presetn)begin
 82     if(!presetn)begin
 83       init <= 16'h00;
 84     end
 85     else if(wr_init)begin
 86       if(pstrb[1])begin
 87         init <= pwdata[15:8];
 88         end
 89       if(pstrb[0])begin
 90         init <= pwdata[7:0];
 91       end
 92     end
 93   end
 94  
 95   //PWM MOD
 96   always @(posedge pclk or negedge presetn)begin 
 97     if(!presetn)begin
 98       mod <= 16'h00;
 99     end
100     else if(wr_mod)begin
101       if(pstrb[1])begin
102         mod <= pwdata[15 :8];
103       end
104       if(pstrb[0])begin
105          mod <= pwdata[7:0];
106         end
107     end
108   end
109 
110 //PWM MID
111   always @(posedge pclk or negedge presetn)begin 
112     if(!presetn)begin
113       mid <= 16'h00;
114     end
115     else if(wr_mod)begin
116       if(pstrb[1])begin
117         mid <= pwdata[15 :8];
118       end
119       if(pstrb[0])begin
120          mid <= pwdata[7:0];
121         end
122     end
123   end
124  
125   //read registers 
126   always @(*)begin
127     if(rd_en)begin
128       case(paddr[11:2])
129         PWM_STS_OFFSET  : begin 
130           prdata = {31'h0,sts_tof};
131         end
132         PWM_CTRL_OFFSET : begin
133           prdata = {30'h0,ctrl_ie,ctrl_en};
134           end
135         PWM_INIT_OFFSET : begin
136           prdata = {16'h0,init};
137         end
138         PWM_MOD_OFFSET  : begin 
139           prdata = {16'h0,mod};
140         end
141         PWM_MID_OFFSET  : begin 
142           prdata = {16'h0,mid};
143         end
144         default : begin
145           prdata = 32'h0;
146          end
147       endcase
148     end
149     else begin
150       prdata = 32'h0;
151     end
152   end
153 
154   assign reg_map = paddr[11:2] == PWM_STS_OFFSET  ||
155                    paddr[11:2] == PWM_CTRL_OFFSET ||
156                    paddr[11:2] == PWM_INIT_OFFSET ||
157                    paddr[11:2] == PWM_MOD_OFFSET  ||
158                    paddr[11:2] == PWM_MID_OFFSET;
159 
160   assign pslverr = psel & penable & reg_map;
161   assign pready  = 1'b1;
162   assign int_reg = ctrl_ie & sts_tof;
163 
164 endmodule
165 //`default nettype wire

未完待续,欢迎留言讨论,后面将陆续添加PWM产生的其他代码与集成,以及简易的验证环境,仅供参考!

上一篇:springboot整合swagger2


下一篇:Verilog RTL 设计:同步FIFO的设计与验证 方法一