Livt packages
Eccelerators.RiscV
Version 0.3.0
Composable RV32I and Zmmul processors, machine-mode support, and reusable FPGA system components written in Livt.
Published files (120)
- IRv32ControlPort.lvt
- IRv32DecodePort.lvt
- IRv32FetchPort.lvt
- IRv32LoadStorePort.lvt
- IRv32MultiplyPort.lvt
- IRv32RegisterPort.lvt
- Rv32DspMultiplier.lvt
- Rv32iConstants.lvt
- Rv32iDecode.lvt
- Rv32iDecoder.lvt
- Rv32iIntegerUnit.lvt
- Rv32iOperations.lvt
- Rv32iSemantics.lvt
- Rv32IterativeMultiplier.lvt
- Rv32iZmmulDecoder.lvt
- Rv32MultiplyOperations.lvt
- Rv32NoMultiplier.lvt
- Rv32SequentialEngine.lvt
src/Sequential/Rv32IterativeMultiplier.lvt
namespace Eccelerators.RiscV.Sequential
/**
* Radix-two 32-bit multiplier with 32 iterations and two high-half correction
* edges. Owns a shared 32-bit add/subtract datapath with explicit carry; no multiply operator or
* scheduled calls. All operations have identical latency. Hardware reset clears
* phase/completion and cancels work; operands are sampled only at acceptance.
*/
component Rv32IterativeMultiplier : IRv32MultiplyPort
{
// Concrete operation coverage for composition checks.
public const CAPABILITIES: uint = Rv32MultiplyOperations.CAPABILITY
// Fixed protocol phases and iteration bound.
const IDLE: uint = 0
const ITERATE: uint = 1
const CORRECT_LEFT: uint = 2
const CORRECT_RIGHT: uint = 3
const COMPLETE: uint = 4
const LAST_BIT: uint = 31
// Owned operand/product state; the low half also holds unprocessed multiplier bits.
phase: logic[3]
bitIndex: logic[5]
multiplicand: logic[32]
originalRight: logic[32]
high: logic[32]
low: logic[32]
selectedOperation: logic[2]
// Combinational arithmetic shared by iterations and signed high-half corrections.
addend: logic[32]
subtract: bool
sum: uint
carryOut: uint
/**
* Selects the adder inputs; subtraction uses complement plus carry-in.
*/
process Calculate[]()
{
addend = 0
subtract = false
if (phase as uint == ITERATE && (low as uint & 1) != 0) {
addend = multiplicand
} elif (phase as uint == CORRECT_LEFT
&& (selectedOperation as uint == Rv32MultiplyOperations.MULH
|| selectedOperation as uint == Rv32MultiplyOperations.MULHSU)
&& (multiplicand as uint >> 31) != 0) {
addend = originalRight
subtract = true
} elif (phase as uint == CORRECT_RIGHT
&& selectedOperation as uint == Rv32MultiplyOperations.MULH
&& (originalRight as uint >> 31) != 0) {
addend = multiplicand
subtract = true
}
var operand = addend as uint
var carry: uint = 0
if (subtract) {
operand = ~(addend as uint)
carry = 1
}
sum = (high as uint) + operand + carry
carryOut = 0
if (sum < high as uint) {
carryOut = 1
}
ready = 0b0
result = high
if (selectedOperation as uint == Rv32MultiplyOperations.MUL) {
result = low
}
if (phase as uint == COMPLETE) {
ready = 0b1
}
}
/**
* Samples one transaction, iterates, corrects and holds completion until release.
*/
process Advance()
{
state {
match (phase as uint)
{
IDLE =>
{
if (request == 0b1) {
multiplicand = left
originalRight = right
low = right
high = 0
selectedOperation = operation
bitIndex = 0
phase = ITERATE as logic[3]
}
}
ITERATE =>
{
low = ((low as uint >> 1) | ((sum as uint & 1) << 31)) as logic[32]
high = ((sum >> 1) | (carryOut << 31)) as logic[32]
if (bitIndex as uint == LAST_BIT) {
phase = CORRECT_LEFT as logic[3]
} else {
bitIndex = (bitIndex as uint + 1) as logic[5]
}
}
CORRECT_LEFT =>
{
high = sum as logic[32]
phase = CORRECT_RIGHT as logic[3]
}
CORRECT_RIGHT =>
{
high = sum as logic[32]
phase = COMPLETE as logic[3]
}
_ =>
{
if (request == 0b0) {
phase = IDLE as logic[3]
}
}
}
}
}
}