1/72
Looks like no tags are added yet.
Name | Mastery | Learn | Test | Matching | Spaced | Call with Kai | Chat |
|---|
No analytics yet
Send a link to your students to track their progress
SequentialMultiplier
The top-level sequential multiplication module that integrates signed-magnitude preparation, the ShiftAddMultiplier datapath, MultiplierLatencyCounter, MultiplierController, and final sign correction.
Sequential Multiplier Integration
The architectural composition of datapath, progress tracking, and control into one coordinated multi-cycle multiplication unit.
MagnitudeA
The WIDTH-bit magnitude representation of operand A supplied to the shift-and-add datapath.
MagnitudeB
The WIDTH-bit magnitude representation of operand B supplied to the shift-and-add datapath.
assign MagnitudeA = (SignedMode && A[WIDTH - 1]) ? (~A + 1'b1) : A;
Converts a negative signed A to its positive magnitude when SignedMode is active; otherwise passes A unchanged.
assign MagnitudeB = (SignedMode && B[WIDTH - 1]) ? (~B + 1'b1) : B;
Converts a negative signed B to its positive magnitude when SignedMode is active; otherwise passes B unchanged.
Because ShiftAddMultiplier performs the iterative multiplication on unsigned magnitudes, while sign handling is performed around the datapath.
Why are A and B converted to MagnitudeA and MagnitudeB before entering ShiftAddMultiplier?
MagnitudeProduct
The unsigned 2×WIDTH-bit magnitude result produced by ShiftAddMultiplier before final sign correction.
reg NegativeProduct;
Stores whether the completed magnitude product must ultimately be converted into a negative two's-complement Product.
NegativeProduct <= SignedMode && (A[WIDTH - 1] ^ B[WIDTH - 1]);
Captures whether exactly one signed operand is negative when a new multiplication operation is loaded.
Because a signed multiplication result is negative exactly when one operand is negative and the other is positive.
Why does NegativeProduct use XOR between the sign bits?
Because the sequential multiplication lasts multiple clock cycles, so the required result sign must remain associated with the operands that were accepted when the operation began.
Why is NegativeProduct stored in a register in SequentialMultiplier instead of being calculated continuously from the current A and B inputs?
load
The controller signal that simultaneously initializes the multiplier datapath, clears the latency counter, and captures NegativeProduct for the new operation.
Because load identifies the moment when the sequential multiplier accepts and initializes the information belonging to the new multiplication operation.
Why is NegativeProduct captured when load is asserted?
if (reset) NegativeProduct <= 1'b0;
Clears the stored result-sign information when the sequential multiplier is reset.
if (load) NegativeProduct <= SignedMode && (A[WIDTH - 1] ^ B[WIDTH - 1]);
Stores the sign relationship of the newly loaded operands.
Because A, B, or SignedMode could change while the multi-cycle multiplication is still running, but the final result must retain the sign belonging to the originally loaded operation.
Why must the sequential multiplier preserve sign information across the operation?
MultiplierController
The control module that converts START and CountDone into load, step, BUSY, and DONE behavior.
ShiftAddMultiplier
The datapath module that performs the actual iterative shift-and-add arithmetic.
MultiplierLatencyCounter
The progress-tracking module that determines when the required number of useful multiplication steps has been processed.
START
External request input consumed by MultiplierController to begin a new multiplication operation.
BUSY
External status output generated by MultiplierController indicating that the sequential multiplier is occupied.
DONE
External status output generated by MultiplierController indicating that the multiplication operation has completed.
CountDone
Internal status signal through which MultiplierLatencyCounter tells MultiplierController that the required iterations have been completed.
step
The controller's request that another multiplication iteration be performed.
EffectiveStep
The internally qualified step signal actually delivered to ShiftAddMultiplier and MultiplierLatencyCounter.
assign EffectiveStep = step & ~CountDone;
Allows an iteration only when the controller requests a step and the latency counter has not already declared completion.
Because the controller may still be in RUN during the cycle in which CountDone becomes asserted, so the raw step signal must be prevented from causing an additional arithmetic iteration.
Why is EffectiveStep used instead of connecting controller step directly to the datapath?
~CountDone
Prevents additional useful steps after the latency counter has declared the multiplication complete.
step & ~CountDone
The condition under which both the multiplier datapath and latency counter are allowed to advance.
Because the datapath and counter must advance on exactly the same useful iterations so their views of algorithmic progress remain synchronized.
Why is the same EffectiveStep signal connected to both ShiftAddMultiplier and MultiplierLatencyCounter?
If the datapath stepped without the counter
The arithmetic could advance without the progress tracker recording the iteration, causing their states to disagree.
If the counter stepped without the datapath
The progress tracker could report iterations that the arithmetic datapath never actually performed.
ShiftAddMultiplier #(.WIDTH(WIDTH)) MultiplierDatapath
Instantiates the parameterized iterative arithmetic datapath inside SequentialMultiplier.
.A(MagnitudeA), .B(MagnitudeB)
Connects the sign-normalized operand magnitudes to the ShiftAddMultiplier datapath.
.step(EffectiveStep)
Ensures the ShiftAddMultiplier performs an iteration only on an allowed useful step.
.Product(MagnitudeProduct)
Connects the unsigned accumulated multiplication result from the datapath to the SequentialMultiplier wrapper.
.MultiplierBit(MultiplierBit)
Exposes the current multiplier LSB from ShiftAddMultiplier to the SequentialMultiplier wrapper.
MultiplierBit
The internal signal carrying the current least significant bit of the working multiplier from ShiftAddMultiplier.
MultiplierLatencyCounter #(.WIDTH(WIDTH)) LatencyCounter
Instantiates the parameterized algorithmic-progress counter inside SequentialMultiplier.
.clear(load)
Uses the controller's load pulse to reset multiplication progress at the beginning of every new operation.
.step(EffectiveStep)
Makes the latency counter advance on the same useful iterations as the shift-and-add datapath.
.CountDone(CountDone)
Returns the multiplication-completion condition from the latency counter to the surrounding integration logic and controller.
Because loading new operands begins a new multiplication and therefore requires the previous operation's iteration count and completion state to be discarded.
Why is load connected to the latency counter's clear input?
MultiplierController MuliplierControl
Instantiates the FSM responsible for sequencing the sequential multiplication operation.
.START(START)
Passes the external multiplication request into MultiplierController.
.CountDone(CountDone)
Provides the controller with the completion feedback required to leave RUN.
.load(load)
Provides the initialization command used by the datapath, latency counter, and NegativeProduct register.
.step(step)
Provides the controller's raw request for repeated multiplication iterations.
.BUSY(BUSY)
Connects the controller's occupied-status indication directly to the SequentialMultiplier output.
.DONE(DONE)
Connects the controller's completion indication directly to the SequentialMultiplier output.
Controller → load → Datapath
Initializes the working multiplicand, multiplier, accumulator, and product for the new operation.
Controller → load → Latency Counter
Clears the previous multiplication's progress information.
Controller → load → NegativeProduct register
Captures the sign information belonging to the new operands.
Controller → step → EffectiveStep → Datapath
Commands useful shift-and-add iterations while multiplication remains incomplete.
Controller → step → EffectiveStep → Latency Counter
Advances algorithmic-progress tracking alongside the datapath.
Latency Counter → CountDone → Controller
Closes the control feedback loop by telling the controller when the required iterations are complete.
START → Controller → load
The beginning of the internal initialization sequence for a requested multiplication.
load → initialize datapath + clear counter + capture sign
The coordinated actions performed when a new multiplication operation is accepted.
RUN → step → EffectiveStep
The path by which the controller repeatedly requests useful multiplication iterations.
EffectiveStep → Datapath + Counter
The synchronization mechanism ensuring arithmetic progress and recorded progress occur together.
CountDone → Controller → DONE_STATE
The completion-feedback path that causes the controller to terminate RUN and announce completion.
assign Product = (NegativeProduct) ? (~MagnitudeProduct + 1'b1) : MagnitudeProduct;
Produces the final externally visible Product by applying the stored sign to the completed magnitude result.
~MagnitudeProduct + 1'b1
Converts the positive magnitude result into its negative two's-complement representation when NegativeProduct is asserted.
Because the iterative datapath is kept focused on magnitude multiplication while signed interpretation is handled by the SequentialMultiplier wrapper.
Why is final sign correction performed outside ShiftAddMultiplier?
Operand interpretation → magnitude preparation → load → repeated shift-and-add steps → completion detection → final sign correction
The complete data/control flow of SequentialMultiplier.
Datapath–Controller Cooperation
The architectural organization in which ShiftAddMultiplier knows how to perform an iteration while MultiplierController determines when iterations occur.
Counter–Controller Cooperation
The feedback organization in which MultiplierController requests progress and MultiplierLatencyCounter reports when enough progress has occurred.
Datapath–Counter Synchronization
The requirement that ShiftAddMultiplier and MultiplierLatencyCounter advance from the same EffectiveStep so arithmetic state and progress state remain aligned.
Wrapper Module
The role of SequentialMultiplier because it connects specialized submodules and handles operand/result interpretation around them.
The SequentialMultiplier is more than a ShiftAddMultiplier.
Is it true that ShiftAddMultiplier alone implements the complete sequential multiplication protocol?
Because ShiftAddMultiplier performs the arithmetic iterations but does not independently handle START/BUSY/DONE sequencing, iteration completion, or persistent signed-result information.
Why is ShiftAddMultiplier insufficient by itself to implement the complete SequentialMultiplier?
State Is the Price of Reuse
The sequential architecture must preserve working arithmetic state, iteration progress, controller state, and result-sign information because multiplication is distributed across time.