Skip to content

Commit e3e43d2

Browse files
authored
Support internal C>>17/PCIN>>17 feature on Xilinx DSPs (#465)
Closes #464
1 parent e218874 commit e3e43d2

9 files changed

+233
-40
lines changed

architecture_descriptions/xilinx_ultrascale_plus.yml

+3-2
Original file line numberDiff line numberDiff line change
@@ -164,7 +164,8 @@ implementations:
164164
# connectivity or OPMODE value to allow for proper implementation.
165165
#
166166
# TODO(@gussmith23): deal with this when we support multiple DSPs.
167-
"(not (bveq (extract 5 4 OPMODE) (bv #b01 2)))",
167+
# This is the line that we need to get rid of to use PCIN.
168+
# "(not (bveq (extract 5 4 OPMODE) (bv #b01 2)))",
168169

169170
# ERROR: [DRC DSPS-4] Invalid PCIN Connection for CARRYINSEL value: DSP48E2 cell DSP48E2_0
170171
# has CARRYINSEL[2:0] set to 011 which uses the input of the PCIN bus for its computation,
@@ -250,7 +251,7 @@ implementations:
250251
{ name: INMODE, direction: input, bitwidth: 5, value: INMODE },
251252
{ name: MULTSIGNIN, direction: input, bitwidth: 1, value: (bv 0 1) },
252253
{ name: OPMODE, direction: input, bitwidth: 9, value: OPMODE },
253-
{ name: PCIN, direction: input, bitwidth: 48, value: (bv 0 48) },
254+
{ name: PCIN, direction: input, bitwidth: 48, value: (choose (zero-extend C (bitvector 48)) (bv 0 48)) },
254255
{ name: RSTA, direction: input, bitwidth: 1, value: (bv 0 1) },
255256
{ name: RSTALLCARRYIN, direction: input, bitwidth: 1, value: (bv 0 1) },
256257
{ name: RSTALUMODE, direction: input, bitwidth: 1, value: (bv 0 1) },

integration_tests/lakeroad/two_stage_multiplier_xilinx.v

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
// RUN: racket $LAKEROAD_DIR/bin/main.rkt \
2-
// RUN: --solver bitwuzla \
2+
// RUN: --solver cvc5 \
33
// RUN: --verilog-module-filepath %s \
44
// RUN: --architecture xilinx-ultrascale-plus \
55
// RUN: --template dsp \

integration_tests/lakeroad/xilinx_addmuland_1_stage_signed_18_bit.sv

+33-35
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,8 @@
33
// either it wasn't that change, or some other change I did after it just
44
// further cemented the breakage.
55
//
6-
// outfile=$(mktemp)
7-
// RUN: (racket $LAKEROAD_DIR/bin/main.rkt \
6+
// RUN: outfile=$(mktemp)
7+
// RUN: racket $LAKEROAD_DIR/bin/main.rkt \
88
// RUN: --solver bitwuzla \
99
// RUN: --verilog-module-filepath %s \
1010
// RUN: --architecture xilinx-ultrascale-plus \
@@ -14,44 +14,42 @@
1414
// RUN: --verilog-module-out-signal out:18 \
1515
// RUN: --pipeline-depth 1 \
1616
// RUN: --clock-name clk \
17-
// RUN: --module-name top \
17+
// RUN: --module-name out \
1818
// RUN: --input-signal 'a:(port a 18):18' \
1919
// RUN: --input-signal 'b:(port b 18):18' \
2020
// RUN: --input-signal 'c:(port c 18):18' \
2121
// RUN: --input-signal 'd:(port d 18):18' \
2222
// RUN: --timeout 60 \
2323
// RUN: --extra-cycles 3 \
24-
// RUN: || true) 2>&1 \
25-
// RUN: | FileCheck %s
26-
// > $outfile
27-
// FileCheck %s < $outfile
28-
// if [ -z ${LAKEROAD_PRIVATE_DIR+x} ]; then \
29-
// echo "Warning: LAKEROAD_PRIVATE_DIR is not set. Skipping simulation."; \
30-
// exit 0; \
31-
// else \
32-
// python3 $LAKEROAD_DIR/bin/simulate_with_verilator.py \
33-
// --use_random_intermediate_inputs \
34-
// --seed=23 \
35-
// --max_num_tests=10000 \
36-
// --verilog_filepath $outfile \
37-
// --verilog_filepath %s \
38-
// --clock_name clk \
39-
// --pipeline_depth 1 \
40-
// --output_signal_name out \
41-
// --input_signal a:18 \
42-
// --input_signal b:18 \
43-
// --input_signal c:18 \
44-
// --input_signal d:18 \
45-
// --verilator_include_dir "$LAKEROAD_PRIVATE_DIR/DSP48E2/" \
46-
// --verilator_extra_arg='-DXIL_XECLIB' \
47-
// --verilator_extra_arg='-Wno-UNOPTFLAT' \
48-
// --verilator_extra_arg='-Wno-LATCH' \
49-
// --verilator_extra_arg='-Wno-WIDTH' \
50-
// --verilator_extra_arg='-Wno-STMTDLY' \
51-
// --verilator_extra_arg='-Wno-CASEX' \
52-
// --verilator_extra_arg='-Wno-TIMESCALEMOD' \
53-
// --verilator_extra_arg='-Wno-PINMISSING'; \
54-
// fi
24+
// RUN: > $outfile
25+
// RUN: FileCheck %s < $outfile
26+
// RUN: if [ -z ${LAKEROAD_PRIVATE_DIR+x} ]; then \
27+
// RUN: echo "Warning: LAKEROAD_PRIVATE_DIR is not set. Skipping simulation."; \
28+
// RUN: exit 0; \
29+
// RUN: else \
30+
// RUN: python3 $LAKEROAD_DIR/bin/simulate_with_verilator.py \
31+
// RUN: --test_module_name out \
32+
// RUN: --ground_truth_module_name top \
33+
// RUN: --max_num_tests=10000 \
34+
// RUN: --verilog_filepath $outfile \
35+
// RUN: --verilog_filepath %s \
36+
// RUN: --clock_name clk \
37+
// RUN: --pipeline_depth 1 \
38+
// RUN: --output_signal out:18 \
39+
// RUN: --input_signal a:18 \
40+
// RUN: --input_signal b:18 \
41+
// RUN: --input_signal c:18 \
42+
// RUN: --input_signal d:18 \
43+
// RUN: --verilator_include_dir "$LAKEROAD_PRIVATE_DIR/DSP48E2/" \
44+
// RUN: --verilator_extra_arg='-DXIL_XECLIB' \
45+
// RUN: --verilator_extra_arg='-Wno-UNOPTFLAT' \
46+
// RUN: --verilator_extra_arg='-Wno-LATCH' \
47+
// RUN: --verilator_extra_arg='-Wno-WIDTH' \
48+
// RUN: --verilator_extra_arg='-Wno-STMTDLY' \
49+
// RUN: --verilator_extra_arg='-Wno-CASEX' \
50+
// RUN: --verilator_extra_arg='-Wno-TIMESCALEMOD' \
51+
// RUN: --verilator_extra_arg='-Wno-PINMISSING'; \
52+
// RUN: fi
5553

5654
(* use_dsp = "yes" *) module top(
5755
input signed [17:0] a,
@@ -71,4 +69,4 @@
7169
assign out = stage0;
7270
endmodule
7371

74-
// CHECK: Synthesis Timeout
72+
// CHECK: module out(a, b, c, clk, d, out);

integration_tests/lakeroad/xilinx_muladd_0_stage_unsigned_13_bit.sv

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
// RUN: outfile=$(mktemp)
22
// RUN: racket $LAKEROAD_DIR/bin/main.rkt \
3-
// RUN: --solver stp \
3+
// RUN: --solver cvc5 \
44
// RUN: --verilog-module-filepath %s \
55
// RUN: --architecture xilinx-ultrascale-plus \
66
// RUN: --template dsp \

integration_tests/lakeroad/xilinx_mulsub_1_stage_unsigned_14_bit.sv

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
// RUN: outfile=$(mktemp)
22
// RUN: racket $LAKEROAD_DIR/bin/main.rkt \
3-
// RUN: --solver bitwuzla \
3+
// RUN: --solver cvc5 \
44
// RUN: --verilog-module-filepath %s \
55
// RUN: --architecture xilinx-ultrascale-plus \
66
// RUN: --template dsp \
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
// RUN: outfile=$(mktemp)
2+
// RUN: racket $LAKEROAD_DIR/bin/main.rkt \
3+
// RUN: --solver bitwuzla \
4+
// RUN: --verilog-module-filepath %s \
5+
// RUN: --architecture xilinx-ultrascale-plus \
6+
// RUN: --template dsp \
7+
// RUN: --out-format verilog \
8+
// RUN: --top-module-name top \
9+
// RUN: --verilog-module-out-signal out:48 \
10+
// RUN: --pipeline-depth 0 \
11+
// RUN: --module-name out \
12+
// RUN: --input-signal 'c:(port c 47):47' \
13+
// RUN: --timeout 90 \
14+
// RUN: > $outfile
15+
// RUN: FileCheck %s < $outfile
16+
// RUN: if [ -z ${LAKEROAD_PRIVATE_DIR+x} ]; then \
17+
// RUN: echo "Warning: LAKEROAD_PRIVATE_DIR is not set. Skipping simulation."; \
18+
// RUN: exit 0; \
19+
// RUN: else \
20+
// RUN: python3 $LAKEROAD_DIR/bin/simulate_with_verilator.py \
21+
// RUN: --test_module_name out \
22+
// RUN: --ground_truth_module_name top \
23+
// RUN: --max_num_tests=10000 \
24+
// RUN: --verilog_filepath $outfile \
25+
// RUN: --verilog_filepath %s \
26+
// RUN: --pipeline_depth 0 \
27+
// RUN: --output_signal out:48 \
28+
// RUN: --input_signal c:47 \
29+
// RUN: --verilator_include_dir "$LAKEROAD_PRIVATE_DIR/DSP48E2/" \
30+
// RUN: --verilator_extra_arg='-DXIL_XECLIB' \
31+
// RUN: --verilator_extra_arg='-Wno-UNOPTFLAT' \
32+
// RUN: --verilator_extra_arg='-Wno-LATCH' \
33+
// RUN: --verilator_extra_arg='-Wno-WIDTH' \
34+
// RUN: --verilator_extra_arg='-Wno-STMTDLY' \
35+
// RUN: --verilator_extra_arg='-Wno-CASEX' \
36+
// RUN: --verilator_extra_arg='-Wno-TIMESCALEMOD' \
37+
// RUN: --verilator_extra_arg='-Wno-PINMISSING'; \
38+
// RUN: fi
39+
40+
// TODO(@gussmith23): For some reason, this doesn't work with c of length 48.
41+
// Works with 47 though.
42+
module top(input [46:0] c, output [47:0] out);
43+
assign out = 48'(48'(c) >> 17);
44+
endmodule
45+
46+
// CHECK: module out(c, out);
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
// RUN: outfile=$(mktemp)
2+
// RUN: (racket $LAKEROAD_DIR/bin/main.rkt \
3+
// RUN: --solver bitwuzla \
4+
// RUN: --verilog-module-filepath %s \
5+
// RUN: --architecture xilinx-ultrascale-plus \
6+
// RUN: --template dsp \
7+
// RUN: --out-format verilog \
8+
// RUN: --top-module-name top \
9+
// RUN: --verilog-module-out-signal out:48 \
10+
// RUN: --pipeline-depth 0 \
11+
// RUN: --module-name out \
12+
// RUN: --input-signal 'c:(port c 48):48' \
13+
// RUN: --timeout 90 \
14+
// RUN: || true) \
15+
// RUN: > $outfile \
16+
// RUN: 2>&1
17+
// RUN: FileCheck %s < $outfile
18+
// if [ -z ${LAKEROAD_PRIVATE_DIR+x} ]; then \
19+
// echo "Warning: LAKEROAD_PRIVATE_DIR is not set. Skipping simulation."; \
20+
// exit 0; \
21+
// else \
22+
// python3 $LAKEROAD_DIR/bin/simulate_with_verilator.py \
23+
// --test_module_name out \
24+
// --ground_truth_module_name top \
25+
// --max_num_tests=10000 \
26+
// --verilog_filepath $outfile \
27+
// --verilog_filepath %s \
28+
// --pipeline_depth 0 \
29+
// --output_signal out:48 \
30+
// --input_signal c:47 \
31+
// --verilator_include_dir "$LAKEROAD_PRIVATE_DIR/DSP48E2/" \
32+
// --verilator_extra_arg='-DXIL_XECLIB' \
33+
// --verilator_extra_arg='-Wno-UNOPTFLAT' \
34+
// --verilator_extra_arg='-Wno-LATCH' \
35+
// --verilator_extra_arg='-Wno-WIDTH' \
36+
// --verilator_extra_arg='-Wno-STMTDLY' \
37+
// --verilator_extra_arg='-Wno-CASEX' \
38+
// --verilator_extra_arg='-Wno-TIMESCALEMOD' \
39+
// --verilator_extra_arg='-Wno-PINMISSING'; \
40+
// fi
41+
42+
// TODO(@gussmith23): For some reason, this doesn't work with c of length 48.
43+
// Works with 47 though.
44+
module top(input [47:0] c, output [47:0] out);
45+
assign out = 48'(48'(c) >> 17);
46+
endmodule
47+
48+
// CHECK: Synthesis failed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
// RUN: outfile=$(mktemp)
2+
// RUN: racket $LAKEROAD_DIR/bin/main.rkt \
3+
// RUN: --solver bitwuzla \
4+
// RUN: --verilog-module-filepath %s \
5+
// RUN: --architecture xilinx-ultrascale-plus \
6+
// RUN: --template dsp \
7+
// RUN: --out-format verilog \
8+
// RUN: --top-module-name top \
9+
// RUN: --verilog-module-out-signal out:48 \
10+
// RUN: --pipeline-depth 0 \
11+
// RUN: --module-name out \
12+
// RUN: --input-signal 'c:(port c 48):48' \
13+
// RUN: --timeout 90 \
14+
// RUN: > $outfile
15+
// RUN: FileCheck %s < $outfile
16+
// RUN: if [ -z ${LAKEROAD_PRIVATE_DIR+x} ]; then \
17+
// RUN: echo "Warning: LAKEROAD_PRIVATE_DIR is not set. Skipping simulation."; \
18+
// RUN: exit 0; \
19+
// RUN: else \
20+
// RUN: python3 $LAKEROAD_DIR/bin/simulate_with_verilator.py \
21+
// RUN: --test_module_name out \
22+
// RUN: --ground_truth_module_name top \
23+
// RUN: --max_num_tests=10000 \
24+
// RUN: --verilog_filepath $outfile \
25+
// RUN: --verilog_filepath %s \
26+
// RUN: --pipeline_depth 0 \
27+
// RUN: --output_signal out:48 \
28+
// RUN: --input_signal c:48 \
29+
// RUN: --verilator_include_dir "$LAKEROAD_PRIVATE_DIR/DSP48E2/" \
30+
// RUN: --verilator_extra_arg='-DXIL_XECLIB' \
31+
// RUN: --verilator_extra_arg='-Wno-UNOPTFLAT' \
32+
// RUN: --verilator_extra_arg='-Wno-LATCH' \
33+
// RUN: --verilator_extra_arg='-Wno-WIDTH' \
34+
// RUN: --verilator_extra_arg='-Wno-STMTDLY' \
35+
// RUN: --verilator_extra_arg='-Wno-CASEX' \
36+
// RUN: --verilator_extra_arg='-Wno-TIMESCALEMOD' \
37+
// RUN: --verilator_extra_arg='-Wno-PINMISSING'; \
38+
// RUN: fi
39+
40+
// TODO(@gussmith23): here, I explicitly do a signed shift, which does
41+
// synthesize. I assumed >> did a signed shift when the arguments are signed,
42+
// but perhaps I'm wrong. Why does this matter? Because it means we need to be
43+
// careful about how we do our rewriting in the egraph. We can't necessarily
44+
// just rewrite to a >> in the egraph without fully understanding the semantics.
45+
// So the task here is to understand how we should be writing the shift
46+
// in a partial-product multiply-splitting scenario.
47+
module top(input [47:0] c, output [47:0] out);
48+
assign out = {{17{c[47]}}, c[47:17]};
49+
endmodule
50+
51+
// CHECK: module out(c, out);
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
// RUN: outfile=$(mktemp)
2+
// RUN: racket $LAKEROAD_DIR/bin/main.rkt \
3+
// RUN: --solver cvc5 \
4+
// RUN: --verilog-module-filepath %s \
5+
// RUN: --architecture xilinx-ultrascale-plus \
6+
// RUN: --template dsp \
7+
// RUN: --out-format verilog \
8+
// RUN: --top-module-name top \
9+
// RUN: --verilog-module-out-signal out:48 \
10+
// RUN: --pipeline-depth 0 \
11+
// RUN: --module-name out \
12+
// RUN: --input-signal 'a:(port a 16):16' \
13+
// RUN: --input-signal 'b:(port b 16):16' \
14+
// RUN: --input-signal 'c:(port c 48):48' \
15+
// RUN: --timeout 90 \
16+
// RUN: > $outfile
17+
// RUN: FileCheck %s < $outfile
18+
// RUN: if [ -z ${LAKEROAD_PRIVATE_DIR+x} ]; then \
19+
// RUN: echo "Warning: LAKEROAD_PRIVATE_DIR is not set. Skipping simulation."; \
20+
// RUN: exit 0; \
21+
// RUN: else \
22+
// RUN: python3 $LAKEROAD_DIR/bin/simulate_with_verilator.py \
23+
// RUN: --test_module_name out \
24+
// RUN: --ground_truth_module_name top \
25+
// RUN: --max_num_tests=10000 \
26+
// RUN: --verilog_filepath $outfile \
27+
// RUN: --verilog_filepath %s \
28+
// RUN: --pipeline_depth 0 \
29+
// RUN: --output_signal out:48 \
30+
// RUN: --input_signal a:30 \
31+
// RUN: --input_signal b:18 \
32+
// RUN: --input_signal c:48 \
33+
// RUN: --verilator_include_dir "$LAKEROAD_PRIVATE_DIR/DSP48E2/" \
34+
// RUN: --verilator_extra_arg='-DXIL_XECLIB' \
35+
// RUN: --verilator_extra_arg='-Wno-UNOPTFLAT' \
36+
// RUN: --verilator_extra_arg='-Wno-LATCH' \
37+
// RUN: --verilator_extra_arg='-Wno-WIDTH' \
38+
// RUN: --verilator_extra_arg='-Wno-STMTDLY' \
39+
// RUN: --verilator_extra_arg='-Wno-CASEX' \
40+
// RUN: --verilator_extra_arg='-Wno-TIMESCALEMOD' \
41+
// RUN: --verilator_extra_arg='-Wno-PINMISSING'; \
42+
// RUN: fi
43+
44+
module top(input [15:0] a, input [15:0] b, input [47:0] c, output [47:0] out);
45+
logic [31:0] mul_result = a * b;
46+
assign out = mul_result + {{17{c[47]}}, c[47:17]};
47+
endmodule
48+
49+
// CHECK: module out(a, b, c, out);

0 commit comments

Comments
 (0)