(一)功能描述:
产生最简单的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产生的其他代码与集成,以及简易的验证环境,仅供参考!