[xls/contrib] Tutorial: XLS[cc] Overview
This tutorial is aimed at walking you through getting a function written in C++ and then compiling into a working Verilog module.
This assumes that you've already been successful in building XLS. See Installing and building if not.
Create your first C++ module.
XLS[cc] takes as input a single translation unit -- one .cc
file. Other files
may be included in that one file, but only the top-level file should be
provided.
Create a file called test.cc
with the following contents.
#pragma hls_top
int add3(int input) { return input + 3; }
Note that #pragma hls_top
denotes the top-level function for the module. The
xls func or proc created will follow that function's interface.
Translate into optimized XLS IR.
Now that the C++ function has been created, xlscc
can be used to translate the
C++ into XLS IR. opt_main
is used afterwards to optimize and transform the IR
into a form more easily synthesized into verilog.
$ ./bazel-bin/xls/contrib/xlscc/xlscc test.cc > test.ir
$ ./bazel-bin/xls/tools/opt_main test.ir > test.opt.ir
The resulting test.opt.ir
file should look something like the following
package my_package
file_number 1 "./test.cc"
top fn add3(input: bits[32]) -> bits[32] {
literal.2: bits[32] = literal(value=3, id=2, pos=[(1,2,23)])
ret add.3: bits[32] = add(input, literal.2, id=3, pos=[(1,2,23)])
}
Perform code-generation into a combinational Verilog block.
With the same IR, you can either generate a combinational block or a clocked
pipelined block with the codegen_main
tool. In this section, we'll demonstrate
how to generate a combinational block.
$ ./bazel-bin/xls/tools/codegen_main test.opt.ir \
--generator=combinational \
--delay_model="unit" \
--output_verilog_path=test.v \
--module_name=xls_test \
--top=add3
Below is a quick summary of each option:
--generator=combinational
states thatcodegen_main
should generate a combinational module.--delay_model="unit"
states to use the unit delay model. Additional delay models include asap7 and sky130.--output_verilog_path=test.v
is where the output verilog should be written to.--module_name=xls_test
states that the generated verilog module should have the name ofxls_test
.--top=add3
states that the function that should be used for codegen is the function (fn
) namedadd3
.
The resulting test.v
should have contents similar to the following
module xls_test(
input wire [31:0] input,
output wire [31:0] out
);
wire [31:0] add_6;
assign add_6 = input + 32'h0000_0003;
assign out = add_6;
endmodule
Create your second C++ module and generate an optimized IR file.
XLS[cc] supports two ways of handling looping C++ constructs -- it can unroll the loop, or convert the loop into sequential logic. In this section, we'll demonstrate loop unrolling.
Unrolled loops are annotated with #pragma hls_unroll yes
. For example, create
a file called test_unroll.cc
with the following contents.
#pragma hls_top
int test_unroll(int x) {
int ret = 0;
#pragma hls_unroll yes
for(int i=0;i<32;++i) {
ret += x * i;
}
return ret;
}
Then compile, and optimize the resulting IR
$ ./bazel-bin/xls/contrib/xlscc/xlscc test_unroll.cc > test_unroll.ir
$ ./bazel-bin/xls/tools/opt_main test_unroll.ir > test_unroll.opt.ir
Perform code-generation into a pipelined Verilog block.
The previous section should have left you with an IR file called
test_unroll.opt.ir
with a function with the signature fn test_unroll(x:
bits[32]) -> bits[32]
. The function is likely too large to fit into a single
clock cycle so we'll create a pipelined module.
$ ./bazel-bin/xls/tools/codegen_main test_unroll.opt.ir \
--generator=pipeline \
--delay_model="asap7" \
--output_verilog_path=test_unroll.v \
--module_name=xls_test_unroll \
--entry=test_unroll \
--reset=rst \
--reset_active_low=false \
--reset_asynchronous=false \
--pipeline_stages=5 \
--flop_inputs=true \
--flop_outputs=true
Below is a quick summary of each option:
--generator=pipeline
-codegen_main
should generate a pipelined module.--delay_model="asap7"
- use the asap7 delay model.--output_verilog_path=test_unroll.v
- where the output verilog should be written to.--module_name=xls_test_unroll
- the generated verilog module should have the name ofxls_unroll_test
.--entry=test_unroll
- the function that should be used for codegen is the function (fn
) namedtest_unroll
.--reset=rst
- there should be a reset signal namedrst
.--reset_active_low=false
- a high reset signal means reset the module.--reset_asynchronous=false
- rst is a synchronous reset signal.--pipeline_stages=5
- create a 5 stage pipeline.--flop_inputs=true
and--flop_outputs=true
- input and outputs for the block are registered.
Additional XLS[cc] examples.
The above tutorials only touches upon the capabilities of XLS[cc]. XLS[cc] is based on libclang and supports many C++17 features. Notable unsupported features include pointers, function pointers, and virtual methods.
For developers, it is possible to check if a specific feature is supported by checking translator_logic_test.cc and other unit tests in the same directory.