blob: 950060c2892caac6075ce3d1dee57fd50327ebc3 [file] [log] [blame]
// Copyright lowRISC contributors.
// Licensed under the Apache License, Version 2.0, see LICENSE for details.
// SPDX-License-Identifier: Apache-2.0
{
name: "pwm",
human_name: "Pulse Width Modulator",
one_line_desc: "Transmission of pulse-width modulated output signals with adjustable duty cycle",
one_paragraph_desc: '''
Pulse Width Modulator creates pulse-width modulated (PWM) signals with adjustable duty cycle.
It is suitable for general-purpose use, but primarily designed for control of LEDs.
All outputs are programmable with frequency, phase, and duty cycle.
'''
design_spec: "../doc",
dv_doc: "../doc/dv",
hw_checklist: "../doc/checklist",
sw_checklist: "/sw/device/lib/dif/dif_pwm",
revisions: [
{
version: "1.0",
life_stage: "L1",
design_stage: "D2S",
verification_stage: "V2S",
dif_stage: "S2",
notes: ""
}
]
clocking: [
{clock: "clk_i", reset: "rst_ni", primary: true},
{clock: "clk_core_i", reset: "rst_core_ni"}
]
bus_interfaces: [
{ protocol: "tlul", direction: "device" }
],
regwidth: "32",
param_list: [
{ name: "NOutputs",
desc: "Number of PWM outputs",
type: "int",
default: "6",
}
]
available_output_list: [
{ name: "pwm"
desc: '''Pulse output. Note that though this output is always enabled, there is a formal
set of enable pins (pwm_en_o) which are required for top-level integration of
comportable IPs.'''
width: "6"
}
]
alert_list: [
{ name: "fatal_fault",
desc: '''
This fatal alert is triggered when a fatal TL-UL bus integrity fault is detected.
'''
}
],
countermeasures: [
{ name: "BUS.INTEGRITY",
desc: "End-to-end bus integrity scheme."
}
]
registers: [
{ name: "REGWEN",
desc: "Register write enable for all control registers",
swaccess: "rw0c",
hwaccess: "none",
fields: [
{ bits: "0",
desc: ''' When true, all writable registers can be modified.
When false, they become read-only. Defaults true, write
zero to clear. This can be cleared after initial
configuration at boot in order to lock in the listed
register settings.'''
resval: 1
}
]
}
{ name: "CFG",
desc: "Configuration register",
swaccess: "rw",
async: "clk_core_i",
hwqe: "true",
regwen: "REGWEN",
fields: [
{ bits: "31",
name: "CNTR_EN",
desc: '''Assert this bit to enable the PWM phase counter.
Clearing this bit disables and resets the phase counter.'''
resval: "0x0"
},
{ bits: "30:27",
name: "DC_RESN"
desc: '''Phase Resolution (logarithmic). All duty-cycle and phase
shift registers represent fractional PWM cycles, expressed in
units of 2^16 PWM cycles. Each PWM cycle is divided
into 2^(DC_RESN+1) time slices, and thus only the (DC_RESN+1)
most significant bits of each phase or duty cycle register
are relevant.'''
resval: 7
},
{ bits: "26:0",
name: "CLK_DIV",
desc: '''Sets the period of each PWM beat to be (CLK_DIV+1)
input clock periods. Since PWM pulses are generated once
every 2^(DC_RESN+1) beats, the period between output
pulses is 2^(DC_RESN+1)*(CLK_DIV+1) times longer than the
input clock period.'''
resval: "0x00008000"
}
]
},
{ multireg: { name: "PWM_EN",
desc: "Enable PWM operation for each channel",
count: "NOutputs",
swaccess: "rw",
cname: "pwm_en",
compact: "1",
async: "clk_core_i",
hwqe: "true",
regwen: "REGWEN",
fields: [
{ bits: "0",
name: "EN",
desc: '''Write 1 to this bit to enable PWM pulses on the
corresponding channel.''',
resval: "0"
}
]
}
},
{ multireg: { name: "INVERT",
desc: "Invert the PWM output for each channel",
count: "NOutputs",
swaccess: "rw",
cname: "pwm_invert",
compact: "1",
async: "clk_core_i",
hwqe: "true",
regwen: "REGWEN",
fields: [
{ bits: "0",
name: "INVERT",
desc: '''Write 1 to this bit to invert the output for each channel,
so that the corresponding output is active-low.''',
resval: "0"
}
]
}
},
{ multireg: { name: "PWM_PARAM",
desc: "Basic PWM Channel Parameters",
count: "NOutputs"
swaccess: "rw",
cname: "pwm_params",
async: "clk_core_i",
hwqe: "true",
regwen: "REGWEN",
fields: [
{ bits: "31",
name: "BLINK_EN",
desc: '''Enables blink (or heartbeat). If cleared, the output duty
cycle will remain constant at DUTY_CYCLE.A. Enabling this
bit causes the PWM duty cycle to fluctuate between
DUTY_CYCLE.A and DUTY_CYCLE.B'''
resval: 0
},
{ bits: "30",
name: "HTBT_EN",
desc: '''Modulates blink behavior to create a heartbeat effect. When
HTBT_EN is set, the duty cycle increases (or decreases)
linearly from DUTY_CYCLE.A to DUTY_CYCLE.B and back, in
steps of (BLINK_PARAM.Y+1), with an increment (decrement)
once every (BLINK_PARAM.X+1) PWM cycles. When HTBT_EN is
cleared, the standard blink behavior applies, meaning that
the output duty cycle alternates between DUTY_CYCLE.A for
(BLINK_PARAM.X+1) pulses and DUTY_CYCLE.B for
(BLINK_PARAM.Y+1) pulses.'''
resval: 0
},
{ bits: "15:0",
name: "PHASE_DELAY",
desc: '''Phase delay of the PWM rising edge, in units of 2^(-16) PWM
cycles''',
resval: "0x0000"
}
]
}
},
{ multireg: { name: "DUTY_CYCLE",
desc:'''Controls the duty_cycle of each channel.''',
count: "NOutputs"
swaccess: "rw",
cname: "duty_cycle",
async: "clk_core_i",
hwqe: "true",
regwen: "REGWEN",
fields: [
{ bits: "31:16",
name: "B",
desc: '''The target duty cycle for PWM output, in units
of 2^(-16)ths of a pulse cycle. The actual precision is
however limited to the (DC_RESN+1) most significant bits.
This setting only applies when blinking, and determines
the target duty cycle.
'''
resval: "0x7fff"
}
{ bits: "15:0",
name: "A",
desc: '''The initial duty cycle for PWM output, in units
of 2^(-16)ths of a pulse cycle. The actual precision is
however limited to the (DC_RESN+1) most significant bits.
This setting applies continuously when not blinking
and determines the initial duty cycle when blinking.
'''
resval: "0x7fff"
}
]
}
},
{ multireg: { name: "BLINK_PARAM",
desc: "Hardware controlled blink/heartbeat parameters.",
count: "NOutputs"
swaccess: "rw",
cname: "blink_param",
async: "clk_core_i",
hwqe: "true",
regwen: "REGWEN",
fields: [
{ bits: "15:0",
name: "X",
desc: '''This blink-rate timing parameter has two different
interpretations depending on whether or not the heartbeat
feature is enabled. If heartbeat is disabled, a blinking
PWM will pulse at duty cycle A for (X+1) pulses before
switching to duty cycle B. If heartbeat is enabled
the duty-cycle will start at the duty cycle A, but
will be incremented (or decremented) every (X+1) cycles.
In heartbeat mode is enabled, the size of each step is
controlled by BLINK_PARAM.Y.'''
resval: "0x00"
}
{ bits: "31:16",
name: "Y",
desc: '''This blink-rate timing parameter has two different
interpretations depending on whether or not the heartbeat
feature is enabled. If heartbeat is disabled, a blinking
PWM will pulse at duty cycle B for (Y+1) pulse cycles
before returning to duty cycle A. If heartbeat is enabled
the duty cycle will increase (or decrease) by (Y+1) units
every time it is incremented (or decremented)'''
resval: "0x0"
}
]
}
}
]
}