diff --git a/data/components.json b/data/components.json
index 7a3716502d..23233eaed1 100644
--- a/data/components.json
+++ b/data/components.json
@@ -508,15 +508,11 @@
}
}
},
- "handshake.addf.vivado": {
+ "handshake.addf.vivado": {
"latency": {
"64": {
- "1.0" : 9.0,
- "2.0" : 9.0,
- "3.75" : 9.0,
- "4.1" : 9.0,
- "5.0" : 9.0
- }
+ "1.0": 9.0
+ }
},
"delay": {
"data": {
@@ -574,8 +570,14 @@
"handshake.subf.flopoco": {
"latency": {
"64": {
- "1.0": 11.0,
- "2.0": 9.0
+ "2.705000": 12.0,
+ "5.091333": 7.0,
+ "9.068000": 2.0
+ },
+ "32": {
+ "2.798000": 36.0,
+ "2.922000": 10.0,
+ "3.649333": 6.0
}
},
"delay": {
@@ -586,9 +588,9 @@
"1": 0.0
},
"ready": {
- "1": 1.406
+ "1": 0.0
},
- "VR": 1.411,
+ "VR": 0,
"CV": 0,
"CR": 0,
"VC": 0,
@@ -634,8 +636,7 @@
"handshake.subf.vivado": {
"latency": {
"64": {
- "1.0": 11.0,
- "2.0": 9.0
+ "1.0": 9.0
}
},
"delay": {
@@ -760,8 +761,7 @@
"handshake.mulf.vivado": {
"latency": {
"64": {
- "1.0" : 4.0,
- "2.0" : 4.0
+ "1.0": 5.0
}
},
"delay": {
@@ -820,8 +820,7 @@
"handshake.divui": {
"latency": {
"64": {
- "1.0": 38.0,
- "2.0": 36.0
+ "1.0": 38.0
}
},
"delay": {
@@ -878,28 +877,86 @@
}
},
"handshake.divsi": {
- "latency": {
- "64": {
- "1.0": 36.0,
- "2.0": 36.0
- }
+ "latency":{
+ "32":{
+ "2.488": 36.0
+ }
},
"delay": {
- "data": {
- "64": 0.0
- },
- "valid": {
- "1": 0.0
- },
- "ready": {
- "1": 0.0
+ "data": {
+ "32": 0.0
+ },
+ "valid": {
+ "1": 0.0
+ },
+ "ready": {
+ "1": 1.121
+ },
+ "VR": 1.125,
+ "CV": 0.0,
+ "CR": 0.0,
+ "VC": 0.0,
+ "VD": 0.0
},
- "VR": 0,
- "CV": 0,
- "CR": 0,
- "VC": 0,
- "VD": 0
+ "inport": {
+ "delay": {
+ "data": {
+ "64": 0
+ },
+ "valid": {
+ "1": 0
+ },
+ "ready": {
+ "1": 0
+ },
+ "VR": 0,
+ "CV": 0,
+ "CR": 0,
+ "VC": 0,
+ "VD": 0
+ }
+ },
+ "outport": {
+ "delay": {
+ "data": {
+ "64": 0
+ },
+ "valid": {
+ "1": 0
+ },
+ "ready": {
+ "1": 0
+ },
+ "VR": 0,
+ "CV": 0,
+ "CR": 0,
+ "VC": 0,
+ "VD": 0
+ }
+ }
+ },
+ "handshake.remsi": {
+ "latency":{
+ "32":{
+ "2.488": 36.0
+ }
},
+ "delay": {
+ "data": {
+ "32": 0.0
+ },
+ "valid": {
+ "1": 0.0
+ },
+ "ready": {
+ "1": 1.121
+ },
+ "VR": 1.125,
+ "CV": 0.0,
+ "CR": 0.0,
+ "VC": 0.0,
+ "VD": 0.0
+ },
"inport": {
"delay": {
"data": {
@@ -1007,8 +1064,7 @@
"handshake.divf.vivado": {
"latency": {
"64": {
- "1.0" : 32.0,
- "2.0" : 30.0
+ "1.0": 29.0
}
},
"delay": {
@@ -1132,17 +1188,11 @@
"handshake.cmpf.vivado": {
"latency": {
"64": {
- "0.0" : 0.0
- }
+ "1.0": 1.0
+ }
},
"delay": {
"data": {
- "1": 1.397,
- "2": 1.397,
- "4": 2.038,
- "8": 1.707,
- "16": 1.775,
- "32": 1.895,
"64": 2.135
},
"valid": {
@@ -1987,5 +2037,371 @@
"VD": 0
}
}
+ },
+ "handshake.sitofp": {
+ "latency": {
+ "64": {
+ "1.190": 5.0
+ }
+ },
+ "delay": {
+ "data": {
+ "64": 0.0
+ },
+ "valid": {
+ "1": 0.0
+ },
+ "ready": {
+ "1": 1.121
+ },
+ "VR": 0,
+ "CV": 0,
+ "CR": 0,
+ "VC": 0,
+ "VD": 0
+ },
+ "inport": {
+ "delay": {
+ "data": {
+ "64": 0
+ },
+ "valid": {
+ "1": 0
+ },
+ "ready": {
+ "1": 0
+ },
+ "VR": 0,
+ "CV": 0,
+ "CR": 0,
+ "VC": 0,
+ "VD": 0
+ }
+ },
+ "outport": {
+ "delay": {
+ "data": {
+ "64": 0
+ },
+ "valid": {
+ "1": 0
+ },
+ "ready": {
+ "1": 0
+ },
+ "VR": 0,
+ "CV": 0,
+ "CR": 0,
+ "VC": 0,
+ "VD": 0
+ }
+ }
+ },
+ "handshake.fptosi": {
+ "latency": {
+ "64": {
+ "1.190": 5.0
+ }
+ },
+ "delay": {
+ "data": {
+ "64": 0.0
+ },
+ "valid": {
+ "1": 0.0
+ },
+ "ready": {
+ "1": 1.121
+ },
+ "VR": 0,
+ "CV": 0,
+ "CR": 0,
+ "VC": 0,
+ "VD": 0
+ },
+ "inport": {
+ "delay": {
+ "data": {
+ "64": 0
+ },
+ "valid": {
+ "1": 0
+ },
+ "ready": {
+ "1": 0
+ },
+ "VR": 0,
+ "CV": 0,
+ "CR": 0,
+ "VC": 0,
+ "VD": 0
+ }
+ },
+ "outport": {
+ "delay": {
+ "data": {
+ "64": 0
+ },
+ "valid": {
+ "1": 0
+ },
+ "ready": {
+ "1": 0
+ },
+ "VR": 0,
+ "CV": 0,
+ "CR": 0,
+ "VC": 0,
+ "VD": 0
+ }
+ }
+ },
+ "handshake.maximumf.flopoco": {
+ "latency": {
+ "64": {
+ "0.0": 0.0
+ }
+ },
+ "delay": {
+ "data": {
+ "1": 1.397,
+ "2": 1.397,
+ "4": 2.038,
+ "8": 1.707,
+ "16": 1.775,
+ "32": 1.895,
+ "64": 2.135
+ },
+ "valid": {
+ "1": 1.397
+ },
+ "ready": {
+ "1": 1.406
+ },
+ "VR": 1.411,
+ "CV": 0,
+ "CR": 0,
+ "VC": 0,
+ "VD": 0
+ },
+ "inport": {
+ "delay": {
+ "data": {
+ "64": 0
+ },
+ "valid": {
+ "1": 0
+ },
+ "ready": {
+ "1": 0
+ },
+ "VR": 0,
+ "CV": 0,
+ "CR": 0,
+ "VC": 0,
+ "VD": 0
+ }
+ },
+ "outport": {
+ "delay": {
+ "data": {
+ "64": 0
+ },
+ "valid": {
+ "1": 0
+ },
+ "ready": {
+ "1": 0
+ },
+ "VR": 0,
+ "CV": 0,
+ "CR": 0,
+ "VC": 0,
+ "VD": 0
+ }
+ }
+ },
+ "handshake.maximumf.vivado": {
+ "latency": {
+ "64": {
+ "1.0": 1.0
+ }
+ },
+ "delay": {
+ "data": {
+ "64": 2.135
+ },
+ "valid": {
+ "1": 1.397
+ },
+ "ready": {
+ "1": 1.406
+ },
+ "VR": 1.411,
+ "CV": 0,
+ "CR": 0,
+ "VC": 0,
+ "VD": 0
+ },
+ "inport": {
+ "delay": {
+ "data": {
+ "64": 0
+ },
+ "valid": {
+ "1": 0
+ },
+ "ready": {
+ "1": 0
+ },
+ "VR": 0,
+ "CV": 0,
+ "CR": 0,
+ "VC": 0,
+ "VD": 0
+ }
+ },
+ "outport": {
+ "delay": {
+ "data": {
+ "64": 0
+ },
+ "valid": {
+ "1": 0
+ },
+ "ready": {
+ "1": 0
+ },
+ "VR": 0,
+ "CV": 0,
+ "CR": 0,
+ "VC": 0,
+ "VD": 0
+ }
+ }
+ },
+ "handshake.minimumf.flopoco": {
+ "latency": {
+ "64": {
+ "0.0": 0.0
+ }
+ },
+ "delay": {
+ "data": {
+ "1": 1.397,
+ "2": 1.397,
+ "4": 2.038,
+ "8": 1.707,
+ "16": 1.775,
+ "32": 1.895,
+ "64": 2.135
+ },
+ "valid": {
+ "1": 1.397
+ },
+ "ready": {
+ "1": 1.406
+ },
+ "VR": 1.411,
+ "CV": 0,
+ "CR": 0,
+ "VC": 0,
+ "VD": 0
+ },
+ "inport": {
+ "delay": {
+ "data": {
+ "64": 0
+ },
+ "valid": {
+ "1": 0
+ },
+ "ready": {
+ "1": 0
+ },
+ "VR": 0,
+ "CV": 0,
+ "CR": 0,
+ "VC": 0,
+ "VD": 0
+ }
+ },
+ "outport": {
+ "delay": {
+ "data": {
+ "64": 0
+ },
+ "valid": {
+ "1": 0
+ },
+ "ready": {
+ "1": 0
+ },
+ "VR": 0,
+ "CV": 0,
+ "CR": 0,
+ "VC": 0,
+ "VD": 0
+ }
+ }
+ },
+ "handshake.minimumf.vivado": {
+ "latency": {
+ "64": {
+ "1.0": 1.0
+ }
+ },
+ "delay": {
+ "data": {
+ "64": 2.135
+ },
+ "valid": {
+ "1": 1.397
+ },
+ "ready": {
+ "1": 1.406
+ },
+ "VR": 1.411,
+ "CV": 0,
+ "CR": 0,
+ "VC": 0,
+ "VD": 0
+ },
+ "inport": {
+ "delay": {
+ "data": {
+ "64": 0
+ },
+ "valid": {
+ "1": 0
+ },
+ "ready": {
+ "1": 0
+ },
+ "VR": 0,
+ "CV": 0,
+ "CR": 0,
+ "VC": 0,
+ "VD": 0
+ }
+ },
+ "outport": {
+ "delay": {
+ "data": {
+ "64": 0
+ },
+ "valid": {
+ "1": 0
+ },
+ "ready": {
+ "1": 0
+ },
+ "VR": 0,
+ "CV": 0,
+ "CR": 0,
+ "VC": 0,
+ "VD": 0
+ }
+ }
}
-}
\ No newline at end of file
+}
diff --git a/data/rtl-config-vhdl-beta.json b/data/rtl-config-vhdl-beta.json
index f1f29a72c5..86117fbf34 100644
--- a/data/rtl-config-vhdl-beta.json
+++ b/data/rtl-config-vhdl-beta.json
@@ -1,9 +1,27 @@
[
+ {
+ "name": "handshake.absf",
+ "generator": "python $DYNAMATIC/experimental/tools/unit-generators/vhdl/vhdl-unit-generator.py -n $MODULE_NAME -o $OUTPUT_DIR/$MODULE_NAME.vhd -t absf -p bitwidth=$BITWIDTH extra_signals=$EXTRA_SIGNALS"
+ },
{
"name": "handshake.addf",
- "generator": "python $DYNAMATIC/experimental/tools/unit-generators/vhdl/vhdl-unit-generator.py -n $MODULE_NAME -o $OUTPUT_DIR/$MODULE_NAME.vhd -t addf -p is_double=$IS_DOUBLE extra_signals=$EXTRA_SIGNALS",
+ "parameters": [
+ {
+ "name": "LATENCY",
+ "type": "unsigned"
+ },
+ {
+ "name": "INTERNAL_DELAY",
+ "type": "string"
+ },
+ {
+ "name": "FPU_IMPL",
+ "type": "string"
+ }
+ ],
+ "generator": "python $DYNAMATIC/experimental/tools/unit-generators/vhdl/vhdl-unit-generator.py -n $MODULE_NAME -o $OUTPUT_DIR/$MODULE_NAME.vhd -t addf -p is_double=$IS_DOUBLE fpu_impl='\"$FPU_IMPL\"' internal_delay='\"$INTERNAL_DELAY\"' latency=$LATENCY extra_signals=$EXTRA_SIGNALS",
"dependencies": [
- "flopoco_ip_cores"
+ "flopoco_ip_cores", "vivado_ip_wrappers"
]
},
{
@@ -20,11 +38,19 @@
{
"name": "PREDICATE",
"type": "string"
+ },
+ {
+ "name": "FPU_IMPL",
+ "type": "string"
+ },
+ {
+ "name": "LATENCY",
+ "type": "unsigned"
}
],
- "generator": "python $DYNAMATIC/experimental/tools/unit-generators/vhdl/vhdl-unit-generator.py -n $MODULE_NAME -o $OUTPUT_DIR/$MODULE_NAME.vhd -t cmpf -p is_double=$IS_DOUBLE extra_signals=$EXTRA_SIGNALS predicate=\"'$PREDICATE'\"",
+ "generator": "python $DYNAMATIC/experimental/tools/unit-generators/vhdl/vhdl-unit-generator.py -n $MODULE_NAME -o $OUTPUT_DIR/$MODULE_NAME.vhd -t cmpf -p is_double=$IS_DOUBLE fpu_impl='\"$FPU_IMPL\"' latency=$LATENCY extra_signals=$EXTRA_SIGNALS predicate=\"'$PREDICATE'\"",
"dependencies": [
- "flopoco_ip_cores"
+ "flopoco_ip_cores", "vivado_ip_wrappers"
]
},
{
@@ -52,20 +78,116 @@
],
"generator": "python $DYNAMATIC/experimental/tools/unit-generators/vhdl/vhdl-unit-generator.py -n $MODULE_NAME -o $OUTPUT_DIR/$MODULE_NAME.vhd -t cmpi -p predicate=\"'$PREDICATE'\" bitwidth=$BITWIDTH extra_signals=$EXTRA_SIGNALS"
},
+ {
+ "name": "handshake.divf",
+ "parameters": [
+ {
+ "name": "LATENCY",
+ "type": "unsigned"
+ },
+ {
+ "name": "INTERNAL_DELAY",
+ "type": "string"
+ },
+ {
+ "name": "FPU_IMPL",
+ "type": "string"
+ }
+ ],
+ "generator": "python $DYNAMATIC/experimental/tools/unit-generators/vhdl/vhdl-unit-generator.py -n $MODULE_NAME -o $OUTPUT_DIR/$MODULE_NAME.vhd -t divf -p is_double=$IS_DOUBLE fpu_impl='\"$FPU_IMPL\"' internal_delay='\"$INTERNAL_DELAY\"' latency=$LATENCY extra_signals=$EXTRA_SIGNALS",
+ "dependencies": [
+ "flopoco_ip_cores", "vivado_ip_wrappers"
+ ]
+ },
+ {
+ "name": "handshake.divsi",
+ "parameters": [
+ {
+ "name": "LATENCY",
+ "type": "unsigned"
+ }
+ ],
+ "generator": "python $DYNAMATIC/experimental/tools/unit-generators/vhdl/vhdl-unit-generator.py -n $MODULE_NAME -o $OUTPUT_DIR/$MODULE_NAME.vhd -t divsi -p bitwidth=$BITWIDTH latency=$LATENCY extra_signals=$EXTRA_SIGNALS",
+ "dependencies": [
+ "vivado_ip_wrappers"
+ ]
+ },
+ {
+ "name": "handshake.remsi",
+ "parameters": [
+ {
+ "name": "LATENCY",
+ "type": "unsigned"
+ }
+ ],
+ "generator": "python $DYNAMATIC/experimental/tools/unit-generators/vhdl/vhdl-unit-generator.py -n $MODULE_NAME -o $OUTPUT_DIR/$MODULE_NAME.vhd -t remsi -p bitwidth=$BITWIDTH latency=$LATENCY extra_signals=$EXTRA_SIGNALS",
+ "dependencies": [
+ "vivado_ip_wrappers"
+ ]
+ },
+ {
+ "name": "handshake.divui",
+ "parameters": [
+ {
+ "name": "LATENCY",
+ "type": "unsigned"
+ }
+ ],
+ "generator": "python $DYNAMATIC/experimental/tools/unit-generators/vhdl/vhdl-unit-generator.py -n $MODULE_NAME -o $OUTPUT_DIR/$MODULE_NAME.vhd -t divui -p bitwidth=$BITWIDTH latency=$LATENCY extra_signals=$EXTRA_SIGNALS",
+ "dependencies": [
+ "vivado_ip_wrappers"
+ ]
+ },
+ {
+ "name": "handshake.negf",
+ "generator": "python $DYNAMATIC/experimental/tools/unit-generators/vhdl/vhdl-unit-generator.py -n $MODULE_NAME -o $OUTPUT_DIR/$MODULE_NAME.vhd -t negf -p bitwidth=$BITWIDTH extra_signals=$EXTRA_SIGNALS"
+ },
{
"name": "handshake.extsi",
"generator": "python $DYNAMATIC/experimental/tools/unit-generators/vhdl/vhdl-unit-generator.py -n $MODULE_NAME -o $OUTPUT_DIR/$MODULE_NAME.vhd -t extsi -p input_bitwidth=$INPUT_BITWIDTH output_bitwidth=$OUTPUT_BITWIDTH extra_signals=$EXTRA_SIGNALS"
},
+ {
+ "name": "handshake.extf",
+ "generator": "python $DYNAMATIC/experimental/tools/unit-generators/vhdl/vhdl-unit-generator.py -n $MODULE_NAME -o $OUTPUT_DIR/$MODULE_NAME.vhd -t extf -p extra_signals=$EXTRA_SIGNALS"
+ },
{
"name": "handshake.mulf",
- "generator": "python $DYNAMATIC/experimental/tools/unit-generators/vhdl/vhdl-unit-generator.py -n $MODULE_NAME -o $OUTPUT_DIR/$MODULE_NAME.vhd -t mulf -p is_double=$IS_DOUBLE extra_signals=$EXTRA_SIGNALS",
+ "parameters": [
+ {
+ "name": "LATENCY",
+ "type": "unsigned"
+ },
+ {
+ "name": "INTERNAL_DELAY",
+ "type": "string"
+ },
+ {
+ "name": "FPU_IMPL",
+ "type": "string"
+ }
+ ],
+ "generator": "python $DYNAMATIC/experimental/tools/unit-generators/vhdl/vhdl-unit-generator.py -n $MODULE_NAME -o $OUTPUT_DIR/$MODULE_NAME.vhd -t mulf -p is_double=$IS_DOUBLE fpu_impl='\"$FPU_IMPL\"' internal_delay='\"$INTERNAL_DELAY\"' latency=$LATENCY extra_signals=$EXTRA_SIGNALS",
"dependencies": [
- "flopoco_ip_cores"
+ "flopoco_ip_cores", "vivado_ip_wrappers"
]
},
+ {
+ "name": "handshake.maximumf",
+ "generator": "python $DYNAMATIC/experimental/tools/unit-generators/vhdl/vhdl-unit-generator.py -n $MODULE_NAME -o $OUTPUT_DIR/$MODULE_NAME.vhd -t maximumf -p latency=$LATENCY extra_signals=$EXTRA_SIGNALS"
+ },
+ {
+ "name": "handshake.minimumf",
+ "generator": "python $DYNAMATIC/experimental/tools/unit-generators/vhdl/vhdl-unit-generator.py -n $MODULE_NAME -o $OUTPUT_DIR/$MODULE_NAME.vhd -t minimumf -p latency=$LATENCY extra_signals=$EXTRA_SIGNALS"
+ },
{
"name": "handshake.muli",
- "generator": "python $DYNAMATIC/experimental/tools/unit-generators/vhdl/vhdl-unit-generator.py -n $MODULE_NAME -o $OUTPUT_DIR/$MODULE_NAME.vhd -t muli -p bitwidth=$BITWIDTH extra_signals=$EXTRA_SIGNALS"
+ "parameters": [
+ {
+ "name": "LATENCY",
+ "type": "unsigned"
+ }
+ ],
+ "generator": "python $DYNAMATIC/experimental/tools/unit-generators/vhdl/vhdl-unit-generator.py -n $MODULE_NAME -o $OUTPUT_DIR/$MODULE_NAME.vhd -t muli -p bitwidth=$BITWIDTH latency=$LATENCY extra_signals=$EXTRA_SIGNALS"
},
{
"name": "handshake.select",
@@ -73,9 +195,23 @@
},
{
"name": "handshake.subf",
- "generator": "python $DYNAMATIC/experimental/tools/unit-generators/vhdl/vhdl-unit-generator.py -n $MODULE_NAME -o $OUTPUT_DIR/$MODULE_NAME.vhd -t subf -p is_double=$IS_DOUBLE extra_signals=$EXTRA_SIGNALS",
+ "parameters": [
+ {
+ "name": "LATENCY",
+ "type": "unsigned"
+ },
+ {
+ "name": "INTERNAL_DELAY",
+ "type": "string"
+ },
+ {
+ "name": "FPU_IMPL",
+ "type": "string"
+ }
+ ],
+ "generator": "python $DYNAMATIC/experimental/tools/unit-generators/vhdl/vhdl-unit-generator.py -n $MODULE_NAME -o $OUTPUT_DIR/$MODULE_NAME.vhd -t subf -p is_double=$IS_DOUBLE fpu_impl='\"$FPU_IMPL\"' internal_delay='\"$INTERNAL_DELAY\"' latency=$LATENCY extra_signals=$EXTRA_SIGNALS",
"dependencies": [
- "flopoco_ip_cores"
+ "flopoco_ip_cores", "vivado_ip_wrappers"
]
},
{
@@ -86,6 +222,10 @@
"name": "handshake.trunci",
"generator": "python $DYNAMATIC/experimental/tools/unit-generators/vhdl/vhdl-unit-generator.py -n $MODULE_NAME -o $OUTPUT_DIR/$MODULE_NAME.vhd -t trunci -p input_bitwidth=$INPUT_BITWIDTH output_bitwidth=$OUTPUT_BITWIDTH extra_signals=$EXTRA_SIGNALS"
},
+ {
+ "name": "handshake.truncf",
+ "generator": "python $DYNAMATIC/experimental/tools/unit-generators/vhdl/vhdl-unit-generator.py -n $MODULE_NAME -o $OUTPUT_DIR/$MODULE_NAME.vhd -t truncf -p extra_signals=$EXTRA_SIGNALS"
+ },
{
"name": "handshake.buffer",
"parameters": [
@@ -113,6 +253,19 @@
"types"
]
},
+ {
+ "name": "handshake.lazy_fork",
+ "parameters": [
+ {
+ "name": "SIZE",
+ "type": "unsigned"
+ }
+ ],
+ "generator": "python $DYNAMATIC/experimental/tools/unit-generators/vhdl/vhdl-unit-generator.py -n $MODULE_NAME -o $OUTPUT_DIR/$MODULE_NAME.vhd -t lazy_fork -p size=$SIZE bitwidth=$BITWIDTH extra_signals=$EXTRA_SIGNALS",
+ "dependencies": [
+ "types"
+ ]
+ },
{
"name": "handshake.sink",
"generator": "python $DYNAMATIC/experimental/tools/unit-generators/vhdl/vhdl-unit-generator.py -n $MODULE_NAME -o $OUTPUT_DIR/$MODULE_NAME.vhd -t sink -p bitwidth=$BITWIDTH extra_signals=$EXTRA_SIGNALS"
@@ -160,6 +313,14 @@
"name": "handshake.cond_br",
"generator": "python $DYNAMATIC/experimental/tools/unit-generators/vhdl/vhdl-unit-generator.py -n $MODULE_NAME -o $OUTPUT_DIR/$MODULE_NAME.vhd -t cond_br -p bitwidth=$BITWIDTH extra_signals=$EXTRA_SIGNALS"
},
+ {
+ "name": "handshake.not",
+ "generator": "python $DYNAMATIC/experimental/tools/unit-generators/vhdl/vhdl-unit-generator.py -n $MODULE_NAME -o $OUTPUT_DIR/$MODULE_NAME.vhd -t not -p bitwidth=$BITWIDTH extra_signals=$EXTRA_SIGNALS"
+ },
+ {
+ "name": "handshake.br",
+ "generator": "python $DYNAMATIC/experimental/tools/unit-generators/vhdl/vhdl-unit-generator.py -n $MODULE_NAME -o $OUTPUT_DIR/$MODULE_NAME.vhd -t br -p bitwidth=$BITWIDTH extra_signals=$EXTRA_SIGNALS"
+ },
{
"name": "handshake.source",
"generator": "python $DYNAMATIC/experimental/tools/unit-generators/vhdl/vhdl-unit-generator.py -n $MODULE_NAME -o $OUTPUT_DIR/$MODULE_NAME.vhd -t source -p extra_signals=$EXTRA_SIGNALS"
@@ -182,6 +343,17 @@
"name": "handshake.store",
"generator": "python $DYNAMATIC/experimental/tools/unit-generators/vhdl/vhdl-unit-generator.py -n $MODULE_NAME -o $OUTPUT_DIR/$MODULE_NAME.vhd -t store -p addr_bitwidth=$ADDR_BITWIDTH data_bitwidth=$DATA_BITWIDTH extra_signals=$EXTRA_SIGNALS"
},
+ {
+ "name": "handshake.lsq",
+ "generator": "/usr/bin/env python3 $DYNAMATIC/tools/backend/lsq-generator-python/lsq-generator.py -o $OUTPUT_DIR -c $OUTPUT_DIR/$MODULE_NAME.json",
+ "use-json-config": "$OUTPUT_DIR/$MODULE_NAME.json",
+ "hdl": "vhdl",
+ "io-kind": "flat",
+ "io-map": [{ "clk": "clock" }, { "rst": "reset" }, { "*": "io_*" }],
+ "io-signals": {
+ "data": "_bits"
+ }
+ },
{
"name": "handshake.mem_controller",
"parameters": [
@@ -203,6 +375,14 @@
"types"
]
},
+ {
+ "name": "handshake.ori",
+ "generator": "python $DYNAMATIC/experimental/tools/unit-generators/vhdl/vhdl-unit-generator.py -n $MODULE_NAME -o $OUTPUT_DIR/$MODULE_NAME.vhd -t ori -p bitwidth=$BITWIDTH extra_signals=$EXTRA_SIGNALS"
+ },
+ {
+ "name": "handshake.xori",
+ "generator": "python $DYNAMATIC/experimental/tools/unit-generators/vhdl/vhdl-unit-generator.py -n $MODULE_NAME -o $OUTPUT_DIR/$MODULE_NAME.vhd -t xori -p bitwidth=$BITWIDTH extra_signals=$EXTRA_SIGNALS"
+ },
{
"name": "handshake.speculator",
"parameters": [
@@ -241,6 +421,10 @@
"name": "handshake.non_spec",
"generator": "python $DYNAMATIC/experimental/tools/unit-generators/vhdl/vhdl-unit-generator.py -n $MODULE_NAME -o $OUTPUT_DIR/$MODULE_NAME.vhd -t non_spec -p bitwidth=$BITWIDTH extra_signals=$EXTRA_SIGNALS"
},
+ {
+ "name": "handshake.ndwire",
+ "generator": "python $DYNAMATIC/experimental/tools/unit-generators/vhdl/vhdl-unit-generator.py -n $MODULE_NAME -o $OUTPUT_DIR/$MODULE_NAME.vhd -t ndwire -p bitwidth=$BITWIDTH extra_signals=$EXTRA_SIGNALS"
+ },
{
"name": "mem_to_bram",
"generator": "python $DYNAMATIC/experimental/tools/unit-generators/vhdl/vhdl-unit-generator.py -n $MODULE_NAME -o $OUTPUT_DIR/$MODULE_NAME.vhd -t mem_to_bram -p addr_bitwidth=$ADDR_BITWIDTH data_bitwidth=$DATA_BITWIDTH"
@@ -253,17 +437,33 @@
"name": "handshake.shli",
"generator": "python $DYNAMATIC/experimental/tools/unit-generators/vhdl/vhdl-unit-generator.py -n $MODULE_NAME -o $OUTPUT_DIR/$MODULE_NAME.vhd -t shli -p bitwidth=$BITWIDTH extra_signals=$EXTRA_SIGNALS"
},
+ {
+ "name": "handshake.shrsi",
+ "generator": "python $DYNAMATIC/experimental/tools/unit-generators/vhdl/vhdl-unit-generator.py -n $MODULE_NAME -o $OUTPUT_DIR/$MODULE_NAME.vhd -t shrsi -p bitwidth=$BITWIDTH extra_signals=$EXTRA_SIGNALS"
+ },
{
"name": "handshake.sitofp",
- "generator": "python $DYNAMATIC/experimental/tools/unit-generators/vhdl/vhdl-unit-generator.py -n $MODULE_NAME -o $OUTPUT_DIR/$MODULE_NAME.vhd -t sitofp -p bitwidth=$BITWIDTH extra_signals=$EXTRA_SIGNALS"
+ "parameters": [
+ {
+ "name": "LATENCY",
+ "type": "unsigned"
+ }
+ ],
+ "generator": "python $DYNAMATIC/experimental/tools/unit-generators/vhdl/vhdl-unit-generator.py -n $MODULE_NAME -o $OUTPUT_DIR/$MODULE_NAME.vhd -t sitofp -p latency=$LATENCY bitwidth=$BITWIDTH extra_signals=$EXTRA_SIGNALS"
},
{
"name": "handshake.fptosi",
- "generator": "python $DYNAMATIC/experimental/tools/unit-generators/vhdl/vhdl-unit-generator.py -n $MODULE_NAME -o $OUTPUT_DIR/$MODULE_NAME.vhd -t fptosi -p bitwidth=$BITWIDTH extra_signals=$EXTRA_SIGNALS"
+ "parameters": [
+ {
+ "name": "LATENCY",
+ "type": "unsigned"
+ }
+ ],
+ "generator": "python $DYNAMATIC/experimental/tools/unit-generators/vhdl/vhdl-unit-generator.py -n $MODULE_NAME -o $OUTPUT_DIR/$MODULE_NAME.vhd -t fptosi -p latency=$LATENCY bitwidth=$BITWIDTH extra_signals=$EXTRA_SIGNALS"
},
{
- "name": "handshake.ready_remover",
- "generator": "python $DYNAMATIC/experimental/tools/unit-generators/vhdl/vhdl-unit-generator.py -n $MODULE_NAME -o $OUTPUT_DIR/$MODULE_NAME.vhd -t ready_remover -p bitwidth=$BITWIDTH"
+ "name": "handshake.rigidifier",
+ "generator": "python $DYNAMATIC/experimental/tools/unit-generators/vhdl/vhdl-unit-generator.py -n $MODULE_NAME -o $OUTPUT_DIR/$MODULE_NAME.vhd -t rigidifier -p bitwidth=$BITWIDTH"
},
{
"name": "handshake.valid_merger",
@@ -282,6 +482,13 @@
"types"
]
},
+ {
+ "name": "handshake.join",
+ "parameters": [
+ { "name": "SIZE", "type": "unsigned"}
+ ],
+ "generator": "python $DYNAMATIC/experimental/tools/unit-generators/vhdl/vhdl-unit-generator.py -n $MODULE_NAME -o $OUTPUT_DIR/$MODULE_NAME.vhd -t top_join -p size=$SIZE"
+ },
{
"name": "handshake.sharing_wrapper",
"parameters":[
@@ -314,6 +521,9 @@
{
"generic": "$DYNAMATIC/data/vhdl/support/flopoco_ip_cores.vhd"
},
+ {
+ "generic": "$DYNAMATIC/data/vhdl/support/vivado_ip_wrappers.vhd"
+ },
{
"generic": "$DYNAMATIC/data/vhdl/support/sharing_support.vhd"
}
diff --git a/data/rtl-config-vhdl.json b/data/rtl-config-vhdl.json
index d79e827447..3461d79e1e 100644
--- a/data/rtl-config-vhdl.json
+++ b/data/rtl-config-vhdl.json
@@ -850,7 +850,7 @@
"module-name": "logic_not"
},
{
- "name": "handshake.ready_remover",
+ "name": "handshake.rigidifier",
"generator": "python $DYNAMATIC/experimental/tools/unit-generators/vhdl/vhdl-unit-generator.py -n $MODULE_NAME -o $OUTPUT_DIR/$MODULE_NAME.vhd -t ready_remover -p bitwidth=$BITWIDTH"
},
{
diff --git a/data/vhdl/arith/flopoco/subf.vhd b/data/vhdl/arith/flopoco/subf.vhd
index 83e0f70a20..6d0aa98504 100644
--- a/data/vhdl/arith/flopoco/subf.vhd
+++ b/data/vhdl/arith/flopoco/subf.vhd
@@ -183,7 +183,7 @@ begin
R => result
);
- operator : entity work.FPAdd_64bit(arch)
+ operator : entity work.FloatingPointAdder_64bit(arch)
port map(
clk => clk,
ce => oehb_ready,
diff --git a/data/vhdl/support/flopoco_ip_cores.vhd b/data/vhdl/support/flopoco_ip_cores.vhd
index 0115b60537..9c9cd4fe96 100644
--- a/data/vhdl/support/flopoco_ip_cores.vhd
+++ b/data/vhdl/support/flopoco_ip_cores.vhd
@@ -4604,14 +4604,14 @@ library std;
use std.textio.all;
library work;
-entity FPAdd_64bit is
+entity FloatingPointAdder_64bit is
port (clk, ce : in std_logic;
X : in std_logic_vector(11+52+2 downto 0);
Y : in std_logic_vector(11+52+2 downto 0);
R : out std_logic_vector(11+52+2 downto 0) );
end entity;
-architecture arch of FPAdd_64bit is
+architecture arch of FloatingPointAdder_64bit is
component RightShifterSticky53_by_max_55_F500_uid12 is
port ( clk, ce : in std_logic;
X : in std_logic_vector(52 downto 0);
diff --git a/data/vhdl/support/vivado_ip_wrappers.vhd b/data/vhdl/support/vivado_ip_wrappers.vhd
new file mode 100644
index 0000000000..4c66bd0bed
--- /dev/null
+++ b/data/vhdl/support/vivado_ip_wrappers.vhd
@@ -0,0 +1,2242 @@
+-- (c) Copyright 1995-2019 Xilinx, Inc. All rights reserved.
+--
+-- This file contains confidential and proprietary information
+-- of Xilinx, Inc. and is protected under U.S. and
+-- international copyright and other intellectual property
+-- laws.
+--
+-- DISCLAIMER
+-- This disclaimer is not a license and does not grant any
+-- rights to the materials distributed herewith. Except as
+-- otherwise provided in a valid license issued to you by
+-- Xilinx, and to the maximum extent permitted by applicable
+-- law: (1) THESE MATERIALS ARE MADE AVAILABLE "AS IS" AND
+-- WITH ALL FAULTS, AND XILINX HEREBY DISCLAIMS ALL WARRANTIES
+-- AND CONDITIONS, EXPRESS, IMPLIED, OR STATUTORY, INCLUDING
+-- BUT NOT LIMITED TO WARRANTIES OF MERCHANTABILITY, NON-
+-- INFRINGEMENT, OR FITNESS FOR ANY PARTICULAR PURPOSE; and
+-- (2) Xilinx shall not be liable (whether in contract or tort,
+-- including negligence, or under any other theory of
+-- liability) for any loss or damage of any kind or nature
+-- related to, arising under or in connection with these
+-- materials, including for any direct, or any indirect,
+-- special, incidental, or consequential loss or damage
+-- (including loss of data, profits, goodwill, or any type of
+-- loss or damage suffered as a result of any action brought
+-- by a third party) even if such damage or loss was
+-- reasonably foreseeable or Xilinx had been advised of the
+-- possibility of the same.
+--
+-- CRITICAL APPLICATIONS
+-- Xilinx products are not designed or intended to be fail-
+-- safe, or for use in any application requiring fail-safe
+-- performance, such as life-support or safety devices or
+-- systems, Class III medical devices, nuclear facilities,
+-- applications related to the deployment of airbags, or any
+-- other applications that could lead to death, personal
+-- injury, or severe property or environmental damage
+-- (individually and collectively, "Critical
+-- Applications"). Customer assumes the sole risk and
+-- liability of any use of Xilinx products in Critical
+-- Applications, subject only to applicable laws and
+-- regulations governing limitations on product liability.
+--
+-- THIS COPYRIGHT NOTICE AND DISCLAIMER MUST BE RETAINED AS
+-- PART OF THIS FILE AT ALL TIMES.
+--
+-- DO NOT MODIFY THIS FILE.
+
+-- IP VLNV: xilinx.com:ip:floating_point:7.1
+-- IP Revision: 8
+
+LIBRARY ieee;
+USE ieee.std_logic_1164.ALL;
+USE ieee.numeric_std.ALL;
+
+LIBRARY floating_point_v7_1_8;
+USE floating_point_v7_1_8.floating_point_v7_1_8;
+
+ENTITY addf_vitis_hls_single_precision_lat_8 IS
+ PORT (
+ aclk : IN STD_LOGIC;
+ aclken : IN STD_LOGIC;
+ s_axis_a_tvalid : IN STD_LOGIC;
+ s_axis_a_tdata : IN STD_LOGIC_VECTOR(31 DOWNTO 0);
+ s_axis_b_tvalid : IN STD_LOGIC;
+ s_axis_b_tdata : IN STD_LOGIC_VECTOR(31 DOWNTO 0);
+ m_axis_result_tvalid : OUT STD_LOGIC;
+ m_axis_result_tdata : OUT STD_LOGIC_VECTOR(31 DOWNTO 0)
+ );
+END addf_vitis_hls_single_precision_lat_8;
+
+ARCHITECTURE addf_vitis_hls_single_precision_lat_8_arch OF addf_vitis_hls_single_precision_lat_8 IS
+ ATTRIBUTE DowngradeIPIdentifiedWarnings : STRING;
+ ATTRIBUTE DowngradeIPIdentifiedWarnings OF addf_vitis_hls_single_precision_lat_8_arch: ARCHITECTURE IS "yes";
+ COMPONENT floating_point_v7_1_8 IS
+ GENERIC (
+ C_XDEVICEFAMILY : STRING;
+ C_HAS_ADD : INTEGER;
+ C_HAS_SUBTRACT : INTEGER;
+ C_HAS_MULTIPLY : INTEGER;
+ C_HAS_DIVIDE : INTEGER;
+ C_HAS_SQRT : INTEGER;
+ C_HAS_COMPARE : INTEGER;
+ C_HAS_FIX_TO_FLT : INTEGER;
+ C_HAS_FLT_TO_FIX : INTEGER;
+ C_HAS_FLT_TO_FLT : INTEGER;
+ C_HAS_RECIP : INTEGER;
+ C_HAS_RECIP_SQRT : INTEGER;
+ C_HAS_ABSOLUTE : INTEGER;
+ C_HAS_LOGARITHM : INTEGER;
+ C_HAS_EXPONENTIAL : INTEGER;
+ C_HAS_FMA : INTEGER;
+ C_HAS_FMS : INTEGER;
+ C_HAS_UNFUSED_MULTIPLY_ADD : INTEGER;
+ C_HAS_UNFUSED_MULTIPLY_SUB : INTEGER;
+ C_HAS_UNFUSED_MULTIPLY_ACCUMULATOR_A : INTEGER;
+ C_HAS_UNFUSED_MULTIPLY_ACCUMULATOR_S : INTEGER;
+ C_HAS_ACCUMULATOR_A : INTEGER;
+ C_HAS_ACCUMULATOR_S : INTEGER;
+ C_HAS_ACCUMULATOR_PRIMITIVE_A : INTEGER;
+ C_HAS_ACCUMULATOR_PRIMITIVE_S : INTEGER;
+ C_A_WIDTH : INTEGER;
+ C_A_FRACTION_WIDTH : INTEGER;
+ C_B_WIDTH : INTEGER;
+ C_B_FRACTION_WIDTH : INTEGER;
+ C_C_WIDTH : INTEGER;
+ C_C_FRACTION_WIDTH : INTEGER;
+ C_RESULT_WIDTH : INTEGER;
+ C_RESULT_FRACTION_WIDTH : INTEGER;
+ C_COMPARE_OPERATION : INTEGER;
+ C_LATENCY : INTEGER;
+ C_OPTIMIZATION : INTEGER;
+ C_MULT_USAGE : INTEGER;
+ C_BRAM_USAGE : INTEGER;
+ C_RATE : INTEGER;
+ C_ACCUM_INPUT_MSB : INTEGER;
+ C_ACCUM_MSB : INTEGER;
+ C_ACCUM_LSB : INTEGER;
+ C_HAS_UNDERFLOW : INTEGER;
+ C_HAS_OVERFLOW : INTEGER;
+ C_HAS_INVALID_OP : INTEGER;
+ C_HAS_DIVIDE_BY_ZERO : INTEGER;
+ C_HAS_ACCUM_OVERFLOW : INTEGER;
+ C_HAS_ACCUM_INPUT_OVERFLOW : INTEGER;
+ C_HAS_ACLKEN : INTEGER;
+ C_HAS_ARESETN : INTEGER;
+ C_THROTTLE_SCHEME : INTEGER;
+ C_HAS_A_TUSER : INTEGER;
+ C_HAS_A_TLAST : INTEGER;
+ C_HAS_B : INTEGER;
+ C_HAS_B_TUSER : INTEGER;
+ C_HAS_B_TLAST : INTEGER;
+ C_HAS_C : INTEGER;
+ C_HAS_C_TUSER : INTEGER;
+ C_HAS_C_TLAST : INTEGER;
+ C_HAS_OPERATION : INTEGER;
+ C_HAS_OPERATION_TUSER : INTEGER;
+ C_HAS_OPERATION_TLAST : INTEGER;
+ C_HAS_RESULT_TUSER : INTEGER;
+ C_HAS_RESULT_TLAST : INTEGER;
+ C_TLAST_RESOLUTION : INTEGER;
+ C_A_TDATA_WIDTH : INTEGER;
+ C_A_TUSER_WIDTH : INTEGER;
+ C_B_TDATA_WIDTH : INTEGER;
+ C_B_TUSER_WIDTH : INTEGER;
+ C_C_TDATA_WIDTH : INTEGER;
+ C_C_TUSER_WIDTH : INTEGER;
+ C_OPERATION_TDATA_WIDTH : INTEGER;
+ C_OPERATION_TUSER_WIDTH : INTEGER;
+ C_RESULT_TDATA_WIDTH : INTEGER;
+ C_RESULT_TUSER_WIDTH : INTEGER;
+ C_FIXED_DATA_UNSIGNED : INTEGER
+ );
+ PORT (
+ aclk : IN STD_LOGIC;
+ aclken : IN STD_LOGIC;
+ aresetn : IN STD_LOGIC;
+ s_axis_a_tvalid : IN STD_LOGIC;
+ s_axis_a_tready : OUT STD_LOGIC;
+ s_axis_a_tdata : IN STD_LOGIC_VECTOR(31 DOWNTO 0);
+ s_axis_a_tuser : IN STD_LOGIC_VECTOR(0 DOWNTO 0);
+ s_axis_a_tlast : IN STD_LOGIC;
+ s_axis_b_tvalid : IN STD_LOGIC;
+ s_axis_b_tready : OUT STD_LOGIC;
+ s_axis_b_tdata : IN STD_LOGIC_VECTOR(31 DOWNTO 0);
+ s_axis_b_tuser : IN STD_LOGIC_VECTOR(0 DOWNTO 0);
+ s_axis_b_tlast : IN STD_LOGIC;
+ s_axis_c_tvalid : IN STD_LOGIC;
+ s_axis_c_tready : OUT STD_LOGIC;
+ s_axis_c_tdata : IN STD_LOGIC_VECTOR(31 DOWNTO 0);
+ s_axis_c_tuser : IN STD_LOGIC_VECTOR(0 DOWNTO 0);
+ s_axis_c_tlast : IN STD_LOGIC;
+ s_axis_operation_tvalid : IN STD_LOGIC;
+ s_axis_operation_tready : OUT STD_LOGIC;
+ s_axis_operation_tdata : IN STD_LOGIC_VECTOR(7 DOWNTO 0);
+ s_axis_operation_tuser : IN STD_LOGIC_VECTOR(0 DOWNTO 0);
+ s_axis_operation_tlast : IN STD_LOGIC;
+ m_axis_result_tvalid : OUT STD_LOGIC;
+ m_axis_result_tready : IN STD_LOGIC;
+ m_axis_result_tdata : OUT STD_LOGIC_VECTOR(31 DOWNTO 0);
+ m_axis_result_tuser : OUT STD_LOGIC_VECTOR(0 DOWNTO 0);
+ m_axis_result_tlast : OUT STD_LOGIC
+ );
+ END COMPONENT floating_point_v7_1_8;
+ ATTRIBUTE X_INTERFACE_INFO : STRING;
+ ATTRIBUTE X_INTERFACE_PARAMETER : STRING;
+ ATTRIBUTE X_INTERFACE_INFO OF m_axis_result_tdata: SIGNAL IS "xilinx.com:interface:axis:1.0 M_AXIS_RESULT TDATA";
+ ATTRIBUTE X_INTERFACE_PARAMETER OF m_axis_result_tvalid: SIGNAL IS "XIL_INTERFACENAME M_AXIS_RESULT, TDATA_NUM_BYTES 4, TDEST_WIDTH 0, TID_WIDTH 0, TUSER_WIDTH 0, HAS_TREADY 0, HAS_TSTRB 0, HAS_TKEEP 0, HAS_TLAST 0, FREQ_HZ 100000000, PHASE 0.000, LAYERED_METADATA undef, INSERT_VIP 0";
+ ATTRIBUTE X_INTERFACE_INFO OF m_axis_result_tvalid: SIGNAL IS "xilinx.com:interface:axis:1.0 M_AXIS_RESULT TVALID";
+ ATTRIBUTE X_INTERFACE_INFO OF s_axis_b_tdata: SIGNAL IS "xilinx.com:interface:axis:1.0 S_AXIS_B TDATA";
+ ATTRIBUTE X_INTERFACE_PARAMETER OF s_axis_b_tvalid: SIGNAL IS "XIL_INTERFACENAME S_AXIS_B, TDATA_NUM_BYTES 4, TDEST_WIDTH 0, TID_WIDTH 0, TUSER_WIDTH 0, HAS_TREADY 0, HAS_TSTRB 0, HAS_TKEEP 0, HAS_TLAST 0, FREQ_HZ 100000000, PHASE 0.000, LAYERED_METADATA undef, INSERT_VIP 0";
+ ATTRIBUTE X_INTERFACE_INFO OF s_axis_b_tvalid: SIGNAL IS "xilinx.com:interface:axis:1.0 S_AXIS_B TVALID";
+ ATTRIBUTE X_INTERFACE_INFO OF s_axis_a_tdata: SIGNAL IS "xilinx.com:interface:axis:1.0 S_AXIS_A TDATA";
+ ATTRIBUTE X_INTERFACE_PARAMETER OF s_axis_a_tvalid: SIGNAL IS "XIL_INTERFACENAME S_AXIS_A, TDATA_NUM_BYTES 4, TDEST_WIDTH 0, TID_WIDTH 0, TUSER_WIDTH 0, HAS_TREADY 0, HAS_TSTRB 0, HAS_TKEEP 0, HAS_TLAST 0, FREQ_HZ 100000000, PHASE 0.000, LAYERED_METADATA undef, INSERT_VIP 0";
+ ATTRIBUTE X_INTERFACE_INFO OF s_axis_a_tvalid: SIGNAL IS "xilinx.com:interface:axis:1.0 S_AXIS_A TVALID";
+ ATTRIBUTE X_INTERFACE_PARAMETER OF aclken: SIGNAL IS "XIL_INTERFACENAME aclken_intf, POLARITY ACTIVE_LOW";
+ ATTRIBUTE X_INTERFACE_INFO OF aclken: SIGNAL IS "xilinx.com:signal:clockenable:1.0 aclken_intf CE";
+ ATTRIBUTE X_INTERFACE_PARAMETER OF aclk: SIGNAL IS "XIL_INTERFACENAME aclk_intf, ASSOCIATED_BUSIF S_AXIS_OPERATION:M_AXIS_RESULT:S_AXIS_C:S_AXIS_B:S_AXIS_A, ASSOCIATED_RESET aresetn, ASSOCIATED_CLKEN aclken, FREQ_HZ 10000000, PHASE 0.000, INSERT_VIP 0";
+ ATTRIBUTE X_INTERFACE_INFO OF aclk: SIGNAL IS "xilinx.com:signal:clock:1.0 aclk_intf CLK";
+BEGIN
+ U0 : floating_point_v7_1_8
+ GENERIC MAP (
+ C_XDEVICEFAMILY => "kintex7",
+ C_HAS_ADD => 1,
+ C_HAS_SUBTRACT => 0,
+ C_HAS_MULTIPLY => 0,
+ C_HAS_DIVIDE => 0,
+ C_HAS_SQRT => 0,
+ C_HAS_COMPARE => 0,
+ C_HAS_FIX_TO_FLT => 0,
+ C_HAS_FLT_TO_FIX => 0,
+ C_HAS_FLT_TO_FLT => 0,
+ C_HAS_RECIP => 0,
+ C_HAS_RECIP_SQRT => 0,
+ C_HAS_ABSOLUTE => 0,
+ C_HAS_LOGARITHM => 0,
+ C_HAS_EXPONENTIAL => 0,
+ C_HAS_FMA => 0,
+ C_HAS_FMS => 0,
+ C_HAS_UNFUSED_MULTIPLY_ADD => 0,
+ C_HAS_UNFUSED_MULTIPLY_SUB => 0,
+ C_HAS_UNFUSED_MULTIPLY_ACCUMULATOR_A => 0,
+ C_HAS_UNFUSED_MULTIPLY_ACCUMULATOR_S => 0,
+ C_HAS_ACCUMULATOR_A => 0,
+ C_HAS_ACCUMULATOR_S => 0,
+ C_HAS_ACCUMULATOR_PRIMITIVE_A => 0,
+ C_HAS_ACCUMULATOR_PRIMITIVE_S => 0,
+ C_A_WIDTH => 32,
+ C_A_FRACTION_WIDTH => 24,
+ C_B_WIDTH => 32,
+ C_B_FRACTION_WIDTH => 24,
+ C_C_WIDTH => 32,
+ C_C_FRACTION_WIDTH => 24,
+ C_RESULT_WIDTH => 32,
+ C_RESULT_FRACTION_WIDTH => 24,
+ C_COMPARE_OPERATION => 8,
+ C_LATENCY => 8,
+ C_OPTIMIZATION => 1,
+ C_MULT_USAGE => 2,
+ C_BRAM_USAGE => 0,
+ C_RATE => 1,
+ C_ACCUM_INPUT_MSB => 32,
+ C_ACCUM_MSB => 32,
+ C_ACCUM_LSB => -31,
+ C_HAS_UNDERFLOW => 0,
+ C_HAS_OVERFLOW => 0,
+ C_HAS_INVALID_OP => 0,
+ C_HAS_DIVIDE_BY_ZERO => 0,
+ C_HAS_ACCUM_OVERFLOW => 0,
+ C_HAS_ACCUM_INPUT_OVERFLOW => 0,
+ C_HAS_ACLKEN => 1,
+ C_HAS_ARESETN => 0,
+ C_THROTTLE_SCHEME => 3,
+ C_HAS_A_TUSER => 0,
+ C_HAS_A_TLAST => 0,
+ C_HAS_B => 1,
+ C_HAS_B_TUSER => 0,
+ C_HAS_B_TLAST => 0,
+ C_HAS_C => 0,
+ C_HAS_C_TUSER => 0,
+ C_HAS_C_TLAST => 0,
+ C_HAS_OPERATION => 0,
+ C_HAS_OPERATION_TUSER => 0,
+ C_HAS_OPERATION_TLAST => 0,
+ C_HAS_RESULT_TUSER => 0,
+ C_HAS_RESULT_TLAST => 0,
+ C_TLAST_RESOLUTION => 0,
+ C_A_TDATA_WIDTH => 32,
+ C_A_TUSER_WIDTH => 1,
+ C_B_TDATA_WIDTH => 32,
+ C_B_TUSER_WIDTH => 1,
+ C_C_TDATA_WIDTH => 32,
+ C_C_TUSER_WIDTH => 1,
+ C_OPERATION_TDATA_WIDTH => 8,
+ C_OPERATION_TUSER_WIDTH => 1,
+ C_RESULT_TDATA_WIDTH => 32,
+ C_RESULT_TUSER_WIDTH => 1,
+ C_FIXED_DATA_UNSIGNED => 0
+ )
+ PORT MAP (
+ aclk => aclk,
+ aclken => aclken,
+ aresetn => '1',
+ s_axis_a_tvalid => s_axis_a_tvalid,
+ s_axis_a_tdata => s_axis_a_tdata,
+ s_axis_a_tuser => STD_LOGIC_VECTOR(TO_UNSIGNED(0, 1)),
+ s_axis_a_tlast => '0',
+ s_axis_b_tvalid => s_axis_b_tvalid,
+ s_axis_b_tdata => s_axis_b_tdata,
+ s_axis_b_tuser => STD_LOGIC_VECTOR(TO_UNSIGNED(0, 1)),
+ s_axis_b_tlast => '0',
+ s_axis_c_tvalid => '0',
+ s_axis_c_tdata => STD_LOGIC_VECTOR(TO_UNSIGNED(0, 32)),
+ s_axis_c_tuser => STD_LOGIC_VECTOR(TO_UNSIGNED(0, 1)),
+ s_axis_c_tlast => '0',
+ s_axis_operation_tvalid => '0',
+ s_axis_operation_tdata => STD_LOGIC_VECTOR(TO_UNSIGNED(0, 8)),
+ s_axis_operation_tuser => STD_LOGIC_VECTOR(TO_UNSIGNED(0, 1)),
+ s_axis_operation_tlast => '0',
+ m_axis_result_tvalid => m_axis_result_tvalid,
+ m_axis_result_tready => '0',
+ m_axis_result_tdata => m_axis_result_tdata
+ );
+END addf_vitis_hls_single_precision_lat_8_arch;
+
+-- ==============================================================
+-- Vivado(TM) HLS - High-Level Synthesis from C, C++ and SystemC v2019.2.1 (64-bit)
+-- Copyright 1986-2019 Xilinx, Inc. All Rights Reserved.
+-- ==============================================================
+Library ieee;
+use ieee.std_logic_1164.all;
+
+entity addf_vitis_hls_wrapper is
+ port (
+ clk : in std_logic;
+ reset : in std_logic;
+ ce : in std_logic;
+ din0 : in std_logic_vector(32 - 1 downto 0);
+ din1 : in std_logic_vector(32 - 1 downto 0);
+ dout : out std_logic_vector(32 - 1 downto 0)
+ );
+end entity;
+
+architecture arch of addf_vitis_hls_wrapper is
+ --------------------- Local signal ------------------
+ signal aclk : std_logic;
+ signal aclken : std_logic;
+ signal a_tvalid : std_logic;
+ signal a_tdata : std_logic_vector(32 - 1 downto 0);
+ signal b_tvalid : std_logic;
+ signal b_tdata : std_logic_vector(32 - 1 downto 0);
+ signal r_tvalid : std_logic;
+ signal r_tdata : std_logic_vector(32 - 1 downto 0);
+ signal din0_buf1 : std_logic_vector(32 - 1 downto 0);
+ signal din1_buf1 : std_logic_vector(32 - 1 downto 0);
+ signal ce_r : std_logic;
+ signal dout_i : std_logic_vector(32 - 1 downto 0);
+ signal dout_r : std_logic_vector(32 - 1 downto 0);
+begin
+ --------------------- Instantiation -----------------
+ addf_vitis_hls_single_precision_lat_8_u : entity work.addf_vitis_hls_single_precision_lat_8
+ port map (
+ aclk => aclk,
+ aclken => aclken,
+ s_axis_a_tvalid => a_tvalid,
+ s_axis_a_tdata => a_tdata,
+ s_axis_b_tvalid => b_tvalid,
+ s_axis_b_tdata => b_tdata,
+ m_axis_result_tvalid => r_tvalid,
+ m_axis_result_tdata => r_tdata
+ );
+
+ --------------------- Assignment --------------------
+ aclk <= clk;
+ aclken <= ce_r;
+ a_tvalid <= '1';
+ a_tdata <= din0_buf1;
+ b_tvalid <= '1';
+ b_tdata <= din1_buf1;
+ dout_i <= r_tdata;
+
+ --------------------- Input buffer ------------------
+ process (clk) begin
+ if clk'event and clk = '1' then
+ if ce = '1' then
+ din0_buf1 <= din0;
+ din1_buf1 <= din1;
+ end if;
+ end if;
+ end process;
+
+ process (clk) begin
+ if clk'event and clk = '1' then
+ ce_r <= ce;
+ end if;
+ end process;
+
+ process (clk) begin
+ if clk'event and clk = '1' then
+ if ce_r = '1' then
+ dout_r <= dout_i;
+ end if;
+ end if;
+ end process;
+
+ dout <= dout_i when ce_r = '1' else dout_r;
+end architecture;
+
+
+-- (c) Copyright 1995-2019 Xilinx, Inc. All rights reserved.
+--
+-- This file contains confidential and proprietary information
+-- of Xilinx, Inc. and is protected under U.S. and
+-- international copyright and other intellectual property
+-- laws.
+--
+-- DISCLAIMER
+-- This disclaimer is not a license and does not grant any
+-- rights to the materials distributed herewith. Except as
+-- otherwise provided in a valid license issued to you by
+-- Xilinx, and to the maximum extent permitted by applicable
+-- law: (1) THESE MATERIALS ARE MADE AVAILABLE "AS IS" AND
+-- WITH ALL FAULTS, AND XILINX HEREBY DISCLAIMS ALL WARRANTIES
+-- AND CONDITIONS, EXPRESS, IMPLIED, OR STATUTORY, INCLUDING
+-- BUT NOT LIMITED TO WARRANTIES OF MERCHANTABILITY, NON-
+-- INFRINGEMENT, OR FITNESS FOR ANY PARTICULAR PURPOSE; and
+-- (2) Xilinx shall not be liable (whether in contract or tort,
+-- including negligence, or under any other theory of
+-- liability) for any loss or damage of any kind or nature
+-- related to, arising under or in connection with these
+-- materials, including for any direct, or any indirect,
+-- special, incidental, or consequential loss or damage
+-- (including loss of data, profits, goodwill, or any type of
+-- loss or damage suffered as a result of any action brought
+-- by a third party) even if such damage or loss was
+-- reasonably foreseeable or Xilinx had been advised of the
+-- possibility of the same.
+--
+-- CRITICAL APPLICATIONS
+-- Xilinx products are not designed or intended to be fail-
+-- safe, or for use in any application requiring fail-safe
+-- performance, such as life-support or safety devices or
+-- systems, Class III medical devices, nuclear facilities,
+-- applications related to the deployment of airbags, or any
+-- other applications that could lead to death, personal
+-- injury, or severe property or environmental damage
+-- (individually and collectively, "Critical
+-- Applications"). Customer assumes the sole risk and
+-- liability of any use of Xilinx products in Critical
+-- Applications, subject only to applicable laws and
+-- regulations governing limitations on product liability.
+--
+-- THIS COPYRIGHT NOTICE AND DISCLAIMER MUST BE RETAINED AS
+-- PART OF THIS FILE AT ALL TIMES.
+--
+-- DO NOT MODIFY THIS FILE.
+
+-- IP VLNV: xilinx.com:ip:floating_point:7.1
+-- IP Revision: 8
+
+LIBRARY ieee;
+USE ieee.std_logic_1164.ALL;
+USE ieee.numeric_std.ALL;
+
+LIBRARY floating_point_v7_1_8;
+USE floating_point_v7_1_8.floating_point_v7_1_8;
+
+ENTITY cmpf_vitis_hls_single_precision_lat_0 IS
+ PORT (
+ s_axis_a_tvalid : IN STD_LOGIC;
+ s_axis_a_tdata : IN STD_LOGIC_VECTOR(31 DOWNTO 0);
+ s_axis_b_tvalid : IN STD_LOGIC;
+ s_axis_b_tdata : IN STD_LOGIC_VECTOR(31 DOWNTO 0);
+ s_axis_operation_tvalid : IN STD_LOGIC;
+ s_axis_operation_tdata : IN STD_LOGIC_VECTOR(7 DOWNTO 0);
+ m_axis_result_tvalid : OUT STD_LOGIC;
+ m_axis_result_tdata : OUT STD_LOGIC_VECTOR(7 DOWNTO 0)
+ );
+END cmpf_vitis_hls_single_precision_lat_0;
+
+ARCHITECTURE cmpf_vitis_hls_single_precision_lat_0_arch OF cmpf_vitis_hls_single_precision_lat_0 IS
+ ATTRIBUTE DowngradeIPIdentifiedWarnings : STRING;
+ ATTRIBUTE DowngradeIPIdentifiedWarnings OF cmpf_vitis_hls_single_precision_lat_0_arch: ARCHITECTURE IS "yes";
+ COMPONENT floating_point_v7_1_8 IS
+ GENERIC (
+ C_XDEVICEFAMILY : STRING;
+ C_HAS_ADD : INTEGER;
+ C_HAS_SUBTRACT : INTEGER;
+ C_HAS_MULTIPLY : INTEGER;
+ C_HAS_DIVIDE : INTEGER;
+ C_HAS_SQRT : INTEGER;
+ C_HAS_COMPARE : INTEGER;
+ C_HAS_FIX_TO_FLT : INTEGER;
+ C_HAS_FLT_TO_FIX : INTEGER;
+ C_HAS_FLT_TO_FLT : INTEGER;
+ C_HAS_RECIP : INTEGER;
+ C_HAS_RECIP_SQRT : INTEGER;
+ C_HAS_ABSOLUTE : INTEGER;
+ C_HAS_LOGARITHM : INTEGER;
+ C_HAS_EXPONENTIAL : INTEGER;
+ C_HAS_FMA : INTEGER;
+ C_HAS_FMS : INTEGER;
+ C_HAS_UNFUSED_MULTIPLY_ADD : INTEGER;
+ C_HAS_UNFUSED_MULTIPLY_SUB : INTEGER;
+ C_HAS_UNFUSED_MULTIPLY_ACCUMULATOR_A : INTEGER;
+ C_HAS_UNFUSED_MULTIPLY_ACCUMULATOR_S : INTEGER;
+ C_HAS_ACCUMULATOR_A : INTEGER;
+ C_HAS_ACCUMULATOR_S : INTEGER;
+ C_HAS_ACCUMULATOR_PRIMITIVE_A : INTEGER;
+ C_HAS_ACCUMULATOR_PRIMITIVE_S : INTEGER;
+ C_A_WIDTH : INTEGER;
+ C_A_FRACTION_WIDTH : INTEGER;
+ C_B_WIDTH : INTEGER;
+ C_B_FRACTION_WIDTH : INTEGER;
+ C_C_WIDTH : INTEGER;
+ C_C_FRACTION_WIDTH : INTEGER;
+ C_RESULT_WIDTH : INTEGER;
+ C_RESULT_FRACTION_WIDTH : INTEGER;
+ C_COMPARE_OPERATION : INTEGER;
+ C_LATENCY : INTEGER;
+ C_OPTIMIZATION : INTEGER;
+ C_MULT_USAGE : INTEGER;
+ C_BRAM_USAGE : INTEGER;
+ C_RATE : INTEGER;
+ C_ACCUM_INPUT_MSB : INTEGER;
+ C_ACCUM_MSB : INTEGER;
+ C_ACCUM_LSB : INTEGER;
+ C_HAS_UNDERFLOW : INTEGER;
+ C_HAS_OVERFLOW : INTEGER;
+ C_HAS_INVALID_OP : INTEGER;
+ C_HAS_DIVIDE_BY_ZERO : INTEGER;
+ C_HAS_ACCUM_OVERFLOW : INTEGER;
+ C_HAS_ACCUM_INPUT_OVERFLOW : INTEGER;
+ C_HAS_ACLKEN : INTEGER;
+ C_HAS_ARESETN : INTEGER;
+ C_THROTTLE_SCHEME : INTEGER;
+ C_HAS_A_TUSER : INTEGER;
+ C_HAS_A_TLAST : INTEGER;
+ C_HAS_B : INTEGER;
+ C_HAS_B_TUSER : INTEGER;
+ C_HAS_B_TLAST : INTEGER;
+ C_HAS_C : INTEGER;
+ C_HAS_C_TUSER : INTEGER;
+ C_HAS_C_TLAST : INTEGER;
+ C_HAS_OPERATION : INTEGER;
+ C_HAS_OPERATION_TUSER : INTEGER;
+ C_HAS_OPERATION_TLAST : INTEGER;
+ C_HAS_RESULT_TUSER : INTEGER;
+ C_HAS_RESULT_TLAST : INTEGER;
+ C_TLAST_RESOLUTION : INTEGER;
+ C_A_TDATA_WIDTH : INTEGER;
+ C_A_TUSER_WIDTH : INTEGER;
+ C_B_TDATA_WIDTH : INTEGER;
+ C_B_TUSER_WIDTH : INTEGER;
+ C_C_TDATA_WIDTH : INTEGER;
+ C_C_TUSER_WIDTH : INTEGER;
+ C_OPERATION_TDATA_WIDTH : INTEGER;
+ C_OPERATION_TUSER_WIDTH : INTEGER;
+ C_RESULT_TDATA_WIDTH : INTEGER;
+ C_RESULT_TUSER_WIDTH : INTEGER;
+ C_FIXED_DATA_UNSIGNED : INTEGER
+ );
+ PORT (
+ aclk : IN STD_LOGIC;
+ aclken : IN STD_LOGIC;
+ aresetn : IN STD_LOGIC;
+ s_axis_a_tvalid : IN STD_LOGIC;
+ s_axis_a_tready : OUT STD_LOGIC;
+ s_axis_a_tdata : IN STD_LOGIC_VECTOR(31 DOWNTO 0);
+ s_axis_a_tuser : IN STD_LOGIC_VECTOR(0 DOWNTO 0);
+ s_axis_a_tlast : IN STD_LOGIC;
+ s_axis_b_tvalid : IN STD_LOGIC;
+ s_axis_b_tready : OUT STD_LOGIC;
+ s_axis_b_tdata : IN STD_LOGIC_VECTOR(31 DOWNTO 0);
+ s_axis_b_tuser : IN STD_LOGIC_VECTOR(0 DOWNTO 0);
+ s_axis_b_tlast : IN STD_LOGIC;
+ s_axis_c_tvalid : IN STD_LOGIC;
+ s_axis_c_tready : OUT STD_LOGIC;
+ s_axis_c_tdata : IN STD_LOGIC_VECTOR(31 DOWNTO 0);
+ s_axis_c_tuser : IN STD_LOGIC_VECTOR(0 DOWNTO 0);
+ s_axis_c_tlast : IN STD_LOGIC;
+ s_axis_operation_tvalid : IN STD_LOGIC;
+ s_axis_operation_tready : OUT STD_LOGIC;
+ s_axis_operation_tdata : IN STD_LOGIC_VECTOR(7 DOWNTO 0);
+ s_axis_operation_tuser : IN STD_LOGIC_VECTOR(0 DOWNTO 0);
+ s_axis_operation_tlast : IN STD_LOGIC;
+ m_axis_result_tvalid : OUT STD_LOGIC;
+ m_axis_result_tready : IN STD_LOGIC;
+ m_axis_result_tdata : OUT STD_LOGIC_VECTOR(7 DOWNTO 0);
+ m_axis_result_tuser : OUT STD_LOGIC_VECTOR(0 DOWNTO 0);
+ m_axis_result_tlast : OUT STD_LOGIC
+ );
+ END COMPONENT floating_point_v7_1_8;
+ ATTRIBUTE X_INTERFACE_INFO : STRING;
+ ATTRIBUTE X_INTERFACE_PARAMETER : STRING;
+ ATTRIBUTE X_INTERFACE_INFO OF m_axis_result_tdata: SIGNAL IS "xilinx.com:interface:axis:1.0 M_AXIS_RESULT TDATA";
+ ATTRIBUTE X_INTERFACE_PARAMETER OF m_axis_result_tvalid: SIGNAL IS "XIL_INTERFACENAME M_AXIS_RESULT, TDATA_NUM_BYTES 1, TDEST_WIDTH 0, TID_WIDTH 0, TUSER_WIDTH 0, HAS_TREADY 0, HAS_TSTRB 0, HAS_TKEEP 0, HAS_TLAST 0, FREQ_HZ 100000000, PHASE 0.000, LAYERED_METADATA undef, INSERT_VIP 0";
+ ATTRIBUTE X_INTERFACE_INFO OF m_axis_result_tvalid: SIGNAL IS "xilinx.com:interface:axis:1.0 M_AXIS_RESULT TVALID";
+ ATTRIBUTE X_INTERFACE_INFO OF s_axis_operation_tdata: SIGNAL IS "xilinx.com:interface:axis:1.0 S_AXIS_OPERATION TDATA";
+ ATTRIBUTE X_INTERFACE_PARAMETER OF s_axis_operation_tvalid: SIGNAL IS "XIL_INTERFACENAME S_AXIS_OPERATION, TDATA_NUM_BYTES 1, TDEST_WIDTH 0, TID_WIDTH 0, TUSER_WIDTH 0, HAS_TREADY 0, HAS_TSTRB 0, HAS_TKEEP 0, HAS_TLAST 0, FREQ_HZ 100000000, PHASE 0.000, LAYERED_METADATA undef, INSERT_VIP 0";
+ ATTRIBUTE X_INTERFACE_INFO OF s_axis_operation_tvalid: SIGNAL IS "xilinx.com:interface:axis:1.0 S_AXIS_OPERATION TVALID";
+ ATTRIBUTE X_INTERFACE_INFO OF s_axis_b_tdata: SIGNAL IS "xilinx.com:interface:axis:1.0 S_AXIS_B TDATA";
+ ATTRIBUTE X_INTERFACE_PARAMETER OF s_axis_b_tvalid: SIGNAL IS "XIL_INTERFACENAME S_AXIS_B, TDATA_NUM_BYTES 4, TDEST_WIDTH 0, TID_WIDTH 0, TUSER_WIDTH 0, HAS_TREADY 0, HAS_TSTRB 0, HAS_TKEEP 0, HAS_TLAST 0, FREQ_HZ 100000000, PHASE 0.000, LAYERED_METADATA undef, INSERT_VIP 0";
+ ATTRIBUTE X_INTERFACE_INFO OF s_axis_b_tvalid: SIGNAL IS "xilinx.com:interface:axis:1.0 S_AXIS_B TVALID";
+ ATTRIBUTE X_INTERFACE_INFO OF s_axis_a_tdata: SIGNAL IS "xilinx.com:interface:axis:1.0 S_AXIS_A TDATA";
+ ATTRIBUTE X_INTERFACE_PARAMETER OF s_axis_a_tvalid: SIGNAL IS "XIL_INTERFACENAME S_AXIS_A, TDATA_NUM_BYTES 4, TDEST_WIDTH 0, TID_WIDTH 0, TUSER_WIDTH 0, HAS_TREADY 0, HAS_TSTRB 0, HAS_TKEEP 0, HAS_TLAST 0, FREQ_HZ 100000000, PHASE 0.000, LAYERED_METADATA undef, INSERT_VIP 0";
+ ATTRIBUTE X_INTERFACE_INFO OF s_axis_a_tvalid: SIGNAL IS "xilinx.com:interface:axis:1.0 S_AXIS_A TVALID";
+BEGIN
+ U0 : floating_point_v7_1_8
+ GENERIC MAP (
+ C_XDEVICEFAMILY => "kintex7",
+ C_HAS_ADD => 0,
+ C_HAS_SUBTRACT => 0,
+ C_HAS_MULTIPLY => 0,
+ C_HAS_DIVIDE => 0,
+ C_HAS_SQRT => 0,
+ C_HAS_COMPARE => 1,
+ C_HAS_FIX_TO_FLT => 0,
+ C_HAS_FLT_TO_FIX => 0,
+ C_HAS_FLT_TO_FLT => 0,
+ C_HAS_RECIP => 0,
+ C_HAS_RECIP_SQRT => 0,
+ C_HAS_ABSOLUTE => 0,
+ C_HAS_LOGARITHM => 0,
+ C_HAS_EXPONENTIAL => 0,
+ C_HAS_FMA => 0,
+ C_HAS_FMS => 0,
+ C_HAS_UNFUSED_MULTIPLY_ADD => 0,
+ C_HAS_UNFUSED_MULTIPLY_SUB => 0,
+ C_HAS_UNFUSED_MULTIPLY_ACCUMULATOR_A => 0,
+ C_HAS_UNFUSED_MULTIPLY_ACCUMULATOR_S => 0,
+ C_HAS_ACCUMULATOR_A => 0,
+ C_HAS_ACCUMULATOR_S => 0,
+ C_HAS_ACCUMULATOR_PRIMITIVE_A => 0,
+ C_HAS_ACCUMULATOR_PRIMITIVE_S => 0,
+ C_A_WIDTH => 32,
+ C_A_FRACTION_WIDTH => 24,
+ C_B_WIDTH => 32,
+ C_B_FRACTION_WIDTH => 24,
+ C_C_WIDTH => 32,
+ C_C_FRACTION_WIDTH => 24,
+ C_RESULT_WIDTH => 1,
+ C_RESULT_FRACTION_WIDTH => 0,
+ C_COMPARE_OPERATION => 8,
+ C_LATENCY => 0,
+ C_OPTIMIZATION => 1,
+ C_MULT_USAGE => 0,
+ C_BRAM_USAGE => 0,
+ C_RATE => 1,
+ C_ACCUM_INPUT_MSB => 32,
+ C_ACCUM_MSB => 32,
+ C_ACCUM_LSB => -31,
+ C_HAS_UNDERFLOW => 0,
+ C_HAS_OVERFLOW => 0,
+ C_HAS_INVALID_OP => 0,
+ C_HAS_DIVIDE_BY_ZERO => 0,
+ C_HAS_ACCUM_OVERFLOW => 0,
+ C_HAS_ACCUM_INPUT_OVERFLOW => 0,
+ C_HAS_ACLKEN => 0,
+ C_HAS_ARESETN => 0,
+ C_THROTTLE_SCHEME => 3,
+ C_HAS_A_TUSER => 0,
+ C_HAS_A_TLAST => 0,
+ C_HAS_B => 1,
+ C_HAS_B_TUSER => 0,
+ C_HAS_B_TLAST => 0,
+ C_HAS_C => 0,
+ C_HAS_C_TUSER => 0,
+ C_HAS_C_TLAST => 0,
+ C_HAS_OPERATION => 1,
+ C_HAS_OPERATION_TUSER => 0,
+ C_HAS_OPERATION_TLAST => 0,
+ C_HAS_RESULT_TUSER => 0,
+ C_HAS_RESULT_TLAST => 0,
+ C_TLAST_RESOLUTION => 0,
+ C_A_TDATA_WIDTH => 32,
+ C_A_TUSER_WIDTH => 1,
+ C_B_TDATA_WIDTH => 32,
+ C_B_TUSER_WIDTH => 1,
+ C_C_TDATA_WIDTH => 32,
+ C_C_TUSER_WIDTH => 1,
+ C_OPERATION_TDATA_WIDTH => 8,
+ C_OPERATION_TUSER_WIDTH => 1,
+ C_RESULT_TDATA_WIDTH => 8,
+ C_RESULT_TUSER_WIDTH => 1,
+ C_FIXED_DATA_UNSIGNED => 0
+ )
+ PORT MAP (
+ aclk => '0',
+ aclken => '1',
+ aresetn => '1',
+ s_axis_a_tvalid => s_axis_a_tvalid,
+ s_axis_a_tdata => s_axis_a_tdata,
+ s_axis_a_tuser => STD_LOGIC_VECTOR(TO_UNSIGNED(0, 1)),
+ s_axis_a_tlast => '0',
+ s_axis_b_tvalid => s_axis_b_tvalid,
+ s_axis_b_tdata => s_axis_b_tdata,
+ s_axis_b_tuser => STD_LOGIC_VECTOR(TO_UNSIGNED(0, 1)),
+ s_axis_b_tlast => '0',
+ s_axis_c_tvalid => '0',
+ s_axis_c_tdata => STD_LOGIC_VECTOR(TO_UNSIGNED(0, 32)),
+ s_axis_c_tuser => STD_LOGIC_VECTOR(TO_UNSIGNED(0, 1)),
+ s_axis_c_tlast => '0',
+ s_axis_operation_tvalid => s_axis_operation_tvalid,
+ s_axis_operation_tdata => s_axis_operation_tdata,
+ s_axis_operation_tuser => STD_LOGIC_VECTOR(TO_UNSIGNED(0, 1)),
+ s_axis_operation_tlast => '0',
+ m_axis_result_tvalid => m_axis_result_tvalid,
+ m_axis_result_tready => '0',
+ m_axis_result_tdata => m_axis_result_tdata
+ );
+END cmpf_vitis_hls_single_precision_lat_0_arch;
+
+-- ==============================================================
+-- Vivado(TM) HLS - High-Level Synthesis from C, C++ and SystemC v2019.2.1 (64-bit)
+-- Copyright 1986-2019 Xilinx, Inc. All Rights Reserved.
+-- ==============================================================
+Library ieee;
+use ieee.std_logic_1164.all;
+
+entity cmpf_vitis_hls_wrapper is
+ port (
+ clk : in std_logic;
+ reset : in std_logic;
+ ce : in std_logic;
+ din0 : in std_logic_vector(32 - 1 downto 0);
+ din1 : in std_logic_vector(32 - 1 downto 0);
+ opcode : in std_logic_vector(4 downto 0);
+ dout : out std_logic_vector(1 - 1 downto 0)
+ );
+end entity;
+
+architecture arch of cmpf_vitis_hls_wrapper is
+ --------------------- Constant ----------------------
+ -- AutoESL opcode
+ constant AP_OEQ : std_logic_vector(4 downto 0) := "00001";
+ constant AP_OGT : std_logic_vector(4 downto 0) := "00010";
+ constant AP_OGE : std_logic_vector(4 downto 0) := "00011";
+ constant AP_OLT : std_logic_vector(4 downto 0) := "00100";
+ constant AP_OLE : std_logic_vector(4 downto 0) := "00101";
+ constant AP_ONE : std_logic_vector(4 downto 0) := "00110";
+ constant AP_UNO : std_logic_vector(4 downto 0) := "01000";
+ -- FPV6 opcode
+ constant OP_EQ : std_logic_vector(7 downto 0) := "00010100";
+ constant OP_GT : std_logic_vector(7 downto 0) := "00100100";
+ constant OP_GE : std_logic_vector(7 downto 0) := "00110100";
+ constant OP_LT : std_logic_vector(7 downto 0) := "00001100";
+ constant OP_LE : std_logic_vector(7 downto 0) := "00011100";
+ constant OP_NE : std_logic_vector(7 downto 0) := "00101100";
+ constant OP_UO : std_logic_vector(7 downto 0) := "00000100";
+ --------------------- Local signal ------------------
+ signal a_tvalid : std_logic;
+ signal a_tdata : std_logic_vector(31 downto 0);
+ signal b_tvalid : std_logic;
+ signal b_tdata : std_logic_vector(31 downto 0);
+ signal op_tvalid : std_logic;
+ signal op_tdata : std_logic_vector(7 downto 0);
+ signal r_tvalid : std_logic;
+ signal r_tdata : std_logic_vector(7 downto 0);
+ signal din0_buf1 : std_logic_vector(32 - 1 downto 0);
+ signal din1_buf1 : std_logic_vector(32 - 1 downto 0);
+ signal opcode_buf1 : std_logic_vector(4 downto 0);
+ signal ce_r : std_logic;
+ signal dout_i : std_logic_vector(1 - 1 downto 0);
+ signal dout_r : std_logic_vector(1 - 1 downto 0);
+begin
+ --------------------- Instantiation -----------------
+ cmpf_vitis_hls_single_precision_lat_0_u : entity work.cmpf_vitis_hls_single_precision_lat_0
+ port map (
+ s_axis_a_tvalid => a_tvalid,
+ s_axis_a_tdata => a_tdata,
+ s_axis_b_tvalid => b_tvalid,
+ s_axis_b_tdata => b_tdata,
+ s_axis_operation_tvalid => op_tvalid,
+ s_axis_operation_tdata => op_tdata,
+ m_axis_result_tvalid => r_tvalid,
+ m_axis_result_tdata => r_tdata
+ );
+
+ --------------------- Assignment --------------------
+ a_tvalid <= '1';
+ a_tdata <= din0_buf1;
+ b_tvalid <= '1';
+ b_tdata <= din1_buf1;
+ op_tvalid <= '1';
+ dout_i <= r_tdata(0 downto 0);
+
+ --------------------- Opcode ------------------------
+ process (opcode_buf1) begin
+ case (opcode_buf1) is
+ when AP_OEQ => op_tdata <= OP_EQ;
+ when AP_OGT => op_tdata <= OP_GT;
+ when AP_OGE => op_tdata <= OP_GE;
+ when AP_OLT => op_tdata <= OP_LT;
+ when AP_OLE => op_tdata <= OP_LE;
+ when AP_ONE => op_tdata <= OP_NE;
+ when AP_UNO => op_tdata <= OP_UO;
+ when others => op_tdata <= OP_EQ;
+ end case;
+ end process;
+
+ --------------------- Input buffer ------------------
+ process (clk) begin
+ if clk'event and clk = '1' then
+ if ce = '1' then
+ din0_buf1 <= din0;
+ din1_buf1 <= din1;
+ opcode_buf1 <= opcode;
+ end if;
+ end if;
+ end process;
+
+ process (clk) begin
+ if clk'event and clk = '1' then
+ ce_r <= ce;
+ end if;
+ end process;
+
+ process (clk) begin
+ if clk'event and clk = '1' then
+ if ce_r = '1' then
+ dout_r <= dout_i;
+ end if;
+ end if;
+ end process;
+
+ dout <= dout_i when ce_r = '1' else dout_r;
+end architecture;
+
+-- (c) Copyright 1995-2019 Xilinx, Inc. All rights reserved.
+--
+-- This file contains confidential and proprietary information
+-- of Xilinx, Inc. and is protected under U.S. and
+-- international copyright and other intellectual property
+-- laws.
+--
+-- DISCLAIMER
+-- This disclaimer is not a license and does not grant any
+-- rights to the materials distributed herewith. Except as
+-- otherwise provided in a valid license issued to you by
+-- Xilinx, and to the maximum extent permitted by applicable
+-- law: (1) THESE MATERIALS ARE MADE AVAILABLE "AS IS" AND
+-- WITH ALL FAULTS, AND XILINX HEREBY DISCLAIMS ALL WARRANTIES
+-- AND CONDITIONS, EXPRESS, IMPLIED, OR STATUTORY, INCLUDING
+-- BUT NOT LIMITED TO WARRANTIES OF MERCHANTABILITY, NON-
+-- INFRINGEMENT, OR FITNESS FOR ANY PARTICULAR PURPOSE; and
+-- (2) Xilinx shall not be liable (whether in contract or tort,
+-- including negligence, or under any other theory of
+-- liability) for any loss or damage of any kind or nature
+-- related to, arising under or in connection with these
+-- materials, including for any direct, or any indirect,
+-- special, incidental, or consequential loss or damage
+-- (including loss of data, profits, goodwill, or any type of
+-- loss or damage suffered as a result of any action brought
+-- by a third party) even if such damage or loss was
+-- reasonably foreseeable or Xilinx had been advised of the
+-- possibility of the same.
+--
+-- CRITICAL APPLICATIONS
+-- Xilinx products are not designed or intended to be fail-
+-- safe, or for use in any application requiring fail-safe
+-- performance, such as life-support or safety devices or
+-- systems, Class III medical devices, nuclear facilities,
+-- applications related to the deployment of airbags, or any
+-- other applications that could lead to death, personal
+-- injury, or severe property or environmental damage
+-- (individually and collectively, "Critical
+-- Applications"). Customer assumes the sole risk and
+-- liability of any use of Xilinx products in Critical
+-- Applications, subject only to applicable laws and
+-- regulations governing limitations on product liability.
+--
+-- THIS COPYRIGHT NOTICE AND DISCLAIMER MUST BE RETAINED AS
+-- PART OF THIS FILE AT ALL TIMES.
+--
+-- DO NOT MODIFY THIS FILE.
+
+-- IP VLNV: xilinx.com:ip:floating_point:7.1
+-- IP Revision: 8
+
+LIBRARY ieee;
+USE ieee.std_logic_1164.ALL;
+USE ieee.numeric_std.ALL;
+
+LIBRARY floating_point_v7_1_8;
+USE floating_point_v7_1_8.floating_point_v7_1_8;
+
+ENTITY divf_vitis_hls_single_precision_lat_28 IS
+ PORT (
+ aclk : IN STD_LOGIC;
+ aclken : IN STD_LOGIC;
+ s_axis_a_tvalid : IN STD_LOGIC;
+ s_axis_a_tdata : IN STD_LOGIC_VECTOR(31 DOWNTO 0);
+ s_axis_b_tvalid : IN STD_LOGIC;
+ s_axis_b_tdata : IN STD_LOGIC_VECTOR(31 DOWNTO 0);
+ m_axis_result_tvalid : OUT STD_LOGIC;
+ m_axis_result_tdata : OUT STD_LOGIC_VECTOR(31 DOWNTO 0)
+ );
+END divf_vitis_hls_single_precision_lat_28;
+
+ARCHITECTURE divf_vitis_hls_single_precision_lat_28_arch OF divf_vitis_hls_single_precision_lat_28 IS
+ ATTRIBUTE DowngradeIPIdentifiedWarnings : STRING;
+ ATTRIBUTE DowngradeIPIdentifiedWarnings OF divf_vitis_hls_single_precision_lat_28_arch: ARCHITECTURE IS "yes";
+ COMPONENT floating_point_v7_1_8 IS
+ GENERIC (
+ C_XDEVICEFAMILY : STRING;
+ C_HAS_ADD : INTEGER;
+ C_HAS_SUBTRACT : INTEGER;
+ C_HAS_MULTIPLY : INTEGER;
+ C_HAS_DIVIDE : INTEGER;
+ C_HAS_SQRT : INTEGER;
+ C_HAS_COMPARE : INTEGER;
+ C_HAS_FIX_TO_FLT : INTEGER;
+ C_HAS_FLT_TO_FIX : INTEGER;
+ C_HAS_FLT_TO_FLT : INTEGER;
+ C_HAS_RECIP : INTEGER;
+ C_HAS_RECIP_SQRT : INTEGER;
+ C_HAS_ABSOLUTE : INTEGER;
+ C_HAS_LOGARITHM : INTEGER;
+ C_HAS_EXPONENTIAL : INTEGER;
+ C_HAS_FMA : INTEGER;
+ C_HAS_FMS : INTEGER;
+ C_HAS_UNFUSED_MULTIPLY_ADD : INTEGER;
+ C_HAS_UNFUSED_MULTIPLY_SUB : INTEGER;
+ C_HAS_UNFUSED_MULTIPLY_ACCUMULATOR_A : INTEGER;
+ C_HAS_UNFUSED_MULTIPLY_ACCUMULATOR_S : INTEGER;
+ C_HAS_ACCUMULATOR_A : INTEGER;
+ C_HAS_ACCUMULATOR_S : INTEGER;
+ C_HAS_ACCUMULATOR_PRIMITIVE_A : INTEGER;
+ C_HAS_ACCUMULATOR_PRIMITIVE_S : INTEGER;
+ C_A_WIDTH : INTEGER;
+ C_A_FRACTION_WIDTH : INTEGER;
+ C_B_WIDTH : INTEGER;
+ C_B_FRACTION_WIDTH : INTEGER;
+ C_C_WIDTH : INTEGER;
+ C_C_FRACTION_WIDTH : INTEGER;
+ C_RESULT_WIDTH : INTEGER;
+ C_RESULT_FRACTION_WIDTH : INTEGER;
+ C_COMPARE_OPERATION : INTEGER;
+ C_LATENCY : INTEGER;
+ C_OPTIMIZATION : INTEGER;
+ C_MULT_USAGE : INTEGER;
+ C_BRAM_USAGE : INTEGER;
+ C_RATE : INTEGER;
+ C_ACCUM_INPUT_MSB : INTEGER;
+ C_ACCUM_MSB : INTEGER;
+ C_ACCUM_LSB : INTEGER;
+ C_HAS_UNDERFLOW : INTEGER;
+ C_HAS_OVERFLOW : INTEGER;
+ C_HAS_INVALID_OP : INTEGER;
+ C_HAS_DIVIDE_BY_ZERO : INTEGER;
+ C_HAS_ACCUM_OVERFLOW : INTEGER;
+ C_HAS_ACCUM_INPUT_OVERFLOW : INTEGER;
+ C_HAS_ACLKEN : INTEGER;
+ C_HAS_ARESETN : INTEGER;
+ C_THROTTLE_SCHEME : INTEGER;
+ C_HAS_A_TUSER : INTEGER;
+ C_HAS_A_TLAST : INTEGER;
+ C_HAS_B : INTEGER;
+ C_HAS_B_TUSER : INTEGER;
+ C_HAS_B_TLAST : INTEGER;
+ C_HAS_C : INTEGER;
+ C_HAS_C_TUSER : INTEGER;
+ C_HAS_C_TLAST : INTEGER;
+ C_HAS_OPERATION : INTEGER;
+ C_HAS_OPERATION_TUSER : INTEGER;
+ C_HAS_OPERATION_TLAST : INTEGER;
+ C_HAS_RESULT_TUSER : INTEGER;
+ C_HAS_RESULT_TLAST : INTEGER;
+ C_TLAST_RESOLUTION : INTEGER;
+ C_A_TDATA_WIDTH : INTEGER;
+ C_A_TUSER_WIDTH : INTEGER;
+ C_B_TDATA_WIDTH : INTEGER;
+ C_B_TUSER_WIDTH : INTEGER;
+ C_C_TDATA_WIDTH : INTEGER;
+ C_C_TUSER_WIDTH : INTEGER;
+ C_OPERATION_TDATA_WIDTH : INTEGER;
+ C_OPERATION_TUSER_WIDTH : INTEGER;
+ C_RESULT_TDATA_WIDTH : INTEGER;
+ C_RESULT_TUSER_WIDTH : INTEGER;
+ C_FIXED_DATA_UNSIGNED : INTEGER
+ );
+ PORT (
+ aclk : IN STD_LOGIC;
+ aclken : IN STD_LOGIC;
+ aresetn : IN STD_LOGIC;
+ s_axis_a_tvalid : IN STD_LOGIC;
+ s_axis_a_tready : OUT STD_LOGIC;
+ s_axis_a_tdata : IN STD_LOGIC_VECTOR(31 DOWNTO 0);
+ s_axis_a_tuser : IN STD_LOGIC_VECTOR(0 DOWNTO 0);
+ s_axis_a_tlast : IN STD_LOGIC;
+ s_axis_b_tvalid : IN STD_LOGIC;
+ s_axis_b_tready : OUT STD_LOGIC;
+ s_axis_b_tdata : IN STD_LOGIC_VECTOR(31 DOWNTO 0);
+ s_axis_b_tuser : IN STD_LOGIC_VECTOR(0 DOWNTO 0);
+ s_axis_b_tlast : IN STD_LOGIC;
+ s_axis_c_tvalid : IN STD_LOGIC;
+ s_axis_c_tready : OUT STD_LOGIC;
+ s_axis_c_tdata : IN STD_LOGIC_VECTOR(31 DOWNTO 0);
+ s_axis_c_tuser : IN STD_LOGIC_VECTOR(0 DOWNTO 0);
+ s_axis_c_tlast : IN STD_LOGIC;
+ s_axis_operation_tvalid : IN STD_LOGIC;
+ s_axis_operation_tready : OUT STD_LOGIC;
+ s_axis_operation_tdata : IN STD_LOGIC_VECTOR(7 DOWNTO 0);
+ s_axis_operation_tuser : IN STD_LOGIC_VECTOR(0 DOWNTO 0);
+ s_axis_operation_tlast : IN STD_LOGIC;
+ m_axis_result_tvalid : OUT STD_LOGIC;
+ m_axis_result_tready : IN STD_LOGIC;
+ m_axis_result_tdata : OUT STD_LOGIC_VECTOR(31 DOWNTO 0);
+ m_axis_result_tuser : OUT STD_LOGIC_VECTOR(0 DOWNTO 0);
+ m_axis_result_tlast : OUT STD_LOGIC
+ );
+ END COMPONENT floating_point_v7_1_8;
+ ATTRIBUTE X_INTERFACE_INFO : STRING;
+ ATTRIBUTE X_INTERFACE_PARAMETER : STRING;
+ ATTRIBUTE X_INTERFACE_INFO OF m_axis_result_tdata: SIGNAL IS "xilinx.com:interface:axis:1.0 M_AXIS_RESULT TDATA";
+ ATTRIBUTE X_INTERFACE_PARAMETER OF m_axis_result_tvalid: SIGNAL IS "XIL_INTERFACENAME M_AXIS_RESULT, TDATA_NUM_BYTES 4, TDEST_WIDTH 0, TID_WIDTH 0, TUSER_WIDTH 0, HAS_TREADY 0, HAS_TSTRB 0, HAS_TKEEP 0, HAS_TLAST 0, FREQ_HZ 100000000, PHASE 0.000, LAYERED_METADATA undef, INSERT_VIP 0";
+ ATTRIBUTE X_INTERFACE_INFO OF m_axis_result_tvalid: SIGNAL IS "xilinx.com:interface:axis:1.0 M_AXIS_RESULT TVALID";
+ ATTRIBUTE X_INTERFACE_INFO OF s_axis_b_tdata: SIGNAL IS "xilinx.com:interface:axis:1.0 S_AXIS_B TDATA";
+ ATTRIBUTE X_INTERFACE_PARAMETER OF s_axis_b_tvalid: SIGNAL IS "XIL_INTERFACENAME S_AXIS_B, TDATA_NUM_BYTES 4, TDEST_WIDTH 0, TID_WIDTH 0, TUSER_WIDTH 0, HAS_TREADY 0, HAS_TSTRB 0, HAS_TKEEP 0, HAS_TLAST 0, FREQ_HZ 100000000, PHASE 0.000, LAYERED_METADATA undef, INSERT_VIP 0";
+ ATTRIBUTE X_INTERFACE_INFO OF s_axis_b_tvalid: SIGNAL IS "xilinx.com:interface:axis:1.0 S_AXIS_B TVALID";
+ ATTRIBUTE X_INTERFACE_INFO OF s_axis_a_tdata: SIGNAL IS "xilinx.com:interface:axis:1.0 S_AXIS_A TDATA";
+ ATTRIBUTE X_INTERFACE_PARAMETER OF s_axis_a_tvalid: SIGNAL IS "XIL_INTERFACENAME S_AXIS_A, TDATA_NUM_BYTES 4, TDEST_WIDTH 0, TID_WIDTH 0, TUSER_WIDTH 0, HAS_TREADY 0, HAS_TSTRB 0, HAS_TKEEP 0, HAS_TLAST 0, FREQ_HZ 100000000, PHASE 0.000, LAYERED_METADATA undef, INSERT_VIP 0";
+ ATTRIBUTE X_INTERFACE_INFO OF s_axis_a_tvalid: SIGNAL IS "xilinx.com:interface:axis:1.0 S_AXIS_A TVALID";
+ ATTRIBUTE X_INTERFACE_PARAMETER OF aclken: SIGNAL IS "XIL_INTERFACENAME aclken_intf, POLARITY ACTIVE_LOW";
+ ATTRIBUTE X_INTERFACE_INFO OF aclken: SIGNAL IS "xilinx.com:signal:clockenable:1.0 aclken_intf CE";
+ ATTRIBUTE X_INTERFACE_PARAMETER OF aclk: SIGNAL IS "XIL_INTERFACENAME aclk_intf, ASSOCIATED_BUSIF S_AXIS_OPERATION:M_AXIS_RESULT:S_AXIS_C:S_AXIS_B:S_AXIS_A, ASSOCIATED_RESET aresetn, ASSOCIATED_CLKEN aclken, FREQ_HZ 10000000, PHASE 0.000, INSERT_VIP 0";
+ ATTRIBUTE X_INTERFACE_INFO OF aclk: SIGNAL IS "xilinx.com:signal:clock:1.0 aclk_intf CLK";
+BEGIN
+ U0 : floating_point_v7_1_8
+ GENERIC MAP (
+ C_XDEVICEFAMILY => "kintex7",
+ C_HAS_ADD => 0,
+ C_HAS_SUBTRACT => 0,
+ C_HAS_MULTIPLY => 0,
+ C_HAS_DIVIDE => 1,
+ C_HAS_SQRT => 0,
+ C_HAS_COMPARE => 0,
+ C_HAS_FIX_TO_FLT => 0,
+ C_HAS_FLT_TO_FIX => 0,
+ C_HAS_FLT_TO_FLT => 0,
+ C_HAS_RECIP => 0,
+ C_HAS_RECIP_SQRT => 0,
+ C_HAS_ABSOLUTE => 0,
+ C_HAS_LOGARITHM => 0,
+ C_HAS_EXPONENTIAL => 0,
+ C_HAS_FMA => 0,
+ C_HAS_FMS => 0,
+ C_HAS_UNFUSED_MULTIPLY_ADD => 0,
+ C_HAS_UNFUSED_MULTIPLY_SUB => 0,
+ C_HAS_UNFUSED_MULTIPLY_ACCUMULATOR_A => 0,
+ C_HAS_UNFUSED_MULTIPLY_ACCUMULATOR_S => 0,
+ C_HAS_ACCUMULATOR_A => 0,
+ C_HAS_ACCUMULATOR_S => 0,
+ C_HAS_ACCUMULATOR_PRIMITIVE_A => 0,
+ C_HAS_ACCUMULATOR_PRIMITIVE_S => 0,
+ C_A_WIDTH => 32,
+ C_A_FRACTION_WIDTH => 24,
+ C_B_WIDTH => 32,
+ C_B_FRACTION_WIDTH => 24,
+ C_C_WIDTH => 32,
+ C_C_FRACTION_WIDTH => 24,
+ C_RESULT_WIDTH => 32,
+ C_RESULT_FRACTION_WIDTH => 24,
+ C_COMPARE_OPERATION => 8,
+ C_LATENCY => 28,
+ C_OPTIMIZATION => 1,
+ C_MULT_USAGE => 0,
+ C_BRAM_USAGE => 0,
+ C_RATE => 1,
+ C_ACCUM_INPUT_MSB => 32,
+ C_ACCUM_MSB => 32,
+ C_ACCUM_LSB => -31,
+ C_HAS_UNDERFLOW => 0,
+ C_HAS_OVERFLOW => 0,
+ C_HAS_INVALID_OP => 0,
+ C_HAS_DIVIDE_BY_ZERO => 0,
+ C_HAS_ACCUM_OVERFLOW => 0,
+ C_HAS_ACCUM_INPUT_OVERFLOW => 0,
+ C_HAS_ACLKEN => 1,
+ C_HAS_ARESETN => 0,
+ C_THROTTLE_SCHEME => 3,
+ C_HAS_A_TUSER => 0,
+ C_HAS_A_TLAST => 0,
+ C_HAS_B => 1,
+ C_HAS_B_TUSER => 0,
+ C_HAS_B_TLAST => 0,
+ C_HAS_C => 0,
+ C_HAS_C_TUSER => 0,
+ C_HAS_C_TLAST => 0,
+ C_HAS_OPERATION => 0,
+ C_HAS_OPERATION_TUSER => 0,
+ C_HAS_OPERATION_TLAST => 0,
+ C_HAS_RESULT_TUSER => 0,
+ C_HAS_RESULT_TLAST => 0,
+ C_TLAST_RESOLUTION => 0,
+ C_A_TDATA_WIDTH => 32,
+ C_A_TUSER_WIDTH => 1,
+ C_B_TDATA_WIDTH => 32,
+ C_B_TUSER_WIDTH => 1,
+ C_C_TDATA_WIDTH => 32,
+ C_C_TUSER_WIDTH => 1,
+ C_OPERATION_TDATA_WIDTH => 8,
+ C_OPERATION_TUSER_WIDTH => 1,
+ C_RESULT_TDATA_WIDTH => 32,
+ C_RESULT_TUSER_WIDTH => 1,
+ C_FIXED_DATA_UNSIGNED => 0
+ )
+ PORT MAP (
+ aclk => aclk,
+ aclken => aclken,
+ aresetn => '1',
+ s_axis_a_tvalid => s_axis_a_tvalid,
+ s_axis_a_tdata => s_axis_a_tdata,
+ s_axis_a_tuser => STD_LOGIC_VECTOR(TO_UNSIGNED(0, 1)),
+ s_axis_a_tlast => '0',
+ s_axis_b_tvalid => s_axis_b_tvalid,
+ s_axis_b_tdata => s_axis_b_tdata,
+ s_axis_b_tuser => STD_LOGIC_VECTOR(TO_UNSIGNED(0, 1)),
+ s_axis_b_tlast => '0',
+ s_axis_c_tvalid => '0',
+ s_axis_c_tdata => STD_LOGIC_VECTOR(TO_UNSIGNED(0, 32)),
+ s_axis_c_tuser => STD_LOGIC_VECTOR(TO_UNSIGNED(0, 1)),
+ s_axis_c_tlast => '0',
+ s_axis_operation_tvalid => '0',
+ s_axis_operation_tdata => STD_LOGIC_VECTOR(TO_UNSIGNED(0, 8)),
+ s_axis_operation_tuser => STD_LOGIC_VECTOR(TO_UNSIGNED(0, 1)),
+ s_axis_operation_tlast => '0',
+ m_axis_result_tvalid => m_axis_result_tvalid,
+ m_axis_result_tready => '0',
+ m_axis_result_tdata => m_axis_result_tdata
+ );
+END divf_vitis_hls_single_precision_lat_28_arch;
+
+
+-- ==============================================================
+-- Vivado(TM) HLS - High-Level Synthesis from C, C++ and SystemC v2019.1 (64-bit)
+-- Copyright 1986-2019 Xilinx, Inc. All Rights Reserved.
+-- ==============================================================
+Library ieee;
+use ieee.std_logic_1164.all;
+
+entity divf_vitis_hls_wrapper is
+ port (
+ clk : in std_logic;
+ reset : in std_logic;
+ ce : in std_logic;
+ din0 : in std_logic_vector(32 - 1 downto 0);
+ din1 : in std_logic_vector(32 - 1 downto 0);
+ dout : out std_logic_vector(32 - 1 downto 0)
+ );
+end entity;
+
+architecture arch of divf_vitis_hls_wrapper is
+ --------------------- Local signals ------------------
+ signal aclk : std_logic;
+ signal aclken : std_logic;
+ signal a_tvalid : std_logic;
+ signal a_tdata : std_logic_vector(32 - 1 downto 0);
+ signal b_tvalid : std_logic;
+ signal b_tdata : std_logic_vector(32 - 1 downto 0);
+ signal r_tvalid : std_logic;
+ signal r_tdata : std_logic_vector(32 - 1 downto 0);
+ signal din0_buf1 : std_logic_vector(32 - 1 downto 0);
+ signal din1_buf1 : std_logic_vector(32 - 1 downto 0);
+ signal ce_r : std_logic;
+ signal dout_i : std_logic_vector(32 - 1 downto 0);
+ signal dout_r : std_logic_vector(32 - 1 downto 0);
+begin
+ --------------------- Instantiation -----------------
+ divf_vitis_hls_single_precision_lat_28_u : entity work.divf_vitis_hls_single_precision_lat_28
+ port map (
+ aclk => aclk,
+ aclken => aclken,
+ s_axis_a_tvalid => a_tvalid,
+ s_axis_a_tdata => a_tdata,
+ s_axis_b_tvalid => b_tvalid,
+ s_axis_b_tdata => b_tdata,
+ m_axis_result_tvalid => r_tvalid,
+ m_axis_result_tdata => r_tdata
+ );
+
+ --------------------- Assignment --------------------
+ aclk <= clk;
+ aclken <= ce_r;
+ a_tvalid <= '1';
+ a_tdata <= din0_buf1;
+ b_tvalid <= '1';
+ b_tdata <= din1_buf1;
+ dout_i <= r_tdata;
+
+ --------------------- Input buffer ------------------
+ process (clk) begin
+ if clk'event and clk = '1' then
+ if ce = '1' then
+ din0_buf1 <= din0;
+ din1_buf1 <= din1;
+ end if;
+ end if;
+ end process;
+
+ process (clk) begin
+ if clk'event and clk = '1' then
+ ce_r <= ce;
+ end if;
+ end process;
+
+ process (clk) begin
+ if clk'event and clk = '1' then
+ if ce_r = '1' then
+ dout_r <= dout_i;
+ end if;
+ end if;
+ end process;
+
+ dout <= dout_i when ce_r = '1' else dout_r;
+end architecture;
+
+
+-- (c) Copyright 1995-2019 Xilinx, Inc. All rights reserved.
+--
+-- This file contains confidential and proprietary information
+-- of Xilinx, Inc. and is protected under U.S. and
+-- international copyright and other intellectual property
+-- laws.
+--
+-- DISCLAIMER
+-- This disclaimer is not a license and does not grant any
+-- rights to the materials distributed herewith. Except as
+-- otherwise provided in a valid license issued to you by
+-- Xilinx, and to the maximum extent permitted by applicable
+-- law: (1) THESE MATERIALS ARE MADE AVAILABLE "AS IS" AND
+-- WITH ALL FAULTS, AND XILINX HEREBY DISCLAIMS ALL WARRANTIES
+-- AND CONDITIONS, EXPRESS, IMPLIED, OR STATUTORY, INCLUDING
+-- BUT NOT LIMITED TO WARRANTIES OF MERCHANTABILITY, NON-
+-- INFRINGEMENT, OR FITNESS FOR ANY PARTICULAR PURPOSE; and
+-- (2) Xilinx shall not be liable (whether in contract or tort,
+-- including negligence, or under any other theory of
+-- liability) for any loss or damage of any kind or nature
+-- related to, arising under or in connection with these
+-- materials, including for any direct, or any indirect,
+-- special, incidental, or consequential loss or damage
+-- (including loss of data, profits, goodwill, or any type of
+-- loss or damage suffered as a result of any action brought
+-- by a third party) even if such damage or loss was
+-- reasonably foreseeable or Xilinx had been advised of the
+-- possibility of the same.
+--
+-- CRITICAL APPLICATIONS
+-- Xilinx products are not designed or intended to be fail-
+-- safe, or for use in any application requiring fail-safe
+-- performance, such as life-support or safety devices or
+-- systems, Class III medical devices, nuclear facilities,
+-- applications related to the deployment of airbags, or any
+-- other applications that could lead to death, personal
+-- injury, or severe property or environmental damage
+-- (individually and collectively, "Critical
+-- Applications"). Customer assumes the sole risk and
+-- liability of any use of Xilinx products in Critical
+-- Applications, subject only to applicable laws and
+-- regulations governing limitations on product liability.
+--
+-- THIS COPYRIGHT NOTICE AND DISCLAIMER MUST BE RETAINED AS
+-- PART OF THIS FILE AT ALL TIMES.
+--
+-- DO NOT MODIFY THIS FILE.
+
+-- IP VLNV: xilinx.com:ip:floating_point:7.1
+-- IP Revision: 8
+
+LIBRARY ieee;
+USE ieee.std_logic_1164.ALL;
+USE ieee.numeric_std.ALL;
+
+LIBRARY floating_point_v7_1_8;
+USE floating_point_v7_1_8.floating_point_v7_1_8;
+
+ENTITY mulf_vitis_hls_single_precision_lat_4 IS
+ PORT (
+ aclk : IN STD_LOGIC;
+ aclken : IN STD_LOGIC;
+ s_axis_a_tvalid : IN STD_LOGIC;
+ s_axis_a_tdata : IN STD_LOGIC_VECTOR(31 DOWNTO 0);
+ s_axis_b_tvalid : IN STD_LOGIC;
+ s_axis_b_tdata : IN STD_LOGIC_VECTOR(31 DOWNTO 0);
+ m_axis_result_tvalid : OUT STD_LOGIC;
+ m_axis_result_tdata : OUT STD_LOGIC_VECTOR(31 DOWNTO 0)
+ );
+END mulf_vitis_hls_single_precision_lat_4;
+
+ARCHITECTURE mulf_vitis_hls_single_precision_lat_4_arch OF mulf_vitis_hls_single_precision_lat_4 IS
+ ATTRIBUTE DowngradeIPIdentifiedWarnings : STRING;
+ ATTRIBUTE DowngradeIPIdentifiedWarnings OF mulf_vitis_hls_single_precision_lat_4_arch: ARCHITECTURE IS "yes";
+ COMPONENT floating_point_v7_1_8 IS
+ GENERIC (
+ C_XDEVICEFAMILY : STRING;
+ C_HAS_ADD : INTEGER;
+ C_HAS_SUBTRACT : INTEGER;
+ C_HAS_MULTIPLY : INTEGER;
+ C_HAS_DIVIDE : INTEGER;
+ C_HAS_SQRT : INTEGER;
+ C_HAS_COMPARE : INTEGER;
+ C_HAS_FIX_TO_FLT : INTEGER;
+ C_HAS_FLT_TO_FIX : INTEGER;
+ C_HAS_FLT_TO_FLT : INTEGER;
+ C_HAS_RECIP : INTEGER;
+ C_HAS_RECIP_SQRT : INTEGER;
+ C_HAS_ABSOLUTE : INTEGER;
+ C_HAS_LOGARITHM : INTEGER;
+ C_HAS_EXPONENTIAL : INTEGER;
+ C_HAS_FMA : INTEGER;
+ C_HAS_FMS : INTEGER;
+ C_HAS_UNFUSED_MULTIPLY_ADD : INTEGER;
+ C_HAS_UNFUSED_MULTIPLY_SUB : INTEGER;
+ C_HAS_UNFUSED_MULTIPLY_ACCUMULATOR_A : INTEGER;
+ C_HAS_UNFUSED_MULTIPLY_ACCUMULATOR_S : INTEGER;
+ C_HAS_ACCUMULATOR_A : INTEGER;
+ C_HAS_ACCUMULATOR_S : INTEGER;
+ C_HAS_ACCUMULATOR_PRIMITIVE_A : INTEGER;
+ C_HAS_ACCUMULATOR_PRIMITIVE_S : INTEGER;
+ C_A_WIDTH : INTEGER;
+ C_A_FRACTION_WIDTH : INTEGER;
+ C_B_WIDTH : INTEGER;
+ C_B_FRACTION_WIDTH : INTEGER;
+ C_C_WIDTH : INTEGER;
+ C_C_FRACTION_WIDTH : INTEGER;
+ C_RESULT_WIDTH : INTEGER;
+ C_RESULT_FRACTION_WIDTH : INTEGER;
+ C_COMPARE_OPERATION : INTEGER;
+ C_LATENCY : INTEGER;
+ C_OPTIMIZATION : INTEGER;
+ C_MULT_USAGE : INTEGER;
+ C_BRAM_USAGE : INTEGER;
+ C_RATE : INTEGER;
+ C_ACCUM_INPUT_MSB : INTEGER;
+ C_ACCUM_MSB : INTEGER;
+ C_ACCUM_LSB : INTEGER;
+ C_HAS_UNDERFLOW : INTEGER;
+ C_HAS_OVERFLOW : INTEGER;
+ C_HAS_INVALID_OP : INTEGER;
+ C_HAS_DIVIDE_BY_ZERO : INTEGER;
+ C_HAS_ACCUM_OVERFLOW : INTEGER;
+ C_HAS_ACCUM_INPUT_OVERFLOW : INTEGER;
+ C_HAS_ACLKEN : INTEGER;
+ C_HAS_ARESETN : INTEGER;
+ C_THROTTLE_SCHEME : INTEGER;
+ C_HAS_A_TUSER : INTEGER;
+ C_HAS_A_TLAST : INTEGER;
+ C_HAS_B : INTEGER;
+ C_HAS_B_TUSER : INTEGER;
+ C_HAS_B_TLAST : INTEGER;
+ C_HAS_C : INTEGER;
+ C_HAS_C_TUSER : INTEGER;
+ C_HAS_C_TLAST : INTEGER;
+ C_HAS_OPERATION : INTEGER;
+ C_HAS_OPERATION_TUSER : INTEGER;
+ C_HAS_OPERATION_TLAST : INTEGER;
+ C_HAS_RESULT_TUSER : INTEGER;
+ C_HAS_RESULT_TLAST : INTEGER;
+ C_TLAST_RESOLUTION : INTEGER;
+ C_A_TDATA_WIDTH : INTEGER;
+ C_A_TUSER_WIDTH : INTEGER;
+ C_B_TDATA_WIDTH : INTEGER;
+ C_B_TUSER_WIDTH : INTEGER;
+ C_C_TDATA_WIDTH : INTEGER;
+ C_C_TUSER_WIDTH : INTEGER;
+ C_OPERATION_TDATA_WIDTH : INTEGER;
+ C_OPERATION_TUSER_WIDTH : INTEGER;
+ C_RESULT_TDATA_WIDTH : INTEGER;
+ C_RESULT_TUSER_WIDTH : INTEGER;
+ C_FIXED_DATA_UNSIGNED : INTEGER
+ );
+ PORT (
+ aclk : IN STD_LOGIC;
+ aclken : IN STD_LOGIC;
+ aresetn : IN STD_LOGIC;
+ s_axis_a_tvalid : IN STD_LOGIC;
+ s_axis_a_tready : OUT STD_LOGIC;
+ s_axis_a_tdata : IN STD_LOGIC_VECTOR(31 DOWNTO 0);
+ s_axis_a_tuser : IN STD_LOGIC_VECTOR(0 DOWNTO 0);
+ s_axis_a_tlast : IN STD_LOGIC;
+ s_axis_b_tvalid : IN STD_LOGIC;
+ s_axis_b_tready : OUT STD_LOGIC;
+ s_axis_b_tdata : IN STD_LOGIC_VECTOR(31 DOWNTO 0);
+ s_axis_b_tuser : IN STD_LOGIC_VECTOR(0 DOWNTO 0);
+ s_axis_b_tlast : IN STD_LOGIC;
+ s_axis_c_tvalid : IN STD_LOGIC;
+ s_axis_c_tready : OUT STD_LOGIC;
+ s_axis_c_tdata : IN STD_LOGIC_VECTOR(31 DOWNTO 0);
+ s_axis_c_tuser : IN STD_LOGIC_VECTOR(0 DOWNTO 0);
+ s_axis_c_tlast : IN STD_LOGIC;
+ s_axis_operation_tvalid : IN STD_LOGIC;
+ s_axis_operation_tready : OUT STD_LOGIC;
+ s_axis_operation_tdata : IN STD_LOGIC_VECTOR(7 DOWNTO 0);
+ s_axis_operation_tuser : IN STD_LOGIC_VECTOR(0 DOWNTO 0);
+ s_axis_operation_tlast : IN STD_LOGIC;
+ m_axis_result_tvalid : OUT STD_LOGIC;
+ m_axis_result_tready : IN STD_LOGIC;
+ m_axis_result_tdata : OUT STD_LOGIC_VECTOR(31 DOWNTO 0);
+ m_axis_result_tuser : OUT STD_LOGIC_VECTOR(0 DOWNTO 0);
+ m_axis_result_tlast : OUT STD_LOGIC
+ );
+ END COMPONENT floating_point_v7_1_8;
+ ATTRIBUTE X_INTERFACE_INFO : STRING;
+ ATTRIBUTE X_INTERFACE_PARAMETER : STRING;
+ ATTRIBUTE X_INTERFACE_INFO OF m_axis_result_tdata: SIGNAL IS "xilinx.com:interface:axis:1.0 M_AXIS_RESULT TDATA";
+ ATTRIBUTE X_INTERFACE_PARAMETER OF m_axis_result_tvalid: SIGNAL IS "XIL_INTERFACENAME M_AXIS_RESULT, TDATA_NUM_BYTES 4, TDEST_WIDTH 0, TID_WIDTH 0, TUSER_WIDTH 0, HAS_TREADY 0, HAS_TSTRB 0, HAS_TKEEP 0, HAS_TLAST 0, FREQ_HZ 100000000, PHASE 0.000, LAYERED_METADATA undef, INSERT_VIP 0";
+ ATTRIBUTE X_INTERFACE_INFO OF m_axis_result_tvalid: SIGNAL IS "xilinx.com:interface:axis:1.0 M_AXIS_RESULT TVALID";
+ ATTRIBUTE X_INTERFACE_INFO OF s_axis_b_tdata: SIGNAL IS "xilinx.com:interface:axis:1.0 S_AXIS_B TDATA";
+ ATTRIBUTE X_INTERFACE_PARAMETER OF s_axis_b_tvalid: SIGNAL IS "XIL_INTERFACENAME S_AXIS_B, TDATA_NUM_BYTES 4, TDEST_WIDTH 0, TID_WIDTH 0, TUSER_WIDTH 0, HAS_TREADY 0, HAS_TSTRB 0, HAS_TKEEP 0, HAS_TLAST 0, FREQ_HZ 100000000, PHASE 0.000, LAYERED_METADATA undef, INSERT_VIP 0";
+ ATTRIBUTE X_INTERFACE_INFO OF s_axis_b_tvalid: SIGNAL IS "xilinx.com:interface:axis:1.0 S_AXIS_B TVALID";
+ ATTRIBUTE X_INTERFACE_INFO OF s_axis_a_tdata: SIGNAL IS "xilinx.com:interface:axis:1.0 S_AXIS_A TDATA";
+ ATTRIBUTE X_INTERFACE_PARAMETER OF s_axis_a_tvalid: SIGNAL IS "XIL_INTERFACENAME S_AXIS_A, TDATA_NUM_BYTES 4, TDEST_WIDTH 0, TID_WIDTH 0, TUSER_WIDTH 0, HAS_TREADY 0, HAS_TSTRB 0, HAS_TKEEP 0, HAS_TLAST 0, FREQ_HZ 100000000, PHASE 0.000, LAYERED_METADATA undef, INSERT_VIP 0";
+ ATTRIBUTE X_INTERFACE_INFO OF s_axis_a_tvalid: SIGNAL IS "xilinx.com:interface:axis:1.0 S_AXIS_A TVALID";
+ ATTRIBUTE X_INTERFACE_PARAMETER OF aclken: SIGNAL IS "XIL_INTERFACENAME aclken_intf, POLARITY ACTIVE_LOW";
+ ATTRIBUTE X_INTERFACE_INFO OF aclken: SIGNAL IS "xilinx.com:signal:clockenable:1.0 aclken_intf CE";
+ ATTRIBUTE X_INTERFACE_PARAMETER OF aclk: SIGNAL IS "XIL_INTERFACENAME aclk_intf, ASSOCIATED_BUSIF S_AXIS_OPERATION:M_AXIS_RESULT:S_AXIS_C:S_AXIS_B:S_AXIS_A, ASSOCIATED_RESET aresetn, ASSOCIATED_CLKEN aclken, FREQ_HZ 10000000, PHASE 0.000, INSERT_VIP 0";
+ ATTRIBUTE X_INTERFACE_INFO OF aclk: SIGNAL IS "xilinx.com:signal:clock:1.0 aclk_intf CLK";
+BEGIN
+ U0 : floating_point_v7_1_8
+ GENERIC MAP (
+ C_XDEVICEFAMILY => "kintex7",
+ C_HAS_ADD => 0,
+ C_HAS_SUBTRACT => 0,
+ C_HAS_MULTIPLY => 1,
+ C_HAS_DIVIDE => 0,
+ C_HAS_SQRT => 0,
+ C_HAS_COMPARE => 0,
+ C_HAS_FIX_TO_FLT => 0,
+ C_HAS_FLT_TO_FIX => 0,
+ C_HAS_FLT_TO_FLT => 0,
+ C_HAS_RECIP => 0,
+ C_HAS_RECIP_SQRT => 0,
+ C_HAS_ABSOLUTE => 0,
+ C_HAS_LOGARITHM => 0,
+ C_HAS_EXPONENTIAL => 0,
+ C_HAS_FMA => 0,
+ C_HAS_FMS => 0,
+ C_HAS_UNFUSED_MULTIPLY_ADD => 0,
+ C_HAS_UNFUSED_MULTIPLY_SUB => 0,
+ C_HAS_UNFUSED_MULTIPLY_ACCUMULATOR_A => 0,
+ C_HAS_UNFUSED_MULTIPLY_ACCUMULATOR_S => 0,
+ C_HAS_ACCUMULATOR_A => 0,
+ C_HAS_ACCUMULATOR_S => 0,
+ C_HAS_ACCUMULATOR_PRIMITIVE_A => 0,
+ C_HAS_ACCUMULATOR_PRIMITIVE_S => 0,
+ C_A_WIDTH => 32,
+ C_A_FRACTION_WIDTH => 24,
+ C_B_WIDTH => 32,
+ C_B_FRACTION_WIDTH => 24,
+ C_C_WIDTH => 32,
+ C_C_FRACTION_WIDTH => 24,
+ C_RESULT_WIDTH => 32,
+ C_RESULT_FRACTION_WIDTH => 24,
+ C_COMPARE_OPERATION => 8,
+ C_LATENCY => 4,
+ C_OPTIMIZATION => 1,
+ C_MULT_USAGE => 3,
+ C_BRAM_USAGE => 0,
+ C_RATE => 1,
+ C_ACCUM_INPUT_MSB => 32,
+ C_ACCUM_MSB => 32,
+ C_ACCUM_LSB => -31,
+ C_HAS_UNDERFLOW => 0,
+ C_HAS_OVERFLOW => 0,
+ C_HAS_INVALID_OP => 0,
+ C_HAS_DIVIDE_BY_ZERO => 0,
+ C_HAS_ACCUM_OVERFLOW => 0,
+ C_HAS_ACCUM_INPUT_OVERFLOW => 0,
+ C_HAS_ACLKEN => 1,
+ C_HAS_ARESETN => 0,
+ C_THROTTLE_SCHEME => 3,
+ C_HAS_A_TUSER => 0,
+ C_HAS_A_TLAST => 0,
+ C_HAS_B => 1,
+ C_HAS_B_TUSER => 0,
+ C_HAS_B_TLAST => 0,
+ C_HAS_C => 0,
+ C_HAS_C_TUSER => 0,
+ C_HAS_C_TLAST => 0,
+ C_HAS_OPERATION => 0,
+ C_HAS_OPERATION_TUSER => 0,
+ C_HAS_OPERATION_TLAST => 0,
+ C_HAS_RESULT_TUSER => 0,
+ C_HAS_RESULT_TLAST => 0,
+ C_TLAST_RESOLUTION => 0,
+ C_A_TDATA_WIDTH => 32,
+ C_A_TUSER_WIDTH => 1,
+ C_B_TDATA_WIDTH => 32,
+ C_B_TUSER_WIDTH => 1,
+ C_C_TDATA_WIDTH => 32,
+ C_C_TUSER_WIDTH => 1,
+ C_OPERATION_TDATA_WIDTH => 8,
+ C_OPERATION_TUSER_WIDTH => 1,
+ C_RESULT_TDATA_WIDTH => 32,
+ C_RESULT_TUSER_WIDTH => 1,
+ C_FIXED_DATA_UNSIGNED => 0
+ )
+ PORT MAP (
+ aclk => aclk,
+ aclken => aclken,
+ aresetn => '1',
+ s_axis_a_tvalid => s_axis_a_tvalid,
+ s_axis_a_tdata => s_axis_a_tdata,
+ s_axis_a_tuser => STD_LOGIC_VECTOR(TO_UNSIGNED(0, 1)),
+ s_axis_a_tlast => '0',
+ s_axis_b_tvalid => s_axis_b_tvalid,
+ s_axis_b_tdata => s_axis_b_tdata,
+ s_axis_b_tuser => STD_LOGIC_VECTOR(TO_UNSIGNED(0, 1)),
+ s_axis_b_tlast => '0',
+ s_axis_c_tvalid => '0',
+ s_axis_c_tdata => STD_LOGIC_VECTOR(TO_UNSIGNED(0, 32)),
+ s_axis_c_tuser => STD_LOGIC_VECTOR(TO_UNSIGNED(0, 1)),
+ s_axis_c_tlast => '0',
+ s_axis_operation_tvalid => '0',
+ s_axis_operation_tdata => STD_LOGIC_VECTOR(TO_UNSIGNED(0, 8)),
+ s_axis_operation_tuser => STD_LOGIC_VECTOR(TO_UNSIGNED(0, 1)),
+ s_axis_operation_tlast => '0',
+ m_axis_result_tvalid => m_axis_result_tvalid,
+ m_axis_result_tready => '0',
+ m_axis_result_tdata => m_axis_result_tdata
+ );
+END mulf_vitis_hls_single_precision_lat_4_arch;
+
+-- ==============================================================
+-- Vivado(TM) HLS - High-Level Synthesis from C, C++ and SystemC v2019.2.1 (64-bit)
+-- Copyright 1986-2019 Xilinx, Inc. All Rights Reserved.
+-- ==============================================================
+Library ieee;
+use ieee.std_logic_1164.all;
+
+entity mulf_vitis_hls_wrapper is
+ port (
+ clk : in std_logic;
+ reset : in std_logic;
+ ce : in std_logic;
+ din0 : in std_logic_vector(32 -1 downto 0);
+ din1 : in std_logic_vector(32 -1 downto 0);
+ dout : out std_logic_vector(32 -1 downto 0)
+ );
+end entity;
+
+architecture arch of mulf_vitis_hls_wrapper is
+ --------------------- Local signals ------------------
+ signal aclk : std_logic;
+ signal aclken : std_logic;
+ signal a_tvalid : std_logic;
+ signal a_tdata : std_logic_vector(32 - 1 downto 0);
+ signal b_tvalid : std_logic;
+ signal b_tdata : std_logic_vector(32 - 1downto 0);
+ signal r_tvalid : std_logic;
+ signal r_tdata : std_logic_vector(32 - 1 downto 0);
+ signal din0_buf1 : std_logic_vector(32 - 1 downto 0);
+ signal din1_buf1 : std_logic_vector(32 - 1 downto 0);
+ signal ce_r : std_logic;
+ signal dout_i : std_logic_vector(32 - 1 downto 0);
+ signal dout_r : std_logic_vector(32 - 1 downto 0);
+begin
+ --------------------- Instantiation -----------------
+ mulf_vitis_hls_single_precision_lat_4_u : entity work.mulf_vitis_hls_single_precision_lat_4
+ port map (
+ aclk => aclk,
+ aclken => aclken,
+ s_axis_a_tvalid => a_tvalid,
+ s_axis_a_tdata => a_tdata,
+ s_axis_b_tvalid => b_tvalid,
+ s_axis_b_tdata => b_tdata,
+ m_axis_result_tvalid => r_tvalid,
+ m_axis_result_tdata => r_tdata
+ );
+
+ --------------------- Assignment --------------------
+ aclk <= clk;
+ aclken <= ce_r;
+ a_tvalid <= '1';
+ a_tdata <= din0_buf1;
+ b_tvalid <= '1';
+ b_tdata <= din1_buf1;
+ dout_i <= r_tdata;
+
+ --------------------- Input buffer ------------------
+ process (clk) begin
+ if clk'event and clk = '1' then
+ if ce = '1' then
+ din0_buf1 <= din0;
+ din1_buf1 <= din1;
+ end if;
+ end if;
+ end process;
+
+ process (clk) begin
+ if clk'event and clk = '1' then
+ ce_r <= ce;
+ end if;
+ end process;
+
+ process (clk) begin
+ if clk'event and clk = '1' then
+ if ce_r = '1' then
+ dout_r <= dout_i;
+ end if;
+ end if;
+ end process;
+
+ dout <= dout_i when ce_r = '1' else dout_r;
+end architecture;
+
+-- (c) Copyright 1995-2019 Xilinx, Inc. All rights reserved.
+--
+-- This file contains confidential and proprietary information
+-- of Xilinx, Inc. and is protected under U.S. and
+-- international copyright and other intellectual property
+-- laws.
+--
+-- DISCLAIMER
+-- This disclaimer is not a license and does not grant any
+-- rights to the materials distributed herewith. Except as
+-- otherwise provided in a valid license issued to you by
+-- Xilinx, and to the maximum extent permitted by applicable
+-- law: (1) THESE MATERIALS ARE MADE AVAILABLE "AS IS" AND
+-- WITH ALL FAULTS, AND XILINX HEREBY DISCLAIMS ALL WARRANTIES
+-- AND CONDITIONS, EXPRESS, IMPLIED, OR STATUTORY, INCLUDING
+-- BUT NOT LIMITED TO WARRANTIES OF MERCHANTABILITY, NON-
+-- INFRINGEMENT, OR FITNESS FOR ANY PARTICULAR PURPOSE; and
+-- (2) Xilinx shall not be liable (whether in contract or tort,
+-- including negligence, or under any other theory of
+-- liability) for any loss or damage of any kind or nature
+-- related to, arising under or in connection with these
+-- materials, including for any direct, or any indirect,
+-- special, incidental, or consequential loss or damage
+-- (including loss of data, profits, goodwill, or any type of
+-- loss or damage suffered as a result of any action brought
+-- by a third party) even if such damage or loss was
+-- reasonably foreseeable or Xilinx had been advised of the
+-- possibility of the same.
+--
+-- CRITICAL APPLICATIONS
+-- Xilinx products are not designed or intended to be fail-
+-- safe, or for use in any application requiring fail-safe
+-- performance, such as life-support or safety devices or
+-- systems, Class III medical devices, nuclear facilities,
+-- applications related to the deployment of airbags, or any
+-- other applications that could lead to death, personal
+-- injury, or severe property or environmental damage
+-- (individually and collectively, "Critical
+-- Applications"). Customer assumes the sole risk and
+-- liability of any use of Xilinx products in Critical
+-- Applications, subject only to applicable laws and
+-- regulations governing limitations on product liability.
+--
+-- THIS COPYRIGHT NOTICE AND DISCLAIMER MUST BE RETAINED AS
+-- PART OF THIS FILE AT ALL TIMES.
+--
+-- DO NOT MODIFY THIS FILE.
+
+-- IP VLNV: xilinx.com:ip:floating_point:7.1
+-- IP Revision: 8
+
+LIBRARY ieee;
+USE ieee.std_logic_1164.ALL;
+USE ieee.numeric_std.ALL;
+
+LIBRARY floating_point_v7_1_8;
+USE floating_point_v7_1_8.floating_point_v7_1_8;
+
+ENTITY subf_vitis_hls_single_precision_lat_8 IS
+ PORT (
+ aclk : IN STD_LOGIC;
+ aclken : IN STD_LOGIC;
+ s_axis_a_tvalid : IN STD_LOGIC;
+ s_axis_a_tdata : IN STD_LOGIC_VECTOR(31 DOWNTO 0);
+ s_axis_b_tvalid : IN STD_LOGIC;
+ s_axis_b_tdata : IN STD_LOGIC_VECTOR(31 DOWNTO 0);
+ m_axis_result_tvalid : OUT STD_LOGIC;
+ m_axis_result_tdata : OUT STD_LOGIC_VECTOR(31 DOWNTO 0)
+ );
+END subf_vitis_hls_single_precision_lat_8;
+
+ARCHITECTURE subf_vitis_hls_single_precision_lat_8_arch OF subf_vitis_hls_single_precision_lat_8 IS
+ ATTRIBUTE DowngradeIPIdentifiedWarnings : STRING;
+ ATTRIBUTE DowngradeIPIdentifiedWarnings OF subf_vitis_hls_single_precision_lat_8_arch: ARCHITECTURE IS "yes";
+ COMPONENT floating_point_v7_1_8 IS
+ GENERIC (
+ C_XDEVICEFAMILY : STRING;
+ C_HAS_ADD : INTEGER;
+ C_HAS_SUBTRACT : INTEGER;
+ C_HAS_MULTIPLY : INTEGER;
+ C_HAS_DIVIDE : INTEGER;
+ C_HAS_SQRT : INTEGER;
+ C_HAS_COMPARE : INTEGER;
+ C_HAS_FIX_TO_FLT : INTEGER;
+ C_HAS_FLT_TO_FIX : INTEGER;
+ C_HAS_FLT_TO_FLT : INTEGER;
+ C_HAS_RECIP : INTEGER;
+ C_HAS_RECIP_SQRT : INTEGER;
+ C_HAS_ABSOLUTE : INTEGER;
+ C_HAS_LOGARITHM : INTEGER;
+ C_HAS_EXPONENTIAL : INTEGER;
+ C_HAS_FMA : INTEGER;
+ C_HAS_FMS : INTEGER;
+ C_HAS_UNFUSED_MULTIPLY_ADD : INTEGER;
+ C_HAS_UNFUSED_MULTIPLY_SUB : INTEGER;
+ C_HAS_UNFUSED_MULTIPLY_ACCUMULATOR_A : INTEGER;
+ C_HAS_UNFUSED_MULTIPLY_ACCUMULATOR_S : INTEGER;
+ C_HAS_ACCUMULATOR_A : INTEGER;
+ C_HAS_ACCUMULATOR_S : INTEGER;
+ C_HAS_ACCUMULATOR_PRIMITIVE_A : INTEGER;
+ C_HAS_ACCUMULATOR_PRIMITIVE_S : INTEGER;
+ C_A_WIDTH : INTEGER;
+ C_A_FRACTION_WIDTH : INTEGER;
+ C_B_WIDTH : INTEGER;
+ C_B_FRACTION_WIDTH : INTEGER;
+ C_C_WIDTH : INTEGER;
+ C_C_FRACTION_WIDTH : INTEGER;
+ C_RESULT_WIDTH : INTEGER;
+ C_RESULT_FRACTION_WIDTH : INTEGER;
+ C_COMPARE_OPERATION : INTEGER;
+ C_LATENCY : INTEGER;
+ C_OPTIMIZATION : INTEGER;
+ C_MULT_USAGE : INTEGER;
+ C_BRAM_USAGE : INTEGER;
+ C_RATE : INTEGER;
+ C_ACCUM_INPUT_MSB : INTEGER;
+ C_ACCUM_MSB : INTEGER;
+ C_ACCUM_LSB : INTEGER;
+ C_HAS_UNDERFLOW : INTEGER;
+ C_HAS_OVERFLOW : INTEGER;
+ C_HAS_INVALID_OP : INTEGER;
+ C_HAS_DIVIDE_BY_ZERO : INTEGER;
+ C_HAS_ACCUM_OVERFLOW : INTEGER;
+ C_HAS_ACCUM_INPUT_OVERFLOW : INTEGER;
+ C_HAS_ACLKEN : INTEGER;
+ C_HAS_ARESETN : INTEGER;
+ C_THROTTLE_SCHEME : INTEGER;
+ C_HAS_A_TUSER : INTEGER;
+ C_HAS_A_TLAST : INTEGER;
+ C_HAS_B : INTEGER;
+ C_HAS_B_TUSER : INTEGER;
+ C_HAS_B_TLAST : INTEGER;
+ C_HAS_C : INTEGER;
+ C_HAS_C_TUSER : INTEGER;
+ C_HAS_C_TLAST : INTEGER;
+ C_HAS_OPERATION : INTEGER;
+ C_HAS_OPERATION_TUSER : INTEGER;
+ C_HAS_OPERATION_TLAST : INTEGER;
+ C_HAS_RESULT_TUSER : INTEGER;
+ C_HAS_RESULT_TLAST : INTEGER;
+ C_TLAST_RESOLUTION : INTEGER;
+ C_A_TDATA_WIDTH : INTEGER;
+ C_A_TUSER_WIDTH : INTEGER;
+ C_B_TDATA_WIDTH : INTEGER;
+ C_B_TUSER_WIDTH : INTEGER;
+ C_C_TDATA_WIDTH : INTEGER;
+ C_C_TUSER_WIDTH : INTEGER;
+ C_OPERATION_TDATA_WIDTH : INTEGER;
+ C_OPERATION_TUSER_WIDTH : INTEGER;
+ C_RESULT_TDATA_WIDTH : INTEGER;
+ C_RESULT_TUSER_WIDTH : INTEGER;
+ C_FIXED_DATA_UNSIGNED : INTEGER
+ );
+ PORT (
+ aclk : IN STD_LOGIC;
+ aclken : IN STD_LOGIC;
+ aresetn : IN STD_LOGIC;
+ s_axis_a_tvalid : IN STD_LOGIC;
+ s_axis_a_tready : OUT STD_LOGIC;
+ s_axis_a_tdata : IN STD_LOGIC_VECTOR(31 DOWNTO 0);
+ s_axis_a_tuser : IN STD_LOGIC_VECTOR(0 DOWNTO 0);
+ s_axis_a_tlast : IN STD_LOGIC;
+ s_axis_b_tvalid : IN STD_LOGIC;
+ s_axis_b_tready : OUT STD_LOGIC;
+ s_axis_b_tdata : IN STD_LOGIC_VECTOR(31 DOWNTO 0);
+ s_axis_b_tuser : IN STD_LOGIC_VECTOR(0 DOWNTO 0);
+ s_axis_b_tlast : IN STD_LOGIC;
+ s_axis_c_tvalid : IN STD_LOGIC;
+ s_axis_c_tready : OUT STD_LOGIC;
+ s_axis_c_tdata : IN STD_LOGIC_VECTOR(31 DOWNTO 0);
+ s_axis_c_tuser : IN STD_LOGIC_VECTOR(0 DOWNTO 0);
+ s_axis_c_tlast : IN STD_LOGIC;
+ s_axis_operation_tvalid : IN STD_LOGIC;
+ s_axis_operation_tready : OUT STD_LOGIC;
+ s_axis_operation_tdata : IN STD_LOGIC_VECTOR(7 DOWNTO 0);
+ s_axis_operation_tuser : IN STD_LOGIC_VECTOR(0 DOWNTO 0);
+ s_axis_operation_tlast : IN STD_LOGIC;
+ m_axis_result_tvalid : OUT STD_LOGIC;
+ m_axis_result_tready : IN STD_LOGIC;
+ m_axis_result_tdata : OUT STD_LOGIC_VECTOR(31 DOWNTO 0);
+ m_axis_result_tuser : OUT STD_LOGIC_VECTOR(0 DOWNTO 0);
+ m_axis_result_tlast : OUT STD_LOGIC
+ );
+ END COMPONENT floating_point_v7_1_8;
+ ATTRIBUTE X_INTERFACE_INFO : STRING;
+ ATTRIBUTE X_INTERFACE_PARAMETER : STRING;
+ ATTRIBUTE X_INTERFACE_INFO OF m_axis_result_tdata: SIGNAL IS "xilinx.com:interface:axis:1.0 M_AXIS_RESULT TDATA";
+ ATTRIBUTE X_INTERFACE_PARAMETER OF m_axis_result_tvalid: SIGNAL IS "XIL_INTERFACENAME M_AXIS_RESULT, TDATA_NUM_BYTES 4, TDEST_WIDTH 0, TID_WIDTH 0, TUSER_WIDTH 0, HAS_TREADY 0, HAS_TSTRB 0, HAS_TKEEP 0, HAS_TLAST 0, FREQ_HZ 100000000, PHASE 0.000, LAYERED_METADATA undef, INSERT_VIP 0";
+ ATTRIBUTE X_INTERFACE_INFO OF m_axis_result_tvalid: SIGNAL IS "xilinx.com:interface:axis:1.0 M_AXIS_RESULT TVALID";
+ ATTRIBUTE X_INTERFACE_INFO OF s_axis_b_tdata: SIGNAL IS "xilinx.com:interface:axis:1.0 S_AXIS_B TDATA";
+ ATTRIBUTE X_INTERFACE_PARAMETER OF s_axis_b_tvalid: SIGNAL IS "XIL_INTERFACENAME S_AXIS_B, TDATA_NUM_BYTES 4, TDEST_WIDTH 0, TID_WIDTH 0, TUSER_WIDTH 0, HAS_TREADY 0, HAS_TSTRB 0, HAS_TKEEP 0, HAS_TLAST 0, FREQ_HZ 100000000, PHASE 0.000, LAYERED_METADATA undef, INSERT_VIP 0";
+ ATTRIBUTE X_INTERFACE_INFO OF s_axis_b_tvalid: SIGNAL IS "xilinx.com:interface:axis:1.0 S_AXIS_B TVALID";
+ ATTRIBUTE X_INTERFACE_INFO OF s_axis_a_tdata: SIGNAL IS "xilinx.com:interface:axis:1.0 S_AXIS_A TDATA";
+ ATTRIBUTE X_INTERFACE_PARAMETER OF s_axis_a_tvalid: SIGNAL IS "XIL_INTERFACENAME S_AXIS_A, TDATA_NUM_BYTES 4, TDEST_WIDTH 0, TID_WIDTH 0, TUSER_WIDTH 0, HAS_TREADY 0, HAS_TSTRB 0, HAS_TKEEP 0, HAS_TLAST 0, FREQ_HZ 100000000, PHASE 0.000, LAYERED_METADATA undef, INSERT_VIP 0";
+ ATTRIBUTE X_INTERFACE_INFO OF s_axis_a_tvalid: SIGNAL IS "xilinx.com:interface:axis:1.0 S_AXIS_A TVALID";
+ ATTRIBUTE X_INTERFACE_PARAMETER OF aclken: SIGNAL IS "XIL_INTERFACENAME aclken_intf, POLARITY ACTIVE_LOW";
+ ATTRIBUTE X_INTERFACE_INFO OF aclken: SIGNAL IS "xilinx.com:signal:clockenable:1.0 aclken_intf CE";
+ ATTRIBUTE X_INTERFACE_PARAMETER OF aclk: SIGNAL IS "XIL_INTERFACENAME aclk_intf, ASSOCIATED_BUSIF S_AXIS_OPERATION:M_AXIS_RESULT:S_AXIS_C:S_AXIS_B:S_AXIS_A, ASSOCIATED_RESET aresetn, ASSOCIATED_CLKEN aclken, FREQ_HZ 10000000, PHASE 0.000, INSERT_VIP 0";
+ ATTRIBUTE X_INTERFACE_INFO OF aclk: SIGNAL IS "xilinx.com:signal:clock:1.0 aclk_intf CLK";
+BEGIN
+ U0 : floating_point_v7_1_8
+ GENERIC MAP (
+ C_XDEVICEFAMILY => "kintex7",
+ C_HAS_ADD => 0,
+ C_HAS_SUBTRACT => 1,
+ C_HAS_MULTIPLY => 0,
+ C_HAS_DIVIDE => 0,
+ C_HAS_SQRT => 0,
+ C_HAS_COMPARE => 0,
+ C_HAS_FIX_TO_FLT => 0,
+ C_HAS_FLT_TO_FIX => 0,
+ C_HAS_FLT_TO_FLT => 0,
+ C_HAS_RECIP => 0,
+ C_HAS_RECIP_SQRT => 0,
+ C_HAS_ABSOLUTE => 0,
+ C_HAS_LOGARITHM => 0,
+ C_HAS_EXPONENTIAL => 0,
+ C_HAS_FMA => 0,
+ C_HAS_FMS => 0,
+ C_HAS_UNFUSED_MULTIPLY_ADD => 0,
+ C_HAS_UNFUSED_MULTIPLY_SUB => 0,
+ C_HAS_UNFUSED_MULTIPLY_ACCUMULATOR_A => 0,
+ C_HAS_UNFUSED_MULTIPLY_ACCUMULATOR_S => 0,
+ C_HAS_ACCUMULATOR_A => 0,
+ C_HAS_ACCUMULATOR_S => 0,
+ C_HAS_ACCUMULATOR_PRIMITIVE_A => 0,
+ C_HAS_ACCUMULATOR_PRIMITIVE_S => 0,
+ C_A_WIDTH => 32,
+ C_A_FRACTION_WIDTH => 24,
+ C_B_WIDTH => 32,
+ C_B_FRACTION_WIDTH => 24,
+ C_C_WIDTH => 32,
+ C_C_FRACTION_WIDTH => 24,
+ C_RESULT_WIDTH => 32,
+ C_RESULT_FRACTION_WIDTH => 24,
+ C_COMPARE_OPERATION => 8,
+ C_LATENCY => 8,
+ C_OPTIMIZATION => 1,
+ C_MULT_USAGE => 2,
+ C_BRAM_USAGE => 0,
+ C_RATE => 1,
+ C_ACCUM_INPUT_MSB => 32,
+ C_ACCUM_MSB => 32,
+ C_ACCUM_LSB => -31,
+ C_HAS_UNDERFLOW => 0,
+ C_HAS_OVERFLOW => 0,
+ C_HAS_INVALID_OP => 0,
+ C_HAS_DIVIDE_BY_ZERO => 0,
+ C_HAS_ACCUM_OVERFLOW => 0,
+ C_HAS_ACCUM_INPUT_OVERFLOW => 0,
+ C_HAS_ACLKEN => 1,
+ C_HAS_ARESETN => 0,
+ C_THROTTLE_SCHEME => 3,
+ C_HAS_A_TUSER => 0,
+ C_HAS_A_TLAST => 0,
+ C_HAS_B => 1,
+ C_HAS_B_TUSER => 0,
+ C_HAS_B_TLAST => 0,
+ C_HAS_C => 0,
+ C_HAS_C_TUSER => 0,
+ C_HAS_C_TLAST => 0,
+ C_HAS_OPERATION => 0,
+ C_HAS_OPERATION_TUSER => 0,
+ C_HAS_OPERATION_TLAST => 0,
+ C_HAS_RESULT_TUSER => 0,
+ C_HAS_RESULT_TLAST => 0,
+ C_TLAST_RESOLUTION => 0,
+ C_A_TDATA_WIDTH => 32,
+ C_A_TUSER_WIDTH => 1,
+ C_B_TDATA_WIDTH => 32,
+ C_B_TUSER_WIDTH => 1,
+ C_C_TDATA_WIDTH => 32,
+ C_C_TUSER_WIDTH => 1,
+ C_OPERATION_TDATA_WIDTH => 8,
+ C_OPERATION_TUSER_WIDTH => 1,
+ C_RESULT_TDATA_WIDTH => 32,
+ C_RESULT_TUSER_WIDTH => 1,
+ C_FIXED_DATA_UNSIGNED => 0
+ )
+ PORT MAP (
+ aclk => aclk,
+ aclken => aclken,
+ aresetn => '1',
+ s_axis_a_tvalid => s_axis_a_tvalid,
+ s_axis_a_tdata => s_axis_a_tdata,
+ s_axis_a_tuser => STD_LOGIC_VECTOR(TO_UNSIGNED(0, 1)),
+ s_axis_a_tlast => '0',
+ s_axis_b_tvalid => s_axis_b_tvalid,
+ s_axis_b_tdata => s_axis_b_tdata,
+ s_axis_b_tuser => STD_LOGIC_VECTOR(TO_UNSIGNED(0, 1)),
+ s_axis_b_tlast => '0',
+ s_axis_c_tvalid => '0',
+ s_axis_c_tdata => STD_LOGIC_VECTOR(TO_UNSIGNED(0, 32)),
+ s_axis_c_tuser => STD_LOGIC_VECTOR(TO_UNSIGNED(0, 1)),
+ s_axis_c_tlast => '0',
+ s_axis_operation_tvalid => '0',
+ s_axis_operation_tdata => STD_LOGIC_VECTOR(TO_UNSIGNED(0, 8)),
+ s_axis_operation_tuser => STD_LOGIC_VECTOR(TO_UNSIGNED(0, 1)),
+ s_axis_operation_tlast => '0',
+ m_axis_result_tvalid => m_axis_result_tvalid,
+ m_axis_result_tready => '0',
+ m_axis_result_tdata => m_axis_result_tdata
+ );
+END subf_vitis_hls_single_precision_lat_8_arch;
+
+
+-- ==============================================================
+-- Vivado(TM) HLS - High-Level Synthesis from C, C++ and SystemC v2019.2.1 (64-bit)
+-- Copyright 1986-2019 Xilinx, Inc. All Rights Reserved.
+-- ==============================================================
+Library ieee;
+use ieee.std_logic_1164.all;
+
+entity subf_vitis_hls_wrapper is
+ port (
+ clk : in std_logic;
+ reset : in std_logic;
+ ce : in std_logic;
+ din0 : in std_logic_vector(32 - 1 downto 0);
+ din1 : in std_logic_vector(32 - 1 downto 0);
+ dout : out std_logic_vector(32 - 1 downto 0)
+ );
+end entity;
+
+architecture arch of subf_vitis_hls_wrapper is
+ --------------------- Local signals ------------------
+ signal aclk : std_logic;
+ signal aclken : std_logic;
+ signal a_tvalid : std_logic;
+ signal a_tdata : std_logic_vector(32 - 1 downto 0);
+ signal b_tvalid : std_logic;
+ signal b_tdata : std_logic_vector(32 - 1 downto 0);
+ signal r_tvalid : std_logic;
+ signal r_tdata : std_logic_vector(32 - 1 downto 0);
+ signal din0_buf1 : std_logic_vector(32 - 1 downto 0);
+ signal din1_buf1 : std_logic_vector(32 - 1 downto 0);
+ signal ce_r : std_logic;
+ signal dout_i : std_logic_vector(32 - 1 downto 0);
+ signal dout_r : std_logic_vector(32 - 1 downto 0);
+begin
+ --------------------- Instantiation -----------------
+ subf_vitis_hls_single_precision_lat_8_u : entity work.subf_vitis_hls_single_precision_lat_8
+ port map (
+ aclk => aclk,
+ aclken => aclken,
+ s_axis_a_tvalid => a_tvalid,
+ s_axis_a_tdata => a_tdata,
+ s_axis_b_tvalid => b_tvalid,
+ s_axis_b_tdata => b_tdata,
+ m_axis_result_tvalid => r_tvalid,
+ m_axis_result_tdata => r_tdata
+ );
+
+ --------------------- Assignment --------------------
+ aclk <= clk;
+ aclken <= ce_r;
+ a_tvalid <= '1';
+ a_tdata <= din0_buf1;
+ b_tvalid <= '1';
+ b_tdata <= din1_buf1;
+ dout_i <= r_tdata;
+
+ --------------------- Input buffer ------------------
+ process (clk) begin
+ if clk'event and clk = '1' then
+ if ce = '1' then
+ din0_buf1 <= din0;
+ din1_buf1 <= din1;
+ end if;
+ end if;
+ end process;
+
+ process (clk) begin
+ if clk'event and clk = '1' then
+ ce_r <= ce;
+ end if;
+ end process;
+
+ process (clk) begin
+ if clk'event and clk = '1' then
+ if ce_r = '1' then
+ dout_r <= dout_i;
+ end if;
+ end if;
+ end process;
+
+ dout <= dout_i when ce_r = '1' else dout_r;
+end architecture;
+
+-- ==============================================================
+-- Generated by Vitis HLS v2024.2.2
+-- Copyright 1986-2022 Xilinx, Inc. All Rights Reserved.
+-- Copyright 2022-2025 Advanced Micro Devices, Inc. All Rights Reserved.
+-- ==============================================================
+
+library ieee;
+use ieee.std_logic_1164.all;
+use ieee.numeric_std.all;
+
+entity sdiv_32ns_32ns_32_36_seq_1_divseq is
+ port (
+ clk : in std_logic;
+ reset : in std_logic;
+ ce : in std_logic;
+ dividend : in std_logic_vector(32 - 1 downto 0);
+ divisor : in std_logic_vector(32 - 1 downto 0);
+ sign_i : in std_logic_vector(1 downto 0);
+ sign_o : out std_logic_vector(1 downto 0);
+ quot : out std_logic_vector(32 - 1 downto 0);
+ remd : out std_logic_vector(32 - 1 downto 0));
+end entity;
+
+architecture arch of sdiv_32ns_32ns_32_36_seq_1_divseq is
+ signal dividend0 : unsigned(32 - 1 downto 0);
+ signal divisor0 : unsigned(32 - 1 downto 0);
+ signal sign0 : unsigned(1 downto 0);
+ signal dividend_reg : unsigned(32 - 1 downto 0);
+ signal remd_reg : unsigned(32 - 1 downto 0);
+ signal comb_tmp : unsigned(32 - 1 downto 0);
+ signal cal_tmp : unsigned(32 downto 0);
+begin
+ quot <= std_logic_vector(resize(dividend_reg, 32));
+ remd <= std_logic_vector(resize(remd_reg, 32));
+ sign_o <= std_logic_vector(sign0);
+
+ process (clk)
+ begin
+ if rising_edge(clk) then
+ dividend0 <= unsigned(dividend);
+ divisor0 <= unsigned(divisor);
+ sign0 <= unsigned(sign_i);
+ end if;
+ end process;
+
+ comb_tmp <= remd_reg(32 - 2 downto 0) & dividend_reg(32 - 1);
+ cal_tmp <= ('0' & comb_tmp) - ('0' & divisor0);
+
+ process (clk)
+ begin
+ if rising_edge(clk) then
+ if ce = '1' then
+ dividend_reg <= dividend_reg(32 - 2 downto 0) & (not cal_tmp(32));
+ if cal_tmp(32) = '1' then
+ remd_reg <= comb_tmp;
+ else
+ remd_reg <= cal_tmp(32 - 1 downto 0);
+ end if;
+ end if;
+ end if;
+ end process;
+end architecture;
+
+library ieee;
+use ieee.std_logic_1164.all;
+use ieee.numeric_std.all;
+
+-- ==============================================================
+-- Generated by Vitis HLS v2024.2.2
+-- Copyright 1986-2022 Xilinx, Inc. All Rights Reserved.
+-- Copyright 2022-2025 Advanced Micro Devices, Inc. All Rights Reserved.
+-- ==============================================================
+
+
+entity divsi_vitis_hls_wrapper is
+ port (
+ clk : in STD_LOGIC;
+ reset : in STD_LOGIC;
+ ce : in STD_LOGIC;
+ din0 : in STD_LOGIC_VECTOR(32 - 1 downto 0);
+ din1 : in STD_LOGIC_VECTOR(32 - 1 downto 0);
+ dout : out STD_LOGIC_VECTOR(32 - 1 downto 0));
+end entity;
+
+architecture arch of divsi_vitis_hls_wrapper is
+ signal dividend0 : STD_LOGIC_VECTOR(32 - 1 downto 0);
+ signal divisor0 : STD_LOGIC_VECTOR(32 - 1 downto 0);
+ signal dividend_u : STD_LOGIC_VECTOR(32 - 1 downto 0);
+ signal divisor_u : STD_LOGIC_VECTOR(32 - 1 downto 0);
+ signal quot_u : STD_LOGIC_VECTOR(32 - 1 downto 0);
+ signal remd_u : STD_LOGIC_VECTOR(32 - 1 downto 0);
+ signal quot : STD_LOGIC_VECTOR(32 - 1 downto 0);
+ signal remd : STD_LOGIC_VECTOR(32 - 1 downto 0);
+ signal sign_i : STD_LOGIC_VECTOR(1 downto 0);
+ signal sign_o : STD_LOGIC_VECTOR(1 downto 0);
+begin
+ sdiv_32ns_32ns_32_36_seq_1_divseq_u : entity work.sdiv_32ns_32ns_32_36_seq_1_divseq
+ port map(
+ clk => clk,
+ reset => reset,
+ ce => ce,
+ dividend => dividend_u,
+ divisor => divisor_u,
+ sign_i => sign_i,
+ sign_o => sign_o,
+ quot => quot_u,
+ remd => remd_u);
+
+ sign_i <= (dividend0(32-1) xor divisor0(32-1)) & dividend0(32-1);
+ dividend_u <= STD_LOGIC_VECTOR(UNSIGNED(not dividend0) + 1) when dividend0(32-1) = '1' else dividend0;
+ divisor_u <= STD_LOGIC_VECTOR(UNSIGNED(not divisor0) + 1) when divisor0(32-1) = '1' else divisor0;
+
+process (clk)
+begin
+ if (clk'event and clk = '1') then
+ dividend0 <= din0;
+ divisor0 <= din1;
+
+ if (sign_o(1) = '1') then
+ quot <= STD_LOGIC_VECTOR(UNSIGNED(not quot_u) + 1);
+ remd <= STD_LOGIC_VECTOR(UNSIGNED(not remd_u) + 1);
+ else
+ quot <= quot_u;
+ remd <= remd_u;
+ end if;
+ end if;
+end process;
+
+dout <= quot;
+
+end architecture;
+
+
+-- ==============================================================
+-- Vivado(TM) HLS - High-Level Synthesis from C, C++ and SystemC v2019.2.1 (64-bit)
+-- Copyright 1986-2019 Xilinx, Inc. All Rights Reserved.
+-- ==============================================================
+Library ieee;
+use ieee.std_logic_1164.all;
+
+entity divui_vitis_hls_wrapper is
+ port (
+ clk : in std_logic;
+ reset : in std_logic;
+ ce : in std_logic;
+ din0 : in std_logic_vector(32 - 1 downto 0);
+ din1 : in std_logic_vector(32 - 1 downto 0);
+ dout : out std_logic_vector(32 - 1 downto 0)
+ );
+end entity;
+
+architecture arch of divui_vitis_hls_wrapper is
+ component array_RAM_udiv_32ns_32ns_32_36_1 is
+ generic (
+ ID : integer;
+ NUM_STAGE : integer;
+ din0_TYPE : integer;
+ din1_TYPE : integer;
+ dout_TYPE : integer);
+ port (
+ clk : in std_logic;
+ reset : in std_logic;
+ ce : in std_logic;
+ din0 : in std_logic_vector(din0_TYPE - 1 downto 0);
+ din1 : in std_logic_vector(din1_TYPE - 1 downto 0);
+ dout : out std_logic_vector(dout_TYPE - 1 downto 0));
+ end component;
+begin
+ --------------------- Instantiation -----------------
+ array_RAM_udiv_32ns_32ns_32_36_1_U1 : component array_RAM_udiv_32ns_32ns_32_36_1
+ generic map(
+ ID => 1,
+ NUM_STAGE => 36,
+ din0_TYPE => 32,
+ din1_TYPE => 32,
+ dout_TYPE => 32)
+ port map(
+ clk => clk,
+ reset => reset,
+ ce => ce,
+ din0 => din0,
+ din1 => din1,
+ dout => dout
+ );
+end architecture;
+
+-- ==============================================================
+-- Generated by Vitis HLS v2024.2.2
+-- Copyright 1986-2022 Xilinx, Inc. All Rights Reserved.
+-- Copyright 2022-2025 Advanced Micro Devices, Inc. All Rights Reserved.
+-- ==============================================================
+
+library ieee;
+use ieee.std_logic_1164.all;
+use ieee.numeric_std.all;
+
+entity remsi_vitis_hls_wrapper is
+ port (
+ clk : in STD_LOGIC;
+ reset : in STD_LOGIC;
+ ce : in STD_LOGIC;
+ din0 : in STD_LOGIC_VECTOR(32 - 1 downto 0);
+ din1 : in STD_LOGIC_VECTOR(32 - 1 downto 0);
+ dout : out STD_LOGIC_VECTOR(32 - 1 downto 0));
+end entity;
+
+architecture arch of divsi_vitis_hls_wrapper is
+ component sdiv_32ns_32ns_32_36_seq_1_divseq is
+ port (
+ reset : in STD_LOGIC;
+ clk : in STD_LOGIC;
+ ce : in STD_LOGIC;
+ dividend : in STD_LOGIC_VECTOR(32 - 1 downto 0);
+ divisor : in STD_LOGIC_VECTOR(32 - 1 downto 0);
+ sign_i : in STD_LOGIC_VECTOR(1 downto 0);
+ sign_o : out STD_LOGIC_VECTOR(1 downto 0);
+ quot : out STD_LOGIC_VECTOR(32 - 1 downto 0);
+ remd : out STD_LOGIC_VECTOR(32 - 1 downto 0));
+ end component;
+
+ signal dividend0 : STD_LOGIC_VECTOR(32 - 1 downto 0);
+ signal divisor0 : STD_LOGIC_VECTOR(32 - 1 downto 0);
+ signal dividend_u : STD_LOGIC_VECTOR(32 - 1 downto 0);
+ signal divisor_u : STD_LOGIC_VECTOR(32 - 1 downto 0);
+ signal quot_u : STD_LOGIC_VECTOR(32 - 1 downto 0);
+ signal remd_u : STD_LOGIC_VECTOR(32 - 1 downto 0);
+ signal quot : STD_LOGIC_VECTOR(32 - 1 downto 0);
+ signal remd : STD_LOGIC_VECTOR(32 - 1 downto 0);
+ signal sign_i : STD_LOGIC_VECTOR(1 downto 0);
+ signal sign_o : STD_LOGIC_VECTOR(1 downto 0);
+begin
+ sdiv_32ns_32ns_32_36_seq_1_divseq_u : entity work.sdiv_32ns_32ns_32_36_seq_1_divseq
+ port map(
+ clk => clk,
+ reset => reset,
+ ce => ce,
+ dividend => dividend_u,
+ divisor => divisor_u,
+ sign_i => sign_i,
+ sign_o => sign_o,
+ quot => quot_u,
+ remd => remd_u);
+
+ sign_i <= (dividend0(32-1) xor divisor0(32-1)) & dividend0(32-1);
+ dividend_u <= STD_LOGIC_VECTOR(UNSIGNED(not dividend0) + 1) when dividend0(32-1) = '1' else dividend0;
+ divisor_u <= STD_LOGIC_VECTOR(UNSIGNED(not divisor0) + 1) when divisor0(32-1) = '1' else divisor0;
+
+process (clk)
+begin
+ if (clk'event and clk = '1') then
+ dividend0 <= din0;
+ divisor0 <= din1;
+
+ if (sign_o(1) = '1') then
+ quot <= STD_LOGIC_VECTOR(UNSIGNED(not quot_u) + 1);
+ remd <= STD_LOGIC_VECTOR(UNSIGNED(not remd_u) + 1);
+ else
+ quot <= quot_u;
+ remd <= remd_u;
+ end if;
+ end if;
+end process;
+
+dout <= remd;
+
+end architecture;
diff --git a/docs/DeveloperGuide/CompilerIntrinsics/BetaBackend.md b/docs/DeveloperGuide/CompilerIntrinsics/BetaBackend.md
new file mode 100644
index 0000000000..8f36448724
--- /dev/null
+++ b/docs/DeveloperGuide/CompilerIntrinsics/BetaBackend.md
@@ -0,0 +1,152 @@
+# Beta Backend
+
+The beta backend is a re-development of the system used to transform the external modules of the Hardware IR into concrete RTL units. (More information about the Hardware IR can be found in the [backend documentation](https://github.com/EPFL-LAP/dynamatic/blob/main/docs/DeveloperGuide/CompilerIntrinsics/Backend.md)).
+
+How we emit the RTL units is far from a complete, finished product, but this document details the reasons behind each decision, including both positive and negative consequences.
+
+## How Dynamatic Calls the Beta Backend
+### Background
+
+To use the beta backend requires knowledge of some aspects of how Dynamatic compiles from the Handshake IR down to RTL, and so this is first discussed:
+
+#### Handshake IR
+
+In the Handshake IR, there are many types of operations, declared in [HandshakeOps.td](https://github.com/EPFL-LAP/dynamatic/blob/main/include/dynamatic/Dialect/Handshake/HandshakeOps.td) or [HandshakeArithOps.td](https://github.com/EPFL-LAP/dynamatic/blob/main/include/dynamatic/Dialect/Handshake/HandshakeArithOps.td). These operations become C++ classes, which provide many useful member functions and member variables. Each operation defines how it can be added to the IR (through [MLIR builders](https://mlir.llvm.org/docs/DefiningDialects/Operations/#builder-methods)), as well how it should be verified (both its own member variables, as well as verification of its input operands and output results).
+
+Each Handshake operation is fully self-contained: all information about the operation is stored in the operation, and the operation knows nothing about other operations.
+
+
+#### Hardware IR
+
+During compilation, the Handshake IR is lowered to the Hardware IR.
+
+RTL languages are based on a pattern of "definition" and "instances". The "definition" contains all information about an object in one place, and many "instances" can share this information by containing a reference to their corresponding definition.
+
+The Hardware IR aims to replicate this pattern inside the MLIR eco-system. First, a definition is built for each Handshake operations. Then, if two (or more) operations have **exactly identical** definitions, their definitions are merged.
+
+##### ModuleExternOp
+
+Each definition is added to the Hardware IR as a `HWModuleExternOp`(declared in [HWStructure.td](https://github.com/EPFL-LAP/dynamatic/blob/main/include/dynamatic/Dialect/HW/HWStructure.td)), an operation with no inputs or outputs. Any information needed to generate the RTL is stored in this operation, and it can be referenced by multiple instances.
+
+##### InstanceOp
+
+Each original Handshake operation is considered an instance, and so is converted to an `InstanceOp`, (also declared in [HWStructure.td](https://github.com/EPFL-LAP/dynamatic/blob/main/include/dynamatic/Dialect/HW/HWStructure.td)) a generic, (mostly empty) C++ class. Each `InstanceOp` has a reference to the corresponding `HWModuleExternOp`.
+
+This means, in contrast to the Handshake IR, the Hardware IR does not use different C++ classes to represent different operations. There is very little functionality present to analyze or alter the Hardware IR once generated.
+
+Each InstanceOp contains only 3 pieces of information: 1) its unique name, 2) a reference to a `HWExternalModuleOp`, 3) the names of its inputs and outputs.
+
+##### Example
+
+Below the serialized representation of a `ConstantOp` can be seen for both Handshake and Hardware.
+
+
+
+The output of the operation is highlighted in red. The inputs to the operation are highlighted in blue. The C++ class of the operation is highlighted in green. The information the operation contains is highlighted in orange. The type information of the inputs and outputs is highlighted in pink.
+
+In the Handshake IR, the `ConstantOp` contains `value = 30 : i6`, which indicates the value of the constant is a 6-bit integer of value 30.
+
+In the Hardware IR, the `InstanceOp` representing this constant instead has a reference to `@hardware_constant_1`. While all information about the inputs and outputs is present, there is no information about the operation itself (include what type of operation it is).
+
+The `HWModuleExternOp` first contains the value used to reference it, in this case, `@handshake_constant_1`. It then redundantly contains all the input and output name and type information (as this information is also present on all the instances). Finally, after the attributes keywrod, it contains the information shared between the instances which they are missing: in this case, their original operation type (`handshake.constant`), (redundantly) the constant bitwidth (`6`), as well as the constant value (`"011110"`)
+
+
+##### Value
+
+The usefulness of the Hardware IR is unclear: if we simply generated a unique definition for every single Handshake operation, the RTL files would be larger, but the final circuits would be the same. The Hardware IR is serialized very differently to the Handshake IR, which can make them annoying to compare.
+
+While important memory system details are handled in the conversion between Handshake and Hardware, the fact that the printed IR is 1) not alterable or analyzable programatically due to the conversion to `InstanceOp`, and 2) annoying to read, means that its existance as an IR will probably be removed eventually.
+
+### Step 1: Merging Definitions
+
+The first relevant part of compilation is the process of generating `HWModuleExternOp` from all the HandshakeOps. The relevant piece of code is:
+
+https://github.com/EPFL-LAP/dynamatic/blob/aa984a5925706e19fe718cabc05c9874e679dd39/lib/Conversion/HandshakeToHW/HandshakeToHW.cpp#L545-L561
+
+An if statement checks for each type of Handshake operation, and from it builds a dictionary representing the definition. This dictionary will be stored directly on the `HWModuleExternOp`, and a `HWModuleExternOp` is generated for each unique dictionary.
+
+Any value which affects if two Handshake operations should share a `HWModuleExternOp` should be placed in this dictionary inside this if statement.
+
+### Step 2: Additional Information for Generation
+
+The dictionary used to define a `HWModuleExternOp` was not designed with the beta backend in mind, and is unsuitable for directly making RTL generation decisions. This is mainly based on serialization approaches: while the C++ dictionary can contain complex C++ objects, the RTL generation decisions must be encoded as strings.
+
+For this reason, a **second set of if statements exists**, at:
+
+https://github.com/EPFL-LAP/dynamatic/blob/aa984a5925706e19fe718cabc05c9874e679dd39/lib/Support/RTL/RTL.cpp#L284-L291
+
+These if statements are analysis ran on the Hardware IR, which as discussed above cannot really by analyzed. They are therefore extremely fragile. However, they were placed here to minize impact on the default backend during development.
+
+The second set of if statements analyzes the `HWModuleExternOp` dictionary to better format the information for RTL generation. This helps with the goal of keeping the RTL generation as simple as possible: analysis is done on the IR, the beta backend is simply text manipulation.
+
+### Step 3: JSON Files for Parameter Passing
+
+A [json file](https://github.com/EPFL-LAP/dynamatic/blob/main/data/rtl-config-vhdl-beta.json) controls how information passes from the C++ MLIR-based flow to the python text printing logic.
+
+As discussed in the [backend documentation](https://github.com/EPFL-LAP/dynamatic/blob/main/docs/DeveloperGuide/CompilerIntrinsics/Backend.md), the JSON file is relatively powerful. The beta backend uses very few of its features, as it is not quite powerful enough, but this means the syntax can be complex.
+
+An example entry is:
+```
+ {
+ "name": "handshake.addf",
+ "parameters": [
+ {
+ "name": "LATENCY",
+ "type": "unsigned"
+ },
+ {
+ "name": "INTERNAL_DELAY",
+ "type": "string"
+ },
+ {
+ "name": "FPU_IMPL",
+ "type": "string"
+ }
+ ],
+ "generator": "python $DYNAMATIC/experimental/tools/unit-generators/vhdl/vhdl-unit-generator.py -n $MODULE_NAME -o $OUTPUT_DIR/$MODULE_NAME.vhd -t addf -p is_double=$IS_DOUBLE fpu_impl='\"$FPU_IMPL\"' internal_delay='\"$INTERNAL_DELAY\"' latency=$LATENCY extra_signals=$EXTRA_SIGNALS",
+ "dependencies": [
+ "flopoco_ip_cores", "vivado_ip_wrappers"
+ ]
+ },
+```
+
+This entry matches to the `AddFOp` op based on the `name` field.
+
+The three parameters are values from the `HWModuleExternOp` dictionary. The JSON files allows different RTL generation methods to be "matched with" based on the values in the dictionary. Adding these 3 parameters enforces that every `AddFOp` contains these values in their dictionaries for generation, and therefore allows us to pass these values to the python script.
+
+There are parameters in the python call that is not in the `parameters` JSON field. One example is `is_double`. This value is not in the `HWModuleExternOp` dictionary, but was added as further analysis in the second set of if statements, ran on the Hardware IR. Since it is not in the original dictionary, we do not need to "match with" it.
+
+
+### Analysis of How Dynamatic Calls the Beta Backend
+
+This system is very, very messy. Two sets of if statements, JSON matching based on the parameters in the first dictionary but not on the second, analysis on the Hardware IR: these should all be removed.
+
+This is primarily due to Dynamatic's original backend foreseeing that it would generate a lot of the simple units internally, and only generate complex units externally.
+
+However, systems like speculation and taint tracking means that even simple units can have complex RTL generation. There are many many features in the original backend we no longer use, as while they are powerful, they do not give 100% of the functionality required. However, their existance makes the process more complex. The presence of the Hardware IR itself also makes this process more complex.
+
+While pivoting from the Hardware IR is not possible in the immediate future, the goal is to remove both sets of if statements, and the JSON file, relatively soon. Instead interfaces will be used such that each Handshake operation has its own code to build its (correctly serialized) `HWModuleExternOp` dictionary.
+
+## The Beta Backend
+
+The majority of the Beta Backend is very simple: it prints RTL code which is only lightly parameterized.
+
+There are two complex aspects:
+
+### Signal Managers
+
+Speculation. taint tracking, and tagged tokens for multi-threading, require wrappers around core RTL units to deal with tokens that contain more than one payload. These are discussed in detail [here](SignalManager.md)
+
+
+### Arithmetic Units with IP cores
+
+For arithmetic units which have IP cores, the beta backend does not handle the IP cores themselves: these are generated offline, and imported into the synthesis or simulation library unconditonally.
+
+
+However, the beta backend does generate the following wrapper, which is mostly IP agnostic:
+
+
+
+To generate the wrapper, the beta backend needs 2 pieces of information: 1) which ip core to use, and 2) how many slots to place in the valid propagation buffer.
+
+Our IP selection system is both relatively new and imperfect: currently the beta backend may combine several parameters to select an IP core. In future, this should be changed so the entire IP core name is simply passed to the beta backend.
\ No newline at end of file
diff --git a/docs/DeveloperGuide/CompilerIntrinsics/Figures/BetaBackend/hs_vs_hw.png b/docs/DeveloperGuide/CompilerIntrinsics/Figures/BetaBackend/hs_vs_hw.png
new file mode 100644
index 0000000000..81ea8e3fea
Binary files /dev/null and b/docs/DeveloperGuide/CompilerIntrinsics/Figures/BetaBackend/hs_vs_hw.png differ
diff --git a/docs/DeveloperGuide/CompilerIntrinsics/Figures/BetaBackend/ip_wrapper.png b/docs/DeveloperGuide/CompilerIntrinsics/Figures/BetaBackend/ip_wrapper.png
new file mode 100644
index 0000000000..78bf9d168d
Binary files /dev/null and b/docs/DeveloperGuide/CompilerIntrinsics/Figures/BetaBackend/ip_wrapper.png differ
diff --git a/experimental/lib/Transforms/Rigidification/HandshakeRigidification.cpp b/experimental/lib/Transforms/Rigidification/HandshakeRigidification.cpp
index 05a8362349..2858bef5d9 100644
--- a/experimental/lib/Transforms/Rigidification/HandshakeRigidification.cpp
+++ b/experimental/lib/Transforms/Rigidification/HandshakeRigidification.cpp
@@ -116,8 +116,8 @@ HandshakeRigidificationPass::insertValidMerger(ValidEquivalence prop) {
auto newOp = builder.create(loc, ownerChannel,
targetChannel);
- ownerChannel.replaceAllUsesExcept(newOp.getLhs(), newOp);
- targetChannel.replaceAllUsesExcept(newOp.getRhs(), newOp);
+ ownerChannel.replaceAllUsesExcept(newOp.getLhsOut(), newOp);
+ targetChannel.replaceAllUsesExcept(newOp.getRhsOut(), newOp);
return success();
}
diff --git a/experimental/tools/frequency-profiler/Simulator.cpp b/experimental/tools/frequency-profiler/Simulator.cpp
index 6e9981bee7..8b8ae79d5a 100644
--- a/experimental/tools/frequency-profiler/Simulator.cpp
+++ b/experimental/tools/frequency-profiler/Simulator.cpp
@@ -365,6 +365,12 @@ LogicalResult StdExecuter::execute(mlir::arith::DivFOp, std::vector &in,
return success();
}
+LogicalResult StdExecuter::execute(mlir::arith::NegFOp, std::vector &in,
+ std::vector &out) {
+ out[0] = -any_cast(in[0]);
+ return success();
+}
+
LogicalResult StdExecuter::execute(mlir::arith::RemFOp, std::vector &in,
std::vector &out) {
out[0] = any_cast(in[0]).mod(any_cast(in[1]));
@@ -742,6 +748,7 @@ StdExecuter::StdExecuter(mlir::func::FuncOp &toplevel,
arith::IndexCastOp,
arith::MulFOp,
arith::MulIOp,
+ arith::NegFOp,
arith::OrIOp,
arith::RemFOp,
arith::RemSIOp,
diff --git a/experimental/tools/frequency-profiler/Simulator.h b/experimental/tools/frequency-profiler/Simulator.h
index 05a504553f..28da99925f 100644
--- a/experimental/tools/frequency-profiler/Simulator.h
+++ b/experimental/tools/frequency-profiler/Simulator.h
@@ -79,6 +79,8 @@ class StdExecuter {
std::vector &);
LogicalResult execute(mlir::arith::DivFOp, std::vector &,
std::vector &);
+ LogicalResult execute(mlir::arith::NegFOp, std::vector &,
+ std::vector &);
LogicalResult execute(mlir::arith::RemFOp, std::vector &,
std::vector &);
LogicalResult execute(mlir::arith::RemSIOp, std::vector &,
diff --git a/experimental/tools/unit-generators/vhdl/generators/handshake/absf.py b/experimental/tools/unit-generators/vhdl/generators/handshake/absf.py
new file mode 100644
index 0000000000..540d463958
--- /dev/null
+++ b/experimental/tools/unit-generators/vhdl/generators/handshake/absf.py
@@ -0,0 +1,18 @@
+from generators.support.unary import generate_unary
+
+
+def generate_absf(name, params):
+ bitwidth = params["bitwidth"]
+
+ body = f"""
+ outs({bitwidth} - 1) <= '0';
+ outs({bitwidth} - 2 downto 0) <= ins({bitwidth} - 2 downto 0);
+ """
+
+ return generate_unary(
+ name=name,
+ handshake_op="absf",
+ bitwidth=bitwidth,
+ body=body,
+ extra_signals=params.get("extra_signals", None),
+ )
diff --git a/experimental/tools/unit-generators/vhdl/generators/handshake/addf.py b/experimental/tools/unit-generators/vhdl/generators/handshake/addf.py
index d0f2f886a4..cde9ee6f9d 100644
--- a/experimental/tools/unit-generators/vhdl/generators/handshake/addf.py
+++ b/experimental/tools/unit-generators/vhdl/generators/handshake/addf.py
@@ -1,270 +1,39 @@
-from generators.support.signal_manager import generate_buffered_signal_manager
-from generators.handshake.join import generate_join
-from generators.support.delay_buffer import generate_delay_buffer
-from generators.handshake.buffers.one_slot_break_dv import generate_one_slot_break_dv
+from generators.support.arith_ip import generate_flopoco_ip_wrapper, generate_vivado_ip_wrapper
+from generators.support.utils import VIVADO_IMPL, FLOPOCO_IMPL
def generate_addf(name, params):
- is_double = params["is_double"]
- extra_signals = params["extra_signals"]
-
- if extra_signals:
- return _generate_addf_signal_manager(name, is_double, extra_signals)
- else:
- return _generate_addf(name, is_double)
-
-
-def _generate_addf(name, is_double):
- if is_double:
- return _generate_addf_double_precision(name)
- else:
- return _generate_addf_single_precision(name)
-
-
-def _get_latency(is_double):
- return 12 if is_double else 9 # todo
-
-
-def _generate_addf_single_precision(name):
- join_name = f"{name}_join"
- one_slot_break_dv_name = f"{name}_one_slot_break_dv"
- buff_name = f"{name}_buff"
-
- dependencies = generate_join(join_name, {"size": 2}) + \
- generate_one_slot_break_dv(one_slot_break_dv_name, {"bitwidth": 0}) + \
- generate_delay_buffer(
- buff_name, {"slots": _get_latency(is_double=False) - 1})
-
- entity = f"""
-library ieee;
-use ieee.std_logic_1164.all;
-use ieee.numeric_std.all;
-
--- Entity of addf_single_precision
-entity {name} is
- port (
- -- inputs
- clk : in std_logic;
- rst : in std_logic;
- lhs : in std_logic_vector(32 - 1 downto 0);
- lhs_valid : in std_logic;
- rhs : in std_logic_vector(32 - 1 downto 0);
- rhs_valid : in std_logic;
- result_ready : in std_logic;
- -- outputs
- result : out std_logic_vector(32 - 1 downto 0);
- result_valid : out std_logic;
- lhs_ready : out std_logic;
- rhs_ready : out std_logic
- );
-end entity;
-"""
-
- architecture = f"""
--- Architecture of addf_single_precision
-architecture arch of {name} is
- signal join_valid : std_logic;
- signal buff_valid, one_slot_break_dv_ready : std_logic;
-
- -- intermediate input signals for IEEE-754 to Flopoco-simple-float conversion
- signal ip_lhs, ip_rhs : std_logic_vector(32 + 1 downto 0);
-
- -- intermediate output signal for Flopoco-simple-float to IEEE-754 conversion
- signal ip_result : std_logic_vector(32 + 1 downto 0);
-begin
- join_inputs : entity work.{join_name}(arch)
- port map(
- -- inputs
- ins_valid(0) => lhs_valid,
- ins_valid(1) => rhs_valid,
- outs_ready => one_slot_break_dv_ready,
- -- outputs
- outs_valid => join_valid,
- ins_ready(0) => lhs_ready,
- ins_ready(1) => rhs_ready
- );
-
- one_slot_break_dv : entity work.{one_slot_break_dv_name}(arch)
- port map(
- clk => clk,
- rst => rst,
- ins_valid => buff_valid,
- outs_ready => result_ready,
- outs_valid => result_valid,
- ins_ready => one_slot_break_dv_ready
- );
-
- buff : entity work.{buff_name}(arch)
- port map(
- clk,
- rst,
- join_valid,
- one_slot_break_dv_ready,
- buff_valid
- );
-
- ieee2nfloat_lhs: entity work.InputIEEE_32bit(arch)
- port map (
- X => lhs,
- R => ip_lhs
- );
-
- ieee2nfloat_rhs: entity work.InputIEEE_32bit(arch)
- port map (
- X => rhs,
- R => ip_rhs
- );
-
- nfloat2ieee_result : entity work.OutputIEEE_32bit(arch)
- port map (
- X => ip_result,
- R => result
- );
-
- ip : entity work.FloatingPointAdder(arch)
- port map (
- clk => clk,
- ce => one_slot_break_dv_ready,
- X => ip_lhs,
- Y => ip_rhs,
- R => ip_result
- );
-end architecture;
-"""
-
- return dependencies + entity + architecture
-
-
-def _generate_addf_double_precision(name):
- join_name = f"{name}_join"
- one_slot_break_dv_name = f"{name}_one_slot_break_dv"
- buff_name = f"{name}_buff"
-
- dependencies = generate_join(join_name, {"size": 2}) + \
- generate_one_slot_break_dv(one_slot_break_dv_name, {"bitwidth": 1}) + \
- generate_delay_buffer(
- buff_name, {"slots": _get_latency(is_double=True) - 1})
-
- entity = f"""
-library ieee;
-use ieee.std_logic_1164.all;
-use ieee.numeric_std.all;
-
--- Entity of addf_double_precision
-entity {name} is
- port (
- -- inputs
- clk : in std_logic;
- rst : in std_logic;
- lhs : in std_logic_vector(64 - 1 downto 0);
- lhs_valid : in std_logic;
- rhs : in std_logic_vector(64 - 1 downto 0);
- rhs_valid : in std_logic;
- result_ready : in std_logic;
- -- outputs
- result : out std_logic_vector(64 - 1 downto 0);
- result_valid : out std_logic;
- lhs_ready : out std_logic;
- rhs_ready : out std_logic
- );
-end entity;
-"""
-
- architecture = f"""
--- Architecture of addf_double_precision
-architecture arch of {name} is
- signal join_valid : std_logic;
- signal buff_valid, one_slot_break_dv_ready : std_logic;
-
- -- intermediate input signals for IEEE-754 to Flopoco-simple-float conversion
- signal ip_lhs, ip_rhs : std_logic_vector(64 + 1 downto 0);
-
- -- intermediate output signal for Flopoco-simple-float to IEEE-754 conversion
- signal ip_result : std_logic_vector(64 + 1 downto 0);
-begin
- join_inputs : entity work.{join_name}(arch)
- port map(
- -- inputs
- ins_valid(0) => lhs_valid,
- ins_valid(1) => rhs_valid,
- outs_ready => one_slot_break_dv_ready,
- -- outputs
- outs_valid => join_valid,
- ins_ready(0) => lhs_ready,
- ins_ready(1) => rhs_ready
- );
-
- one_slot_break_dv : entity work.{one_slot_break_dv_name}(arch)
- port map(
- clk => clk,
- rst => rst,
- ins_valid => buff_valid,
- outs_ready => result_ready,
- outs_valid => result_valid,
- ins_ready => one_slot_break_dv_ready,
- ins(0) => '0',
- outs => open
- );
-
- buff : entity work.{buff_name}(arch)
- port map(
- clk,
- rst,
- join_valid,
- one_slot_break_dv_ready,
- buff_valid
- );
-
- ieee2nfloat_lhs: entity work.InputIEEE_64bit(arch)
- port map (
- X => lhs,
- R => ip_lhs
- );
-
- ieee2nfloat_rhs: entity work.InputIEEE_64bit(arch)
- port map (
- X => rhs,
- R => ip_rhs
- );
-
- nfloat2ieee_result : entity work.OutputIEEE_64bit(arch)
- port map (
- X => ip_result,
- R => result
- );
-
- ip : entity work.FPAdd_64bit(arch)
- port map (
- clk => clk,
- ce => one_slot_break_dv_ready,
- X => ip_lhs,
- Y => ip_rhs,
- R => ip_result
- );
-end architecture;
-"""
-
- return dependencies + entity + architecture
-
-
-def _generate_addf_signal_manager(name, is_double, extra_signals):
- bitwidth = 64 if is_double else 32
- return generate_buffered_signal_manager(
- name,
- [{
- "name": "lhs",
- "bitwidth": bitwidth,
- "extra_signals": extra_signals
- }, {
- "name": "rhs",
- "bitwidth": bitwidth,
- "extra_signals": extra_signals
- }],
- [{
- "name": "result",
- "bitwidth": bitwidth,
- "extra_signals": extra_signals
- }],
- extra_signals,
- lambda name: _generate_addf(name, is_double),
- _get_latency(is_double))
+ impl = params["fpu_impl"]
+
+ latency = params["latency"]
+
+ extra_signals = params.get("extra_signals", None)
+
+ # only used for flopoco
+ is_double = params.get("is_double", None)
+ internal_delay = params.get("internal_delay", None)
+
+ handshake_op = "addf"
+
+ if impl == FLOPOCO_IMPL:
+ if is_double is None:
+ raise ValueError(f"is_double was missing for generating a flopoco {handshake_op}")
+ if internal_delay is None:
+ raise ValueError(f"internal_delay was missing for generating a flopoco {{mod_type}}")
+
+ return generate_flopoco_ip_wrapper(
+ name=name,
+ handshake_op=handshake_op,
+ core_unit="FloatingPointAdder",
+ latency=latency,
+ is_double=is_double,
+ internal_delay=internal_delay,
+ extra_signals=extra_signals
+ )
+ elif impl == VIVADO_IMPL:
+ return generate_vivado_ip_wrapper(
+ name=name,
+ handshake_op=handshake_op,
+ latency=latency,
+ extra_signals=extra_signals
+ )
diff --git a/experimental/tools/unit-generators/vhdl/generators/handshake/addi.py b/experimental/tools/unit-generators/vhdl/generators/handshake/addi.py
index 304e9d5537..c554b2af85 100644
--- a/experimental/tools/unit-generators/vhdl/generators/handshake/addi.py
+++ b/experimental/tools/unit-generators/vhdl/generators/handshake/addi.py
@@ -1,86 +1,17 @@
-from generators.support.signal_manager import generate_default_signal_manager
-from generators.handshake.join import generate_join
+from generators.support.arith_binary import generate_arith_binary
def generate_addi(name, params):
bitwidth = params["bitwidth"]
- extra_signals = params.get("extra_signals", None)
-
- if extra_signals:
- return _generate_addi_signal_manager(name, bitwidth, extra_signals)
- else:
- return _generate_addi(name, bitwidth)
-
-
-def _generate_addi(name, bitwidth):
- join_name = f"{name}_join"
-
- dependencies = generate_join(join_name, {"size": 2})
-
- entity = f"""
-library ieee;
-use ieee.std_logic_1164.all;
-use ieee.numeric_std.all;
-
--- Entity of addi
-entity {name} is
- port (
- -- inputs
- clk : in std_logic;
- rst : in std_logic;
- lhs : in std_logic_vector({bitwidth} - 1 downto 0);
- lhs_valid : in std_logic;
- rhs : in std_logic_vector({bitwidth} - 1 downto 0);
- rhs_valid : in std_logic;
- result_ready : in std_logic;
- -- outputs
- result : out std_logic_vector({bitwidth} - 1 downto 0);
- result_valid : out std_logic;
- lhs_ready : out std_logic;
- rhs_ready : out std_logic
- );
-end entity;
-"""
-
- architecture = f"""
--- Architecture of addi
-architecture arch of {name} is
-begin
- join_inputs : entity work.{join_name}(arch)
- port map(
- -- inputs
- ins_valid(0) => lhs_valid,
- ins_valid(1) => rhs_valid,
- outs_ready => result_ready,
- -- outputs
- outs_valid => result_valid,
- ins_ready(0) => lhs_ready,
- ins_ready(1) => rhs_ready
- );
+ body = """
result <= std_logic_vector(unsigned(lhs) + unsigned(rhs));
-end architecture;
-"""
-
- return dependencies + entity + architecture
-
-
-def _generate_addi_signal_manager(name, bitwidth, extra_signals):
- return generate_default_signal_manager(
- name,
- [{
- "name": "lhs",
- "bitwidth": bitwidth,
- "extra_signals": extra_signals
- }, {
- "name": "rhs",
- "bitwidth": bitwidth,
- "extra_signals": extra_signals
- }],
- [{
- "name": "result",
- "bitwidth": bitwidth,
- "extra_signals": extra_signals
- }],
- extra_signals,
- lambda name: _generate_addi(name, bitwidth))
+ """
+
+ return generate_arith_binary(
+ name=name,
+ handshake_op="addi",
+ bitwidth=bitwidth,
+ body=body,
+ extra_signals=params.get("extra_signals", None),
+ )
diff --git a/experimental/tools/unit-generators/vhdl/generators/handshake/andi.py b/experimental/tools/unit-generators/vhdl/generators/handshake/andi.py
index 26a60aff58..d59a6dc890 100644
--- a/experimental/tools/unit-generators/vhdl/generators/handshake/andi.py
+++ b/experimental/tools/unit-generators/vhdl/generators/handshake/andi.py
@@ -1,86 +1,17 @@
-from generators.support.signal_manager import generate_default_signal_manager
-from generators.handshake.join import generate_join
+from generators.support.arith_binary import generate_arith_binary
def generate_andi(name, params):
bitwidth = params["bitwidth"]
- extra_signals = params["extra_signals"]
-
- if extra_signals:
- return _generate_andi_signal_manager(name, bitwidth, extra_signals)
- else:
- return _generate_andi(name, bitwidth)
-
-
-def _generate_andi(name, bitwidth):
- join_name = f"{name}_join"
-
- dependencies = generate_join(join_name, {"size": 2})
-
- entity = f"""
-library ieee;
-use ieee.std_logic_1164.all;
-use ieee.numeric_std.all;
-
--- Entity of andi
-entity {name} is
- port (
- -- inputs
- clk : in std_logic;
- rst : in std_logic;
- lhs : in std_logic_vector({bitwidth} - 1 downto 0);
- lhs_valid : in std_logic;
- rhs : in std_logic_vector({bitwidth} - 1 downto 0);
- rhs_valid : in std_logic;
- result_ready : in std_logic;
- -- outputs
- result : out std_logic_vector({bitwidth} - 1 downto 0);
- result_valid : out std_logic;
- lhs_ready : out std_logic;
- rhs_ready : out std_logic
- );
-end entity;
-"""
-
- architecture = f"""
--- Architecture of andi
-architecture arch of {name} is
-begin
- join_inputs : entity work.{join_name}(arch)
- port map(
- -- inputs
- ins_valid(0) => lhs_valid,
- ins_valid(1) => rhs_valid,
- outs_ready => result_ready,
- -- outputs
- outs_valid => result_valid,
- ins_ready(0) => lhs_ready,
- ins_ready(1) => rhs_ready
- );
+ body = """
result <= lhs and rhs;
-end architecture;
-"""
-
- return dependencies + entity + architecture
-
-
-def _generate_andi_signal_manager(name, bitwidth, extra_signals):
- return generate_default_signal_manager(
- name,
- [{
- "name": "lhs",
- "bitwidth": bitwidth,
- "extra_signals": extra_signals
- }, {
- "name": "rhs",
- "bitwidth": bitwidth,
- "extra_signals": extra_signals
- }],
- [{
- "name": "result",
- "bitwidth": bitwidth,
- "extra_signals": extra_signals
- }],
- extra_signals,
- lambda name: _generate_andi(name, bitwidth))
+ """
+
+ return generate_arith_binary(
+ name=name,
+ handshake_op="andi",
+ bitwidth=bitwidth,
+ body=body,
+ extra_signals=params.get("extra_signals", None),
+ )
diff --git a/experimental/tools/unit-generators/vhdl/generators/handshake/br.py b/experimental/tools/unit-generators/vhdl/generators/handshake/br.py
new file mode 100644
index 0000000000..9dde8635b5
--- /dev/null
+++ b/experimental/tools/unit-generators/vhdl/generators/handshake/br.py
@@ -0,0 +1,113 @@
+from generators.support.signal_manager import generate_default_signal_manager
+
+
+def generate_br(name, params):
+ bitwidth = params["bitwidth"]
+ extra_signals = params.get("extra_signals", None)
+
+ if extra_signals:
+ return _generate_br_signal_manager(name, bitwidth, extra_signals)
+ elif bitwidth == 0:
+ return _generate_br_dataless(name)
+ else:
+ return _generate_br(name, bitwidth)
+
+
+def _generate_br_dataless(name):
+ entity = f"""
+library ieee;
+use ieee.std_logic_1164.all;
+use ieee.numeric_std.all;
+
+-- Entity of br_dataless
+entity {name} is
+ port (
+ clk, rst : in std_logic;
+ -- input channel
+ ins_valid : in std_logic;
+ ins_ready : out std_logic;
+ -- input channel
+ outs_valid : out std_logic;
+ outs_ready : in std_logic
+ );
+end entity;
+"""
+
+ architecture = f"""
+-- Architecture of br_dataless
+architecture arch of {name} is
+begin
+ outs_valid <= ins_valid;
+ ins_ready <= outs_ready;
+end architecture;
+"""
+
+ return entity + architecture
+
+
+def _generate_br(name, bitwidth):
+ inner_name = f"{name}_inner"
+
+ dependencies = _generate_br_dataless(inner_name)
+
+ entity = f"""
+library ieee;
+use ieee.std_logic_1164.all;
+use ieee.numeric_std.all;
+
+-- Entity of br
+entity {name} is
+ port (
+ clk : in std_logic;
+ rst : in std_logic;
+ -- input channel
+ ins : in std_logic_vector({bitwidth} - 1 downto 0);
+ ins_valid : in std_logic;
+ ins_ready : out std_logic;
+ -- output channel
+ outs : out std_logic_vector({bitwidth} - 1 downto 0);
+ outs_valid : out std_logic;
+ outs_ready : in std_logic
+ );
+end entity;
+"""
+
+ architecture = f"""
+-- Architecture of br
+architecture arch of {name} is
+begin
+ control : entity work.{inner_name}
+ port map(
+ clk => clk,
+ rst => rst,
+ ins_valid => ins_valid,
+ ins_ready => ins_ready,
+ outs_valid => outs_valid,
+ outs_ready => outs_ready
+ );
+
+ outs <= ins;
+end architecture;
+
+"""
+
+ return dependencies + entity + architecture
+
+
+def _generate_br_signal_manager(name, bitwidth, extra_signals):
+ return generate_default_signal_manager(
+ name,
+ [{
+ "name": "ins",
+ "bitwidth": bitwidth,
+ "extra_signals": extra_signals
+ }],
+ [{
+ "name": "outs",
+ "bitwidth": bitwidth,
+ "extra_signals": extra_signals
+ }],
+ extra_signals,
+ lambda name:
+ (_generate_br_dataless(name) if bitwidth == 0
+ else _generate_br(name, bitwidth)))
diff --git a/experimental/tools/unit-generators/vhdl/generators/handshake/buffer.py b/experimental/tools/unit-generators/vhdl/generators/handshake/buffer.py
index 6704385f00..c65436e404 100644
--- a/experimental/tools/unit-generators/vhdl/generators/handshake/buffer.py
+++ b/experimental/tools/unit-generators/vhdl/generators/handshake/buffer.py
@@ -3,7 +3,7 @@
from generators.handshake.buffers.one_slot_break_dv import generate_one_slot_break_dv
from generators.handshake.buffers.one_slot_break_r import generate_one_slot_break_r
from generators.handshake.buffers.one_slot_break_dvr import generate_one_slot_break_dvr
-from generators.handshake.buffers.shift_reg_break_dvr import generate_shift_reg_break_dv
+from generators.handshake.buffers.shift_reg_break_dv import generate_shift_reg_break_dv
from generators.support.utils import try_enum_cast
@@ -38,3 +38,10 @@ def generate_buffer(name, params):
return generate_shift_reg_break_dv(name, params)
case _:
raise ValueError(f"Unhandled buffer type: {buffer_type}")
+
+
+def generate_valid_propagation_buffer(name, latency):
+ if latency == 1:
+ return generate_one_slot_break_dv(name, {"bitwidth": 0})
+ else:
+ return generate_shift_reg_break_dv(name, {"bitwidth": 0, "num_slots": latency})
diff --git a/experimental/tools/unit-generators/vhdl/generators/handshake/buffers/fifo_break_dv.py b/experimental/tools/unit-generators/vhdl/generators/handshake/buffers/fifo_break_dv.py
index bf851f2525..f924f3b699 100644
--- a/experimental/tools/unit-generators/vhdl/generators/handshake/buffers/fifo_break_dv.py
+++ b/experimental/tools/unit-generators/vhdl/generators/handshake/buffers/fifo_break_dv.py
@@ -2,6 +2,7 @@
from generators.support.signal_manager.utils.concat import get_concat_extra_signals_bitwidth
from generators.handshake.buffers.one_slot_break_dv import generate_one_slot_break_dv
+
def generate_fifo_break_dv(name, params):
bitwidth = params["bitwidth"]
num_slots = params["num_slots"]
@@ -162,7 +163,6 @@ def _generate_fifo_break_dv_dataless(name, num_slots):
return entity + architecture
-
def _generate_fifo_break_dv(name, num_slots, bitwidth):
entity = f"""
library ieee;
diff --git a/experimental/tools/unit-generators/vhdl/generators/handshake/buffers/fifo_break_none.py b/experimental/tools/unit-generators/vhdl/generators/handshake/buffers/fifo_break_none.py
index ef718c94bf..1047973d52 100644
--- a/experimental/tools/unit-generators/vhdl/generators/handshake/buffers/fifo_break_none.py
+++ b/experimental/tools/unit-generators/vhdl/generators/handshake/buffers/fifo_break_none.py
@@ -97,7 +97,7 @@ def _generate_fifo_break_none_dataless(name, num_slots):
dependencies = generate_fifo_break_dv(
fifo_inner_name,
{"num_slots": num_slots,
- "bitwdith": 0})
+ "bitwidth": 0})
entity = f"""
library ieee;
diff --git a/experimental/tools/unit-generators/vhdl/generators/handshake/buffers/shift_reg_break_dvr.py b/experimental/tools/unit-generators/vhdl/generators/handshake/buffers/shift_reg_break_dv.py
similarity index 100%
rename from experimental/tools/unit-generators/vhdl/generators/handshake/buffers/shift_reg_break_dvr.py
rename to experimental/tools/unit-generators/vhdl/generators/handshake/buffers/shift_reg_break_dv.py
diff --git a/experimental/tools/unit-generators/vhdl/generators/handshake/cmpf.py b/experimental/tools/unit-generators/vhdl/generators/handshake/cmpf.py
index 2b5109914d..c6ecb08068 100644
--- a/experimental/tools/unit-generators/vhdl/generators/handshake/cmpf.py
+++ b/experimental/tools/unit-generators/vhdl/generators/handshake/cmpf.py
@@ -1,166 +1,63 @@
-from generators.support.signal_manager import generate_buffered_signal_manager
-from generators.handshake.join import generate_join
-from generators.handshake.buffers.one_slot_break_dv import generate_one_slot_break_dv
+from generators.support.arith_binary import generate_arith_binary
+from generators.support.utils import VIVADO_IMPL, FLOPOCO_IMPL
def generate_cmpf(name, params):
- is_double = params["is_double"]
- extra_signals = params["extra_signals"]
predicate = params["predicate"]
-
- if extra_signals:
- return _generate_cmpf_signal_manager(name, is_double, predicate, extra_signals)
+ impl = params["fpu_impl"]
+ latency = params["latency"]
+
+ # only used by flopoco
+ is_double = params.get("is_double", None)
+
+ if impl == FLOPOCO_IMPL:
+ bitwidth = 64 if is_double else 32
+ if is_double is None:
+ raise ValueError(f"is_double was missing for generating a flopoco cmpf")
+
+ signals = _get_flopoco_signals(bitwidth)
+ body = _get_flopoco_body(bitwidth, predicate)
+ elif impl == VIVADO_IMPL:
+ signals = _get_vivado_signals()
+ body = _get_vivado_body(predicate)
+ bitwidth = 32
else:
- return _generate_cmpf(name, is_double, predicate)
-
+ raise ValueError(f"Invalid fpu implementation on cmpf: {impl}")
-_expression_from_predicate = {
- "oeq": "not unordered and XeqY",
- "ogt": "not unordered and XgtY",
- "oge": "not unordered and XgeY",
- "olt": "not unordered and XltY",
- "ole": "not unordered and XleY",
- "one": "not unordered and not XeqY",
- "ueq": "unordered or XeqY",
- "ugt": "unordered or XgtY",
- "uge": "unordered or XgeY",
- "ult": "unordered or XltY",
- "ule": "unordered or XleY",
- "une": "unordered or not XeqY",
- "uno": "unordered"
-}
+ return generate_arith_binary(
+ name=name,
+ handshake_op="cmpf",
+ input_bitwidth=bitwidth,
+ output_bitwidth=1,
+ signals=signals,
+ body=body,
+ latency=latency,
+ extra_signals=params.get("extra_signals", None)
+ )
-def _generate_cmpf(name, is_double, predicate):
- inner_name = f"{name}_inner"
- bitwidth = 64 if is_double else 32
- if is_double:
- dependencies = _generate_cmpf_double_precision(inner_name)
- else:
- dependencies = _generate_cmpf_single_precision(inner_name)
+##################################################
+# Flopoco
+##################################################
- entity = f"""
-library ieee;
-use ieee.std_logic_1164.all;
-use ieee.numeric_std.all;
-
--- Entity of cmpf
-entity {name} is
- port (
- -- inputs
- clk : in std_logic;
- rst : in std_logic;
- lhs : in std_logic_vector({bitwidth} - 1 downto 0);
- lhs_valid : in std_logic;
- rhs : in std_logic_vector({bitwidth} - 1 downto 0);
- rhs_valid : in std_logic;
- result_ready : in std_logic;
- -- outputs
- result : out std_logic_vector(0 downto 0);
- result_valid : out std_logic;
- lhs_ready : out std_logic;
- rhs_ready : out std_logic
- );
-end entity;
-"""
- architecture = f"""
--- Architecture of cmpf
-architecture arch of {name} is
+def _get_flopoco_signals(bitwidth):
+ return f"""
signal unordered : std_logic;
signal XltY : std_logic;
signal XeqY : std_logic;
signal XgtY : std_logic;
signal XleY : std_logic;
signal XgeY : std_logic;
-begin
- operator : entity work.{inner_name}(arch)
- port map(
- clk => clk,
- rst => rst,
- lhs => lhs,
- lhs_valid => lhs_valid,
- rhs => rhs,
- rhs_valid => rhs_valid,
- result_ready => result_ready,
- unordered => unordered,
- XltY => XltY,
- XeqY => XeqY,
- XgtY => XgtY,
- XleY => XleY,
- XgeY => XgeY,
- result_valid => result_valid,
- lhs_ready => lhs_ready,
- rhs_ready => rhs_ready
- );
-
- result(0) <= {_expression_from_predicate[predicate]};
-end architecture;
-"""
+ signal ip_lhs: std_logic_vector({bitwidth + 2} - 1 downto 0);
+ signal ip_rhs: std_logic_vector({bitwidth + 2} - 1 downto 0);
+ """
- return dependencies + entity + architecture
-
-def _get_latency(is_double):
- return 1 # todo
-
-
-def _generate_cmpf_single_precision(name):
- join_name = f"{name}_join"
-
- dependencies = generate_join(join_name, {"size": 2})
-
- entity = f"""
-
-
-library ieee;
-use ieee.std_logic_1164.all;
-use ieee.numeric_std.all;
-
--- Entity of cmpf_single_precision
-entity {name} is
- port(
- -- inputs
- clk: in std_logic;
- rst: in std_logic;
- lhs: in std_logic_vector(32 - 1 downto 0);
- lhs_valid: in std_logic;
- rhs: in std_logic_vector(32 - 1 downto 0);
- rhs_valid: in std_logic;
- result_ready: in std_logic;
- -- outputs
- unordered: out std_logic;
- XltY: out std_logic;
- XeqY: out std_logic;
- XgtY: out std_logic;
- XleY: out std_logic;
- XgeY: out std_logic;
- result_valid: out std_logic;
- lhs_ready: out std_logic;
- rhs_ready: out std_logic
- );
-end entity;
-"""
-
- architecture = f"""
--- Architecture of cmpf_single_precision
-architecture arch of {name} is
- signal ip_lhs: std_logic_vector(32 + 1 downto 0);
- signal ip_rhs: std_logic_vector(32 + 1 downto 0);
-begin
- join_inputs: entity work.{join_name}(arch)
- port map(
- -- inputs
- ins_valid(0)=> lhs_valid,
- ins_valid(1)=> rhs_valid,
- outs_ready=> result_ready,
- -- outputs
- outs_valid=> result_valid,
- ins_ready(0)=> lhs_ready,
- ins_ready(1)=> rhs_ready
- );
-
- ieee2nfloat_0: entity work.InputIEEE_32bit(arch)
+def _get_flopoco_body(bitwidth, predicate):
+ expression = _get_flopoco_expression_from_predicate(predicate)
+ return f"""
+ ieee2nfloat_0: entity work.InputIEEE_{bitwidth}bit(arch)
port map(
--input
X=> lhs,
@@ -168,14 +65,14 @@ def _generate_cmpf_single_precision(name):
R=> ip_lhs
);
- ieee2nfloat_1: entity work.InputIEEE_32bit(arch)
+ ieee2nfloat_1: entity work.InputIEEE_{bitwidth}bit(arch)
port map(
--input
X=> rhs,
--output
R=> ip_rhs
);
- operator: entity work.FPComparator_32bit(arch)
+ operator: entity work.FPComparator_{bitwidth}bit(arch)
port map (clk=> clk,
ce=> '1',
X=> ip_lhs,
@@ -186,125 +83,79 @@ def _generate_cmpf_single_precision(name):
XgtY=> XgtY,
XleY=> XleY,
XgeY=> XgeY);
-end architecture;
-"""
- return dependencies + entity + architecture
+ result(0) <= {expression};
+ """
-def _generate_cmpf_double_precision(name):
- join_name = f"{name}_join"
- one_slot_break_dv_name = f"{name}_one_slot_break_dv"
+def _get_flopoco_expression_from_predicate(predicate):
+ expressions = {
+ "oeq": "not unordered and XeqY",
+ "ogt": "not unordered and XgtY",
+ "oge": "not unordered and XgeY",
+ "olt": "not unordered and XltY",
+ "ole": "not unordered and XleY",
+ "one": "not unordered and not XeqY",
+ "ueq": "unordered or XeqY",
+ "ugt": "unordered or XgtY",
+ "uge": "unordered or XgeY",
+ "ult": "unordered or XltY",
+ "ule": "unordered or XleY",
+ "une": "unordered or not XeqY",
+ "uno": "unordered"
+ }
+ if predicate not in expressions:
+ raise ValueError(f"Unsupported flopoco predicate: {predicate}")
- dependencies = generate_join(join_name, {"size": 2}) + \
- generate_one_slot_break_dv(one_slot_break_dv_name, {"bitwidth": 0})
+ return f"{expressions[predicate]}"
- entity = f"""
-library ieee;
-use ieee.std_logic_1164.all;
-use ieee.numeric_std.all;
--- Entity of cmpf_double_precision
-entity {name} is
- port(
- -- inputs
- clk: in std_logic;
- rst: in std_logic;
- lhs: in std_logic_vector(64 - 1 downto 0);
- lhs_valid: in std_logic;
- rhs: in std_logic_vector(64 - 1 downto 0);
- rhs_valid: in std_logic;
- result_ready: in std_logic;
- -- outputs
- result: out std_logic_vector(64 - 1 downto 0);
- result_valid: out std_logic;
- lhs_ready: out std_logic;
- rhs_ready: out std_logic
- );
-end entity;
-"""
-
- architecture = f"""
--- Architecture of cmpf_double_precision
-architecture arch of {name} is
- signal join_valid: std_logic;
- signal buff_valid, one_slot_break_dv_valid, one_slot_break_dv_ready : std_logic;
- signal one_slot_break_dv_dataOut, one_slot_break_dv_datain : std_logic_vector(0 downto 0);
- signal ip_lhs : std_logic_vector(64 + 1 downto 0);
- signal ip_rhs : std_logic_vector(64 + 1 downto 0);
-begin
+##################################################
+# Vivado
+##################################################
- one_slot_break_dv : entity work.{one_slot_break_dv_name}(arch)
- port map(
- clk => clk,
- rst => rst,
- ins_valid => buff_valid,
- outs_ready => result_ready,
- outs_valid => result_valid,
- ins_ready => one_slot_break_dv_ready
- );
- join_inputs : entity work.{join_name}(arch)
- port map(
- -- inputs
- ins_valid(0) => lhs_valid,
- ins_valid(1) => rhs_valid,
- outs_ready => one_slot_break_dv_ready,
- -- outputs
- outs_valid => buff_valid,
- ins_ready(0) => lhs_ready,
- ins_ready(1) => rhs_ready
- );
- ieee2nfloat_0: entity work.InputIEEE_64bit(arch)
- port map (
- --input
- X => lhs,
- --output
- R => ip_lhs
- );
-
- ieee2nfloat_1: entity work.InputIEEE_64bit(arch)
- port map (
- --input
- X => rhs,
- --output
- R => ip_rhs
- );
- operator : entity work.FPComparator_64bit(arch)
- port map (clk => clk,
- ce => one_slot_break_dv_ready,
- X => ip_lhs,
- Y => ip_rhs,
- unordered => unordered,
- XltY => XltY,
- XeqY => XeqY,
- XgtY => XgtY,
- XleY => XleY,
- XgeY => XgeY);
-end architecture;
+def _get_vivado_signals():
+ return f"""
+ signal alu_opcode : std_logic_vector(4 downto 0);
"""
- return dependencies + entity + architecture
-
-def _generate_cmpf_signal_manager(name, is_double, predicate, extra_signals):
- bitwidth = 64 if is_double else 32
- return generate_buffered_signal_manager(
- name,
- [{
- "name": "lhs",
- "bitwidth": bitwidth,
- "extra_signals": extra_signals
- }, {
- "name": "rhs",
- "bitwidth": bitwidth,
- "extra_signals": extra_signals
- }],
- [{
- "name": "result",
- "bitwidth": 1,
- "extra_signals": extra_signals
- }],
- extra_signals,
- lambda name: _generate_cmpf(name, is_double, predicate),
- _get_latency(is_double))
+def _get_vivado_body(predicate):
+ predicate_code = _get_vivado_code_from_predicate(predicate)
+ return f"""
+ -- Predicate: {predicate}
+ alu_opcode <= {predicate_code};
+ array_RAM_fcmp_32ns_32ns_1_2_1_u1 : entity work.cmpf_vitis_hls_wrapper
+ generic map(
+ ID => 1,
+ NUM_STAGE => 2,
+ din0_WIDTH => 32,
+ din1_WIDTH => 32,
+ dout_WIDTH => 1)
+ port map(
+ clk => clk,
+ reset => rst,
+ din0 => lhs,
+ din1 => rhs,
+ ce => oehb_ready,
+ opcode => alu_opcode,
+ dout(0) => result(0)
+ );
+ """
+
+
+def _get_vivado_code_from_predicate(predicate):
+ codes = {
+ "oeq": "00001",
+ "ogt": "00010",
+ "oge": "00011",
+ "olt": "00100",
+ "ole": "00101",
+ "one": "00110",
+ "uno": "01000",
+ }
+ if predicate not in codes:
+ raise ValueError(f"Unsupported vivado predicate: {predicate}")
+
+ return f"\"{codes[predicate]}\""
diff --git a/experimental/tools/unit-generators/vhdl/generators/handshake/cmpi.py b/experimental/tools/unit-generators/vhdl/generators/handshake/cmpi.py
index 349da570fc..c97e3c460b 100644
--- a/experimental/tools/unit-generators/vhdl/generators/handshake/cmpi.py
+++ b/experimental/tools/unit-generators/vhdl/generators/handshake/cmpi.py
@@ -1,23 +1,34 @@
-from generators.support.signal_manager import generate_default_signal_manager
-from generators.handshake.join import generate_join
+from generators.support.arith_binary import generate_arith_binary
def generate_cmpi(name, params):
+
bitwidth = params["bitwidth"]
+
predicate = params["predicate"]
- extra_signals = params.get("extra_signals", None)
- if extra_signals:
- return _generate_cmpi_signal_manager(name, predicate, bitwidth, extra_signals)
- else:
- return _generate_cmpi(name, predicate, bitwidth)
+ modifier = _get_sign_from_predicate(predicate)
+ comparator = _get_symbol_from_predicate(predicate)
+
+ body = f"""
+ result(0) <= '1' when ({modifier}(lhs) {comparator} {modifier}(rhs)) else '0';
+"""
+
+ return generate_arith_binary(
+ name=name,
+ handshake_op="cmpi",
+ input_bitwidth=bitwidth,
+ output_bitwidth=1,
+ body=body,
+ extra_signals=params.get("extra_signals", None)
+ )
def _get_symbol_from_predicate(pred):
match pred:
case "eq":
return "="
- case "neq":
+ case "ne":
return "/="
case "slt" | "ult":
return "<"
@@ -33,7 +44,7 @@ def _get_symbol_from_predicate(pred):
def _get_sign_from_predicate(pred):
match pred:
- case "eq" | "neq":
+ case "eq" | "ne":
return ""
case "slt" | "sle" | "sgt" | "sge":
return "signed"
@@ -41,80 +52,3 @@ def _get_sign_from_predicate(pred):
return "unsigned"
case _:
raise ValueError(f"Predicate {pred} not known")
-
-
-def _generate_cmpi(name, predicate, bitwidth):
- join_name = f"{name}_join"
-
- dependencies = generate_join(join_name, {"size": 2})
-
- entity = f"""
-library ieee;
-use ieee.std_logic_1164.all;
-use ieee.numeric_std.all;
-
--- Entity of cmpi
-entity {name} is
- port (
- -- inputs
- clk : in std_logic;
- rst : in std_logic;
- lhs : in std_logic_vector({bitwidth} - 1 downto 0);
- lhs_valid : in std_logic;
- rhs : in std_logic_vector({bitwidth} - 1 downto 0);
- rhs_valid : in std_logic;
- result_ready : in std_logic;
- -- outputs
- result : out std_logic_vector(0 downto 0);
- result_valid : out std_logic;
- lhs_ready : out std_logic;
- rhs_ready : out std_logic
- );
-end entity;
-"""
-
- modifier = _get_sign_from_predicate(predicate)
- comparator = _get_symbol_from_predicate(predicate)
-
- architecture = f"""
--- Architecture of cmpi
-architecture arch of {name} is
-begin
- join_inputs : entity work.{join_name}(arch)
- port map(
- -- inputs
- ins_valid(0) => lhs_valid,
- ins_valid(1) => rhs_valid,
- outs_ready => result_ready,
- -- outputs
- outs_valid => result_valid,
- ins_ready(0) => lhs_ready,
- ins_ready(1) => rhs_ready
- );
-
- result(0) <= '1' when ({modifier}(lhs) {comparator} {modifier}(rhs)) else '0';
-end architecture;
-"""
-
- return dependencies + entity + architecture
-
-
-def _generate_cmpi_signal_manager(name, predicate, bitwidth, extra_signals):
- return generate_default_signal_manager(
- name,
- [{
- "name": "lhs",
- "bitwidth": bitwidth,
- "extra_signals": extra_signals
- }, {
- "name": "rhs",
- "bitwidth": bitwidth,
- "extra_signals": extra_signals
- }],
- [{
- "name": "result",
- "bitwidth": 1,
- "extra_signals": extra_signals
- }],
- extra_signals,
- lambda name: _generate_cmpi(name, predicate, bitwidth))
diff --git a/experimental/tools/unit-generators/vhdl/generators/handshake/divf.py b/experimental/tools/unit-generators/vhdl/generators/handshake/divf.py
new file mode 100644
index 0000000000..33da2d7579
--- /dev/null
+++ b/experimental/tools/unit-generators/vhdl/generators/handshake/divf.py
@@ -0,0 +1,38 @@
+from generators.support.arith_ip import generate_flopoco_ip_wrapper, generate_vivado_ip_wrapper
+from generators.support.utils import VIVADO_IMPL, FLOPOCO_IMPL
+
+
+def generate_divf(name, params):
+ impl = params["fpu_impl"]
+ latency = params["latency"]
+
+ extra_signals = params.get("extra_signals", None)
+
+ # only used for flopoco
+ is_double = params.get("is_double", None)
+ internal_delay = params.get("internal_delay", None)
+
+ handshake_op = "divf"
+
+ if impl == FLOPOCO_IMPL:
+ if is_double is None:
+ raise ValueError(f"is_double was missing for generating a flopoco {handshake_op}")
+ if internal_delay is None:
+ raise ValueError(f"internal_delay was missing for generating a flopoco {handshake_op}")
+
+ return generate_flopoco_ip_wrapper(
+ name=name,
+ handshake_op=handshake_op,
+ core_unit="FloatingPointDivider",
+ latency=latency,
+ is_double=is_double,
+ internal_delay=internal_delay,
+ extra_signals=extra_signals
+ )
+ elif impl == VIVADO_IMPL:
+ return generate_vivado_ip_wrapper(
+ name=name,
+ handshake_op=handshake_op,
+ latency=latency,
+ extra_signals=extra_signals
+ )
diff --git a/experimental/tools/unit-generators/vhdl/generators/handshake/divsi.py b/experimental/tools/unit-generators/vhdl/generators/handshake/divsi.py
new file mode 100644
index 0000000000..84cbecdbdd
--- /dev/null
+++ b/experimental/tools/unit-generators/vhdl/generators/handshake/divsi.py
@@ -0,0 +1,15 @@
+from generators.support.arith_ip import generate_vivado_ip_wrapper
+
+
+def generate_divsi(name, params):
+
+ latency = params["latency"]
+
+ extra_signals = params.get("extra_signals", None)
+
+ return generate_vivado_ip_wrapper(
+ name=name,
+ handshake_op="divsi",
+ latency=latency,
+ extra_signals=extra_signals
+ )
diff --git a/experimental/tools/unit-generators/vhdl/generators/handshake/divui.py b/experimental/tools/unit-generators/vhdl/generators/handshake/divui.py
new file mode 100644
index 0000000000..9cbb305a7b
--- /dev/null
+++ b/experimental/tools/unit-generators/vhdl/generators/handshake/divui.py
@@ -0,0 +1,15 @@
+from generators.support.arith_ip import generate_vivado_ip_wrapper
+
+
+def generate_divui(name, params):
+
+ latency = params["latency"]
+
+ extra_signals = params.get("extra_signals", None)
+
+ return generate_vivado_ip_wrapper(
+ name=name,
+ handshake_op="divui",
+ latency=latency,
+ extra_signals=extra_signals
+ )
diff --git a/experimental/tools/unit-generators/vhdl/generators/handshake/extf.py b/experimental/tools/unit-generators/vhdl/generators/handshake/extf.py
new file mode 100644
index 0000000000..e8a4ddb25b
--- /dev/null
+++ b/experimental/tools/unit-generators/vhdl/generators/handshake/extf.py
@@ -0,0 +1,25 @@
+from generators.support.unary import generate_unary
+
+
+def generate_extf(name, params):
+
+ signals = f"""
+ signal float_value : float32;
+ signal float_extended : float64;
+ """
+
+ body = f"""
+ float_value <= to_float(ins);
+ float_extended <= to_float64(float_value);
+ outs <= to_std_logic_vector(float_extended);
+ """
+
+ return generate_unary(
+ name=name,
+ handshake_op="extf",
+ input_bitwidth=32,
+ output_bitwidth=64,
+ signals=signals,
+ body=body,
+ extra_signals=params.get("extra_signals", None),
+ )
diff --git a/experimental/tools/unit-generators/vhdl/generators/handshake/extsi.py b/experimental/tools/unit-generators/vhdl/generators/handshake/extsi.py
index 7c751f56d2..8110954e6c 100644
--- a/experimental/tools/unit-generators/vhdl/generators/handshake/extsi.py
+++ b/experimental/tools/unit-generators/vhdl/generators/handshake/extsi.py
@@ -1,66 +1,20 @@
-from generators.support.signal_manager import generate_default_signal_manager
+from generators.support.unary import generate_unary
def generate_extsi(name, params):
input_bitwidth = params["input_bitwidth"]
output_bitwidth = params["output_bitwidth"]
- extra_signals = params.get("extra_signals", None)
- if extra_signals:
- return _generate_extsi_signal_manager(name, input_bitwidth, output_bitwidth, extra_signals)
- else:
- return _generate_extsi(name, input_bitwidth, output_bitwidth)
-
-
-def _generate_extsi(name, input_bitwidth, output_bitwidth):
- entity = f"""
-library ieee;
-use ieee.std_logic_1164.all;
-use ieee.numeric_std.all;
-
--- Entity of extsi
-entity {name} is
- port (
- clk : in std_logic;
- rst : in std_logic;
- -- input channel
- ins : in std_logic_vector({input_bitwidth} - 1 downto 0);
- ins_valid : in std_logic;
- ins_ready : out std_logic;
- -- output channel
- outs : out std_logic_vector({output_bitwidth} - 1 downto 0);
- outs_valid : out std_logic;
- outs_ready : in std_logic
- );
-end entity;
-"""
-
- architecture = f"""
--- Architecture of extsi
-architecture arch of {name} is
-begin
+ body = f"""
outs({output_bitwidth} - 1 downto {input_bitwidth}) <= ({output_bitwidth} - {input_bitwidth} - 1 downto 0 => ins({input_bitwidth} - 1));
outs({input_bitwidth} - 1 downto 0) <= ins;
- outs_valid <= ins_valid;
- ins_ready <= outs_ready;
-end architecture;
-"""
-
- return entity + architecture
-
-
-def _generate_extsi_signal_manager(name, input_bitwidth, output_bitwidth, extra_signals):
- return generate_default_signal_manager(
- name,
- [{
- "name": "ins",
- "bitwidth": input_bitwidth,
- "extra_signals": extra_signals
- }],
- [{
- "name": "outs",
- "bitwidth": output_bitwidth,
- "extra_signals": extra_signals
- }],
- extra_signals,
- lambda name: _generate_extsi(name, input_bitwidth, output_bitwidth))
+ """
+
+ return generate_unary(
+ name=name,
+ handshake_op="extsi",
+ input_bitwidth=input_bitwidth,
+ output_bitwidth=output_bitwidth,
+ body=body,
+ extra_signals=params.get("extra_signals", None),
+ )
diff --git a/experimental/tools/unit-generators/vhdl/generators/handshake/extui.py b/experimental/tools/unit-generators/vhdl/generators/handshake/extui.py
index 95a059199a..04cee9ac63 100644
--- a/experimental/tools/unit-generators/vhdl/generators/handshake/extui.py
+++ b/experimental/tools/unit-generators/vhdl/generators/handshake/extui.py
@@ -1,66 +1,20 @@
-from generators.support.signal_manager import generate_default_signal_manager
+from generators.support.unary import generate_unary
def generate_extui(name, params):
input_bitwidth = params["input_bitwidth"]
output_bitwidth = params["output_bitwidth"]
- extra_signals = params.get("extra_signals", None)
- if extra_signals:
- return _generate_extui_signal_manager(name, input_bitwidth, output_bitwidth, extra_signals)
- else:
- return _generate_extui(name, input_bitwidth, output_bitwidth)
-
-
-def _generate_extui(name, input_bitwidth, output_bitwidth):
-
- entity = f"""
-library ieee;
-use ieee.std_logic_1164.all;
-use ieee.numeric_std.all;
-
--- Entity of extui
-entity {name} is
-port (
- clk : in std_logic;
- rst : in std_logic;
- -- input channel
- ins : in std_logic_vector({input_bitwidth} - 1 downto 0);
- ins_valid : in std_logic;
- ins_ready : out std_logic;
- -- output channel
- outs : out std_logic_vector({output_bitwidth} - 1 downto 0);
- outs_valid : out std_logic;
- outs_ready : in std_logic
- );
-end entity;
-"""
- architecture = f"""
--- Architecture of extui
-architecture arch of {name} is
-
-begin
+ body = f"""
outs({output_bitwidth} - 1 downto {input_bitwidth}) <= ({output_bitwidth} - {input_bitwidth} - 1 downto 0 => '0');
outs({input_bitwidth} - 1 downto 0) <= ins;
- outs_valid <= ins_valid;
- ins_ready <= outs_ready;
-end architecture;
-"""
- return entity + architecture
-
-
-def _generate_extui_signal_manager(name, input_bitwidth, output_bitwidth, extra_signals):
- return generate_default_signal_manager(
- name,
- [{
- "name": "ins",
- "bitwidth": input_bitwidth,
- "extra_signals": extra_signals
- }],
- [{
- "name": "outs",
- "bitwidth": output_bitwidth,
- "extra_signals": extra_signals
- }],
- extra_signals,
- lambda name: _generate_extui(name, input_bitwidth, output_bitwidth))
+ """
+
+ return generate_unary(
+ name=name,
+ handshake_op="extui",
+ input_bitwidth=input_bitwidth,
+ output_bitwidth=output_bitwidth,
+ body=body,
+ extra_signals=params.get("extra_signals", None),
+ )
diff --git a/experimental/tools/unit-generators/vhdl/generators/handshake/fptosi.py b/experimental/tools/unit-generators/vhdl/generators/handshake/fptosi.py
index 42c27f8eeb..1b31a54cca 100644
--- a/experimental/tools/unit-generators/vhdl/generators/handshake/fptosi.py
+++ b/experimental/tools/unit-generators/vhdl/generators/handshake/fptosi.py
@@ -1,67 +1,20 @@
-from generators.support.signal_manager import generate_buffered_signal_manager
-from generators.support.delay_buffer import generate_delay_buffer
-from generators.handshake.buffers.one_slot_break_dv import generate_one_slot_break_dv
+from generators.support.unary import generate_unary
def generate_fptosi(name, params):
- bitwidth = params["bitwidth"]
- extra_signals = params["extra_signals"]
-
- if extra_signals:
- return _generate_fptosi_signal_manager(name, bitwidth, extra_signals)
- else:
- return _generate_fptosi(name, bitwidth)
-
-
-def _generate_fptosi(name, bitwidth):
- one_slot_break_dv_name = f"{name}_one_slot_break_dv"
- buff_name = f"{name}_buff"
-
- dependencies = generate_one_slot_break_dv(one_slot_break_dv_name, {"bitwidth": bitwidth}) + \
- generate_delay_buffer(
- buff_name, {"slots": 4})
-
- entity = f"""
-library ieee;
-use ieee.std_logic_1164.all;
-use ieee.numeric_std.all;
-use ieee.float_pkg.all;
-
--- Entity of fptosi
-entity {name} is
- port (
- -- inputs
- clk : in std_logic;
- rst : in std_logic;
- ins : in std_logic_vector({bitwidth} - 1 downto 0);
- ins_valid : in std_logic;
- outs_ready : in std_logic;
- -- outputs
- outs : out std_logic_vector({bitwidth} - 1 downto 0);
- outs_valid : out std_logic;
- ins_ready : out std_logic
- );
-begin
- assert {bitwidth}=32
- report "fptosi currently only supports 32-bit floating point operands"
- severity failure;
-end entity;
-"""
-
- architecture = f"""
--- Architecture of fptosi
-architecture arch of {name} is
- signal converted : std_logic_vector({bitwidth} - 1 downto 0);
- signal q0 : std_logic_vector({bitwidth} - 1 downto 0);
- signal q1 : std_logic_vector({bitwidth} - 1 downto 0);
- signal q2 : std_logic_vector({bitwidth} - 1 downto 0);
- signal q3 : std_logic_vector({bitwidth} - 1 downto 0);
- signal q4 : std_logic_vector({bitwidth} - 1 downto 0);
- signal buff_valid, one_slot_break_dv_ready : std_logic;
- signal one_slot_break_dv_dataOut, one_slot_break_dv_datain : std_logic_vector({bitwidth} - 1 downto 0);
+ latency = params["latency"]
+
+ signals = f"""
+ signal converted : std_logic_vector(32 - 1 downto 0);
+ signal q0 : std_logic_vector(32 - 1 downto 0);
+ signal q1 : std_logic_vector(32 - 1 downto 0);
+ signal q2 : std_logic_vector(32 - 1 downto 0);
+ signal q3 : std_logic_vector(32 - 1 downto 0);
+ signal q4 : std_logic_vector(32 - 1 downto 0);
signal float_value : float32;
-begin
+ """
+ body = f"""
float_value <= to_float(ins);
converted <= std_logic_vector(to_signed(float_value, 32));
outs <= q4;
@@ -75,7 +28,7 @@ def _generate_fptosi(name, bitwidth):
q2 <= (others => '0');
q3 <= (others => '0');
q4 <= (others => '0');
- elsif (one_slot_break_dv_ready) then
+ elsif (valid_buffer_ready) then
q0 <= converted;
q1 <= q0;
q2 <= q1;
@@ -84,49 +37,14 @@ def _generate_fptosi(name, bitwidth):
end if;
end if;
end process;
-
- buff : entity work.{buff_name}(arch)
- port map(
- clk,
- rst,
- ins_valid,
- one_slot_break_dv_ready,
- buff_valid
- );
-
- one_slot_break_dv : entity work.{one_slot_break_dv_name}(arch)
- port map(
- clk => clk,
- rst => rst,
- ins_valid => buff_valid,
- outs_ready => outs_ready,
- outs_valid => outs_valid,
- ins_ready => one_slot_break_dv_ready,
- ins => one_slot_break_dv_datain,
- outs => one_slot_break_dv_dataOut
- );
-
- ins_ready <= one_slot_break_dv_ready;
-
-end architecture;
-"""
-
- return dependencies + entity + architecture
-
-
-def _generate_fptosi_signal_manager(name, bitwidth, extra_signals):
- return generate_buffered_signal_manager(
- name,
- [{
- "name": "ins",
- "bitwidth": bitwidth,
- "extra_signals": extra_signals
- }],
- [{
- "name": "outs",
- "bitwidth": bitwidth,
- "extra_signals": extra_signals
- }],
- extra_signals,
- lambda name: _generate_fptosi(name, bitwidth),
- 5)
+ """
+
+ return generate_unary(
+ name=name,
+ handshake_op="fptosi",
+ bitwidth=32,
+ signals=signals,
+ body=body,
+ extra_signals=params.get("extra_signals", None),
+ latency=latency
+ )
diff --git a/experimental/tools/unit-generators/vhdl/generators/handshake/lazy_fork.py b/experimental/tools/unit-generators/vhdl/generators/handshake/lazy_fork.py
index d369f56708..3e30bd5cab 100644
--- a/experimental/tools/unit-generators/vhdl/generators/handshake/lazy_fork.py
+++ b/experimental/tools/unit-generators/vhdl/generators/handshake/lazy_fork.py
@@ -29,6 +29,8 @@ def _generate_lazy_fork_dataless(name, size):
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
+
+
-- Entity of lazy_fork_dataless
entity {name} is
port (
@@ -53,6 +55,7 @@ def _generate_lazy_fork_dataless(name, size):
outs_ready,
allnReady
);
+
valids : process (ins_valid, outs_ready)
variable tmp_ready : std_logic_vector({size} - 1 downto 0);
begin
@@ -84,6 +87,7 @@ def _generate_lazy_fork(name, size, bitwidth):
library ieee;
use ieee.std_logic_1164.all;
use work.types.all;
+
-- Entity of lazy_fork
entity {name} is
port (
diff --git a/experimental/tools/unit-generators/vhdl/generators/handshake/load.py b/experimental/tools/unit-generators/vhdl/generators/handshake/load.py
index 9f09759d0e..7b01da72b2 100644
--- a/experimental/tools/unit-generators/vhdl/generators/handshake/load.py
+++ b/experimental/tools/unit-generators/vhdl/generators/handshake/load.py
@@ -1,3 +1,5 @@
+
+
from generators.support.signal_manager.utils.entity import generate_entity
from generators.support.signal_manager.utils.concat import ConcatLayout
from generators.support.signal_manager.utils.generation import generate_concat, generate_slice
diff --git a/experimental/tools/unit-generators/vhdl/generators/handshake/logical_not.py b/experimental/tools/unit-generators/vhdl/generators/handshake/logical_not.py
new file mode 100644
index 0000000000..8ec079b7ce
--- /dev/null
+++ b/experimental/tools/unit-generators/vhdl/generators/handshake/logical_not.py
@@ -0,0 +1,17 @@
+from generators.support.unary import generate_unary
+
+
+def generate_logical_not(name, params):
+ bitwidth = params["bitwidth"]
+
+ body = f"""
+ outs <= not ins;
+ """
+
+ return generate_unary(
+ name=name,
+ modType="not",
+ bitwidth=bitwidth,
+ body=body,
+ extra_signals=params.get("extra_signals", None),
+ )
diff --git a/experimental/tools/unit-generators/vhdl/generators/handshake/maximumf.py b/experimental/tools/unit-generators/vhdl/generators/handshake/maximumf.py
new file mode 100644
index 0000000000..acb6e9589a
--- /dev/null
+++ b/experimental/tools/unit-generators/vhdl/generators/handshake/maximumf.py
@@ -0,0 +1,97 @@
+from generators.handshake.cmpf import generate_cmpf
+from generators.support.utils import VIVADO_IMPL, FLOPOCO_IMPL
+from generators.support.signal_manager import generate_arith_binary_signal_manager
+
+
+def generate_maximumf(name, params):
+ latency = params["latency"]
+
+ fpu_impl = params["fpu_impl"]
+
+ extra_signals = params.get("extra_signals", None)
+
+ # flopoco only
+ is_double = params.get("is_double", None)
+
+ if fpu_impl == VIVADO_IMPL:
+ bitwidth = 32
+ elif fpu_impl == FLOPOCO_IMPL:
+ if is_double is None:
+ raise ValueError("is_double was missing for generating a flopoco maximumf")
+ bitwidth = 64 if is_double else 32
+
+ def generate_inner(name): return _generate_maximumf(name, params, bitwidth)
+ def generate(): return generate_inner(name)
+
+ if extra_signals:
+ return generate_arith_binary_signal_manager(
+ name=name,
+ bitwidth=bitwidth,
+ extra_signals=extra_signals,
+ generate_inner=generate_inner,
+ latency=latency
+ )
+ else:
+ return generate()
+
+
+def _generate_maximumf(name, params, bitwidth):
+ cmpf_name = f"{name}_cmp"
+ cmpf_params = {k: v for k, v in params.items() if k != "extra_signals"}
+ cmpf_params["predicate"] = "ogt"
+ dependencies = generate_cmpf(cmpf_name, cmpf_params)
+
+ entity = f"""
+library ieee;
+use ieee.std_logic_1164.all;
+
+-- Entity of maximumf
+entity {name} is
+ port(
+ clk: in std_logic;
+ rst: in std_logic;
+ -- input channel lhs
+ lhs: in std_logic_vector({bitwidth} - 1 downto 0);
+ lhs_valid: in std_logic;
+ lhs_ready: out std_logic;
+ -- input channel rhs
+ rhs: in std_logic_vector({bitwidth} - 1 downto 0);
+ rhs_valid: in std_logic;
+ rhs_ready: out std_logic;
+ -- output channel result
+ result : out std_logic_vector({bitwidth} - 1 downto 0);
+ result_valid: out std_logic;
+ result_ready: in std_logic
+ );
+end entity;
+"""
+
+ architecture = f"""
+-- Architecture of maximumf
+architecture arch of {name} is
+
+ signal cmp_result : std_logic_vector(0 downto 0);
+
+begin
+
+ cmp_inst: entity work.{cmpf_name}
+ port map (
+ clk => clk,
+ rst => rst,
+ lhs => lhs,
+ lhs_valid => lhs_valid,
+ lhs_ready => lhs_ready,
+ rhs => rhs,
+ rhs_valid => rhs_valid,
+ rhs_ready => rhs_ready,
+ result => cmp_result,
+ result_valid => result_valid,
+ result_ready => result_ready
+ );
+
+ result <= lhs when cmp_result = "1" else rhs;
+
+end architecture;
+"""
+
+ return dependencies + entity + architecture
diff --git a/experimental/tools/unit-generators/vhdl/generators/handshake/minimumf.py b/experimental/tools/unit-generators/vhdl/generators/handshake/minimumf.py
new file mode 100644
index 0000000000..1d35df4b93
--- /dev/null
+++ b/experimental/tools/unit-generators/vhdl/generators/handshake/minimumf.py
@@ -0,0 +1,97 @@
+from generators.handshake.cmpf import generate_cmpf
+from generators.support.utils import VIVADO_IMPL, FLOPOCO_IMPL
+from generators.support.signal_manager import generate_arith_binary_signal_manager
+
+
+def generate_minimumf(name, params):
+ latency = params["latency"]
+
+ fpu_impl = params["fpu_impl"]
+
+ extra_signals = params.get("extra_signals", None)
+
+ # flopoco only
+ is_double = params.get("is_double", None)
+
+ if fpu_impl == VIVADO_IMPL:
+ bitwidth = 32
+ elif fpu_impl == FLOPOCO_IMPL:
+ if is_double is None:
+ raise ValueError("is_double was missing for generating a flopoco minimumf")
+ bitwidth = 64 if is_double else 32
+
+ def generate_inner(name): return _generate_minimumf(name, params, bitwidth)
+ def generate(): return generate_inner(name)
+
+ if extra_signals:
+ return generate_arith_binary_signal_manager(
+ name=name,
+ bitwidth=bitwidth,
+ extra_signals=extra_signals,
+ generate_inner=generate_inner,
+ latency=latency
+ )
+ else:
+ return generate()
+
+
+def _generate_minimumf(name, params, bitwidth):
+ cmpf_name = f"{name}_cmp"
+ cmpf_params = {k: v for k, v in params.items() if k != "extra_signals"}
+ cmpf_params["predicate"] = "olt"
+ dependencies = generate_cmpf(cmpf_name, cmpf_params)
+
+ entity = f"""
+library ieee;
+use ieee.std_logic_1164.all;
+
+-- Entity of minimumf
+entity {name} is
+ port(
+ clk: in std_logic;
+ rst: in std_logic;
+ -- input channel lhs
+ lhs: in std_logic_vector({bitwidth} - 1 downto 0);
+ lhs_valid: in std_logic;
+ lhs_ready: out std_logic;
+ -- input channel rhs
+ rhs: in std_logic_vector({bitwidth} - 1 downto 0);
+ rhs_valid: in std_logic;
+ rhs_ready: out std_logic;
+ -- output channel result
+ result : out std_logic_vector({bitwidth} - 1 downto 0);
+ result_valid: out std_logic;
+ result_ready: in std_logic
+ );
+end entity;
+"""
+
+ architecture = f"""
+-- Architecture of minimumf
+architecture arch of {name} is
+
+ signal cmp_result : std_logic_vector(0 downto 0);
+
+begin
+
+ cmp_inst: entity work.{cmpf_name}
+ port map (
+ clk => clk,
+ rst => rst,
+ lhs => lhs,
+ lhs_valid => lhs_valid,
+ lhs_ready => lhs_ready,
+ rhs => rhs,
+ rhs_valid => rhs_valid,
+ rhs_ready => rhs_ready,
+ result => cmp_result,
+ result_valid => result_valid,
+ result_ready => result_ready
+ );
+
+ result <= lhs when cmp_result = "1" else rhs;
+
+end architecture;
+"""
+
+ return dependencies + entity + architecture
diff --git a/experimental/tools/unit-generators/vhdl/generators/handshake/mulf.py b/experimental/tools/unit-generators/vhdl/generators/handshake/mulf.py
index 8839b631a0..ed5520aff4 100644
--- a/experimental/tools/unit-generators/vhdl/generators/handshake/mulf.py
+++ b/experimental/tools/unit-generators/vhdl/generators/handshake/mulf.py
@@ -1,270 +1,38 @@
-from generators.support.signal_manager import generate_buffered_signal_manager
-from generators.handshake.join import generate_join
-from generators.support.delay_buffer import generate_delay_buffer
-from generators.handshake.buffers.one_slot_break_dv import generate_one_slot_break_dv
+from generators.support.arith_ip import generate_flopoco_ip_wrapper, generate_vivado_ip_wrapper
+from generators.support.utils import VIVADO_IMPL, FLOPOCO_IMPL
def generate_mulf(name, params):
- is_double = params["is_double"]
- extra_signals = params["extra_signals"]
-
- if extra_signals:
- return _generate_mulf_signal_manager(name, is_double, extra_signals)
- else:
- return _generate_mulf(name, is_double)
-
-
-def _generate_mulf(name, is_double):
- if is_double:
- return _generate_mulf_double_precision(name)
- else:
- return _generate_mulf_single_precision(name)
-
-
-def _get_latency(is_double):
- # doesn't depend on the bitwidth
- return 4
-
-
-def _generate_mulf_single_precision(name):
- join_name = f"{name}_join"
- buff_name = f"{name}_buff"
- one_slot_break_dv_name = f"{name}_one_slot_break_dv"
-
- dependencies = generate_join(join_name, {"size": 2}) + \
- generate_delay_buffer(buff_name, {"slots": _get_latency(is_double=False) - 1}) + \
- generate_one_slot_break_dv(one_slot_break_dv_name, {"bitwidth": 0})
-
- entity = f"""
-library ieee;
-use ieee.std_logic_1164.all;
-use ieee.numeric_std.all;
-
--- Entity of mulf_single_precision
-entity {name} is
- port (
- -- inputs
- clk : in std_logic;
- rst : in std_logic;
- lhs : in std_logic_vector(32 - 1 downto 0);
- lhs_valid : in std_logic;
- rhs : in std_logic_vector(32 - 1 downto 0);
- rhs_valid : in std_logic;
- result_ready : in std_logic;
- -- outputs
- result : out std_logic_vector(32 - 1 downto 0);
- result_valid : out std_logic;
- lhs_ready : out std_logic;
- rhs_ready : out std_logic
- );
-end entity;
-"""
-
- architecture = f"""
--- Architecture of mulf_single_precision
-architecture arch of {name} is
- signal join_valid : std_logic;
- signal buff_valid, one_slot_break_dv_ready : std_logic;
-
- -- intermediate input signals for IEEE-754 to Flopoco-simple-float conversion
- signal ip_lhs, ip_rhs : std_logic_vector(32 + 1 downto 0);
-
- -- intermediate output signal for Flopoco-simple-float to IEEE-754 conversion
- signal ip_result : std_logic_vector(32 + 1 downto 0);
-begin
- join_inputs : entity work.{join_name}(arch)
- port map(
- -- inputs
- ins_valid(0) => lhs_valid,
- ins_valid(1) => rhs_valid,
- outs_ready => one_slot_break_dv_ready,
- -- outputs
- outs_valid => join_valid,
- ins_ready(0) => lhs_ready,
- ins_ready(1) => rhs_ready
- );
-
- buff : entity work.{buff_name}(arch)
- port map(
- clk,
- rst,
- join_valid,
- one_slot_break_dv_ready,
- buff_valid
- );
-
- one_slot_break_dv : entity work.{one_slot_break_dv_name}(arch)
- port map(
- clk => clk,
- rst => rst,
- ins_valid => buff_valid,
- outs_ready => result_ready,
- outs_valid => result_valid,
- ins_ready => one_slot_break_dv_ready
- );
-
- ieee2nfloat_lhs: entity work.InputIEEE_32bit(arch)
- port map (
- X => lhs,
- R => ip_lhs
- );
-
- ieee2nfloat_rhs: entity work.InputIEEE_32bit(arch)
- port map (
- X => rhs,
- R => ip_rhs
- );
-
- nfloat2ieee_result : entity work.OutputIEEE_32bit(arch)
- port map (
- X => ip_result,
- R => result
- );
-
- ip : entity work.FloatingPointMultiplier(arch)
- port map (
- clk => clk,
- ce => one_slot_break_dv_ready,
- X => ip_lhs,
- Y => ip_rhs,
- R => ip_result
- );
-end architecture;
-"""
-
- return dependencies + entity + architecture
-
-
-def _generate_mulf_double_precision(name):
- join_name = f"{name}_join"
- one_slot_break_dv_name = f"{name}_one_slot_break_dv"
- buff_name = f"{name}_buff"
-
- dependencies = generate_join(join_name, {"size": 2}) + \
- generate_one_slot_break_dv(one_slot_break_dv_name, {"bitwidth": 0}) + \
- generate_delay_buffer(
- buff_name, {"slots": _get_latency(is_double=True) - 1})
-
- entity = f"""
-library ieee;
-use ieee.std_logic_1164.all;
-use ieee.numeric_std.all;
-
--- Entity of mulf_double_precision
-entity {name} is
- port (
- -- inputs
- clk : in std_logic;
- rst : in std_logic;
- lhs : in std_logic_vector(64 - 1 downto 0);
- lhs_valid : in std_logic;
- rhs : in std_logic_vector(64 - 1 downto 0);
- rhs_valid : in std_logic;
- result_ready : in std_logic;
- -- outputs
- result : out std_logic_vector(64 - 1 downto 0);
- result_valid : out std_logic;
- lhs_ready : out std_logic;
- rhs_ready : out std_logic
- );
-end entity;
-"""
-
- architecture = f"""
--- Architecture of mulf_double_precision
-architecture arch of {name} is
- signal join_valid : std_logic;
- signal buff_valid, one_slot_break_dv_ready : std_logic;
-
- -- intermediate input signals for IEEE-754 to Flopoco-simple-float conversion
- signal ip_lhs, ip_rhs : std_logic_vector(64 + 1 downto 0);
-
- -- intermediate output signal for Flopoco-simple-float to IEEE-754 conversion
- signal ip_result : std_logic_vector(64 + 1 downto 0);
-begin
- join_inputs : entity work.{join_name}(arch)
- port map(
- -- inputs
- ins_valid(0) => lhs_valid,
- ins_valid(1) => rhs_valid,
- outs_ready => one_slot_break_dv_ready,
- -- outputs
- outs_valid => join_valid,
- ins_ready(0) => lhs_ready,
- ins_ready(1) => rhs_ready
- );
-
- buff : entity work.{buff_name}(arch)
- port map(
- clk,
- rst,
- join_valid,
- one_slot_break_dv_ready,
- buff_valid
- );
-
- one_slot_break_dv : entity work.{one_slot_break_dv_name}(arch)
- port map(
- clk => clk,
- rst => rst,
- ins_valid => buff_valid,
- outs_ready => result_ready,
- outs_valid => result_valid,
- ins_ready => one_slot_break_dv_ready,
- ins(0) => '0',
- outs => open
- );
-
- ieee2nfloat_lhs: entity work.InputIEEE_64bit(arch)
- port map (
- X => lhs,
- R => ip_lhs
- );
-
- ieee2nfloat_rhs: entity work.InputIEEE_64bit(arch)
- port map (
- X => rhs,
- R => ip_rhs
- );
-
- nfloat2ieee_result : entity work.OutputIEEE_64bit(arch)
- port map (
- X => ip_result,
- R => result
- );
-
- ip : entity work.FPMult_64bit(arch)
- port map (
- clk => clk,
- ce => one_slot_break_dv_ready,
- X => ip_lhs,
- Y => ip_rhs,
- R => ip_result
- );
-end architecture;
-"""
-
- return dependencies + entity + architecture
-
-
-def _generate_mulf_signal_manager(name, is_double, extra_signals):
- bitwidth = 64 if is_double else 32
- return generate_buffered_signal_manager(
- name,
- [{
- "name": "lhs",
- "bitwidth": bitwidth,
- "extra_signals": extra_signals
- }, {
- "name": "rhs",
- "bitwidth": bitwidth,
- "extra_signals": extra_signals
- }],
- [{
- "name": "result",
- "bitwidth": bitwidth,
- "extra_signals": extra_signals
- }],
- extra_signals,
- lambda name: _generate_mulf(name, is_double),
- _get_latency(is_double))
+ impl = params["fpu_impl"]
+ latency = params["latency"]
+
+ extra_signals = params.get("extra_signals", None)
+
+ # only used for flopoco
+ is_double = params.get("is_double", None)
+ internal_delay = params.get("internal_delay", None)
+
+ handshake_op = "mulf"
+
+ if impl == FLOPOCO_IMPL:
+ if is_double is None:
+ raise ValueError(f"is_double was missing for generating a flopoco {handshake_op}")
+ if internal_delay is None:
+ raise ValueError(f"internal_delay was missing for generating a flopoco {handshake_op}")
+
+ return generate_flopoco_ip_wrapper(
+ name=name,
+ handshake_op=handshake_op,
+ core_unit="FloatingPointMultiplier",
+ latency=latency,
+ is_double=is_double,
+ internal_delay=internal_delay,
+ extra_signals=extra_signals
+ )
+ elif impl == VIVADO_IMPL:
+ return generate_vivado_ip_wrapper(
+ name=name,
+ handshake_op=handshake_op,
+ latency=latency,
+ extra_signals=extra_signals
+ )
diff --git a/experimental/tools/unit-generators/vhdl/generators/handshake/muli.py b/experimental/tools/unit-generators/vhdl/generators/handshake/muli.py
index 249dfce1bb..b5646e792b 100644
--- a/experimental/tools/unit-generators/vhdl/generators/handshake/muli.py
+++ b/experimental/tools/unit-generators/vhdl/generators/handshake/muli.py
@@ -1,61 +1,28 @@
-from generators.support.signal_manager import generate_buffered_signal_manager
-from generators.handshake.join import generate_join
-from generators.support.delay_buffer import generate_delay_buffer
-from generators.handshake.buffers.one_slot_break_dv import generate_one_slot_break_dv
+from generators.support.arith_binary import generate_arith_binary
def generate_muli(name, params):
bitwidth = params["bitwidth"]
- extra_signals = params.get("extra_signals", None)
-
- if extra_signals:
- return _generate_muli_signal_manager(name, bitwidth, extra_signals)
- else:
- return _generate_muli(name, bitwidth)
-
-
-def _get_latency():
- return 4
-
-
-def _generate_mul_4_stage(name, bitwidth):
- entity = f"""
-library ieee;
-use ieee.std_logic_1164.all;
-use ieee.numeric_std.all;
-
--- Entity of mul_4_stage
-entity {name} is
- port (
- clk : in std_logic;
- ce : in std_logic;
- a : in std_logic_vector({bitwidth} - 1 downto 0);
- b : in std_logic_vector({bitwidth} - 1 downto 0);
- p : out std_logic_vector({bitwidth} - 1 downto 0));
-end entity;
-"""
-
- architecture = f"""
--- Architecture of mul_4_stage
-architecture behav of {name} is
+ latency = params["latency"]
+ signals = f"""
signal a_reg : std_logic_vector({bitwidth} - 1 downto 0);
signal b_reg : std_logic_vector({bitwidth} - 1 downto 0);
signal q0 : std_logic_vector({bitwidth} - 1 downto 0);
signal q1 : std_logic_vector({bitwidth} - 1 downto 0);
signal q2 : std_logic_vector({bitwidth} - 1 downto 0);
signal mul : std_logic_vector({bitwidth} - 1 downto 0);
+ """
-begin
-
+ body = f"""
mul <= std_logic_vector(resize(unsigned(std_logic_vector(signed(a_reg) * signed(b_reg))), {bitwidth}));
process (clk)
begin
if (clk'event and clk = '1') then
- if (ce = '1') then
- a_reg <= a;
- b_reg <= b;
+ if (valid_buffer_ready = '1') then
+ a_reg <= lhs;
+ b_reg <= rhs;
q0 <= mul;
q1 <= q0;
q2 <= q1;
@@ -63,120 +30,15 @@ def _generate_mul_4_stage(name, bitwidth):
end if;
end process;
- p <= q2;
-end architecture;
-"""
-
- return entity + architecture
-
-
-def _generate_muli(name, bitwidth):
- join_name = f"{name}_join"
- mul_4_stage_name = f"{name}_mul_4_stage"
- buff_name = f"{name}_buff"
- one_slot_break_dv_name = f"{name}_one_slot_break_dv"
-
- dependencies = \
- generate_join(join_name, {"size": 2}) + \
- _generate_mul_4_stage(mul_4_stage_name, bitwidth) + \
- generate_delay_buffer(buff_name, {"slots": _get_latency() - 1}) + \
- generate_one_slot_break_dv(one_slot_break_dv_name, {"bitwidth": bitwidth})
-
- entity = f"""
-library ieee;
-use ieee.std_logic_1164.all;
-use ieee.numeric_std.all;
-
--- Entity of muli
-entity {name} is
- port (
- -- inputs
- clk, rst : in std_logic;
- lhs : in std_logic_vector({bitwidth} - 1 downto 0);
- lhs_valid : in std_logic;
- rhs : in std_logic_vector({bitwidth} - 1 downto 0);
- rhs_valid : in std_logic;
- result_ready : in std_logic;
- -- outputs
- result : out std_logic_vector({bitwidth} - 1 downto 0);
- result_valid : out std_logic;
- lhs_ready : out std_logic;
- rhs_ready : out std_logic
- );
-end entity;
-"""
-
- architecture = f"""
--- Architecture of muli
-architecture arch of {name} is
- signal join_valid : std_logic;
- signal buff_valid, one_slot_break_dv_valid, one_slot_break_dv_ready : std_logic;
- signal one_slot_break_dv_dataOut, one_slot_break_dv_datain : std_logic_vector({bitwidth} - 1 downto 0);
-begin
- join_inputs : entity work.{join_name}(arch)
- port map(
- -- inputs
- ins_valid(0) => lhs_valid,
- ins_valid(1) => rhs_valid,
- outs_ready => one_slot_break_dv_ready,
- -- outputs
- outs_valid => join_valid,
- ins_ready(0) => lhs_ready,
- ins_ready(1) => rhs_ready
- );
-
- multiply_unit : entity work.{mul_4_stage_name}(behav)
- port map(
- clk => clk,
- ce => one_slot_break_dv_ready,
- a => lhs,
- b => rhs,
- p => result
- );
-
- buff : entity work.{buff_name}(arch)
- port map(
- clk,
- rst,
- join_valid,
- one_slot_break_dv_ready,
- buff_valid
- );
-
- one_slot_break_dv : entity work.{one_slot_break_dv_name}(arch)
- port map(
- clk => clk,
- rst => rst,
- ins_valid => buff_valid,
- outs_ready => result_ready,
- outs_valid => result_valid,
- ins_ready => one_slot_break_dv_ready,
- ins => one_slot_break_dv_datain,
- outs => one_slot_break_dv_dataOut
- );
-end architecture;
-"""
-
- return dependencies + entity + architecture
-
-
-def _generate_muli_signal_manager(name, bitwidth, extra_signals):
- return generate_buffered_signal_manager(
- name,
- [{
- "name": "lhs",
- "bitwidth": bitwidth,
- "extra_signals": extra_signals
- }, {
- "name": "rhs",
- "bitwidth": bitwidth,
- "extra_signals": extra_signals
- }],
- [{
- "name": "result",
- "bitwidth": bitwidth,
- "extra_signals": extra_signals
- }],
- extra_signals,
- lambda name: _generate_muli(name, bitwidth),
- _get_latency())
+ result <= q2;
+ """
+
+ return generate_arith_binary(
+ name=name,
+ handshake_op="muli",
+ bitwidth=bitwidth,
+ signals=signals,
+ body=body,
+ extra_signals=params.get("extra_signals", None),
+ latency=latency
+ )
diff --git a/experimental/tools/unit-generators/vhdl/generators/handshake/ndwire.py b/experimental/tools/unit-generators/vhdl/generators/handshake/ndwire.py
new file mode 100644
index 0000000000..3824b64480
--- /dev/null
+++ b/experimental/tools/unit-generators/vhdl/generators/handshake/ndwire.py
@@ -0,0 +1,94 @@
+from generators.support.utils import data
+from generators.support.signal_manager import generate_unary_signal_manager
+
+
+def generate_ndwire(name, params):
+ bitwidth = params["bitwidth"]
+ extra_signals = params.get("extra_signals", None)
+
+ def generate_inner(name): return _generate_ndwire(name, bitwidth)
+ def generate(): return generate_inner(name)
+
+ if extra_signals:
+ return generate_unary_signal_manager(
+ name=name,
+ bitwidth=bitwidth,
+ generate_inner=generate_inner,
+ extra_signals=extra_signals
+ )
+ else:
+ return generate()
+
+
+def _generate_ndwire(name: str, bitwidth: int) -> str:
+ # only included if bitwidth > 0
+ potential_input = f"ins : in std_logic_vector({bitwidth} - 1 downto 0);"
+ potential_output = f"outs : out std_logic_vector({bitwidth} - 1 downto 0);"
+ potential_assignment = "outs <= ins;"
+
+ entity = f"""
+library ieee;
+use ieee.std_logic_1164.all;
+use ieee.numeric_std.all;
+
+-- Entity of ndwire
+entity {name} is
+ port (
+ clk, rst : in std_logic;
+ -- input channel
+ ins_valid : in std_logic;
+ ins_ready : out std_logic;
+ {data(potential_input, bitwidth)}
+ -- output channel
+ outs_valid : out std_logic;
+ outs_ready : in std_logic
+ {data(potential_output, bitwidth)}
+ );
+end entity;
+
+"""
+
+ architecture = f"""
+-- Architecture of ndwire
+architecture arch of {name} is
+ type nd_state_t is (SLEEPING, RUNNING);
+ signal state, next_state : nd_state_t;
+
+ -- This is the source of non-determism.
+ -- It needs to be set to a primary input in a formal tool
+ -- If the formal tools does not implicitly treat undriven signals
+ -- like primary inputs this needs to be done explicitly.
+ signal nd_next_state : nd_state_t;
+
+begin
+ process (clk, rst)
+ begin
+ -- The initialization of the state is non-deterministic
+ if rst = '1' then
+ state <= nd_next_state;
+ elsif rising_edge(clk) then
+ state <= next_state;
+ end if;
+ end process;
+
+ process (state, ins_valid, outs_ready)
+ begin
+ -- If the wire is sleeping it can always switch to the running state.
+ -- If (ins_valid and outs_ready) we either have a transaction
+ -- and can freely choose the state again.
+ if (state = SLEEPING) then
+ next_state <= nd_next_state;
+ elsif (ins_valid and outs_ready) then
+ next_state <= nd_next_state;
+ else
+ next_state <= state;
+ end if;
+ end process;
+
+ ins_ready <= outs_ready and (state = RUNNING);
+ outs_valid <= ins_valid and (state = RUNNING);
+ {data(potential_assignment, bitwidth)}
+
+end architecture;
+"""
+ return entity + architecture
diff --git a/experimental/tools/unit-generators/vhdl/generators/handshake/negf.py b/experimental/tools/unit-generators/vhdl/generators/handshake/negf.py
new file mode 100644
index 0000000000..1dbbc70b85
--- /dev/null
+++ b/experimental/tools/unit-generators/vhdl/generators/handshake/negf.py
@@ -0,0 +1,18 @@
+from generators.support.unary import generate_unary
+
+
+def generate_negf(name, params):
+ bitwidth = params.get("bitwidth", None)
+
+ body = f"""
+ outs({bitwidth} - 1) <= ins({bitwidth} - 1) xor '1';
+ outs({bitwidth} - 2 downto 0) <= ins({bitwidth} - 2 downto 0);
+ """
+
+ return generate_unary(
+ name=name,
+ handshake_op="negf",
+ bitwidth=bitwidth,
+ body=body,
+ extra_signals=params.get("extra_signals", None)
+ )
diff --git a/experimental/tools/unit-generators/vhdl/generators/handshake/ori.py b/experimental/tools/unit-generators/vhdl/generators/handshake/ori.py
new file mode 100644
index 0000000000..0012936738
--- /dev/null
+++ b/experimental/tools/unit-generators/vhdl/generators/handshake/ori.py
@@ -0,0 +1,17 @@
+from generators.support.arith_binary import generate_arith_binary
+
+
+def generate_ori(name, params):
+ bitwidth = params["bitwidth"]
+
+ body = """
+ result <= lhs or rhs;
+ """
+
+ return generate_arith_binary(
+ name=name,
+ handshake_op="ori",
+ bitwidth=bitwidth,
+ body=body,
+ extra_signals=params.get("extra_signals", None)
+ )
diff --git a/experimental/tools/unit-generators/vhdl/generators/handshake/ready_remover.py b/experimental/tools/unit-generators/vhdl/generators/handshake/ready_remover.py
index dfec42b404..eb0870de2c 100644
--- a/experimental/tools/unit-generators/vhdl/generators/handshake/ready_remover.py
+++ b/experimental/tools/unit-generators/vhdl/generators/handshake/ready_remover.py
@@ -1,66 +1,46 @@
+from generators.support.utils import data
+from generators.support.signal_manager import generate_unary_signal_manager
+
def generate_ready_remover(name, params):
bitwidth = params["bitwidth"]
-
- if bitwidth > 0:
- return _generate_rigidifier(name, bitwidth)
+ extra_signals = params["extra_signals"]
+
+ def generate_inner(name): return _generate_ready_remover(name, bitwidth)
+ def generate(): return generate_inner(name)
+
+ if extra_signals:
+ return generate_unary_signal_manager(
+ name=name,
+ bitwidth=bitwidth,
+ extra_signals=extra_signals,
+ generate_inner=generate_inner
+ )
else:
- return _generate_rigidifier_dataless(name)
-
-
-def _generate_rigidifier(name, bitwidth):
-
- entity = f"""
-library ieee;
-use ieee.std_logic_1164.all;
-use ieee.numeric_std.all;
-
--- Entity of rigidifier
-entity {name} is
- port (
- -- inputs
- clk : in std_logic;
- rst : in std_logic;
- ins : in std_logic_vector({bitwidth} - 1 downto 0);
- ins_valid : in std_logic;
- outs_ready : in std_logic;
- -- outputs
- outs : out std_logic_vector({bitwidth} - 1 downto 0);
- outs_valid : out std_logic;
- ins_ready : out std_logic
- );
-end entity;
-"""
-
- architecture = f"""
--- Architecture of rigidifier
-architecture arch of {name} is
-begin
- outs <= ins;
- outs_valid <= ins_valid;
- ins_ready <= '1';
-end architecture;
-"""
-
- return entity + architecture
+ return generate()
-def _generate_rigidifier_dataless(name):
+def _generate_ready_remover(name, bitwidth):
+ potential_input = f"ins : in std_logic_vector({bitwidth} - 1 downto 0);"
+ potential_output = f"outs : out std_logic_vector({bitwidth} - 1 downto 0);"
+ potential_assignment = "outs <= ins;"
entity = f"""
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
--- Entity of rigidifier
+-- Entity of ready remover
entity {name} is
port (
-- inputs
clk : in std_logic;
rst : in std_logic;
+ {data(potential_input, bitwidth)}
ins_valid : in std_logic;
outs_ready : in std_logic;
-- outputs
+ {data(potential_output, bitwidth)}
outs_valid : out std_logic;
ins_ready : out std_logic
);
@@ -68,9 +48,10 @@ def _generate_rigidifier_dataless(name):
"""
architecture = f"""
--- Architecture of rigidifier
+-- Architecture of ready remover
architecture arch of {name} is
begin
+ {data(potential_assignment, bitwidth)}
outs_valid <= ins_valid;
ins_ready <= '1';
end architecture;
diff --git a/experimental/tools/unit-generators/vhdl/generators/handshake/remsi.py b/experimental/tools/unit-generators/vhdl/generators/handshake/remsi.py
new file mode 100644
index 0000000000..e1e5d5c142
--- /dev/null
+++ b/experimental/tools/unit-generators/vhdl/generators/handshake/remsi.py
@@ -0,0 +1,15 @@
+from generators.support.arith_ip import generate_vivado_ip_wrapper
+
+
+def generate_remsi(name, params):
+
+ latency = params["latency"]
+
+ extra_signals = params.get("extra_signals", None)
+
+ return generate_vivado_ip_wrapper(
+ name=name,
+ handshake_op="remsi",
+ latency=latency,
+ extra_signals=extra_signals
+ )
diff --git a/experimental/tools/unit-generators/vhdl/generators/handshake/shli.py b/experimental/tools/unit-generators/vhdl/generators/handshake/shli.py
index 222580a004..b81e590bd1 100644
--- a/experimental/tools/unit-generators/vhdl/generators/handshake/shli.py
+++ b/experimental/tools/unit-generators/vhdl/generators/handshake/shli.py
@@ -1,89 +1,17 @@
-from generators.support.signal_manager import generate_default_signal_manager
-from generators.handshake.join import generate_join
+from generators.support.arith_binary import generate_arith_binary
def generate_shli(name, params):
bitwidth = params["bitwidth"]
- extra_signals = params.get("extra_signals", None)
-
- if extra_signals:
- return _generate_shli_signal_manager(name, bitwidth, extra_signals)
- else:
- return _generate_shli(name, bitwidth)
-
-
-def _generate_shli(name, bitwidth):
- join_name = f"{name}_join"
-
- dependencies = \
- generate_join(join_name, {
- "size": 2
- })
-
- entity = f"""
-library ieee;
-use ieee.std_logic_1164.all;
-use ieee.numeric_std.all;
-
--- Entity of shli
-entity {name} is
- port (
- -- inputs
- clk : in std_logic;
- rst : in std_logic;
- lhs : in std_logic_vector({bitwidth} - 1 downto 0);
- lhs_valid : in std_logic;
- rhs : in std_logic_vector({bitwidth} - 1 downto 0);
- rhs_valid : in std_logic;
- result_ready : in std_logic;
- -- outputs
- result : out std_logic_vector({bitwidth} - 1 downto 0);
- result_valid : out std_logic;
- lhs_ready : out std_logic;
- rhs_ready : out std_logic
- );
-end entity;
-"""
-
- architecture = f"""
--- Architecture of shli
-architecture arch of {name} is
-begin
- join_inputs : entity work.{join_name}
- port map(
- -- inputs
- ins_valid(0) => lhs_valid,
- ins_valid(1) => rhs_valid,
- outs_ready => result_ready,
- -- outputs
- outs_valid => result_valid,
- ins_ready(0) => lhs_ready,
- ins_ready(1) => rhs_ready
- );
+ body = f"""
result <= std_logic_vector(shift_left(unsigned(lhs), to_integer(unsigned('0' & rhs({bitwidth} - 2 downto 0)))));
-end architecture;
-"""
-
- return dependencies + entity + architecture
-
-
-def _generate_shli_signal_manager(name, bitwidth, extra_signals):
- return generate_default_signal_manager(
- name,
- [{
- "name": "lhs",
- "bitwidth": bitwidth,
- "extra_signals": extra_signals
- }, {
- "name": "rhs",
- "bitwidth": bitwidth,
- "extra_signals": extra_signals
- }],
- [{
- "name": "result",
- "bitwidth": bitwidth,
- "extra_signals": extra_signals
- }],
- extra_signals,
- lambda name: _generate_shli(name, bitwidth))
+ """
+
+ return generate_arith_binary(
+ name=name,
+ handshake_op="shli",
+ bitwidth=bitwidth,
+ body=body,
+ extra_signals=params.get("extra_signals", None)
+ )
diff --git a/experimental/tools/unit-generators/vhdl/generators/handshake/shrsi.py b/experimental/tools/unit-generators/vhdl/generators/handshake/shrsi.py
new file mode 100644
index 0000000000..e2361229bc
--- /dev/null
+++ b/experimental/tools/unit-generators/vhdl/generators/handshake/shrsi.py
@@ -0,0 +1,17 @@
+from generators.support.arith_binary import generate_arith_binary
+
+
+def generate_shrsi(name, params):
+ bitwidth = params["bitwidth"]
+
+ body = f"""
+ result <= std_logic_vector(shift_right(signed(lhs), to_integer(signed('0' & rhs({bitwidth} - 2 downto 0)))));
+ """
+
+ return generate_arith_binary(
+ name=name,
+ handshake_op="shrsi",
+ bitwidth=bitwidth,
+ body=body,
+ extra_signals=params.get("extra_signals", None)
+ )
diff --git a/experimental/tools/unit-generators/vhdl/generators/handshake/shrui.py b/experimental/tools/unit-generators/vhdl/generators/handshake/shrui.py
new file mode 100644
index 0000000000..eef6560b19
--- /dev/null
+++ b/experimental/tools/unit-generators/vhdl/generators/handshake/shrui.py
@@ -0,0 +1,17 @@
+from generators.support.arith_binary import generate_arith_binary
+
+
+def generate_shrui(name, params):
+ bitwidth = params["bitwidth"]
+
+ body = f"""
+ result <= std_logic_vector(shift_right(unsigned(lhs), to_integer(unsigned('0' & rhs(DATA_TYPE - 2 downto 0)))));
+ """
+
+ return generate_arith_binary(
+ name=name,
+ handshake_op="shrui",
+ bitwidth=bitwidth,
+ body=body,
+ extra_signals=params.get("extra_signals", None)
+ )
diff --git a/experimental/tools/unit-generators/vhdl/generators/handshake/sitofp.py b/experimental/tools/unit-generators/vhdl/generators/handshake/sitofp.py
index b429a39ff3..a868d065c4 100644
--- a/experimental/tools/unit-generators/vhdl/generators/handshake/sitofp.py
+++ b/experimental/tools/unit-generators/vhdl/generators/handshake/sitofp.py
@@ -1,67 +1,20 @@
-from generators.support.signal_manager import generate_buffered_signal_manager
-from generators.support.delay_buffer import generate_delay_buffer
-from generators.handshake.buffers.one_slot_break_dv import generate_one_slot_break_dv
+from generators.support.unary import generate_unary
def generate_sitofp(name, params):
- bitwidth = params["bitwidth"]
- extra_signals = params["extra_signals"]
-
- if extra_signals:
- return _generate_sitofp_signal_manager(name, bitwidth, extra_signals)
- else:
- return _generate_sitofp(name, bitwidth)
-
-
-def _generate_sitofp(name, bitwidth):
- one_slot_break_dv_name = f"{name}_one_slot_break_dv"
- buff_name = f"{name}_buff"
-
- dependencies = generate_one_slot_break_dv(one_slot_break_dv_name, {"bitwidth": bitwidth}) + \
- generate_delay_buffer(
- buff_name, {"slots": 4})
-
- entity = f"""
-library ieee;
-use ieee.std_logic_1164.all;
-use ieee.numeric_std.all;
-use ieee.float_pkg.all;
-
--- Entity of sitofp
-entity {name} is
- port (
- -- inputs
- clk : in std_logic;
- rst : in std_logic;
- ins : in std_logic_vector({bitwidth} - 1 downto 0);
- ins_valid : in std_logic;
- outs_ready : in std_logic;
- -- outputs
- outs : out std_logic_vector({bitwidth} - 1 downto 0);
- outs_valid : out std_logic;
- ins_ready : out std_logic
- );
-begin
- assert {bitwidth}=32
- report "sitofp currently only supports 32-bit floating point operands"
- severity failure;
-end entity;
-"""
-
- architecture = f"""
--- Architecture of sitofp
-architecture arch of {name} is
- signal converted : std_logic_vector({bitwidth} - 1 downto 0);
- signal q0 : std_logic_vector({bitwidth} - 1 downto 0);
- signal q1 : std_logic_vector({bitwidth} - 1 downto 0);
- signal q2 : std_logic_vector({bitwidth} - 1 downto 0);
- signal q3 : std_logic_vector({bitwidth} - 1 downto 0);
- signal q4 : std_logic_vector({bitwidth} - 1 downto 0);
- signal buff_valid, one_slot_break_dv_ready : std_logic;
- signal one_slot_break_dv_dataOut, one_slot_break_dv_datain : std_logic_vector({bitwidth} - 1 downto 0);
+ latency = params["latency"]
+
+ signals = f"""
+ signal converted : std_logic_vector(32 - 1 downto 0);
+ signal q0 : std_logic_vector(32 - 1 downto 0);
+ signal q1 : std_logic_vector(32 - 1 downto 0);
+ signal q2 : std_logic_vector(32 - 1 downto 0);
+ signal q3 : std_logic_vector(32 - 1 downto 0);
+ signal q4 : std_logic_vector(32 - 1 downto 0);
signal float_value : float32;
-begin
+ """
+ body = f"""
float_value <= to_float(signed(ins));
converted <= to_std_logic_vector(float_value);
outs <= q4;
@@ -75,7 +28,7 @@ def _generate_sitofp(name, bitwidth):
q2 <= (others => '0');
q3 <= (others => '0');
q4 <= (others => '0');
- elsif (one_slot_break_dv_ready) then
+ elsif (valid_buffer_ready) then
q0 <= converted;
q1 <= q0;
q2 <= q1;
@@ -84,48 +37,15 @@ def _generate_sitofp(name, bitwidth):
end if;
end if;
end process;
-
- buff : entity work.{buff_name}(arch)
- port map(
- clk,
- rst,
- ins_valid,
- one_slot_break_dv_ready,
- buff_valid
- );
-
- one_slot_break_dv : entity work.{one_slot_break_dv_name}(arch)
- port map(
- clk => clk,
- rst => rst,
- ins_valid => buff_valid,
- outs_ready => outs_ready,
- outs_valid => outs_valid,
- ins_ready => one_slot_break_dv_ready,
- ins => one_slot_break_dv_datain,
- outs => one_slot_break_dv_dataOut
- );
- ins_ready <= one_slot_break_dv_ready;
-
-end architecture;
-"""
-
- return dependencies + entity + architecture
-
-
-def _generate_sitofp_signal_manager(name, bitwidth, extra_signals):
- return generate_buffered_signal_manager(
- name,
- [{
- "name": "ins",
- "bitwidth": bitwidth,
- "extra_signals": extra_signals
- }],
- [{
- "name": "outs",
- "bitwidth": bitwidth,
- "extra_signals": extra_signals
- }],
- extra_signals,
- lambda name: _generate_sitofp(name, bitwidth),
- 5)
+ """
+
+ return generate_unary(
+ name=name,
+ handshake_op="sitofp",
+ input_bitwidth=32,
+ output_bitwidth=32,
+ signals=signals,
+ body=body,
+ extra_signals=params.get("extra_signals", None),
+ latency=latency
+ )
diff --git a/experimental/tools/unit-generators/vhdl/generators/handshake/subf.py b/experimental/tools/unit-generators/vhdl/generators/handshake/subf.py
index 782e70b503..1c30e62bc1 100644
--- a/experimental/tools/unit-generators/vhdl/generators/handshake/subf.py
+++ b/experimental/tools/unit-generators/vhdl/generators/handshake/subf.py
@@ -1,280 +1,99 @@
-from generators.support.signal_manager import generate_buffered_signal_manager
-from generators.handshake.join import generate_join
-from generators.support.delay_buffer import generate_delay_buffer
-from generators.handshake.buffers.one_slot_break_dv import generate_one_slot_break_dv
+from generators.handshake.addf import generate_addf
+from generators.support.signal_manager import generate_arith_binary_signal_manager
+from generators.support.utils import VIVADO_IMPL, FLOPOCO_IMPL
def generate_subf(name, params):
- is_double = params["is_double"]
- extra_signals = params["extra_signals"]
+ latency = params["latency"]
- if extra_signals:
- return _generate_subf_signal_manager(name, is_double, extra_signals)
- else:
- return _generate_subf(name, is_double)
-
-
-def _generate_subf(name, is_double):
- if is_double:
- return _generate_subf_double_precision(name)
- else:
- return _generate_subf_single_precision(name)
-
-
-def _get_latency(is_double):
- return 12 if is_double else 9 # todo
-
-
-def _generate_subf_single_precision(name):
- join_name = f"{name}_join"
- one_slot_break_dv_name = f"{name}_one_slot_break_dv"
- buff_name = f"{name}_buff"
-
- dependencies = generate_join(join_name, {"size": 2}) + \
- generate_one_slot_break_dv(one_slot_break_dv_name, {"bitwidth": 0}) + \
- generate_delay_buffer(
- buff_name, {"slots": _get_latency(is_double=False) - 1})
-
- entity = f"""
-library ieee;
-use ieee.std_logic_1164.all;
-use ieee.numeric_std.all;
-
--- Entity of subf_single_precision
-entity {name} is
- port (
- -- inputs
- clk : in std_logic;
- rst : in std_logic;
- lhs : in std_logic_vector(32 - 1 downto 0);
- lhs_valid : in std_logic;
- rhs : in std_logic_vector(32 - 1 downto 0);
- rhs_valid : in std_logic;
- result_ready : in std_logic;
- -- outputs
- result : out std_logic_vector(32 - 1 downto 0);
- result_valid : out std_logic;
- lhs_ready : out std_logic;
- rhs_ready : out std_logic
- );
-end entity;
-"""
-
- architecture = f"""
--- Architecture of subf_single_precision
-architecture arch of {name} is
- signal join_valid : std_logic;
- signal buff_valid, one_slot_break_dv_valid, one_slot_break_dv_ready : std_logic;
-
- -- subf is the same as addf, but we flip the sign bit of rhs
- signal rhs_neg : std_logic_vector(32 - 1 downto 0);
-
- -- intermediate input signals for IEEE-754 to Flopoco-simple-float conversion
- signal ip_lhs, ip_rhs : std_logic_vector(32 + 1 downto 0);
-
- -- intermediate output signal for Flopoco-simple-float to IEEE-754 conversion
- signal ip_result : std_logic_vector(32 + 1 downto 0);
-begin
- join_inputs : entity work.{join_name}(arch)
- port map(
- -- inputs
- ins_valid(0) => lhs_valid,
- ins_valid(1) => rhs_valid,
- outs_ready => one_slot_break_dv_ready,
- -- outputs
- outs_valid => join_valid,
- ins_ready(0) => lhs_ready,
- ins_ready(1) => rhs_ready
- );
-
- one_slot_break_dv : entity work.{one_slot_break_dv_name}(arch)
- port map(
- clk => clk,
- rst => rst,
- ins_valid => buff_valid,
- outs_ready => result_ready,
- outs_valid => result_valid,
- ins_ready => one_slot_break_dv_ready
- );
-
- rhs_neg <= not rhs(32 - 1) & rhs(32 - 2 downto 0);
+ fpu_impl = params["fpu_impl"]
- buff : entity work.{buff_name}(arch)
- port map(
- clk,
- rst,
- join_valid,
- one_slot_break_dv_ready,
- buff_valid
- );
+ extra_signals = params.get("extra_signals", None)
- ieee2nfloat_0 : entity work.InputIEEE_32bit(arch)
- port map(
- X => lhs,
- R => ip_lhs
- );
+ # flopoco only
+ is_double = params.get("is_double", None)
- ieee2nfloat_1 : entity work.InputIEEE_32bit(arch)
- port map(
- X => rhs_neg,
- R => ip_rhs
- );
+ if fpu_impl == VIVADO_IMPL:
+ bitwidth = 32
+ elif fpu_impl == FLOPOCO_IMPL:
+ if is_double is None:
+ raise ValueError("is_double was missing for generating a flopoco subf")
+ bitwidth = 64 if is_double else 32
- nfloat2ieee : entity work.OutputIEEE_32bit(arch)
- port map(
- X => ip_result,
- R => result
- );
+ def generate_inner(name): return _generate_subf(name, params, bitwidth)
+ def generate(): return generate_inner(name)
- operator : entity work.FloatingPointAdder(arch)
- port map(
- clk => clk,
- ce => one_slot_break_dv_ready,
- X => ip_lhs,
- Y => ip_rhs,
- R => ip_result
- );
-end architecture;
-"""
-
- return dependencies + entity + architecture
+ if extra_signals:
+ return generate_arith_binary_signal_manager(
+ name=name,
+ bitwidth=bitwidth,
+ extra_signals=extra_signals,
+ generate_inner=generate_inner,
+ latency=latency
+ )
+ else:
+ return generate()
-def _generate_subf_double_precision(name):
- join_name = f"{name}_join"
- one_slot_break_dv_name = f"{name}_one_slot_break_dv"
- buff_name = f"{name}_buff"
+def _generate_subf(name, params, bitwidth):
- dependencies = generate_join(join_name, {"size": 2}) + \
- generate_one_slot_break_dv(one_slot_break_dv_name, {"bitwidth": 1}) + \
- generate_delay_buffer(
- buff_name, {"slots": _get_latency(is_double=True) - 1})
+ addf_name = f"{name}_addf"
+ addf_params = {k: v for k, v in params.items() if k != "extra_signals"}
+ dependencies = generate_addf(addf_name, addf_params)
entity = f"""
library ieee;
use ieee.std_logic_1164.all;
-use ieee.numeric_std.all;
--- Entity of subf_double_precision
+-- Entity of subf
entity {name} is
- port (
- -- inputs
- clk : in std_logic;
- rst : in std_logic;
- lhs : in std_logic_vector(64 - 1 downto 0);
- lhs_valid : in std_logic;
- rhs : in std_logic_vector(64 - 1 downto 0);
- rhs_valid : in std_logic;
- result_ready : in std_logic;
- -- outputs
- result : out std_logic_vector(64 - 1 downto 0);
- result_valid : out std_logic;
- lhs_ready : out std_logic;
- rhs_ready : out std_logic
+ port(
+ clk: in std_logic;
+ rst: in std_logic;
+ -- input channel lhs
+ lhs: in std_logic_vector({bitwidth} - 1 downto 0);
+ lhs_valid: in std_logic;
+ lhs_ready: out std_logic;
+ -- input channel rhs
+ rhs: in std_logic_vector({bitwidth} - 1 downto 0);
+ rhs_valid: in std_logic;
+ rhs_ready: out std_logic;
+ -- output channel result
+ result : out std_logic_vector({bitwidth} - 1 downto 0);
+ result_valid: out std_logic;
+ result_ready: in std_logic
);
end entity;
"""
architecture = f"""
--- Architecture of subf_double_precision
+-- Architecture of subf
architecture arch of {name} is
- signal join_valid : std_logic;
- signal buff_valid, one_slot_break_dv_valid, one_slot_break_dv_ready : std_logic;
-
-- subf is the same as addf, but we flip the sign bit of rhs
- signal rhs_neg : std_logic_vector(64 - 1 downto 0);
-
- -- intermediate input signals for IEEE-754 to Flopoco-simple-float conversion
- signal ip_lhs, ip_rhs : std_logic_vector(64 + 1 downto 0);
-
- -- intermediate output signal for Flopoco-simple-float to IEEE-754 conversion
- signal ip_result : std_logic_vector(64 + 1 downto 0);
+ signal rhs_neg : std_logic_vector({bitwidth} - 1 downto 0);
begin
- join_inputs : entity work.{join_name}(arch)
- port map(
- -- inputs
- ins_valid(0) => lhs_valid,
- ins_valid(1) => rhs_valid,
- outs_ready => one_slot_break_dv_ready,
- -- outputs
- outs_valid => join_valid,
- ins_ready(0) => lhs_ready,
- ins_ready(1) => rhs_ready
- );
- one_slot_break_dv : entity work.{one_slot_break_dv_name}(arch)
- port map(
- clk => clk,
- rst => rst,
- ins_valid => buff_valid,
- outs_ready => result_ready,
- outs_valid => result_valid,
- ins_ready => one_slot_break_dv_ready,
- ins(0) => '0',
- outs => open
- );
-
- rhs_neg <= not rhs(64 - 1) & rhs(64 - 2 downto 0);
-
- buff : entity work.{buff_name}(arch)
- port map(
- clk,
- rst,
- join_valid,
- one_slot_break_dv_ready,
- buff_valid
- );
-
- ieee2nfloat_0 : entity work.InputIEEE_64bit(arch)
- port map(
- X => lhs,
- R => ip_lhs
- );
- ieee2nfloat_1 : entity work.InputIEEE_64bit(arch)
- port map(
- X => rhs_neg,
- R => ip_rhs
- );
-
- nfloat2ieee : entity work.OutputIEEE_64bit(arch)
- port map(
- X => ip_result,
- R => result
- );
-
- operator : entity work.FPAdd_64bit(arch)
- port map(
- clk => clk,
- ce => one_slot_break_dv_ready,
- X => ip_lhs,
- Y => ip_rhs,
- R => ip_result
- );
+ rhs_neg <= not rhs({bitwidth} - 1) & rhs({bitwidth} - 2 downto 0);
+
+ FloatingPointAdder_U1: entity work.{addf_name}
+ port map (
+ clk => clk,
+ rst => rst,
+ -- input channel from "lhs"
+ lhs => lhs,
+ lhs_valid => lhs_valid,
+ lhs_ready => lhs_ready,
+ -- input channel from "rhs", made negative
+ rhs => rhs_neg,
+ rhs_valid => rhs_valid,
+ rhs_ready => rhs_ready,
+ --output channel to "result"
+ result => result,
+ result_valid => result_valid,
+ result_ready => result_ready
+ );
end architecture;
"""
return dependencies + entity + architecture
-
-
-def _generate_subf_signal_manager(name, is_double, extra_signals):
- bitwidth = 64 if is_double else 32
- return generate_buffered_signal_manager(
- name,
- [{
- "name": "lhs",
- "bitwidth": bitwidth,
- "extra_signals": extra_signals
- }, {
- "name": "rhs",
- "bitwidth": bitwidth,
- "extra_signals": extra_signals
- }],
- [{
- "name": "result",
- "bitwidth": bitwidth,
- "extra_signals": extra_signals
- }],
- extra_signals,
- lambda name: _generate_subf(name, is_double),
- _get_latency(is_double))
diff --git a/experimental/tools/unit-generators/vhdl/generators/handshake/subi.py b/experimental/tools/unit-generators/vhdl/generators/handshake/subi.py
index c0a4fe5f2c..3fb7503c05 100644
--- a/experimental/tools/unit-generators/vhdl/generators/handshake/subi.py
+++ b/experimental/tools/unit-generators/vhdl/generators/handshake/subi.py
@@ -1,86 +1,17 @@
-from generators.support.signal_manager import generate_default_signal_manager
-from generators.handshake.join import generate_join
+from generators.support.arith_binary import generate_arith_binary
def generate_subi(name, params):
bitwidth = params["bitwidth"]
- extra_signals = params["extra_signals"]
-
- if extra_signals:
- return _generate_subi_signal_manager(name, bitwidth, extra_signals)
- else:
- return _generate_subi(name, bitwidth)
-
-
-def _generate_subi(name, bitwidth):
- join_name = f"{name}_join"
-
- dependencies = generate_join(join_name, {"size": 2})
-
- entity = f"""
-library ieee;
-use ieee.std_logic_1164.all;
-use ieee.numeric_std.all;
-
--- Entity of subi
-entity {name} is
- port (
- -- inputs
- clk : in std_logic;
- rst : in std_logic;
- lhs : in std_logic_vector({bitwidth} - 1 downto 0);
- lhs_valid : in std_logic;
- rhs : in std_logic_vector({bitwidth} - 1 downto 0);
- rhs_valid : in std_logic;
- result_ready : in std_logic;
- -- outputs
- result : out std_logic_vector({bitwidth} - 1 downto 0);
- result_valid : out std_logic;
- lhs_ready : out std_logic;
- rhs_ready : out std_logic
- );
-end entity;
-"""
-
- architecture = f"""
--- Architecture of subi
-architecture arch of {name} is
-begin
- join_inputs : entity work.{join_name}(arch)
- port map(
- -- inputs
- ins_valid(0) => lhs_valid,
- ins_valid(1) => rhs_valid,
- outs_ready => result_ready,
- -- outputs
- outs_valid => result_valid,
- ins_ready(0) => lhs_ready,
- ins_ready(1) => rhs_ready
- );
+ body = """
result <= std_logic_vector(unsigned(lhs) - unsigned(rhs));
-end architecture;
-"""
-
- return dependencies + entity + architecture
-
-
-def _generate_subi_signal_manager(name, bitwidth, extra_signals):
- return generate_default_signal_manager(
- name,
- [{
- "name": "lhs",
- "bitwidth": bitwidth,
- "extra_signals": extra_signals
- }, {
- "name": "rhs",
- "bitwidth": bitwidth,
- "extra_signals": extra_signals
- }],
- [{
- "name": "result",
- "bitwidth": bitwidth,
- "extra_signals": extra_signals
- }],
- extra_signals,
- lambda name: _generate_subi(name, bitwidth))
+ """
+
+ return generate_arith_binary(
+ name=name,
+ handshake_op="subi",
+ bitwidth=bitwidth,
+ body=body,
+ extra_signals=params.get("extra_signals", None)
+ )
diff --git a/experimental/tools/unit-generators/vhdl/generators/handshake/top_join.py b/experimental/tools/unit-generators/vhdl/generators/handshake/top_join.py
new file mode 100644
index 0000000000..a807f388dc
--- /dev/null
+++ b/experimental/tools/unit-generators/vhdl/generators/handshake/top_join.py
@@ -0,0 +1,87 @@
+from generators.support.signal_manager import generate_default_signal_manager
+from generators.support.logic import generate_and_n
+
+
+def generate_top_join(name, params):
+ size = params["size"]
+ extra_signals = params.get("extra_signals", None)
+
+ size = params["size"]
+
+ if extra_signals:
+ return _generate_top_join_signal_manager(name, size, extra_signals)
+ else:
+ return _generate_top_join(name, size)
+
+
+def _generate_top_join(name, size):
+
+ and_n_module_name = f"{name}_and_n"
+ dependencies = generate_and_n(and_n_module_name, {"size": size})
+
+ entity = f"""
+library ieee;
+use ieee.std_logic_1164.all;
+use ieee.numeric_std.all;
+
+-- Entity of top_join
+entity {name} is
+ port (
+ -- inputs
+ clk : in std_logic;
+ rst : in std_logic;
+ ins_valid : in std_logic_vector({size} - 1 downto 0);
+ outs_ready : in std_logic;
+ -- outputs
+ outs_valid : out std_logic;
+ ins_ready : in std_logic_vector({size} - 1 downto 0);
+ );
+end entity;
+
+"""
+
+ architecture = f"""
+-- Architecture of top_join
+architecture arch of {name} is
+ signal allValid : std_logic;
+begin
+ allValidAndGate : entity work.{and_n_module_name} port map(ins_valid, allValid);
+ outs_valid <= allValid;
+
+ process (ins_valid, outs_ready)
+ variable singlePValid : std_logic_vector({size} - 1 downto 0);
+ begin
+ for i in 0 to {size} - 1 loop
+ singlePValid(i) := '1';
+ for j in 0 to {size} - 1 loop
+ if (i /= j) then
+ singlePValid(i) := (singlePValid(i) and ins_valid(j));
+ end if;
+ end loop;
+ end loop;
+ for i in 0 to {size} - 1 loop
+ ins_ready(i) <= (singlePValid(i) and outs_ready);
+ end loop;
+ end process;
+
+end architecture;
+"""
+
+ return dependencies + entity + architecture
+
+
+def _generate_top_join_signal_manager(name, size, extra_signals):
+ return generate_default_signal_manager(
+ name,
+ [{
+ "name": "ins",
+ "bitwidth": 0,
+ "extra_signals": extra_signals
+ },],
+ [{
+ "name": "outs",
+ "bitwidth": 0,
+ "extra_signals": extra_signals
+ }],
+ extra_signals,
+ lambda name: _generate_top_join(name, size))
diff --git a/experimental/tools/unit-generators/vhdl/generators/handshake/truncf.py b/experimental/tools/unit-generators/vhdl/generators/handshake/truncf.py
new file mode 100644
index 0000000000..9bdbc47a95
--- /dev/null
+++ b/experimental/tools/unit-generators/vhdl/generators/handshake/truncf.py
@@ -0,0 +1,25 @@
+from generators.support.unary import generate_unary
+
+
+def generate_truncf(name, params):
+
+ signals = f"""
+ signal float_value : float64;
+ signal float_truncated : float32;
+ """
+
+ body = f"""
+ float_value <= to_float(ins, 11, 52);
+ float_truncated <= to_float32(float_value);
+ outs <= to_std_logic_vector(float_truncated);
+ """
+
+ return generate_unary(
+ name=name,
+ handshake_op="truncf",
+ input_bitwidth=64,
+ output_bitwidth=32,
+ signals=signals,
+ body=body,
+ extra_signals=params.get("extra_signals", None)
+ )
diff --git a/experimental/tools/unit-generators/vhdl/generators/handshake/trunci.py b/experimental/tools/unit-generators/vhdl/generators/handshake/trunci.py
index 54d7b1cd89..d8a7d28aeb 100644
--- a/experimental/tools/unit-generators/vhdl/generators/handshake/trunci.py
+++ b/experimental/tools/unit-generators/vhdl/generators/handshake/trunci.py
@@ -1,4 +1,4 @@
-from generators.support.signal_manager import generate_default_signal_manager
+from generators.support.unary import generate_unary
def generate_trunci(name, params):
@@ -6,60 +6,17 @@ def generate_trunci(name, params):
output_bitwidth = params["output_bitwidth"]
extra_signals = params.get("extra_signals", None)
- if extra_signals:
- return _generate_trunci_signal_manager(name, input_bitwidth, output_bitwidth, extra_signals)
- else:
- return _generate_trunci(name, input_bitwidth, output_bitwidth)
+ op_type = "trunci"
-
-def _generate_trunci(name, input_bitwidth, output_bitwidth):
- entity = f"""
-library ieee;
-use ieee.std_logic_1164.all;
-use ieee.numeric_std.all;
-
--- Entity of trunci
-entity {name} is
- port (
- clk : in std_logic;
- rst : in std_logic;
- -- input channel
- ins : in std_logic_vector({input_bitwidth} - 1 downto 0);
- ins_valid : in std_logic;
- ins_ready : out std_logic;
- -- output channel
- outs : out std_logic_vector({output_bitwidth} - 1 downto 0);
- outs_valid : out std_logic;
- outs_ready : in std_logic
- );
-end entity;
-"""
-
- architecture = f"""
--- Architecture of trunci
-architecture arch of {name} is
-begin
+ body = f"""
outs <= ins({output_bitwidth} - 1 downto 0);
- outs_valid <= ins_valid;
- ins_ready <= not ins_valid or (ins_valid and outs_ready);
-end architecture;
-"""
-
- return entity + architecture
-
-
-def _generate_trunci_signal_manager(name, input_bitwidth, output_bitwidth, extra_signals):
- return generate_default_signal_manager(
- name,
- [{
- "name": "ins",
- "bitwidth": input_bitwidth,
- "extra_signals": extra_signals
- }],
- [{
- "name": "outs",
- "bitwidth": output_bitwidth,
- "extra_signals": extra_signals
- }],
- extra_signals,
- lambda name: _generate_trunci(name, input_bitwidth, output_bitwidth))
+ """
+
+ return generate_unary(
+ name=name,
+ handshake_op=op_type,
+ input_bitwidth=input_bitwidth,
+ output_bitwidth=output_bitwidth,
+ body=body,
+ extra_signals=extra_signals
+ )
diff --git a/experimental/tools/unit-generators/vhdl/generators/handshake/valid_merger.py b/experimental/tools/unit-generators/vhdl/generators/handshake/valid_merger.py
index 3ec4ae56dc..585d60b360 100644
--- a/experimental/tools/unit-generators/vhdl/generators/handshake/valid_merger.py
+++ b/experimental/tools/unit-generators/vhdl/generators/handshake/valid_merger.py
@@ -1,65 +1,39 @@
+from generators.support.utils import data
+from generators.support.signal_manager.utils.entity import generate_entity
+from generators.support.signal_manager.utils.generation import generate_default_mappings
+
def generate_valid_merger(name, params):
- left_bitwidth = params["left_bitwidth"]
- right_bitwidth = params["right_bitwidth"]
-
- if left_bitwidth > 0 and right_bitwidth > 0:
- return _generate_valid_merger(name, left_bitwidth, right_bitwidth)
- elif left_bitwidth > 0:
- return _generate_valid_merger_right_dataless(name, left_bitwidth)
- elif right_bitwidth > 0:
- return _generate_valid_merger_left_dataless(name, right_bitwidth)
+ lhs_bitwidth = params["left_bitwidth"]
+ rhs_bitwidth = params["right_bitwidth"]
+
+ lhs_extra_signals = params.get("lhs_extra_signals", None)
+ rhs_extra_signals = params.get("rhs_extra_signals", None)
+
+ def generate_inner(name): return _generate_valid_merger(name, lhs_bitwidth, rhs_bitwidth)
+ def generate(): return generate_inner(name)
+
+ if lhs_extra_signals or rhs_extra_signals:
+ return _generate_valid_merger_signal_manager(
+ name,
+ lhs_bitwidth,
+ rhs_bitwidth,
+ generate_inner,
+ lhs_extra_signals,
+ rhs_extra_signals
+ )
else:
- return _generate_valid_merger_dataless(name)
+ return generate()
-def _generate_valid_merger(name, left_bitwidth, right_bitwidth):
+def _generate_valid_merger(name, lhs_bitwidth, rhs_bitwidth):
+ possible_lhs_ins = f"lhs_ins : in std_logic_vector({lhs_bitwidth} - 1 downto 0);"
+ possible_rhs_ins = f"rhs_ins : in std_logic_vector({rhs_bitwidth} - 1 downto 0);"
+ possible_lhs_outs = f"lhs_outs : out std_logic_vector({lhs_bitwidth} - 1 downto 0);"
+ possible_rhs_outs = f"rhs_outs : out std_logic_vector({rhs_bitwidth} - 1 downto 0);"
- entity = f"""
-library ieee;
-use ieee.std_logic_1164.all;
-use ieee.numeric_std.all;
-
--- Entity of valid_merger
-entity {name} is
- port (
- -- inputs
- clk : in std_logic;
- rst : in std_logic;
- lhs_ins : in std_logic_vector({left_bitwidth} - 1 downto 0);
- lhs_ins_valid : in std_logic;
- lhs_outs_ready : in std_logic;
- rhs_ins : in std_logic_vector({right_bitwidth} - 1 downto 0);
- rhs_ins_valid : in std_logic;
- rhs_outs_ready : in std_logic;
- -- outputs
- lhs_outs : out std_logic_vector({left_bitwidth} - 1 downto 0);
- lhs_outs_valid : out std_logic;
- lhs_ins_ready : out std_logic;
- rhs_outs : out std_logic_vector({right_bitwidth} - 1 downto 0);
- rhs_outs_valid : out std_logic;
- rhs_ins_ready : out std_logic
- );
-end entity;
-"""
-
- architecture = f"""
--- Architecture of valid_merger
-architecture arch of {name} is
-begin
- lhs_outs <= lhs_ins;
- rhs_outs <= rhs_ins;
- lhs_outs_valid <= lhs_ins_valid;
- rhs_outs_valid <= lhs_ins_valid; -- merge happens here
- lhs_ins_ready <= lhs_outs_ready;
- rhs_ins_ready <= rhs_outs_ready;
-end architecture;
-"""
-
- return entity + architecture
-
-
-def _generate_valid_merger_right_dataless(name, left_bitwidth):
+ possible_lhs_assignment = "lhs_outs <= lhs_ins;"
+ possible_rhs_assignment = "rhs_outs <= rhs_ins;"
entity = f"""
library ieee;
@@ -72,113 +46,109 @@ def _generate_valid_merger_right_dataless(name, left_bitwidth):
-- inputs
clk : in std_logic;
rst : in std_logic;
- lhs_ins : in std_logic_vector({left_bitwidth} - 1 downto 0);
+ {data(possible_lhs_ins, lhs_bitwidth)}
lhs_ins_valid : in std_logic;
lhs_outs_ready : in std_logic;
+ {data(possible_rhs_ins, rhs_bitwidth)}
rhs_ins_valid : in std_logic;
rhs_outs_ready : in std_logic;
-- outputs
- lhs_outs : out std_logic_vector({left_bitwidth} - 1 downto 0);
+ {data(possible_lhs_outs, lhs_bitwidth)}
lhs_outs_valid : out std_logic;
lhs_ins_ready : out std_logic;
+ {data(possible_rhs_outs, rhs_bitwidth)}
rhs_outs_valid : out std_logic;
rhs_ins_ready : out std_logic
);
end entity;
"""
-
architecture = f"""
-- Architecture of valid_merger
architecture arch of {name} is
begin
- lhs_outs <= lhs_ins;
+ {data(possible_lhs_assignment, lhs_bitwidth)}
lhs_outs_valid <= lhs_ins_valid;
- rhs_outs_valid <= lhs_ins_valid; -- merge happens here
lhs_ins_ready <= lhs_outs_ready;
- rhs_ins_ready <= rhs_outs_ready;
-end architecture;
-"""
-
- return entity + architecture
-
-def _generate_valid_merger_left_dataless(name, right_bitwidth):
-
- entity = f"""
-library ieee;
-use ieee.std_logic_1164.all;
-use ieee.numeric_std.all;
-
--- Entity of valid_merger
-entity {name} is
- port (
- -- inputs
- clk : in std_logic;
- rst : in std_logic;
- lhs_ins_valid : in std_logic;
- lhs_outs_ready : in std_logic;
- rhs_ins : in std_logic_vector({right_bitwidth} - 1 downto 0);
- rhs_ins_valid : in std_logic;
- rhs_outs_ready : in std_logic;
- -- outputs
- lhs_outs_valid : out std_logic;
- lhs_ins_ready : out std_logic;
- rhs_outs : out std_logic_vector({right_bitwidth} - 1 downto 0);
- rhs_outs_valid : out std_logic;
- rhs_ins_ready : out std_logic
- );
-end entity;
-"""
-
- architecture = f"""
--- Architecture of valid_merger
-architecture arch of {name} is
-begin
- rhs_outs <= rhs_ins;
- lhs_outs_valid <= lhs_ins_valid;
+ {data(possible_rhs_assignment, rhs_bitwidth)}
rhs_outs_valid <= lhs_ins_valid; -- merge happens here
- lhs_ins_ready <= lhs_outs_ready;
rhs_ins_ready <= rhs_outs_ready;
end architecture;
"""
-
return entity + architecture
-def _generate_valid_merger_dataless(name):
- entity = f"""
-library ieee;
-use ieee.std_logic_1164.all;
-use ieee.numeric_std.all;
-
--- Entity of valid_merger
-entity {name} is
- port (
- -- inputs
- clk : in std_logic;
- rst : in std_logic;
- lhs_ins_valid : in std_logic;
- lhs_outs_ready : in std_logic;
- rhs_ins_valid : in std_logic;
- rhs_outs_ready : in std_logic;
- -- outputs
- lhs_outs_valid : out std_logic;
- lhs_ins_ready : out std_logic;
- rhs_outs_valid : out std_logic;
- rhs_ins_ready : out std_logic
- );
-end entity;
-"""
+def _generate_valid_merger_signal_manager(name,
+ lhs_bitwidth,
+ rhs_bitwidth,
+ generate_inner,
+ lhs_extra_signals,
+ rhs_extra_signals):
+ inner_name = f"{name}_inner"
+ inner = generate_inner(inner_name)
+
+ in_channels = [
+ {
+ "name": "lhs_in",
+ "bitwidth": lhs_bitwidth,
+ "extra_signals": lhs_extra_signals
+ },
+ {
+ "name": "rhs_in",
+ "bitwidth": rhs_bitwidth,
+ "extra_signals": rhs_extra_signals
+ }
+ ]
+
+ out_channels = [
+ {
+ "name": "lhs_out",
+ "bitwidth": lhs_bitwidth,
+ "extra_signals": lhs_extra_signals
+ },
+ {
+ "name": "rhs_out",
+ "bitwidth": rhs_bitwidth,
+ "extra_signals": rhs_extra_signals
+ }
+ ]
+
+ entity = generate_entity(
+ name,
+ in_channels,
+ out_channels
+ )
+
+ extra_signal_assignments = []
+ # directly pass extra signals through the valid merger
+ # regardless of how they're normally forwarded
+ for extra_signal_name in lhs_extra_signals:
+ extra_signal_assignments.append(
+ f"lhs_out_{extra_signal_name} <= lhs_in_{extra_signal_name};"
+ )
+
+ for extra_signal_name in rhs_extra_signals:
+ extra_signal_assignments.append(
+ f"rhs_out_{extra_signal_name} <= rhs_in_{extra_signal_name};"
+ )
+
+ # Map channels to inner component
+ mappings = generate_default_mappings(in_channels + out_channels)
architecture = f"""
--- Architecture of valid_merger
+-- Architecture of signal manager (valid merger)
architecture arch of {name} is
begin
- lhs_outs_valid <= lhs_ins_valid;
- rhs_outs_valid <= lhs_ins_valid; -- merge happens here
- lhs_ins_ready <= lhs_outs_ready;
- rhs_ins_ready <= rhs_outs_ready;
+-- Forward extra signals to output channels
+{"\n ".join(extra_signal_assignments)}
+
+inner : entity work.{inner_name}(arch)
+ port map(
+ clk => clk,
+ rst => rst,
+ {mappings}
+ );
end architecture;
"""
- return entity + architecture
+ return inner + entity + architecture
diff --git a/experimental/tools/unit-generators/vhdl/generators/handshake/xori.py b/experimental/tools/unit-generators/vhdl/generators/handshake/xori.py
new file mode 100644
index 0000000000..337a792084
--- /dev/null
+++ b/experimental/tools/unit-generators/vhdl/generators/handshake/xori.py
@@ -0,0 +1,17 @@
+from generators.support.arith_binary import generate_arith_binary
+
+
+def generate_xori(name, params):
+ bitwidth = params["bitwidth"]
+
+ body = """
+ result <= lhs xor rhs;
+ """
+
+ return generate_arith_binary(
+ name=name,
+ handshake_op="xori",
+ bitwidth=bitwidth,
+ body=body,
+ extra_signals=params.get("extra_signals", None),
+ )
diff --git a/experimental/tools/unit-generators/vhdl/generators/support/arith_binary.py b/experimental/tools/unit-generators/vhdl/generators/support/arith_binary.py
new file mode 100644
index 0000000000..76648da3ec
--- /dev/null
+++ b/experimental/tools/unit-generators/vhdl/generators/support/arith_binary.py
@@ -0,0 +1,205 @@
+from generators.handshake.join import generate_join
+from generators.support.signal_manager import generate_arith_binary_signal_manager
+from generators.support.utils import ExtraSignals
+from generators.handshake.buffer import generate_valid_propagation_buffer
+
+
+def generate_arith_binary(
+ name: str,
+ handshake_op: str,
+ extra_signals: ExtraSignals,
+ body: str,
+ signals: str = "",
+ dependencies: str = "",
+ bitwidth: int = None,
+ input_bitwidth: int = None,
+ output_bitwidth: int = None,
+ latency: int = 0,
+):
+ """
+ Generates boilerplate VHDL entity and handshaking code for two input arithmetic units
+ (though it could be used for any operation with two data-carrying inputs
+ used to generate a data output,
+ but it depends where we draw the line of what "arithmetic" means)
+
+ If latency = 0:
+ Output ready is directly forwarded up from input ready.
+ Output valid is directly forwarded down from input valid.
+ Else:
+ Handshaking signals are passed through a valid propagation buffer.
+ Which is either a one slot break dv, or a shift register buffer
+
+ Args:
+ name: Unique name based on MLIR op name (e.g. adder0).
+ handshake_op: What kind of handshake op this RTL entity corresponds to. Only used in comments.
+ extra_signals: Extra signals on input/output channels, from IR.
+ body: VHDL body of the unit, excluding handshaking.
+ signals: Local signal declarations used in body.
+ dependencies: Dependencies, excluding handshaking.
+ bitwidth: Unit bitwidth (if input/output are the same).
+ input_bitwidth: Input bitwidth, if input and output bitwidth differ, e.g. cmpf
+ output_bitwidth: Output bitwidth, if input and output bitwidth differ, e.g. cmpf
+ latency:
+
+ Returns:
+ VHDL code as a string.
+ """
+
+ if bitwidth is not None:
+ if input_bitwidth is not None or output_bitwidth is not None:
+ raise RuntimeError("If bitwidth is specified, input and output bitwidth must not be specified")
+
+ input_bitwidth = bitwidth
+ output_bitwidth = bitwidth
+
+ elif input_bitwidth is None or output_bitwidth is None:
+ raise RuntimeError("If bitwidth is not specified, both input and output bitwidth must be specified")
+
+ # generate inner function takes a name parameter
+ # since the top level name is used for the signal manager wrapper
+ #
+ # the signal manager wrapper will make a new name for the inner unit
+
+ def generate_inner(name): return _generate_arith_binary(
+ name,
+ handshake_op,
+ input_bitwidth,
+ output_bitwidth,
+ signals,
+ body,
+ latency,
+ dependencies
+ )
+
+ # if no signal manager,
+ # the unit uses the top level name
+
+ def generate(): return generate_inner(name)
+
+ if extra_signals:
+ return generate_arith_binary_signal_manager(
+ name=name,
+ input_bitwidth=input_bitwidth,
+ output_bitwidth=output_bitwidth,
+ extra_signals=extra_signals,
+ generate_inner=generate_inner,
+ latency=latency
+ )
+ else:
+ return generate()
+
+
+def _generate_arith_binary(
+ name,
+ handshake_op,
+ input_bitwidth,
+ output_bitwidth,
+ signals,
+ body,
+ latency,
+ dependencies,
+):
+
+ join_name = f"{name}_join"
+ dependencies += generate_join(join_name, {"size": 2})
+
+ # all 2 input arithmetic units have the same entity
+ entity = f"""
+library ieee;
+use ieee.std_logic_1164.all;
+use ieee.numeric_std.all;
+use ieee.float_pkg.all;
+
+-- Entity of {handshake_op}
+entity {name} is
+ port(
+ clk: in std_logic;
+ rst: in std_logic;
+ -- input channel lhs
+ lhs: in std_logic_vector({input_bitwidth} - 1 downto 0);
+ lhs_valid: in std_logic;
+ lhs_ready: out std_logic;
+ -- input channel rhs
+ rhs: in std_logic_vector({input_bitwidth} - 1 downto 0);
+ rhs_valid: in std_logic;
+ rhs_ready: out std_logic;
+ -- output channel result
+ result : out std_logic_vector({output_bitwidth} - 1 downto 0);
+ result_valid: out std_logic;
+ result_ready: in std_logic
+ );
+end entity;
+"""
+ signals = signals.lstrip()
+ body = body.lstrip()
+
+ # but the architecture differs depending
+ # on the latency
+
+ # Handshaking handled by a join
+ if latency == 0:
+ architecture = f"""
+-- Architecture of {handshake_op}
+architecture arch of {name} is
+ {signals}
+begin
+ join_inputs : entity work.{join_name}(arch)
+ port map(
+ -- input valids
+ ins_valid(0) => lhs_valid,
+ ins_valid(1) => rhs_valid,
+ -- input readys
+ ins_ready(0) => lhs_ready,
+ ins_ready(1) => rhs_ready,
+ -- output channel to "result"
+ outs_valid => result_valid,
+ outs_ready => result_ready
+ );
+
+ {body}
+
+end architecture;
+"""
+ # otherwise, we need a buffer to propagate the valid
+ else:
+ valid_buffer_name = f"{name}_valid_buffer"
+ dependencies += generate_valid_propagation_buffer(valid_buffer_name, latency)
+
+ architecture = f"""
+-- Architecture of {handshake_op}
+architecture arch of {name} is
+ signal join_valid, valid_buffer_ready : std_logic;
+ {signals}
+begin
+
+ join_inputs : entity work.{join_name}(arch)
+ port map(
+ -- input valids
+ ins_valid(0) => lhs_valid,
+ ins_valid(1) => rhs_valid,
+ -- input readys
+ ins_ready(0) => lhs_ready,
+ ins_ready(1) => rhs_ready,
+ -- output channel to valid_buffer
+ outs_valid => join_valid,
+ outs_ready => valid_buffer_ready
+ );
+
+ valid_buffer : entity work.{valid_buffer_name}(arch)
+ port map(
+ clk => clk,
+ rst => rst,
+ -- input channel from join
+ ins_valid => join_valid,
+ ins_ready => valid_buffer_ready,
+ -- output channel to "result"
+ outs_ready => result_ready,
+ outs_valid => result_valid
+ );
+
+ {body}
+
+end architecture;
+"""
+
+ return dependencies + entity + architecture
diff --git a/experimental/tools/unit-generators/vhdl/generators/support/arith_ip.py b/experimental/tools/unit-generators/vhdl/generators/support/arith_ip.py
new file mode 100644
index 0000000000..3e394f701c
--- /dev/null
+++ b/experimental/tools/unit-generators/vhdl/generators/support/arith_ip.py
@@ -0,0 +1,123 @@
+from generators.support.arith_binary import generate_arith_binary
+
+
+def generate_flopoco_ip_wrapper(name,
+ handshake_op,
+ core_unit,
+ latency,
+ is_double,
+ internal_delay,
+ extra_signals):
+ """
+ Generates boilerplate VHDL entity and handshaking code for arithmetic units which
+ are wrappers for IP arithmetic cores, such as floating point units, or integer division.
+
+ For flopoco units, it adds the necessary conversions, and instantiates the unit from
+ flopoco_ip_cores, with a number of clock enable signals based on the operation's latency
+ (The op latency must be provided when calling the backed, no latencies are hardcoded).
+
+ For vitis ips, the unit is instantiated from vitis_ip_wrappers. These are only wrappers,
+ and so these units can only be used if the propetiary IP cores are also present in simulation.
+ The backend does not handle this.
+
+ Args:
+ name: Unique name based on MLIR op name (e.g. adder0).
+ handshake_op: What kind of handshake op this RTL entity corresponds to. Only used in comments.
+ core_unit: What is the name of this unit in the flopoco ip cores
+ latency: Operation latency, used to add clock enables to flopoco units.
+ is_double: Flag to specify either 32 or 64 bit units.
+ internal_delay: internal delay of the unit, currently used to identify the desired flopoco unit.
+ bitwidth: Unit bitwidth (if input/output are the same).
+ extra_signals: Extra signals on input/output channels, from IR.
+
+
+ Returns:
+ VHDL code as a string.
+ """
+
+ bitwidth = 64 if is_double else 32
+
+ signals = f"""
+ --intermediate input signals for float conversion
+ signal ip_lhs, ip_rhs : std_logic_vector({bitwidth + 2} - 1 downto 0);
+
+ --intermidiate output signal(s) for float conversion
+ signal ip_result : std_logic_vector({bitwidth + 2} - 1 downto 0);
+ """
+
+ clock_enables = "\n".join(
+ [f" ce_{i} => valid_buffer_ready," for i in range(1, latency + 1)]
+ )
+ clock_enables = clock_enables.lstrip()
+
+ body = f"""
+ ieee2nfloat_0: entity work.InputIEEE_{bitwidth}bit(arch)
+ port map (
+ --input
+ X =>lhs,
+ --output
+ R => ip_lhs
+ );
+
+ ieee2nfloat_1: entity work.InputIEEE_{bitwidth}bit(arch)
+ port map (
+ --input
+ X => rhs,
+ --output
+ R => ip_rhs
+ );
+
+ operator : entity work.{core_unit}_{bitwidth}_{internal_delay}(arch)
+ port map (
+ clk => clk,
+ {clock_enables}
+ X => ip_lhs,
+ Y => ip_rhs,
+ R => ip_result
+ );
+
+ nfloat2ieee : entity work.OutputIEEE_{bitwidth}bit(arch)
+ port map (
+ --input
+ X => ip_result,
+ --ouput
+ R => result
+ );
+ """
+
+ return generate_arith_binary(
+ name=name,
+ handshake_op=handshake_op,
+ bitwidth=bitwidth,
+ signals=signals,
+ body=body,
+ latency=latency,
+ extra_signals=extra_signals
+ )
+
+
+def generate_vivado_ip_wrapper(name,
+ handshake_op,
+ latency,
+ extra_signals):
+
+ body = f"""
+ {handshake_op}_vitis_hls_wrapper_U1 : entity work.{handshake_op}_vitis_hls_wrapper
+ port map(
+ clk => clk,
+ reset => rst,
+ ce => valid_buffer_ready,
+ din0 => lhs,
+ din1 => rhs,
+ dout => result
+ );
+ """
+
+ return generate_arith_binary(
+ name=name,
+ handshake_op=handshake_op,
+ bitwidth=32,
+ body=body,
+ latency=latency,
+ extra_signals=extra_signals
+ )
diff --git a/experimental/tools/unit-generators/vhdl/generators/support/delay_buffer.py b/experimental/tools/unit-generators/vhdl/generators/support/delay_buffer.py
deleted file mode 100644
index 829b8fba7f..0000000000
--- a/experimental/tools/unit-generators/vhdl/generators/support/delay_buffer.py
+++ /dev/null
@@ -1,57 +0,0 @@
-def generate_delay_buffer(name, params):
- slots = params["slots"]
-
- entity = f"""
-library ieee;
-use ieee.std_logic_1164.all;
-use ieee.numeric_std.all;
-
--- Entity of delay_buffer
-entity {name} is
- port (
- clk, rst : in std_logic;
- valid_in : in std_logic;
- ready_in : in std_logic;
- valid_out : out std_logic);
-end entity;
-"""
-
- architecture = f"""
--- Architecture of delay_buffer
-architecture arch of {name} is
-
- type mem is array ({slots} - 1 downto 0) of std_logic;
- signal regs : mem;
-
-begin
-
- gen_assignements : for i in 0 to {slots} - 1 generate
- first_assignment : if i = 0 generate
- process (clk) begin
- if rising_edge(clk) then
- if (rst = '1') then
- regs(i) <= '0';
- elsif (ready_in = '1') then
- regs(i) <= valid_in;
- end if;
- end if;
- end process;
- end generate first_assignment;
- other_assignments : if i > 0 generate
- process (clk) begin
- if rising_edge(clk) then
- if (rst = '1') then
- regs(i) <= '0';
- elsif (ready_in = '1') then
- regs(i) <= regs(i - 1);
- end if;
- end if;
- end process;
- end generate other_assignments;
- end generate gen_assignements;
-
- valid_out <= regs({slots} - 1);
-end architecture;
-"""
-
- return entity + architecture
diff --git a/experimental/tools/unit-generators/vhdl/generators/support/signal_manager/__init__.py b/experimental/tools/unit-generators/vhdl/generators/support/signal_manager/__init__.py
index 4a6336a884..9d48029a57 100644
--- a/experimental/tools/unit-generators/vhdl/generators/support/signal_manager/__init__.py
+++ b/experimental/tools/unit-generators/vhdl/generators/support/signal_manager/__init__.py
@@ -1,5 +1,7 @@
from .default import generate_default_signal_manager
from .buffered import generate_buffered_signal_manager
+from .unary import generate_unary_signal_manager
+from .arith_binary import generate_arith_binary_signal_manager
from .concat import generate_concat_signal_manager
from .spec_units import generate_spec_units_signal_manager
@@ -7,6 +9,8 @@
__all__ = [
"generate_default_signal_manager",
"generate_buffered_signal_manager",
+ "generate_unary_signal_manager",
+ "generate_arith_binary_signal_manager",
"generate_concat_signal_manager",
"generate_spec_units_signal_manager",
]
diff --git a/experimental/tools/unit-generators/vhdl/generators/support/signal_manager/arith_binary.py b/experimental/tools/unit-generators/vhdl/generators/support/signal_manager/arith_binary.py
new file mode 100644
index 0000000000..f8ee7dc1a2
--- /dev/null
+++ b/experimental/tools/unit-generators/vhdl/generators/support/signal_manager/arith_binary.py
@@ -0,0 +1,59 @@
+from collections.abc import Callable
+from .utils.types import ExtraSignals
+from generators.support.signal_manager import generate_buffered_signal_manager, generate_default_signal_manager
+
+
+def generate_arith_binary_signal_manager(
+ name: str,
+ extra_signals: ExtraSignals,
+ generate_inner: Callable[[str], str],
+ latency: int,
+ bitwidth: int = None,
+ input_bitwidth: int = None,
+ output_bitwidth: int = None
+) -> str:
+ if bitwidth is not None:
+ if input_bitwidth is not None or output_bitwidth is not None:
+ raise RuntimeError("If bitwidth is specified, input and output bitwidth must not be specified")
+
+ input_bitwidth = bitwidth
+ output_bitwidth = bitwidth
+
+ elif input_bitwidth is None or output_bitwidth is None:
+ raise RuntimeError("If bitwidth is not specified, both input and output bitwidth must be specified")
+
+
+ in_channels = \
+ [{
+ "name": "lhs",
+ "bitwidth": input_bitwidth,
+ "extra_signals": extra_signals
+ }, {
+ "name": "rhs",
+ "bitwidth": input_bitwidth,
+ "extra_signals": extra_signals
+ }]
+ out_channels = \
+ [{
+ "name": "result",
+ "bitwidth": output_bitwidth,
+ "extra_signals": extra_signals
+ }]
+
+ if latency == 0:
+ return generate_default_signal_manager(
+ name,
+ in_channels,
+ out_channels,
+ extra_signals,
+ generate_inner
+ )
+ else:
+ return generate_buffered_signal_manager(
+ name,
+ in_channels,
+ out_channels,
+ extra_signals,
+ generate_inner,
+ latency
+ )
diff --git a/experimental/tools/unit-generators/vhdl/generators/support/signal_manager/unary.py b/experimental/tools/unit-generators/vhdl/generators/support/signal_manager/unary.py
new file mode 100644
index 0000000000..667102c691
--- /dev/null
+++ b/experimental/tools/unit-generators/vhdl/generators/support/signal_manager/unary.py
@@ -0,0 +1,54 @@
+from collections.abc import Callable
+from .utils.types import ExtraSignals
+from generators.support.signal_manager import generate_buffered_signal_manager, generate_default_signal_manager
+
+
+def generate_unary_signal_manager(
+ name: str,
+ extra_signals: ExtraSignals,
+ generate_inner: Callable[[str], str],
+ latency: int = 0,
+ bitwidth: int = None,
+ input_bitwidth: int = None,
+ output_bitwidth: int = None,
+) -> str:
+ if bitwidth is not None:
+ if input_bitwidth is not None or output_bitwidth is not None:
+ raise RuntimeError("If bitwidth is specified, input and output bitwidth must not be specified")
+
+ input_bitwidth = bitwidth
+ output_bitwidth = bitwidth
+
+ elif input_bitwidth is None or output_bitwidth is None:
+ raise RuntimeError("If bitwidth is not specified, both input and output bitwidth must be specified")
+
+ in_channels = \
+ [{
+ "name": "ins",
+ "bitwidth": input_bitwidth,
+ "extra_signals": extra_signals
+ }]
+ out_channels = \
+ [{
+ "name": "outs",
+ "bitwidth": output_bitwidth,
+ "extra_signals": extra_signals
+ }]
+
+ if latency == 0:
+ return generate_default_signal_manager(
+ name,
+ in_channels,
+ out_channels,
+ extra_signals,
+ generate_inner
+ )
+ else:
+ return generate_buffered_signal_manager(
+ name,
+ in_channels,
+ out_channels,
+ extra_signals,
+ generate_inner,
+ latency
+ )
diff --git a/experimental/tools/unit-generators/vhdl/generators/support/signal_manager/utils/types.py b/experimental/tools/unit-generators/vhdl/generators/support/signal_manager/utils/types.py
index bd8450aef9..8be5a3d4b2 100644
--- a/experimental/tools/unit-generators/vhdl/generators/support/signal_manager/utils/types.py
+++ b/experimental/tools/unit-generators/vhdl/generators/support/signal_manager/utils/types.py
@@ -1,7 +1,5 @@
from typing import TypedDict, NotRequired
-
-# Define the type for extra signals, which are stored as a dictionary with signal names and their bitwidths.
-ExtraSignals = dict[str, int]
+from generators.support.utils import ExtraSignals
class Channel(TypedDict):
diff --git a/experimental/tools/unit-generators/vhdl/generators/support/unary.py b/experimental/tools/unit-generators/vhdl/generators/support/unary.py
new file mode 100644
index 0000000000..b9c0c0826d
--- /dev/null
+++ b/experimental/tools/unit-generators/vhdl/generators/support/unary.py
@@ -0,0 +1,175 @@
+from generators.support.signal_manager import generate_unary_signal_manager
+from generators.support.utils import ExtraSignals
+from generators.support.utils import ExtraSignals
+from generators.handshake.buffer import generate_valid_propagation_buffer
+
+
+def generate_unary(
+ name: str,
+ handshake_op: str,
+ body: str,
+ extra_signals: ExtraSignals,
+ signals: str = "",
+ dependencies: str = "",
+ latency: int = 0,
+ bitwidth: int = None,
+ input_bitwidth: int = None,
+ output_bitwidth: int = None,
+) -> str:
+ """
+ Generates boilerplate VHDL entity and handshaking code for unary units
+ (units with one input and one output).
+
+ If latency = 0:
+ Output ready is directly forwarded up from input ready.
+ Output valid is directly forwarded down from input valid.
+ Else:
+ Handshaking signals are passed through a valid propagation buffer.
+ Which is either a one slot break dv, or a shift register buffer
+
+ Args:
+ name: Unique name based on MLIR op name (e.g. adder0).
+ handshake_op: Which handshake operation this module corresponds to, used only in comments
+ signals: Local signal declarations used in body.
+ body: VHDL body of the unit, excluding handshaking.
+ dependencies: Dependencies, excluding handshaking.
+ latency:
+ bitwidth: Unit bitwidth (if input/output are the same).
+ input_bitwidth: Input bitwidth (used if asymmetric).
+ output_bitwidth: Output bitwidth (used if asymmetric).
+ extra_signals: Extra signals on input/output channels, from IR.
+
+
+ Returns:
+ VHDL code as a string.
+ """
+ if bitwidth is not None:
+ if input_bitwidth is not None or output_bitwidth is not None:
+ raise RuntimeError("If bitwidth is specified, input and output bitwidth must not be specified")
+
+ input_bitwidth = bitwidth
+ output_bitwidth = bitwidth
+
+ elif input_bitwidth is None or output_bitwidth is None:
+ raise RuntimeError("If bitwidth is not specified, both input and output bitwidth must be specified")
+
+ # generate inner function takes a name parameter
+ # since the top level name is used for the signal manager wrapper
+ #
+ # the signal manager wrapper will make a new name for the inner unit
+ def generate_inner(name): return _generate_unary(
+ name=name,
+ handshake_op=handshake_op,
+ input_bitwidth=input_bitwidth,
+ output_bitwidth=output_bitwidth,
+ signals=signals,
+ body=body,
+ dependencies=dependencies,
+ latency=latency
+ )
+
+ # if no signal manager,
+ # the unit uses the top level name
+ def generate(): return generate_inner(name)
+
+ if extra_signals:
+ return generate_unary_signal_manager(
+ name=name,
+ input_bitwidth=input_bitwidth,
+ output_bitwidth=output_bitwidth,
+ extra_signals=extra_signals,
+ generate_inner=generate_inner,
+ latency=latency
+ )
+ else:
+ return generate()
+
+
+def _generate_unary(
+ name,
+ handshake_op,
+ input_bitwidth,
+ output_bitwidth,
+ signals,
+ body,
+ dependencies,
+ latency
+):
+
+ # all unary units have the same entity
+ entity = f"""
+library ieee;
+use ieee.std_logic_1164.all;
+use ieee.numeric_std.all;
+use ieee.float_pkg.all;
+
+-- Entity of {handshake_op}
+entity {name} is
+ port(
+ clk: in std_logic;
+ rst: in std_logic;
+ -- input channel
+ ins: in std_logic_vector({input_bitwidth} - 1 downto 0);
+ ins_valid: in std_logic;
+ ins_ready: out std_logic;
+ -- output channel
+ outs: out std_logic_vector({output_bitwidth} - 1 downto 0);
+ outs_valid: out std_logic;
+ outs_ready: in std_logic
+ );
+end entity;
+"""
+ signals = signals.lstrip()
+ body = body.lstrip()
+
+ # but the architecture differs depending
+ # on the latency
+
+ # Handshaking is directly forwarded
+ if latency == 0:
+ architecture = f"""
+-- Architecture of {handshake_op}
+architecture arch of {name} is
+ {signals}
+begin
+
+ {body}
+
+ -- combinatorial unit forwards handshaking
+ outs_valid <= ins_valid;
+ ins_ready <= outs_ready;
+
+end architecture;
+"""
+ # otherwise, we need a buffer to propagate the valid
+ else:
+ valid_buffer_name = f"{name}_valid_buffer"
+ dependencies += generate_valid_propagation_buffer(valid_buffer_name, latency)
+
+ architecture = f"""
+-- Architecture of {handshake_op}
+architecture arch of {name} is
+ {signals}
+ signal valid_buffer_ready : std_logic;
+begin
+ valid_buffer : entity work.{valid_buffer_name}(arch)
+ port map(
+ clk => clk,
+ rst => rst,
+ -- input channel from "ins"
+ ins_valid => ins_valid,
+ ins_ready => valid_buffer_ready,
+ -- output channel to "outs"
+ outs_valid => outs_valid,
+ outs_ready => outs_ready
+ );
+
+ -- expose to allow use as a clock enable signal
+ ins_ready <= valid_buffer_ready;
+
+ {body}
+
+end architecture;
+"""
+
+ return dependencies + entity + architecture
diff --git a/experimental/tools/unit-generators/vhdl/generators/support/utils.py b/experimental/tools/unit-generators/vhdl/generators/support/utils.py
index b1f54fcc95..bf5bf8fea9 100644
--- a/experimental/tools/unit-generators/vhdl/generators/support/utils.py
+++ b/experimental/tools/unit-generators/vhdl/generators/support/utils.py
@@ -6,8 +6,16 @@ def data(code: str, bitwidth: int) -> str:
return code if bitwidth else ""
+# Define the type for extra signals, which are stored as a dictionary with signal names and their bitwidths.
+ExtraSignals = dict[str, int]
+
+
def try_enum_cast(value: str, enum_class: Type[Enum]) -> Union[Enum, str]:
try:
return enum_class(value)
except ValueError:
return value
+
+
+VIVADO_IMPL = "vivado"
+FLOPOCO_IMPL = "flopoco"
diff --git a/experimental/tools/unit-generators/vhdl/vhdl-unit-generator.py b/experimental/tools/unit-generators/vhdl/vhdl-unit-generator.py
index cf4ff3b7d9..4d9764c92f 100644
--- a/experimental/tools/unit-generators/vhdl/vhdl-unit-generator.py
+++ b/experimental/tools/unit-generators/vhdl/vhdl-unit-generator.py
@@ -2,132 +2,22 @@
import ast
import sys
-import generators.handshake.addf as addf
-import generators.handshake.addi as addi
-import generators.handshake.andi as andi
-import generators.handshake.buffer as buffer
-import generators.handshake.cmpf as cmpf
-import generators.handshake.cmpi as cmpi
-import generators.handshake.cond_br as cond_br
-import generators.handshake.constant as constant
-import generators.handshake.control_merge as control_merge
-import generators.handshake.extsi as extsi
-import generators.handshake.fork as fork
-import generators.handshake.load as load
-import generators.handshake.mem_controller as mem_controller
-import generators.handshake.merge as merge
-import generators.handshake.mulf as mulf
-import generators.handshake.muli as muli
-import generators.handshake.mux as mux
-import generators.handshake.ram as ram
-import generators.handshake.select as select
-import generators.handshake.sink as sink
-import generators.handshake.source as source
-import generators.handshake.store as store
-import generators.handshake.subf as subf
-import generators.handshake.subi as subi
-import generators.handshake.trunci as trunci
-import generators.handshake.speculation.spec_commit as spec_commit
-import generators.handshake.speculation.spec_save_commit as spec_save_commit
-import generators.handshake.speculation.speculating_branch as speculating_branch
-import generators.handshake.speculation.speculator as speculator
-import generators.handshake.speculation.non_spec as non_spec
-import generators.support.mem_to_bram as mem_to_bram
-import generators.handshake.extui as extui
-import generators.handshake.shli as shli
-import generators.handshake.blocker as blocker
-import generators.handshake.sitofp as sitofp
-import generators.handshake.fptosi as fptosi
-import generators.handshake.ready_remover as ready_remover
-import generators.handshake.valid_merger as valid_merger
-import generators.handshake.sharing_wrapper as sharing_wrapper
-import generators.handshake.lazy_fork as lazy_fork
-
-
-def generate_code(name, mod_type, parameters):
- match mod_type:
- case "addf":
- return addf.generate_addf(name, parameters)
- case "addi":
- return addi.generate_addi(name, parameters)
- case "andi":
- return andi.generate_andi(name, parameters)
- case "buffer":
- return buffer.generate_buffer(name, parameters)
- case "cmpi":
- return cmpi.generate_cmpi(name, parameters)
- case "cmpf":
- return cmpf.generate_cmpf(name, parameters)
- case "cond_br":
- return cond_br.generate_cond_br(name, parameters)
- case "constant":
- return constant.generate_constant(name, parameters)
- case "control_merge":
- return control_merge.generate_control_merge(name, parameters)
- case "extsi":
- return extsi.generate_extsi(name, parameters)
- case "fork":
- return fork.generate_fork(name, parameters)
- case "load":
- return load.generate_load(name, parameters)
- case "mem_controller":
- return mem_controller.generate_mem_controller(name, parameters)
- case "merge":
- return merge.generate_merge(name, parameters)
- case "mulf":
- return mulf.generate_mulf(name, parameters)
- case "muli":
- return muli.generate_muli(name, parameters)
- case "mux":
- return mux.generate_mux(name, parameters)
- case "ram":
- return ram.generate_ram(name, parameters)
- case "select":
- return select.generate_select(name, parameters)
- case "sink":
- return sink.generate_sink(name, parameters)
- case "source":
- return source.generate_source(name, parameters)
- case "store":
- return store.generate_store(name, parameters)
- case "subf":
- return subf.generate_subf(name, parameters)
- case "subi":
- return subi.generate_subi(name, parameters)
- case "trunci":
- return trunci.generate_trunci(name, parameters)
- case "spec_commit":
- return spec_commit.generate_spec_commit(name, parameters)
- case "spec_save_commit":
- return spec_save_commit.generate_spec_save_commit(name, parameters)
- case "speculating_branch":
- return speculating_branch.generate_speculating_branch(name, parameters)
- case "speculator":
- return speculator.generate_speculator(name, parameters)
- case "non_spec":
- return non_spec.generate_non_spec(name, parameters)
- case "mem_to_bram":
- return mem_to_bram.generate_mem_to_bram(name, parameters)
- case "extui":
- return extui.generate_extui(name, parameters)
- case "shli":
- return shli.generate_shli(name, parameters)
- case "blocker":
- return blocker.generate_blocker(name, parameters)
- case "sitofp":
- return sitofp.generate_sitofp(name, parameters)
- case "fptosi":
- return fptosi.generate_fptosi(name, parameters)
- case "ready_remover":
- return ready_remover.generate_ready_remover(name, parameters)
- case "valid_merger":
- return valid_merger.generate_valid_merger(name, parameters)
- case "sharing_wrapper":
- return sharing_wrapper.generate_sharing_wrapper(name, parameters)
- case "lazy_fork":
- return sharing_wrapper.generate_lazy_fork(name, parameters)
- case _:
- raise ValueError(f"Module type {mod_type} not found")
+import importlib
+
+
+class Generators():
+ def __init__(self):
+ self._data = {}
+
+ def __getitem__(self, key):
+ return self._data[key]
+
+ def __contains__(self, key):
+ return key in self._data
+
+ def add(self, category, mod):
+ imported = importlib.import_module(f"generators.{category}.{mod}")
+ self._data[mod] = getattr(imported, f"generate_{mod}")
def parse_parameters(param_list):
@@ -143,7 +33,7 @@ def parse_parameters(param_list):
"Invalid parameter format. Use key=value key=value,...\n")
-def main():
+def main(generators):
parser = argparse.ArgumentParser(description="VHDL Generator Script")
parser.add_argument(
"-n", "--name", required=True, help="Name of the generated module"
@@ -172,9 +62,74 @@ def main():
# Printing parameters for diagnostic purposes
header = f"-- {args.name} : {args.type}({parameters})\n\n"
+ if args.type not in generators:
+ raise ValueError(f"Module type {args.type} not found")
+
+ generate_code = generators[args.type]
+
with open(args.output, "w") as file:
- print(header + generate_code(args.name, args.type, parameters), file=file)
+ print(header + generate_code(args.name, parameters), file=file)
if __name__ == "__main__":
- main()
+ generators = Generators()
+ generators.add("handshake", "absf")
+ generators.add("handshake", "addf")
+ generators.add("handshake", "addi")
+ generators.add("handshake", "andi")
+ generators.add("handshake", "buffer")
+ generators.add("handshake", "cmpi")
+ generators.add("handshake", "cmpf")
+ generators.add("handshake", "cond_br")
+ generators.add("handshake", "br")
+ generators.add("handshake", "constant")
+ generators.add("handshake", "control_merge")
+ generators.add("handshake", "divf")
+ generators.add("handshake", "divsi")
+ generators.add("handshake", "divui")
+ generators.add("handshake", "negf")
+ generators.add("handshake", "extsi")
+ generators.add("handshake", "extf")
+ generators.add("handshake", "fork")
+ generators.add("handshake", "lazy_fork")
+ generators.add("handshake", "load")
+ generators.add("handshake", "maximumf")
+ generators.add("handshake", "minimumf")
+ generators.add("handshake", "mem_controller")
+ generators.add("handshake", "merge")
+ generators.add("handshake", "mulf")
+ generators.add("handshake", "muli")
+ generators.add("handshake", "mux")
+ generators.add("handshake", "ndwire")
+ generators.add("handshake", "ori")
+ generators.add("handshake", "xori")
+ generators.add("handshake", "logical_not")
+ generators.add("handshake", "select")
+ generators.add("handshake", "sink")
+ generators.add("handshake", "source")
+ generators.add("handshake", "store")
+ generators.add("handshake", "subf")
+ generators.add("handshake", "subi")
+ generators.add("handshake", "trunci")
+ generators.add("handshake", "truncf")
+ generators.add("handshake.speculation", "spec_commit")
+ generators.add("handshake.speculation", "spec_save_commit")
+ generators.add("handshake.speculation", "speculating_branch")
+ generators.add("handshake.speculation", "speculator")
+ generators.add("handshake.speculation", "non_spec")
+ generators.add("support", "mem_to_bram")
+ generators.add("handshake", "extui")
+ generators.add("handshake", "shli")
+ generators.add("handshake", "shrsi")
+ generators.add("handshake", "shrui")
+ generators.add("handshake", "blocker")
+ generators.add("handshake", "sitofp")
+ generators.add("handshake", "fptosi")
+ generators.add("handshake", "ready_remover")
+ generators.add("handshake", "valid_merger")
+ generators.add("handshake", "top_join")
+ generators.add("handshake", "remsi")
+ generators.add("handshake", "ram")
+ generators.add("handshake", "sharing_wrapper")
+
+ main(generators)
diff --git a/include/dynamatic/Dialect/Handshake/HandshakeArithOps.td b/include/dynamatic/Dialect/Handshake/HandshakeArithOps.td
index 73c80e5526..e956be6144 100644
--- a/include/dynamatic/Dialect/Handshake/HandshakeArithOps.td
+++ b/include/dynamatic/Dialect/Handshake/HandshakeArithOps.td
@@ -7,7 +7,7 @@
//===----------------------------------------------------------------------===//
//
// This file define Handshake equivalent of operations from the `arith` dialect
-// in tablegen.
+// in tablegen.
//
//===----------------------------------------------------------------------===//
@@ -62,13 +62,13 @@ class Handshake_Arith_FloatBinaryOp traits = []> :
class Handshake_Arith_FloatUnaryOp traits = []> :
Handshake_Arith_Op,
- IsFloatChannel<"result">,
+ IsFloatChannel<"ins">,
+ IsFloatChannel<"outs">,
]> {
- let arguments = (ins ChannelType:$operand);
- let results = (outs ChannelType:$result);
+ let arguments = (ins ChannelType:$ins);
+ let results = (outs ChannelType:$outs);
- let assemblyFormat = "$operand attr-dict `:` type($result)";
+ let assemblyFormat = "$ins attr-dict `:` type($outs)";
}
class Handshake_Arith_CompareOp traits = []> :
@@ -103,7 +103,7 @@ class Handshake_Arith_IToICastOp traits = []> :
> {
let arguments = (ins ChannelType:$in);
let results = (outs ChannelType:$out);
-
+
let assemblyFormat = "$in attr-dict `:` type($in) `to` type($out)";
let hasFolder = 1;
@@ -117,7 +117,7 @@ class Handshake_Arith_FToFCastOp traits = []> :
> {
let arguments = (ins ChannelType:$in);
let results = (outs ChannelType:$out);
-
+
let assemblyFormat = "$in attr-dict `:` type($in) `to` type($out)";
// TODO: add folding operation
@@ -130,7 +130,7 @@ class Handshake_Arith_IToFCastOp traits = []> :
> {
let arguments = (ins ChannelType:$in);
let results = (outs ChannelType:$out);
-
+
let assemblyFormat = "$in attr-dict `:` type($in) `to` type($out)";
// TODO: add folding operation
@@ -143,7 +143,7 @@ class Handshake_Arith_FToICastOp traits = []> :
> {
let arguments = (ins ChannelType:$in);
let results = (outs ChannelType:$out);
-
+
let assemblyFormat = "$in attr-dict `:` type($in) `to` type($out)";
// TODO: add folding operation
@@ -156,7 +156,7 @@ class Handshake_Arith_FToICastOp traits = []> :
def Handshake_AddFOp : Handshake_Arith_FloatBinaryOp<"addf", [
Commutative,
FPUImplInterface,
- InternalDelayInterface
+ LatencyInterface
]> {
let summary = "Floating-point addition.";
}
@@ -197,11 +197,11 @@ def Handshake_CmpFOp : Handshake_Arith_CompareOp<"cmpf", [
IsFloatChannel<"lhs">,
IsFloatChannel<"rhs">,
FPUImplInterface,
- InternalDelayInterface
+ LatencyInterface
]> {
let summary = "Floating-point comparison.";
-
- let arguments = (ins Handshake_CmpFPredicateAttr:$predicate,
+
+ let arguments = (ins Handshake_CmpFPredicateAttr:$predicate,
ChannelType:$lhs, ChannelType:$rhs);
}
@@ -228,7 +228,7 @@ def Handshake_CmpIOp : Handshake_Arith_CompareOp<"cmpi", [
IsIntChannel<"rhs">
]> {
let summary = "Integer comparison.";
-
+
let arguments = (ins Handshake_CmpIPredicateAttr:$predicate, ChannelType:$lhs,
ChannelType:$rhs);
}
@@ -264,20 +264,36 @@ def Handshake_ConstantOp : Handshake_Arith_Op<"constant", [
def Handshake_DivFOp : Handshake_Arith_FloatBinaryOp<"divf", [
FPUImplInterface,
- InternalDelayInterface
+ LatencyInterface
]> {
let summary = "Floating-point division.";
}
-def Handshake_RemSIOp : Handshake_Arith_IntBinaryOp<"remsi"> {
- let summary = "Signed integer remainder.";
+def Handshake_DivSIOp : Handshake_Arith_IntBinaryOp<"divsi", [
+ IsIntSizedChannel<32, "lhs">,
+ IsIntSizedChannel<32, "rhs">,
+ IsIntSizedChannel<32, "result">,
+ LatencyInterface
+]>{
+ let summary = "Signed integer division.";
}
-def Handshake_DivSIOp : Handshake_Arith_IntBinaryOp<"divsi"> {
- let summary = "Signed integer division.";
+def Handshake_RemSIOp : Handshake_Arith_IntBinaryOp<"remsi", [
+ IsIntSizedChannel<32, "lhs">,
+ IsIntSizedChannel<32, "rhs">,
+ IsIntSizedChannel<32, "result">,
+ LatencyInterface
+]> {
+ let summary = "Signed integer remainder.";
}
-def Handshake_DivUIOp : Handshake_Arith_IntBinaryOp<"divui"> {
+def Handshake_DivUIOp : Handshake_Arith_IntBinaryOp<"divui", [
+ IsIntSizedChannel<32, "lhs">,
+ IsIntSizedChannel<32, "rhs">,
+ IsIntSizedChannel<32, "result">,
+ LatencyInterface
+]>
+{
let summary = "Unsigned integer division.";
}
@@ -299,13 +315,21 @@ def Handshake_ExtUIOp : Handshake_Arith_IToICastOp<"extui"> {
}
def Handshake_MaximumFOp : Handshake_Arith_FloatBinaryOp<"maximumf", [
- Commutative
+ Commutative,
+ IsFloatSizedChannel<32, "lhs">,
+ IsFloatSizedChannel<32, "rhs">,
+ IsFloatSizedChannel<32, "result">,
+ LatencyInterface
]> {
let summary = "Floating-point maximum.";
}
def Handshake_MinimumFOp : Handshake_Arith_FloatBinaryOp< "minimumf", [
- Commutative
+ Commutative,
+ IsFloatSizedChannel<32, "lhs">,
+ IsFloatSizedChannel<32, "rhs">,
+ IsFloatSizedChannel<32, "result">,
+ LatencyInterface
]> {
let summary = "Floating-point minimum.";
}
@@ -313,12 +337,15 @@ def Handshake_MinimumFOp : Handshake_Arith_FloatBinaryOp< "minimumf", [
def Handshake_MulFOp : Handshake_Arith_FloatBinaryOp<"mulf", [
Commutative,
FPUImplInterface,
- InternalDelayInterface
+ LatencyInterface
]> {
let summary = "Floating-point multiplication.";
}
-def Handshake_MulIOp : Handshake_Arith_IntBinaryOp<"muli", [Commutative]> {
+def Handshake_MulIOp : Handshake_Arith_IntBinaryOp<"muli", [
+ Commutative,
+ LatencyInterface
+]> {
let summary = "Integer multiplication.";
}
@@ -337,7 +364,7 @@ def Handshake_SelectOp : Handshake_Arith_Op<"select", [
DeclareOpInterfaceMethods,
]> {
let summary = "Select a value based on a 1-bit predicate.";
-
+
let arguments = (ins ChannelType:$condition, ChannelType:$trueValue,
ChannelType:$falseValue);
let results = (outs ChannelType:$result);
@@ -362,7 +389,7 @@ def Handshake_ShRUIOp : Handshake_Arith_IntBinaryOp<"shrui"> {
def Handshake_SubFOp : Handshake_Arith_FloatBinaryOp<"subf", [
FPUImplInterface,
- InternalDelayInterface
+ LatencyInterface
]> {
let summary = "Floating-point subtraction.";
}
@@ -376,32 +403,46 @@ def Handshake_TruncIOp : Handshake_Arith_IToICastOp<"trunci"> {
let hasCanonicalizer = 1;
}
-def Handshake_TruncFOp : Handshake_Arith_FToFCastOp<"truncf"> {
+def Handshake_TruncFOp : Handshake_Arith_FToFCastOp<"truncf", [
+ IsFloatSizedChannel<64, "in">,
+ IsFloatSizedChannel<32, "out">
+]>{
let summary = "Floating-point truncation.";
// TODO: add canonicalizer
- let hasVerifier = 1;
}
def Handshake_XOrIOp : Handshake_Arith_IntBinaryOp<"xori", [Commutative]> {
let summary = "Bitwise exclusive union.";
}
-def Handshake_UIToFPOp : Handshake_Arith_IToFCastOp<"uitofp"> {
+def Handshake_UIToFPOp : Handshake_Arith_IToFCastOp<"uitofp", [
+ IsIntSizedChannel<32, "in">,
+ IsFloatSizedChannel<32, "out">
+]> {
let summary = "Converts a unsigned integer to float.";
}
-def Handshake_SIToFPOp : Handshake_Arith_IToFCastOp<"sitofp"> {
+def Handshake_SIToFPOp : Handshake_Arith_IToFCastOp<"sitofp",[
+ IsIntSizedChannel<32, "in">,
+ IsFloatSizedChannel<32, "out">
+]> {
let summary = "Converts a signed integer to float.";
}
-def Handshake_FPToSIOp : Handshake_Arith_FToICastOp<"fptosi"> {
+def Handshake_FPToSIOp : Handshake_Arith_FToICastOp<"fptosi", [
+ IsFloatSizedChannel<32, "in">,
+ IsIntSizedChannel<32, "out">,
+ LatencyInterface
+]> {
let summary = "Converts a float to signed integer.";
}
-def Handshake_ExtFOp : Handshake_Arith_FToFCastOp<"extf"> {
+def Handshake_ExtFOp : Handshake_Arith_FToFCastOp<"extf", [
+ IsFloatSizedChannel<32, "in">,
+ IsFloatSizedChannel<64, "out">
+]>{
let summary = "Floating point extension.";
// TODO: add canonicalizer
- let hasVerifier = 1;
}
def Handshake_AbsFOp : Handshake_Arith_FToFCastOp<"absf"> {
diff --git a/include/dynamatic/Dialect/Handshake/HandshakeInterfaces.td b/include/dynamatic/Dialect/Handshake/HandshakeInterfaces.td
index a2b4041346..957ef78f2d 100644
--- a/include/dynamatic/Dialect/Handshake/HandshakeInterfaces.td
+++ b/include/dynamatic/Dialect/Handshake/HandshakeInterfaces.td
@@ -217,42 +217,38 @@ def ControlInterface : OpInterface<"ControlInterface"> {
def HasClock : NativeOpTrait<"HasClock">;
-
-def InternalDelayInterface : OpInterface<"InternalDelayInterface"> {
+def LatencyInterface : OpInterface<"LatencyInterface"> {
let cppNamespace = "::dynamatic::handshake";
let description = [{
- Handshake operations which have a variable internal delay
- used in frequency regulation.
+ We must know the exact latency of multi-cycle operations,
+ in order to correctly buffer the circuit,
+ as well as and generate valid-signal shift registers in their RTL.
+ This interface lets us store the latency on the operation,
+ allowing the components.json to act as a single-source-of-truth.
}];
- let methods = [
- InterfaceMethod<[{
- Sets the internal delay as a StringAttr named "internal_delay".
- }], "void", "setInternalDelay", (ins "::llvm::StringRef":$value), [{
- Operation *op = $_op.getOperation();
- op->setAttr("internal_delay",
- StringAttr::get(op->getContext(), value));
- }]>,
-
- // Return StringAttr instead of StringRef to ensure proper memory allocation.
- // Using StringRef would result in the default value "0.0" becoming a dangling pointer.
- InterfaceMethod<[{
- Gets the internal delay as a StringAttr named "internal_delay". Defaults to "0.0" if not set.
- }], "StringAttr", "getInternalDelay", (ins), [{
- Operation *op = $_op.getOperation();
- if (auto attr = op->getAttrOfType("internal_delay"))
- return attr;
- return StringAttr::get(op->getContext(), "0.0");
+ let methods = [
+ InterfaceMethod<[{
+ Gets the operation latency as an integer.
+ }], "FailureOr", "getLatency", (ins), [{
+ Operation *op = $_op.getOperation();
+ auto attr = op->getAttrOfType("latency");
+ if (!attr)
+ return failure();
+ return attr.getInt();
+ }]>,
+
+ InterfaceMethod<[{
+ Sets the operation latency.
+ }], "void", "setLatency", (ins "int64_t":$latency), [{
+ $_op->setAttr("latency", IntegerAttr::get(IntegerType::get($_op->getContext(), 64), latency));
}]>
];
}
-
-
def FPUImplInterface : OpInterface<"FPUImplInterface"> {
let cppNamespace = "::dynamatic::handshake";
let description = [{
- Specifies which "vendor" of floating point units
- to use
+ Allows specification of attributes which affect FPU RTL.
}];
let methods = [
@@ -272,6 +268,25 @@ InterfaceMethod<[{
return attr.getValue();
}
return FPUImpl::FLOPOCO;
+ }]>,
+
+ InterfaceMethod<[{
+ Sets the internal delay as a StringAttr named "internal_delay".
+ }], "void", "setInternalDelay", (ins "::llvm::StringRef":$value), [{
+ Operation *op = $_op.getOperation();
+ op->setAttr("internal_delay",
+ StringAttr::get(op->getContext(), value));
+ }]>,
+
+ // Return StringAttr instead of StringRef to ensure proper memory allocation.
+ // Using StringRef would result in the default value "0_0" becoming a dangling pointer.
+ InterfaceMethod<[{
+ Gets the internal delay as a StringAttr named "internal_delay". Defaults to "0_0" if not set.
+ }], "StringAttr", "getInternalDelay", (ins), [{
+ Operation *op = $_op.getOperation();
+ if (auto attr = op->getAttrOfType("internal_delay"))
+ return attr;
+ return StringAttr::get(op->getContext(), "0_0");
}]>
];
}
diff --git a/include/dynamatic/Dialect/Handshake/HandshakeOps.td b/include/dynamatic/Dialect/Handshake/HandshakeOps.td
index 2f03f1bfd4..fba390a4c4 100644
--- a/include/dynamatic/Dialect/Handshake/HandshakeOps.td
+++ b/include/dynamatic/Dialect/Handshake/HandshakeOps.td
@@ -150,7 +150,7 @@ def InstanceOp : Handshake_Op<"instance", [
and returns a control output as its last result.
Example:
-
+
```mlir
%2:2 = handshake.instance @my_add(%0, %1, %ctrl) : (f32, f32, !handshake.control) -> (f32, !handshake.control)
```
@@ -221,10 +221,10 @@ def BufferOp : Handshake_Op<"buffer", [
let summary = "buffer operation";
let description = [{
Represents an arbitrary buffer whose properties (e.g., type, latency, and number of
- slots) are dictated by HW parameters.
+ slots) are dictated by HW parameters.
}];
-
- let arguments = (ins HandshakeType:$operand,
+
+ let arguments = (ins HandshakeType:$operand,
Handshake_BufferTypeAttr:$bufferType,
ConfinedAttr]>:$numSlots
);
@@ -263,7 +263,7 @@ def BufferOp : Handshake_Op<"buffer", [
}
}];
-
+
let builders = [
OpBuilder<(
ins
@@ -294,7 +294,7 @@ def InitOp : Handshake_Op<"init", [
A single-slot buffer which contains a token in its reset state.
Similar to a buffer, its timing behavior is configurable.
}];
-
+
let arguments = (ins HandshakeType:$operand);
let results = (outs HandshakeType:$result);
@@ -315,7 +315,7 @@ def NDWireOp : Handshake_Op<"ndwire", [
let description = [{
Represents a wire that non-determinastically stalls the propagation of a signal.
}];
-
+
let arguments = (ins HandshakeType:$operand);
let results = (outs HandshakeType:$result);
@@ -324,7 +324,7 @@ def NDWireOp : Handshake_Op<"ndwire", [
}];
}
-class Handshake_ForkOp traits = []> :
+class Handshake_ForkOp traits = []> :
Handshake_Op {
@@ -339,7 +339,7 @@ class Handshake_ForkOp traits = []> :
}]>
];
- let assemblyFormat = [{
+ let assemblyFormat = [{
custom($operand, attr-dict,
type($operand), type($result))
}];
@@ -399,7 +399,7 @@ def MergeOp : Handshake_Op<"merge", [
let arguments = (ins Variadic:$dataOperands);
let results = (outs HandshakeType:$result);
-
+
let assemblyFormat = [{
$dataOperands attr-dict `:` custom(type($result))
}];
@@ -462,26 +462,26 @@ def ControlMergeOp : Handshake_Op<"control_merge", [
Example:
```
- %res, %idx = control_merge %a, %b, %c :
+ %res, %idx = control_merge %a, %b, %c :
!handshake.channel, !handshake.channel
```
}];
let arguments = (ins Variadic:$dataOperands);
let results = (outs HandshakeType:$result, ChannelType:$index);
-
+
let builders = [OpBuilder<
(ins "ValueRange":$operands), [{
assert(!operands.empty() && "cmerge needs at least one operand");
$_state.addOperands(operands);
-
+
// Optimize the size of the index result based on the number of operands
auto dataType = ::dynamatic::handshake::getOptimizedIndexValType(
$_builder, operands.size());
auto idxType = ::dynamatic::handshake::ChannelType::get(dataType);
$_state.addTypes({operands[0].getType(), idxType});
}]>];
-
+
let hasCustomAssemblyFormat = 1;
let hasVerifier = 1;
}
@@ -504,7 +504,7 @@ def BranchOp : Handshake_Op<"br", [
}];
let arguments = (ins HandshakeType:$operand);
let results = (outs HandshakeType:$result);
-
+
let assemblyFormat = [{
$operand attr-dict `:` custom(type($result))
}];
@@ -536,7 +536,7 @@ def ConditionalBranchOp : Handshake_Op<"cond_br", [
HandshakeType:$dataOperand);
let results = (outs HandshakeType:$trueResult,
HandshakeType:$falseResult);
-
+
let assemblyFormat = [{
$conditionOperand `,` $dataOperand attr-dict
`:` type($conditionOperand) `,` custom(type($dataOperand))
@@ -559,7 +559,7 @@ def SinkOp : Handshake_Op<"sink"> {
sink %data : !handshake.channel
```
}];
-
+
let arguments = (ins HandshakeType:$operand);
let assemblyFormat = [{
$operand attr-dict `:` custom(type($operand))
@@ -620,7 +620,7 @@ def BlockerOp : Handshake_Op<"blocker", [
]> {
let summary = "blocker operation";
let description = [{
- A data synchronizer. Blocks handshakes until all inputs are valid,
+ A data synchronizer. Blocks handshakes until all inputs are valid,
then forwards the first input.
Example:
@@ -670,8 +670,8 @@ def MemoryControllerOp : Handshake_Op<"mem_controller", [
]> {
let summary = "memory controller (dynamatic)";
let description = [{
- Each `MemoryControllerOp` represents an interface to an externally defined
- unidimensional memory (i.e., it interfaces a memref input to a Handshake
+ Each `MemoryControllerOp` represents an interface to an externally defined
+ unidimensional memory (i.e., it interfaces a memref input to a Handshake
function). It receives control signals from each basic block containing
store operations referencing the wrapped memref; the formers are fed to the
operation through constants indicating the number of stores the basic block
@@ -684,7 +684,7 @@ def MemoryControllerOp : Handshake_Op<"mem_controller", [
Additionally, the `connectedBlocks` attribute contains the ordered list of
basic blocks (referenced by their unique IDs) that communicate with the
controller. Every load/store operation is required to be tagged with the ID
- of a basic block present in this list.
+ of a basic block present in this list.
Optionally, a memory controller may act as a middle-person between an LSQ
and the external memory.
@@ -692,7 +692,7 @@ def MemoryControllerOp : Handshake_Op<"mem_controller", [
The order of memory inputs is
1. For each basic block:
a. If there is at least one store in the block, a control signal fed
- through a constant indicating the number of store operations in the
+ through a constant indicating the number of store operations in the
block.
b. Load/Store access requests from within the block, in program order.
2. If an LSQ references the same memory region:
@@ -701,7 +701,7 @@ def MemoryControllerOp : Handshake_Op<"mem_controller", [
signals described above.
b. A single address operand for load accesses coming through the LSQ and
a single pair of address/data operands for store accesses coming
- through the LSQ.
+ through the LSQ.
The order of memory outputs is
1. Load results, in program order (i.e., in load accesses order).
@@ -718,7 +718,7 @@ def MemoryControllerOp : Handshake_Op<"mem_controller", [
let builders = [OpBuilder<(ins "Value":$memRef, "Value":$memStart,
"ValueRange":$inputs, "Value":$ctrlEnd,
- "ArrayRef":$blocks,
+ "ArrayRef":$blocks,
"unsigned":$numLoads)>];
let hasVerifier = 1;
@@ -738,7 +738,7 @@ def MemoryControllerOp : Handshake_Op<"mem_controller", [
}
/// Returns a convenient data-structure to go over the controls and memory
- /// accesses that are connected to the memory controller.
+ /// accesses that are connected to the memory controller.
dynamatic::MCPorts getPorts();
}];
}
@@ -761,13 +761,13 @@ def LSQOp : Handshake_Op<"lsq", [
clearly program-orderable, and stored in the LSQ's inputs in that order.
Additionally, two groups connected to the same LSQ cannot share the same
control signal, which are determined by the program location of the first
- memory access of each group).
+ memory access of each group).
- Control signals are not fed through a constant and are instead data-less
signals simply indicating that a new group has started.
- To ensure proper identification of groups when analyzing the operation's
operands, the `groupSizes` attribute contains the numberf of load/store
- ports in each LSQ group, in operand order.
-
+ ports in each LSQ group, in operand order.
+
In the absence of an MC on the same memory region, the LSQ talks directly to
the external memory and its first memory input will be the Handhsake
function's memref argument that it interfaces in the circuit. In the
@@ -787,18 +787,18 @@ def LSQOp : Handshake_Op<"lsq", [
1. Load results, in program order (i.e., in load accesses order).
2. If an MC references the same memory region, a single address operand for
load accesses and a single pair of address/data operands for store
- accesses going to the external memory through the MC.
+ accesses going to the external memory through the MC.
3. Control signal indicating completion.
}];
-
+
let arguments = (ins Variadic:$inputs, I32ArrayAttr:$groupSizes);
let results = (outs Variadic:$outputs);
let builders = [
- OpBuilder<(ins "Value":$memref, "Value":$memStart, "ValueRange":$inputs,
+ OpBuilder<(ins "Value":$memref, "Value":$memStart, "ValueRange":$inputs,
"Value":$ctrlEnd, "ArrayRef":$groupSizes, "unsigned":$numLoads)>,
- OpBuilder<(ins "::dynamatic::handshake::MemoryControllerOp":$mcOp,
- "ValueRange":$inputs, "ArrayRef":$groupSizes,
+ OpBuilder<(ins "::dynamatic::handshake::MemoryControllerOp":$mcOp,
+ "ValueRange":$inputs, "ArrayRef":$groupSizes,
"unsigned":$numLoads)>,
];
let hasVerifier = 1;
@@ -814,10 +814,10 @@ def LSQOp : Handshake_Op<"lsq", [
}
/// Returns a convenient data-structure to go over the controls and memory
- /// accesses that are connected to the LSQ.
+ /// accesses that are connected to the LSQ.
dynamatic::LSQPorts getPorts();
-
- /// Determines whether the LSQ is connected to an MC.
+
+ /// Determines whether the LSQ is connected to an MC.
bool isConnectedToMC() {
return !isa(getInputs().front().getType());
}
@@ -1067,12 +1067,12 @@ def SpeculatorOp : Handshake_Op<"speculator", [
let summary = "Central control unit of the speculative circuit.";
let description = [{
The speculator produces speculative tokens when real data has
- not yet arrived. The speculator is also responsible for deciding
+ not yet arrived. The speculator is also responsible for deciding
the correctness of its speculation.
It needs to send control tokens to save units and commit units
($saveCtrl, $commitCtrl). For save-commit units, three control
- signals are needed. $SCSaveCtrl is connected directly, while
+ signals are needed. $SCSaveCtrl is connected directly, while
$SCCommitCtrl replicates the branches that $dataOut
follows and might not reach a save-commit. $SCIsMisspec is needed
in the replicated branches to discard the latter signal.
@@ -1090,9 +1090,9 @@ def SpeculatorOp : Handshake_Op<"speculator", [
ControlType:$trigger,
UI32Attr:$fifoDepth);
let results = (outs ChannelType:$dataOut,
- ChannelType:$saveCtrl, ChannelType:$commitCtrl,
+ ChannelType:$saveCtrl, ChannelType:$commitCtrl,
ChannelType:$SCSaveCtrl,
- ChannelType:$SCCommitCtrl,
+ ChannelType:$SCCommitCtrl,
ChannelType:$SCIsMisspec);
let assemblyFormat = [{
@@ -1150,13 +1150,13 @@ def SpecSaveOp : Handshake_Op<"spec_save", [
]> {
let summary = "Saves data tokens that interact in the speculative region.";
let description = [{
- Save units are used to mark the beginning of the speculation region.
- Whenever a speculative token can interact with a non-speculative token,
+ Save units are used to mark the beginning of the speculation region.
+ Whenever a speculative token can interact with a non-speculative token,
the non-speculative token needs to be saved. In case of correct speculation
or no speculation, the saved token can be dropped.
- On the other hand, if the speculation was incorrect, the saved tokens
- need to be reinserted into the circuit to repeat the previously
+ On the other hand, if the speculation was incorrect, the saved tokens
+ need to be reinserted into the circuit to repeat the previously
miscalculated computations.
Example:
@@ -1196,14 +1196,14 @@ def SpecCommitOp : Handshake_Op<"spec_commit", [
]> {
let summary = "Stall speculative data tokens until they are resolved.";
let description = [{
- Commit units are used to mark the end of the speculation region.
- Commit units are used to stall speculative tokens until they receive
- the decision from the speculator. In case the speculation is correct,
- the speculative tokens are converted into non-speculative tokens and
- passed on to the rest of the circuit.
- Otherwise, the speculative tokens are discarded.
-
- Any non-speculative token can pass through the commit units
+ Commit units are used to mark the end of the speculation region.
+ Commit units are used to stall speculative tokens until they receive
+ the decision from the speculator. In case the speculation is correct,
+ the speculative tokens are converted into non-speculative tokens and
+ passed on to the rest of the circuit.
+ Otherwise, the speculative tokens are discarded.
+
+ Any non-speculative token can pass through the commit units
without any stall.
Example:
@@ -1247,7 +1247,7 @@ def SpecSaveCommitOp : Handshake_Op<"spec_save_commit", [
To increase loop parallelism, the save-commit unit will let both
speculative and non-speculative tokens pass as well as save
a copy of them.
-
+
Example:
```mlir
@@ -1288,10 +1288,10 @@ def SpeculatingBranchOp : Handshake_Op<"speculating_branch", [
let description = [{
The speculating branch operation represents a conditional
branch that decides the condition based on if a token Value is
- speculative or not.
+ speculative or not.
The $tagFromOperand field is the condition. Depending on wether the data
- is speculative or not, $dataOperand will be send to $trueResult or
+ is speculative or not, $dataOperand will be send to $trueResult or
$falseResult. The speculative tag is a fictious attribute.
Example:
@@ -1305,7 +1305,7 @@ def SpeculatingBranchOp : Handshake_Op<"speculating_branch", [
let arguments = (ins HandshakeType:$tagFromOperand, HandshakeType:$dataOperand);
let results = (outs HandshakeType:$trueResult, HandshakeType:$falseResult);
let assemblyFormat = [{
- `[` $tagFromOperand `]` $dataOperand attr-dict `:`
+ `[` $tagFromOperand `]` $dataOperand attr-dict `:`
type($tagFromOperand) `,` type($dataOperand) `,`
type($trueResult) `,` type($falseResult)
}];
@@ -1368,15 +1368,15 @@ def NonSpecOp : Handshake_Op<"non_spec", [
//===----------------------------------------------------------------------===//
def SharingWrapperOp : Handshake_Op<"sharing_wrapper", [
- SameOperandsAndResultType,
+ SameOperandsAndResultType,
DeclareOpInterfaceMethods,
]> {
let summary = "sharing wrapper operation";
let description = [{
- The sharing_wrapper operation represents the selecting & distributing logic
+ The sharing_wrapper operation represents the selecting & distributing logic
that manages access to a shared unit.
-
+
The sharing wrapper interfaces with the shared unit and the rest of the
circuit.
@@ -1386,18 +1386,18 @@ def SharingWrapperOp : Handshake_Op<"sharing_wrapper", [
operation that share the unit.
- $numSharedOperands: the number of operands of the shared unit.
- $latency: the execution latency of the shared unit.
-
+
The convention for the input operands:
- the first "numSharedOperands * len(credits)" operands are the operands
from the circuit
- the last operand is the result computed by the shared unit
-
+
The convention for the output results:
- the first "len(credits)" results are results dispatched to the rest of the
circuit
- the last "numSharedOperands" result is the selected operands that will be
delivered to the shared unit.
-
+
Future improvement:
- Add the number of operations that share the unit (now it is assumed to be
the size of the DenseI64ArrayAttr credits).
@@ -1435,7 +1435,7 @@ def BundleOp : Handshake_Op<"bundle", [Pure]> {
that combining individual signals into a `handshake::ChannelType` is a
two-step process.
1. First, bundle a `i1` value, which produces a `!handshake.control` and
- `i1` (representing the upstream ready signal) as results.
+ `i1` (representing the upstream ready signal) as results.
2. Then, bundle the `!handshake.control` along with a value representing the
data signal (of a compatible signal type e.g., `i32`), which produces
a `!handshake.channel`.
@@ -1445,12 +1445,12 @@ def BundleOp : Handshake_Op<"bundle", [Pure]> {
```mlir
// Bundling into a channel with a downstream extra signal
%channel = bundle %ctrl, %data, %extra : _ to
-
+
// -----
-
+
// Bundling into a channel with an upstream extra signal
%channel, %extra = bundle %ctrl, %data : _ to
-
+
// -----
// Bundling into a control-only channel
@@ -1482,7 +1482,7 @@ def BundleOp : Handshake_Op<"bundle", [Pure]> {
>
];
- let hasCustomAssemblyFormat = 1;
+ let hasCustomAssemblyFormat = 1;
let hasVerifier = 1;
}
@@ -1503,16 +1503,16 @@ def UnbundleOp : Handshake_Op<"unbundle", [
"downstream bundle").
2. Then, unbundle the `!handshake.control` along with an `i1` value
representing the ready signal, which produces an `i1` result representing
- the valid signal.
+ the valid signal.
Example:
```mlir
// Unbundling a channel with a downstream extra signal
%ctrl, %data, %extra = unbundle %channel : to _
-
+
// -----
-
+
// Unbundling a channel with an upstream extra signal
%ctrl, %data = unbundle %channel [%extra] : to _
@@ -1556,7 +1556,7 @@ def ReadyRemoverOp : Handshake_Op<"ready_remover",[
Rigidifies a channel to simplify the handshake logic.
}];
let description = [{
- Rigidifies a channel by setting the output valid signal to 1 and input ready
+ Rigidifies a channel by setting the output ready signal to 1 and input ready
signal to a open. This allows the simplification of redundant handshake logic.
}];
@@ -1580,8 +1580,8 @@ def ReadyRemoverOp : Handshake_Op<"ready_remover",[
}
def ValidMergerOp : Handshake_Op<"valid_merger",[
- AllTypesMatch<["lhsIn", "lhs"]>,
- AllTypesMatch<["rhsIn", "rhs"]>,
+ AllTypesMatch<["lhsIn", "lhsOut"]>,
+ AllTypesMatch<["rhsIn", "rhsOut"]>,
DeclareOpInterfaceMethods
]> {
let summary = [{
@@ -1594,7 +1594,7 @@ def ValidMergerOp : Handshake_Op<"valid_merger",[
}];
let arguments = (ins HandshakeType:$lhsIn, HandshakeType:$rhsIn);
- let results = (outs HandshakeType:$lhs, HandshakeType:$rhs);
+ let results = (outs HandshakeType:$lhsOut, HandshakeType:$rhsOut);
let assemblyFormat = [{
$lhsIn `,` $rhsIn attr-dict `:` custom(type($lhsIn)) `,` custom(type($rhsIn))
diff --git a/include/dynamatic/Dialect/Handshake/HandshakeTypes.td b/include/dynamatic/Dialect/Handshake/HandshakeTypes.td
index 4485827359..66305ab5e9 100644
--- a/include/dynamatic/Dialect/Handshake/HandshakeTypes.td
+++ b/include/dynamatic/Dialect/Handshake/HandshakeTypes.td
@@ -263,6 +263,18 @@ class IsFloatChannel : PredOpTrait<
]>
>;
+/// Ensures an operand/result is of ChannelType carrying FloatType data of the
+/// specified width.
+class IsFloatSizedChannel : PredOpTrait<
+ name # " should be of ChannelType carrying FloatType data of width " # width,
+ And<[
+ IsChannelPred,
+ IsFloatChannelPred,
+ IsSizedChannelPred
+ ]>
+>;
+
+
/// Constraint to ensure an operand/result shouldn't have any extra signals.
class IsSimpleHandshake : PredOpTrait<
name # " shouldn't have any extra signals",
diff --git a/include/dynamatic/Support/RTL/RTL.h b/include/dynamatic/Support/RTL/RTL.h
index b3fec1d2be..0d775930c0 100644
--- a/include/dynamatic/Support/RTL/RTL.h
+++ b/include/dynamatic/Support/RTL/RTL.h
@@ -292,20 +292,15 @@ class RTLMatch {
/// Registers different parameters for each type of extern op.
/// Temporary function. These parameters should be added to hw.parameters
/// (generation_params in the future)
- void registerParameters(hw::HWModuleExternOp &modOp);
-
- void registerBitwidthParameter(hw::HWModuleExternOp &modOp,
- llvm::StringRef modName,
- hw::ModuleType &modType);
- void registerTransparentParameter(hw::HWModuleExternOp &modOp,
- llvm::StringRef modName,
- hw::ModuleType &modType);
- void registerExtraSignalParameters(hw::HWModuleExternOp &modOp,
- llvm::StringRef modName,
- hw::ModuleType &modType);
- void registerSelectedDelayParameter(hw::HWModuleExternOp &modOp,
- llvm::StringRef modName,
- hw::ModuleType &modType);
+ LogicalResult registerParameters(hw::HWModuleExternOp &modOp);
+
+ LogicalResult registerBitwidthParameter(hw::HWModuleExternOp &modOp,
+ llvm::StringRef modName,
+ hw::ModuleType &modType);
+
+ LogicalResult registerExtraSignalParameters(hw::HWModuleExternOp &modOp,
+ llvm::StringRef modName,
+ hw::ModuleType &modType);
/// Attempts to concretize the matched RTL component using the original RTL
/// request that created the match. Generic components are copied to the
diff --git a/include/dynamatic/Support/TimingModels.h b/include/dynamatic/Support/TimingModels.h
index aa04525696..78f9297ed6 100644
--- a/include/dynamatic/Support/TimingModels.h
+++ b/include/dynamatic/Support/TimingModels.h
@@ -127,7 +127,7 @@ struct DelayDepMetric {
llvm::dbgs()
<< "CRITICAL WARNING: an operator has no known implementation "
- << "capable of running at the requested oper ating frequency. "
+ << "capable of running at the requested operating frequency. "
<< "Closest match selected. Consider increasing target clock period "
<< "or adding an appropriate implementation.\n";
diff --git a/lib/Conversion/HandshakeToHW/HandshakeToHW.cpp b/lib/Conversion/HandshakeToHW/HandshakeToHW.cpp
index 030fa1410b..f2f6a253a5 100644
--- a/lib/Conversion/HandshakeToHW/HandshakeToHW.cpp
+++ b/lib/Conversion/HandshakeToHW/HandshakeToHW.cpp
@@ -752,16 +752,24 @@ ModuleDiscriminator::ModuleDiscriminator(Operation *op) {
unsupported = true;
});
- if (auto internalDelayInterface =
- llvm::dyn_cast(op)) {
- auto delayAttr = internalDelayInterface.getInternalDelay();
- addParam("INTERNAL_DELAY", delayAttr);
- }
-
if (auto fpuImplInterface =
llvm::dyn_cast(op)) {
auto impl = fpuImplInterface.getFPUImpl();
addString("FPU_IMPL", stringifyEnum(impl));
+
+ auto delayAttr = fpuImplInterface.getInternalDelay();
+ addParam("INTERNAL_DELAY", delayAttr);
+ }
+
+ if (auto latencyInterface =
+ llvm::dyn_cast(op)) {
+ auto latency = latencyInterface.getLatency();
+ if (failed(latency)) {
+ op->emitError() << "Missing required latency value on operation";
+ unsupported = true;
+ return;
+ }
+ addUnsigned("LATENCY", latency.value());
}
}
diff --git a/lib/Dialect/Handshake/HandshakeOps.cpp b/lib/Dialect/Handshake/HandshakeOps.cpp
index c0e5facdeb..f357ac52d1 100644
--- a/lib/Dialect/Handshake/HandshakeOps.cpp
+++ b/lib/Dialect/Handshake/HandshakeOps.cpp
@@ -1951,34 +1951,18 @@ OpFoldResult TruncIOp::fold(FoldAdaptor adaptor) {
return getIn();
return nullptr;
}
-/// Extension operations can only extend to a channel with a wider data type and
-/// identical extra signals.
-template
-static LogicalResult verifyTruncOp(Op op) {
- ChannelType srcType = op.getIn().getType();
- ChannelType dstType = op.getOut().getType();
+
+LogicalResult TruncIOp::verify() {
+ ChannelType srcType = getIn().getType();
+ ChannelType dstType = getOut().getType();
if (srcType.getDataBitWidth() < dstType.getDataBitWidth()) {
- return op.emitError() << "result channel's data type "
- << dstType.getDataType()
- << " must be narrower than operand type "
- << srcType.getDataType();
+ return emitError() << "result channel's data type " << dstType.getDataType()
+ << " must be narrower than operand type "
+ << srcType.getDataType();
}
return success();
}
-LogicalResult TruncIOp::verify() { return verifyTruncOp(*this); }
-
-//===----------------------------------------------------------------------===//
-// TruncFOp
-//===----------------------------------------------------------------------===//
-
-LogicalResult TruncFOp::verify() { return verifyTruncOp(*this); }
-
-//===----------------------------------------------------------------------===//
-// ExtFOp
-//===----------------------------------------------------------------------===//
-LogicalResult ExtFOp::verify() { return verifyExtOp(*this); }
-
#define GET_OP_CLASSES
#include "dynamatic/Dialect/Handshake/Handshake.cpp.inc"
\ No newline at end of file
diff --git a/lib/Support/RTL/RTL.cpp b/lib/Support/RTL/RTL.cpp
index 1b2c489b0a..30cfe5db2d 100644
--- a/lib/Support/RTL/RTL.cpp
+++ b/lib/Support/RTL/RTL.cpp
@@ -281,132 +281,171 @@ static std::string getBitwidthString(Type type) {
return std::to_string(handshake::getHandshakeTypeBitWidth(type));
}
-void RTLMatch::registerParameters(hw::HWModuleExternOp &modOp) {
- auto modName =
+LogicalResult RTLMatch::registerParameters(hw::HWModuleExternOp &modOp) {
+ auto handshakeOp =
modOp->template getAttrOfType(RTL_NAME_ATTR_NAME).getValue();
auto modType = modOp.getModuleType();
- registerBitwidthParameter(modOp, modName, modType);
- registerExtraSignalParameters(modOp, modName, modType);
+ LogicalResult gotBitwidth =
+ registerBitwidthParameter(modOp, handshakeOp, modType);
+ LogicalResult gotExtraSignals =
+ registerExtraSignalParameters(modOp, handshakeOp, modType);
+
+ return success(gotBitwidth.succeeded() && gotExtraSignals.succeeded());
}
-void RTLMatch::registerBitwidthParameter(hw::HWModuleExternOp &modOp,
- llvm::StringRef modName,
- hw::ModuleType &modType) {
+LogicalResult RTLMatch::registerBitwidthParameter(hw::HWModuleExternOp &modOp,
+ llvm::StringRef handshakeOp,
+ hw::ModuleType &modType) {
if (
// default (All(Data)TypesMatch)
- modName == "handshake.addi" || modName == "handshake.andi" ||
- modName == "handshake.buffer" || modName == "handshake.cmpi" ||
- modName == "handshake.fork" || modName == "handshake.lazy_fork" ||
- modName == "handshake.merge" || modName == "handshake.muli" ||
- modName == "handshake.sink" || modName == "handshake.subi" ||
- modName == "handshake.shli" || modName == "handshake.blocker" ||
- modName == "handshake.sitofp" || modName == "handshake.fptosi" ||
- modName == "handshake.ready_remover" ||
+ handshakeOp == "handshake.addi" || handshakeOp == "handshake.andi" ||
+ handshakeOp == "handshake.buffer" || handshakeOp == "handshake.cmpi" ||
+ handshakeOp == "handshake.fork" || handshakeOp == "handshake.lazy_fork" ||
+ handshakeOp == "handshake.merge" || handshakeOp == "handshake.muli" ||
+ handshakeOp == "handshake.sink" || handshakeOp == "handshake.subi" ||
+ handshakeOp == "handshake.shli" || handshakeOp == "handshake.blocker" ||
+ handshakeOp == "handshake.sitofp" || handshakeOp == "handshake.fptosi" ||
+ handshakeOp == "handshake.rigidifier" || handshakeOp == "handshake.ori" ||
+ handshakeOp == "handshake.shrsi" || handshakeOp == "handshake.xori" ||
+ handshakeOp == "handshake.negf" || handshakeOp == "handshake.divsi" ||
+ handshakeOp == "handshake.absf" || handshakeOp == "handshake.divui" ||
+ handshakeOp == "handshake.shrui" || handshakeOp == "handshake.remsi" ||
// the first input has data bitwidth
- modName == "handshake.speculator" || modName == "handshake.spec_commit" ||
- modName == "handshake.spec_save_commit" ||
- modName == "handshake.sharing_wrapper" ||
- modName == "handshake.non_spec") {
+ handshakeOp == "handshake.speculator" ||
+ handshakeOp == "handshake.spec_commit" ||
+ handshakeOp == "handshake.spec_save_commit" ||
+ handshakeOp == "handshake.sharing_wrapper" ||
+ handshakeOp == "handshake.non_spec") {
// Default
serializedParams["BITWIDTH"] = getBitwidthString(modType.getInputType(0));
- } else if (modName == "handshake.cond_br" || modName == "handshake.select") {
+ } else if (handshakeOp == "handshake.cond_br" ||
+ handshakeOp == "handshake.select") {
serializedParams["BITWIDTH"] = getBitwidthString(modType.getInputType(1));
- } else if (modName == "handshake.constant") {
+ } else if (handshakeOp == "handshake.constant") {
serializedParams["BITWIDTH"] = getBitwidthString(modType.getOutputType(0));
- } else if (modName == "handshake.control_merge") {
+ } else if (handshakeOp == "handshake.control_merge") {
serializedParams["DATA_BITWIDTH"] =
getBitwidthString(modType.getInputType(0));
serializedParams["INDEX_BITWIDTH"] =
getBitwidthString(modType.getOutputType(1));
- } else if (modName == "handshake.extsi" || modName == "handshake.trunci" ||
- modName == "handshake.extui") {
+ } else if (handshakeOp == "handshake.extsi" ||
+ handshakeOp == "handshake.trunci" ||
+ handshakeOp == "handshake.extui") {
serializedParams["INPUT_BITWIDTH"] =
getBitwidthString(modType.getInputType(0));
serializedParams["OUTPUT_BITWIDTH"] =
getBitwidthString(modType.getOutputType(0));
- } else if (modName == "handshake.load") {
+ } else if (handshakeOp == "handshake.load") {
serializedParams["ADDR_BITWIDTH"] =
getBitwidthString(modType.getInputType(0));
serializedParams["DATA_BITWIDTH"] =
getBitwidthString(modType.getOutputType(1));
- } else if (modName == "handshake.mux") {
+ } else if (handshakeOp == "handshake.mux") {
serializedParams["INDEX_BITWIDTH"] =
getBitwidthString(modType.getInputType(0));
serializedParams["DATA_BITWIDTH"] =
getBitwidthString(modType.getInputType(1));
- } else if (modName == "handshake.store") {
+ } else if (handshakeOp == "handshake.store") {
serializedParams["ADDR_BITWIDTH"] =
getBitwidthString(modType.getInputType(0));
serializedParams["DATA_BITWIDTH"] =
getBitwidthString(modType.getInputType(1));
- } else if (modName == "handshake.speculating_branch") {
+ } else if (handshakeOp == "handshake.speculating_branch") {
serializedParams["SPEC_TAG_BITWIDTH"] =
getBitwidthString(modType.getInputType(0));
serializedParams["DATA_BITWIDTH"] =
getBitwidthString(modType.getInputType(1));
- } else if (modName == "handshake.mem_controller" ||
- modName == "handshake.lsq") {
+ } else if (handshakeOp == "handshake.mem_controller" ||
+ handshakeOp == "handshake.lsq") {
serializedParams["DATA_BITWIDTH"] =
getBitwidthString(modType.getInputType(0));
// Warning: Ports differ from instance to instance.
// Therefore, mod.getNumOutputs() is also variable.
serializedParams["ADDR_BITWIDTH"] =
getBitwidthString(modType.getOutputType(modType.getNumOutputs() - 2));
- } else if (modName == "mem_to_bram") {
+ } else if (handshakeOp == "mem_to_bram") {
serializedParams["ADDR_BITWIDTH"] =
getBitwidthString(modType.getInputType(1));
serializedParams["DATA_BITWIDTH"] =
getBitwidthString(modType.getInputType(4));
- } else if (modName == "handshake.addf" || modName == "handshake.cmpf" ||
- modName == "handshake.mulf" || modName == "handshake.subf" ||
- modName == "handshake.divf" || modName == "handshake.negf" ||
- modName == "handshake.maximumf" ||
- modName == "handshake.minimumf") {
+ } else if (handshakeOp == "handshake.addf" ||
+ handshakeOp == "handshake.cmpf" ||
+ handshakeOp == "handshake.mulf" ||
+ handshakeOp == "handshake.subf" ||
+ handshakeOp == "handshake.divf") {
int bitwidth = handshake::getHandshakeTypeBitWidth(modType.getInputType(0));
serializedParams["IS_DOUBLE"] = bitwidth == 64 ? "True" : "False";
- } else if (modName == "handshake.valid_merger") {
+ } else if (handshakeOp == "handshake.valid_merger") {
serializedParams["LEFT_BITWIDTH"] =
getBitwidthString(modType.getInputType(0));
serializedParams["RIGHT_BITWIDTH"] =
getBitwidthString(modType.getInputType(1));
- } else if (modName == "handshake.source" || modName == "mem_controller") {
+ } else if (handshakeOp == "handshake.source" ||
+ handshakeOp == "mem_controller" ||
+ handshakeOp == "handshake.truncf" ||
+ handshakeOp == "handshake.extf" ||
+ handshakeOp == "handshake.maximumf" ||
+ handshakeOp == "handshake.minimumf" ||
+ handshakeOp == "handshake.join") {
// Skip
+ } else {
+ modOp->emitError("Failed to get bitwidth of operation");
+ return failure();
}
+ return success();
}
-void RTLMatch::registerExtraSignalParameters(hw::HWModuleExternOp &modOp,
- llvm::StringRef modName,
- hw::ModuleType &modType) {
+LogicalResult
+RTLMatch::registerExtraSignalParameters(hw::HWModuleExternOp &modOp,
+ llvm::StringRef handshakeOp,
+ hw::ModuleType &modType) {
+
if (
// default (AllExtraSignalsMatch)
- modName == "handshake.addf" || modName == "handshake.addi" ||
- modName == "handshake.andi" || modName == "handshake.buffer" ||
- modName == "handshake.cmpf" || modName == "handshake.cmpi" ||
- modName == "handshake.cond_br" || modName == "handshake.constant" ||
- modName == "handshake.extsi" || modName == "handshake.fork" ||
- modName == "handshake.merge" || modName == "handshake.mulf" ||
- modName == "handshake.muli" || modName == "handshake.select" ||
- modName == "handshake.sink" || modName == "handshake.subf" ||
- modName == "handshake.extui" || modName == "handshake.shli" ||
- modName == "handshake.subi" || modName == "handshake.spec_save_commit" ||
- modName == "handshake.speculator" || modName == "handshake.trunci" ||
- modName == "handshake.mux" || modName == "handshake.control_merge" ||
- modName == "handshake.blocker" || modName == "handshake.sitofp" ||
- modName == "handshake.fptosi" || modName == "handshake.lazy_fork" ||
+ handshakeOp == "handshake.addf" || handshakeOp == "handshake.addi" ||
+ handshakeOp == "handshake.andi" || handshakeOp == "handshake.buffer" ||
+ handshakeOp == "handshake.cmpf" || handshakeOp == "handshake.cmpi" ||
+ handshakeOp == "handshake.cond_br" ||
+ handshakeOp == "handshake.constant" || handshakeOp == "handshake.extsi" ||
+ handshakeOp == "handshake.fork" || handshakeOp == "handshake.merge" ||
+ handshakeOp == "handshake.mulf" || handshakeOp == "handshake.muli" ||
+ handshakeOp == "handshake.select" || handshakeOp == "handshake.sink" ||
+ handshakeOp == "handshake.subf" || handshakeOp == "handshake.extui" ||
+ handshakeOp == "handshake.shli" || handshakeOp == "handshake.subi" ||
+ handshakeOp == "handshake.spec_save_commit" ||
+ handshakeOp == "handshake.speculator" ||
+ handshakeOp == "handshake.trunci" || handshakeOp == "handshake.mux" ||
+ handshakeOp == "handshake.control_merge" ||
+ handshakeOp == "handshake.blocker" || handshakeOp == "handshake.sitofp" ||
+ handshakeOp == "handshake.fptosi" ||
+ handshakeOp == "handshake.lazy_fork" || handshakeOp == "handshake.divf" ||
+ handshakeOp == "handshake.ori" || handshakeOp == "handshake.shrsi" ||
+ handshakeOp == "handshake.xori" || handshakeOp == "handshake.negf" ||
+ handshakeOp == "handshake.truncf" || handshakeOp == "handshake.divsi" ||
+ handshakeOp == "handshake.absf" || handshakeOp == "handshake.divui" ||
+ handshakeOp == "handshake.extf" || handshakeOp == "handshake.maximumf" ||
+ handshakeOp == "handshake.minimumf" || handshakeOp == "handshake.shrui" ||
+ handshakeOp == "handshake.join" || handshakeOp == "handshake.remsi" ||
// the first input has extra signals
- modName == "handshake.load" || modName == "handshake.store" ||
- modName == "handshake.spec_commit" ||
- modName == "handshake.speculating_branch") {
+ handshakeOp == "handshake.load" || handshakeOp == "handshake.store" ||
+ handshakeOp == "handshake.spec_commit" ||
+ handshakeOp == "handshake.speculating_branch") {
serializedParams["EXTRA_SIGNALS"] =
serializeExtraSignals(modType.getInputType(0));
- } else if (modName == "handshake.source" || modName == "handshake.non_spec") {
+ } else if (handshakeOp == "handshake.source" ||
+ handshakeOp == "handshake.non_spec") {
serializedParams["EXTRA_SIGNALS"] =
serializeExtraSignals(modType.getOutputType(0));
- } else if (modName == "handshake.mem_controller" ||
- modName == "mem_to_bram") {
+ } else if (handshakeOp == "handshake.mem_controller" ||
+ handshakeOp == "mem_to_bram" || handshakeOp == "handshake.lsq" ||
+ handshakeOp == "handshake.sharing_wrapper") {
// Skip
+ } else {
+ modOp.emitError("Failed to get extra signals of operation");
+ return failure();
}
+ return success();
}
LogicalResult RTLMatch::concretize(const RTLRequest &request,
diff --git a/lib/Transforms/BufferPlacement/HandshakePlaceBuffers.cpp b/lib/Transforms/BufferPlacement/HandshakePlaceBuffers.cpp
index 78ec3650cf..bc52ba6cc9 100644
--- a/lib/Transforms/BufferPlacement/HandshakePlaceBuffers.cpp
+++ b/lib/Transforms/BufferPlacement/HandshakePlaceBuffers.cpp
@@ -249,20 +249,34 @@ void HandshakePlaceBuffersPass::runOnOperation() {
if (failed(TimingDatabase::readFromJSON(timingModels, timingDB)))
llvm::errs() << "=== TimindDB read failed ===\n";
modOp.walk([&](mlir::Operation *op) {
- if (auto internalDelayInterface =
- llvm::dyn_cast(op)) {
+ if (auto fpuImplInterface =
+ llvm::dyn_cast(op)) {
double delay;
+
if (!failed(timingDB.getInternalCombinationalDelay(op, SignalType::DATA,
delay, targetCP))) {
std::string delayStr = std::to_string(delay);
std::replace(delayStr.begin(), delayStr.end(), '.', '_');
- internalDelayInterface.setInternalDelay(delayStr);
+ fpuImplInterface.setInternalDelay(delayStr);
} else {
op->emitError("Failed to get internal delay from timing model");
return signalPassFailure();
}
}
+ if (auto latencyInterface =
+ llvm::dyn_cast(op)) {
+ double latency;
+ if (!failed(
+ timingDB.getLatency(op, SignalType::DATA, latency, targetCP))) {
+
+ int64_t latency_int = static_cast(latency);
+ latencyInterface.setLatency(latency_int);
+ } else {
+ op->emitError("Failed to get latency from timing model");
+ return signalPassFailure();
+ }
+ }
});
// Make sure all operation names are unique and haven't changed from what is
diff --git a/test/Conversion/HandshakeToHW/types.mlir b/test/Conversion/HandshakeToHW/types.mlir
index fcdaed1823..70e692511b 100644
--- a/test/Conversion/HandshakeToHW/types.mlir
+++ b/test/Conversion/HandshakeToHW/types.mlir
@@ -21,8 +21,8 @@ handshake.func @dontChangeTypes(%arg : !handshake.channel, %start: !handsha
// CHECK: %[[VAL_4:.*]] = hw.instance "addf0" @handshake_addf_0(lhs: %[[VAL_0]]: !handshake.channel, rhs: %[[VAL_1]]: !handshake.channel, clk: %[[VAL_2]]: i1, rst: %[[VAL_3]]: i1) -> (result: !handshake.channel)
// CHECK: hw.output %[[VAL_4]] : !handshake.channel
// CHECK: }
-// CHECK: hw.module.extern @handshake_addf_0(in %[[VAL_6:.*]] : !handshake.channel, in %[[VAL_7:.*]] : !handshake.channel, in %[[VAL_8:.*]] : i1, in %[[VAL_9:.*]] : i1, out result : !handshake.channel) attributes {hw.name = "handshake.addf", hw.parameters = {DATA_TYPE = !handshake.channel, FPU_IMPL = "flopoco", INTERNAL_DELAY = "0.0"}}
+// CHECK: hw.module.extern @handshake_addf_0(in %[[VAL_6:.*]] : !handshake.channel, in %[[VAL_7:.*]] : !handshake.channel, in %[[VAL_8:.*]] : i1, in %[[VAL_9:.*]] : i1, out result : !handshake.channel) attributes {hw.name = "handshake.addf", hw.parameters = {DATA_TYPE = !handshake.channel, FPU_IMPL = "flopoco", INTERNAL_DELAY = "0_0", LATENCY = 1 : ui32}}
handshake.func @lowerNonIntTypes(%arg0 : !handshake.channel, %arg1 : !handshake.channel) -> !handshake.channel {
- %res = addf %arg0, %arg1 :
+ %res = addf %arg0, %arg1 {latency = 1}:
end %res :
}
diff --git a/test/Transforms/HandshakeOptimizeBitwidths/arith-forward.mlir b/test/Transforms/HandshakeOptimizeBitwidths/arith-forward.mlir
index 8cc15538d8..fa3f39ba09 100644
--- a/test/Transforms/HandshakeOptimizeBitwidths/arith-forward.mlir
+++ b/test/Transforms/HandshakeOptimizeBitwidths/arith-forward.mlir
@@ -58,44 +58,6 @@ handshake.func @muliFW(%arg0: !handshake.channel, %arg1: !handshake.channel<
// -----
-// CHECK-LABEL: handshake.func @divuiFW(
-// CHECK-SAME: %[[VAL_0:.*]]: !handshake.channel,
-// CHECK-SAME: %[[VAL_1:.*]]: !handshake.channel,
-// CHECK-SAME: %[[VAL_2:.*]]: !handshake.control<>, ...) -> !handshake.channel attributes {argNames = ["arg0", "arg1", "start"], resNames = ["out0"]} {
-// CHECK: %[[VAL_3:.*]] = trunci %[[VAL_1]] {handshake.bb = 0 : ui32} : to
-// CHECK: %[[VAL_4:.*]] = extsi %[[VAL_0]] {handshake.bb = 0 : ui32} : to
-// CHECK: %[[VAL_5:.*]] = divui %[[VAL_4]], %[[VAL_3]] :
-// CHECK: %[[VAL_6:.*]] = extui %[[VAL_5]] : to
-// CHECK: end %[[VAL_6]] :
-// CHECK: }
-handshake.func @divuiFW(%arg0: !handshake.channel, %arg1: !handshake.channel, %start: !handshake.control<>) -> !handshake.channel {
- %ext0 = extsi %arg0 : to
- %ext1 = extsi %arg1 : to
- %res = divui %ext0, %ext1 :
- end %res :
-}
-
-// -----
-
-// CHECK-LABEL: handshake.func @divsiFW(
-// CHECK-SAME: %[[VAL_0:.*]]: !handshake.channel,
-// CHECK-SAME: %[[VAL_1:.*]]: !handshake.channel,
-// CHECK-SAME: %[[VAL_2:.*]]: !handshake.control<>, ...) -> !handshake.channel attributes {argNames = ["arg0", "arg1", "start"], resNames = ["out0"]} {
-// CHECK: %[[VAL_3:.*]] = trunci %[[VAL_1]] {handshake.bb = 0 : ui32} : to
-// CHECK: %[[VAL_4:.*]] = extsi %[[VAL_0]] {handshake.bb = 0 : ui32} : to
-// CHECK: %[[VAL_5:.*]] = divsi %[[VAL_4]], %[[VAL_3]] :
-// CHECK: %[[VAL_6:.*]] = extsi %[[VAL_5]] : to
-// CHECK: end %[[VAL_6]] :
-// CHECK: }
-handshake.func @divsiFW(%arg0: !handshake.channel, %arg1: !handshake.channel, %start: !handshake.control<>) -> !handshake.channel {
- %ext0 = extsi %arg0 : to
- %ext1 = extsi %arg1 : to
- %res = divsi %ext0, %ext1 :
- end %res :
-}
-
-// -----
-
// CHECK-LABEL: handshake.func @andiFW(
// CHECK-SAME: %[[VAL_0:.*]]: !handshake.channel,
// CHECK-SAME: %[[VAL_1:.*]]: !handshake.channel,
diff --git a/tools/dynamatic/dynamatic.cpp b/tools/dynamatic/dynamatic.cpp
index a790b7b49f..6802ce245d 100644
--- a/tools/dynamatic/dynamatic.cpp
+++ b/tools/dynamatic/dynamatic.cpp
@@ -682,7 +682,7 @@ CommandResult WriteHDL::execute(CommandArguments &args) {
hdl = "vhdl-beta";
} else if (it->second != "vhdl") {
llvm::errs() << "Unknow HDL '" << it->second
- << "', possible options are 'vhdl', "
+ << "', possible options are 'vhdl', 'vhdl-beta',"
"'verilog', and 'smv'.\n";
return CommandResult::FAIL;
}
diff --git a/tools/export-rtl/export-rtl.cpp b/tools/export-rtl/export-rtl.cpp
index c32d8dae31..55f6cabfb9 100644
--- a/tools/export-rtl/export-rtl.cpp
+++ b/tools/export-rtl/export-rtl.cpp
@@ -171,8 +171,8 @@ LogicalResult ExportInfo::concretizeExternalModules() {
// Try to find a matching component
RTLMatch *match = config.getMatchingComponent(request);
if (!match) {
- emitError(request.loc)
- << "Failed to find matching RTL component for external module";
+ extOp->emitError(
+ "Failed to find matching RTL component for external module");
llvm::errs() << extOp->getAttrOfType(
RTL_PARAMETERS_ATTR_NAME)
<< "\n";
@@ -203,7 +203,12 @@ LogicalResult ExportInfo::concretizeExternalModules() {
// Parameter analysis
// TODO: Do this at the HW-level analysis
if (extOp)
- match->registerParameters(extOp);
+ if (match->registerParameters(extOp).failed()) {
+ llvm::errs() << extOp->getAttrOfType(RTL_NAME_ATTR_NAME)
+ << "\n";
+
+ return failure();
+ }
// ...then generate the component itself
return match->concretize(request, dynamaticPath, outputPath);
diff --git a/tools/hls-verifier/resources/template_two_port_RAM.vhd b/tools/hls-verifier/resources/template_two_port_RAM.vhd
index ae05694c95..c2a20771e8 100644
--- a/tools/hls-verifier/resources/template_two_port_RAM.vhd
+++ b/tools/hls-verifier/resources/template_two_port_RAM.vhd
@@ -66,8 +66,14 @@ begin
index := 0;
file_open(file_status, file_ptr, TV_IN, READ_MODE);
- if (file_status /= OPEN_OK) then
- assert false report "ERROR: Could not open file: " & TV_IN severity failure;
+ if file_status = NAME_ERROR then
+ report "ERROR: File not found: " & TV_IN severity failure;
+ elsif file_status = STATUS_ERROR then
+ report "ERROR: File already open: " & TV_IN severity failure;
+ elsif file_status = MODE_ERROR then
+ report "ERROR: File mode error: " & TV_IN severity failure;
+ elsif file_status /= OPEN_OK then
+ report "ERROR: Unknown file open error: " & TV_IN severity failure;
end if;
-- Use read_token procedure to read tokens from the file