DesignWare Floating-Point MAC IP Implementation
This document outlines the successful implementation and verification of a DesignWare Building Block (DWBB) floating-point multiply-accumulate (MAC) IP core. The following sections detail the module implementation, simulation setup, synthesis approach, and troubleshooting steps.
Verilog Module Implementation
The following SystemVerilog module instantiates the DesignWare floating-point MAC IP:
module floating_point_mac(
operand_a,
operand_b,
operand_c,
rounding_mode,
result,
status_flags
);
parameter mantissa_width = 23;
parameter exponent_width = 8;
parameter ieee_compliance = 0;
input [mantissa_width+exponent_width : 0] operand_a;
input [mantissa_width+exponent_width : 0] operand_b;
input [mantissa_width+exponent_width : 0] operand_c;
input [2 : 0] rounding_mode;
output [mantissa_width+exponent_width : 0] result;
output [7 : 0] status_flags;
// Instantiate the DesignWare FP MAC component
DW_fp_mac #(mantissa_width, exponent_width, ieee_compliance) MAC_UNIT (
.a(operand_a),
.b(operand_b),
.c(operand_c),
.rnd(rounding_mode),
.z(result),
.status(status_flags)
);
endmodule
Simulation Configuration
The Makefile for VCS simulation includes the necessary paths for DesignWare libraries:
SYNOPSYS = /opt/synopsys/syn/O-2018.06-SP1
# VCS compilation command
vcs_compile:
cd ../work/vcs && vcs -sverilog -full64 +v2k -debug_pp -timescale=${TIMESCALE} \
-cpp g++ -cc gcc -LDFLAGS -Wl,--no-as-needed -CFLAGS -fPIE -fsdb \
-f ../../prj/filelist.f -o ${OUTPUT} -l compile.log \
-y ${SYNOPSYS}/dw/sim_ver +libext+.v+.inc +incdir+${SYNOPSYS}/dw/sim_ver
Testbench Implementation
A comprehensive testbench was developed to verify the floating-point MAC functionality:
`timescale 1ps/1ps
module fp_mac_testbench;
// Parameters for testbench
parameter mantissa_width = 23;
parameter exponent_width = 8;
parameter ieee_compliance = 0;
// Test signals
logic [mantissa_width+exponent_width : 0] operand_a;
logic [mantissa_width+exponent_width : 0] operand_b;
logic [mantissa_width+exponent_width : 0] operand_c;
logic [2 : 0] rounding_mode;
wire [mantissa_width+exponent_width : 0] result;
wire [7 : 0] status_flags;
// Instantiate the DUT
floating_point_mac DUT (
.operand_a(operand_a),
.operand_b(operand_b),
.operand_c(operand_c),
.rounding_mode(rounding_mode),
.result(result),
.status_flags(status_flags)
);
// Task for waveform dumping
task setup_waveform_dump();
$dumpfile("fp_mac_simulation.vcd");
$dumpvars(0, fp_mac_testbench);
$fsdbDumpfile("fp_mac_testbench.fsdb");
$fsdbDumpvars("+all");
$vcdpluson;
$vcdplusmemon;
endtask
// Clock generation
logic clk = 0;
always #5 clk = ~clk;
// Reset generation
logic rst = 0;
initial begin
rst = 1;
#10 rst = 0;
end
// Test cases
initial begin
setup_waveform_dump();
// Test case 1: Basic multiplication with addition
operand_a = 32'h3F800000; // 1.0
operand_b = 32'h40000000; // 2.0
operand_c = 32'h3F000000; // 0.5
rounding_mode = 3'b000;
#20;
// Test case 2: Complex operation
operand_a = 32'h40A9999A; // 5.3
operand_b = 32'h42C75EB8; // 99.685
operand_c = 32'h455C81FA; // 3528.123456
// Expected: a*b+c = 7FFFFFFF (4,056.453956)
rounding_mode = 3'b000;
#20;
// Additional test cases would go here...
$finish;
end
// Monitor for displaying results
always_ff @(posedge clk) begin
$display("A = %h, B = %h, C = %h, Rounding = %b, Result = %h, Status = %h",
operand_a, operand_b, operand_c, rounding_mode, result, status_flags);
end
endmodule
Synthesis Configuration
The synthesis script for Design Compiler was configured as follows:
set design_name "fp_mac"
set standard_cell_libraries "
../../lib/logic/slow.db
"
set target_library "$standard_cell_libraries"
set synthetic_library "dw_foundation.sldb"
set link_library "* $target_library dw_foundation.sldb"
sh mkdir -p ./reports
sh mkdir -p ./outputs
set report_path "./reports"
set output_path "./outputs"
set_svf $output_path/${design_name}.svf
Synthesis Challenges and Solutions
During implementation, a critical issue was encountered where the final gate-level netlist did not include the gate-level descriptions of the IP core. This rendered the netlist unsuitable for backend implementation.
After reviewing the DesignWare Building Block User Guide, it was determined that the issue stemmed from using the compile_ultra -incremental command without prior initialization. The -incremental flag is intended for encremental compilation after an initial compile_ultra operation.
The solution was to modify the synthesis command to use compile instead:
# Original problematic command
# compile_ultra -incremental
# Corrected commands
# Option 1: Basic compile
compile
# Option 2: Full compile_ultra without incremental flag
compile_ultra
Both approaches successfully generated netlists with proper gate-level descriptions of the IP core. The compile_ultra command without the -incremental flag produced higher quality netlists.
This issue highlighted the importance of understanding tool-specific flags and their dependencies. The legacy script had included the -incremental parameter without a clear understanding of its purpose, leading to the synthesis problem.
As documented in the Design Compiler User Guide, compile_ultra -incremental is meant for incremental compilation after an initial compile_ultra operation. The legacy script was using this flag without the prerequisite initialization step, which worked in previous cases but failed with the DesignWare IP due to its reliance on the dw_foundation.sldb synthetic library.