pluto_hdl_adi/docs/library/axi_pwm_gen/index.rst

276 lines
13 KiB
ReStructuredText

.. _axi_pwm_gen:
AXI PWM Generator
================================================================================
.. hdl-component-diagram::
The :git-hdl:`AXI PWM Generator <library/axi_pwm_gen>` core is used to generate
a maximum of 16 configurable signals (Pulse-Width Modulations).
The pulses are generated according to the state of a counter;
there is one counter for each pulse.
Features
--------------------------------------------------------------------------------
* Up to 16 configurable signals (period, width, offset)
* External synchronization
* External clock
Files
--------------------------------------------------------------------------------
.. list-table::
:header-rows: 1
* - Name
- Description
* - :git-hdl:`library/axi_pwm_gen/axi_pwm_gen.sv`
- SystemVerilog source for the top module
* - :git-hdl:`library/axi_pwm_gen/axi_pwm_gen_1.v`
- Verilog source for a channel module
* - :git-hdl:`library/axi_pwm_gen/axi_pwm_gen_regmap.sv`
- SystemVerilog source for regmap
* - :git-hdl:`library/axi_pwm_gen/axi_pwm_gen_constr.ttcl`
- Dynamic constraint file (AMD tools)
* - :git-hdl:`library/axi_pwm_gen/axi_pwm_gen_constr.sdc`
- Constraint file (Intel tools)
* - :git-hdl:`library/axi_pwm_gen/axi_pwm_gen_ip.tcl`
- IP definition file (AMD tools)
* - :git-hdl:`library/axi_pwm_gen/axi_pwm_gen_hw.tcl`
- IP definition file (Intel tools)
Block Diagram
--------------------------------------------------------------------------------
.. image:: block_diagram.svg
:alt: AXI PWM Generator block diagram
Configuration Parameters
--------------------------------------------------------------------------------
.. note::
The pulse period, width and offset are set in number of clock cycles.
The clock is the axi clock or if activated, the external clock.
.. hdl-parameters::
* - ID
- Core ID should be unique for each IP in the system.
* - ASYNC_CLK_EN
- Use external clock, asynchronous to s_axi_aclk.
* - N_PWMS
- Number of pulses/pwms.
* - PWM_EXT_SYNC
- PWM offset counter uses external sync.
* - EXT_ASYNC_SYNC
- The external sync for pulse 0 is asynchronous.
* - SOFTWARE_BRINGUP
- Require software, to bring the core out if reset
* - EXT_SYNC_PHASE_ALIGN
- Set default flag value for external sync phase align feature
* - FORCE_ALIGN
- Set default flag value for force align feature
* - START_AT_SYNC
- Set default flag value for start at sync feature
.. _axi_pwm_gen interface:
Interface
--------------------------------------------------------------------------------
.. hdl-interfaces::
* - ext_clk
- External clock.
* - ext_sync
- External sync signal, synchronizes pulses to an external signal.
* - pwm_*
- Output PWM, up to 16, indexed from 0 to 15.
Detailed Description
--------------------------------------------------------------------------------
Let's start with some base notions:
- The pulse generators are based on incrementing counters.
- The pulse period starts on the high level interval and ends on the low level.
- By default, all counters start at the same time. When a different phase (delay)
is needed between the pulses, we can set an offset.
- The offset feature can synchronize channels 0 to 15 relative to an offset
counter.
- The offset counter will wait for a HIGH -> LOW transition of the
synchronization pulse (''load_config'' or ''ext_sync'').
For more info see the below channel phase alignment feature.
- To **disable a PWM channel**, write 0 to its ``period`` register.
- The duty cycle is the ratio between pulse width over pulse period.
The following features can be enabled by setting a flag in the
register REG_UP_CONTROL(0x18):
Channel phase alignment
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
The AXI PWM Generator core can be synchronized by an external signal on the
HIGH -> LOW transition of the ext_sync signal.
The external sync can be used in two modes, based on the external sync align
feature.
- external_sync_align flag is set(1) the ext_sync will trigger a phase align
at each neg-edge.
- otherwise the phase align must be armed by a load config toggle, while
the external sync must be held HIGH.
Software bringup (software reset)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
If set, the software must bring the core out of reset, after a system reset,
for the pwm signals to be generated.
Force align
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
If set, the current active pulses are immediately stopped and realigned.
Otherwise, the synchronized pulses will start only after all running pulse
periods end. Software overwritable at runtime.
Start at sync
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
If active, the pulses will start after the trigger event.
Otherwise each pulse will start after a period equal to the one for which
it is set. Software over writable at runtime.
This flags are software overwritable at runtime. Default value is given at build time.
- software bringup = 1
- start at sync = 1
- force align = 0
- ext sync align = 0
Timing Diagrams and examples
--------------------------------------------------------------------------------
The timing diagram below, shows the ``load_config`` functionality with
force sync and force start disabled.
.. wavedrom::
{ "signal" : [
{ "name": "clk", "wave": "P.............................."},
{ "name": "pwm_1 period", "wave": "9.............9................","data":["8","10"]},
{ "name": "pwm_1 pulse", "wave": "9.............9................","data":["3","5"]},
{ "name": "pwm_1 offset", "wave": "9.............9................","data":["1","0"]},
{ "name": "pwm_2 period", "wave": "6.............6................","data":["8","10"]},
{ "name": "pwm_2 pulse", "wave": "6.............6................","data":["3","5"]},
{ "name": "pwm_2 offset", "wave": "6.............6................","data":["5","4"]},
{ "name": "load_config", "wave": "0............10................",phase: 0,},
{ "name": "offset counter", "wave": "7777777777777777777777777777777","data":["55","56","57","58","59","60","61","62","63","64","65","66","67","68","0","1","2","3","4","5","6","7","8","9","10","11","12","13","14","15","16"]},
{ "name": "counter 0", "wave": "45555555544444=6666666666333333","data":["8","1","2","3","4","5","6","7","8","1","2","3","4","5","1","1","2","3","4","5","6","7","8","9","10","1","2","3","4","5","6"]},
{ "name": "pwm 0", "wave": "lh..l....h...l.h....l....h....l"},
{ "name": "counter 1", "wave": "44444555555554=...6666666666333","data":["4","5","6","7","8","1","2","3","4","5","6","7","8","1","1","1","2","3","4","5","6","7","8","9","10","1","2","3","4","5"]},
{ "name": "pwm 1", "wave": "l....h..l....hl...h....l....h.."},
],
foot: {text: ['tspan', 'load_config force_sync and start at sync e.g.'],
}}
The timing diagram below, shows the ``load_config`` functionality with
force sync disabled and force start enabled.
.. wavedrom::
{ "signal" : [
{ "name": "clk", "wave": "P.............................."},
{ "name": "pwm_1 period", "wave": "9...........9..................","data":["8","10"]},
{ "name": "pwm_1 pulse", "wave": "9...........9..................","data":["3","5"]},
{ "name": "pwm_1 offset", "wave": "9...........9..................","data":["1","0"]},
{ "name": "pwm_2 period", "wave": "6...........6..................","data":["8","10"]},
{ "name": "pwm_2 pulse", "wave": "6...........6..................","data":["3","5"]},
{ "name": "pwm_2 offset", "wave": "6...........6..................","data":["5","4"]},
{ "name": "load_config", "wave": "0..........10..................",phase: 0,},
{ "name": "offset counter", "wave": "7777777777777777777777777777777","data":["55","56","57","58","59","60","61","62","63","64","65","66","67","68","0","1","2","3","4","5","6","7","8","9","10","11","12","13","14","15","16"]},
{ "name": "counter 0", "wave": "45555555544444444=6666666666333","data":["8","1","2","3","4","5","6","7","8","1","2","3","4","5","6","7","8","1","1","2","3","4","5","6","7","8","9","10","1","2","3"]},
{ "name": "pwm 0", "wave": "lh..l....h...l....h....l....h.."},
{ "name": "counter 1", "wave": "4444455555555=.......6666666666","data":["4","5","6","7","8","1","2","3","4","5","6","7","8","1","1","2","3","4","5","6","7","8","9","10"]},
{ "name": "pwm 1", "wave": "l....h..l............h....l...."},
],
foot: {text: ['tspan', 'load_config with start at sync(default)'],
}}
The timing diagram below, shows the ``load_config`` functionality with
force sync and force start enabled.
.. wavedrom::
{ "signal" : [
{ "name": "clk", "wave": "P.............................."},
{ "name": "pwm_1 period", "wave": "9.............9................","data":["8","10"]},
{ "name": "pwm_1 pulse", "wave": "9.............9................","data":["3","5"]},
{ "name": "pwm_1 offset", "wave": "9.............9................","data":["1","0"]},
{ "name": "pwm_2 period", "wave": "6.............6................","data":["8","10"]},
{ "name": "pwm_2 pulse", "wave": "6.............6................","data":["3","5"]},
{ "name": "pwm_2 offset", "wave": "6.............6................","data":["5","4"]},
{ "name": "load_config", "wave": "0............10................",phase: 0,},
{ "name": "offset counter", "wave": "7777777777777777777777777777777","data":["55","56","57","58","59","60","61","62","63","64","65","66","67","68","0","1","2","3","4","5","6","7","8","9","10","11","12","13","14","15","16"]},
{ "name": "counter 0", "wave": "45555555544444=6666666666333333","data":["8","1","2","3","4","5","6","7","8","1","2","3","4","5","1","1","2","3","4","5","6","7","8","9","10","1","2","3","4","5","6"]},
{ "name": "pwm 0", "wave": "lh..l....h...l.h....l....h....l"},
{ "name": "counter 1", "wave": "44444555555554=...6666666666333","data":["4","5","6","7","8","1","2","3","4","5","6","7","8","1","1","1","2","3","4","5","6","7","8","9","10","1","2","3","4","5"]},
{ "name": "pwm 1", "wave": "l....h..l....hl...h....l....h.."},
],
foot: {text: ['tspan', 'load_config force_sync and start at sync e.g.'],
}}
The below timing diagrams, shows the ``external_sync`` functionality:
.. wavedrom::
{ "signal" : [
{ "name": "clk", "wave": "P............................"},
{ "name": "pwm_1 period", "wave": "9............................","data":["8"]},
{ "name": "pwm_1 pulse", "wave": "9............................","data":["3"]},
{ "name": "pwm_1 offset", "wave": "9............................","data":["1"]},
{ "name": "pwm_2 period", "wave": "6............................","data":["8"]},
{ "name": "pwm_2 pulse", "wave": "6............................","data":["3"]},
{ "name": "pwm_2 offset", "wave": "6............................","data":["5"]},
{ "name": "external_sync", "wave": "1....0.......................",phase: 0.5,},
{ "name": "offset counter", "wave": "=.....7777777777777777777777=","data":["0","1","2","3","4","5","6","7","8","9","10","11","12","13","14","15","16","17","18","19","20","21","22"]},
{ "name": "counter 0", "wave": "=......444444455555555444444=","data":["1","2","3","4","5","6","7","8","1","2","3","4","5","6","7","8","1","2","3","4","5","6"]},
{ "name": "pwm 0", "wave": "l......h..l....h..l....h..l.."},
{ "name": "counter 1", "wave": "=..........44444445555555544=","data":["1","2","3","4","5","6","7","8","1","2","3","4","5","6","7","8","1","2"]},
{ "name": "pwm 1", "wave": "l..........h..l....h..l....h."},
],
foot: {text: ['tspan', 'External sync, start at sync (default) e.g.'],
}}
.. wavedrom::
{ "signal" : [
{ "name": "clk", "wave": "P............................"},
{ "name": "pwm_1 period", "wave": "9............................","data":["8"]},
{ "name": "pwm_1 pulse", "wave": "9............................","data":["3"]},
{ "name": "pwm_1 offset", "wave": "9............................","data":["1"]},
{ "name": "pwm_2 period", "wave": "6............................","data":["8"]},
{ "name": "pwm_2 pulse", "wave": "6............................","data":["3"]},
{ "name": "pwm_2 offset", "wave": "6............................","data":["5"]},
{ "name": "external_sync", "wave": "1....0.......................",phase: 0.5,},
{ "name": "offset counter", "wave": "=.....7777777777777777777777=","data":["0","1","2","3","4","5","6","7","8","9","10","11","12","13","14","15","16","17","18","19","20","21","22"]},
{ "name": "counter 0", "wave": "=......444444455555555444444=","data":["1","2","3","4","5","6","7","8","1","2","3","4","5","6","7","8","1","2","3","4","5","6"]},
{ "name": "pwm 0", "wave": "l.............h..l....h..l..."},
{ "name": "counter 1", "wave": "=..........44444445555555544=","data":["1","2","3","4","5","6","7","8","1","2","3","4","5","6","7","8","1","2"]},
{ "name": "pwm 1", "wave": "l.................h..l....h.."},
],
foot: {text: ['tspan', 'External sync without start at sync e.g.'],
}}
Register Map
--------------------------------------------------------------------------------
.. hdl-regmap::
:name: axi_pwm_gen