blob: 1a6d7c100b7353a8c4a414f1a99e979869d52c80 [file] [log] [blame]
Chris Frantz74f90952022-04-18 20:57:01 -07001# Copyright lowRISC contributors.
2# Licensed under the Apache License, Version 2.0, see LICENSE for details.
3# SPDX-License-Identifier: Apache-2.0
4
5load("@nonhermetic//:env.bzl", "ENV")
6
7"""Rules for memory splicing with Vivado.
8"""
9
10def _bitstream_splice_impl(ctx):
11 update = ctx.actions.declare_file("{}.update.mem".format(ctx.label.name))
12 output = ctx.actions.declare_file("{}.bit".format(ctx.label.name))
13
14 ctx.actions.run(
15 mnemonic = "GenVivadoImage",
16 outputs = [update],
17 inputs = [ctx.executable._tool, ctx.file.data],
18 arguments = [
19 ctx.file.data.path,
20 update.path,
Miles Daid88d9fd2022-08-17 11:37:20 -040021 ] + (["--swap-nibbles"] if ctx.attr.swap_nybbles else []),
Chris Frantz74f90952022-04-18 20:57:01 -070022 executable = ctx.executable._tool,
23 use_default_shell_env = True,
24 execution_requirements = {
25 "no-sandbox": "",
26 },
27 )
28
Dan McArdlee1a8aad2022-07-22 12:02:58 -040029 # Vivado's `updatemem` only accepts bitstream filenames that end with
30 # ".bit". If the `src` bitstream came from the GCP bucket, its filename will
31 # end with ".bit.splice" or ".bit.orig" and `updatemem` would reject it.
32 #
33 # TODO(#13807) Eliminate this symlink step once the names of cached
34 # bitstream files are guaranteed to end with ".bit".
35 tmpsrc = ctx.actions.declare_file("{}.tmpsrc.bit".format(ctx.label.name))
36 ctx.actions.symlink(output = tmpsrc, target_file = ctx.file.src)
37
Chris Frantz74f90952022-04-18 20:57:01 -070038 ctx.actions.run(
39 mnemonic = "SpliceBitstream",
40 outputs = [output],
Dan McArdlee1a8aad2022-07-22 12:02:58 -040041 inputs = [tmpsrc, ctx.file.meminfo, update],
Chris Frantz74f90952022-04-18 20:57:01 -070042 arguments = [
43 "-force",
44 "--meminfo",
45 ctx.file.meminfo.path,
46 "--data",
47 update.path,
48 "--bit",
Dan McArdlee1a8aad2022-07-22 12:02:58 -040049 tmpsrc.path,
Chris Frantz74f90952022-04-18 20:57:01 -070050 "--proc",
51 "dummy",
52 "--out",
53 output.path,
54 ] + ["--debug"] if ctx.attr.debug else [],
55 executable = "updatemem",
56 use_default_shell_env = False,
57 execution_requirements = {
58 "no-sandbox": "",
59 },
60 env = ENV,
61 )
62
63 return [
64 DefaultInfo(
65 files = depset([output]),
66 data_runfiles = ctx.runfiles(files = [output]),
67 ),
68 OutputGroupInfo(
69 bitstream = depset([output]),
70 update = depset([update]),
71 ),
72 ]
73
74bitstream_splice = rule(
75 implementation = _bitstream_splice_impl,
76 attrs = {
77 "meminfo": attr.label(allow_single_file = True, doc = "Memory layout info file (an .mmi file)"),
78 "src": attr.label(allow_single_file = True, doc = "The bitstream to splice"),
79 "data": attr.label(allow_single_file = True, doc = "The memory image to splice into the bitstream"),
80 "swap_nybbles": attr.bool(default = True, doc = "Swap nybbles while preparing the memory image"),
81 "debug": attr.bool(default = True, doc = "Emit debug info while updating"),
82 "_tool": attr.label(
83 default = "//hw/ip/rom_ctrl/util:gen_vivado_mem_image",
84 executable = True,
85 cfg = "exec",
86 ),
87 },
88)