276 lines
13 KiB
ReStructuredText
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
|