Professional Documents
Culture Documents
c
=
1
LC
Equation 2
This frequency determines the system response speed of each phase operating individually.
For a given capacitance, a larger inductance will result in a larger charge time. In a
multiphase converter where only one phase is active, the corner frequency can be defined as
the following:
c
i
=
1
L
i
C
Equation 3
In this case, L
i
is the inductance of phase i. The output capacitance is shared and therefore
the same for all phases. For a fixed capacitance, the charge time depends only on the
inductance. As a result, a phase with a large inductance will result in a long charge time, and
this corresponds to a small steady-state current ripple contribution for that phase.
The LC estimation process is illustrated in Figure 3.14. Before beginning the LC Estimation
and Sequencing step, all controllers switch into bus mode to allow information to be shared
among all phases. Switch S
2
in each phase is set such that the ADC reference is set to V
ref1
,
which is below the rated output voltage reference, V
ref2
, as illustrated in Figure 3.2. The
CHAPTER 3: SYSTEM DESCRIPTION 43
starting phase begins the procedure by switching at a fixed duty ratio in open-loop while the
other phases wait. As soon as an output voltage of V
ref1
is reached, the starting phase stops
and discharges the output. The time taken to charge the output, in units of switching periods,
is recorded. The initial phase transmits this charge time to all other phases in the system, and
the other phases store the value in registers. Since only 4 bits of data are sent during each
transmission, multiple data transmissions are used in case the charge time may exceed 2
4
switching cycles. At this point the second phase repeats this process, and so on. When all
phases have finished, each phase has knowledge of its own charge time and the charge times
of all other phases. These charge times are now used to order the phases, minimizing the
total ripple.
Figure 3.14: The charging and discharging process for estimating the LC products
The phases each independently determine their order in the switching cycle. A flowchart of
the algorithm is shown in Figure 3.15. Each phase compares its own charge time to those of
the other phases, and counts the number of phases with small charge times, or larger
estimated inductances. To avoid a conflict arising from multiple phases having identical
CHAPTER 3: SYSTEM DESCRIPTION 44
estimated inductances, the ring order of each phase, found during the Phase Detection
process, is appended onto the charge times. This avoids the problem where multiple phases
place themselves in the same location of the switching sequence, which would lead to poor
interleaving, contradicting the purpose of the phase sequencing procedure. Each phase takes
the binary value corresponding to the number of phases with larger estimated inductances
appended with its ring order, and performs a circular bit shift on this value. The result of this
operation is a number ranging from 0 to (n 1), where n is the number of phases in the
system. This number corresponds to each phases order in the switching sequence. This has
the effect of placing phases with similar estimated inductance values 180 apart from each
other in the switching sequence. Note that if the number of phases is odd, two phases cannot
be placed 180 apart from each other; however, they will be placed approximately 180 apart.
CHAPTER 3: SYSTEM DESCRIPTION 45
Figure 3.15: Flowchart of the phase sequencing algorithm
Table 3.2 provides an example of phase reordering based on measured charge times. In this
example the first 2 phases in the ring have charge times of 10 switching cycles, the third
phase has a charge time of 5 cycles and the fourth phase has a charge time of 6 cycles.
Therefore, the first two phases have inductances that are larger than those of the last two
phases. Each phase counts the number of phases with smaller charge times compared to its
own charge time. In this example the first two phases would place themselves into the same
order. To resolve this issue, the charge times are appended with each phases position in the
CHAPTER 3: SYSTEM DESCRIPTION 46
ring (found during the Phase Detection process), and these values are used during the
comparisons. The charge time appended with the ring position is unique for all phases since
the ring positions are unique and, as a result, the resulting phase orders are unique. Each
phase then performs a circular bit shift operation on this value to determine its switching
sequence order. The circular bit shift operation was chosen because its digital hardware
implementation is very simple. This has the effect of placing phases with similar values
calculated in column 4 of
Table 3.2 opposite each other in the switching sequence. The result of this operation will be
unique for each phase and the values will range from 0 to (n 1). This operation also works
properly with an odd number of phases; unique phase orders ranging from 0 to (n 1) will
still be produced in these cases. Once the LC Estimation and Sequencing procedure is
complete, the Digitally-Controlled DLL step begins.
1. Phase ID 2. Charge Time
3. Charge
Time
Appended
with
Phase ID
4. Number of
Phases with
Smaller Charge
Times
5. Switching
Sequence Order
Decimal Binary Decimal Binary Binary Decimal Binary Decimal Binary
0 00 10 1010 1010-00 2 10 1 01
1 01 10 1010 1010-01 3 11 3 11
2 10 5 0101 0101-10 0 00 0 00
3 11 6 0110 0110-11 1 01 2 10
Table 3.2: An example of phase reordering based on charge times with 4 phases.
3.3.4 Digitally-Controlled DLL
The Digitally-Controlled DLL is used for timing the switching signals of the phases for
interleaved operation. In the proposed design, one of the phases is selected as the Timing
CHAPTER 3: SYSTEM DESCRIPTION 47
Phase. This phase is responsible for dictating the timing of the beginning of the switching
cycles of all other phases, such that the switching pulses of all phases are evenly spaced.
3.3.4.1 Selection of the Timing Phase
The timing operations for interleaved operation are centralized in one of the phases in order
to ensure that the switching signals are evenly spaced. If the timing procedure were to be
distributed among all phases, there could be small discrepancies in timing due to process
variation among the controllers. In other words, the switching signals would not necessarily
be evenly spaced over the course of a switching period. Although this would still result in
approximate ripple cancelation, undesirable harmonic noise could be produced.
Another advantage of using only one phase for timing is that an external reference clock is
not required. This reduces the pin requirements of the controllers. The only requirement is
an internally generated clock signal with a frequency equal to the desired switching
frequency.
In the proposed design, all controllers are identical and they are therefore all capable of
producing the timing signals necessary for interleaved operation. The selection of the Timing
Phase could be arbitrary; it does not matter which phase is selected as long as exactly one
phase is designated as the Timing Phase. In the proposed design, the first phase in the
switching sequence is selected.
CHAPTER 3: SYSTEM DESCRIPTION 48
3.3.4.2 Clock Generation Architecture
The purpose of the Digitally-Controlled DLL is to produce a clock signal with a frequency of
nf
s
for a system having n phases and a switching frequency of f
s
. A clock with a frequency of
nf
s
is required to evenly space the switching signals of all phases for interleaved operation.
Since the plug-and-play controllers are designed to function with an arbitrary number of
phases, the Digitally-Controlled DLL must be capable of producing clock signals of different
frequencies.
Table 3.3 lists the required output clock frequencies and periods of the Digitally-Controlled
DLL for a system operating at a switching frequency of 1 MHz (corresponding to a switching
period of 1s) with different quantities of phases.
n (number of phases) nf
s
(output frequency)[MHz] 1/(nf
s
) (output period) [ns]
2 2 500.00
3 3 333.33
4 4 250.00
5 5 200.00
6 6 166.67
7 7 142.86
8 8 125.00
9 9 111.11
10 10 100.00
Table 3.3: Required output frequencies and periods for a system operating at a switching frequency of 1 MHz
for various phase counts
The Digitally-Controlled DLL, shown in Figure 3.16, has two main components: a
Programmable Ring Oscillator and a Digital Frequency Compensator. The Digital
Frequency Compensator adjusts the inputs to the Programmable Ring Oscillator such that
the desired output clock frequency is achieved. The inputs to this module are n, a digital
value corresponding to the number of phases, and a clock with a frequency of f
s
. the
CHAPTER 3: SYSTEM DESCRIPTION 49
switching frequency. The outputs are a clock with a frequency of nf
s
and a signal indicating
when the correct output frequency has been achieved.
Figure 3.16: Digitally-Controlled DLL block diagram
The Programmable Ring Oscillator of Figure 3.16 consists of number of digitally
programmable delay cells arranged in a ring configuration and connected through 2-to-1
multiplexors. The delay cells are similar to the current-starved delay cells presented in [24].
A NAND-gate is also included in the ring for the inversion required to produce an oscillating
clock signal. The NAND-gate also allows the ring oscillator to be disabled, conserving
power when not needed. There are two methods of changing the output clock frequency: the
programmable delay cell control signals and the multiplexor inputs. Each programmable
delay cell has a digital control input that varies the propagation delay through the cell. The
multiplexors allow the number of programmable delay cells in the ring to be varied.
Depending on the multiplexor control signal, the previous delay cell can either be omitted or
included in the ring.
CHAPTER 3: SYSTEM DESCRIPTION 50
The Digital Frequency Compensator is responsible for adjusting the delay cell and
multiplexor control signals in order to achieve the desired output clock frequency. The
module compares the frequency of the output to that of the input by measuring the number of
output clock cycles over the course of a large number of input clock cycles. Using this
feedback, it iteratively adjusts the Programmable Ring Oscillator control signals to produce
an output clock with a frequency as close as possible to nf
s
. Although the controller cannot
lock to a frequency of exactly nf
s
due to the quantization of the control signals, it behaves in a
similar fashion to a standard analog delay-locked loop. However, its control is performed in
a completely digital fashion.
A flowchart presenting the operation of the Digital Frequency Compensator is shown in
Figure 3.17. The delay cell and multiplexor control signals are first set to a starting value.
Next, a counter is enabled that counts the number of cycles of the output clock, clk_out.
Simultaneously, a counter is enabled that counts the number of cycles of the input clock,
which has a frequency of f
s
. After a period of M input clock cycles, the counters are disabled
and there outputs are compared. If the output clock counter is greater than nM, where n is the
number of phases, the ring oscillator is too fast. In this case, the control signals are adjusted
such that the delay of the ring oscillator is increased. The counting process repeats itself
until the output clock counter is less than nM. The reverse occurs for the latter case. In this
way, the control signals are adjusted in an iterative manner until an output frequency close to
the desired value is achieved. At this point, the Locked output of the Digitally-Controlled
DLL is raised and regular operation of the system may now begin.
The range and resolution of the Digitally-Controlled DLL depend on a number of factors. A
larger number of multiplexors and Programmable Delay Cells with shorter delays will result
CHAPTER 3: SYSTEM DESCRIPTION 51
in a wider range of possible output frequencies. Also, adjusting the number of control
signals for the Programmable Delay Cells can increase the delay resolution and therefore can
allow the output frequency to be more closely matched to a frequency of nf
s
. It should be
noted that changing the specifications can result in different chip area and power
requirements, so a reasonable compromise should be chosen. Also, the Digitally-Controlled
DLL only needs to be capable of generating frequencies larger than 2f
s
since the input clock
is used for timing with a single phase.
In the prototype design, the Digitally-Controlled DLL begins locking the output clock signal
only after the LC Product Estimation and Sequencing step is complete. However, in order to
reduce the time required for the initialization process, the Digitally-Controlled DLL could be
activated simultaneously with the LC Product Estimation and Sequencing block, directly
after the Phase Detection process is complete (the correct frequency can only be produced
once the number of phases is known).
CHAPTER 3: SYSTEM DESCRIPTION 52
Figure 3.17: Flowchart of the operation of the Digital Frequency Compensator
CHAPTER 3: SYSTEM DESCRIPTION 53
3.3.5 Regular Operation
Once the phases have been counted and ordered, and the output of the Digitally-Controlled
DLL has locked to the correct frequency, regular operation begins. The regular operation of
the system involves two concurrent functions. The timing phase measures the output voltage
using its ADC and transmits the error signal across the bus at the appropriate instances. At
the same time, all the phases continuously monitor the bus to determine when they should
begin their switching actions. They read the error signals from the bus in order to calculate
and produce the correct duty ratios.
Shortly after the Digitally-Controlled DLL has locked to the correct frequency for clk_out,
the timing phase begins measuring the output voltage with its ADC. Then, it transmits this
error across the bus at the positive edge of the first clk_out cycle. At the next (n 1) positive
edges of clk_out, the timing phase transmits the same error. After n cycles, one switching
period has taken place, and the timing phase samples the error signal once again, and
transmits the new value onto the bus, and the process repeats. Since the error signal is
generated by the ADC of only one phase, mismatches in the ADCs among different phases
are not a concern. In the design, it is assumed that the error signals is 4 bits, so only one data
transmission is necessary.
After the LC Estimation and Sequencing step, all phases (including the timing phase) monitor
the bus to detect when regular operation should begin. It starts after the timing phase
executes its first data transmission, at which point the first phase in the series reads the error
value. The first phase sends this data to its compensator to produce the desired value for the
CHAPTER 3: SYSTEM DESCRIPTION 54
duty ratio sent to the DPWM, and first switching cycle begins. After the second data
transmission, the second phase does the same, and so on. After n transmissions, the first
phase begins its second switching cycle and this process repeats itself indefinitely. All
phases constantly monitor the bus, keeping count of the number of transmissions. Since each
phase has a unique order in the switching cycle, each transmission corresponds to the
beginning of only one phases switching cycle.
Figure 3.18 illustrates an example of regular operation with four phases. The output of the
Digitally-Controlled DLL for the timing phase is shown as clk_out(t). This clock has a
frequency of approximately 4f
s
. At each positive edge of this clock, the timing phase
transmits the error signal onto the bus, comm_out(t). Over the course of four transmissions,
all phases begin a new switching cycle. The switching signals of the four phases (outputted
by their corresponding DPWMs) are shown as c
i
(t). The period of each of these signals is f
s
,
the desired switching frequency of the system. Also, due to the timing of the data
transmissions, the switching signals are properly interleaved; they are evenly spaced apart
from each other by a time period of T
s
/4. From the time that the timing phase begins
transmitting an error signal until the corresponding phase begins its next switching cycle,
there is a small delay, t
d
. This delay is due to the fact that the data transmission and
computation takes a finite period of time. However, this delay is nearly the same for all
phases, so it does not affect the interleaving.
CHAPTER 3: SYSTEM DESCRIPTION 55
Figure 3.18: Waveforms during regular operation in steady-state
CHAPTER 4: EXPERIMENTAL VERIFICATION 56
Chapter 4
Experimental Verification and Results
4.1 Experimental Systems
Two experimental controllers were used to verify the functionality of the proposed design: a
large-scale FPGA-based prototype and a custom-built IC implementation. The systems are
described in the following sections.
4.1.1 FPGA-Based Implementation
The FPGA-based implementation consists of an Altera DE2 development board linked to a
PCB, with a plug-in interface allowing power stages to be easily added and removed, as
shown in Figure 4.1. All the controllers have been synthesized on a single FPGA chip.
However, each controller is identical and implemented in a separate module, ensuring that
masterless behaviour occurs. The Digitally-Controlled DLL (3.3.4) could not be fully
implemented on the FPGA system due to its need for analog hardware. In its place, a dual-
CHAPTER 4: EXPERIMENTAL VERIFICATION 57
output DPWM was employed. In addition to producing standard PWM signals for the gate
drivers, the dual-output DPWM also supplies timing signals for dictating when the phases
should begin their switching cycles. These timing signals are set based on the number of
phases in the system, allowing for interleaved operation at a nearly constant frequency. The
FPGA-based system allowed quick synthesis of the system, such that the controller
prototypes could be tested.
Figure 4.1: FPGA-based prototype
4.1.2 IC Implementation
4.1.2.1 Chip Overview
The controller was implemented and fabricated on an integrated circuit (IC) using a 0.18m
CMOS process. This chip functions as a plug-and-play controller for one phase; in the case
CHAPTER 4: EXPERIMENTAL VERIFICATION 58
of a multiphase system, multiple chips are placed into the ring configuration of Figure 3.1.
The IC demonstrates the feasibility of a practical implementation of the system.
Furthermore, several components were implemented on the IC that could not be easily
realized on a FPGA-based system. In Figure 4.2, a photograph of the die of the fabricated IC
is shown. Note that a portion of the chip area was used for another unrelated design. The
controller has been implemented within an area of approximately 1.2 mm
2
including its pads.
The specifications of the chip are summarized in Table 4.1. The PCB board layout and
schematic diagrams are provided in Appendix C.
A total of 27 pins were used in the IC implementation. However, most of these were used for
the purpose of programming and debugging, and thus would not be required for an industrial
implementation of the chip. Without the programming and debugging pins, and assuming
only one VDD and one VSS pin are required, the IC could potentially be implemented with
as few as 8 pins (VDD, VSS, reset, comm_in, comm_out, v_out, switch_HS, and
switch_LS), or even fewer if the power switches and gate drivers were to be integrated onto
the chip.
Certain functions on the chip were unfortunately not fully functional. Specifically, the
transmission gate failed to adequately pass the necessary current, resulting in slow rise and
fall times during communication in bus mode. As a result, the chip failed to function
properly with more than two phases. The chip does, however, demonstrate basic
functionality with one or two phases.
CHAPTER 4: EXPERIMENTAL VERIFICATION 59
Figure 4.2: Die photograph of the fabricated IC
Specification Value
CMOS Technology 0.18 m
Chip Area (excluding pins) 0.35 mm
2
Pin Count (actively used) 27
Switching Frequency (f
s
) 500 kHz
DPWM Resolution 8 bits
Communication delay per bit 20 ns
CHAPTER 4: EXPERIMENTAL VERIFICATION 60
Table 4.1: Chip specifications
4.1.2.2 On-Chip Components
A diagram of the chips layout and its main components is shown in Figure 4.3. The main
components are the Digital Controller, the Communication Block and Transmission Gate,
the DAC and ADC, and the Digitally-Controlled DLL. The chip area required for each of
these components is listed in
Table 4.2.
Component Chip Area [mm
2
]
Digital Controller 0.194
Communication Block and Transmission Gate 0.018
DAC and ADC 0.093
Digitally-Controlled DLL 0.041
Table 4.2: Chip area required by each component
CHAPTER 4: EXPERIMENTAL VERIFICATION 61
Figure 4.3: Chip layout diagram
The Digital Controller was synthesized from Verilog HDL and the layout was realized using
a standard digital cell library. The Verilog HDL code is included in Appendix A. The
Digital Controller includes the Phase Detector (3.3.2), the LC Estimator and Sequencer
(3.3.3), the Digital Frequency Compensator for the Digitally-Controlled DLL block (3.3.4),
and the controller for regular operation (3.3.5). Also included is a Programmable Unit,
which allows various parameters, such as the compensator coefficients, to be programmed
CHAPTER 4: EXPERIMENTAL VERIFICATION 62
onto each chip. In addition, the Programmable Unit allows information on the status of each
chip to be monitored. While not necessary for basic functionality, the Programmable Unit
was useful for analyzing and debugging the prototype chip. As a result, the chip has not been
optimized in order to reduce its area. On a commercial version of the chip, the area could be
reduced significantly by removing the unnecessary components and/or using a smaller
CMOS technology.
The Communication Block was implemented using a gate-level netlist of digital cells from a
standard cell library. The gate-level netlist is included in Appendix B. The transmitter and
receiver were implemented as shown in Figure 3.4 using delay cells.
The DAC and ADC from [25] are used on the chip. The purpose of the DAC is to supply a
reference voltage for the ADC. The reference voltage can be varied based on a digital input.
A programmable DAC was chosen because different voltage references are needed
depending on the stage of operation. During the LC estimation and sequencing stage, the
reference needs to be lower than the steady-state reference so that the output voltage is
charged to only a low value.
4.2 Experimental Results
The proposed system was verified using an experimental setup consisting of a PCB
supporting up to four power stages. The PCB was designed such that phases can be easily
added or removed from the system using a plug-in interface. Certain functions of the
controller have been verified with the IC implementation while others have been verified
with the FPGA-based implementation.
CHAPTER 4: EXPERIMENTAL VERIFICATION 63
4.2.1 Single Phase Operation
Single phase operation with a plug-and-play controller is similar to operation with a non-
scalable single phase system, except that the controller must recognize that only a single
phase is present and respond appropriately.
Figure 4.4 shows the start-up procedure with a single phase using the IC. The input
communication signal, the output voltage, and the output PWM switching signal are shown.
With single phase operation, the communication signal sent from the controller is directly
linked to its communication input port, since only one controller is present in the ring
configuration.
The auto-configuration process begins with a reset signal being sent to the controller. The
reset signal is also connected to the controllers communication input through a tri-state
buffer. As a result, the controller is able to identify itself as the initial phase, using the first
starting phase detection procedure described in 3.3.2.2. Next the Phase Detection Process
begins (3.3.2.1), where a value of 1 is sent to the next phase in the ring. Since only one
phase exists, the value is immediately received at the communication input port of the
controller. As a result, the controller recognizes that it is the only phase in the system and
thus single phase operation should be performed, and the LC Product Estimation and
Sequencing and Digitally-Controlled DLL processes are omitted.
Single-phase, closed-loop operation begins immediately after the controller recognizes itself
as the only phase. An enlarged view of the steady-state closed-loop operation with a single
phase is shown in Figure 4.5.
CHAPTER 4: EXPERIMENTAL VERIFICATION 64
Figure 4.4: Start-up procedure for single phase operation using the IC controller
Output voltage
PWM signal
Figure 4.5: Closed-loop steady-state single phase operation with the IC controller
CHAPTER 4: EXPERIMENTAL VERIFICATION 65
4.2.2 Multiphase Operation
Operation with multiple phases has been fully verified using the FPGA-based system and
partially demonstrated using the IC-based controllers. In multiphase operation, the
controllers must identify the number of phases, optimize the phase sequence, and share
timing and error information for interleaving and voltage regulation.
Figure 4.6 presents the entire auto-configuration process with 4 phases using the FPGA
setup. First, the Phase Detection Process occurs, where the phases communicate with each
other as described in 3.3.2.1 to determine that 4 phases exist. Next, the LC Product
Estimation and Sequencing is performed, where each phase charges the output to a value
below the reference value. This information is used to sequence the phases in the optimal
order to minimize the output voltage ripple, as described in 3.3.3. The details and effect of
the sequencing process will be discussed in 4.2.3. Next, regular operation of the system
begins, where the controllers regulate the output voltage to the reference value and
sequenced, interleaved operation occurs.
CHAPTER 4: EXPERIMENTAL VERIFICATION 66
Figure 4.6: Configuration and regular operation with 4 phases with the FPGA-based controller
The interleaved switching sequences in steady-state for various numbers of phases are shown
in Figure 4.7, Figure 4.8, Figure 4.9, and Figure 4.10. Open-loop operation with 2 phases
using the IC controller is shown in Figure 4.7. In this case, the switching signals of the 2
phases are interleaved approximately 180 apart from each other. In Figure 4.8, Figure 4.9,
and Figure 4.10, steady-state closed-loop operation is demonstrated with the FPGA-based
system for 2, 3, and 4 phases, respectively. Even interleaved operation is achieved, where
the switching signals are spaced 180, 120, and 90 apart from each other, respectively. In
each of these cases, approximately the same switching frequency is maintained.
CHAPTER 4: EXPERIMENTAL VERIFICATION 67
Figure 4.7: Open-loop operation with 2 phases using IC controllers
Figure 4.8: Closed-loop steady-state operation with 2 phases using the FPGA-based system
CHAPTER 4: EXPERIMENTAL VERIFICATION 68
Figure 4.9: Closed-loop steady-state operation with 3 phases using the FPGA-based system
Figure 4.10: Closed-loop steady-state operation with 4 phases using the FPGA-based system
CHAPTER 4: EXPERIMENTAL VERIFICATION 69
4.2.3 Phase Sequencing
In this section the phase sequencing procedure is demonstrated and the effect of the
procedure is compared to the case where the phases are not optimally sequenced. As
described in 3.3.3, the order that the phases are sequenced in a multiphase system can have
an impact on the total output ripple due to mismatches in the inductor values.
Figure 4.11: One phase completes the charge process to estimate its LC product
The charge process for one phase is illustrated with the FPGA-based system in Figure 4.11.
In this figure, the phase enables its power stage with a fixed duty cycle and measures the time
it takes to charge the output to 0.4V, while the other phases are disabled. After this occurs,
the output voltage is discharged. The output is charged to a voltage well below the rated
output of 1.5V, such that the load does not enable itself.
CHAPTER 4: EXPERIMENTAL VERIFICATION 70
Figure 4.12: The charge process for two phases with different inductance values
Figure 4.12 demonstrates the charge process for two phases having different inductance
values: one phase has an inductance of 0.5H and the other phase has an inductance of
1.0H. It can be seen that a significant difference in charge times exists, allowing for proper
phase sequencing to occur. As expected, a larger charge time corresponds to a larger
inductance. Also, the phases are charged one at a time so that the inductance of each phase
can be estimated individually. Figure 4.13 and Figure 4.14 show the steady-state AC current
ripples corresponding to these two phases. The phase with the 0.5H inductance has a
steady-state peak-to-peak current ripple contribution of 2.20A while the phase with the
1.0H inductance has a steady-state peak-to-peak current ripple contribution of 1.19A.
These current ripples were measured in a four phase system; however, they are the individual
current contributions for these phases. As expected, the phase with the larger inductance has
a larger charge time and a smaller peak-to-peak current ripple contribution.
CHAPTER 4: EXPERIMENTAL VERIFICATION 71
Figure 4.13: The steady-state AC current ripple of the phase with a 0.5H inductor
Figure 4.14: The steady-state AC current ripple of the phase with a 1.0H inductor
The effect of using the information extracted during the LC product estimation procedure is
demonstrated for a four phase system in Figure 4.15 and Figure 4.16. In both cases, two of
CHAPTER 4: EXPERIMENTAL VERIFICATION 72
the four phases have inductances of 0.5H while the other two phases have inductance of
1.0H. In Figure 4.15 and Figure 4.16, the total output current ripple is shown, whereas
Figure 4.13 and Figure 4.14 each show the ripple contribution from only a single phase.
Both cases result in a reduction in total current ripple, demonstrating one of the key
advantages of a multiphase system.
In Figure 4.15, the LC product estimation and phase sequencing algorithm has been disabled.
In this case, the phases are sequenced in their default order, which corresponds to the worst
case scenario where phases with similar inductance values are placed adjacent to each other
in the switching sequence. In this case, the magnitude of the total peak-to-peak current ripple
is 1.14A. This is only a minor improvement compared to the single phase case of Figure
4.14 due to the mismatch in inductor values.
In Figure 4.16, the phase order optimization has been implemented. In this case, phases with
similar inductance values are placed 180 apart from each other in the switching sequence.
This results in a total peak-to-peak current ripple of 0.69A, which represents a 39% reduction
compared to the case where the phase order optimization is disabled. This could allow for a
proportional reduction in the size of the output filter capacitor.
The shape of the voltage waveforms in Figure 4.12 does not have a perfectly quadratic shape,
as would be expected for a second-order system. The waveform appears to have a large
slope at the beginning of the charge process, followed by a reduced slope. This is likely
caused by non-linear behaviour of the output capacitor. The output capacitor may exhibit
different capacitance values at difference voltages, causing the waveform to be slightly
misshapen.
CHAPTER 4: EXPERIMENTAL VERIFICATION 73
Figure 4.15: The steady-state total AC current ripple with unoptimized phase sequencing
Figure 4.16: The steady-state total AC current ripple with optimized phase sequencing
CHAPTER 4: EXPERIMENTAL VERIFICATION 74
4.2.4 Communication Protocol
The communication block could not be fully implemented on the FPGA-based controller
because the FPGA only supports purely digital hardware. Also, it was not fully functional on
the IC-based controller due to problems related to the transmission gate and driving power.
As a result, simulations are provided illustrating the desired behaviour of the communication
block.
A simulation showing the functionality of the communication block is provided in Figure
4.17. The simulation was performed with a SPICE net list consisting of 8 communication
blocks in a ring configuration. The output of block 0 is connected to the input of block 1, the
output of block 1 is connected to the input of block 2, and so on. To complete the ring, the
output of block 7 is connected to the input of block 0. The simulation does not show realistic
behaviour with respect to the rest of the controller, but is rather meant to demonstrate the
general functionality of the communication block.
In the simulation of Figure 4.17, the 8 communication blocks take turns transmitting data.
From 0 ns to 900 ns, the communication protocol operates in series mode (since the BusMode
signal is low). During this period, data sent from each phase is only received by the very
next phase in the ring (only one comm_out signal is active at any time between 0 ns and 900
ns). Also, the data received (RXData) matches the data transmitted (TXData). The positive
edges of the ReceiveEnd signals indicate when each communication block has finished
receiving a transmission. At 900 ns, the communication blocks switch into bus mode, when
the BusMode signal becomes high. After 900 ns, data sent from any of the communication
CHAPTER 4: EXPERIMENTAL VERIFICATION 75
blocks is received by all the other blocks. This is verified since all comm_out signals are
equal during this period, since the transmission gates have been closed. Also, all phases
receive the same data while in bus mode.
Figure 4.17: Simulation of 8 communication blocks arranged in a ring configuration
CHAPTER 5: CONCLUSIONS AND FUTURE WORK 76
Chapter 5
Conclusion
5.1 Thesis Summary and Contributions
A new architecture for plug-and-play controllers for scalable low-power SMPS has been
proposed in this work. The controllers operate in both single phase mode and multiphase
mode, with a variable number of phases. No central control is required for multiphase
operation as the control is performed masterlessly. The controllers are able to identify the
number of phases using an auto-configuration process during start-up. They are also capable
of sequencing themselves in an order that reduces the output ripple during interleaved
operation.
This auto-configuration allows the same controller design to be used in a wide variety of
applications requiring different quantities of phases. The simple communication interface
CHAPTER 5: CONCLUSIONS AND FUTURE WORK 77
among the phases leads to a low pin count, allowing the architecture to be used as a cost-
effective solution in both single phase and multiphase applications.
The proposed design was verified using FPGA- and IC-based prototype systems. The
experimental systems successfully perform the auto-configuration process where the number
of phases is identified and the phases are placed into a sequence that minimizes the ripple.
Also, closed-loop, interleaved operation is achieved using the proposed communication
protocol. The system is also capable of operating at a fixed frequency with even interleaving
with various phase counts.
5.2 Future Work
The prototype system has been implemented and tested using voltage mode control.
However, its structure has been designed in such a way that it can be adapted for current-
programmed mode (CPM) control. CPM control can offer numerous advantages such as
simpler dynamics, inherent over-current protection, and equal current sharing in multiphase
converters.
In order to realize CPM control in multiphase systems, each controller must measure the
current contribution of its phase using a current sensor. CPM control can then be
implemented based on these measurements in addition to the output voltage measurement.
The information could be further used to achieve equal current sharing among the phases. In
a practical system without current feedback, the inductor currents among the phases will not
be equal due to parasitic elements and timing (i.e., one phase begins before the others during
CHAPTER 5: CONCLUSIONS AND FUTURE WORK 78
start-up, resulting in a higher dc current in that phase). Also, equal current sharing prevents
phases from sinking current, which could severely degrade the systems overall efficiency.
In the described system, each plug-and-play controller could measure its current and share
the information with other phases in order to achieve CPM control, equal current sharing, and
over-current protection. The necessary modifications for each plug-and-play controller
would be the addition of a current sensor, the adaption of the compensator to support CPM
control, and modifying the controller to read and transmit current measurements over the bus,
in addition to output voltage measurements. An example of the data transmissions on the bus
with corresponding switching signals is shown in Figure 5.1 during steady-state for the case
of a multiphase system with 4 phases.
Figure 5.1: Current measurements being shared on the communication bus in CPM mode
Another possible extension to this work is the integration of an auto-tuning design into the
compensator for true plug-and-play support. These auto-tuning systems, described in 2.5,
could be used to dynamically adjust the compensators to achieve optimized dynamic
performance for power stages with varying parameters. This would achieve some of the
same advantages encountered with single phase auto-tuning controllers: power stage
CHAPTER 5: CONCLUSIONS AND FUTURE WORK 79
parameters could be allowed to vary without requiring the compensator to be re-designed. In
a multiphase system, an auto-tuning controller could further compensate for variations in the
number of power stages. Without an auto-tuning controller, the compensators would likely
need to be reprogrammed for each different application. This process would lead to an
increase in cost. Also, pins would be required so that each controller could be programmed,
increasing the pin count of the controller.
APPENDIX A: VERILOG HDL FOR DIGITAL BLOCKS 80
Appendix A: Verilog HDL for Digital
Blocks
/*******************************************************************************************
/ Module: pap_digital_low
/ Written by: Jason Weinstein
/
/ Combines all modules operating at the low frequency clock
*******************************************************************************************/
module pap_digital_low (Reset, clk, ReceiveEnd, RXData, BusMode, BusModeNot,
is_initial_phase, ADCIn, MuxControl, DelayControl, ClkDLL, Error, VrefOut, EnableDPWM,
PhaseCount, PhaseOrder, DonePhaseSequence, DonePhaseCount, DPID, DLast, OpenLoop, DOpenLoop,
Discharge, ClkProgram, DataBus, DCharge, DebugRail, RingOscFreq, DeadTime, Transmit, TXData,
D, ADCSamplePhaseTimer, DAC_enable, DAC_freq, Prog_select, ADC_enable, Ring_osc_enable,
DLL_enable);
input Reset;
input clk;
input [3:0] RXData;
output BusMode;
output BusModeNot;
input is_initial_phase;
input [3:0] ADCIn;
output [6:0] MuxControl;
output [2:0] DelayControl;
input ClkDLL;
input [3:0] Error;
output [9:0] VrefOut;
output EnableDPWM;
output [3:0] PhaseCount;
output [3:0] PhaseOrder;
output DonePhaseCount;
output DonePhaseSequence;
output [15:0] DPID;
input [15:0] DLast;
output OpenLoop;
output [7:0] DOpenLoop;
output Discharge;
input ClkProgram;
input [7:0] DataBus;
output [7:0] DCharge;
output [3:0] DebugRail;
output [7:0] RingOscFreq;
output [7:0] DeadTime;
output Transmit;
output [3:0] TXData;
input [7:0] D;
output ADCSamplePhaseTimer;
input ReceiveEnd;
output DAC_enable;
output [2:0] DAC_freq;
input Prog_select;
output ADC_enable;
output Ring_osc_enable;
output DLL_enable;
assign BusModeNot = !BusMode;
wire PhaseEnabled;
APPENDIX A: VERILOG HDL FOR DIGITAL BLOCKS 81
wire InitialPhaseOverride;
wire InitialPhaseOverrideValue;
wire Start;
wire [3:0] TXDataPhaseCounter;
wire TransmitPhaseCounter;
wire EnableDPWMPhaseSequencer;
wire VoltageLevel;
wire ReOrderPhases;
wire [15:0] PhaseTimer;
wire PhaseOrderOverride;
wire [3:0] PhaseOrderOverrideValue;
wire TransmitPhaseSequencer;
wire [3:0] TXDataPhaseSequencer;
wire Locked;
wire MuxControlOverride;
wire DelayControlOverride;
wire [6:0] MuxControlOverrideValue;
wire [2:0] DelayControlOverrideValue;
wire [7:0] DeadTime;
wire [9:0] Vref0;
wire [9:0] Vref1;
wire HalfClock;
wire [15:0] LUT8; // These 9 entries are the values
for the PI look-up table
wire [15:0] LUT7; // There is a different value for
each error value:
wire [15:0] LUT6; // -4, -3, -2, -1, 0, +1, +2, +3,
+4
wire [15:0] LUT5;
wire [15:0] LUT4;
wire [15:0] LUT3;
wire [15:0] LUT2;
wire [15:0] LUT1;
wire [15:0] LUT0;
wire [3:0] TXDataPhaseTimer;
wire TransmitPhaseTimer;
wire ReceiveSync;
wire [3:0] SmallerPhases;
wire [3:0] PhaseID;
reg [9:0] VrefOutReg;
assign VrefOut = VrefOutReg;
reg EnableDPWMReg;
assign EnableDPWM = EnableDPWMReg;
reg TransmitReg;
assign Transmit = TransmitReg;
reg [3:0] TXDataReg;
assign TXData = TXDataReg;
// Phase counter
phase_counter PC (Reset, clk, ReceiveSync, RXData, TransmitPhaseCounter,
TXDataPhaseCounter, BusMode, is_initial_phase, PhaseID, PhaseCount, DonePhaseCount,
PhaseEnabled, InitialPhaseOverride, InitialPhaseOverrideValue, Start);
// Phase sequencer
phase_sequencer PS (Reset, clk, ReceiveSync, RXData, TransmitPhaseSequencer,
TXDataPhaseSequencer, PhaseID, PhaseCount, DonePhaseCount, EnableDPWMPhaseSequencer,
DonePhaseSequence, PhaseOrder, Discharge, VoltageLevel, ADCIn[3], ReOrderPhases, PhaseTimer,
PhaseOrderOverride, PhaseOrderOverrideValue, SmallerPhases);
// Digital DLL controller
digital_dll_controller DDC (Reset, clk, PhaseCount, Locked, MuxControl, DelayControl,
ClkDLL, DonePhaseSequence, PhaseOrder, MuxControlOverride, DelayControlOverride,
MuxControlOverrideValue, DelayControlOverrideValue);
// Phase timer
phase_timer PT (Reset, ClkDLL, PhaseCount, TXDataPhaseTimer, TransmitPhaseTimer,
Locked, ADCSamplePhaseTimer, ADCIn);
// PI compensator
pi_compensator PIC (DPID, DLast, Error, LUT0, LUT1, LUT2, LUT3, LUT4, LUT5, LUT6,
LUT7, LUT8, DeadTime);
// Programmable unit
APPENDIX A: VERILOG HDL FOR DIGITAL BLOCKS 82
programmable_unit PU (Reset, ClkProgram, DataBus, PhaseEnabled, ReOrderPhases,
InitialPhaseOverride, InitialPhaseOverrideValue, Start, Vref0, Vref1, OpenLoop,
PhaseOrderOverride, DOpenLoop, DeadTime, DCharge, LUT0, LUT1, LUT2, LUT3, LUT4, LUT5, LUT6,
LUT7, LUT8, PhaseOrderOverrideValue, MuxControlOverride, DelayControlOverride,
MuxControlOverrideValue, DelayControlOverrideValue, DebugRail, DonePhaseCount,
DonePhaseSequence, Locked, PhaseID, PhaseOrder, PhaseCount, PhaseTimer, is_initial_phase,
RingOscFreq, D, Error, DelayControl, DAC_enable, DAC_freq, SmallerPhases, Prog_select,
ADC_enable, Ring_osc_enable, DLL_enable);
// Voltage level sent to DAC
always @(VoltageLevel or Vref0 or Vref1)
begin
if (VoltageLevel == 1'b0)
begin
VrefOutReg = Vref0;
end
else
begin
VrefOutReg = Vref1;
end
end
// DPWM enable register
always @(DonePhaseSequence or DonePhaseCount or PhaseCount or
EnableDPWMPhaseSequencer)
begin
if ((DonePhaseSequence == 1'b1 | (DonePhaseCount == 1'b1 & PhaseCount ==
4'b1)))
begin
EnableDPWMReg = 1'b1;
end
else
begin
EnableDPWMReg = EnableDPWMPhaseSequencer;
end
end
// Transmitter registers
always @(DonePhaseSequence or TransmitPhaseTimer or DonePhaseCount or
TransmitPhaseSequencer or TransmitPhaseCounter or TXDataPhaseTimer or TXDataPhaseSequencer or
TXDataPhaseCounter)
begin
if (DonePhaseSequence == 1'b1)
begin
TransmitReg = TransmitPhaseTimer;
TXDataReg = TXDataPhaseTimer;
end
else if (DonePhaseCount == 1'b1)
begin
TransmitReg = TransmitPhaseSequencer;
TXDataReg = TXDataPhaseSequencer;
end
else
begin
TransmitReg = TransmitPhaseCounter;
TXDataReg = TXDataPhaseCounter;
end
end
// Receive synchronization
reg Q1;
reg Q2;
reg Q3;
wire Q3_and_Q1;
assign ReceiveSync = Q2;
always @(negedge Reset or posedge ReceiveEnd or posedge Q3_and_Q1)
begin
if (Reset == 1'b0)
APPENDIX A: VERILOG HDL FOR DIGITAL BLOCKS 83
begin
Q1 <= 1'b0;
end
else if (Q3_and_Q1 == 1'b1)
begin
Q1 <= 1'b0;
end
else
begin
Q1 <= 1'b1;
end
end
always @(negedge Reset or posedge clk)
begin
if (Reset == 1'b0)
begin
Q2 <= 1'b0;
end
else
begin
Q2 <= Q1;
end
end
always @(negedge Reset or posedge clk)
begin
if (Reset == 1'b0)
begin
Q3 <= 1'b0;
end
else
begin
Q3 <= Q2;
end
end
assign Q3_and_Q1 = Q3 & Q1;
endmodule
/*******************************************************************************************
/ Module: pap_digital_high
/ Written by: Jason Weinstein
/
/ Combines all modules operating at the high frequency clock
*******************************************************************************************/
module pap_digital_high (Reset, clk_256, clk, HSSwitch, LSSwitch, DeadTime, EnableDPWM,
Discharge, DonePhaseSequence, DonePhaseCount, PhaseCount, PhaseOrder, ReceiveEnd, RXData,
DPID, DLast, Error, ADCIn, OpenLoop, DOpenLoop, ADCSample, DCharge, DALow,
ADCSamplePhaseTimer);
input Reset;
input clk_256;
input clk;
output HSSwitch;
output LSSwitch;
input [7:0] DeadTime;
input EnableDPWM;
input Discharge;
input DonePhaseSequence;
input DonePhaseCount;
input [3:0] PhaseCount;
input [3:0] PhaseOrder;
input ReceiveEnd;
input [3:0] RXData;
input [15:0] DPID;
output [15:0] DLast;
output [3:0] Error;
input [3:0] ADCIn;
input OpenLoop;
APPENDIX A: VERILOG HDL FOR DIGITAL BLOCKS 84
input [7:0] DOpenLoop;
output ADCSample;
input [7:0] DCharge;
output [7:0] DALow;
input ADCSamplePhaseTimer;
wire [7:0] DOut;
wire DPWMStartRO;
reg [7:0] D;
assign DALow = D;
reg DPWMStartReg;
reg ADCSampleReg;
reg DPWMStartFinal;
reg ADCSampleFinal;
assign ADCSample = ADCSampleFinal;
// DPWM
dpwm DPWM (Reset, clk_256, DPWMStartFinal, HSSwitch, LSSwitch, DeadTime, D,
EnableDPWM, Discharge);
// Regular operation controller
reg_operation RO (Reset, clk_256, clk, DOut, DonePhaseSequence, DonePhaseCount,
PhaseCount, PhaseOrder, DPWMStartRO, ReceiveEnd, RXData, DPID, DLast, Error, ADCIn, OpenLoop,
DOpenLoop);
// Duty ratio register
always @(DonePhaseSequence or DonePhaseCount or PhaseCount or DOut or DCharge)
begin
if ((DonePhaseSequence == 1'b1 | (DonePhaseCount == 1'b1 & PhaseCount ==
4'b1)))
begin
D = DOut;
end
else
begin
D = DCharge;
end
end
// Synchronization across clock domains
always @(negedge Reset or posedge clk_256)
begin
if (Reset == 1'b0)
begin
ADCSampleReg <= 1'b0;
DPWMStartReg <= 1'b0;
end
else
begin
if (DonePhaseSequence == 1'b1)
begin
ADCSampleReg <= ADCSamplePhaseTimer;
DPWMStartReg <= DPWMStartRO;
end
else if ((DonePhaseCount == 1'b1 & PhaseCount == 4'b1))
begin
ADCSampleReg <= clk;
DPWMStartReg <= DPWMStartRO;
end
else
begin
ADCSampleReg <= clk;
DPWMStartReg <= clk;
end
end
end
always @(negedge Reset or posedge clk_256)
begin
if (Reset == 1'b0)
begin
ADCSampleFinal <= 1'b0;
APPENDIX A: VERILOG HDL FOR DIGITAL BLOCKS 85
DPWMStartFinal <= 1'b0;
end
else
begin
ADCSampleFinal <= ADCSampleReg;
DPWMStartFinal <= DPWMStartReg;
end
end
endmodule
/*******************************************************************************************
/ Module: digital_dll_controller
/ Written by: Jason Weinstein
/
/ This module adjusts the number of delay cells in the ring oscillator as well as the
/ programmable delay such that the output clock has a frequency of N x f_s, where N is
/ the number of phases.
*******************************************************************************************/
module digital_dll_controller(Reset, clk, PhaseCount, Locked, MuxControl, DelayControl,
ClkOut, DonePhaseSequence, PhaseOrder, MuxControlOverride, DelayControlOverride,
MuxControlOverrideValue, DelayControlOverrideValue);
input Reset; // Reset signal - active LO
input clk; // Main clock (1 MHz =
f_s)
input [3:0] PhaseCount; // The total number of phases
present in the system - can be sampled
//
once the phase count is complete
output Locked; // Indicates that the DLL has
"locked" at the appropriate frequency
output [6:0] MuxControl; // Indicates which delay cells should be
in the ring - used for coarse
//
frequency adjustments
output [2:0] DelayControl; // Input to all the programmable delay
cells - used for fine frequency
//
adjustments
input ClkOut; // DLL clock output
input DonePhaseSequence; // Goes high once the phase ordering
precedure is complete
input [3:0] PhaseOrder; // The order in the switching
sequence of this phase
input MuxControlOverride;
input DelayControlOverride;
input [6:0] MuxControlOverrideValue;
input [2:0] DelayControlOverrideValue;
reg [9:0] DLLState; // State variable for the main
DLL controller FSM
reg [6:0] MuxControlReg; // Register for storing MuxControl output
reg LockedReg; // Register for storing Locked
output
reg [2:0] DelayControlReg; // Register for storing DelayControl
output
reg [9:0] AuxCounter; // Auxiliary counter used for various
purposes
reg EnableCounter; // Used for enabling the counter
for measuring frequency
reg [9:0] Target; // Target number of oscillations
per 100 oscillations of clk
reg [9:0] TargetCounter; // For counting number of DLL output
oscillations
reg [3:0] TargetCounterState; // State variable for this counter
reg EnableCounterNoGlitch; // Glitch-free version of EnableCounter
reg EnableCounterInter; //
reg [2:0] DelayControlTemp; //
// Assign outputs to various registers
APPENDIX A: VERILOG HDL FOR DIGITAL BLOCKS 86
// More proper than using "output reg"
assign MuxControl = MuxControlReg;
assign Locked = LockedReg;
//
always @(DelayControlReg or DelayControlOverride or DelayControlOverrideValue)
begin
if (DelayControlOverride == 1'b1)
begin
DelayControlTemp = DelayControlOverrideValue;
end
else
begin
DelayControlTemp = DelayControlReg;
end
end
assign DelayControl = DelayControlTemp;
// Main digital DLL controller FSM
always @(negedge Reset or posedge clk)
begin
if (Reset == 1'b0)
begin
DLLState <= 10'b0000000000;
LockedReg <= 1'b0;
DelayControlReg <= 3'b100;
AuxCounter <= 10'b0;
EnableCounter <= 1'b0;
end
else
begin
case (DLLState)
//////////////////////
// Initial state
//////////////////////
// Wait for phase sequencing to be done
// Also, only proceed if this is the first phase
10'b0000000000:
begin
LockedReg <= 1'b0;
DelayControlReg <= 3'b100;
AuxCounter <= 10'b0;
EnableCounter <= 1'b0;
if (DonePhaseSequence == 1'b1 & PhaseOrder == 4'b0000)
begin
DLLState <= 10'b0000000001;
end
else
begin
DLLState <= 10'b0000000000;
end
end
////////////////////////////////
// Do initial comparison
////////////////////////////////
// Wait 100 cycles
// Start with delay cell control variables in the middle
10'b0000000001:
begin
LockedReg <= 1'b0;
DelayControlReg <= 3'b100;
AuxCounter <= AuxCounter + 10'b1;
EnableCounter <= 1'b1;
if (AuxCounter > 10'd100)
begin
DLLState <= 10'b0000000010;
end
else if (DelayControlOverride == 1'b1)
begin
DLLState <= 10'b1110000111;
end
APPENDIX A: VERILOG HDL FOR DIGITAL BLOCKS 87
else
begin
DLLState <= 10'b0000000001;
end
end
// Wait another cycle
10'b0000000010:
begin
LockedReg <= 1'b0;
DelayControlReg <= 3'b100;
AuxCounter <= 10'b0;
EnableCounter <= 1'b0;
DLLState <= 10'b0000000011;
end
// And another
10'b0000000011:
begin
LockedReg <= 1'b0;
DelayControlReg <= 3'b100;
AuxCounter <= 10'b0;
EnableCounter <= 1'b0;
DLLState <= 10'b0000000100;
end
// Check if target is too large or too small
10'b0000000100:
begin
LockedReg <= 1'b0;
DelayControlReg <= 3'b100;
AuxCounter <= 10'b0;
EnableCounter <= 1'b0;
if (TargetCounter >= Target)
begin
DLLState <= 10'b1000000000;
end
else
begin
DLLState <= 10'b1100000000;
end
end
////////////////////////
// Too fast
////////////////////////
// Reduce delay cell control variable by 1'b1
10'b1000000000:
begin
LockedReg <= 1'b0;
DelayControlReg <= DelayControlReg - 3'b1;
AuxCounter <= 10'b0;
EnableCounter <= 1'b0;
DLLState <= 10'b1000000001;
end
// Wait 100 cycles
10'b1000000001:
begin
LockedReg <= 1'b0;
DelayControlReg <= DelayControlReg;
AuxCounter <= AuxCounter + 10'b1;
EnableCounter <= 1'b1;
if (AuxCounter > 10'd100)
begin
DLLState <= 10'b1000000010;
end
else
begin
DLLState <= 10'b1000000001;
end
end
// Wait one more cycle
10'b1000000010:
begin
LockedReg <= 1'b0;
APPENDIX A: VERILOG HDL FOR DIGITAL BLOCKS 88
DelayControlReg <= DelayControlReg;
AuxCounter <= 10'b0;
EnableCounter <= 1'b0;
DLLState <= 10'b1000000011;
end
// And another
10'b1000000011:
begin
LockedReg <= 1'b0;
DelayControlReg <= DelayControlReg;
AuxCounter <= 10'b0;
EnableCounter <= 1'b0;
DLLState <= 10'b1000000100;
end
// Check if target is met - if so we are done
// If control variable is 4'b0000, we are done - can't reduce
any more
// Otherwise, reduce by 1'b1 and go again
10'b1000000100:
begin
LockedReg <= 1'b0;
DelayControlReg <= DelayControlReg;
AuxCounter <= 10'b0;
EnableCounter <= 1'b0;
if (DelayControlReg == 3'b000 | TargetCounter < Target)
begin
DLLState <= 10'b1110000000;
end
else
begin
DLLState <= 10'b1000000000;
end
end
///////////////////////
// Too slow
///////////////////////
// Increase delay cell control variable by 1'b1
10'b1100000000:
begin
LockedReg <= 1'b0;
DelayControlReg <= DelayControlReg + 3'b1;
AuxCounter <= 10'b0;
EnableCounter <= 1'b0;
DLLState <= 10'b1100000001;
end
// Wait 100 cycles
10'b1100000001:
begin
LockedReg <= 1'b0;
DelayControlReg <= DelayControlReg;
AuxCounter <= AuxCounter + 10'b1;
EnableCounter <= 1'b1;
if (AuxCounter > 10'd100)
begin
DLLState <= 10'b1100000010;
end
else
begin
DLLState <= 10'b1100000001;
end
end
// Wait one more cycle
10'b1100000010:
begin
LockedReg <= 1'b0;
DelayControlReg <= DelayControlReg;
AuxCounter <= 10'b0;
EnableCounter <= 1'b0;
DLLState <= 10'b1100000011;
end
// And another
APPENDIX A: VERILOG HDL FOR DIGITAL BLOCKS 89
10'b1100000011:
begin
LockedReg <= 1'b0;
DelayControlReg <= DelayControlReg;
AuxCounter <= 10'b0;
EnableCounter <= 1'b0;
DLLState <= 10'b1100000100;
end
// Check if target is met - if so we are done
// If control variable is 4'b1111, we are done - can't increase
any more
// Otherwise, increase by 1'b1 and go again
10'b1100000100:
begin
LockedReg <= 1'b0;
DelayControlReg <= DelayControlReg;
AuxCounter <= 10'b0;
EnableCounter <= 1'b0;
if (DelayControlReg == 3'b111 | TargetCounter >= Target)
begin
DLLState <= 10'b1110000000;
end
else
begin
DLLState <= 10'b1100000000;
end
end
//////////////////////
// All done
//////////////////////
//
10'b1110000111:
begin
LockedReg <= 1'b0;
DelayControlReg <= DelayControlReg;
AuxCounter <= AuxCounter + 10'b1;
EnableCounter <= 1'b0;
if (AuxCounter > 10'd20)
begin
DLLState <= 10'b1110000000;
end
else
begin
DLLState <= 10'b1110000111;
end
end
// DLL output is "locked"
10'b1110000000:
begin
LockedReg <= 1'b1;
DelayControlReg <= DelayControlReg;
AuxCounter <= 10'b0;
EnableCounter <= 1'b0;
DLLState <= 10'b1110000000;
end
endcase
end
end
// Remove any glitches from counter enable register
// Used because we are dealing with two separate clock domains
always @(negedge Reset or posedge clk)
begin
if (Reset == 1'b0)
begin
EnableCounterNoGlitch <= 1'b0;
EnableCounterInter <= 1'b0;
end
else
begin
EnableCounterNoGlitch <= EnableCounterInter;
APPENDIX A: VERILOG HDL FOR DIGITAL BLOCKS 90
EnableCounterInter <= EnableCounter;
end
end
// Coarse adjustments of DLL frequency and counter targets
// Depends on # of phases in the system
always @(PhaseCount or MuxControlOverride or MuxControlOverrideValue)
begin
if (MuxControlOverride == 1'b1)
begin
MuxControlReg = MuxControlOverrideValue;
Target = 10'd400;
end
else if (PhaseCount == 4'b0010)
begin
MuxControlReg = 7'b0000000;
Target = 10'd200;
end
else if (PhaseCount == 4'b0011)
begin
MuxControlReg = 7'b1010100;
Target = 10'd300;
end
else if (PhaseCount == 4'b0100)
begin
MuxControlReg = 7'b1101010;
Target = 10'd400;
end
else if (PhaseCount == 4'b0101)
begin
MuxControlReg = 7'b1101010;
Target = 10'd500;
end
else if (PhaseCount == 4'b0110)
begin
MuxControlReg = 7'b1110110;
Target = 10'd600;
end
else if (PhaseCount == 4'b0111)
begin
MuxControlReg = 7'b1110110;
Target = 10'd700;
end
else if (PhaseCount == 4'b1000)
begin
MuxControlReg = 7'b1111110;
Target = 10'd800;
end
else if (PhaseCount == 4'b1111) // Special
begin
MuxControlReg = 7'b0000111;
Target = 10'd200;
end
else
begin
MuxControlReg = 7'b0000000;
Target = 10'd200;
end
end
// Counter used for measuring oscillations at DLL output
always @(negedge Reset or posedge ClkOut)
begin
if (Reset == 1'b0)
begin
TargetCounterState <= 4'b0000;
TargetCounter <= 10'b0;
end
else
begin
case (TargetCounterState)
APPENDIX A: VERILOG HDL FOR DIGITAL BLOCKS 91
4'b0000:
begin
if (EnableCounterNoGlitch == 1'b1)
begin
TargetCounterState <= 4'b0001;
TargetCounter <= 10'b0;
end
else
begin
TargetCounterState <= 4'b0000;
TargetCounter <= TargetCounter;
end
end
4'b0001:
begin
TargetCounter <= TargetCounter + 10'b1;
if (EnableCounterNoGlitch == 1'b0)
begin
TargetCounterState <= 4'b0000;
end
else
begin
TargetCounterState <= 4'b0001;
end
end
endcase
end
end
endmodule
/*******************************************************************************************
/ Module: dpwm
/ Written by: Jason Weinstein
/
/ Digital counter-based DPWM.
*******************************************************************************************/
module dpwm(Reset, clk_256, Start, HSSwitch, LSSwitch, DeadTime, D, Enable, Discharge);
input Reset; // Reset signal - active LO
input clk_256; // Input clock (256 MHz = 256f_s)
input Start; // Pulse indicating the start of
each switching cycle
output HSSwitch; // High-side switch
output LSSwitch; // Low-side switch
input [7:0] DeadTime; // Dead-time input
input [7:0] D; // Duty ratio
input Enable; // Indicates whether the DPWM is
enabled
input Discharge; // When Discharge == 1'b1, stage
is discharged
reg [3:0] DPWMState; // State variable for main DPWM FSM
reg [9:0] DPWMCount; // Counter used for DPWM
reg HSSwitchReg; // Register for storing HSSwitch
output
reg LSSwitchReg; // Register for storing LSSwitch
output
reg StartPulse; // Start pulse derived
from Start but using clk_256
reg [3:0] SPState; // Start pulse FSM state
reg [7:0] DReg; // Register for storing
duty ratio at each start pulse
// Override switching signals if we should discharge the power stage
assign HSSwitch = (HSSwitchReg | Discharge);
assign LSSwitch = (LSSwitchReg | Discharge);
// Main DPWM FSM
always @(negedge Reset or posedge clk_256)
begin
APPENDIX A: VERILOG HDL FOR DIGITAL BLOCKS 92
if (Reset == 1'b0)
begin
DPWMState <= 4'b0000;
DPWMCount <= 10'b0;
HSSwitchReg <= 1'b1;
LSSwitchReg <= 1'b0;
DReg <= 8'b0;
end
else
begin
case (DPWMState)
// In this state DPWM is disabled
// Wait for Enable and StartPulse to rise
4'b0000:
begin
HSSwitchReg <= 1'b1;
LSSwitchReg <= 1'b0;
DPWMCount <= 10'b0;
if (StartPulse == 1'b1 & Enable == 1'b1)
begin
DReg <= D;
DPWMState <= 4'b0001;
end
else
begin
DReg <= 8'b0;
DPWMState <= 4'b0000;
end
end
// Initial dead time
4'b0001:
begin
HSSwitchReg <= 1'b1;
LSSwitchReg <= 1'b0;
if (Enable == 1'b0)
begin
DPWMState <= 4'b0000;
DPWMCount <= 10'b0;
DReg <= 8'b0;
end
else if (StartPulse == 1'b1)
begin
DPWMState <= 4'b0001;
DPWMCount <= 10'b0;
DReg <= D;
end
if (DPWMCount >= {2'b0, DeadTime[7:0]})
begin
DPWMState <= 4'b0010;
DPWMCount <= DPWMCount + 10'b1;
DReg <= DReg;
end
else
begin
DPWMState <= 4'b0001;
DPWMCount <= DPWMCount + 10'b1;
DReg <= DReg;
end
end
// Enable HSSwitch
4'b0010:
begin
HSSwitchReg <= 1'b0;
LSSwitchReg <= 1'b0;
if (Enable == 1'b0)
begin
DPWMState <= 4'b0000;
DPWMCount <= 10'b0;
DReg <= 8'b0;
end
else if (StartPulse == 1'b1)
APPENDIX A: VERILOG HDL FOR DIGITAL BLOCKS 93
begin
DPWMState <= 4'b0001;
DPWMCount <= 10'b0;
DReg <= D;
end
else if (DPWMCount >= {2'b0, DReg[7:0]})
begin
DPWMState <= 4'b0011;
DPWMCount <= DPWMCount + 10'b1;
DReg <= DReg;
end
else
begin
DPWMState <= 4'b0010;
DPWMCount <= DPWMCount + 10'b1;
DReg <= DReg;
end
end
// Middle dead time
4'b0011:
begin
HSSwitchReg <= 1'b1;
LSSwitchReg <= 1'b0;
if (Enable == 1'b0)
begin
DPWMState <= 4'b0000;
DPWMCount <= 10'b0;
DReg <= 8'b0;
end
else if (StartPulse == 1'b1)
begin
DPWMState <= 4'b0001;
DPWMCount <= 10'b0;
DReg <= D;
end
else if (DPWMCount >= {2'b0, DReg[7:0]} + {2'b0,
DeadTime[7:0]})
begin
DPWMState <= 4'b0100;
DPWMCount <= DPWMCount + 10'b1;
DReg <= DReg;
end
else
begin
DPWMState <= 4'b0011;
DPWMCount <= DPWMCount + 10'b1;
DReg <= DReg;
end
end
// Enable LSSwitch
4'b0100:
begin
HSSwitchReg <= 1'b1;
LSSwitchReg <= 1'b1;
DPWMCount <= 10'b0;
if (Enable == 1'b0)
begin
DPWMState <= 4'b0000;
DReg <= 8'b0;
end
else if (StartPulse == 1'b1)
begin
DPWMState <= 4'b0001;
DReg <= D;
end
else
begin
DPWMState <= 4'b0100;
DReg <= DReg;
end
end
APPENDIX A: VERILOG HDL FOR DIGITAL BLOCKS 94
endcase
end
end
// Produces a pulse lasting a single cycle of clk_256 based on StartPulse input
always @(negedge Reset or posedge clk_256)
begin
if (Reset == 1'b0)
begin
StartPulse <= 1'b0;
SPState <= 4'b0000;
end
else
begin
case (SPState)
4'b0000:
begin
if (Start == 1'b1)
begin
StartPulse <= 1'b1;
SPState <= 4'b0001;
end
else
begin
StartPulse <= 1'b0;
SPState <= 4'b0000;
end
end
4'b0001:
begin
StartPulse <= 1'b0;
if (Start == 1'b0)
begin
SPState <= 4'b0000;
end
else
begin
SPState <= 4'b0001;
end
end
endcase
end
end
endmodule
/*******************************************************************************************
/ Module: phase_counter
/ Written by: Jason Weinstein
/
/ This module is responsible for determining the number of phases present in the system.
*******************************************************************************************/
module phase_counter(Reset, clk, ReceiveSync, RXData, TransmitOutNoGlitch, TXDataOut,
BusModeOut, is_initial_phase, PhaseIDOut, PhaseCountOut, DonePhaseCountOut, PhaseEnabled,
InitialPhaseOverride, InitialPhaseOverrideValue, Start);
input Reset; // Reset signal (active LO)
input clk; // Main clock (1 MHz =
f_s)
input ReceiveSync; // From the communication block -
rising edge indicates that a
//
transmission has just been received
input [3:0] RXData; // Data received from last
transmission - should be sampled and
//
stored shortly after ReceiveSync goes high
output TransmitOutNoGlitch; // Output to communication block - rising
edge indicates that a
//
transmission should be sent
APPENDIX A: VERILOG HDL FOR DIGITAL BLOCKS 95
output [3:0] TXDataOut; // Output to communication block
(4 bits) - is sampled by the
//
communication block when TransmitOutNoGlitch goes high
output BusModeOut; // Indicates whether the
communication block should operate in
//
series mode (1'b0) or bus mode (1'b1)
input is_initial_phase; // Boolean value indicating
whether the phase is the initial phase:
// the
initial phase must begin by transmitting '1' to the next
//
phase even before it has received a transmission
output [3:0] PhaseIDOut; // The ID number of this phase - can be
sampled after the phase count
// has
completed
output [3:0] PhaseCountOut; // The total number of phases present in
the system - can be sampled
//
once the phase count is complete
output DonePhaseCountOut; // Goes high once the phase counting
precedure is complete
input PhaseEnabled; // If this signal is not high,
the phase is disabled
input InitialPhaseOverride; // If this value is one use
InitialPhaseOverrideValue instead of is_initial_phase
input InitialPhaseOverrideValue; // This value is used instead of
is_initial_phase if InitialPhaseOverrideValue is high
input Start; //
reg [9:0] PCState; // State variable for the main
phase counter FSM
reg BusModeReg; // Register for storing
the BusMode output
reg Transmit; // Register indicating a
transmission should begin
reg TransmitOut; // Glitch-free version of
Transmit
reg [3:0] TXData; // Data that should be
transmitted to the comm block
reg [7:0] AuxCounter; // Auxiliary counter used for various
purposes at different
//
stages of the FSM
reg [3:0] PhaseID; // Register for storing the
phase's ID number
reg [3:0] PhaseCount; // Register for storing the total number
of phases
reg DonePhaseCount; // Goes high once the entire
phase counting process is complete
wire is_initial_phase_final; // Final value indicating initial phase
// Assign outputs to various registers
// More proper than using "output reg"
assign BusModeOut = BusModeReg;
assign TXDataOut = TXData;
assign PhaseIDOut = PhaseID;
assign PhaseCountOut = PhaseCount;
assign DonePhaseCountOut = DonePhaseCount;
assign TransmitOutNoGlitch = TransmitOut;
// See if is_initial_phase should be overrident
assign is_initial_phase_final = ((InitialPhaseOverride == 1'b1) ?
InitialPhaseOverrideValue : is_initial_phase);
// Used to remove glitches from Transmit signal
// The transmit signal must never glitch
// This delays the signal by one clock cycle but that's OK since this stage
// is not timing critical
APPENDIX A: VERILOG HDL FOR DIGITAL BLOCKS 96
always @(negedge Reset or posedge clk)
begin
if (Reset == 1'b0)
begin
TransmitOut <= 1'b0;
end
else
begin
TransmitOut <= Transmit;
end
end
// Main phase counter FSM
always @(negedge Reset or posedge clk)
begin
if (Reset == 1'b0)
begin
PCState <= 10'b0000000000;
BusModeReg <= 1'b0;
Transmit <= 1'b0;
TXData <= 4'b0;
AuxCounter <= 8'b0;
PhaseID <= 4'b0;
PhaseCount <= 4'b0;
DonePhaseCount <= 1'b0;
end
else
begin
case (PCState)
////////////////////
// Initialization
////////////////////
10'b0101010101:
begin
PhaseCount <= 4'b0;
DonePhaseCount <= 1'b0;
BusModeReg <= 1'b0;
Transmit <= 1'b0;
TXData <= 4'b0;
PhaseID <= 4'b0;
AuxCounter <= 8'b0;
if (Start == 1'b1)
begin
PCState <= 10'b0000000000;
end
else
begin
PCState <= 10'b0101010101;
end
end
// Check if phase has been enabled (by programming unit)
10'b0000000000:
begin
PhaseCount <= 4'b0;
DonePhaseCount <= 1'b0;
BusModeReg <= 1'b0;
Transmit <= 1'b0;
TXData <= 4'b0;
PhaseID <= 4'b0;
if (PhaseEnabled == 1'b0)
begin
PCState <= 10'b1111111111;
AuxCounter <= 8'b0;
end
else if (AuxCounter > 8'b00010000)
begin
PCState <= 10'b0000000001;
AuxCounter <= 8'b0;
end
else
begin
APPENDIX A: VERILOG HDL FOR DIGITAL BLOCKS 97
PCState <= 10'b0000000000;
AuxCounter <= AuxCounter + 8'b1;
end
end
// Check whether this phase is the initial phase
10'b0000000001:
begin
PhaseCount <= 4'b0;
DonePhaseCount <= 1'b0;
BusModeReg <= 1'b0;
Transmit <= 1'b0;
AuxCounter <= 8'b0;
TXData <= 4'b0;
PhaseID <= 4'b0;
if (is_initial_phase_final == 1'b1)
begin
PCState <= 10'b1000000000;
end
else
begin
PCState <= 10'b0000000010;
end
end
///////////////////////
// Non-initial phases
///////////////////////
// Wait until we receive a transmission
10'b0000000010:
begin
PhaseCount <= 4'b0;
DonePhaseCount <= 1'b0;
BusModeReg <= 1'b0;
Transmit <= 1'b0;
AuxCounter <= 8'b0;
TXData <= 4'b0;
PhaseID <= 4'b0;
if (ReceiveSync == 1'b1)
begin
PCState <= 10'b0000000011;
end
else
begin
PCState <= 10'b0000000010;
end
end
// Transmission has been received - store the value as the
Phase ID
10'b0000000011:
begin
PhaseCount <= 4'b0;
DonePhaseCount <= 1'b0;
BusModeReg <= 1'b0;
PhaseID <= RXData;
Transmit <= 1'b0;
TXData <= RXData + 4'b1;
AuxCounter <= 8'b0;
PCState <= 10'b0000000100;
end
// Wait a few clock cycles
10'b0000000100:
begin
PhaseCount <= 4'b0;
DonePhaseCount <= 1'b0;
BusModeReg <= 1'b0;
PhaseID <= PhaseID;
Transmit <= 1'b0;
TXData <= TXData;
if (AuxCounter > 8'b00001000)
begin
PCState <= 10'b0000000101;
AuxCounter <= 8'b0;
APPENDIX A: VERILOG HDL FOR DIGITAL BLOCKS 98
end
else
begin
PCState <= 10'b0000000100;
AuxCounter <= AuxCounter + 8'b1;
end
end
// Transmit PhaseID + 1'b1
10'b0000000101:
begin
PhaseCount <= 4'b0;
DonePhaseCount <= 1'b0;
PhaseID <= PhaseID;
Transmit <= 1'b1;
BusModeReg <= 1'b0;
TXData <= TXData;
AuxCounter <= 8'b0;
PCState <= 10'b0000000110;
end
// Wait a few cycles
10'b0000000110:
begin
PhaseCount <= 4'b0;
DonePhaseCount <= 1'b0;
PhaseID <= PhaseID;
Transmit <= 1'b0;
BusModeReg <= 1'b0;
TXData <= TXData;
if (AuxCounter > 8'b00001000)
begin
PCState <= 10'b0000000111;
AuxCounter <= 8'b0;
end
else
begin
PCState <= 10'b0000000110;
AuxCounter <= AuxCounter + 8'b1;
end
end
// Go into bus mode and wait for a transmission
10'b0000000111:
begin
DonePhaseCount <= 1'b0;
PhaseID <= PhaseID;
Transmit <= 1'b0;
BusModeReg <= 1'b1;
TXData <= 4'b0;
AuxCounter <= 8'b0;
if (ReceiveSync == 1'b1)
begin
PCState <= 10'b0000001000;
PhaseCount <= RXData;
end
else
begin
PCState <= 10'b0000000111;
PhaseCount <= 4'b0;
end
end
// Transmission received - non-initial phase finished
10'b0000001000:
begin
PhaseCount <= PhaseCount;
DonePhaseCount <= 1'b1;
PhaseID <= PhaseID;
Transmit <= 1'b0;
BusModeReg <= 1'b1;
TXData <= 4'b0;
AuxCounter <= 8'b0;
PCState <= 10'b0000001000;
APPENDIX A: VERILOG HDL FOR DIGITAL BLOCKS 99
end
///////////////////////
// Initial phase
///////////////////////
// Wait a few clock cycles to make sure other phases are ready
10'b1000000000:
begin
PhaseCount <= 4'b0;
DonePhaseCount <= 1'b0;
BusModeReg <= 1'b0;
Transmit <= 1'b0;
TXData <= 4'b1;
PhaseID <= 4'b0;
if (AuxCounter > 8'b00100000)
begin
PCState <= 10'b1000000001;
AuxCounter <= 8'b0;
end
else
begin
PCState <= 10'b1000000000;
AuxCounter <= AuxCounter + 8'b1;
end
end
// Transmit 1'b1 to the next phase
10'b1000000001:
begin
PhaseCount <= 4'b0;
DonePhaseCount <= 1'b0;
BusModeReg <= 1'b0;
Transmit <= 1'b1;
TXData <= 4'b1;
PhaseID <= 4'b0;
AuxCounter <= 8'b0;
PCState <= 10'b1000000010;
end
// Check if we receive a transmission within the next couple
clock cycles
// If so this is the only phase in the system
10'b1000000010:
begin
DonePhaseCount <= 1'b0;
BusModeReg <= 1'b0;
Transmit <= 1'b0;
PhaseID <= 4'b0;
TXData <= TXData;
if (ReceiveSync == 1'b1)
begin
PhaseCount <= 4'b1;
PCState <= 10'b1100000000;
AuxCounter <= 8'b0;
end
else if (AuxCounter > 8'b00000010)
begin
PhaseCount <= 4'b0;
PCState <= 10'b1000000011;
AuxCounter <= 8'b0;
end
else
begin
PhaseCount <= 4'b0;
PCState <= 10'b1000000010;
AuxCounter <= AuxCounter + 8'b1;
end
end
// There are other phases
// Wait until a transmission is received from the last phase in
the ring
10'b1000000011:
begin
PhaseCount <= 4'b0;
APPENDIX A: VERILOG HDL FOR DIGITAL BLOCKS 100
DonePhaseCount <= 1'b0;
BusModeReg <= 1'b0;
Transmit <= 1'b0;
PhaseID <= 4'b0;
TXData <= 4'b0;
AuxCounter <= 8'b0;
if (ReceiveSync == 1'b1)
begin
PCState <= 10'b1000000101;
end
else
begin
PCState <= 10'b1000000011;
end
end
// Wait a few clock cycles so that all other phases are in bus
mode
10'b1000000101:
begin
PhaseCount <= RXData;
DonePhaseCount <= 1'b0;
BusModeReg <= 1'b0;
Transmit <= 1'b0;
PhaseID <= 4'b0;
TXData <= RXData;
if (AuxCounter > 8'b00010000)
begin
PCState <= 10'b1000000110;
AuxCounter <= 8'b0;
end
else
begin
PCState <= 10'b1000000101;
AuxCounter <= AuxCounter + 8'b1;
end
end
// Set bus mode on
10'b1000000110:
begin
PhaseCount <= PhaseCount;
DonePhaseCount <= 1'b0;
BusModeReg <= 1'b1;
Transmit <= 1'b0;
PhaseID <= 4'b0;
TXData <= TXData;
AuxCounter <= 8'b0;
PCState <= 10'b1000000111;
end
// Send # of phases on bus
10'b1000000111:
begin
PhaseCount <= PhaseCount;
DonePhaseCount <= 1'b0;
BusModeReg <= 1'b1;
Transmit <= 1'b1;
PhaseID <= 4'b0;
TXData <= TXData;
AuxCounter <= 8'b0;
PCState <= 10'b1000001000;
end
// Wait one more cycle
10'b1000001000:
begin
PhaseCount <= PhaseCount;
DonePhaseCount <= 1'b0;
BusModeReg <= 1'b1;
Transmit <= 1'b0;
PhaseID <= 4'b0;
TXData <= TXData;
AuxCounter <= 8'b0;
PCState <= 10'b1100000000;
APPENDIX A: VERILOG HDL FOR DIGITAL BLOCKS 101
end
// Initial phase finished
10'b1100000000:
begin
PhaseCount <= PhaseCount;
DonePhaseCount <= 1'b1;
BusModeReg <= 1'b1;
Transmit <= 1'b0;
PhaseID <= 4'b0;
TXData <= 4'b0;
AuxCounter <= 8'b0;
PCState <= 10'b1100000000;
end
///////////////////////
// Phase is disabled
///////////////////////
// Stay here forever if disabled
10'b1111111111:
begin
PhaseCount <= 4'b0;
DonePhaseCount <= 1'b0;
BusModeReg <= 1'b1;
Transmit <= 1'b0;
PhaseID <= 4'b0;
TXData <= 4'b0;
AuxCounter <= 8'b0;
PCState <= 10'b1111111111;
end
endcase
end
end
endmodule
/******************************************************************************************
/ Module: phase_sequencer
/ Written by: Jason Weinstein
/
/ This module measures the charge time with a fixed duty ratio, transmits the charge time,
/ receives charge times from other phases, and then computes phase order.
*******************************************************************************************/
module phase_sequencer(Reset, clk, ReceiveSync, RXData, TransmitOutNoGlitch, TXDataOut,
PhaseID, PhaseCount, DonePhaseCount, EnableDPWM, DonePhaseSequence, PhaseOrder, Discharge,
VoltageLevel, ADCIn_3, ReOrderPhases, PhaseTimer, PhaseOrderOverride,
PhaseOrderOverrideValue, SmallerPhasesOut);
input Reset; // Reset signal - active LO
input clk; // Main clock (1 MHz =
f_s)
input ReceiveSync; // From the communication block -
rising edge indicates that a
//
transmission has just been received
input [3:0] RXData; // Data received from last
transmission - should be sampled and
//
stored shortly after ReceiveSync goes high
output TransmitOutNoGlitch; // Output to communication block - rising
edge indicates that a
//
transmission should be sent
output [3:0] TXDataOut; // Output to communication block
(4 bits) - is sampled by the
//
communication block when TransmitOutNoGlitch goes high
input [3:0] PhaseID; // Phase ID number of this phase - can be
sampled once phase
//
counting process is finished
input [3:0] PhaseCount; // The total number of phases
present in the system - can be sampled
APPENDIX A: VERILOG HDL FOR DIGITAL BLOCKS 102
//
once the phase count is complete
input DonePhaseCount; // Goes high once the phase counting
precedure is complete
output EnableDPWM; // Indicates that DPWM should be
enabled - set high when the charging
//
process occurs
output DonePhaseSequence; // Goes high once the phase ordering
precedure is complete
output [3:0] PhaseOrder; // The order in the switching sequence of
this phase
output Discharge; // Sent to the DPWM to discharge
output before charge process begins
output VoltageLevel; // During phase sequencing step,
indicates that a lower reference
//
voltage should be used for the ADC
input ADCIn_3; // MSB of ADC output - when this
value is zero, the ADC measurement is
// >=
to the reference - stop charging at this point and measure
// the
charge time
input ReOrderPhases; // When ReOrderPhases == 1'b1, do phase
reordering as usual - otherwise
//
just set PhaseOrder = PhaseID and finish
output [15:0] PhaseTimer; //
input PhaseOrderOverride;
input [3:0] PhaseOrderOverrideValue; //
output [3:0] SmallerPhasesOut; //
reg [9:0] PSState; // State variable for the main
phase sequencing FSM
reg Transmit; // Register indicating a
transmission should begin
reg TransmitOut; // Glitch-free version of
Transmit
reg [3:0] CurrentCount; // Counter for keeping track of
which phase should currently be performing
// the
charge process
reg EnableDPWMReg; // Register for storing
EnableDPWM output
reg DonePhaseSequenceReg; // Register for storing DonePhaseSequence
output
reg [3:0] PhaseOrderReg; // Register for storing PhaseOrder output
reg [19:0] AuxCounter; // Auxiliary counter used for various
purposes during the phase sequencing
// process
reg DischargeReg; // Register for storing Discharge
output
reg VoltageLevelReg; // Register for storing VoltageLevel
output
reg [15:0] PhaseTiming [15:0]; // Register for storing the charge times
of all phases
reg [3:0] TXData; // Data that should be
transmitted to the comm block
reg [3:0] SmallerPhases; // For counting the number of phases that
have smaller charge times
//
than this phase - info used for phase reordering
reg [1:0] BitShift; // Depending on the total number
of phases, the algorithm should shift
// by
a different number of bits
reg [19:0] CompA; // These registers are for
performing comparisons
reg [19:0] CompB;
APPENDIX A: VERILOG HDL FOR DIGITAL BLOCKS 103
// Assign outputs to various registers
// More proper than using "output reg"
assign TransmitOutNoGlitch = TransmitOut;
assign EnableDPWM = EnableDPWMReg;
assign DonePhaseSequence = DonePhaseSequenceReg;
assign PhaseOrder = PhaseOrderReg;
assign Discharge = DischargeReg;
assign VoltageLevel = VoltageLevelReg;
assign TXDataOut = TXData;
assign PhaseTimer = PhaseTiming[PhaseID];
assign SmallerPhasesOut = SmallerPhases;
// Used to remove glitches from Transmit signal
// The transmit signal must never glitch
// This delays the signal by one clock cycle but that's OK since this stage
// is not timing critical
always @(negedge Reset or posedge clk)
begin
if (Reset == 1'b0)
begin
TransmitOut <= 1'b0;
end
else
begin
TransmitOut <= Transmit;
end
end
// Main phase sequencing FSM
always @(negedge Reset or posedge clk)
begin
if (Reset == 1'b0)
begin
PSState <= 10'b0000000000;
Transmit <= 1'b0;
CurrentCount <= 4'b0;
EnableDPWMReg <= 1'b0;
DonePhaseSequenceReg <= 1'b0;
PhaseOrderReg <= 4'b0;
AuxCounter <= 20'b0;
DischargeReg <= 1'b0;
VoltageLevelReg <= 1'b1;
TXData <= 4'b0;
SmallerPhases <= 4'b0;
end
else
begin
case (PSState)
///////////////////////////
// Initial state
///////////////////////////
// Wait until phase counting is complete
10'b0000000000:
begin
Transmit <= 1'b0;
CurrentCount <= 4'b0;
EnableDPWMReg <= 1'b0;
DonePhaseSequenceReg <= 1'b0;
PhaseOrderReg <= 4'b0;
AuxCounter <= 20'b0;
DischargeReg <= 1'b0;
VoltageLevelReg <= 1'b1;
TXData <= 4'b0;
if ((DonePhaseCount == 1'b1) & (PhaseCount > 1'b1))
begin
PSState <= 10'b0000000001;
end
else
begin
PSState <= 10'b0000000000;
end
APPENDIX A: VERILOG HDL FOR DIGITAL BLOCKS 104
end
/////////////////////////////////////////////////////////
// Branch depending on whether it is this phase's turn
/////////////////////////////////////////////////////////
// Check whether this phase should do the charge process, wait
// for another phase, or we are finished
10'b0000000001:
begin
Transmit <= 1'b0;
CurrentCount <= CurrentCount;
EnableDPWMReg <= 1'b0;
DonePhaseSequenceReg <= 1'b0;
AuxCounter <= 20'b0;
DischargeReg <= 1'b0;
VoltageLevelReg <= 1'b0;
TXData <= 4'b0;
// Don't reorder phases - set PhaseOrderReg to PhaseID
and go to final state
if (ReOrderPhases == 1'b0)
begin
PhaseOrderReg <= PhaseID;
PSState <= 10'b1111111111;
end
else if (PhaseOrderOverride == 1'b1)
begin
PhaseOrderReg <= PhaseOrderOverrideValue;
PSState <= 10'b1111111111;
end
// Do charge process
else if (PhaseID == CurrentCount)
begin
PhaseOrderReg <= 4'b0;
PSState <= 10'b1000000000;
end
// Done all charge processes - go to stage for
calculating phase order
else if (PhaseCount == CurrentCount)
begin
PhaseOrderReg <= 4'b0;
PSState <= 10'b1110000000;
end
// Wait for another phase to do the charge process
else
begin
PhaseOrderReg <= 4'b0;
PSState <= 10'b1100000000;
end
end
//////////////////////////
// This phase's turn
//////////////////////////
// Discharge for a while before starting
10'b1000000000:
begin
Transmit <= 1'b0;
CurrentCount <= CurrentCount;
EnableDPWMReg <= 1'b0;
DonePhaseSequenceReg <= 1'b0;
PhaseOrderReg <= 4'b0;
DischargeReg <= 1'b1;
VoltageLevelReg <= 1'b0;
AuxCounter <= AuxCounter + 20'b1;
TXData <= 4'b0;
if (AuxCounter > 20'd100)
begin
PSState <= 10'b1000000001;
end
else
begin
PSState <= 10'b1000000000;
end
APPENDIX A: VERILOG HDL FOR DIGITAL BLOCKS 105
end
// Start charging
10'b1000000001:
begin
Transmit <= 1'b0;
CurrentCount <= CurrentCount;
EnableDPWMReg <= 1'b1;
DonePhaseSequenceReg <= 1'b0;
PhaseOrderReg <= 4'b0;
DischargeReg <= 1'b0;
VoltageLevelReg <= 1'b0;
AuxCounter <= 20'b0;
PSState <= 10'b1000000010;
TXData <= 4'b0;
end
// Wait for ADC output to be >= 0
// This occurs when the MSB of ADCIn is 1'b0
10'b1000000010:
begin
Transmit <= 1'b0;
CurrentCount <= CurrentCount;
EnableDPWMReg <= 1'b1;
DonePhaseSequenceReg <= 1'b0;
PhaseOrderReg <= 4'b0;
DischargeReg <= 1'b0;
VoltageLevelReg <= 1'b0;
AuxCounter <= AuxCounter + 20'b1;
TXData <= 4'b0;
if (ADCIn_3 == 1'b1)
begin
PSState <= 10'b1000000011;
end
else
begin
PSState <= 10'b1000000010;
end
end
// Record charge time
10'b1000000011:
begin
Transmit <= 1'b0;
CurrentCount <= CurrentCount;
EnableDPWMReg <= 1'b0;
DonePhaseSequenceReg <= 1'b0;
PhaseOrderReg <= 4'b0;
DischargeReg <= 1'b1;
VoltageLevelReg <= 1'b0;
AuxCounter <= 20'd0;
PhaseTiming[PhaseID][15:0] <= AuxCounter[15:0];
TXData <= AuxCounter[3:0];
PSState <= 10'b1000000100;
end
// Transmit first 4 bits
10'b1000000100:
begin
Transmit <= 1'b1;
CurrentCount <= CurrentCount;
EnableDPWMReg <= 1'b0;
DonePhaseSequenceReg <= 1'b0;
PhaseOrderReg <= 4'b0;
DischargeReg <= 1'b1;
VoltageLevelReg <= 1'b0;
AuxCounter <= 20'b1;
TXData <= TXData;
if (AuxCounter == 20'b1)
begin
PSState <= 10'b1000010100;
end
else
begin
PSState <= 10'b1000000100;
APPENDIX A: VERILOG HDL FOR DIGITAL BLOCKS 106
end
end
// Prepare transmission for bits 7:4
10'b1000010100:
begin
Transmit <= 1'b0;
CurrentCount <= CurrentCount;
EnableDPWMReg <= 1'b0;
DonePhaseSequenceReg <= 1'b0;
PhaseOrderReg <= 4'b0;
DischargeReg <= 1'b1;
VoltageLevelReg <= 1'b0;
AuxCounter <= AuxCounter + 20'b1;
if (AuxCounter > 20'd10)
begin
PSState <= 10'b1000000101;
TXData <= PhaseTiming[PhaseID][7:4];
end
else
begin
PSState <= 10'b1000010100;
TXData <= TXData;
end
end
// Transmit bits 7:4
10'b1000000101:
begin
Transmit <= 1'b1;
CurrentCount <= CurrentCount;
EnableDPWMReg <= 1'b0;
DonePhaseSequenceReg <= 1'b0;
PhaseOrderReg <= 4'b0;
DischargeReg <= 1'b1;
VoltageLevelReg <= 1'b0;
AuxCounter <= 20'b0;
TXData <= TXData;
PSState <= 10'b1000000110;
end
// Prepare transmission for bits 11:8
10'b1000000110:
begin
Transmit <= 1'b0;
CurrentCount <= CurrentCount;
EnableDPWMReg <= 1'b0;
DonePhaseSequenceReg <= 1'b0;
PhaseOrderReg <= 4'b0;
DischargeReg <= 1'b1;
VoltageLevelReg <= 1'b0;
if (AuxCounter > 20'd10)
begin
AuxCounter <= 20'b0;
PSState <= 10'b1000000111;
TXData <= PhaseTiming[PhaseID][11:8];
end
else
begin
AuxCounter <= AuxCounter + 20'b1;
PSState <= 10'b1000000110;
TXData <= TXData;
end
end
// Transmit bits 11:8
10'b1000000111:
begin
Transmit <= 1'b1;
CurrentCount <= CurrentCount;
EnableDPWMReg <= 1'b0;
DonePhaseSequenceReg <= 1'b0;
PhaseOrderReg <= 4'b0;
DischargeReg <= 1'b1;
VoltageLevelReg <= 1'b0;
APPENDIX A: VERILOG HDL FOR DIGITAL BLOCKS 107
AuxCounter <= 20'b1;
TXData <= TXData;
if (AuxCounter == 20'b1)
begin
PSState <= 10'b1000001000;
end
else
begin
PSState <= 10'b1000000111;
end
end
// Prepare transmission for bits 15:2
10'b1000001000:
begin
Transmit <= 1'b0;
CurrentCount <= CurrentCount;
EnableDPWMReg <= 1'b0;
DonePhaseSequenceReg <= 1'b0;
PhaseOrderReg <= 4'b0;
DischargeReg <= 1'b1;
VoltageLevelReg <= 1'b0;
if (AuxCounter > 20'd10)
begin
AuxCounter <= 20'b0;
PSState <= 10'b1000001001;
TXData <= PhaseTiming[PhaseID][15:12];
end
else
begin
AuxCounter <= AuxCounter + 20'b1;
PSState <= 10'b1000001000;
TXData <= TXData;
end
end
// Transmit bits 15:12
10'b1000001001:
begin
Transmit <= 1'b1;
EnableDPWMReg <= 1'b0;
DonePhaseSequenceReg <= 1'b0;
PhaseOrderReg <= 4'b0;
DischargeReg <= 1'b1;
VoltageLevelReg <= 1'b0;
AuxCounter <= 20'b1;
TXData <= TXData;
if (AuxCounter == 20'b1)
begin
CurrentCount <= CurrentCount + 4'b1;
PSState <= 10'b1000001010;
end
else
begin
CurrentCount <= CurrentCount;
PSState <= 10'b1000001001;
end
end
// Wait a few cycles
10'b1000001010:
begin
Transmit <= 1'b0;
CurrentCount <= CurrentCount;
EnableDPWMReg <= 1'b0;
DonePhaseSequenceReg <= 1'b0;
PhaseOrderReg <= 4'b0;
DischargeReg <= 1'b1;
VoltageLevelReg <= 1'b0;
AuxCounter <= AuxCounter + 20'b1;
TXData <= 4'b0;
if (AuxCounter > 20'd10)
begin
PSState <= 10'b0000000001;
APPENDIX A: VERILOG HDL FOR DIGITAL BLOCKS 108
end
else
begin
PSState <= 10'b1000001010;
end
end
/////////////////////////////
// Other phase's turn
/////////////////////////////
// Wait for transmission of bits 3:0
10'b1100000000:
begin
Transmit <= 1'b0;
CurrentCount <= CurrentCount;
EnableDPWMReg <= 1'b0;
DonePhaseSequenceReg <= 1'b0;
PhaseOrderReg <= 4'b0;
DischargeReg <= 1'b0;
VoltageLevelReg <= 1'b0;
AuxCounter <= 20'b0;
TXData <= 4'b0;
if (ReceiveSync == 1'b1)
begin
PSState <= 10'b1100000001;
PhaseTiming[CurrentCount][3:0] <= RXData[3:0];
end
else
begin
PSState <= 10'b1100000000;
end
end
// Prepare for transmission of bits 7:4
10'b1100000001:
begin
Transmit <= 1'b0;
CurrentCount <= CurrentCount;
EnableDPWMReg <= 1'b0;
DonePhaseSequenceReg <= 1'b0;
PhaseOrderReg <= 4'b0;
DischargeReg <= 1'b0;
VoltageLevelReg <= 1'b0;
AuxCounter <= 20'b0;
TXData <= 4'b0;
if (ReceiveSync == 1'b0)
begin
PSState <= 10'b1100000010;
end
else
begin
PSState <= 10'b1100000001;
end
end
// Wait for transmission of bits 7:4
10'b1100000010:
begin
Transmit <= 1'b0;
CurrentCount <= CurrentCount;
EnableDPWMReg <= 1'b0;
DonePhaseSequenceReg <= 1'b0;
PhaseOrderReg <= 4'b0;
DischargeReg <= 1'b0;
VoltageLevelReg <= 1'b0;
AuxCounter <= 20'b0;
TXData <= 4'b0;
if (ReceiveSync == 1'b1)
begin
PSState <= 10'b1100000011;
PhaseTiming[CurrentCount][7:4] <= RXData[3:0];
end
else
begin
APPENDIX A: VERILOG HDL FOR DIGITAL BLOCKS 109
PSState <= 10'b1100000010;
end
end
// Prepare for transmission of bits 11:8
10'b1100000011:
begin
Transmit <= 1'b0;
CurrentCount <= CurrentCount;
EnableDPWMReg <= 1'b0;
DonePhaseSequenceReg <= 1'b0;
PhaseOrderReg <= 4'b0;
DischargeReg <= 1'b0;
VoltageLevelReg <= 1'b0;
AuxCounter <= 20'b0;
TXData <= 4'b0;
if (ReceiveSync == 1'b0)
begin
PSState <= 10'b1100000100;
end
else
begin
PSState <= 10'b1100000011;
end
end
// Wait for transmission of bits 11:8
10'b1100000100:
begin
Transmit <= 1'b0;
CurrentCount <= CurrentCount;
EnableDPWMReg <= 1'b0;
DonePhaseSequenceReg <= 1'b0;
PhaseOrderReg <= 4'b0;
DischargeReg <= 1'b0;
VoltageLevelReg <= 1'b0;
AuxCounter <= 20'b0;
TXData <= 4'b0;
if (ReceiveSync == 1'b1)
begin
PSState <= 10'b1100000101;
PhaseTiming[CurrentCount][11:8] <= RXData[3:0];
end
else
begin
PSState <= 10'b1100000100;
end
end
// Prepare for transmission of bits 15:12
10'b1100000101:
begin
Transmit <= 1'b0;
CurrentCount <= CurrentCount;
EnableDPWMReg <= 1'b0;
DonePhaseSequenceReg <= 1'b0;
PhaseOrderReg <= 4'b0;
DischargeReg <= 1'b0;
VoltageLevelReg <= 1'b0;
AuxCounter <= 20'b0;
TXData <= 4'b0;
if (ReceiveSync == 1'b0)
begin
PSState <= 10'b1100000110;
end
else
begin
PSState <= 10'b1100000101;
end
end
// Wait for transmission of bits 15:12
10'b1100000110:
begin
Transmit <= 1'b0;
APPENDIX A: VERILOG HDL FOR DIGITAL BLOCKS 110
CurrentCount <= CurrentCount;
EnableDPWMReg <= 1'b0;
DonePhaseSequenceReg <= 1'b0;
PhaseOrderReg <= 4'b0;
DischargeReg <= 1'b0;
VoltageLevelReg <= 1'b0;
AuxCounter <= 20'b0;
TXData <= 4'b0;
if (ReceiveSync == 1'b1)
begin
PSState <= 10'b1100000111;
PhaseTiming[CurrentCount][15:12] <= RXData[3:0];
end
else
begin
PSState <= 10'b1100000110;
end
end
// Wait for ReceiveSync to go LO
10'b1100000111:
begin
Transmit <= 1'b0;
CurrentCount <= CurrentCount;
EnableDPWMReg <= 1'b0;
DonePhaseSequenceReg <= 1'b0;
PhaseOrderReg <= 4'b0;
DischargeReg <= 1'b0;
VoltageLevelReg <= 1'b0;
AuxCounter <= 20'b0;
TXData <= 4'b0;
if (ReceiveSync == 1'b0)
begin
PSState <= 10'b1100001000;
end
else
begin
PSState <= 10'b1100000111;
end
end
// Go back to branching state
10'b1100001000:
begin
Transmit <= 1'b0;
CurrentCount <= CurrentCount + 1'b1;
EnableDPWMReg <= 1'b0;
DonePhaseSequenceReg <= 1'b0;
PhaseOrderReg <= 4'b0;
DischargeReg <= 1'b0;
VoltageLevelReg <= 1'b0;
AuxCounter <= 20'b0;
TXData <= 4'b0;
PSState <= 10'b0000000001;
end
//////////////////////////////////////////////////////////////////
// Each phase calculates its position in the switching cycle
//////////////////////////////////////////////////////////////////
// Wait one cycle
10'b1110000000:
begin
Transmit <= 1'b0;
CurrentCount <= 4'b0;
EnableDPWMReg <= 1'b0;
DonePhaseSequenceReg <= 1'b0;
PhaseOrderReg <= 4'b0;
DischargeReg <= 1'b0;
VoltageLevelReg <= 1'b0;
AuxCounter <= 20'b0;
TXData <= 4'b0;
SmallerPhases <= 4'b0;
APPENDIX A: VERILOG HDL FOR DIGITAL BLOCKS 111
PSState <= 10'b1110000001;
end
// Determine # of phases that have smaller charge times
10'b1110000001:
begin
Transmit <= 1'b0;
CurrentCount <= CurrentCount;
EnableDPWMReg <= 1'b0;
DonePhaseSequenceReg <= 1'b0;
PhaseOrderReg <= 4'b0;
DischargeReg <= 1'b0;
VoltageLevelReg <= 1'b0;
TXData <= 4'b0;
AuxCounter <= 20'd0;
SmallerPhases <= SmallerPhases;
if (CurrentCount >= PhaseCount)
begin
SmallerPhases <= SmallerPhases;
PSState <= 10'b1110000010;
end
else
begin
CompA <= {PhaseTiming[PhaseID][15:0],
PhaseID[3:0]};
CompB <= {PhaseTiming[CurrentCount][15:0],
CurrentCount[3:0]};
PSState <= 10'b1110010001;
end
end
// Do actual comparison in this state
10'b1110010001:
begin
Transmit <= 1'b0;
CurrentCount <= CurrentCount + 4'b1;
EnableDPWMReg <= 1'b0;
DonePhaseSequenceReg <= 1'b0;
PhaseOrderReg <= 4'b0;
DischargeReg <= 1'b0;
VoltageLevelReg <= 1'b0;
TXData <= 4'b0;
AuxCounter <= 20'd0;
PSState <= 10'b1110000001;
if (CompA > CompB)
begin
SmallerPhases <= SmallerPhases + 4'b1;
end
else
begin
SmallerPhases <= SmallerPhases;
end
end
// Shift according to total number of phases to determine order
10'b1110000010:
begin
Transmit <= 1'b0;
CurrentCount <= 4'b0;
EnableDPWMReg <= 1'b0;
DonePhaseSequenceReg <= 1'b0;
DischargeReg <= 1'b0;
VoltageLevelReg <= 1'b0;
TXData <= 4'b0;
AuxCounter <= 20'b0;
SmallerPhases <= SmallerPhases;
if (ReOrderPhases == 1'b0)
begin
PhaseOrderReg <= PhaseID;
end
else if (BitShift == 2'b11)
begin
PhaseOrderReg <= {SmallerPhases[0],
SmallerPhases[3:1]};
APPENDIX A: VERILOG HDL FOR DIGITAL BLOCKS 112
end
else if (BitShift == 2'b10)
begin
PhaseOrderReg <= {1'b0, SmallerPhases[0],
SmallerPhases[2:1]};
end
else if (BitShift == 2'b01)
begin
PhaseOrderReg <= {2'b00, SmallerPhases[0],
SmallerPhases[1]};
end
else
begin
PhaseOrderReg <= {3'b000, SmallerPhases[0]};
end
PSState <= 10'b1111111111;
end
///////////////////
// All done
///////////////////
// Stay in this state forever - we are all done
10'b1111111111:
begin
Transmit <= 1'b0;
CurrentCount <= 4'b0;
EnableDPWMReg <= 1'b0;
DonePhaseSequenceReg <= 1'b1;
PhaseOrderReg <= PhaseOrderReg;
DischargeReg <= 1'b0;
VoltageLevelReg <= 1'b1;
TXData <= 4'b0;
AuxCounter <= 20'b0;
PSState <= 10'b1111111111;
end
endcase
end
end
// Calculates BitShift based on total number of phases
always @(PhaseCount)
begin
if (PhaseCount > 4'b1000)
begin
BitShift = 2'b11;
end
else if (PhaseCount > 4'b0100)
begin
BitShift = 2'b10;
end
else if (PhaseCount > 4'b0010)
begin
BitShift = 2'b01;
end
else
begin
BitShift = 2'b00;
end
end
endmodule
/*******************************************************************************************
/ Module: phase_timer
/ Written by: Jason Weinstein
/
/ This module waits for the DLL to lock and then measures and transmits errors on the bus
/ for the timing of all the phases.
*******************************************************************************************/
module phase_timer(Reset, clk_dll, PhaseCount, TXData, Transmit, Locked, ADCSample, ADCIn);
APPENDIX A: VERILOG HDL FOR DIGITAL BLOCKS 113
input Reset; // Reset signal - active LO
input clk_dll; // DLL clock - approximately
N*f_s where N is the number of phases
input [3:0] PhaseCount; // The total number of phases
present in the system - can be sampled
//
once the phase count is complete
output [3:0] TXData; // Output to communication block (4 bits)
output Transmit; // Output to communication block
- rising edge indicates that a
//
transmission should be sent
input Locked; // Goes high when DLL is "locked"
output ADCSample; // Positive edge sent to ADC to
start ADC measurement and sampling process
input [3:0] ADCIn; // ADC value
reg [9:0] PTState; // State variable for main phase
timer FSM
reg [3:0] CurrentCount; // For keeping track of the
currently active phase
reg ADCSampleReg; // Register for storing ADCSample
output
reg [3:0] TXDataReg; // Register for storing TXData output
reg TransmitEnable; // For controlling when this
module is active
reg [3:0] TXDataOut; // Register for storing TXData output
(sampled at negative clock edge)
reg [2:0] LockedMetastable; // Metastable version of Locked input
// Assign outputs to various registers
// More proper than using "output reg"
assign ADCSample = ADCSampleReg;
assign TXData = TXDataOut;
// Only transmit when TransmitEnable is high
assign Transmit = clk_dll & TransmitEnable;
// Metastabilize Locked input
always @(negedge Reset or posedge clk_dll)
begin
if (Reset == 1'b0)
begin
LockedMetastable <= 3'b0;
end
else
begin
LockedMetastable[0] <= Locked;
LockedMetastable[1] <= LockedMetastable[0];
LockedMetastable[2] <= LockedMetastable[1];
end
end
// Main phase timer FSM
always @(negedge Reset or posedge clk_dll)
begin
if (Reset == 1'b0)
begin
PTState <= 10'b0000000000;
CurrentCount <= 4'b0;
ADCSampleReg <= 1'b0;
TXDataReg <= 4'b0;
TransmitEnable <= 1'b0;
end
else
begin
case (PTState)
// Initial state
// Wait for DLL to lock - this will only happen if this state
has PhaseOrder 4'b0000
// (no need to check this again here)
APPENDIX A: VERILOG HDL FOR DIGITAL BLOCKS 114
10'b0000000000:
begin
CurrentCount <= 4'b0;
ADCSampleReg <= 1'b0;
TXDataReg <= 4'b0;
TransmitEnable <= 1'b0;
if (LockedMetastable[2] == 1'b1)
begin
PTState <= 10'b0000000001;
end
else
begin
PTState <= 10'b0000000000;
end
end
// Obtain initial sample of ADC
10'b0000000001:
begin
CurrentCount <= 4'b0;
ADCSampleReg <= 1'b1;
TXDataReg <= 4'b0;
TransmitEnable <= 1'b0;
PTState <= 10'b0000000010;
end
// Wait a few cycles to make sure first ADC sample is ready
10'b0000000010:
begin
ADCSampleReg <= 1'b0;
TXDataReg <= ADCIn;
TransmitEnable <= 1'b0;
if (CurrentCount >= (PhaseCount - 4'b1))
begin
CurrentCount <= 4'b0;
PTState <= 10'b0000000011;
end
else
begin
CurrentCount <= CurrentCount + 1'b1;
PTState <= 10'b0000000010;
end
end
// Steady state
10'b0000000011:
begin
if (CurrentCount == 4'b0)
begin
ADCSampleReg <= 1'b1;
end
else
begin
ADCSampleReg <= 1'b0;
end
if (CurrentCount == (PhaseCount - 4'd1))
begin
TXDataReg <= ADCIn;
end
else
begin
TXDataReg <= TXDataReg;
end
TransmitEnable <= 1'b1;
if (CurrentCount == (PhaseCount - 4'b1))
begin
CurrentCount <= 4'b0;
end
else
begin
CurrentCount <= CurrentCount + 1'b1;
end
PTState <= 10'b0000000011;
end
APPENDIX A: VERILOG HDL FOR DIGITAL BLOCKS 115
endcase
end
end
// Sample TXDataReg at negative edge of the clock to satisfy both setup and hold times
always @(negedge Reset or negedge clk_dll)
begin
if (Reset == 1'b0)
begin
TXDataOut <= 4'b0;
end
else
begin
TXDataOut <= TXDataReg;
end
end
endmodule
/*******************************************************************************************
/ Module: pi_compensator
/ Written by: Jason Weinstein
/
/ Basic PI compensator with output saturation.
*******************************************************************************************/
module pi_compensator(DOut, DLast, Error, LUT0, LUT1, LUT2, LUT3, LUT4, LUT5, LUT6, LUT7,
LUT8, DeadTime);
output signed [15:0] DOut; // Duty ratio output
input signed [15:0] DLast; // Previous duty ratio
input [3:0] Error; // Error value
input signed [15:0] LUT8; // These 9 entries are the
values for the PI look-up table
input signed [15:0] LUT7; // There is a different
value for each error value:
input signed [15:0] LUT6; // -4, -3,
-2, -1, 0, +1, +2, +3, +4
input signed [15:0] LUT5;
input signed [15:0] LUT4;
input signed [15:0] LUT3;
input signed [15:0] LUT2;
input signed [15:0] LUT1;
input signed [15:0] LUT0;
input [7:0] DeadTime;
// Note: all numbers in this block have 6 binary digits to the right of the decimal
point and 10 binary
// digits to the left (for a total of 16 digits).
// Registers and wires
reg signed [15:0] EA;
wire signed [15:0] DUnsaturated;
reg signed [15:0] DSaturated;
wire [14:0] min_d_shifted;
wire [14:0] max_d_shifted;
// Minimum and maximum duty ratios
assign max_d_shifted = 14'd16000;
assign min_d_shifted = {1'b0, DeadTime, 6'b0} + 14'd128;
// Calculate unsaturated duty ratio
assign DUnsaturated = DLast + EA;
// Set output duty ratio to appropriate bits of DSaturated
assign DOut = DSaturated;
// Saturate duty ratio
always @(DUnsaturated or max_d_shifted or min_d_shifted)
begin
if (DUnsaturated[15] == 1'b0)
begin
APPENDIX A: VERILOG HDL FOR DIGITAL BLOCKS 116
if (DUnsaturated[14:0] >= max_d_shifted)
begin
DSaturated[15] = 1'b0;
DSaturated[14:0] = max_d_shifted;
end
else if (DUnsaturated[15:0] <= min_d_shifted)
begin
DSaturated[15] = 1'b0;
DSaturated[14:0] = min_d_shifted;
end
else
begin
DSaturated = DUnsaturated;
end
end
else
begin
DSaturated[15] = 1'b0;
DSaturated[14:0] = min_d_shifted;
end
end
// Calculate A*Error (look-up table)
always @(Error or LUT0 or LUT1 or LUT2 or LUT3 or LUT4 or LUT5 or LUT6 or LUT7 or
LUT8)
begin
case (Error)
// +4
4'b0100:
begin
EA = LUT8;
end
// +3
4'b0011:
begin
EA = LUT7;
end
// +2
4'b0010:
begin
EA = LUT6;
end
// +1
4'b0001:
begin
EA = LUT5;
end
// 0
4'b0000:
begin
EA = LUT4;
end
// -1
4'b1111:
begin
EA = LUT3;
end
// -2
4'b1110:
begin
EA = LUT2;
end
// -3
4'b1101:
begin
EA = LUT1;
end
// -4
4'b1100:
begin
EA = LUT0;
APPENDIX A: VERILOG HDL FOR DIGITAL BLOCKS 117
end
// Default
default:
begin
EA = LUT4;
end
endcase
end
endmodule
/*******************************************************************************************
/ Module: programmable_unit
/ Written by: Jason Weinstein
/
/ Programs various values onto the prototype chip
*******************************************************************************************/
module programmable_unit (Reset, ClkProgram, DataBus, PhaseEnabled, PhaseReOrder,
InitialPhaseOverride, InitialPhaseOverrideValue, Start, Vref0, Vref1, OpenLoop,
PhaseOrderOverride, DOpenLoop, DeadTime, DCharge, LUT0, LUT1, LUT2, LUT3, LUT4, LUT5, LUT6,
LUT7, LUT8, PhaseOrder, MuxControlOverride, DelayControlOverride, MuxControlOverrideValue,
DelayControlOverrideValue, DebugRail, DonePhaseCount, DonePhaseSequence, Locked, PhaseID,
PhaseOrderInternal, PhaseCount, PhaseTimer, IsInitialPhase, RingOscFreq, D, Error,
DelayControlIn, DAC_enable, DAC_freq, SmallerPhases, Prog_select, ADC_enable,
Ring_osc_enable, DLL_enable);
input Reset;
input ClkProgram;
input [7:0] DataBus;
output [3:0] DebugRail;
input Prog_select;
output PhaseEnabled;
output PhaseReOrder;
output InitialPhaseOverride;
output InitialPhaseOverrideValue;
output Start;
output OpenLoop;
output PhaseOrderOverride;
output [9:0] Vref0;
output [9:0] Vref1;
output [7:0] DOpenLoop;
output [7:0] DeadTime;
output [7:0] DCharge;
output [15:0] LUT0;
output [15:0] LUT1;
output [15:0] LUT2;
output [15:0] LUT3;
output [15:0] LUT4;
output [15:0] LUT5;
output [15:0] LUT6;
output [15:0] LUT7;
output [15:0] LUT8;
output [3:0] PhaseOrder;
output MuxControlOverride;
output DelayControlOverride;
output [6:0] MuxControlOverrideValue;
output [2:0] DelayControlOverrideValue;
output [7:0] RingOscFreq;
output DAC_enable;
output [2:0] DAC_freq;
output ADC_enable;
output Ring_osc_enable;
output DLL_enable;
input DonePhaseCount;
input DonePhaseSequence;
input Locked;
input [3:0] PhaseID;
input [3:0] PhaseOrderInternal;
input [3:0] PhaseCount;
APPENDIX A: VERILOG HDL FOR DIGITAL BLOCKS 118
input [15:0] PhaseTimer;
input IsInitialPhase;
input [7:0] D;
input [3:0] Error;
input [2:0] DelayControlIn;
input [3:0] SmallerPhases;
wire [7:0] DebugMuxSelect;
reg [3:0] DebugRailReg;
assign DebugRail = DebugRailReg;
reg [7:0] ProgramData [32:0];
reg [1:0] ProgramState;
reg [7:0] Address;
parameter signed a = 16'b0000000000100011;
parameter A0 = a*(16'hffff-16'd4+16'd1);
parameter A1 = a*(16'hffff-16'd3+16'd1);
parameter A2 = a*(16'hffff-16'd2+16'd1);
parameter A3 = a*(16'hffff-16'd1+16'd1);
parameter A4 = a*16'd0;
parameter A5 = a*16'd1;
parameter A6 = a*16'd2;
parameter A7 = a*16'd3;
parameter A8 = a*16'd4;
parameter Unused = 8'b0;
// Default values and output assignments
// 00: - PhaseOrderOverride OpenLoop Start InitialPhaseOverrideValue
InitialPhaseOverride PhaseReOrder PhaseEnabled
parameter ProgramData_00 = 8'b0_0_0_0_0_0_1_1;
assign PhaseEnabled = ProgramData[0][0];
assign PhaseReOrder = ProgramData[0][1];
assign InitialPhaseOverride = ProgramData[0][2];
assign InitialPhaseOverrideValue = ProgramData[0][3];
assign Start = ProgramData[0][4];
assign OpenLoop = ProgramData[0][5];
assign PhaseOrderOverride = ProgramData[0][6];
// 01: Vref0[7:0]
parameter ProgramData_01 = 8'b01010101;
// 02: Vref0[9:8]
parameter ProgramData_02 = 8'b000000_01;
assign Vref0 = {ProgramData[2][1:0], ProgramData[1]};
// 03: Vref1[7:0]
parameter ProgramData_03 = 8'b00000000;
// 04: Vref1[9:8]
parameter ProgramData_04 = 8'b000000_10;
assign Vref1 = {ProgramData[4][1:0], ProgramData[3]};
// 05: DOpenLoop
parameter ProgramData_05 = 8'b10000000;
assign DOpenLoop = ProgramData[5];
// 06: DeadTime
parameter ProgramData_06 = 8'b00011000;
assign DeadTime = ProgramData[6];
// 07: DCharge
parameter ProgramData_07 = 8'b01000110;
assign DCharge = ProgramData[7];
// 08: LUT8[7:0]
parameter ProgramData_08 = A8[7:0];
// 09: LUT8[15:8]
parameter ProgramData_09 = A8[15:8];
assign LUT8 = {ProgramData[9], ProgramData[8]};
// 10: LUT7[7:0]
parameter ProgramData_10 = A7[7:0];
// 11: LUT7[15:8]
parameter ProgramData_11 = A7[15:8];
assign LUT7 = {ProgramData[11], ProgramData[10]};
// 12: LUT6[7:0]
parameter ProgramData_12 = A6[7:0];
APPENDIX A: VERILOG HDL FOR DIGITAL BLOCKS 119
// 13: LUT6[15:8]
parameter ProgramData_13 = A6[15:8];
assign LUT6 = {ProgramData[13], ProgramData[12]};
// 14: LUT5[7:0]
parameter ProgramData_14 = A5[7:0];
// 15: LUT5[15:8]
parameter ProgramData_15 = A5[15:8];
assign LUT5 = {ProgramData[15], ProgramData[14]};
// 16: LUT4[7:0]
parameter ProgramData_16 = A4[7:0];
// 17: LUT4[15:8]
parameter ProgramData_17 = A4[15:8];
assign LUT4 = {ProgramData[17], ProgramData[16]};
// 18: LUT3[7:0]
parameter ProgramData_18 = A3[7:0];
// 19: LUT3[15:8]
parameter ProgramData_19 = A3[15:8];
assign LUT3 = {ProgramData[19], ProgramData[18]};
// 20: LUT2[7:0]
parameter ProgramData_20 = A2[7:0];
// 21: LUT2[15:8]
parameter ProgramData_21 = A2[15:8];
assign LUT2 = {ProgramData[21], ProgramData[20]};
// 22: LUT1[7:0]
parameter ProgramData_22 = A1[7:0];
// 23: LUT1[15:6]
parameter ProgramData_23 = A1[15:8];
assign LUT1 = {ProgramData[23], ProgramData[22]};
// 24: LUT0[7:0]
parameter ProgramData_24 = A0[7:0];
// 25: LUT0[15:8]
parameter ProgramData_25 = A0[15:8];
assign LUT0 = {ProgramData[25], ProgramData[24]};
// 26: - - - - PhaseOrder
parameter ProgramData_26 = 8'b0000_0000;
assign PhaseOrder = ProgramData[26][3:0];
// 27: - - - - - - MuxControlOverride DelayControlOverride
parameter ProgramData_27 = 8'b000000_00;
assign MuxControlOverride = ProgramData[27][1];
assign DelayControlOverride = ProgramData[27][0];
// 28: - MuxControlOverrideValue
parameter ProgramData_28 = 8'b00000000;
assign MuxControlOverrideValue = ProgramData[28][6:0];
// 29: - - - - - DelayControlOverrideValue
parameter ProgramData_29 = 8'b00000000;
assign DelayControlOverrideValue = ProgramData[29][2:0];
// 30: DebugMuxSelect
parameter ProgramData_30 = 8'b00000000;
assign DebugMuxSelect = ProgramData[30];
// 31: RingOscFreq
parameter ProgramData_31 = 8'b11110000;
assign RingOscFreq = ProgramData[31];
// 32: - ADC_enable Ring_osc_enable DLL_enable DAC_enable DAC_freq
parameter ProgramData_32 = 8'b0_1_1_1_0_001;
assign DAC_enable = ProgramData[32][3];
assign DAC_freq = ProgramData[32][2:0];
assign ADC_enable = ProgramData[32][6];
assign Ring_osc_enable = ProgramData[32][5];
assign DLL_enable = ProgramData[32][4];
always @(negedge Reset or posedge ClkProgram)
begin
if (Reset == 1'b0)
begin
ProgramState <= 2'b00;
Address <= 8'b00000000;
ProgramData[0] <= ProgramData_00;
ProgramData[1] <= ProgramData_01;
ProgramData[2] <= ProgramData_02;
ProgramData[3] <= ProgramData_03;
ProgramData[4] <= ProgramData_04;
APPENDIX A: VERILOG HDL FOR DIGITAL BLOCKS 120
ProgramData[5] <= ProgramData_05;
ProgramData[6] <= ProgramData_06;
ProgramData[7] <= ProgramData_07;
ProgramData[8] <= ProgramData_08;
ProgramData[9] <= ProgramData_09;
ProgramData[10] <= ProgramData_10;
ProgramData[11] <= ProgramData_11;
ProgramData[12] <= ProgramData_12;
ProgramData[13] <= ProgramData_13;
ProgramData[14] <= ProgramData_14;
ProgramData[15] <= ProgramData_15;
ProgramData[16] <= ProgramData_16;
ProgramData[17] <= ProgramData_17;
ProgramData[18] <= ProgramData_18;
ProgramData[19] <= ProgramData_19;
ProgramData[20] <= ProgramData_20;
ProgramData[21] <= ProgramData_21;
ProgramData[22] <= ProgramData_22;
ProgramData[23] <= ProgramData_23;
ProgramData[24] <= ProgramData_24;
ProgramData[25] <= ProgramData_25;
ProgramData[26] <= ProgramData_26;
ProgramData[27] <= ProgramData_27;
ProgramData[28] <= ProgramData_28;
ProgramData[29] <= ProgramData_29;
ProgramData[30] <= ProgramData_30;
ProgramData[31] <= ProgramData_31;
ProgramData[32] <= ProgramData_32;
end
else
begin
if (Prog_select == 1'b1)
begin
ProgramState <= 2'b01;
Address <= 8'b00000000;
end
else
begin
case (ProgramState)
2'b00:
begin
ProgramState <= 2'b01;
Address <= DataBus;
end
2'b01:
begin
ProgramState <= 2'b00;
ProgramData[Address[5:0]] <= DataBus;
end
endcase
end
end
end
always @(DebugMuxSelect or DebugRail or DonePhaseCount or DonePhaseSequence or Locked
or PhaseID or PhaseOrderInternal or PhaseCount or PhaseTimer or IsInitialPhase or D or Error
or DelayControlIn or SmallerPhases)
begin
case (DebugMuxSelect)
8'b00000000:
begin
DebugRailReg = {IsInitialPhase, Locked, DonePhaseSequence,
DonePhaseCount};
end
8'b00000001:
begin
DebugRailReg = PhaseID;
end
8'b00000010:
begin
DebugRailReg = PhaseOrderInternal;
APPENDIX A: VERILOG HDL FOR DIGITAL BLOCKS 121
end
8'b00000011:
begin
DebugRailReg = SmallerPhases;
end
8'b00000100:
begin
DebugRailReg = PhaseCount;
end
8'b00000101:
begin
DebugRailReg = PhaseTimer[3:0];
end
8'b00000110:
begin
DebugRailReg = PhaseTimer[7:4];
end
8'b00000111:
begin
DebugRailReg = PhaseTimer[11:8];
end
8'b00001000:
begin
DebugRailReg = PhaseTimer[15:12];
end
8'b00001001:
begin
DebugRailReg = D[3:0];
end
8'b00001010:
begin
DebugRailReg = D[7:4];
end
8'b00001011:
begin
DebugRailReg = Error;
end
8'b00001100:
begin
DebugRailReg = DelayControlIn;
end
default:
begin
DebugRailReg = 4'b0;
end
endcase
end
endmodule
/*******************************************************************************************
/ Module: reg_operation
/ Written by: Jason Weinstein
/
/ Set of FSM's for controlling the regular operation of the system. Contains
/ functionality for both single phase and multiphase operation. For single phase
/ operation, the main 1 MHz clock is used, otherwise the bus signals are used for timing.
*******************************************************************************************/
module reg_operation(Reset, Clk_256, Clk, DOut, DonePhaseSequence, DonePhaseCount,
PhaseCount, PhaseOrder, DPWMStart, ReceiveEnd, RXData, DPID, DLastOut, ErrorOut, ADCIn,
OpenLoop, DOpenLoop);
input Reset; // Reset signal - active LO
input Clk_256; // 256 MHz clock
input Clk; // 1 MHz clock
output [7:0] DOut; // Duty ratio sent to DPWM
input DonePhaseSequence; // Indicates phase sequencing process is
complete
input DonePhaseCount; // Indicates phase counting process is
complete
input [3:0] PhaseCount; // System phase count
APPENDIX A: VERILOG HDL FOR DIGITAL BLOCKS 122
input [3:0] PhaseOrder; // This phase's order in the
switching sequence
output DPWMStart; // Start pulse sent to DPWM
input ReceiveEnd; // Pulse sent from communication
block when each transmission is
//
complete - acts as a clock for multiphase operation
input [3:0] RXData; // Data received from the bus
(corresponds to error signal)
input [15:0] DPID; // Duty ratio caculated by the
compensator
output [15:0] DLastOut; // Last duty ratio send to the
compensator
output [3:0] ErrorOut; // Error value sent to the compensator
input [3:0] ADCIn; // ADC signal
input OpenLoop; // Indicates whether the
system should operate in open-loop mode
input [7:0] DOpenLoop; // Open-loop duty ratio
reg [3:0] RState; // State variable for multiphase
FSM
reg [3:0] PhaseTracker; // For counting phases for
multiphase operation
reg StartPulse; // Start pulse for
beginning of cycle
reg [3:0] SState; // State variable for main
control (both single phase and multiphase)
reg DPWMStartReg; // Indicates DPWM should begin
new switching cycle
reg [3:0] RXDataReg; // Data received from the bus
reg [15:0] DLast; // Previous duty radio
reg [3:0] AuxCounter; // Auxiliary counter used for various
purposes
reg [15:0] DReg; // Duty ratio sent to the
DPWM
reg [3:0] TState; // State variable for single
phase FSM
reg TStartPulse; // Indicates DPWM should begin
its switching cycle for single phase operation
wire AStartPulse; // DPWM start signal
wire SelfFlag; // Indicates whether we are using
single phase or multiphase operation
// If on, the main
clock will be used instead of the bus transmission signals
reg [3:0] ADCCapture; // Register for holding the last ADC
value (used for single phase operation)
reg [2:0] DonePhaseSequenceMS; // Metastable verion of DonePhaseSequence
reg [2:0] DonePhaseCountMS_256; // Metastable version of DonePhaseCount
(for clk_256)
reg [1:0] AStartPulseMS; // Metastable version of AStartPulse;
// Assign outputs to various registers
// More proper than using "output reg"
assign DPWMStart = DPWMStartReg;
assign DLastOut = DLast;
assign DOut = (OpenLoop == 1'b1 ? DOpenLoop : DReg[13:6]);
assign ErrorOut = RXDataReg;
// ADC input is captured at every clock cycle for single phase operation
always @(negedge Reset or posedge Clk)
begin
if (Reset == 1'b0)
begin
ADCCapture <= 4'b0;
end
else
begin
ADCCapture <= ADCIn;
end
end
APPENDIX A: VERILOG HDL FOR DIGITAL BLOCKS 123
// Metastabilize DonePhaseSequence input
always @(negedge Reset or posedge ReceiveEnd)
begin
if (Reset == 1'b0)
begin
DonePhaseSequenceMS <= 3'b0;
end
else
begin
DonePhaseSequenceMS[0] <= DonePhaseSequence;
DonePhaseSequenceMS[1] <= DonePhaseSequenceMS[0];
DonePhaseSequenceMS[2] <= DonePhaseSequenceMS[1];
end
end
// Metastabilize DonePhaseCount input (for Clk_256)
always @(negedge Reset or posedge Clk_256)
begin
if (Reset == 1'b0)
begin
DonePhaseCountMS_256 <= 3'b0;
end
else
begin
DonePhaseCountMS_256[0] <= DonePhaseCount;
DonePhaseCountMS_256[1] <= DonePhaseCountMS_256[0];
DonePhaseCountMS_256[2] <= DonePhaseCountMS_256[1];
end
end
// Metastabilize AStartPulse (for Clk_256)
always @(negedge Reset or posedge Clk_256)
begin
if (Reset == 1'b0)
begin
AStartPulseMS <= 2'b0;
end
else
begin
AStartPulseMS[0] <= AStartPulse;
AStartPulseMS[1] <= AStartPulseMS[0];
end
end
// Set DPWM block start pulse depending on whether we are using single phase or
multiphase operation
assign AStartPulse = ((DonePhaseCount == 1'b1 & PhaseCount == 4'b1) ? TStartPulse :
StartPulse);
// Indicates whether we are using single phase or multiphase operation
assign SelfFlag = ((DonePhaseCount == 1'b1 & PhaseCount == 4'b1) ? 1'b1 : 1'b0);
// Main FSM for multiphase operation
always @(negedge Reset or posedge ReceiveEnd)
begin
if (Reset == 1'b0)
begin
RState <= 4'b0000;
PhaseTracker <= 4'b0000;
StartPulse <= 1'b0;
end
else
begin
case (RState)
// Initial state
// Wait until phase sequencing has been performed
4'b0000:
begin
if (DonePhaseSequenceMS[2] == 1'b1)
begin
RState <= 4'b0001;
PhaseTracker <= 4'b0001;
APPENDIX A: VERILOG HDL FOR DIGITAL BLOCKS 124
if (PhaseOrder == 4'b0)
begin
StartPulse <= 1'b1;
end
else
begin
StartPulse <= 1'b0;
end
end
else
begin
RState <= 4'b0000;
PhaseTracker <= 4'b0000;
StartPulse <= 1'b0;
end
end
// Steady state
// Receive transmissions and act if current count is this phase
4'b0001:
begin
if (PhaseTracker == PhaseOrder)
begin
StartPulse <= 1'b1;
end
else
begin
StartPulse <= 1'b0;
end
if (PhaseTracker == (PhaseCount - 4'b1))
begin
PhaseTracker <= 4'b0;
end
else
begin
PhaseTracker <= (PhaseTracker + 4'b1);
end
RState <= 4'b0001;
end
endcase
end
end
// Similar to above except using Clk instead of ReceiveEnd for timing
always @(negedge Reset or posedge Clk_256)
begin
if (Reset == 1'b0)
begin
TState <= 4'b0000;
TStartPulse <= 1'b0;
end
else
begin
case (TState)
// Initial state
// Wait until phases have been counted and this is the only
phase
4'b0000:
begin
if (DonePhaseCountMS_256[2] == 1'b1 & PhaseCount ==
4'b1)
begin
TState <= 4'b0001;
end
else
begin
TState <= 4'b0000;
end
TStartPulse <= 1'b0;
end
// Before first cycle
4'b0001:
APPENDIX A: VERILOG HDL FOR DIGITAL BLOCKS 125
begin
if (Clk == 1'b1)
begin
TState <= 4'b0010;
end
else
begin
TState <= 4'b0001;
end
TStartPulse <= 1'b0;
end
// Still before first cycle
4'b0010:
begin
if (Clk == 1'b0)
begin
TState <= 4'b0011;
end
else
begin
TState <= 4'b0010;
end
TStartPulse <= 1'b0;
end
// Regular operation
// Mirror Clk pulses
4'b0011:
begin
if (Clk == 1'b1)
begin
TState <= 4'b0100;
TStartPulse <= 1'b1;
end
else
begin
TState <= 4'b0011;
TStartPulse <= 1'b0;
end
end
// Regular operation
4'b0100:
begin
if (Clk == 1'b0)
begin
TState <= 4'b0011;
TStartPulse <= 1'b0;
end
else
begin
TState <= 4'b0100;
TStartPulse <= 1'b1;
end
end
endcase
end
end
// Main FSM for both single phase and multiphase operation
always @(negedge Reset or posedge Clk_256)
begin
if (Reset == 1'b0)
begin
SState <= 4'b0000;
DPWMStartReg <= 1'b0;
RXDataReg <= 4'b0;
DLast <= 16'b0;
AuxCounter <= 4'b0;
DReg <= 16'b0;
end
else
begin
APPENDIX A: VERILOG HDL FOR DIGITAL BLOCKS 126
case (SState)
// Initial phase
// Wait for start pulse
4'b0000:
begin
DPWMStartReg <= 1'b0;
AuxCounter <= 4'b0;
if (AStartPulseMS[1] == 1'b1)
begin
SState <= 4'b0001;
if (SelfFlag == 1'b1)
begin
RXDataReg <= ADCCapture;
end
else
begin
RXDataReg <= RXData;
end
end
else
begin
SState <= 4'b0000;
RXDataReg <= RXDataReg;
end
DLast <= DLast;
DReg <= DReg;
end
// Wait a few cycles and record duty ratio
4'b0001:
begin
AuxCounter <= AuxCounter + 4'b1;
DPWMStartReg <= 1'b0;
RXDataReg <= RXDataReg;
if (AuxCounter == 1'b0 & AStartPulseMS[1] == 1'b0)
begin
DLast <= DLast;
DReg <= DReg;
SState <= 4'b0000;
end
else if (AuxCounter >= 4'd3)
begin
DLast <= DReg;
DReg <= DPID;
SState <= 4'b0010;
end
else
begin
DLast <= DLast;
DReg <= DReg;
SState <= 4'b0001;
end
end
// Send start signal to DPWM and return to initial state and
wait for next cycle
4'b0010:
begin
AuxCounter <= 4'b0;
DPWMStartReg <= 1'b1;
RXDataReg <= RXDataReg;
DLast <= DLast;
DReg <= DReg;
if (AStartPulseMS[1] == 1'b0)
begin
SState <= 4'b0000;
end
else
begin
SState <= 4'b0010;
end
end
endcase
APPENDIX A: VERILOG HDL FOR DIGITAL BLOCKS 127
end
end
endmodule
APPENDIX B: GATE-LEVEL NETLIST FOR COMMUNICATION BLOCK 128
Appendix B: Gate-Level Netlist for
Communication Block
`timescale 1ns/1ps
module comm_block_digital (Reset, Transmit, TXData, comm_out, ReceiveEnd, RXData, comm_in,
IsInitialPhase, clk_256, Clk_out, clk_128_out);
////////////////
// I/O pins
////////////////
input Reset;
input Transmit;
input [3:0] TXData;
inout comm_out;
output ReceiveEnd;
output [3:0] RXData;
input comm_in;
output IsInitialPhase;
input clk_256;
output Clk_out;
output clk_128_out;
///////////////
// Wires
///////////////
wire TranOut;
wire TranEnable;
wire [3:0] TXDataReg;
wire [5:0] TransmitClk;
wire n9, n10, n11, n12, n13, n14;
wire [3:0] ReceiveClk;
wire comm_in_buffered;
wire [19:0] TranDelay0;
wire [19:0] TranDelay1;
wire [19:0] TranDelay2;
wire [19:0] TranDelay3;
wire [19:0] TranDelay4;
wire [19:0] TranDelay5;
wire TranDelayInv2;
wire TranDelayInv3;
wire TranDelayInv4;
wire TranDelayInv5;
wire TranDelayInv6;
wire ReceiveClkWait;
wire [27:0] RecDelay0;
wire [19:0] RecDelay1;
wire [19:0] RecDelay2;
wire [19:0] RecDelay3;
wire [29:0] RecDelay4;
wire RecDelayInv4;
wire ReceiveClkWaitNot;
wire OrTempOutput;
wire TranDelayInv2Reset;
wire TranDelayInv3Reset;
wire TranDelayInv4Reset;
wire TranDelayInv5Reset;
APPENDIX B: GATE-LEVEL NETLIST FOR COMMUNICATION BLOCK 129
wire TranDelayInv6Reset;
wire RecDelayInv4Reset;
wire ReceiveClkWaitNotReset;
wire hi;
wire [4:0] comm_in_delayed;
wire comm_in_delayed_n;
// Tie Hi
TIEHI TH (.Y(hi));
// Clock divider wires
wire AN2, AN3, AN4, AN5, AN6, AN7, AN8, An1, add_22100_carry_7, add_22100_carry_6,
add_22100_carry_5, add_22100_carry_4, add_22100_carry_3, add_22100_carry_2;
wire [7:0] CDCount;
wire clk_128;
wire Clk;
////////////////
// Transmitter
////////////////
// Buffer with enable input
TBUFX20 Tran_B (.A(TranOut), .OE(TranEnable), .Y(comm_out));
OR4X1 ORA1 (.A(TransmitClk[0]), .B(TransmitClk[1]), .C(TransmitClk[2]),
.D(TransmitClk[3]), .Y(OrTempOutput));
OR2X1 ORB1 (.A(TransmitClk[4]), .B(OrTempOutput), .Y(TranEnable));
// Register TXData
DFFRHQX1 TXDReg0 (.D(TXData[0]), .CK(Transmit), .Q(TXDataReg[0]), .RN(Reset));
DFFRHQX1 TXDReg1 (.D(TXData[1]), .CK(Transmit), .Q(TXDataReg[1]), .RN(Reset));
DFFRHQX1 TXDReg2 (.D(TXData[2]), .CK(Transmit), .Q(TXDataReg[2]), .RN(Reset));
DFFRHQX1 TXDReg3 (.D(TXData[3]), .CK(Transmit), .Q(TXDataReg[3]), .RN(Reset));
// Transmitter combinational logic
NAND2BX1 U11 (.AN(TransmitClk[5]), .B(n9), .Y(TranOut));
AOI22X1 U12 (.A0(n10), .A1(n11), .B0(TXDataReg[3]), .B1(TransmitClk[4]), .Y(n9));
INVX1 U13 (.A(TransmitClk[4]), .Y(n11));
MX2X1 U14 (.S0(TransmitClk[3]), .B(TXDataReg[2]), .A(n12), .Y(n10));
MX2X1 U15 (.S0(TransmitClk[2]), .B(TXDataReg[1]), .A(n13), .Y(n12));
AOI2BB2X1 U16 (.A0N(TXDataReg[0]), .A1N(n14), .B0(TransmitClk[0]), .B1(n14), .Y(n13));
INVX1 U17 (.A(TransmitClk[1]), .Y(n14));
// Transmitter timing block
// TransmitClk[0]
DFFRHQX1 TSB0 (.D(hi), .CK(Transmit), .Q(TransmitClk[0]), .RN(TranDelayInv2Reset));
DLY4X1 DL00 (.A(TransmitClk[0]), .Y(TranDelay0[0]));
DLY4X1 DL01 (.A(TranDelay0[0]), .Y(TranDelay0[1]));
DLY4X1 DL02 (.A(TranDelay0[1]), .Y(TranDelay0[2]));
DLY4X1 DL03 (.A(TranDelay0[2]), .Y(TranDelay0[3]));
DLY4X1 DL04 (.A(TranDelay0[3]), .Y(TranDelay0[4]));
DLY4X1 DL05 (.A(TranDelay0[4]), .Y(TranDelay0[5]));
DLY4X1 DL06 (.A(TranDelay0[5]), .Y(TranDelay0[6]));
DLY4X1 DL07 (.A(TranDelay0[6]), .Y(TranDelay0[7]));
DLY4X1 DL08 (.A(TranDelay0[7]), .Y(TranDelay0[8]));
DLY4X1 DL09 (.A(TranDelay0[8]), .Y(TranDelay0[9]));
DLY4X1 DL010 (.A(TranDelay0[9]), .Y(TranDelay0[10]));
DLY4X1 DL011 (.A(TranDelay0[10]), .Y(TranDelay0[11]));
DLY4X1 DL012 (.A(TranDelay0[11]), .Y(TranDelay0[12]));
DLY4X1 DL013 (.A(TranDelay0[12]), .Y(TranDelay0[13]));
DLY4X1 DL014 (.A(TranDelay0[13]), .Y(TranDelay0[14]));
DLY4X1 DL015 (.A(TranDelay0[14]), .Y(TranDelay0[15]));
DLY4X1 DL016 (.A(TranDelay0[15]), .Y(TranDelay0[16]));
DLY4X1 DL017 (.A(TranDelay0[16]), .Y(TranDelay0[17]));
DLY4X1 DL018 (.A(TranDelay0[17]), .Y(TranDelay0[18]));
DLY4X1 DL019 (.A(TranDelay0[18]), .Y(TranDelay0[19]));
// TransmitClk[1]
DFFRHQX1 TSB1 (.D(hi), .CK(TranDelay0[19]), .Q(TransmitClk[1]),
.RN(TranDelayInv3Reset));
DLY4X1 DL10 (.A(TransmitClk[1]), .Y(TranDelay1[0]));
DLY4X1 DL11 (.A(TranDelay1[0]), .Y(TranDelay1[1]));
DLY4X1 DL12 (.A(TranDelay1[1]), .Y(TranDelay1[2]));
APPENDIX B: GATE-LEVEL NETLIST FOR COMMUNICATION BLOCK 130
DLY4X1 DL13 (.A(TranDelay1[2]), .Y(TranDelay1[3]));
DLY4X1 DL14 (.A(TranDelay1[3]), .Y(TranDelay1[4]));
DLY4X1 DL15 (.A(TranDelay1[4]), .Y(TranDelay1[5]));
DLY4X1 DL16 (.A(TranDelay1[5]), .Y(TranDelay1[6]));
DLY4X1 DL17 (.A(TranDelay1[6]), .Y(TranDelay1[7]));
DLY4X1 DL18 (.A(TranDelay1[7]), .Y(TranDelay1[8]));
DLY4X1 DL19 (.A(TranDelay1[8]), .Y(TranDelay1[9]));
DLY4X1 DL110 (.A(TranDelay1[9]), .Y(TranDelay1[10]));
DLY4X1 DL111 (.A(TranDelay1[10]), .Y(TranDelay1[11]));
DLY4X1 DL112 (.A(TranDelay1[11]), .Y(TranDelay1[12]));
DLY4X1 DL113 (.A(TranDelay1[12]), .Y(TranDelay1[13]));
DLY4X1 DL114 (.A(TranDelay1[13]), .Y(TranDelay1[14]));
DLY4X1 DL115 (.A(TranDelay1[14]), .Y(TranDelay1[15]));
DLY4X1 DL116 (.A(TranDelay1[15]), .Y(TranDelay1[16]));
DLY4X1 DL117 (.A(TranDelay1[16]), .Y(TranDelay1[17]));
DLY4X1 DL118 (.A(TranDelay1[17]), .Y(TranDelay1[18]));
DLY4X1 DL119 (.A(TranDelay1[18]), .Y(TranDelay1[19]));
// TransmitClk[2]
DFFRHQX1 TSB2 (.D(hi), .CK(TranDelay1[19]), .Q(TransmitClk[2]),
.RN(TranDelayInv4Reset));
INVX1 TINV2 (.A(TransmitClk[2]), .Y(TranDelayInv2));
AND2X1 TAND2 (.A(Reset), .B(TranDelayInv2), .Y(TranDelayInv2Reset));
DLY4X1 DL20 (.A(TransmitClk[2]), .Y(TranDelay2[0]));
DLY4X1 DL21 (.A(TranDelay2[0]), .Y(TranDelay2[1]));
DLY4X1 DL22 (.A(TranDelay2[1]), .Y(TranDelay2[2]));
DLY4X1 DL23 (.A(TranDelay2[2]), .Y(TranDelay2[3]));
DLY4X1 DL24 (.A(TranDelay2[3]), .Y(TranDelay2[4]));
DLY4X1 DL25 (.A(TranDelay2[4]), .Y(TranDelay2[5]));
DLY4X1 DL26 (.A(TranDelay2[5]), .Y(TranDelay2[6]));
DLY4X1 DL27 (.A(TranDelay2[6]), .Y(TranDelay2[7]));
DLY4X1 DL28 (.A(TranDelay2[7]), .Y(TranDelay2[8]));
DLY4X1 DL29 (.A(TranDelay2[8]), .Y(TranDelay2[9]));
DLY4X1 DL210 (.A(TranDelay2[9]), .Y(TranDelay2[10]));
DLY4X1 DL211 (.A(TranDelay2[10]), .Y(TranDelay2[11]));
DLY4X1 DL212 (.A(TranDelay2[11]), .Y(TranDelay2[12]));
DLY4X1 DL213 (.A(TranDelay2[12]), .Y(TranDelay2[13]));
DLY4X1 DL214 (.A(TranDelay2[13]), .Y(TranDelay2[14]));
DLY4X1 DL215 (.A(TranDelay2[14]), .Y(TranDelay2[15]));
DLY4X1 DL216 (.A(TranDelay2[15]), .Y(TranDelay2[16]));
DLY4X1 DL217 (.A(TranDelay2[16]), .Y(TranDelay2[17]));
DLY4X1 DL218 (.A(TranDelay2[17]), .Y(TranDelay2[18]));
DLY4X1 DL219 (.A(TranDelay2[18]), .Y(TranDelay2[19]));
// TransmitClk[3]
DFFRHQX1 TSB3 (.D(hi), .CK(TranDelay2[19]), .Q(TransmitClk[3]),
.RN(TranDelayInv5Reset));
INVX1 TINV3 (.A(TransmitClk[3]), .Y(TranDelayInv3));
AND2X1 TAND3 (.A(Reset), .B(TranDelayInv3), .Y(TranDelayInv3Reset));
DLY4X1 DL30 (.A(TransmitClk[3]), .Y(TranDelay3[0]));
DLY4X1 DL31 (.A(TranDelay3[0]), .Y(TranDelay3[1]));
DLY4X1 DL32 (.A(TranDelay3[1]), .Y(TranDelay3[2]));
DLY4X1 DL33 (.A(TranDelay3[2]), .Y(TranDelay3[3]));
DLY4X1 DL34 (.A(TranDelay3[3]), .Y(TranDelay3[4]));
DLY4X1 DL35 (.A(TranDelay3[4]), .Y(TranDelay3[5]));
DLY4X1 DL36 (.A(TranDelay3[5]), .Y(TranDelay3[6]));
DLY4X1 DL37 (.A(TranDelay3[6]), .Y(TranDelay3[7]));
DLY4X1 DL38 (.A(TranDelay3[7]), .Y(TranDelay3[8]));
DLY4X1 DL39 (.A(TranDelay3[8]), .Y(TranDelay3[9]));
DLY4X1 DL310 (.A(TranDelay3[9]), .Y(TranDelay3[10]));
DLY4X1 DL311 (.A(TranDelay3[10]), .Y(TranDelay3[11]));
DLY4X1 DL312 (.A(TranDelay3[11]), .Y(TranDelay3[12]));
DLY4X1 DL313 (.A(TranDelay3[12]), .Y(TranDelay3[13]));
DLY4X1 DL314 (.A(TranDelay3[13]), .Y(TranDelay3[14]));
DLY4X1 DL315 (.A(TranDelay3[14]), .Y(TranDelay3[15]));
DLY4X1 DL316 (.A(TranDelay3[15]), .Y(TranDelay3[16]));
DLY4X1 DL317 (.A(TranDelay3[16]), .Y(TranDelay3[17]));
DLY4X1 DL318 (.A(TranDelay3[17]), .Y(TranDelay3[18]));
DLY4X1 DL319 (.A(TranDelay3[18]), .Y(TranDelay3[19]));
// TransmitClk[4]
DFFRHQX1 TSB4 (.D(hi), .CK(TranDelay3[19]), .Q(TransmitClk[4]),
.RN(TranDelayInv6Reset));
INVX1 TINV4 (.A(TransmitClk[4]), .Y(TranDelayInv4));
APPENDIX B: GATE-LEVEL NETLIST FOR COMMUNICATION BLOCK 131
AND2X1 TAND4 (.A(Reset), .B(TranDelayInv4), .Y(TranDelayInv4Reset));
DLY4X1 DL40 (.A(TransmitClk[4]), .Y(TranDelay4[0]));
DLY4X1 DL41 (.A(TranDelay4[0]), .Y(TranDelay4[1]));
DLY4X1 DL42 (.A(TranDelay4[1]), .Y(TranDelay4[2]));
DLY4X1 DL43 (.A(TranDelay4[2]), .Y(TranDelay4[3]));
DLY4X1 DL44 (.A(TranDelay4[3]), .Y(TranDelay4[4]));
DLY4X1 DL45 (.A(TranDelay4[4]), .Y(TranDelay4[5]));
DLY4X1 DL46 (.A(TranDelay4[5]), .Y(TranDelay4[6]));
DLY4X1 DL47 (.A(TranDelay4[6]), .Y(TranDelay4[7]));
DLY4X1 DL48 (.A(TranDelay4[7]), .Y(TranDelay4[8]));
DLY4X1 DL49 (.A(TranDelay4[8]), .Y(TranDelay4[9]));
DLY4X1 DL410 (.A(TranDelay4[9]), .Y(TranDelay4[10]));
DLY4X1 DL411 (.A(TranDelay4[10]), .Y(TranDelay4[11]));
DLY4X1 DL412 (.A(TranDelay4[11]), .Y(TranDelay4[12]));
DLY4X1 DL413 (.A(TranDelay4[12]), .Y(TranDelay4[13]));
DLY4X1 DL414 (.A(TranDelay4[13]), .Y(TranDelay4[14]));
DLY4X1 DL415 (.A(TranDelay4[14]), .Y(TranDelay4[15]));
DLY4X1 DL416 (.A(TranDelay4[15]), .Y(TranDelay4[16]));
DLY4X1 DL417 (.A(TranDelay4[16]), .Y(TranDelay4[17]));
DLY4X1 DL418 (.A(TranDelay4[17]), .Y(TranDelay4[18]));
DLY4X1 DL419 (.A(TranDelay4[18]), .Y(TranDelay4[19]));
// TransmitClk[5]
DFFRHQX1 TSB5 (.D(hi), .CK(TranDelay4[19]), .Q(TransmitClk[5]),
.RN(TranDelayInv6Reset));
INVX1 TINV5 (.A(TransmitClk[5]), .Y(TranDelayInv5));
AND2X1 TAND5 (.A(Reset), .B(TranDelayInv5), .Y(TranDelayInv5Reset));
DLY4X1 DL50 (.A(TransmitClk[5]), .Y(TranDelay5[0]));
DLY4X1 DL51 (.A(TranDelay5[0]), .Y(TranDelay5[1]));
DLY4X1 DL52 (.A(TranDelay5[1]), .Y(TranDelay5[2]));
DLY4X1 DL53 (.A(TranDelay5[2]), .Y(TranDelay5[3]));
DLY4X1 DL54 (.A(TranDelay5[3]), .Y(TranDelay5[4]));
DLY4X1 DL55 (.A(TranDelay5[4]), .Y(TranDelay5[5]));
DLY4X1 DL56 (.A(TranDelay5[5]), .Y(TranDelay5[6]));
DLY4X1 DL57 (.A(TranDelay5[6]), .Y(TranDelay5[7]));
DLY4X1 DL58 (.A(TranDelay5[7]), .Y(TranDelay5[8]));
DLY4X1 DL59 (.A(TranDelay5[8]), .Y(TranDelay5[9]));
DLY4X1 DL510 (.A(TranDelay5[9]), .Y(TranDelay5[10]));
DLY4X1 DL511 (.A(TranDelay5[10]), .Y(TranDelay5[11]));
DLY4X1 DL512 (.A(TranDelay5[11]), .Y(TranDelay5[12]));
DLY4X1 DL513 (.A(TranDelay5[12]), .Y(TranDelay5[13]));
DLY4X1 DL514 (.A(TranDelay5[13]), .Y(TranDelay5[14]));
DLY4X1 DL515 (.A(TranDelay5[14]), .Y(TranDelay5[15]));
DLY4X1 DL516 (.A(TranDelay5[15]), .Y(TranDelay5[16]));
DLY4X1 DL517 (.A(TranDelay5[16]), .Y(TranDelay5[17]));
DLY4X1 DL518 (.A(TranDelay5[17]), .Y(TranDelay5[18]));
DLY4X1 DL519 (.A(TranDelay5[18]), .Y(TranDelay5[19]));
INVX1 TINV6 (.A(TranDelay5[19]), .Y(TranDelayInv6));
AND2X1 TAND6 (.A(Reset), .B(TranDelayInv6), .Y(TranDelayInv6Reset));
////////////////
// Receiver
////////////////
// Buffer comm_in
BUFX1 InBuff (.A(comm_in), .Y(comm_in_buffered));
// Register RXData
DFFRHQX4 RXDReg0 (.D(comm_in_buffered), .CK(ReceiveClk[0]), .Q(RXData[0]),
.RN(Reset));
DFFRHQX4 RXDReg1 (.D(comm_in_buffered), .CK(ReceiveClk[1]), .Q(RXData[1]),
.RN(Reset));
DFFRHQX4 RXDReg2 (.D(comm_in_buffered), .CK(ReceiveClk[2]), .Q(RXData[2]),
.RN(Reset));
DFFRHQX4 RXDReg3 (.D(comm_in_buffered), .CK(ReceiveClk[3]), .Q(RXData[3]),
.RN(Reset));
// Receiver timing block
// ReceiveClkWait
DFFNRX1 RB0 (.D(hi), .CKN(comm_in_buffered), .Q(ReceiveClkWait),
.RN(RecDelayInv4Reset));
DLY4X1 RDL00 (.A(ReceiveClkWait), .Y(RecDelay0[0]));
APPENDIX B: GATE-LEVEL NETLIST FOR COMMUNICATION BLOCK 132
DLY4X1 RDL01 (.A(RecDelay0[0]), .Y(RecDelay0[1]));
DLY4X1 RDL02 (.A(RecDelay0[1]), .Y(RecDelay0[2]));
DLY4X1 RDL03 (.A(RecDelay0[2]), .Y(RecDelay0[3]));
DLY4X1 RDL04 (.A(RecDelay0[3]), .Y(RecDelay0[4]));
DLY4X1 RDL05 (.A(RecDelay0[4]), .Y(RecDelay0[5]));
DLY4X1 RDL06 (.A(RecDelay0[5]), .Y(RecDelay0[6]));
DLY4X1 RDL07 (.A(RecDelay0[6]), .Y(RecDelay0[7]));
DLY4X1 RDL08 (.A(RecDelay0[7]), .Y(RecDelay0[8]));
DLY4X1 RDL09 (.A(RecDelay0[8]), .Y(RecDelay0[9]));
DLY4X1 RDL010 (.A(RecDelay0[9]), .Y(RecDelay0[10]));
DLY4X1 RDL011 (.A(RecDelay0[10]), .Y(RecDelay0[11]));
DLY4X1 RDL012 (.A(RecDelay0[11]), .Y(RecDelay0[12]));
DLY4X1 RDL013 (.A(RecDelay0[12]), .Y(RecDelay0[13]));
DLY4X1 RDL014 (.A(RecDelay0[13]), .Y(RecDelay0[14]));
DLY4X1 RDL015 (.A(RecDelay0[14]), .Y(RecDelay0[15]));
DLY4X1 RDL016 (.A(RecDelay0[15]), .Y(RecDelay0[16]));
DLY4X1 RDL017 (.A(RecDelay0[16]), .Y(RecDelay0[17]));
DLY4X1 RDL018 (.A(RecDelay0[17]), .Y(RecDelay0[18]));
DLY4X1 RDL019 (.A(RecDelay0[18]), .Y(RecDelay0[19]));
DLY4X1 RDL020 (.A(RecDelay0[19]), .Y(RecDelay0[20]));
DLY4X1 RDL021 (.A(RecDelay0[20]), .Y(RecDelay0[21]));
DLY4X1 RDL022 (.A(RecDelay0[21]), .Y(RecDelay0[22]));
DLY4X1 RDL023 (.A(RecDelay0[22]), .Y(RecDelay0[23]));
DLY4X1 RDL024 (.A(RecDelay0[23]), .Y(RecDelay0[24]));
DLY4X1 RDL025 (.A(RecDelay0[24]), .Y(RecDelay0[25]));
DLY4X1 RDL026 (.A(RecDelay0[25]), .Y(RecDelay0[26]));
DLY4X1 RDL027 (.A(RecDelay0[26]), .Y(RecDelay0[27]));
// ReceiveClk[0]
DFFRHQX1 RB1 (.D(hi), .CK(RecDelay0[27]), .Q(ReceiveClk[0]), .RN(RecDelayInv4Reset));
DLY4X1 RDL10 (.A(ReceiveClk[0]), .Y(RecDelay1[0]));
DLY4X1 RDL11 (.A(RecDelay1[0]), .Y(RecDelay1[1]));
DLY4X1 RDL12 (.A(RecDelay1[1]), .Y(RecDelay1[2]));
DLY4X1 RDL13 (.A(RecDelay1[2]), .Y(RecDelay1[3]));
DLY4X1 RDL14 (.A(RecDelay1[3]), .Y(RecDelay1[4]));
DLY4X1 RDL15 (.A(RecDelay1[4]), .Y(RecDelay1[5]));
DLY4X1 RDL16 (.A(RecDelay1[5]), .Y(RecDelay1[6]));
DLY4X1 RDL17 (.A(RecDelay1[6]), .Y(RecDelay1[7]));
DLY4X1 RDL18 (.A(RecDelay1[7]), .Y(RecDelay1[8]));
DLY4X1 RDL19 (.A(RecDelay1[8]), .Y(RecDelay1[9]));
DLY4X1 RDL110 (.A(RecDelay1[9]), .Y(RecDelay1[10]));
DLY4X1 RDL111 (.A(RecDelay1[10]), .Y(RecDelay1[11]));
DLY4X1 RDL112 (.A(RecDelay1[11]), .Y(RecDelay1[12]));
DLY4X1 RDL113 (.A(RecDelay1[12]), .Y(RecDelay1[13]));
DLY4X1 RDL114 (.A(RecDelay1[13]), .Y(RecDelay1[14]));
DLY4X1 RDL115 (.A(RecDelay1[14]), .Y(RecDelay1[15]));
DLY4X1 RDL116 (.A(RecDelay1[15]), .Y(RecDelay1[16]));
DLY4X1 RDL117 (.A(RecDelay1[16]), .Y(RecDelay1[17]));
DLY4X1 RDL118 (.A(RecDelay1[17]), .Y(RecDelay1[18]));
DLY4X1 RDL119 (.A(RecDelay1[18]), .Y(RecDelay1[19]));
// ReceiveClk[1]
DFFRHQX1 RB2 (.D(hi), .CK(RecDelay1[19]), .Q(ReceiveClk[1]), .RN(RecDelayInv4Reset));
DLY4X1 RDL20 (.A(ReceiveClk[1]), .Y(RecDelay2[0]));
DLY4X1 RDL21 (.A(RecDelay2[0]), .Y(RecDelay2[1]));
DLY4X1 RDL22 (.A(RecDelay2[1]), .Y(RecDelay2[2]));
DLY4X1 RDL23 (.A(RecDelay2[2]), .Y(RecDelay2[3]));
DLY4X1 RDL24 (.A(RecDelay2[3]), .Y(RecDelay2[4]));
DLY4X1 RDL25 (.A(RecDelay2[4]), .Y(RecDelay2[5]));
DLY4X1 RDL26 (.A(RecDelay2[5]), .Y(RecDelay2[6]));
DLY4X1 RDL27 (.A(RecDelay2[6]), .Y(RecDelay2[7]));
DLY4X1 RDL28 (.A(RecDelay2[7]), .Y(RecDelay2[8]));
DLY4X1 RDL29 (.A(RecDelay2[8]), .Y(RecDelay2[9]));
DLY4X1 RDL210 (.A(RecDelay2[9]), .Y(RecDelay2[10]));
DLY4X1 RDL211 (.A(RecDelay2[10]), .Y(RecDelay2[11]));
DLY4X1 RDL212 (.A(RecDelay2[11]), .Y(RecDelay2[12]));
DLY4X1 RDL213 (.A(RecDelay2[12]), .Y(RecDelay2[13]));
DLY4X1 RDL214 (.A(RecDelay2[13]), .Y(RecDelay2[14]));
DLY4X1 RDL215 (.A(RecDelay2[14]), .Y(RecDelay2[15]));
DLY4X1 RDL216 (.A(RecDelay2[15]), .Y(RecDelay2[16]));
DLY4X1 RDL217 (.A(RecDelay2[16]), .Y(RecDelay2[17]));
DLY4X1 RDL218 (.A(RecDelay2[17]), .Y(RecDelay2[18]));
DLY4X1 RDL219 (.A(RecDelay2[18]), .Y(RecDelay2[19]));
APPENDIX B: GATE-LEVEL NETLIST FOR COMMUNICATION BLOCK 133
// ReceiveClk[2]
DFFRHQX1 RB3 (.D(hi), .CK(RecDelay2[19]), .Q(ReceiveClk[2]), .RN(RecDelayInv4Reset));
DLY4X1 RDL30 (.A(ReceiveClk[2]), .Y(RecDelay3[0]));
DLY4X1 RDL31 (.A(RecDelay3[0]), .Y(RecDelay3[1]));
DLY4X1 RDL32 (.A(RecDelay3[1]), .Y(RecDelay3[2]));
DLY4X1 RDL33 (.A(RecDelay3[2]), .Y(RecDelay3[3]));
DLY4X1 RDL34 (.A(RecDelay3[3]), .Y(RecDelay3[4]));
DLY4X1 RDL35 (.A(RecDelay3[4]), .Y(RecDelay3[5]));
DLY4X1 RDL36 (.A(RecDelay3[5]), .Y(RecDelay3[6]));
DLY4X1 RDL37 (.A(RecDelay3[6]), .Y(RecDelay3[7]));
DLY4X1 RDL38 (.A(RecDelay3[7]), .Y(RecDelay3[8]));
DLY4X1 RDL39 (.A(RecDelay3[8]), .Y(RecDelay3[9]));
DLY4X1 RDL310 (.A(RecDelay3[9]), .Y(RecDelay3[10]));
DLY4X1 RDL311 (.A(RecDelay3[10]), .Y(RecDelay3[11]));
DLY4X1 RDL312 (.A(RecDelay3[11]), .Y(RecDelay3[12]));
DLY4X1 RDL313 (.A(RecDelay3[12]), .Y(RecDelay3[13]));
DLY4X1 RDL314 (.A(RecDelay3[13]), .Y(RecDelay3[14]));
DLY4X1 RDL315 (.A(RecDelay3[14]), .Y(RecDelay3[15]));
DLY4X1 RDL316 (.A(RecDelay3[15]), .Y(RecDelay3[16]));
DLY4X1 RDL317 (.A(RecDelay3[16]), .Y(RecDelay3[17]));
DLY4X1 RDL318 (.A(RecDelay3[17]), .Y(RecDelay3[18]));
DLY4X1 RDL319 (.A(RecDelay3[18]), .Y(RecDelay3[19]));
// ReceiveClk[3]
DFFRHQX1 RB4 (.D(hi), .CK(RecDelay3[19]), .Q(ReceiveClk[3]), .RN(RecDelayInv4Reset));
DLY4X1 RDL40 (.A(ReceiveClk[3]), .Y(RecDelay4[0]));
DLY4X1 RDL41 (.A(RecDelay4[0]), .Y(RecDelay4[1]));
DLY4X1 RDL42 (.A(RecDelay4[1]), .Y(RecDelay4[2]));
DLY4X1 RDL43 (.A(RecDelay4[2]), .Y(RecDelay4[3]));
DLY4X1 RDL44 (.A(RecDelay4[3]), .Y(RecDelay4[4]));
DLY4X1 RDL45 (.A(RecDelay4[4]), .Y(RecDelay4[5]));
DLY4X1 RDL46 (.A(RecDelay4[5]), .Y(RecDelay4[6]));
DLY4X1 RDL47 (.A(RecDelay4[6]), .Y(RecDelay4[7]));
DLY4X1 RDL48 (.A(RecDelay4[7]), .Y(RecDelay4[8]));
DLY4X1 RDL49 (.A(RecDelay4[8]), .Y(RecDelay4[9]));
DLY4X1 RDL410 (.A(RecDelay4[9]), .Y(RecDelay4[10]));
DLY4X1 RDL411 (.A(RecDelay4[10]), .Y(RecDelay4[11]));
DLY4X1 RDL412 (.A(RecDelay4[11]), .Y(RecDelay4[12]));
DLY4X1 RDL413 (.A(RecDelay4[12]), .Y(RecDelay4[13]));
DLY4X1 RDL414 (.A(RecDelay4[13]), .Y(RecDelay4[14]));
DLY4X1 RDL415 (.A(RecDelay4[14]), .Y(RecDelay4[15]));
DLY4X1 RDL416 (.A(RecDelay4[15]), .Y(RecDelay4[16]));
DLY4X1 RDL417 (.A(RecDelay4[16]), .Y(RecDelay4[17]));
DLY4X1 RDL418 (.A(RecDelay4[17]), .Y(RecDelay4[18]));
DLY4X1 RDL419 (.A(RecDelay4[18]), .Y(RecDelay4[19]));
INVX1 RINV4 (.A(RecDelay4[19]), .Y(RecDelayInv4));
AND2X1 RAND4 (.A(Reset), .B(RecDelayInv4), .Y(RecDelayInv4Reset));
DLY4X1 RDL40b (.A(RecDelay4[19]), .Y(RecDelay4[20]));
DLY4X1 RDL41b (.A(RecDelay4[20]), .Y(RecDelay4[21]));
DLY4X1 RDL42b (.A(RecDelay4[21]), .Y(RecDelay4[22]));
DLY4X1 RDL43b (.A(RecDelay4[22]), .Y(RecDelay4[23]));
DLY4X1 RDL44b (.A(RecDelay4[23]), .Y(RecDelay4[24]));
DLY4X1 RDL45b (.A(RecDelay4[24]), .Y(RecDelay4[25]));
DLY4X1 RDL46b (.A(RecDelay4[25]), .Y(RecDelay4[26]));
DLY4X1 RDL47b (.A(RecDelay4[26]), .Y(RecDelay4[27]));
DLY4X1 RDL48b (.A(RecDelay4[27]), .Y(RecDelay4[28]));
DLY4X1 RDL49b (.A(RecDelay4[28]), .Y(RecDelay4[29]));
// ReceiveEnd
INVX1 RINV5 (.A(ReceiveClkWait), .Y(ReceiveClkWaitNot));
AND2X1 REAND (.A(Reset), .B(ReceiveClkWaitNot), .Y(ReceiveClkWaitNotReset));
DFFRHQX1 FIN (.D(hi), .CK(RecDelay4[29]), .RN(ReceiveClkWaitNotReset),
.Q(ReceiveEnd));
///////////////////////////
// Initial phase detector
///////////////////////////
DLY4X1 IPD0 (.A(comm_in_buffered), .Y(comm_in_delayed[0]));
DLY4X1 IPD1 (.A(comm_in_delayed[0]), .Y(comm_in_delayed[1]));
DLY4X1 IPD2 (.A(comm_in_delayed[1]), .Y(comm_in_delayed[2]));
APPENDIX B: GATE-LEVEL NETLIST FOR COMMUNICATION BLOCK 134
DLY4X1 IPD3 (.A(comm_in_delayed[2]), .Y(comm_in_delayed[3]));
DLY4X1 IPD4 (.A(comm_in_delayed[3]), .Y(comm_in_delayed[4]));
INVX1 IPDINV (.A(comm_in_delayed[4]), .Y(comm_in_delayed_n));
DFFHQX2 IPDDFF (.D(comm_in_delayed_n), .CK(Reset), .Q(IsInitialPhase));
///////////////////////////
// Clock divider
///////////////////////////
DFFRX1 ClkReg_reg (.D(CDCount[7]), .CK(clk_256), .RN(Reset), .Q(Clk));
DFFRX1 clk_128_reg_reg (.D(CDCount[0]), .CK(clk_256), .RN(Reset), .Q(clk_128));
ADDHXL \Aadd_22/U1_1_1 (.A(CDCount[1]), .B(CDCount[0]), .S(N2),
.CO(add_22100_carry_2));
ADDHXL \Aadd_22/U1_1_5 (.A(CDCount[5]), .B(add_22100_carry_5), .S(AN6),
.CO(add_22100_carry_6));
ADDHXL \Aadd_22/U1_1_4 (.A(CDCount[4]), .B(add_22100_carry_4), .S(AN5),
.CO(add_22100_carry_5));
ADDHXL \Aadd_22/U1_1_3 (.A(CDCount[3]), .B(add_22100_carry_3), .S(AN4),
.CO(add_22100_carry_4));
ADDHXL \Aadd_22/U1_1_2 (.A(CDCount[2]), .B(add_22100_carry_2), .S(AN3),
.CO(add_22100_carry_3));
ADDHXL \Aadd_22/U1_1_6 (.A(CDCount[6]), .B(add_22100_carry_6), .S(AN7),
.CO(add_22100_carry_7));
XOR2X1 U3A (.A(add_22100_carry_7), .B(CDCount[7]), .Y(AN8));
DFFRX1 \CDCount_reg[0] (.D(n1), .CK(clk_256), .RN(Reset), .Q(CDCount[0]), .QN(n1));
DFFRX1 \CDCount_reg[2] (.D(AN3), .CK(clk_256), .RN(Reset), .Q(CDCount[2]));
DFFRX1 \CDCount_reg[1] (.D(N2), .CK(clk_256), .RN(Reset), .Q(CDCount[1]));
DFFRX1 \CDCount_reg[6] (.D(AN7), .CK(clk_256), .RN(Reset), .Q(CDCount[6]));
DFFRX1 \CDCount_reg[5] (.D(AN6), .CK(clk_256), .RN(Reset), .Q(CDCount[5]));
DFFRX1 \CDCount_reg[4] (.D(AN5), .CK(clk_256), .RN(Reset), .Q(CDCount[4]));
DFFRX1 \CDCount_reg[3] (.D(AN4), .CK(clk_256), .RN(Reset), .Q(CDCount[3]));
DFFRX1 \CDCount_reg[7] (.D(AN8), .CK(clk_256), .RN(Reset), .Q(CDCount[7]));
CLKBUFX12 CB_a (.A(Clk), .Y(Clk_out));
CLKBUFX12 CB_b (.A(clk_128), .Y(clk_128_out));
endmodule
APPENDIX C: PCB BOARD AND SCHEMATICS 135
Appendix C: PCB Board and Schematics
The printed-circuit board (PCB) design below was fabricated to test the fabricated chip. The
main board includes hardware for interfacing an FPGA development board with the system
for debugging purposes, as well as other necessary hardware including linear regulators and
power connectors. Also included is 4 sockets for connecting modules. Each module consists
of a plug-and-play digital controller chip and a power stage. The PCB layouts and
schematics are shown in the figures below for the main board and the module board.
Figure C. 1: Layout for the main board
2
2
2
2
2
2
1
2
1
2
1
2
1
2
1
2
1
2
1
2 1
2 1
2 1
2 1
1 2 3 4 5 6 7 8
16 15 14 13 12 11 10 9
1 2 3
4
1 2 3
4
1 2 3
4
15 16 17 18 19 20 21 22 23 24 25 26 27 28
14 13 12 11 10 9 8 7 6 5 4 3 2 1
1 2
2 1
1 2
2
1
1 2
3
2 1
3
1
4
2
4 3
2 1
4 3
2 1
1 2
3 4
4 3
2 1
1 2
3 4
5
6
7
8
4
3
2
1
5
6
7
8
4
3
2
1
40 39
38
36
34
32
28
26
24
22
20
18
16
27
25
23
21
19
17
15
13
9
7
5
3
1
10
11 12
14
29 30
31
33
35
37
2
4
6
8
30
15
13
9
7
5
3
34
40
38
36
32
28
26
24
22
20
18
16
14
10
8
11 12
29
1 2
4
6
17
19
21
23
25
27
31
33
35
37
39
1 2
3 4
5 6
7 8
9 10
11 12
13 14
15 16
17 18
19 20
21 22
23 24
25 26
27 28
29 30
31 32
33 34
35 36
37 38
39 40
1 2
3 4
5 6
7 8
9 10
11 12
13 14
15 16
17 18
19 20
21 22
23 24
25 26
27 28
29 30
31 32
33 34
35 36
37 38
39 40
1 2
3 4
5 6
7 8
9 10
11 12
13 14
15 16
17 18
19 20
21 22
23 24
25 26
27 28
29 30
31 32
33 34
35 36
37 38
39 40
1 2
3 4
5 6
7 8
9 10
11 12
13 14
15 16
17 18
19 20
21 22
23 24
25 26
27 28
29 30
31 32
33 34
35 36
37 38
39 40
2 1 2 1 2 1 2 1
2 1
1
2
2 1
2 1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
5
6
7
8
4
3
2
1
1
2
3
1
2
3
1
2
3
2
1 1
2
2
1 2
1
1
2
2
1
2
1
2 1
2
1
2
1
2
1
1 2
2
1
2
1
2
1
1 2
2
1 1 2 3
4 5
1 2 3 4 5 6 7 8
16 15 14 13 12 11 10 9 1 2 3 4 5 6 7 8
16 15 14 13 12 11 10 9
APPENDIX C: PCB BOARD AND SCHEMATICS 136
Figure C. 2: Top-level schematic for the main board
Figure C. 3: Schematic for output voltage capacitors and connectors
+1
--2
J1
CONN
+9V
1
H1
GND
+1
--2
J3
CONN
GND
VIN
+1
--2
J4
CONN
GND
VIN
+1
--2
J2
CONN
GND
VDRIVE
1
2
3
4
5
6
7
8
9
1
0
1
1
1
2
1
3
1
4
1
5
1
6
1
7
1
8
1
9
2
0
2
1
2
2
2
3
2
4
2
5
2
6
2
7
2
8
2
9
3
0
3
1
3
2
3
3
3
4
3
5
3
6
3
7
3
8
3
9
4
0
JP5
Header 20X2
VCC5_JP5 VCC33_JP5
GND GND
1
2
3
4
5
6
7
8
9
1
0
1
1
1
2
1
3
1
4
1
5
1
6
1
7
1
8
1
9
2
0
2
1
2
2
2
3
2
4
2
5
2
6
2
7
2
8
2
9
3
0
3
1
3
2
3
3
3
4
3
5
3
6
3
7
3
8
3
9
4
0
JP6
Header 20X2
VCC5_JP6 VCC33_JP6
GND GND
VIN
VDRIVE
VOUT
VIN
VDRIVE
VOUT
GND GND
GND GND
1 2
3 4
5 6
7 8
9 10
11 12
13 14
15 16
17 18
19 20
21 22
23 24
25 26
27 28
29 30
31 32
33 34
35 36
37 38
39 40
JP1
Header 20X2
LOADSTEP2
LOADSTEP1
+1
--2
J5
CONN
GND
VBANDGAP
U_PowerBlock
PowerBlock.SchDoc
U_PowerOutput
PowerOutput.SchDoc
Data_bus_3 Data_bus_2
Data_bus_1 Data_bus_0
Data_bus_4 Data_bus_5
Data_bus_6 Data_bus_7
Reset Prog_select
comm_out_0 comm_out_3
DebugRail_0_0
DebugRail_1_0
DebugRail_2_0
DebugRail_3_0 Prog_clk_0
MS0_EXT
SR0_EXT
+1.8V
+3.3V +3.3V
+1.8V
VBANDGAP
VIN
VDRIVE
VOUT
VIN
VDRIVE
VOUT
GND GND
GND GND
1 2
3 4
5 6
7 8
9 10
11 12
13 14
15 16
17 18
19 20
21 22
23 24
25 26
27 28
29 30
31 32
33 34
35 36
37 38
39 40
JP2
Header 20X2
Data_bus_3 Data_bus_2
Data_bus_1 Data_bus_0
Data_bus_4 Data_bus_5
Data_bus_6 Data_bus_7
Reset Prog_select
comm_out_1 comm_out_0
DebugRail_0_1
DebugRail_1_1
DebugRail_2_1
DebugRail_3_1 Prog_clk_1
MS1_EXT
SR1_EXT
+1.8V
+3.3V +3.3V
+1.8V
VBANDGAP
VIN
VDRIVE
VOUT
VIN
VDRIVE
VOUT
GND GND
GND GND
1 2
3 4
5 6
7 8
9 10
11 12
13 14
15 16
17 18
19 20
21 22
23 24
25 26
27 28
29 30
31 32
33 34
35 36
37 38
39 40
JP3
Header 20X2
Data_bus_3 Data_bus_2
Data_bus_1 Data_bus_0
Data_bus_4 Data_bus_5
Data_bus_6 Data_bus_7
Reset Prog_select
comm_out_2 comm_out_1
DebugRail_0_2
DebugRail_1_2
DebugRail_2_2
DebugRail_3_2 Prog_clk_2
MS2_EXT
SR2_EXT
+1.8V
+3.3V +3.3V
+1.8V
VBANDGAP
VIN
VDRIVE
VOUT
VIN
VDRIVE
VOUT
GND GND
GND GND
1 2
3 4
5 6
7 8
9 10
11 12
13 14
15 16
17 18
19 20
21 22
23 24
25 26
27 28
29 30
31 32
33 34
35 36
37 38
39 40
JP4
Header 20X2
Data_bus_3 Data_bus_2
Data_bus_1 Data_bus_0
Data_bus_4 Data_bus_5
Data_bus_6 Data_bus_7
Reset Prog_select
comm_out_3 comm_out_2
DebugRail_0_3
DebugRail_1_3
DebugRail_2_3
DebugRail_3_3 Prog_clk_3
MS3_EXT
SR3_EXT
+1.8V
+3.3V +3.3V
+1.8V
VBANDGAP
1 2
3 4
P1
Header 2X2
1 2
3 4
P2
Header 2X2
1 2
3 4
P3
Header 2X2
1 2
3 4
P4
Header 2X2
comm_out_3 comm_out_0 comm_out_0 comm_out_1 comm_out_1 comm_out_2
comm_out_2
comm_out_3
A
u
x
R
e
s
e
t_
fp
g
a
A
u
x
R
e
s
e
tE
n
a
b
le
_
fp
g
a
R
e
s
e
t_
fp
g
a
D
a
ta
_
b
u
s
_
0
_
fp
g
a
D
a
ta
_
b
u
s
_
1
_
fp
g
a
D
a
ta
_
b
u
s
_
4
_
fp
g
a
D
a
ta
_
b
u
s
_
3
_
fp
g
a
D
a
ta
_
b
u
s
_
2
_
fp
g
a
D
a
ta
_
b
u
s
_
5
_
fp
g
a
D
a
ta
_
b
u
s
_
6
_
fp
g
a
D
a
ta
_
b
u
s
_
7
_
fp
g
a
P
ro
g
_
s
e
le
c
t_
fp
g
a
S
R
0
_
E
X
T
M
S
0
_
E
X
T
S
R
1
_
E
X
T
M
S
1
_
E
X
T
S
R
2
_
E
X
T
M
S
2
_
E
X
T
D
e
b
u
g
R
a
il_
3
_
2
_
fp
g
a
D
e
b
u
g
R
a
il_
2
_
2
_
fp
g
a
D
e
b
u
g
R
a
il_
1
_
2
_
fp
g
a
D
e
b
u
g
R
a
il_
0
_
2
_
fp
g
a
D
e
b
u
g
R
a
il_
3
_
1
_
fp
g
a
D
e
b
u
g
R
a
il_
2
_
1
_
fp
g
a
D
e
b
u
g
R
a
il_
1
_
1
_
fp
g
a
D
e
b
u
g
R
a
il_
0
_
1
_
fp
g
a
D
e
b
u
g
R
a
il_
3
_
0
_
fp
g
a
D
e
b
u
g
R
a
il_
2
_
0
_
fp
g
a
D
e
b
u
g
R
a
il_
1
_
0
_
fp
g
a
D
e
b
u
g
R
a
il_
0
_
0
_
fp
g
a
P
ro
g
_
c
lk
_
3
_
fp
g
a
P
ro
g
_
c
lk
_
2
_
fp
g
a
P
ro
g
_
c
lk
_
1
_
fp
g
a
P
ro
g
_
c
lk
_
0
_
fp
g
a
M
S
3
_
E
X
T
S
R
3
_
E
X
T
D
e
b
u
g
R
a
il_
0
_
3
_
fp
g
a
D
e
b
u
g
R
a
il_
1
_
3
_
fp
g
a
D
e
b
u
g
R
a
il_
2
_
3
_
fp
g
a
D
e
b
u
g
R
a
il_
3
_
3
_
fp
g
a
AuxReset_fpga
AuxResetEnable_fpga
Reset_fpga
Data_bus_0_fpga
Data_bus_1_fpga
Data_bus_2_fpga
Data_bus_3_fpga
Data_bus_4_fpga
Data_bus_5_fpga
Data_bus_6_fpga
Data_bus_7_fpga
DebugRail_0_0_fpga
DebugRail_1_0_fpga
DebugRail_2_0_fpga
DebugRail_3_0_fpga
DebugRail_0_1_fpga
DebugRail_1_1_fpga
DebugRail_2_1_fpga
DebugRail_3_1_fpga
DebugRail_0_2_fpga
DebugRail_1_2_fpga
DebugRail_2_2_fpga
DebugRail_3_2_fpga
DebugRail_0_3_fpga
DebugRail_1_3_fpga
DebugRail_2_3_fpga
DebugRail_3_3_fpga
Prog_select_fpga
Prog_clk_0_fpga
Prog_clk_1_fpga
Prog_clk_2_fpga
Prog_clk_3_fpga
AuxReset
Reset
Data_bus_0
Data_bus_1
Data_bus_2
Data_bus_3
Data_bus_4
Data_bus_5
Data_bus_6
Data_bus_7
DebugRail_0_0
DebugRail_1_0
DebugRail_2_0
DebugRail_3_0
DebugRail_0_1
DebugRail_1_1
DebugRail_2_1
DebugRail_3_1
DebugRail_0_2
DebugRail_1_2
DebugRail_2_2
DebugRail_3_2
DebugRail_0_3
DebugRail_1_3
DebugRail_2_3
DebugRail_3_3
Prog_select
Prog_clk_0
Prog_clk_1
Prog_clk_2
Prog_clk_3
U_LevelShift
LevelShift.SchDoc
AuxReset_fpga
AuxResetEnable_fpga
Reset_fpga
Data_bus_0_fpga
Data_bus_1_fpga
Data_bus_2_fpga
Data_bus_3_fpga
Data_bus_4_fpga
Data_bus_5_fpga
Data_bus_6_fpga
Data_bus_7_fpga
Prog_select_fpga
Prog_clk_0_fpga
Prog_clk_1_fpga
Prog_clk_2_fpga
Prog_clk_3_fpga
DebugRail_0_0
DebugRail_1_0
DebugRail_2_0
DebugRail_3_0
DebugRail_0_1
DebugRail_1_1
DebugRail_2_1
DebugRail_3_1
DebugRail_0_2
DebugRail_1_2
DebugRail_2_2
DebugRail_3_2
DebugRail_0_3
DebugRail_1_3
DebugRail_2_3
DebugRail_3_3
Prog_clk_3
Prog_clk_2
Prog_clk_1
Prog_clk_0
Prog_select
Data_bus_7
Data_bus_6
Data_bus_4
Data_bus_5
Data_bus_3
Data_bus_2
Data_bus_1
Data_bus_0
Reset
AuxReset
DebugRail_3_3_fpga
DebugRail_2_3_fpga
DebugRail_1_3_fpga
DebugRail_0_3_fpga
DebugRail_3_2_fpga
DebugRail_1_2_fpga
DebugRail_2_2_fpga
DebugRail_0_2_fpga
DebugRail_3_1_fpga
DebugRail_2_1_fpga
DebugRail_1_1_fpga
DebugRail_3_0_fpga
DebugRail_0_1_fpga
DebugRail_2_0_fpga
DebugRail_1_0_fpga
DebugRail_0_0_fpga
1
H2
1
H3
1
H4
1
H5
L
O
A
D
S
T
E
P
2
L
O
A
D
S
T
E
P
1
AuxReset
ADC_B07
ADC_B08
ADC_B09
ADC_B10
ADC_B11
ADC_B12
ADC_B01
ADC_B02
ADC_B03
ADC_B04
ADC_B05
ADC_B06
ADC_CLK
U_ADC
ADC.SchDoc
ADC_CLK ADC_B01
ADC_B02
ADC_B03
ADC_B04
ADC_B05
ADC_B06
ADC_B07
ADC_B08
ADC_B09
ADC_B10
ADC_B11
ADC_B12
A
D
C
_
C
L
K
A
D
C
_
B
0
1
A
D
C
_
B
0
2
A
D
C
_
B
0
3
A
D
C
_
B
0
4
A
D
C
_
B
0
5
A
D
C
_
B
0
6
A
D
C
_
B
0
7
A
D
C
_
B
0
8
A
D
C
_
B
0
9
A
D
C
_
B
1
0
A
D
C
_
B
1
1
A
D
C
_
B
1
2
LOADSTEP2
LOADSTEP1
U_LoadStep
LoadStep.SchDoc
1
H6
1
H7
1
H8
GND
1
H4o
+1
--2
J1o
CONN
GND
1
H2o
C2o
Cap Semi
C3o
Cap Semi
C4o
Cap Semi
C5o
Cap Semi
C6o
Cap Semi
C1o
Cap Semi
1
H3o
VOUT
1
H1o
1
H5o
1
H6o
APPENDIX C: PCB BOARD AND SCHEMATICS 137
Figure C. 4: Schematic for linear regulators
Figure C. 5: Schematic for load-step circuit
+9V
GND
+1.8V
C1p
Cap Semi
GND
C2p
Cap Semi
GND
R1p
Res3
GND
+9V
GND GND
+3.3V
C3p
Cap Semi
GND
C4p
Cap Semi
GND
R2p
Res3
D2
SUPER REDLED
GND
Output
3
Vin
1
G
N
D
2
G
N
D
4
U2p uA78M15
1
H1p
1
H2p
D1
SUPER REDLED
+9V
GND GND
+5.0V
C5p
Cap Semi
GND
C6p
Cap Semi
GND
R3p
Res3
D3
SUPER REDLED
GND
Output
3
Vin
1
G
N
D
2
G
N
D
4
U3p uA78M15
1
H3p
Output
3
Vin
1
G
N
D
2
G
N
D
4
U1p uA78M15
GND
D4
5
D3
6
D2
7
D1
8
G1
4
S3
3
S2
2
S1
1
M2
IRF7832
D4
5
D3
6
D2
7
D1
8
G1
4
S3
3
S2
2
S1
1
M1
IRF7832
OUTB
5
VDD
6
OUTA
7
NC2
8
INB
4
GND
3
INA
2
NC1
1
DRV1
VDRIVE
GND
GND
1
H1L
1
H2L
1
H3L
C1L
Cap Semi
1 2
3 4
P2L
Header 2X2
GND
GND
+1
--2
J2L
CONN
+1
--2
J1L
CONN
1 2
3 4
P1L
Header 2X2
LOADSTEP2
LOADSTEP1
1
H4L
VOUT
APPENDIX C: PCB BOARD AND SCHEMATICS 138
Figure C. 6: Schematic for level-shifting for communication between the ICs and the FPGA
Figure C. 7: Layout of the plug-in module
AuxReset_fpga
AuxResetEnable_fpga
Reset_fpga
Data_bus_0_fpga
Data_bus_1_fpga
Data_bus_2_fpga
Data_bus_3_fpga
Data_bus_4_fpga
Data_bus_5_fpga
Data_bus_6_fpga
Data_bus_7_fpga
DebugRail_0_0_fpga
DebugRail_1_0_fpga
DebugRail_2_0_fpga
DebugRail_3_0_fpga
DebugRail_0_1_fpga
DebugRail_1_1_fpga
DebugRail_2_1_fpga
DebugRail_3_1_fpga
DebugRail_0_2_fpga
DebugRail_1_2_fpga
DebugRail_2_2_fpga
DebugRail_3_2_fpga
DebugRail_0_3_fpga
DebugRail_1_3_fpga
DebugRail_2_3_fpga
DebugRail_3_3_fpga
Prog_select_fpga
Prog_clk_0_fpga
Prog_clk_1_fpga
Prog_clk_2_fpga
Prog_clk_3_fpga
AuxReset
Reset
Data_bus_0
Data_bus_1
Data_bus_2
Data_bus_3
Data_bus_4
Data_bus_5
Data_bus_6
Data_bus_7
DebugRail_0_0
DebugRail_1_0
DebugRail_2_0
DebugRail_3_0
DebugRail_0_1
DebugRail_1_1
DebugRail_2_1
DebugRail_3_1
DebugRail_0_2
DebugRail_1_2
DebugRail_2_2
DebugRail_3_2
DebugRail_0_3
DebugRail_1_3
DebugRail_2_3
DebugRail_3_3
Prog_select
Prog_clk_0
Prog_clk_1
Prog_clk_2
Prog_clk_3
VCC
1
A_EN
2
A
3
E
4
F
5
B
6
G
11
NC
12
H
13
D
14
D_EN
15
VDD
16
B_EN
7
VSS
8
C
10
C_EN
9
B3s
HCF40109 Quad Low-to-High Voltage Level Shifter
+3.3V
GND
AuxReset_fpga
AuxReset
AuxResetEnable_fpga
AuxReset_fpga
AuxResetEnable_fpga
Reset_fpga
Data_bus_0_fpga
Data_bus_1_fpga
Data_bus_2_fpga
Data_bus_3_fpga
Data_bus_4_fpga
Data_bus_5_fpga
Data_bus_6_fpga
Data_bus_7_fpga
Prog_select_fpga
Prog_clk_0_fpga
Prog_clk_1_fpga
Prog_clk_2_fpga
Prog_clk_3_fpga
DebugRail_0_0_fpga
DebugRail_1_0_fpga
DebugRail_2_0_fpga
DebugRail_3_0_fpga
DebugRail_0_1_fpga
DebugRail_1_1_fpga
DebugRail_2_1_fpga
DebugRail_3_1_fpga
DebugRail_0_2_fpga
DebugRail_1_2_fpga
DebugRail_2_2_fpga
DebugRail_3_2_fpga
DebugRail_0_3_fpga
DebugRail_1_3_fpga
DebugRail_2_3_fpga
DebugRail_3_3_fpga
AuxReset
Reset
Data_bus_0
Data_bus_1
Data_bus_2
Data_bus_3
Data_bus_4
Data_bus_5
Data_bus_6
Data_bus_7
Prog_select
Prog_clk_0
Prog_clk_1
Prog_clk_2
Prog_clk_3
DebugRail_0_0
DebugRail_1_0
DebugRail_2_0
DebugRail_3_0
DebugRail_0_1
DebugRail_1_1
DebugRail_2_1
DebugRail_3_1
DebugRail_0_2
DebugRail_1_2
DebugRail_2_2
DebugRail_3_2
DebugRail_0_3
DebugRail_1_3
DebugRail_2_3
DebugRail_3_3
C1s
Cap Semi
C2s
Cap Semi
C3s
Cap Semi
C4s
Cap Semi
GND GND
+1.8V +3.3V
1DIR
1
1B1
2
1B2
3
GND1
4
1B3
5
1B4
6
VCCB1
7
1B5
8
1B6
9
GND2
10
1B7
11
1B8
12
2B1
13
2B2
14
GND3
15
2B3
16
2B4
17
VCCB2
18
2B5
19
2B6
20
GND4
21
2B7
22
2B8
23
2DIR
24
2OE
25
2A8
26
2A7
27
GND8
28
2A6
29
2A5
30
VCCA2
31
2A4
32
2A3
33
GND7
34
2A2
35
2A1
36
1A8
37
1A7
38
GND6
39
1A6
40
1A5
41
VCCA1
42
1A4
43
1A3
44
GND5
45
1A2
46
1A1
47
1OE
48
B1s
SN74AVC16T245
GND
GND
GND
GND
GND
GND GND
GND
GND
GND
Reset_fpga
Data_bus_0_fpga
Data_bus_1_fpga
Data_bus_2_fpga
Data_bus_3_fpga
Data_bus_4_fpga
Data_bus_5_fpga
Data_bus_6_fpga
Data_bus_7_fpga
Prog_select_fpga
Prog_clk_0_fpga
Prog_clk_1_fpga
Prog_clk_2_fpga
Prog_clk_3_fpga
+3.3V
+3.3V +1.8V
+1.8V
Data_bus_4
Data_bus_3
Data_bus_2
Data_bus_1
Data_bus_0
Reset
Data_bus_5
Data_bus_6
Data_bus_7
Prog_select
Prog_clk_0
Prog_clk_1
Prog_clk_2
Prog_clk_3
GND
GND
1DIR
1
1B1
2
1B2
3
GND1
4
1B3
5
1B4
6
VCCB1
7
1B5
8
1B6
9
GND2
10
1B7
11
1B8
12
2B1
13
2B2
14
GND3
15
2B3
16
2B4
17
VCCB2
18
2B5
19
2B6
20
GND4
21
2B7
22
2B8
23
2DIR
24
2OE
25
2A8
26
2A7
27
GND8
28
2A6
29
2A5
30
VCCA2
31
2A4
32
2A3
33
GND7
34
2A2
35
2A1
36
1A8
37
1A7
38
GND6
39
1A6
40
1A5
41
VCCA1
42
1A4
43
1A3
44
GND5
45
1A2
46
1A1
47
1OE
48
B2s
SN74AVC16T245
GND
GND
GND
GND
GND
GND GND
GND
GND
GND
+1.8V
+1.8V
+3.3V
+3.3V
+1.8V
+1.8V
DebugRail_0_0_fpga
DebugRail_1_0_fpga
DebugRail_2_0_fpga
DebugRail_3_0_fpga
DebugRail_0_0
DebugRail_1_0
DebugRail_2_0
DebugRail_3_0
DebugRail_0_1_fpga
DebugRail_1_1_fpga
DebugRail_2_1_fpga
DebugRail_3_1_fpga
DebugRail_0_1
DebugRail_1_1
DebugRail_2_1
DebugRail_3_1
DebugRail_0_2_fpga
DebugRail_1_2_fpga
DebugRail_2_2_fpga
DebugRail_3_2_fpga
DebugRail_0_2
DebugRail_2_2
DebugRail_1_2
DebugRail_3_2
DebugRail_0_3
DebugRail_1_3
DebugRail_2_3
DebugRail_3_3 DebugRail_3_3_fpga
DebugRail_2_3_fpga
DebugRail_1_3_fpga
DebugRail_0_3_fpga
+3.3V
5
6
7
8
4
3
2
1
1 2
1
2
1 2
1 2
1 2
2
1
2
1
4 3
2 1
4 3
2 1
1
2
3
4
8
7
6
5 1 2
1 2
3 4
5 6
7 8
9 10
11 12
13 14
15 16
17 18
19 20
21 22
23 24
25 26
27 28
29 30
31 32
33 34
35 36
37 38
39 40
33 32 31 30 29 28 27 26 25 24 23
22
21
20
19
18
17
16
15
14
13
12
11 10 9 8 7 6 5 4 3 2 1
44
43
42
41
40
39
38
37
36
35
34
1
1 1
1
1
1
1
1
1
2
1
2 2
1 1 2
APPENDIX C: PCB BOARD AND SCHEMATICS 139
Figure C. 8: Schematic for the plug-in module
VIN
VDRIVE
VOUT
VIN
VDRIVE
VOUT
GND GND
GND GND
1 2
3 4
5 6
7 8
9 10
11 12
13 14
15 16
17 18
19 20
21 22
23 24
25 26
27 28
29 30
31 32
33 34
35 36
37 38
39 40
JP1
Header 20X2
Data_bus_3 Data_bus_2
Data_bus_1 Data_bus_0
Data_bus_4 Data_bus_5
Data_bus_6 Data_bus_7
Reset Prog_select
comm_out comm_in
DebugRail_0
DebugRail_1
DebugRail_2
DebugRail_3 Prog_clk
MS0_EXT
SR0_EXT
+1.8V
+3.3V +3.3V
+1.8V
VBANDGAP
OUTB
5
VDD
6
OUTA
7
NC2
8
INB
4
GND
3
INA
2
NC1
1
DRV1
GND GND GND
C4
100uF/6.3V
C5
100uF/6.3V
GND
1
H2
VIN
1
H8
C3
100uF/6.3V
GND
1
H3
1
H6
1
H7
1
H1
1
H5
1
H4
MS1
SR1
LX
S1
1
G1
2
S2
3
G2
4
D
8
D
7
D
6
D
5
M1
IRF7379PbF
LX
C1
10uF/16V
C2
10uF/16V
L1
UP1B-R47-R
D
e
b
u
g
R
a
i
l
_
1
D
e
b
u
g
R
a
i
l
_
2
D
e
b
u
g
R
a
i
l
_
3
R
e
s
e
t
c
o
m
m
_
i
n
c
o
m
m
_
o
u
t
P
r
o
g
_
s
e
l
e
c
t
S
R
0
_
I
N
T
M
S
0
_
I
N
T
DebugRail_0
Data_bus_0
Data_bus_1
Data_bus_2
Data_bus_3
Data_bus_4
Data_bus_5
Data_bus_6
Data_bus_7
Prog_clk
VDRIVE
VOUT
+1.8V
R1
100k
R2
100k
comm_out
1 2
3 4
P1
Header 2X2
SR0_EXT
MS0_EXT
1 2
3 4
P2
Header 2X2
VBANDGAP
GND
GND
GND
VSS_2
34
CLK_PARAM
35
DATA_BUS_7
36
DATA_BUS_6
37
DATA_BUS_5
38
DATA_BUS_4
39
DATA_BUS_3
40
DATA_BUS_2
41
DATA_BUS_1
42
DATA_BUS_0
43
DRAIL_0
44
NC
12
NC
13
NC
14
NC
15
NC
16
NC
17
NC
18
NC
19
NC
20
NC
21
NC
22
D
R
A
I
L
_
1
1
D
R
A
I
L
_
2
2
D
R
A
I
L
_
3
3
V
S
S
_
3
4
V
D
D
1
8
_
I
O
R
I
N
G
5
R
E
S
E
T
6
C
O
M
M
_
I
N
7
C
O
M
M
_
O
U
T
8
P
R
O
G
_
S
E
L
E
C
T
9
N
C
1
0
N
C
1
1
V
D
D
1
8
_
O
S
C
3
3
M
S
3
2
S
R
3
1
V
O
U
T
3
0
V
D
D
3
3
2
9
V
_
B
A
N
D
G
A
P
2
8
V
D
D
1
8
_
A
D
C
2
7
V
S
S
1
2
6
N
C
2
5
N
C
2
4
N
C
2
3 ICFTRFBS
ICFTRFBS
+3.3V +1.8V
+1.8V
+1.8V
VOUT
SR0_INT
MS0_INT
+3.3V +1.8V VBANDGAP
C6
100uF/6.3V
C7
100uF/6.3V
C8
100uF/6.3V
GND GND GND
R3
100k
REFERENCES 140
References
[1] J. B. Wang and S. Chuang, "A study of the interleaved buck derived converters," in
International Conference on Industrial Technology, 2006, pp. 557-562.
[2] Intel Corporation, "Intel Pentium 4 Processor VR-Down Design Guidelines," 2002.
[3] Current Solutions, Inc., APC-D2000 Product Data Sheet, 2004.
[4] Enatel Limited, CM1748/48 Product Data Sheet, 2008.
[5] Robin Kelley, Michael S. Mazzola, and Volodymyr Bondarenko, "A Scalable SiC
Device for DC/DC Converters in Future Hybrid Electric Vehicles," in 21st Annual
Applied Power Electronics Conference, 2006.
[6] L. Palma and P. Enjeti, "A Modular Fuel Cell, Modular DC-DC Converter Concept for
High Performance and Enhanced Reliability," in Power Electronics Specialists
Conference, 2007.
[7] Faisal H. Khan and Leon M. Tolbert, "5 kW Multilevel DC-DC Converter for Hybrid
Electric and Fuel Cell Automotive Applications," in 42nd Industrial Applications
Conference, New Orleans, United States, 2007.
REFERENCES 141
[8] Wenkang Huang, George Schuellein, and Danny Clavette, "A Scalable Multiphase Buck
Converter with Average Current Share Bus," in 18th Annual Applied Power Electronics
Conference, 2003.
[9] Z. Lukic, C. Blake, S. C. Huerta, and A. Prodic, "Universal and Fault-Tolerant
Multiphase Digital PWM Controller IC for High-Frequency DC-DC Converters," in
22nd Annual IEEE Applied Power Electronics Conference, 2007, pp. 42-47.
[10] Z. Lukic, Z. Zhao, A. Prodic, and D. Goder, "Digital Controller for Multi-Phase DC-DC
Converters with Logarithmic Current Sharing," in IEEE Power Electronics Specialists
Conference, 2007, pp. 119-123.
[11] S. Abedinpour, B Bakkaloglu, and S. Kiaei, "A Multistage Interleaved Synchronous
Buck Converter With Integrated Output Filter in 0.18 m SiGe Process," IEEE
Transactions on Power Electronics, Vol. 22, No. 6, pp. 2164-2175, 2007.
[12] Tony Carosa, Regan Zane, and Dragan Maksimovic, "Scalable Digital Multiphase
Modulator," IEEE Transactions on Power Electronics, Vol. 23, No. 4, pp. 2201-2205,
2008.
[13] Andrija Stupar, "Implementation of Fast Transient Response Digital Controllers for
High Frequency Switch-Mode Power Supplies," University of Toronto, M.A.Sc. Thesis
2008.
[14] L. Corradini, P. Mattavelli, W. Stefanutti, and S. Saggini, "Simplified Model Reference-
Based Autotuning for Digitally Controlled SMPS," IEEE Transactions on Power
REFERENCES 142
Electronics, Vol. 23, No. 4, pp. 1956-1963, 2008.
[15] W. Stefanutti, P. Mattavelli, S. Saggini, and M. Ghioni, "Autotuning of Digitally
Controlled DCDC Converters Based on Relay Feedback," IEEE Transactions on
Power Electronics, Vol. 22, No. 1, pp. 199-207, 2007.
[16] W. Stefanutti, S. Saggini, E. Tedeschi, P. Mattavelli, and P. Tenti, "Simplified Model
Reference Tuning of PID Regulators of Digitally Controlled DC-DC Converters Based
on Crossover Frequency Analysis," in Power Electronics Specialists Conference, 2007,
pp. 785-791.
[17] W. Xiao and W. G. Dunford, "Fuzzy logic auto-tuning applied on DC-DC converter,"
30th Annual Conference of the Industrial Electronics Society, pp. 2661-2666, 2004.
[18] Z. Zhao and A. Prodic, "Limit-Cycle Oscillations Based Auto-Tuning System for
Digitally Controlled DC-DC Power Supplies," IEEE Transactions on Power
Electronics, Vol. 24, No. 6, pp. 2211-2222, 2007.
[19] O. Garcia, A. de Castro, P. Zumelis, and J. A. Cobos, "Digital-Control-Based Solution
to the Effect of Nonidealities of the Inductors in Multiphase Converters," IEEE
Transactions on Power Electronics, vol. 22, no. 6, pp. 2155-2163, 2007.
[20] Dallas Semiconductor Corp., "1-Wire Products Mixed-Signal Design Guide," Technical
Report 2005.
[21] C. K. Liu, P. L. Cheng, S. Y. Y. Leung, and D. C. C. Lam, "Inductance Tolerance
Analyses and Design-Process Map of Embedded Planar Spiral Inductor," in 54th
REFERENCES 143
Electronic Components and Technology Conference, 2004, pp. 1108-1112.
[22] Robert W. Erickson and Dragan Maksimovic, Fundamentals of Power Electronics, 2nd
ed.: Springer Science+Business Media Inc., 2001.
[23] NXP Semiconductors, "PIP212-12M Product Data Sheet," Technical Report 2006.
[24] Z. Lukic, N. Rahman, and A. Prodic, "Multibit Sigma-Delta PWM Digital Controller IC
for DCDC Converters Operating at Switching Frequencies Beyond 10 MHz," IEEE
Transactions on Power Electronics, vol. 22, no. 5, pp. 1693-1707, September 2007.
[25] Amir Parayandeh, "Programmable Application Specific ADC for Digitally Controlled
Switch-Mode Power Supplies," University of Toronto, M.A.Sc. Thesis 2006.